I've already played with the Statechart library. I think it's a good library but especially the fact that transitions take such a long time isn't good in many situations like embedded systems for instance. Of course Statechart has it's entitlement I think for you the new MSM library (currently in review progress) is worth a look. State machines build with MSM have very low overhead and are therefore very efficient. I've taken a simple example to this mail. On my machine the state machine with MSM is about 34 times faster than the one with Statechart. Conoscenza Silente schrieb:
Hi All Yesterday I started playing with Boost State Chart library implementing state machines for my applications. Each time I am moving into a new state I noticed that a new state is created; this means that the constructor of the boost::statechart::state class is called each time ( and the destructor for the state that I am leaving ).
I would like to fasten up the whole process; let's say that I would like to avoid the creation/destruction of the class each time using object already allocated in memory that are deleted only at the exit of the application. Is this a good way in your opinion ?
I saw that there is an allocator template argument but at the state where I am now I would lilke to not spend time in doing a new allocator for that: do you know if there already in place something that I can reuse for my purpose?
Thanks CS _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
#include <boost/statechart/simple_state.hpp> #include <boost/statechart/state_machine.hpp> #include <boost/statechart/event.hpp> #include <boost/statechart/transition.hpp> #include <boost/timer.hpp> #include <boost/progress.hpp> #include <boost/pool/pool_alloc.hpp> #include <boost/msm/back/state_machine.hpp> #include <boost/msm/front/state_machine_def.hpp> using namespace boost::statechart; namespace test_sc { struct state_1; struct state_2; struct state_3; struct state_4; struct main_machine : state_machine< main_machine, state_1 // without allocator I have 5.6 seconds (used also in events) //,boost::pool_allocator< main_machine > // with this // allocator I go to 10 sec used also in events //,boost::fast_pool_allocator< main_machine > // with this //allocator I go to 8.7 sec > {}; struct event_1_2 : event< event_1_2 //, boost::fast_pool_allocator< event_1_2 >
{}; struct event_2_3 : event< event_2_3 //, boost::fast_pool_allocator< event_2_3 > {}; struct event_3_4 : event< event_3_4 //, boost::fast_pool_allocator< event_3_4 > {}; struct event_4_1 : event< event_4_1 //, boost::fast_pool_allocator< event_4_1 > {};
struct state_1 : simple_state< state_1, main_machine > { typedef transition< event_1_2, state_2 > reactions; }; struct state_2 : simple_state< state_2, main_machine > { typedef transition< event_2_3, state_3 > reactions; }; struct state_3 : simple_state< state_3, main_machine > { //typedef transition< event_3_4, state_4 > arc; // it doesn't work typedef transition< event_3_4, state_4 > reactions; //state_3(){std::cout<<"3";} //~state_3(){std::cout<<"~3";} }; struct state_4 : simple_state< state_4, main_machine > { typedef transition< event_4_1, state_1 > reactions; }; } namespace msm = boost::msm; namespace mpl = boost::mpl; namespace test_msm // Concrete FSM implementation { struct event_1_2 {}; struct event_2_3 {}; struct event_3_4 {}; struct event_4_1 {}; // Concrete FSM implementation struct main_machine_ : public msm::front::state_machine_def<main_machine_> { // no need for exception handling or message queue typedef int no_exception_thrown; typedef int no_message_queue; // The list of FSM states struct state_1 : public msm::front::state<> { // optional entry/exit methods //template <class Event,class FSM> //void on_entry(Event const&,FSM& ) {std::cout << "entering: state_1" << std::endl;} //template <class Event,class FSM> //void on_exit(Event const&,FSM& ) {std::cout << "leaving: state_1" << std::endl;} }; struct state_2 : public msm::front::state<> { // optional entry/exit methods //template <class Event,class FSM> //void on_entry(Event const&,FSM& ) {std::cout << "entering: state_2" << std::endl;} //template <class Event,class FSM> //void on_exit(Event const&,FSM& ) {std::cout << "leaving: state_2" << std::endl;} }; struct state_3 : public msm::front::state<> { // optional entry/exit methods //template <class Event,class FSM> //void on_entry(Event const&,FSM& ) {std::cout << "entering: state_3" << std::endl;} //template <class Event,class FSM> //void on_exit(Event const&,FSM& ) {std::cout << "leaving: state_3" << std::endl;} }; struct state_4 : public msm::front::state<> { // optional entry/exit methods //template <class Event,class FSM> //void on_entry(Event const&,FSM& ) {std::cout << "entering: state_4" << std::endl;} //template <class Event,class FSM> //void on_exit(Event const&,FSM& ) {std::cout << "leaving: state_4" << std::endl;} }; // the initial state of the player SM. Must be defined typedef state_1 initial_state; struct transition_table : mpl::vector< // Start Event Next Action Guard // +---------+-------------+---------+---------------------+----------------------+ _row < state_1 , event_1_2 , state_2 >, _row < state_2 , event_2_3 , state_3 >, _row < state_3 , event_3_4 , state_4 >, _row < state_4 , event_4_1 , state_1 > // +---------+-------------+---------+---------------------+----------------------+ > {}; }; typedef msm::back::state_machine<main_machine_> main_machine; } void main(){ test_sc::main_machine fsm; fsm.initiate(); { boost::progress_timer t; // count the time elapsed // before distruction: not very precise // for expected big differences for( int i = 0; i < 1000000; i ++ ){ fsm.process_event( test_sc::event_1_2() ); fsm.process_event( test_sc::event_2_3() ); fsm.process_event( test_sc::event_3_4() ); fsm.process_event( test_sc::event_4_1() ); } } test_msm::main_machine fsm2; fsm2.start(); { boost::progress_timer t; // count the time elapsed // before distruction: not very precise // for expected big differences for( int i = 0; i < 1000000; i ++ ){ fsm2.process_event( test_msm::event_1_2() ); fsm2.process_event( test_msm::event_2_3() ); fsm2.process_event( test_msm::event_3_4() ); fsm2.process_event( test_msm::event_4_1() ); } } }