38 #include "../ExecutionEngine.hpp" 39 #include "../internal/DataSource.hpp" 40 #include "../Service.hpp" 46 #include <boost/bind.hpp> 47 #include <boost/tuple/tuple.hpp> 50 #define TRACE(msg) do { \ 53 Logger::In in( _name ); \ 54 log(Info) << '[' << this->getStatusStr() << ']' << std::string(" ") + msg <<endlog(); \ 58 using namespace detail;
59 using boost::tuples::get;
61 using namespace boost;
67 : smpStatus(nill), _parent (parent) , _name(name), smStatus(
Status::unloaded),
68 initstate(0), finistate(0), current( 0 ), next(0), initc(0),
69 currentProg(0), currentExit(0), currentHandle(0), currentEntry(0), currentRun(0), currentTrans(0),
70 checking_precond(false), mstep(false), mtrace(false), evaluating(0)
81 TRACE(
"StateMachine '" +
_name +
"' destroyed." );
85 TRACE(
"Being Loaded in ExecutionEngine." );
87 for(TransitionMap::iterator it=
stateMap.begin(); it !=
stateMap.end(); ++it) {
92 for(TransList::iterator tlit= it->second.begin(); tlit != it->second.end(); ++tlit ) {
94 get<4>(*tlit)->loaded( this->getEngine() );
100 for(EventList::iterator tlit= it->second.begin(); tlit != it->second.end(); ++tlit ) {
102 get<5>(*tlit)->loaded( this->getEngine() );
108 TRACE(
"Being unloaded from ExecutionEngine." );
119 <<
" into the final state. Program stalled in state '" 157 return "deactivating";
175 TRACE(
"Will pause." );
183 TRACE(
"Won't pause." );
190 TRACE(
"Will step." );
195 TRACE(
"Will step." );
199 TRACE(
"Won't step." );
214 TRACE(
"Will start." );
220 TRACE(
"Won't start." );
227 TRACE(
"Will enter reactive mode." );
231 TRACE(
"Won't enter reactive mode." );
238 TRACE(
"Will stop." );
242 TRACE(
"Won't stop." );
250 TRACE(
"Will reset.");
254 TRACE(
"Won't reset.");
271 TRACE(
"Is paused now.");
283 TRACE(
"Is stopped now.");
296 TRACE(
"Is reset now.");
316 TRACE(
"Is active now.");
325 TRACE(
"Yielding...");
338 TRACE(
"Did a step.");
348 TRACE(
"Is active now.");
354 TRACE(
"Is stopped now.");
359 TRACE(
"Is inactive now.");
364 TRACE(
"Is reset now.");
382 TRACE(
"Will enter initial state.");
387 TRACE(
"Won't enter initial state.");
396 TRACE(
"Won't enter final state.");
402 TRACE(
"Will enter final state.");
405 TRACE(
"Won't enter final state.");
416 if (transProg->
start() == false )
443 if ( transProg->
start() == false )
476 EventMap::mapped_type& hlist =
eventMap[s];
477 for (EventList::iterator eit = hlist.begin();
480 assert( get<6>(*eit).connected() == false );
481 get<6>(*eit).connect();
490 EventMap::mapped_type& hlist =
eventMap[s];
491 for (EventList::iterator eit = hlist.begin();
494 assert( get<6>(*eit).connected() == true );
495 get<6>(*eit).disconnect();
501 const std::string& ename, vector<DataSourceBase::shared_ptr> args,
504 StateInterface* elseto, boost::shared_ptr<ProgramInterface> elseprog )
506 Logger::In in(
"StateMachine::createEventTransition");
510 log(
Error) <<
"Can not receive event '"<< ename <<
"' in StateMachine : not a local operation."<<
endlog();
514 if ( !( sp && guard ) ) {
515 log(
Error) <<
"Invalid arguments for event '"<< ename <<
"'. ";
517 log() <<
"Service was null. ";
519 log() <<
"Guard Condition was null. ";
541 log(
Debug) <<
"Creating Signal handler for Operation '"<< ename <<
"' from state "<< (from ? from->
getName() : string(
"(global)")) <<
" to state " << ( to ? to->
getName() : string(
"(global)") ) <<
Logger::endl;
542 #ifdef ORO_SIGNALLING_OPERATIONS 544 handle = sp->produceSignal( ename,
new CommandFunction( boost::bind( &
StateMachine::eventTransition,
this, from, guard, transprog.get(), to, elseprog.get(), elseto) ), args, 0 );
546 if ( !handle.ready() ) {
554 eventMap[from].push_back( boost::make_tuple( sp, ename, args, to, guard, transprog, handle, elseto, elseprog) );
599 " within state " +
current->
getName() +
": preconditions failed.");
628 TransList::const_iterator it, it1, it2;
629 it1 =
stateMap.find( 0 )->second.begin();
630 it2 =
stateMap.find( 0 )->second.end();
633 for ( it= it1; it != it2; ++it)
634 get<0>(*it)->reset();
638 for ( ; it1 != it2; ++it1 )
639 if ( get<0>(*it1)->evaluate()
656 if ( get<0>(*reqstep)->evaluate() ) {
673 for ( ; it1 != it2; ++it1 ) {
674 if ( get<0>(*it1)->evaluate() &&
checkConditions( get<1>(*it1) ) == 1 ) {
694 }
while ( !stepping );
715 if (
prec_it.first->second.first->evaluate() == false ) {
738 TransList::const_iterator it1, it2;
742 for ( ; it1 != it2; ++it1 )
743 if ( get<0>(*it1)->evaluate() &&
checkConditions( get<1>(*it1)) == 1 ) {
748 it1 =
stateMap.find( 0 )->second.begin();
749 it2 =
stateMap.find( 0 )->second.end();
751 for ( ; it1 != it2; ++it1 )
752 if ( get<0>(*it1)->evaluate() &&
checkConditions( get<1>(*it1)) == 1 ) {
760 vector<string> result;
761 vector<StateInterface*> sl;
764 sl.erase( find(sl.begin(), sl.end(), dummy) );
777 TransitionMap::const_iterator it =
stateMap.begin();
779 if ( it->first && it->first->getName() == name )
808 TransList::iterator it, it1, it2;
812 for ( ; it1 != it2; ++it1 )
813 if ( get<1>(*it1) == s_n
814 && get<0>(*it1)->evaluate()
823 it1 =
stateMap.find( 0 )->second.begin();
824 it2 =
stateMap.find( 0 )->second.end();
827 for ( it= it1; it != it2; ++it)
828 get<0>(*it)->reset();
831 for ( ; it1 != it2; ++it1 )
832 if ( get<1>(*it1) == s_n
833 && get<0>(*it1)->evaluate()
866 if ( statecopy == 0 )
887 precondMap.insert( make_pair(state, make_pair( cnd, line)) );
893 this->
transitionSet( from, to, cnd, boost::shared_ptr<ProgramInterface>(), priority, line);
898 int priority,
int line )
907 TRACE(
"Created global transition to '"+ to->
getName()+
"'");
910 TransList::iterator it;
911 for ( it=
stateMap[from].begin(); it !=
stateMap[from].end() && get<2>(*it) >= priority; ++it)
913 stateMap[from].insert(it, boost::make_tuple( cnd, to, priority, line, transprog ) );
967 TransList::iterator it;
968 for ( it=
stateMap.find(s)->second.begin(); it !=
stateMap.find(s)->second.end(); ++it)
969 get<0>(*it)->reset();
1164 TRACE(
"Won't activate: already active.");
1172 TRACE(
"Won't activate: preconditions failed.");
1180 TRACE(
"Won't activate: Init Commands failed.");
1199 TRACE(
"Activated.");
1202 TRACE(
"Still activating.");
1216 TRACE(
"Won't deactivate: already inactive.");
1250 TRACE(
"Deactivated.");
1253 TRACE(
"Still deactivating.");
bool executePending(bool stepping=false)
void transitionSet(StateInterface *from, StateInterface *to, ConditionInterface *cnd, int priority, int line)
ActivityInterface * getActivity() const
Query for the task this interface is run in.
virtual bool removeFunction(base::ExecutableInterface *f)
TransList::iterator reqend
ProgramInterface * currentHandle
void disableGlobalEvents()
ProgramInterface * currentEntry
std::vector< std::string > getStateList() const
void enableEvents(StateInterface *s)
This interface represents the concept of a condition which can be evaluated and return true or false...
bool interruptible() const
const std::string & getName() const
ProgramInterface * currentRun
virtual void readArguments()=0
virtual int getEntryPoint() const =0
std::string getStatusStr() const
virtual const std::string & getName() const =0
Get the name of this state.
void setFinalState(StateInterface *s)
os::MutexRecursive execlock
enum RTT::scripting::StateMachine::PrivateStatus smpStatus
void disableEvents(StateInterface *s)
void preconditionSet(StateInterface *state, ConditionInterface *cnd, int line)
virtual ProgramInterface * getEntryProgram() const =0
boost::shared_ptr< OperationCallerInterface > shared_ptr
static std::string emptyString
ProgramInterface * currentProgram() const
virtual ProgramInterface * getHandleProgram() const =0
StateInterface * nextState()
void enableGlobalEvents()
int getLineNumber() const
void handleState(StateInterface *s)
Status::StateMachineStatus getStatus() const
boost::shared_ptr< Service > ServicePtr
void addState(StateInterface *s)
virtual int getLineNumber() const =0
ProgramInterface * currentExit
StateInterface * currentState() const
Status::StateMachineStatus smStatus
static std::ostream & endl(std::ostream &__os)
bool executeProgram(ProgramInterface *&cp, bool stepping)
boost::shared_ptr< StateMachine > StateMachinePtr
void changeState(StateInterface *s, ProgramInterface *tprog, bool stepping=false)
boost::shared_ptr< DisposableInterface > shared_ptr
StateInterface * getInitialState() const
ExecutionEngine * getEngine()
std::pair< PreConditionMap::const_iterator, PreConditionMap::const_iterator > prec_it
PreConditionMap precondMap
virtual ProgramInterface * getExitProgram() const =0
void runState(StateInterface *s)
bool requestInitialState()
virtual ProgramInterface * getRunProgram() const =0
StateInterface * getState(const std::string &name) const
virtual bool evaluate()=0
Evaluate the Condition and return the outcome.
base::ActionInterface * initc
StateInterface * requestNextState(bool stepping=false)
bool eventTransition(StateInterface *from, ConditionInterface *c, ProgramInterface *p, StateInterface *to, ProgramInterface *elsep, StateInterface *elseto)
StateInterface * finistate
void setInitialState(StateInterface *s)
int checkConditions(StateInterface *state, bool stepping=false)
TransList::iterator reqstep
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
A Program represents a collection of instructions that can be stepwise executed.
bool requestStateChange(StateInterface *s_n)
StateInterface * getFinalState() const
StateInterface * initstate
The Handle holds the information, and allows manipulation, of a connection between a internal::Signal...
bool inTransition() const
StateMachine(StateMachinePtr parent, const std::string &name="Default")
static Logger::LogFunction endlog()
ProgramInterface * currentProg
void enterState(StateInterface *s)
ProgramInterface * currentTrans
void leaveState(StateInterface *s)
MutexLock is a scope based Monitor, protecting critical sections with a Mutex object through locking ...
bool createEventTransition(ServicePtr sp, ExecutionEngine *target_engine, const std::string &ename, std::vector< base::DataSourceBase::shared_ptr > args, StateInterface *from, StateInterface *to, ConditionInterface *guard, boost::shared_ptr< ProgramInterface > transprog, StateInterface *elseto=0, boost::shared_ptr< ProgramInterface > elseprog=boost::shared_ptr< ProgramInterface >())
virtual std::string getText() const