Salome HOME
PR: merge from BR_DATACONV_PR tag "mergeto_trunk_25oct06"
[modules/yacs.git] / src / engine / Node.cxx
1 #include "Node.hxx"
2 #include "InputPort.hxx"
3 #include "OutputPort.hxx"
4 #include "ComposedNode.hxx"
5 #include "InputDataStreamPort.hxx"
6 #include "OutputDataStreamPort.hxx"
7
8 using namespace YACS::ENGINE;
9 using namespace std;
10
11 Node::Node(const string& name):_name(name),_inGate(this),_outGate(this),_father(0),_colour(YACS::White),_state(YACS::INITED)
12 {
13 }
14
15 Node::~Node()
16 {
17 }
18
19 /**
20  *  initialisation of all input and output ports and gates, for execution
21  */
22
23 void Node::init()
24 {
25   _inGate.exReset();
26   for(set<OutputPort *>::iterator iter=_setOfOutputPort.begin();iter!=_setOfOutputPort.end();iter++)
27     (*iter)->exInit();
28   for(set<InputPort *>::iterator iter2=_setOfInputPort.begin();iter2!=_setOfInputPort.end();iter2++)
29     (*iter2)->exInit();
30   if(_inGate.exIsReady())
31     _state=YACS::TOACTIVATE;
32   else
33     _state=YACS::INITED;
34 }
35
36 /**
37  *  get the set of all nodes connected to the outGate
38  */
39
40 set<Node *> Node::getOutNodes() const
41 {
42   set<Node *> ret;
43   set<InGate *> inGates=_outGate.edSetInGate();
44   for(set<InGate *>::iterator iter=inGates.begin();iter!=inGates.end();iter++)
45     ret.insert((*iter)->getNode());
46   return ret;
47 }
48
49 /**
50  * @note : Update the '_state' attribute.
51  *          Typically called by 'this->_inGate' when 'this->_inGate' is ready.
52  */
53
54 void Node::exUpdateState()
55 {
56   if(_inGate.exIsReady())
57     if(areAllInputPortsValid())
58       _state=YACS::TOACTIVATE;
59     else
60       {
61         string what("Node::exUpdateState : Invalid graph given : Node with name \"");
62         what+=_name; what+="\" ready to run whereas some inputports are not set correctly\nCheck coherence DF/CF";
63         throw Exception(what);
64       }
65 }
66
67 int Node::getNumberOfInputPorts() const
68 {
69   return _setOfInputPort.size();
70 }
71
72 int Node::getNumberOfOutputPorts() const
73 {
74   return _setOfOutputPort.size();
75 }
76
77 InputPort *Node::getInputPort(const string& name) const throw(Exception)
78 {
79   return getPort<InputPort>(name,_setOfInputPort);
80 }
81
82 OutputPort *Node::getOutputPort(const string& name) const throw(Exception)
83 {
84   return getPort<OutputPort>(name,_setOfOutputPort);
85 }
86
87 InputDataStreamPort *Node::getInputDataStreamPort(const string& name) const throw(Exception)
88 {
89   return getPort<InputDataStreamPort>(name,_setOfInputDataStreamPort);
90 }
91
92 OutputDataStreamPort *Node::getOutputDataStreamPort(const string& name) const throw(Exception)
93 {
94   return getPort<OutputDataStreamPort>(name,_setOfOutputDataStreamPort);
95 }
96
97
98 /**
99  * gets a set of the composed nodes that constitute the ascendancy of this node, starting from root
100  * or from a particular ancestor
101  * @param  levelToStop   composed node which is the oldest ancestor required
102  * @return               ascendancy, direct father first in set.
103  */
104
105 set<ComposedNode *> Node::getAllAscendanceOf(ComposedNode *levelToStop)
106 {
107   set<ComposedNode *> ret;
108   for(ComposedNode *iter=_father;iter!=levelToStop && iter!=0; iter=iter->_father)
109       ret.insert(iter);
110   return ret;
111 }
112
113 /**
114  *  @return Implementation of node: C++, Python, CORBA...
115  *  _implementation is set by a derived class in a Runtime
116  *  it normally applies only to elementaryNodes and it is used by Ports to select Data Converters.
117  *  Potential problem with Ports attached to composed Nodes...
118  */
119
120 string Node::getImplementation()
121 {
122   return _implementation;
123 }
124
125 /**
126  * checks if all input ports contains a valid data. Used at execution to change the state of the node
127  * for activation.
128  */
129
130 bool Node::areAllInputPortsValid() const
131 {
132   bool ret=true;
133   for(set<InputPort *>::const_iterator iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++)
134     {
135       ret=!(*iter)->isEmpty();
136       if (!ret) break;
137     }
138   return ret;
139 }
140
141 ComposedNode *Node::getRootNode() throw(Exception)
142 {
143   if(!_father)
144     throw Exception("No root node");
145   ComposedNode *iter=_father;
146   while(iter->_father)
147     iter=iter->_father;
148   return iter;
149 }
150
151 /**
152  * checks validity of ports name, that must not contain a particular character '?'
153  * USAGE NOT CLEAR, not used so far, when are those characters set ?
154  */
155
156 void Node::checkValidityOfPortName(const string& name) throw(Exception)
157 {
158   if(name.find(SEP_CHAR_IN_PORT, 0 )!=string::npos)
159     {
160       string what("Port name "); what+=name; what+="not valid because it contains character "; what+=SEP_CHAR_IN_PORT;
161       throw Exception(what);
162     }
163 }
164
165 /**
166  * @note : Check that 'node1' and 'node2' have exactly the same father
167  * @exception : If 'node1' and 'node2' have NOT exactly the same father
168  */
169 ComposedNode *Node::checkHavingCommonFather(Node *node1, Node *node2) throw(Exception)
170 {
171   if(node1!=0 && node2!=0)
172     {
173       if(node1->_father==node2->_father)
174         return node1->_father;
175     }
176   throw Exception("check failed : nodes have not the same father");
177 }
178
179 /**
180  * set color for inGates : display
181  * USAGE NOT CLEAR, not used so far
182  */
183
184 void Node::initForDFS() const
185 {
186   _colour=YACS::White;
187   set<InGate *> inGates=_outGate.edSetInGate();
188   for(set<InGate *>::iterator iter=inGates.begin();iter!=inGates.end();iter++)
189     (*iter)->initForDFS();
190 }