Salome HOME
Copyrights update 2015.
[modules/yacs.git] / src / engine / WhileLoop.cxx
1 // Copyright (C) 2006-2015  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, or (at your option) any later version.
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
20 #include "WhileLoop.hxx"
21 #include "Runtime.hxx"
22 #include "OutputPort.hxx"
23 #include "Visitor.hxx"
24 #include <iostream>
25
26 //#define _DEVDEBUG_
27 #include "YacsTrace.hxx"
28
29 using namespace YACS::ENGINE;
30 using namespace std;
31
32 const char WhileLoop::NAME_OF_INPUT_CONDITION[]="condition";
33
34 WhileLoop::WhileLoop(const std::string& name):Loop(name),_conditionPort(NAME_OF_INPUT_CONDITION,this)
35 {
36 }
37
38 WhileLoop::WhileLoop(const WhileLoop& other, ComposedNode *father, bool editionOnly):Loop(other,father,editionOnly),
39                                                                                      _conditionPort(other._conditionPort,this)
40 {
41   //Copy Data linking
42   std::vector< std::pair<OutPort *, InPort *> > linksToReproduce=other.getSetOfInternalLinks();
43   std::vector< std::pair<OutPort *, InPort *> >::iterator iter=linksToReproduce.begin();
44   for(;iter!=linksToReproduce.end();++iter)
45     {
46       OutPort* pout = iter->first;
47       InPort* pin = iter->second;
48       edAddLink(getOutPort(other.getPortName(pout)),getInPort(other.getPortName(pin)));
49     }
50 }
51
52 void WhileLoop::init(bool start)
53 {
54   Loop::init(start);
55   _conditionPort.exInit(start);
56 }
57
58 void WhileLoop::exUpdateState()
59 {
60   if(_state == YACS::DISABLED)
61     return;
62   if(_inGate.exIsReady())
63     {
64       setState(YACS::ACTIVATED);
65       _node->exUpdateState();
66       if(_conditionPort.isLinkedOutOfScope())
67         if(_conditionPort.isEmpty())
68           {
69             delete _nodeForNullTurnOfLoops;
70             _nodeForNullTurnOfLoops=new FakeNodeForLoop(this,false,true);
71           }
72         else
73           if(!_conditionPort.getValue())
74             {
75               bool normalFinish=getAllOutPortsLeavingCurrentScope().empty();
76               delete _nodeForNullTurnOfLoops;
77               _nodeForNullTurnOfLoops=new FakeNodeForLoop(this,normalFinish);
78             }
79           else
80             {
81               delete _nodeForNullTurnOfLoops;
82               _nodeForNullTurnOfLoops=0;
83             }
84     }
85 }
86
87 Node *WhileLoop::simpleClone(ComposedNode *father, bool editionOnly) const
88 {
89   return new WhileLoop(*this,father,editionOnly);
90 }
91
92 InputPort *WhileLoop::getInputPort(const std::string& name) const throw(YACS::Exception)
93 {
94   if(name==NAME_OF_INPUT_CONDITION)
95     return (InputPort*)&_conditionPort;
96   return Loop::getInputPort(name);
97 }
98
99 //! Method used to notify the node that a child node has ended
100 /*!
101  * Update the loop state and return the loop change state
102  *
103  *  \param node : the child node that has ended
104  *  \return the loop state change
105  */
106 YACS::Event WhileLoop::updateStateOnFinishedEventFrom(Node *node)
107 {
108   _nbOfTurns++;
109   if(!_conditionPort.getValue())
110     {
111       setState(YACS::DONE);
112       return YACS::FINISH;
113     }
114   else    
115     {
116       node->init(false);
117       node->exUpdateState();
118     }
119   return YACS::NOEVENT;
120 }
121
122 void WhileLoop::checkLinkPossibility(OutPort *start, 
123                                      const std::list<ComposedNode *>& pointsOfViewStart,
124                                      InPort *end, 
125                                      const std::list<ComposedNode *>& pointsOfViewEnd) throw(YACS::Exception)
126 {
127   DEBTRACE("WhileLoop::checkLinkPossibility");
128 }
129
130 void WhileLoop::accept(Visitor *visitor)
131 {
132   visitor->visitWhileLoop(this);
133 }
134
135 std::list<InputPort *> WhileLoop::getLocalInputPorts() const
136 {
137   list<InputPort *> ret;
138   ret.push_back((InputPort *)&_conditionPort);
139   return ret;
140 }