summaryrefslogtreecommitdiffstats
path: root/flow/virtualports.cc
diff options
context:
space:
mode:
authorMichele Calgaro <michele.calgaro@yahoo.it>2020-12-06 19:28:06 +0900
committerMichele Calgaro <michele.calgaro@yahoo.it>2020-12-06 19:28:49 +0900
commit247750abcbf6760bbc52aa5d64fc375d6fbee8a3 (patch)
tree86e029a960ddd599edbeee8dddf70e87ee314e23 /flow/virtualports.cc
parent595ad58e25c5d0f0c512194f66708f99e5bc1527 (diff)
downloadarts-247750abcbf6760bbc52aa5d64fc375d6fbee8a3.tar.gz
arts-247750abcbf6760bbc52aa5d64fc375d6fbee8a3.zip
Renaming of files in preparation for code style tools.
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it> (cherry picked from commit 00d4f92b717fbcbed6f9eee361975d6ee5380d59)
Diffstat (limited to 'flow/virtualports.cc')
-rw-r--r--flow/virtualports.cc491
1 files changed, 0 insertions, 491 deletions
diff --git a/flow/virtualports.cc b/flow/virtualports.cc
deleted file mode 100644
index b733256..0000000
--- a/flow/virtualports.cc
+++ /dev/null
@@ -1,491 +0,0 @@
- /*
-
- Copyright (C) 2000 Stefan Westerfeld
- stefan@space.twc.de
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-
- */
-
-#include "virtualports.h"
-#include <algorithm>
-#include <stdio.h>
-
-using namespace Arts;
-using namespace std;
-
-#undef VPORT_DEBUG
-
-/* virtual port connections */
-
-/*
-
-Port virtualization is used in the following case: suppose you have a module
-M which has an input port and an output port like that:
-
-input
- V
------
- M
------
- V
-output
-
-But suppose the module M is implement as combination of other modules, for
-instance the effect of M is achieved by passing the signal first through an
-A and then through an B module. Clients connecting M should "really" connect
-A,B. For this virtualization is used.
-
-There are two kinds:
-
-- masquerading: which means (like in our case), the input of a module is really
- implemented with the input of another module. So M's input could be really
- implemented by A's input
-
- there is also output masquerading, which would be for instance that M's
- output is really implemented by B's output
-
-- forwarding: if M in our example would choose to do nothing at all, it could
- simply forward its input to its output
-
-
-The interface for the user:
-
-MCOP will show the virtualize function to the user, which the user can use
-to delegate the services of a port to another module onto another port.
-
-- masquerading: in our case, for instance the user could call
-
- m._node()->virtualize("inputport",a._node(),"inputport");
-
- which would forward all input m gets on "inputport" to a's "inputport"
-
-- forwarding: in the same way, the user could call
-
- m._node()->virtualize("inputport",m._node(),"outputport");
-
- which would make m forward its input directly to its output
-
-The implementation:
-
-Virtualization is implemented here, inside the flow system, using a fairly
-complex forwarding strategy, which will have a graph which contains
-
-- "user-made" connections (made with connect())
-- "virtualize-made" connections, which can be either forwarding
- (input to output port) or masquerading (input to input or output to output)
-
-Out of all these, the algorithm builds "real" connections, which are
-then really performed inside the flow system. If you change the "user-made"
-or "virtualize-made" connections, the "real" connections are recalculated.
-
-The "real" connections are created by the expandHelper function. They are
-called vcTransport here.
-
-The strategy expandHelper uses is to go back to a port which is only output
-port (non forwarded, non masqueraded), and then follow the graph recursively
-over vcMasquerade and vcForward edges until it reaches a port which is only
-input. Then it creates a real connection.
-
-Some tweaks are there which allow that not on any change at the graph, all
-real connections will be removed, but only these that could possibly be
-affected by this change, and then not all real connections are created new,
-but only those that could possibly be created by this virtual connection.
-
-Every VPort contains a pointer to the "real" port, to let the flow system
-know where the "real" connections where real data will flow must be made.
-
-*/
-
-VPortConnection::VPortConnection(VPort *source, VPort *dest, Style style)
- :source(source),dest(dest),style(style)
-{
- if(style != vcTransport)
- {
- list<VPortConnection *>::iterator i;
-
- // remove transport connections ending at "source" (they will
- // probably be forwarded/masqueraded elsewhere by this VPortConnection)
- i = source->incoming.begin();
- while(i != source->incoming.end())
- {
- if((*i)->style == vcTransport)
- {
- delete *i;
- i = source->incoming.begin();
- }
- else i++;
- }
-
- // remove transport connections starting at "dest" (they will
- // probably be forwarded/masqueraded elsewhere by this VPortConnection)
- i = dest->outgoing.begin();
- while(i != dest->outgoing.end())
- {
- if((*i)->style == vcTransport)
- {
- delete *i;
- i = dest->outgoing.begin();
- }
- else i++;
- }
- }
-
- // add to the connection lists
- source->outgoing.push_back(this);
- dest->incoming.push_back(this);
-
- if(style == vcTransport)
- {
-#ifdef VPORT_DEBUG
- arts_debug("emit a connection consumer = %s, producer = %s",
- dest->name(), source->name());
-#endif
- dest->port->connect(source->port);
- }
- else
- {
- source->makeTransport(this);
- }
-}
-
-VPortConnection::~VPortConnection()
-{
-#ifdef VPORT_DEBUG
- cout << "~VPortConnection" << endl;
-#endif
-
- if(style != vcTransport)
- {
- // remove transport connection which go through this connection
- source->removeTransport(this);
- }
-
- // remove this connection from the lists
- list<VPortConnection *>::iterator ci;
-
- ci = find(source->outgoing.begin(),source->outgoing.end(),this);
- assert(ci != source->outgoing.end());
- source->outgoing.erase(ci);
-
- ci = find(dest->incoming.begin(),dest->incoming.end(),this);
- assert(ci != dest->incoming.end());
- dest->incoming.erase(ci);
-
- if(style == vcTransport)
- {
-#ifdef VPORT_DEBUG
- arts_debug("delete connection %s -> %s",dest->name(), source->name());
-#endif
- dest->port->disconnect(source->port);
- }
-
- // reestablish all connections which started/ended here before
- if(style != vcTransport)
- {
- list<VPortConnection *>::iterator i;
- stack<VPortConnection *> todo;
-
- // reestablish transport connections which were ending at source...
- for(i = source->incoming.begin(); i != source->incoming.end(); i++)
- if((*i)->style != vcTransport) todo.push(*i);
-
- // ... and starting at dest
- for(i = dest->outgoing.begin(); i != dest->outgoing.end(); i++)
- if((*i)->style != vcTransport) todo.push(*i);
-
- // we need to do this with the stack as makeTransport can affect the
- // incoming/outgoing lists by adding new vcTransport connections
- while(!todo.empty())
- {
- todo.top()->source->makeTransport(todo.top());
- todo.pop();
- }
- }
-
-#ifdef VPORT_DEBUG
- cout << "~VPortConnection done" << endl;
-#endif
-}
-
-/*---------------------- virtual port implementation ----------------------*/
-
-VPort::VPort(Port *port) :port(port)
-{
-#ifdef VPORT_DEBUG
- cout << "VPort: " << name() << endl;
-#endif
-}
-
-VPort::~VPort()
-{
-#ifdef VPORT_DEBUG
- cout << "~VPort: " << name() << endl;
-#endif
- while(!incoming.empty()) delete *incoming.begin();
- while(!outgoing.empty()) delete *outgoing.begin();
-#ifdef VPORT_DEBUG
- cout << "~VPort done" << endl;
-#endif
-}
-
-bool VPort::makeVirtualizeParams(VPort *forward, VPort*& source, VPort*& dest,
- VPortConnection::Style& style)
-{
- source = dest = 0;
- // masquerading
- if((port->flags() & streamIn) && (forward->port->flags() & streamIn))
- {
- // input: data flow direction is from us to the "forward" port
- // XXX?
- source = this;
- dest = forward;
- style = VPortConnection::vcMasquerade;
- }
- else if((port->flags() & streamOut) && (forward->port->flags() & streamOut))
- {
- // output: data flow direction is from the "forward" port to us
- // XXX?
- source = forward;
- dest = this;
- style = VPortConnection::vcMasquerade;
- }
- // forwarding
- else if((port->flags() & streamIn) && (forward->port->flags() & streamOut))
- {
- source = this;
- dest = forward;
- style = VPortConnection::vcForward;
- }
- else if((port->flags() & streamOut) && (forward->port->flags() & streamIn))
- {
- source = forward;
- dest = this;
- style = VPortConnection::vcForward;
- }
- return source != 0;
-}
-
-/**
- * a->virtualize(b) means, that the functionality that port a should provide
- * (e.g. produce or consume data) is really provided by port b
- */
-void VPort::virtualize(VPort *forward)
-{
- VPort *source, *dest;
- VPortConnection::Style style;
-
- if(makeVirtualizeParams(forward,source,dest,style))
- {
-#ifdef VPORT_DEBUG
- cout << "virtualize ... source (producer) is " << source->name() <<
- " dest (consumer) is " << dest->name() << endl;
-#endif
- new VPortConnection(source,dest,style);
- }
-}
-
-void VPort::devirtualize(VPort *forward)
-{
- VPort *source, *dest;
- VPortConnection::Style style;
-
- // XXX?
- if(makeVirtualizeParams(forward,source,dest,style))
- {
- list<VPortConnection *>::iterator i;
- for(i = source->outgoing.begin(); i != source->outgoing.end(); i++)
- {
- if((*i)->source == source && (*i)->dest == dest
- && (*i)->style == style)
- {
- delete (*i);
- return;
- }
- }
- }
-}
-
-void VPort::setFloatValue(float value)
-{
- if(outgoing.empty())
- {
- AudioPort *aport = port->audioPort();
- assert(aport);
- aport->setFloatValue(value);
- }
- else
- {
- list<VPortConnection *>::iterator i;
- for(i=outgoing.begin();i != outgoing.end(); i++)
- {
- VPortConnection *conn = *i;
- assert(conn->style == VPortConnection::vcMasquerade);
-
- conn->dest->setFloatValue(value);
- }
- }
-}
-
-void VPort::connect(VPort *dest)
-{
- VPortConnection *conn;
- if(port->flags() & streamOut)
- {
- conn = new VPortConnection(this,dest,VPortConnection::vcConnect);
- }
- else
- {
- conn = new VPortConnection(dest,this,VPortConnection::vcConnect);
- }
-}
-
-void VPort::disconnect(VPort *dest)
-{
- if(port->flags() & streamOut)
- {
- list<VPortConnection *>::iterator ci = outgoing.begin();
- while(ci != outgoing.end())
- {
- assert((*ci)->source == this);
- if((*ci)->dest == dest && (*ci)->style==VPortConnection::vcConnect)
- {
- delete (*ci); // will remove itself from the outgoing list
- return;
- }
- ci++;
- }
- }
- else
- {
- if(dest->port->flags() & streamOut)
- {
- dest->disconnect(this);
- return;
- }
- }
-}
-
-void VPort::expandHelper(VPortConnection *conn, int state, VPort *current,
- VPort *source, VPort *dest, bool remove)
-{
- list<VPortConnection *>::iterator ci;
-
-#ifdef VPORT_DEBUG
- cout << "expandhelper state " << state << " name " << current->name() << endl;
-#endif
-
- if(state == 1) /* state 1: scan backward for output ports */
- {
- if(current->incoming.empty())
- {
- if(current->port->flags() & streamOut)
- expandHelper(conn,2,current,current,dest,remove);
- }
- for(ci = current->incoming.begin(); ci != current->incoming.end();ci++)
- {
- assert((*ci)->style != VPortConnection::vcTransport);
- expandHelper(conn,1,(*ci)->source,source,dest,remove);
- }
- }
- else if(state == 2) /* state 2: output port expansion */
- {
- assert(current->port->flags() & streamOut);
-
- for(ci = current->outgoing.begin(); ci != current->outgoing.end();ci++)
- {
- /* xconn=0 ensures that only paths are counted which contain conn */
- VPortConnection *xconn = conn;
- if(*ci == conn) xconn = 0;
-
- if((*ci)->style == VPortConnection::vcMasquerade)
- {
- expandHelper(xconn,2,(*ci)->dest,source,dest,remove);
- }
- else if((*ci)->style == VPortConnection::vcConnect)
- {
- expandHelper(xconn,3,(*ci)->dest,source,(*ci)->dest,remove);
- }
- }
- }
- else if(state == 3) /* state 3: input port expansion */
- {
- assert(current->port->flags() & streamIn);
-
- for(ci = current->outgoing.begin(); ci != current->outgoing.end();ci++)
- {
- /* xconn=0 ensures that only paths are counted which contain conn */
- VPortConnection *xconn = conn;
- if(*ci == conn) xconn = 0;
-
- if((*ci)->style == VPortConnection::vcMasquerade)
- {
- // XXX ?
- expandHelper(xconn,3,(*ci)->dest,source,(*ci)->dest,remove);
- }
- else if((*ci)->style == VPortConnection::vcForward)
- {
- expandHelper(xconn,2,(*ci)->dest,source,dest,remove);
- }
- }
-
- if(current->outgoing.empty() && conn == 0)
- {
- if(remove)
- {
- // delete exactly one transport connection
-
- bool removeOk = false;
- ci = current->incoming.begin();
- while(ci != current->incoming.end() && !removeOk)
- {
- if((*ci)->source == source && (*ci)->dest == dest
- && (*ci)->style == VPortConnection::vcTransport)
- {
- delete (*ci);
- removeOk = true;
- }
- else ci++;
- }
- assert(removeOk);
- }
- else
- {
- new VPortConnection(source,dest,VPortConnection::vcTransport);
- }
- }
- }
-}
-
-void VPort::makeTransport(VPortConnection *conn)
-{
- expandHelper(conn,1,this,0,0,false);
-}
-
-void VPort::removeTransport(VPortConnection *conn)
-{
- expandHelper(conn,1,this,0,0,true);
-}
-
-const char *VPort::name()
-{
- if(_name.empty())
- {
- _name = port->parent->object()->_interfaceName() + "." +
- port->name();
- }
- return _name.c_str();
-}