Salome HOME
merge from branch DEV tag mergeto_trunk_04apr08
[modules/yacs.git] / src / engine / WhileLoop.cxx
1 #include "WhileLoop.hxx"
2 #include "Runtime.hxx"
3 #include "OutputPort.hxx"
4 #include "Visitor.hxx"
5 #include <iostream>
6
7 //#define _DEVDEBUG_
8 #include "YacsTrace.hxx"
9
10 using namespace YACS::ENGINE;
11 using namespace std;
12
13 const char WhileLoop::NAME_OF_INPUT_CONDITION[]="condition";
14
15 WhileLoop::WhileLoop(const std::string& name):Loop(name),_conditionPort(NAME_OF_INPUT_CONDITION,this)
16 {
17 }
18
19 WhileLoop::WhileLoop(const WhileLoop& other, ComposedNode *father, bool editionOnly):Loop(other,father,editionOnly),
20                                                                                      _conditionPort(other._conditionPort,this)
21 {
22 }
23
24 void WhileLoop::init(bool start)
25 {
26   Loop::init(start);
27   _conditionPort.exInit(start);
28 }
29
30 void WhileLoop::exUpdateState()
31 {
32   if(_state == YACS::DISABLED)
33     return;
34   if(_inGate.exIsReady())
35     {
36       setState(YACS::TOACTIVATE);
37       _node->exUpdateState();
38       if(_conditionPort.isLinkedOutOfScope())
39         if(_conditionPort.isEmpty())
40           {
41             delete _nodeForNullTurnOfLoops;
42             _nodeForNullTurnOfLoops=new FakeNodeForLoop(this,false,true);
43           }
44         else
45           if(!_conditionPort.getValue())
46             {
47               bool normalFinish=getAllOutPortsLeavingCurrentScope().empty();
48               delete _nodeForNullTurnOfLoops;
49               _nodeForNullTurnOfLoops=new FakeNodeForLoop(this,normalFinish);
50             }
51           else
52             {
53               delete _nodeForNullTurnOfLoops;
54               _nodeForNullTurnOfLoops=0;
55             }
56     }
57 }
58
59 Node *WhileLoop::simpleClone(ComposedNode *father, bool editionOnly) const
60 {
61   return new WhileLoop(*this,father,editionOnly);
62 }
63
64 InputPort *WhileLoop::getInputPort(const std::string& name) const throw(Exception)
65 {
66   if(name==NAME_OF_INPUT_CONDITION)
67     return (InputPort*)&_conditionPort;
68   return Loop::getInputPort(name);
69 }
70
71 //! Method used to notify the node that a child node has ended
72 /*!
73  * Update the loop state and return the loop change state
74  *
75  *  \param node : the child node that has ended
76  *  \return the loop state change
77  */
78 YACS::Event WhileLoop::updateStateOnFinishedEventFrom(Node *node)
79 {
80   _nbOfTurns++;
81   if(!_conditionPort.getValue())
82     {
83       setState(YACS::DONE);
84       return YACS::FINISH;
85     }
86   else    
87     {
88       node->init(false);
89       node->exUpdateState();
90     }
91   return YACS::NOEVENT;
92 }
93
94 void WhileLoop::checkLinkPossibility(OutPort *start, 
95                                      const std::list<ComposedNode *>& pointsOfViewStart,
96                                      InPort *end, 
97                                      const std::list<ComposedNode *>& pointsOfViewEnd) throw(Exception)
98 {
99   DEBTRACE("WhileLoop::checkLinkPossibility");
100 }
101
102 void WhileLoop::accept(Visitor *visitor)
103 {
104   visitor->visitWhileLoop(this);
105 }
106
107 std::list<InputPort *> WhileLoop::getLocalInputPorts() const
108 {
109   list<InputPort *> ret;
110   ret.push_back((InputPort *)&_conditionPort);
111   return ret;
112 }