|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r50886 - in sandbox/msm: boost/msm libs/msm/doc
From: christophe.j.henry_at_[hidden]
Date: 2009-01-29 18:03:37
Author: chenry
Date: 2009-01-29 18:03:36 EST (Thu, 29 Jan 2009)
New Revision: 50886
URL: http://svn.boost.org/trac/boost/changeset/50886
Log:
- simple FSM compile with gcc 3.3
- FSMs with composites or small size compile but do not work completely (events inside a composite lead to no_transition)
- test version of visitable states added (need new policy in state_machine)
Added:
sandbox/msm/boost/msm/visitable_policies.hpp (contents, props changed)
Text files modified:
sandbox/msm/boost/msm/metafunctions.hpp | 5
sandbox/msm/boost/msm/state_machine.hpp | 162 +++++++++++++++++++++++----------------
sandbox/msm/libs/msm/doc/SM.cpp | 45 +++++++++-
sandbox/msm/libs/msm/doc/index.html | 8 +
4 files changed, 145 insertions(+), 75 deletions(-)
Modified: sandbox/msm/boost/msm/metafunctions.hpp
==============================================================================
--- sandbox/msm/boost/msm/metafunctions.hpp (original)
+++ sandbox/msm/boost/msm/metafunctions.hpp 2009-01-29 18:03:36 EST (Thu, 29 Jan 2009)
@@ -30,6 +30,7 @@
BOOST_MPL_HAS_XXX_TRAIT_DEF(pseudo_entry)
BOOST_MPL_HAS_XXX_TRAIT_DEF(pseudo_exit)
BOOST_MPL_HAS_XXX_TRAIT_DEF(concrete_exit_state)
+BOOST_MPL_HAS_XXX_TRAIT_DEF(composite_tag)
namespace boost { namespace msm
{
@@ -178,8 +179,8 @@
template <class State>
struct is_composite_state
{
- enum {value = State::is_composite_tag::value};
- typedef typename State::is_composite_tag type;
+ enum {value = has_composite_tag<State>::type::value};
+ typedef typename has_composite_tag<State>::type type;
};
// transform a transition table in a container of source states
Modified: sandbox/msm/boost/msm/state_machine.hpp
==============================================================================
--- sandbox/msm/boost/msm/state_machine.hpp (original)
+++ sandbox/msm/boost/msm/state_machine.hpp 2009-01-29 18:03:36 EST (Thu, 29 Jan 2009)
@@ -46,6 +46,7 @@
#include <boost/msm/history_policies.hpp>
#include <boost/msm/bind_helpers.hpp>
#include <boost/msm/copy_policies.hpp>
+#include <boost/msm/visitable_policies.hpp>
namespace mpl = boost::mpl;
@@ -56,7 +57,6 @@
namespace boost { namespace msm
{
-
// the interface for all states. Defines entry and exit functions. Overwrite to implement for any state needing it.
struct state_base
{
@@ -67,6 +67,8 @@
#else
~state_base() {}
#endif
+ // used only in conjunction with the VisitableStates state_machine policy
+ void accept(VisitorBase&){}
// empty implementation for the states not wishing to define an entry condition
// will not be called polymorphic way
template <class Event>
@@ -105,7 +107,6 @@
struct state : public state_base, SMPtrPolicy
{
// tags
- typedef mpl::bool_<false> is_composite_tag;
// default: no flag
typedef mpl::vector<> flag_list;
//default: no deferred events
@@ -131,7 +132,6 @@
struct terminate_state : public state_base, SMPtrPolicy
{
// tags
- typedef mpl::bool_<false> is_composite_tag;
typedef mpl::vector<boost::msm::TerminateFlag> flag_list;
//default: no deferred events
typedef mpl::vector<> deferred_events;
@@ -151,7 +151,6 @@
struct interrupt_state : public state_base, SMPtrPolicy
{
// tags
- typedef mpl::bool_<false> is_composite_tag;
typedef mpl::vector<boost::msm::InterruptedFlag,
boost::msm::EndInterruptFlag<EndInterruptEvent> >
flag_list;
@@ -193,7 +192,6 @@
: public state_base, explicit_entry<Composite,ZoneIndex> ,SMPtrPolicy
{
// tags
- typedef mpl::bool_<false> is_composite_tag;
typedef int pseudo_entry;
// default: no flag
typedef mpl::vector<> flag_list;
@@ -216,7 +214,6 @@
struct exit_pseudo_state : public state_base , SMPtrPolicy
{
// tags
- typedef mpl::bool_<false> is_composite_tag;
typedef int pseudo_exit;
typedef int no_automatic_create;
typedef Composite owner;
@@ -293,13 +290,13 @@
};
// forward declaration
-template<class Derived,class HistoryPolicy,class CopyPolicy>
+template<class Derived,class HistoryPolicy,class VisitablePolicy,class CopyPolicy>
class state_machine;
// Generates a singleton runtime lookup table that maps current state
// to a function that makes the SM take its transition on the given
// Event type.
-template <class Fsm, class HistoryPolicy, class CopyPolicy,class Stt, class Event>
+template <class Fsm, class HistoryPolicy,class VisitablePolicy, class CopyPolicy,class Stt, class Event>
struct dispatch_table
{
private:
@@ -398,7 +395,7 @@
{
typedef typename create_stt<Fsm>::type stt;
BOOST_STATIC_CONSTANT(int, state_id = (get_state_id<stt,State>::value));
- cell call_no_transition = &state_machine<Fsm,HistoryPolicy,CopyPolicy>::call_no_transition;
+ cell call_no_transition = &state_machine<Fsm,HistoryPolicy,VisitablePolicy,CopyPolicy>::call_no_transition;
tofill_entries[state_id] = call_no_transition;
}
template <class State>
@@ -407,7 +404,7 @@
{
typedef typename create_stt<Fsm>::type stt;
BOOST_STATIC_CONSTANT(int, state_id = (get_state_id<stt,State>::value));
- cell call_no_transition = &state_machine<Fsm,HistoryPolicy,CopyPolicy>::defer_transition;
+ cell call_no_transition = &state_machine<Fsm,HistoryPolicy,VisitablePolicy,CopyPolicy>::defer_transition;
tofill_entries[state_id] = call_no_transition;
}
dispatch_table* self;
@@ -470,30 +467,32 @@
// This declares the statically-initialized dispatch_table instance.
-template <class Fsm, class HistoryPolicy, class CopyPolicy,class Stt, class Event>
-const dispatch_table<Fsm, HistoryPolicy,CopyPolicy,Stt, Event>
-dispatch_table<Fsm, HistoryPolicy,CopyPolicy,Stt, Event>::instance;
+template <class Fsm, class HistoryPolicy,class VisitablePolicy, class CopyPolicy,class Stt, class Event>
+const dispatch_table<Fsm, HistoryPolicy,VisitablePolicy,CopyPolicy,Stt, Event>
+dispatch_table<Fsm, HistoryPolicy,VisitablePolicy,CopyPolicy,Stt, Event>::instance;
// CRTP base class for state machines. Pass the actual FSM class as
// the Derived parameter.
-template<class Derived,class HistoryPolicy=NoHistory,class CopyPolicy=NoCopy>
-class state_machine : public state_base, CopyPolicy
+template<class Derived,class HistoryPolicy=NoHistory,
+ class VisitablePolicy=NotVisitableStates, class CopyPolicy=NoCopy>
+class state_machine : public state_base,public VisitablePolicy,CopyPolicy
{
private:
typedef boost::function<
- execute_return ()> transition_fct;
+ execute_return ()> transition_fct;
typedef boost::function<
- execute_return () > deferred_fct;
- typedef std::queue<deferred_fct > deferred_events_queue_t;
- typedef std::queue<transition_fct > events_queue_t;
- typedef bool (*flag_handler)(state_machine<Derived,HistoryPolicy,CopyPolicy>&);
+ execute_return () > deferred_fct;
+ typedef std::queue<deferred_fct > deferred_events_queue_t;
+ typedef std::queue<transition_fct > events_queue_t;
+ typedef bool (*flag_handler)(state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>&);
// all state machines are friend with each other to allow embedding any of them in another fsm
- template <class ,class ,class > friend class state_machine;
+ template <class ,class ,class,class > friend class state_machine;
public:
// tags
- typedef mpl::bool_<true> is_composite_tag;
+ typedef int composite_tag;
+
// default: no flag
typedef mpl::vector0<> flag_list;
//default: no deferred events
@@ -530,7 +529,7 @@
// extend the table with tables from composite states
typedef typename extend_table<Derived>::type complete_table;
// use this table as if it came directly from the user
- typedef dispatch_table<Derived,HistoryPolicy,CopyPolicy,complete_table,Event> table;
+ typedef dispatch_table<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy,complete_table,Event> table;
HandledEnum ret_handled=HANDLED_FALSE;
// if the state machine is terminated, do not handle any event
@@ -545,8 +544,8 @@
if (m_event_processing)
{
// event has to be put into the queue
- execute_return (state_machine<Derived,HistoryPolicy,CopyPolicy>::*pf) (Event const& evt) =
- &state_machine<Derived,HistoryPolicy,CopyPolicy>::process_event;
+ execute_return (state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>::*pf) (Event const& evt) =
+ &state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>::process_event;
transition_fct f = boost::bind(pf,this,evt);
m_events_queue.push(f);
return boost::make_tuple(HANDLED_TRUE,&this->m_states);
@@ -664,8 +663,8 @@
boost::bind(boost::apply<bool>(),
boost::bind(deref<flag_handler>(),
boost::bind(plus2<flag_handler*,int>(),
- flags_entries, ::_2)),
- boost::ref(*this)), ::_1));
+ flags_entries, _2)),
+ boost::ref(*this)), _1));
}
// checks if a flag is active using no binary op if 1 region, or OR if > 1 regions
template <class Flag>
@@ -674,10 +673,19 @@
typedef typename get_number_of_regions<typename Derived::initial_state>::type nr_regions;
return FlagHelper<Flag,(nr_regions::value>1)>::helper(*this,get_entries_for_flag<Flag>());
}
-
+ // visit the currently active states (if these are defined as visitable
+ // by implementing accept)
+ void visit_current_states(VisitorBase& vis)
+ {
+ typedef typename get_number_of_regions<typename Derived::initial_state>::type nr_regions;
+ for (int i=0; i<nr_regions::value;++i)
+ {
+ VisitablePolicy::execute(m_states[i],vis);
+ }
+ }
protected: // interface for the derived class
typedef std::vector<pstate_base> pstate_base_list;
-
+
// helper used to fill the initial states
struct init_states
{
@@ -694,13 +702,16 @@
};
// Construct with the default initial states
state_machine()
- : m_states(),
- m_events_queue() ,
- m_deferred_events_queue(),
- m_history(),
- m_state_list(),
- m_event_processing(false),
- m_is_included(false)
+ :state_base()
+ ,VisitablePolicy()
+ ,CopyPolicy()
+ ,m_states()
+ ,m_events_queue()
+ ,m_deferred_events_queue()
+ ,m_history()
+ ,m_state_list()
+ ,m_event_processing(false)
+ ,m_is_included(false)
{
typedef typename get_number_of_regions<typename Derived::initial_state>::type nr_regions;
m_states.reserve(nr_regions::value);
@@ -711,18 +722,22 @@
initial_states, boost::msm::wrap<mpl::placeholders::_1>
>(init_states(m_states));
m_history.set_initial_states(m_states);
+ // create states
fill_states(this);
}
// template constructor. Needed only for sub-fsms having exit pseudo states.
template <class ContainingSM>
state_machine(ContainingSM* containing_sm)
- : m_states(),
- m_events_queue() ,
- m_deferred_events_queue(),
- m_history(),
- m_state_list(),
- m_event_processing(false),
- m_is_included(true)
+ :state_base()
+ ,VisitablePolicy()
+ ,CopyPolicy()
+ ,m_states()
+ ,m_events_queue()
+ ,m_deferred_events_queue()
+ ,m_history()
+ ,m_state_list()
+ ,m_event_processing(false)
+ ,m_is_included(true)
{
typedef typename get_number_of_regions<typename Derived::initial_state>::type nr_regions;
m_states.reserve(nr_regions::value);
@@ -733,10 +748,12 @@
initial_states, boost::msm::wrap<mpl::placeholders::_1>
>(init_states(m_states));
m_history.set_initial_states(m_states);
+ // create states
fill_states(containing_sm);
}
// assignment operator using the copy policy to decide if non_copyable, shallow or deep copying is necessary
- state_machine<Derived,HistoryPolicy,CopyPolicy>& operator= (state_machine<Derived,HistoryPolicy,CopyPolicy> const& rhs)
+ state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>& operator=
+ (state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy> const& rhs)
{
if (this != &rhs)
{
@@ -745,7 +762,8 @@
}
return *this;
}
- state_machine<Derived,HistoryPolicy,CopyPolicy> (state_machine<Derived,HistoryPolicy,CopyPolicy> const& rhs):CopyPolicy(rhs)
+ state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>
+ (state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy> const& rhs):CopyPolicy(rhs)
{
if (this != &rhs)
{
@@ -1039,7 +1057,7 @@
template <class Flag,bool orthogonalStates>
struct FlagHelper
{
- static bool helper(state_machine<Derived,HistoryPolicy,CopyPolicy>& sm,flag_handler* )
+ static bool helper(state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>& sm,flag_handler* )
{
// by default we use OR to accumulate the flags
return sm.is_flag_active<Flag,Flag_OR>();
@@ -1048,7 +1066,7 @@
template <class Flag>
struct FlagHelper<Flag,false>
{
- static bool helper(state_machine<Derived,HistoryPolicy,CopyPolicy>& sm,flag_handler* flags_entries)
+ static bool helper(state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>& sm,flag_handler* flags_entries)
{
// just one active state, so we can call operator[] with 0
return flags_entries[sm.current_state()[0]](sm);
@@ -1059,15 +1077,15 @@
template <class StateType,class Flag>
struct FlagHandler
{
- static bool flag_true(state_machine<Derived,HistoryPolicy,CopyPolicy>& )
+ static bool flag_true(state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>& )
{
return true;
}
- static bool flag_false(state_machine<Derived,HistoryPolicy,CopyPolicy>& )
+ static bool flag_false(state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>& )
{
return false;
}
- static bool forward(state_machine<Derived,HistoryPolicy,CopyPolicy>& fsm)
+ static bool forward(state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>& fsm)
{
typedef typename create_stt<Derived>::type stt;
return (static_cast<StateType& >
@@ -1141,7 +1159,7 @@
template <class State, class Enable=void>
struct create_state_helper
{
- static void set_sm(state_machine<Derived,HistoryPolicy,CopyPolicy>* ,pstate_base )
+ static void set_sm(state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>* ,pstate_base )
{
// state doesn't need its sm
}
@@ -1150,7 +1168,7 @@
template <class State>
struct create_state_helper<State,typename boost::enable_if<typename State::needs_sm >::type>
{
- static void set_sm(state_machine<Derived,HistoryPolicy,CopyPolicy>* sm,pstate_base new_state)
+ static void set_sm(state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>* sm,pstate_base new_state)
{
// create and set the fsm
static_cast<State*>(new_state.get())->set_sm_ptr(static_cast<Derived*>(sm));
@@ -1161,7 +1179,7 @@
template<class ContainingSM>
struct add_state
{
- add_state(state_machine<Derived,HistoryPolicy,CopyPolicy>* self_,ContainingSM* sm)
+ add_state(state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>* self_,ContainingSM* sm)
: self(self_),containing_sm(sm){}
// State is a sub fsm with exit pseudo states and gets a pointer to this fsm, so it can build a callback
@@ -1192,7 +1210,7 @@
execute_return (ContainingSM::*pf) (typename StateType::event const& evt)=
&ContainingSM::process_event;
boost::function<execute_return (typename StateType::event const&)> fct =
- boost::bind(pf,containing_sm,::_1);
+ boost::bind(pf,containing_sm,_1);
static_cast<StateType*>(to_return)->set_forward_fct(fct);
return to_return;
}
@@ -1207,16 +1225,20 @@
pstate_base new_state (this->new_state_helper<State>());
self->m_state_list[state_id]= new_state;
create_state_helper<State>::set_sm(self,new_state);
+ // create a visitor callback
+ self->insert(state_id,boost::bind(&State::accept,
+ static_cast<State*>(new_state.get()),_1) );
}
private:
- state_machine<Derived,HistoryPolicy,CopyPolicy>* self;
+ state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>* self;
ContainingSM* containing_sm;
};
// helper used to copy every state if needed
struct copy_helper
{
- copy_helper(pstate_base_list& to_fill,const pstate_base_list& rhs,state_machine<Derived,HistoryPolicy,CopyPolicy>* sm):
+ copy_helper(pstate_base_list& to_fill,const pstate_base_list& rhs,
+ state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>* sm):
m_tofill_states(to_fill),m_rhs(rhs),m_sm(sm){}
template <class StateType>
void operator()(boost::msm::wrap<StateType> const& )
@@ -1233,14 +1255,15 @@
}
pstate_base_list& m_tofill_states;
const pstate_base_list& m_rhs;
- state_machine<Derived,
- HistoryPolicy,CopyPolicy>* m_sm;
+ state_machine<Derived,HistoryPolicy,
+ VisitablePolicy,CopyPolicy>* m_sm;
};
// copy functions for shallow or deep copy (no need of a 3rd version for NoCopy as noncopyable handles it)
template <class IsShallowCopy>
typename boost::disable_if<typename IsShallowCopy::type,void >::type
- do_copy (state_machine<Derived,HistoryPolicy,CopyPolicy> const& rhs,boost::msm::dummy<0> = 0)
+ do_copy (state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy> const& rhs,
+ boost::msm::dummy<0> = 0)
{
// deep copy simply assigns the data
m_states = rhs.m_states;
@@ -1254,7 +1277,8 @@
}
template <class IsShallowCopy>
typename boost::enable_if<typename IsShallowCopy::type,void >::type
- do_copy (state_machine<Derived,HistoryPolicy,CopyPolicy> const& rhs,boost::msm::dummy<1> = 0)
+ do_copy (state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy> const& rhs,
+ boost::msm::dummy<1> = 0)
{
// shallow copy simply assigns the data
m_states = rhs.m_states;
@@ -1323,7 +1347,7 @@
// helper used to set the correct state as active state upon entry into a fsm
struct direct_event_start_helper
{
- direct_event_start_helper(state_machine<Derived,HistoryPolicy,CopyPolicy>* self_):self(self_){}
+ direct_event_start_helper(state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>* self_):self(self_){}
// this variant is for the standard case, entry due to activation of the containing FSM
template <class EventType>
typename boost::disable_if<typename has_direct_entry<EventType>::type,void>::type
@@ -1392,11 +1416,11 @@
}
private:
// helper for the fork case, does almost like the direct entry
- state_machine<Derived,HistoryPolicy,CopyPolicy>* self;
+ state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>* self;
template <class EventType>
struct fork_helper
{
- fork_helper(state_machine<Derived,HistoryPolicy,CopyPolicy>* self_,EventType const& evt_):
+ fork_helper(state_machine<Derived,HistoryPolicy,VisitablePolicy,CopyPolicy>* self_,EventType const& evt_):
helper_self(self_),helper_evt(evt_){}
template <class StateType>
void operator()(boost::msm::wrap<StateType> const& )
@@ -1409,7 +1433,8 @@
helper_self->m_states[StateType::zone_index] = state_id;
}
private:
- state_machine<Derived,HistoryPolicy,CopyPolicy>* helper_self;
+ state_machine<Derived,HistoryPolicy,
+ VisitablePolicy,CopyPolicy>* helper_self;
EventType const& helper_evt;
};
};
@@ -1574,6 +1599,7 @@
BOOST_STATIC_CONSTANT(int, max_state = (mpl::size<state_list>::value));
// allocate the place without reallocation
m_state_list.resize(max_state);
+ VisitablePolicy::fill_visitors(max_state);
mpl::for_each<
state_list,boost::msm::wrap<mpl::placeholders::_1>
>(add_state<ContainingSM>(this,containing_sm));
@@ -1601,6 +1627,11 @@
}
};
public:
+ template <class Composite,class Event>
+ struct make_frow
+ {
+ typedef frow<Composite,Event> type;
+ };
// gets the transition table from a composite and make from it a forwarding row
template <class Composite>
struct get_transition_table_as_frow
@@ -1612,6 +1643,7 @@
typedef typename mpl::fold<
all_events, mpl::vector<>,
mpl::push_back<mpl::placeholders::_1,
+ /*typename mpl::apply<make_frow<mpl::placeholders::_,mpl::placeholders::_>,Composite,mpl::placeholders::_2 >::type*/
frow<Composite,mpl::placeholders::_2> > >::type type;
};
@@ -1631,7 +1663,7 @@
>::type type;
};
private:
- template <class Fsm, class History, class Copy,class Stt, class Event>
+ template <class Fsm, class History,class Visitable, class Copy,class Stt, class Event>
friend struct dispatch_table;
template <typename T1,class Event> friend struct frow;
Added: sandbox/msm/boost/msm/visitable_policies.hpp
==============================================================================
--- (empty file)
+++ sandbox/msm/boost/msm/visitable_policies.hpp 2009-01-29 18:03:36 EST (Thu, 29 Jan 2009)
@@ -0,0 +1,71 @@
+#ifndef VISITABLE_POLICIES_H
+#define VISITABLE_POLICIES_H
+// Copyright 2008 Christophe Henry
+// henry UNDERSCORE christophe AT hotmail DOT com
+// This is an extended version of the state machine available in the boost::mpl library
+// Distributed under the same license as the original.
+// Copyright for the original version:
+// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
+// under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <vector>
+#include <boost/function.hpp>
+
+
+namespace boost { namespace msm
+{
+// base class for states wanting to be visited
+struct VisitorBase
+{
+ virtual ~VisitorBase(){}
+};
+
+ // dummy policy when visitable states are not desired
+ class NotVisitableStates
+ {
+ public:
+ NotVisitableStates(){}
+ protected:
+ void fill_visitors(int number_of_states)
+ {
+ }
+ template <class FCT>
+ void insert(int index,FCT fct)
+ {
+ }
+ void execute(int index,VisitorBase& vis)
+ {
+ }
+ };
+
+ // policy adding support of visitable states
+ class VisitableStates
+ {
+ public:
+ VisitableStates():m_state_visitors(){}
+ protected:
+ void fill_visitors(int number_of_states)
+ {
+ m_state_visitors.resize(number_of_states);
+ }
+ template <class FCT>
+ void insert(int index,FCT fct)
+ {
+ m_state_visitors[index]=fct;
+ }
+ void execute(int index,VisitorBase& vis)
+ {
+ m_state_visitors[index](vis);
+ }
+ private:
+ typedef boost::function<void (VisitorBase&)> visitor_fct;
+ typedef std::vector<visitor_fct> visitors;
+ visitors m_state_visitors;
+ };
+} } //boost::msm
+
+
+#endif //VISITABLE_POLICIES_H
Modified: sandbox/msm/libs/msm/doc/SM.cpp
==============================================================================
--- sandbox/msm/libs/msm/doc/SM.cpp (original)
+++ sandbox/msm/libs/msm/doc/SM.cpp 2009-01-29 18:03:36 EST (Thu, 29 Jan 2009)
@@ -41,8 +41,17 @@
player& m_player;
};
+ // an easy visitor
+ struct SomeVisitor: public VisitorBase
+ {
+ void visit_state(state_base* astate)
+ {
+ std::cout << "visiting state:" << typeid(*astate).name() << std::endl;
+ }
+ };
+
// Concrete FSM implementation
- struct player : public state_machine<player>
+ struct player : public state_machine<player,NoHistory,VisitableStates>
{
// The list of FSM states
struct Empty : public state<>
@@ -53,6 +62,10 @@
void on_entry(Event const& ) {std::cout << "entering: Empty" << std::endl;}
template <class Event>
void on_exit(Event const& ) {std::cout << "leaving: Empty" << std::endl;}
+ void accept(VisitorBase& vis)
+ {
+ static_cast<SomeVisitor*>(&vis)->visit_state(this);
+ }
};
struct Open : public state<>
{
@@ -62,6 +75,10 @@
void on_entry(Event const& ) {std::cout << "entering: Open" << std::endl;}
template <class Event>
void on_exit(Event const& ) {std::cout << "leaving: Open" << std::endl;}
+ void accept(VisitorBase& vis)
+ {
+ static_cast<SomeVisitor*>(&vis)->visit_state(this);
+ }
};
// a state needing a pointer to the containing state machine
// and using for this the non-default policy
@@ -82,7 +99,7 @@
// then it will remember the last active state and reactivate it
// also possible: AlwaysHistory, the last active state will always be reactivated
// or NoHistory, always restart from the initial state
- struct Playing : public state_machine<Playing,ShallowHistory<mpl::vector<end_pause> > >
+ struct Playing : public state_machine<Playing,ShallowHistory<mpl::vector<end_pause> >,VisitableStates >
{
// when playing, the CD is loaded and we are in either pause or playing (duh)
typedef mpl::vector2<PlayingPaused,CDLoaded> flag_list;
@@ -90,7 +107,12 @@
void on_entry(Event const& ) {std::cout << "entering: Playing" << std::endl;}
template <class Event>
void on_exit(Event const& ) {std::cout << "leaving: Playing" << std::endl;}
-
+ void accept(VisitorBase& vis)
+ {
+ static_cast<SomeVisitor*>(&vis)->visit_state(this);
+ // visit substates
+ visit_current_states(vis);
+ }
// The list of FSM states
// the Playing state machine contains a state which is himself a state machine
// so we have a SM containing a SM containing a SM
@@ -101,7 +123,10 @@
void on_entry(Event const& ) {std::cout << "starting: First song" << std::endl;}
template <class Event>
void on_exit(Event const& ) {std::cout << "finishing: First Song" << std::endl;}
-
+ void accept(VisitorBase& vis)
+ {
+ static_cast<SomeVisitor*>(&vis)->visit_state(this);
+ }
struct LightOn : public state<>
{
template <class Event>
@@ -345,7 +370,6 @@
std::cout << " -> " << state_names[p.current_state()[i]] << std::endl;
}
}
-
void test()
{
player p;
@@ -369,7 +393,12 @@
// go to Open, call on_exit on Empty, then action, then on_entry on Open
p.process_event(open_close()); pstate(p);
+ // visiting Paused and AllOk, but only Paused cares
+ SomeVisitor vis;
+ p.visit_current_states(vis);
p.process_event(open_close()); pstate(p);
+ // visiting Empty and AllOk, but only Empty cares
+ p.visit_current_states(vis);
p.process_event(cd_detected("louie, louie",p));
@@ -377,6 +406,9 @@
//p.process_event(play());
// at this point, Play is active, along FirstSong and LightOn
pstate(p);
+ // visiting Playing+Song1 and AllOk, but only Playing+Song1 care
+ p.visit_current_states(vis);
+
std::cout << "PlayingPaused active:" << std::boolalpha << p.is_flag_active<PlayingPaused>() << std::endl;//=> true
// call on_exit on LightOn,FirstSong,Play like stated in the UML spec.
// and of course on_entry on Paused and StartBlinking
@@ -392,6 +424,9 @@
p.process_event(NextSong());pstate(p);
// We are now in second song, Flag inactive
std::cout << "FirstSong active:" << std::boolalpha << p.is_flag_active<FirstSongPlaying>() << std::endl;//=> false
+ // visiting Playing+Song2 and AllOk, but only Playing cares
+ p.visit_current_states(vis);
+
p.process_event(NextSong());pstate(p);
// 2nd song active
p.process_event(PreviousSong());pstate(p);
Modified: sandbox/msm/libs/msm/doc/index.html
==============================================================================
--- sandbox/msm/libs/msm/doc/index.html (original)
+++ sandbox/msm/libs/msm/doc/index.html 2009-01-29 18:03:36 EST (Thu, 29 Jan 2009)
@@ -6,11 +6,12 @@
<META NAME="GENERATOR" CONTENT="OpenOffice.org 3.0 (Win32)">
<META NAME="CREATED" CONTENT="20080922;21044300">
<META NAME="CHANGEDBY" CONTENT="Christophe Henry">
- <META NAME="CHANGED" CONTENT="20090122;21533200">
+ <META NAME="CHANGED" CONTENT="20090130;5200">
<META NAME="Info 1" CONTENT="">
<META NAME="Info 2" CONTENT="">
<META NAME="Info 3" CONTENT="">
<META NAME="Info 4" CONTENT="">
+ <META NAME="CHANGEDBY" CONTENT="Christophe Henry">
<META NAME="CHANGEDBY" CONTENT="xtoff">
<META NAME="CHANGEDBY" CONTENT="xtoff">
<META NAME="CHANGEDBY" CONTENT="xtoff">
@@ -1920,7 +1921,8 @@
<P>gcc 3.3:</P>
<UL>
<LI><P>the simple test completes 3 times faster with Msm</P>
- <LI><P>the composite does unfortunately not compile with Msm</P>
+ <LI><P>the composite compile but does not work (events of composites
+ lead to no_transition)</P>
</UL>
<H1 CLASS="western" STYLE="margin-left: 0.66cm; text-indent: -0.83cm"><A NAME="8.Compilers|outline"></A>
Compilers</H1>
@@ -1929,7 +1931,7 @@
<LI><P>VC8,VC9, VC9SP1</P>
<LI><P>g++ 4.1 and g++ 4.2.3</P>
<LI><P>partially g++ 3.3 (only <A HREF="SC%20Simple.cpp">simple
- state machines</A> in Msm version 1.0)</P>
+ state machines</A>)</P>
</UL>
<H1 CLASS="western" STYLE="margin-left: 0.68cm; text-indent: -0.76cm"><A NAME="8.Limitations|outline"></A>
Limitations</H1>
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk