1 #include "ComposedNode.hxx"
2 #include "InputPort.hxx"
3 #include "OutputPort.hxx"
4 #include "ElementaryNode.hxx"
8 using namespace YACS::ENGINE;
10 ComposedNode::ComposedNode(const std::string& name):Node(name)
16 * @ note : Runtime called method. Overloads the Scheduler::notifyFrom abstract method. Typically Called in Executor (in a parallel thread or not) by the Task 'task'
17 * to inform the scheduler that an event coded 'event' (in Executor static const var) happened. Contrary to updateStateFrom several level may exist between 'sender' and 'this'.
20 void ComposedNode::notifyFrom(const Task *sender, //* I : task emitting event
21 YACS::Event event //* I : event emitted
24 ElementaryNode *taskTyped=dynamic_cast<ElementaryNode *>((Task *)sender);
25 //ASSERT(taskTyped != 0)
26 YACS::Event curEvent=event;
27 Node *lminus1LevelNode=taskTyped;
28 ComposedNode *curLevelNode=taskTyped->_father;
29 curEvent=curLevelNode->updateStateFrom(lminus1LevelNode,curEvent);
30 while(curEvent!=YACS::NOEVENT && curLevelNode!=this)
32 lminus1LevelNode=curLevelNode;
33 curLevelNode=curLevelNode->_father;
34 curEvent=curLevelNode->updateStateFrom(lminus1LevelNode,curEvent);
39 * @ note : Add a dataflow link.
40 * Precondition : 'start' AND 'end' are in/outputPort contained in a node in descendance of 'this'.
41 * @ exception : incompatibility between input and output (type), or 'start'/'end' is/are NOT in/outputPort
42 * contained in a node in descendance of 'this', or a mutilple link to an input not supporting it.
43 * @ return : true if a new link has been created, false otherwise.
45 bool ComposedNode::edAddLink(OutputPort *start, InputPort *end) throw(Exception)
47 ComposedNode* lwstCmnAnctr=getLowestCommonAncestor(start->getNode(),end->getNode());
48 std::list<ComposedNode *> allAscendanceOfNodeStart=start->getNode()->getAllAscendanceOf(lwstCmnAnctr);
49 std::list<ComposedNode *> allAscendanceOfNodeEnd=end->getNode()->getAllAscendanceOf(lwstCmnAnctr);
50 checkInMyDescendance(lwstCmnAnctr);
51 ComposedNode *iterS=start->getNode()->_father;
52 OutPort *currentPortO=start;
53 while(iterS!=lwstCmnAnctr)
55 currentPortO=iterS->buildDelegateOf(currentPortO, allAscendanceOfNodeEnd);
58 iterS=end->getNode()->_father;
59 InPort *currentPortI=end;
60 while(iterS!=lwstCmnAnctr)
62 currentPortI=iterS->buildDelegateOf(currentPortI, allAscendanceOfNodeEnd);
65 return currentPortO->addInPort(currentPortI);
69 * @ note : Add a controlflow link.
70 * Precondition : 'start' AND 'end' are in/outGate contained in a node in DIRECT descendance of 'this'.
71 * @ exception : If a cycle has been detected, or incompatibility between input and output, or 'start'/'end' is/are NOT in/outputPort
72 * contained in a node in descendance of 'this', or a mutilple link to an input not supporting it.
73 * @ return : true if a new link has been created, false otherwise.
75 bool ComposedNode::edAddLink(OutGate *start, InGate *end) throw(Exception)
77 ComposedNode* father=checkHavingCommonFather(start->getNode(),end->getNode());
80 checkInMyDescendance(father);
81 return father->edAddLink(start,end);
83 bool ret=start->edAddInGate(end);
85 checkNoCyclePassingThrough(end->getNode());
89 bool ComposedNode::edAddCFLink(Node *nodeS, Node *nodeE) throw(Exception)
91 ComposedNode* father=checkHavingCommonFather(nodeS,nodeE);
94 checkInMyDescendance(father);
95 return father->edAddLink(nodeS->getOutGate(),nodeE->getInGate());
97 bool ret=nodeS->getOutGate()->edAddInGate(nodeE->getInGate());
99 checkNoCyclePassingThrough(nodeE);
104 * @ note : Remove a dataflow link.
105 * Precondition : 'start' AND 'end' are in/outputPort contained in a node in descendance of 'this'.
106 * @ exception : The specified link does not exist. The content of Exception is different in accordance with the link from 'start' to 'end' implies DF/DS gateway.
108 void ComposedNode::edRemoveLink(OutputPort *start, InputPort *end) throw(Exception)
110 ComposedNode* lwstCmnAnctr=getLowestCommonAncestor(start->getNode(),end->getNode());
111 checkInMyDescendance(lwstCmnAnctr);
112 std::list<ComposedNode *> allAscendanceOfNodeStart=start->getNode()->getAllAscendanceOf(lwstCmnAnctr);
113 std::list<ComposedNode *> allAscendanceOfNodeEnd=end->getNode()->getAllAscendanceOf(lwstCmnAnctr);
114 //Part of test if the link from 'start' to 'end' really exist particulary all eventually intermediate ports created
115 ComposedNode *iterS=start->getNode()->_father;
116 OutPort *currentPortO=start;
117 while(iterS!=lwstCmnAnctr)
119 currentPortO=iterS->getDelegateOf(currentPortO, allAscendanceOfNodeEnd);
120 iterS=iterS->_father;
122 iterS=end->getNode()->_father;
123 InPort *currentPortI=end;
124 while(iterS!=lwstCmnAnctr)
126 currentPortI=iterS->getDelegateOf(currentPortI, allAscendanceOfNodeStart);
127 iterS=iterS->_father;
129 //End of test for evt intermediate ports created
130 currentPortO->removeInPort(currentPortI);
131 //Performing deletion of intermediate ports
132 iterS=start->getNode()->_father;
133 currentPortO=start; currentPortI=end;
134 while(iterS!=lwstCmnAnctr)
136 currentPortO=iterS->releaseDelegateOf(currentPortO, allAscendanceOfNodeEnd);
137 iterS=iterS->_father;
139 iterS=end->getNode()->_father;
140 while(iterS!=lwstCmnAnctr)
142 currentPortI=iterS->releaseDelegateOf(currentPortI, allAscendanceOfNodeStart);
143 iterS=iterS->_father;
147 void ComposedNode::edRemoveLink(OutGate *start, InGate *end) throw(Exception)
149 ComposedNode* father=checkHavingCommonFather(start->getNode(),end->getNode());
151 throw Exception("edRemoveLink : nodes not in direct descendance of this");
152 start->edRemoveInGate(end);
155 void ComposedNode::publishOutputPort(OutputPort *port) throw(Exception)
157 checkInMyDescendance(port->getNode());
158 _listOfOutputPort.push_back(port);
161 void ComposedNode::publishInputPort(InputPort *port)
163 _listOfInputPort.push_back(port);
166 ComposedNode *ComposedNode::getRootNode() throw(Exception)
170 return Node::getRootNode();
174 * @ note : perform the disconnection of all links under the scope of 'this' connected to an input (dataflow or datastream) of node 'node'.
175 * This method is quite heavy because the links are stored in one direction.
177 void ComposedNode::disconnectAllLinksConnectedTo(Node *node)
179 std::list<ElementaryNode *> listOfAllNodes=getRecursiveConstituents();
180 for(std::list<ElementaryNode *>::iterator iter=listOfAllNodes.begin();iter!=listOfAllNodes.end();iter++)
181 (*iter)->disconnectAllLinksConnectedTo(node);
185 * @ note : Check that 'nodeToTest' is in descendance of 'this' OR equal to 'this'
186 * @ exception : If 'nodeToTest' is NOT in descendance of 'this' AND not equal to 'this'
188 void ComposedNode::checkInMyDescendance(Node *nodeToTest) const throw(Exception)
190 const char what[]="check failed : node is not in the correct descendance";
192 throw Exception(what);
193 if((ComposedNode *)nodeToTest==this)
195 ComposedNode *iter=nodeToTest->_father;
196 while(iter!=0 && iter!=this)
199 throw Exception(what);
204 * @ note : Retrieves the lowest common ancestor of 'node1' AND 'node2'. If 'node1' AND 'node2' are equals and are instance of ComposedNode
205 * the father of 'node1' is returned.
206 * @ exception : 'node1' and 'node2' does not share the same genealogy.
207 * @ return : The lowest common ancestor if it exists.
210 ComposedNode *ComposedNode::getLowestCommonAncestor(Node *node1, Node *node2) throw(Exception)
212 const char what[]="2 nodes does not share the same genealogy";
213 if(node1==0 || node2==0)
214 throw Exception(what);
215 ComposedNode *temp=node1->_father;
216 std::set<ComposedNode *> s;
224 std::set<ComposedNode *>::iterator iter=s.find(temp);
225 while(temp && iter==s.end())
231 throw Exception(what);
237 * @ note : Runtime called method. Perform, the state updating, from the son node 'node' emitting the event 'event' (among Executor static const var).
238 * WARNING Precondition : this == node->_father
239 * @ return : The event (among Executor static const var) destinated to this->_father node to perform eventually up level update.
242 YACS::Event ComposedNode::updateStateFrom(Node *node, //* I : node emitting event
243 YACS::Event event //* I : event emitted
249 return updateStateOnStartEventFrom(node);
252 return updateStateOnFinishedEventFrom(node);
255 return YACS::NOEVENT;//TODO unexpected type of event
260 InPort *ComposedNode::buildDelegateOf(InPort *port, const std::list<ComposedNode *>& pointsOfView)
265 OutPort *ComposedNode::buildDelegateOf(OutPort *port, const std::list<ComposedNode *>& pointsOfView)
270 InPort *ComposedNode::getDelegateOf(InPort *port, const std::list<ComposedNode *>& pointsOfView) throw(Exception)
275 OutPort *ComposedNode::getDelegateOf(OutPort *port, const std::list<ComposedNode *>& pointsOfView) throw(Exception)
280 InPort *ComposedNode::releaseDelegateOf(InPort *port, const std::list<ComposedNode *>& pointsOfView) throw(Exception)
285 OutPort *ComposedNode::releaseDelegateOf(OutPort *port, const std::list<ComposedNode *>& pointsOfView) throw(Exception)