diff options
author | Michele Calgaro <michele.calgaro@yahoo.it> | 2020-12-06 19:28:06 +0900 |
---|---|---|
committer | Michele Calgaro <michele.calgaro@yahoo.it> | 2020-12-06 19:28:49 +0900 |
commit | 247750abcbf6760bbc52aa5d64fc375d6fbee8a3 (patch) | |
tree | 86e029a960ddd599edbeee8dddf70e87ee314e23 /flow/virtualports.cc | |
parent | 595ad58e25c5d0f0c512194f66708f99e5bc1527 (diff) | |
download | arts-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.cc | 491 |
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(); -} |