4 #include "StaticDefinedComposedNode.hxx"
10 /*! \brief Class for bloc node
17 class Bloc : public StaticDefinedComposedNode
20 std::list<Node *> _setOfNode;//OWNERSHIP OF ALL NODES
21 //! For internal calculations
22 mutable std::map<Node *,std::set<Node *> > *_fwLinks;
23 //! For internal calculations
24 mutable std::map<Node *,std::set<Node *> > *_bwLinks;
26 Node *simpleClone(ComposedNode *father, bool editionOnly=true) const;
28 Bloc(const Bloc& other, ComposedNode *father, bool editionOnly);
29 Bloc(const std::string& name);
32 int getNumberOfCFLinks() const;
33 void init(bool start=true);
34 void getReadyTasks(std::vector<Task *>& tasks);
36 //Node* DISOWNnode is a SWIG notation to indicate that the ownership of the node is transfered to C++
37 bool edAddChild(Node *DISOWNnode) throw(Exception);
38 void edRemoveChild(Node *node) throw(Exception);
39 std::list<Node *> getChildren() const { return _setOfNode; }
40 std::list<Node *> edGetDirectDescendants() const { return _setOfNode; }
41 Node *getChildByShortName(const std::string& name) const throw(Exception);
42 void selectRunnableTasks(std::vector<Task *>& tasks);
43 virtual void writeDot(std::ostream &os) const;
44 void accept(Visitor *visitor);
45 template<bool direction>
46 void findAllPathsStartingFrom(Node *start, std::list< std::vector<Node *> >& vec, std::map<Node *, std::set<Node *> >& accelStr) const;
47 template<bool direction>
48 void findAllNodesStartingFrom(Node *start, std::set<Node *>& result, std::map<Node *, std::set<Node *> >& accelStr, LinkInfo& info) const;
49 virtual std::string typeName() {return "YACS__ENGINE__Bloc";}
51 bool areAllSubNodesFinished() const;
52 bool areAllSubNodesDone() const;
53 bool isNameAlreadyUsed(const std::string& name) const;
54 void checkNoCyclePassingThrough(Node *node) throw(Exception);
55 std::vector< std::pair<OutGate *, InGate *> > getSetOfInternalCFLinks() const;
56 YACS::Event updateStateOnFinishedEventFrom(Node *node);
57 YACS::Event updateStateOnFailedEventFrom(Node *node);
58 void initComputation() const;
59 void performCFComputations(LinkInfo& info) const;
60 void destructCFComputations(LinkInfo& info) const;
61 void checkControlDependancy(OutPort *start, InPort *end, bool cross,
62 std::map < ComposedNode *, std::list < OutPort * >, SortHierarc >& fw,
63 std::vector<OutPort *>& fwCross,
64 std::map< ComposedNode *, std::list < OutPort *>, SortHierarc >& bw,
65 LinkInfo& info) const;
66 bool areLinked(Node *start, Node *end, bool fw) const;
67 bool arePossiblyRunnableAtSameTime(Node *start, Node *end) const;
68 void checkCFLinks(const std::list<OutPort *>& starts, InputPort *end, unsigned char& alreadyFed, bool direction, LinkInfo& info) const;
69 static void verdictForOkAndUseless1(const std::map<Node *,std::list <OutPort *> >& pool, InputPort *end, const std::vector<Node *>& candidates,
70 unsigned char& alreadyFed, bool direction, LinkInfo& info);
71 static void verdictForCollapses(const std::map<Node *,std::list <OutPort *> >& pool, InputPort *end, const std::set<Node *>& candidates,
72 unsigned char& alreadyFed, bool direction, LinkInfo& info);
73 void seekOkAndUseless1(std::vector<Node *>& okAndUseless1, std::set<Node *>& allNodes) const;
74 void seekUseless2(std::vector<Node *>& useless2, std::set<Node *>& allNodes) const;
76 static void findUselessLinksIn(const std::list< std::vector<Node *> >& res , LinkInfo& info);
77 template<bool direction>
78 static unsigned appendIfAlreadyFound(std::list< std::vector<Node *> >& res, const std::vector<Node *>& startRes, Node *node, std::map<Node *, std::set<Node *> >& fastFinder);
79 static void updateWithNewFind(const std::vector<Node *>& path, std::map<Node *, std::set<Node *> >& fastFinder);
82 template<bool direction>
83 struct CFDirectionVisTraits
88 struct CFDirectionVisTraits<true>
90 typedef std::map<InGate *,bool>::iterator Iterator;
91 typedef std::map<InGate *,bool>& Nexts;
92 static Nexts getNexts(Node *node) { return node->getOutGate()->edMapInGate(); }
97 struct CFDirectionVisTraits<false>
99 typedef std::map<OutGate *,bool>::iterator Iterator;
100 typedef std::map<OutGate *,bool>& Nexts;
101 static Nexts getNexts(Node *node) { return node->getInGate()->edMapOutGate(); }
105 * Internal method for CF computation. Given 'fastFinder' it searched 'node' to see if an already found path in 'res' go through 'node'.
106 * If true all paths are deduced and append to res and 'fastFinder' is updated for next turn.
108 template<bool direction>
109 unsigned Bloc::appendIfAlreadyFound(std::list< std::vector<Node *> >& res, const std::vector<Node *>& startRes, Node *node, std::map<Node *, std::set<Node *> >& fastFinder)
111 std::map<Node *, std::set<Node *> >::const_iterator iter=fastFinder.find(node);
112 if(iter==fastFinder.end())
115 std::vector<std::pair<std::set<Node *>::iterator, std::set<Node *>::iterator > > li;
116 li.push_back(std::pair<std::set<Node *>::iterator, std::set<Node *>::iterator>(((*iter).second).begin(),((*iter).second).end()));
117 std::vector<Node *> work(startRes);
118 std::list< std::vector<Node *> >::iterator where=res.end(); where--;
119 std::list< std::vector<Node *> >::iterator updates=where;
122 if(li.back().first!=li.back().second)
124 work.push_back(*(li.back().first));
125 if(CFDirectionVisTraits<direction>::getNexts(work.back()).empty())
127 where=res.insert(where,work);
134 const std::set<Node *>& s=fastFinder[*(li.back().first)];
135 li.push_back(std::pair<std::set<Node *>::iterator, std::set<Node *>::iterator>(s.begin(),s.end()));
147 for(unsigned i=0;i<ret;i++,updates--)
148 updateWithNewFind(*updates,fastFinder);
152 template<bool direction>
153 void Bloc::findAllNodesStartingFrom(Node *start, std::set<Node *>& result, std::map<Node *, std::set<Node *> >& accelStr, LinkInfo& info) const
155 std::list< std::vector<Node *> > li;
156 findAllPathsStartingFrom<direction>(start,li,accelStr);
157 for(std::list< std::vector<Node *> >::const_iterator iter=li.begin();iter!=li.end();iter++)
158 for(std::vector<Node *>::const_iterator iter2=(*iter).begin()+1;iter2!=(*iter).end();iter2++)
159 result.insert(*iter2);
161 findUselessLinksIn(li,info);
165 * Method for CF computation.DFS visitor is used.
166 * \param start \b must be a direct descendant of 'this'.
167 * \param direction if true forward visiting is perform, false backward is used.
169 template<bool direction>
170 void Bloc::findAllPathsStartingFrom(Node *start, std::list< std::vector<Node *> >& vec, std::map<Node *, std::set<Node *> >& accelStr) const
176 vec.push_back(std::vector<Node *>());
177 typename CFDirectionVisTraits<direction>::Iterator iter;
178 std::list< std::vector<Node *> >::iterator curLine=vec.begin();
179 while(start->_colour!=YACS::Black)
181 (*curLine).push_back(current);
184 if(CFDirectionVisTraits<direction>::getNexts(current).empty())
187 vec.push_back(std::vector<Node *>((*curLine)));
188 updateWithNewFind(*curLine,accelStr);
189 current->_colour=YACS::Black;
194 current=(*curLine)[idInCase];
195 (*curLine).pop_back();
196 (*curLine).pop_back();
200 if(current->_colour==YACS::Black)
202 appendIfAlreadyFound<direction>(vec,(*curLine),current,accelStr);
203 curLine=vec.end(); curLine--;
204 current->_colour=YACS::Black;
208 current=(*curLine)[idInCase];
209 (*curLine).pop_back();
210 (*curLine).pop_back();
214 for(iter=CFDirectionVisTraits<direction>::getNexts(current).begin();iter!=CFDirectionVisTraits<direction>::getNexts(current).end();iter++)
217 if(iter==CFDirectionVisTraits<direction>::getNexts(current).end())
218 {//Fail this branch should be forgotten go rev
219 current->_colour=YACS::Black;
220 (*curLine).pop_back();
224 current=(*curLine)[idInCase];
225 (*curLine).pop_back();
230 //Nothing to signal continuing in this direction hoping to find
231 current=(*iter).first->getNode();