ParsedStateMachine.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  tag: Peter Soetens Tue Jul 20 17:32:42 CEST 2004 ParsedStateMachine.cxx
3 
4  ParsedStateMachine.cxx - description
5  -------------------
6  begin : Tue July 20 2004
7  copyright : (C) 2004 Peter Soetens
8  email : peter.soetens@mech.kuleuven.ac.be
9 
10  ***************************************************************************
11  * This library is free software; you can redistribute it and/or *
12  * modify it under the terms of the GNU General Public *
13  * License as published by the Free Software Foundation; *
14  * version 2 of the License. *
15  * *
16  * As a special exception, you may use this file as part of a free *
17  * software library without restriction. Specifically, if other files *
18  * instantiate templates or use macros or inline functions from this *
19  * file, or you compile this file and link it with other files to *
20  * produce an executable, this file does not by itself cause the *
21  * resulting executable to be covered by the GNU General Public *
22  * License. This exception does not however invalidate any other *
23  * reasons why the executable file might be covered by the GNU General *
24  * Public License. *
25  * *
26  * This library is distributed in the hope that it will be useful, *
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
29  * General Public License for more details. *
30  * *
31  * You should have received a copy of the GNU General Public *
32  * License along with this library; if not, write to the Free Software *
33  * Foundation, Inc., 59 Temple Place, *
34  * Suite 330, Boston, MA 02111-1307 USA *
35  * *
36  ***************************************************************************/
37 
38 #include "ParsedStateMachine.hpp"
39 #include "../internal/DataSource.hpp"
40 #include "../ExecutionEngine.hpp"
41 #include "StateDescription.hpp"
42 
43 #include "../Service.hpp"
44 #include "StateMachineService.hpp"
45 #include "../TaskContext.hpp"
46 #include "../internal/mystd.hpp"
47 
48 #include <cassert>
49 
50 #include <boost/lambda/lambda.hpp>
51 
52 namespace RTT {
53  using namespace detail;
54  using namespace std;
55  using boost::tuples::get;
64  ParsedStateMachinePtr ParsedStateMachine::copy( std::map<const DataSourceBase*, DataSourceBase*>& replacements, bool instantiate ) const
65  {
66  /* Recursive copy :
67  * First copy this SC, then its child SC's
68  */
69  std::map<const StateInterface*, StateInterface*> statemapping;
71  ret->_text = this->_text;
72  ret->setName( this->_name, false);
73 
74  if (instantiate)
75  Logger::log() <<Logger::Debug <<"Creating an instance of "<< this->_name << Logger::endl;
76 
77  // First copy the task such that commands and attributes can be correctly
78  // copied. This also sets the EventProcessor for the SM.
79  ret->setService( this->object->copy(ret, replacements, instantiate) );
80 
81  // the parameters of the SC, similar to FunctionGraph's Arguments.
82  for ( VisibleWritableValuesMap::const_iterator i = parametervalues.begin();
83  i != parametervalues.end(); ++i )
84  {
85  // What is sure, is that each param
86  // must also be in the ConfigurationInterface.
87  assert( ret->getService()->getValue( i->first ) );
88  ret->parametervalues[i->first] = ret->getService()->getValue( i->first );
89  }
90 
91  //**********************
92  // TODO add copy method to StateMachine itself where all stuff below belongs :
93  // but, not so easy since copy makes new instance...
94  for ( ChildList::const_iterator i = getChildren().begin(); i != getChildren().end(); ++i )
95  {
96  // copy the submachines....
97  assert( dynamic_cast<ParsedStateMachine*>( i->get() ) == static_cast<ParsedStateMachine*>( i->get() ));
98  ParsedStateMachinePtr oldmachine = boost::dynamic_pointer_cast<ParsedStateMachine>( *i );
99  ParsedStateMachinePtr newmachine(oldmachine->copy( replacements, instantiate ));
100  // I would think that providing 'instantiate' would not hurt...
101  // XXX? previously, the instantiate flag was not given to copy, does it now break apps ?
102 
103  ret->addChild( newmachine ); // also copy tree info to StateMachine !
104  newmachine->setParent( ret );
105  }
106 
107  // Copy the InitCommand :
108  if (this->getInitCommand()) {
109  ret->setInitCommand( this->getInitCommand()->copy(replacements) );
110  // test :
111  //ret->getInitCommand()->execute();
112  }
113 
114  // First make a copy of all states. All states are either
115  // known by their name or by a transition from or to them...
116  statemapping[0] = 0; // insert null element.
117  for ( TransitionMap::const_iterator i = stateMap.begin(); i != stateMap.end(); ++i )
118  {
119  if( statemapping.find( i->first ) == statemapping.end() && i->first != 0 ) {
120  StateInterface* cpy = i->first->copy( replacements );
121  ret->addState( cpy );
122  statemapping[i->first] = cpy;
123  }
124  }
125 
126  // next, copy the transitions
127  for ( TransitionMap::const_iterator i = stateMap.begin(); i != stateMap.end(); ++i )
128  {
129  assert( statemapping.find( i->first ) != statemapping.end() );
130  StateInterface* fromState = statemapping[i->first];
131  for ( TransList::const_iterator j = i->second.begin(); j != i->second.end(); ++j )
132  {
133  ConditionInterface* condition = j->get<0>()->copy( replacements );
134  assert( statemapping.find( j->get<1>() ) != statemapping.end() );
135  StateInterface* toState = statemapping[j->get<1>()];
136  int rank = j->get<2>();
137  int line = j->get<3>();
138  boost::shared_ptr<ProgramInterface> transprog( j->get<4>() );
139  if (transprog)
140  transprog.reset( j->get<4>()->copy(replacements) );
141  ret->transitionSet(fromState, toState, condition, transprog, rank, line );
142  }
143  }
144 
145  // next, copy/recreate the events
146  for ( EventMap::const_iterator i = eventMap.begin(); i != eventMap.end(); ++i )
147  {
148  assert( statemapping.find( i->first ) != statemapping.end() );
149  StateInterface* fromState = statemapping[i->first];
150  for ( EventList::const_iterator j = i->second.begin(); j != i->second.end(); ++j )
151  {
152  ServicePtr sp = j->get<0>();
153  string ename = j->get<1>();
154  vector<DataSourceBase::shared_ptr> origargs( j->get<2>() );
155  vector<DataSourceBase::shared_ptr> newargs;
156  for ( vector<DataSourceBase::shared_ptr>::const_iterator vit = origargs.begin();
157  vit != origargs.end(); ++vit)
158  newargs.push_back( (*vit)->copy(replacements) );
159  StateInterface* toState = statemapping[j->get<3>()];
160  ConditionInterface* condition = j->get<4>()->copy( replacements );
161  ProgramInterfacePtr tprog;
162  ProgramInterfacePtr tgraph( j->get<5>() );
163  if (tgraph)
164  tprog.reset( tgraph->copy(replacements) );
165  StateInterface* elseState = statemapping[j->get<7>()];
166  ProgramInterfacePtr eprog;
167  ProgramInterfacePtr egraph( j->get<8>() );
168  if (egraph)
169  eprog.reset( egraph->copy(replacements) );
170 #ifndef NDEBUG
171  bool eresult =
172 #endif
173  ret->createEventTransition(sp, ret->getService()->getOwner()->engine(), ename, newargs, fromState, toState, condition, tprog, elseState, eprog );
174  assert( eresult );
175  }
176  }
177 
178  // finally, copy the preconditions
179  for ( PreConditionMap::const_iterator i = precondMap.begin(); i != precondMap.end(); ++i )
180  {
181  assert( statemapping.find( i->first ) != statemapping.end() );
182  StateInterface* tgtState = statemapping[i->first];
183  ConditionInterface* condition = i->second.first->copy( replacements );
184  int line = i->second.second;
185  ret->preconditionSet( tgtState, condition, line );
186  }
187 
188  // init the StateMachine itself :
189  ret->setFinalState( statemapping[ getFinalState() ]);
190  ret->setInitialState( statemapping[ getInitialState() ]);
191 
192  return ret;
193  }
194 
196  this->smStatus = Status::unloaded;
197  if ( this->isLoaded() ){
198  getEngine()->removeFunction(this);
199  }
200 
201  // we own our states...
202  for ( TransitionMap::iterator i = stateMap.begin();
203  i != stateMap.end(); ++i )
204  delete i->first;
205  // we own our conditions...
206  for ( TransitionMap::iterator i = stateMap.begin();
207  i != stateMap.end(); ++i )
208  for ( TransList::iterator i2 = i->second.begin(); i2 != i->second.end(); ++i2 )
209  delete get<0>( *i2 ); // delete the condition.
210 
211  // we own our event guards...
212  for ( EventMap::iterator i = eventMap.begin();
213  i != eventMap.end(); ++i )
214  for ( EventList::iterator i2 = i->second.begin(); i2 != i->second.end(); ++i2 )
215  delete get<4>( *i2 ); // delete the condition.
216 
217  }
218 
220  : StateMachine( StateMachinePtr() ) // no parent, no task
221  {
222  _text.reset( new string("No Text Set.") );
223  }
224 
226  {
228  // just kill off the interface.
229  if ( !object )
230  return;
231  if ( object->getParent() && object->getParent()->hasService( object->getName() ) ){
232  assert( object == object->getParent()->getService( object->getName() ) );
233  object->getParent()->removeService( object->getName() );
234  }
235  object.reset();
236  }
237 
238  void ParsedStateMachine::addParameter( const std::string& name, AttributeBase* var )
239  {
240  assert( parametervalues.find( name ) == parametervalues.end() );
241  parametervalues[name] = var;
242  // every parameter is also a readonly var...
243  // visiblereadonlyvalues[name] = var->toDataSource();
244  }
245 
246  AttributeBase* ParsedStateMachine::getParameter( const std::string& name ) const
247  {
248  if( parametervalues.find( name ) == parametervalues.end() )
249  return 0;
250  return parametervalues.find(name)->second;
251  }
252 
254  {
255  return parametervalues;
256  }
257 
258  std::vector<std::string> ParsedStateMachine::getParameterNames() const
259  {
260  return keys( parametervalues );
261  }
262 
263  void ParsedStateMachine::setName( const std::string& name, bool recursive )
264  {
265  // XXX BIG NOTE :
266  // this function should me named 'instantiate' or so because it does more than
267  // settting the name, it also recursively arranges names of children and
268  // sets the parent-child TC connections. Reed the 'recursive' flag as 'instantiate'.
269  // it is used only recursively for instantiating root contexts.
270  //cerr << "Setting name "<< _name << " to " << name<<" rec: "<<recursive<<endl;
271  // set the StateMachine name
272  this->_name = name;
273  // set the datasource's name
274  //nameds->set( name );
275 
276  if ( recursive == false )
277  return;
278  //this->getService()->addPeer( this->getService()->getPeer("states")->getPeer("task") );
279  for ( ChildList::const_iterator i = getChildren().begin(); i != getChildren().end(); ++i )
280  {
281  std::string subname = name + "." + (*i)->getName();
282  ParsedStateMachine* psc = static_cast<ParsedStateMachine*>( i->get() );
283  psc->setName( subname, true );
284  // we own our child:
285  psc->getService()->setOwner( 0 );
286  this->getService()->addService( psc->getService() );
287  }
288  }
289 
290  std::string ParsedStateMachine::getText() const
291  {
292  return *_text;
293  }
294 
295  void ParsedStateMachine::setText( std::string text)
296  {
297  *_text = text;
298  }
299 
301  return object;
302  }
304  object = tc;
305  }
306 
307  bool ParsedStateMachine::inState( const std::string& name ) {
308  StateInterface* copy = this->currentState();
309  if (copy == 0)
310  return false;
311  return copy->getName() == name;
312  }
313 
315  {
316  }
317 
318 }
bool inState(const std::string &name)
A hierarchical StateMachine which is loaded in the Program Processor.
std::map< std::string, base::AttributeBase * > VisibleWritableValuesMap
boost::shared_ptr< StateMachineService > StateMachineServicePtr
boost::shared_ptr< ParsedStateMachine > ParsedStateMachinePtr
void setName(const std::string &name, bool recursive)
This interface represents the concept of a condition which can be evaluated and return true or false...
Definition: mystd.hpp:163
virtual const std::string & getName() const =0
Get the name of this state.
virtual ConditionInterface * copy(std::map< const base::DataSourceBase *, base::DataSourceBase * > &alreadyCloned) const
boost::shared_ptr< ProgramInterface > ProgramInterfacePtr
std::vector< std::string > getParameterNames() const
VisibleWritableValuesMap parametervalues
void addParameter(const std::string &name, base::AttributeBase *var)
void setService(boost::shared_ptr< StateMachineService > tc)
boost::shared_ptr< StateMachineService > object
boost::shared_ptr< Service > ServicePtr
Definition: rtt-fwd.hpp:86
boost::shared_ptr< StateMachineService > getService() const
StateInterface * currentState() const
static std::ostream & endl(std::ostream &__os)
Definition: Logger.cpp:383
ParsedStateMachinePtr copy(std::map< const base::DataSourceBase *, base::DataSourceBase * > &replacements, bool instantiate=false) const
boost::shared_ptr< StateMachine > StateMachinePtr
virtual StateInterface * copy(std::map< const base::DataSourceBase *, base::DataSourceBase * > &replacementdss) const =0
std::vector< typename MapT::key_type > keys(const MapT &map)
Definition: mystd.hpp:151
void addChild(StateMachinePtr child)
boost::shared_ptr< std::string > _text
static Logger & log()
Definition: Logger.cpp:117
base::AttributeBase * getParameter(const std::string &name) const
VisibleWritableValuesMap getParameters() const
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
Definition: Activity.cpp:53
const ChildList & getChildren() const


rtt
Author(s): RTT Developers
autogenerated on Tue Jun 25 2019 19:33:26