Salome HOME
e1e0aeb4f5cc98f581fcde8bd7e70255e8eb14b6
[modules/yacs.git] / src / engine / ForLoop.cxx
1 //  Copyright (C) 2006-2008  CEA/DEN, EDF R&D
2 //
3 //  This library is free software; you can redistribute it and/or
4 //  modify it under the terms of the GNU Lesser General Public
5 //  License as published by the Free Software Foundation; either
6 //  version 2.1 of the License.
7 //
8 //  This library is distributed in the hope that it will be useful,
9 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 //  Lesser General Public License for more details.
12 //
13 //  You should have received a copy of the GNU Lesser General Public
14 //  License along with this library; if not, write to the Free Software
15 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 #include "ForLoop.hxx"
20 #include "Runtime.hxx"
21 #include "OutputPort.hxx"
22 #include "Visitor.hxx"
23 #include <iostream>
24
25 using namespace YACS::ENGINE;
26 using namespace std;
27
28 const char ForLoop::NAME_OF_NSTEPS_NUMBER[]="nsteps";
29
30 ForLoop::ForLoop(const std::string& name):Loop(name),_nbOfTimesPort(NAME_OF_NSTEPS_NUMBER,this,Runtime::_tc_int)
31 {
32 }
33
34 ForLoop::ForLoop(const ForLoop& other, ComposedNode *father, bool editionOnly):Loop(other,father,editionOnly),
35                                                                                _nbOfTimesPort(other._nbOfTimesPort,this)
36 {
37 }
38
39 Node *ForLoop::simpleClone(ComposedNode *father, bool editionOnly) const
40 {
41   return new ForLoop(*this,father,editionOnly);
42 }
43
44 InputPort* ForLoop::getInputPort(const std::string& name) const throw(Exception)
45 {
46     if(name == NAME_OF_NSTEPS_NUMBER)return (InputPort*)&_nbOfTimesPort;
47     return Loop::getInputPort(name);
48
49 }
50
51 //! Initialize the node
52 /*!
53  * \param start: a boolean flag to indicate the initialization mode
54  *
55  * If start is true, it's a complete initialization (with port values initialization)
56  * If start is false, there is no port values initialization
57  *
58  */
59 void ForLoop::init(bool start)
60 {
61   Loop::init(start);
62   _nbOfTimesPort.exInit(start);
63 }
64
65 //! Update the state of the for loop
66 /*!
67  * If the inGate port is ready goes to YACS::TOACTIVATE state
68  * If the steps number is 0, create an special internal node
69  *
70  */
71 void ForLoop::exUpdateState()
72 {
73   if(_state == YACS::DISABLED)
74     return;
75   if(_inGate.exIsReady())
76     {
77       setState(YACS::TOACTIVATE);
78       _node->exUpdateState();
79       if(_nbOfTimesPort.isEmpty())
80         {
81           delete _nodeForNullTurnOfLoops;
82           _nodeForNullTurnOfLoops=new FakeNodeForLoop(this,false,true);
83         }
84       else
85         {
86           if(_nbOfTimesPort.getIntValue()==0)
87             {
88               bool normalFinish=getAllOutPortsLeavingCurrentScope().empty();
89               delete _nodeForNullTurnOfLoops;
90               _nodeForNullTurnOfLoops=new FakeNodeForLoop(this,normalFinish);
91             }
92           else if(_nbOfTimesPort.getIntValue()<0)
93             {
94               delete _nodeForNullTurnOfLoops;
95               _nodeForNullTurnOfLoops=new FakeNodeForLoop(this,false);
96             }
97           else
98             {
99               delete _nodeForNullTurnOfLoops;
100               _nodeForNullTurnOfLoops=0;
101             }
102         }
103     }
104 }
105
106 //! Method used to notify the node that a child node has ended
107 /*!
108  * Update the loop state and return the loop change state 
109  *
110  *  \param node : the child node that has ended
111  *  \return the loop state change
112  */
113 YACS::Event ForLoop::updateStateOnFinishedEventFrom(Node *node)
114 {
115   if((++_nbOfTurns)>=_nbOfTimesPort.getIntValue())
116     {
117       setState(YACS::DONE);
118       return YACS::FINISH;
119     }
120   else
121     {
122       node->init(false);
123       node->exUpdateState();
124     }
125   return YACS::NOEVENT;
126 }
127
128 void ForLoop::accept(Visitor *visitor)
129 {
130   visitor->visitForLoop(this);
131 }
132
133 std::list<InputPort *> ForLoop::getLocalInputPorts() const
134 {
135   list<InputPort *> ret;
136   ret.push_back((InputPort *)&_nbOfTimesPort);
137   return ret;
138 }