Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r51277 - sandbox/msm/libs/msm/doc
From: christophe.j.henry_at_[hidden]
Date: 2009-02-16 16:49:43


Author: chenry
Date: 2009-02-16 16:49:41 EST (Mon, 16 Feb 2009)
New Revision: 51277
URL: http://svn.boost.org/trac/boost/changeset/51277

Log:
doc changes
Text files modified:
   sandbox/msm/libs/msm/doc/CompositeTutorial.cpp | 70 +-
   sandbox/msm/libs/msm/doc/DirectEntryTutorial.cpp | 12
   sandbox/msm/libs/msm/doc/Flags.cpp | 70 +-
   sandbox/msm/libs/msm/doc/HarelWithEntry.cpp | 12
   sandbox/msm/libs/msm/doc/HarelWithoutEntry.cpp | 8
   sandbox/msm/libs/msm/doc/HarelWithoutEntryNoTemplateSM.cpp | 34
   sandbox/msm/libs/msm/doc/History.cpp | 70 +-
   sandbox/msm/libs/msm/doc/Orthogonal-deferred.cpp | 88 +-
   sandbox/msm/libs/msm/doc/SC | 2
   sandbox/msm/libs/msm/doc/SC | 178 +++---
   sandbox/msm/libs/msm/doc/SM-0arg.cpp | 872 +++++++++++++++++++-------------------
   sandbox/msm/libs/msm/doc/SM-1arg.cpp | 892 +++++++++++++++++++-------------------
   sandbox/msm/libs/msm/doc/SM-3arg.cpp | 892 +++++++++++++++++++-------------------
   sandbox/msm/libs/msm/doc/SM.cpp | 912 +++++++++++++++++++--------------------
   sandbox/msm/libs/msm/doc/SimpleTutorial.cpp | 40
   sandbox/msm/libs/msm/doc/index.html | 18
   16 files changed, 2080 insertions(+), 2090 deletions(-)

Modified: sandbox/msm/libs/msm/doc/CompositeTutorial.cpp
==============================================================================
--- sandbox/msm/libs/msm/doc/CompositeTutorial.cpp (original)
+++ sandbox/msm/libs/msm/doc/CompositeTutorial.cpp 2009-02-16 16:49:41 EST (Mon, 16 Feb 2009)
@@ -39,14 +39,14 @@
             // every (optional) entry/exit methods get the event passed.
             template <class Event>
             void on_entry(Event const& ) {std::cout << "entering: Empty" << std::endl;}
- template <class Event>
+ template <class Event>
             void on_exit(Event const& ) {std::cout << "leaving: Empty" << std::endl;}
         };
         struct Open : public state<>
         {
             template <class Event>
             void on_entry(Event const& ) {std::cout << "entering: Open" << std::endl;}
- template <class Event>
+ template <class Event>
             void on_exit(Event const& ) {std::cout << "leaving: Open" << std::endl;}
         };
 
@@ -55,7 +55,7 @@
             // when stopped, the CD is loaded
             template <class Event>
             void on_entry(Event const& ) {std::cout << "entering: Stopped" << std::endl;}
- template <class Event>
+ template <class Event>
             void on_exit(Event const& ) {std::cout << "leaving: Stopped" << std::endl;}
         };
 
@@ -67,31 +67,31 @@
             // when playing, the CD is loaded and we are in either pause or playing (duh)
             template <class Event>
             void on_entry(Event const& ) {std::cout << "entering: Playing" << std::endl;}
- template <class Event>
+ template <class Event>
             void on_exit(Event const& ) {std::cout << "leaving: Playing" << std::endl;}
 
             // The list of FSM states
             struct Song1 : public state<>
             {
                 template <class Event>
- 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 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;}
 
             };
             struct Song2 : public state<>
             {
                 template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: Second song" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: Second Song" << std::endl;}
+ void on_entry(Event const& ) {std::cout << "starting: Second song" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: Second Song" << std::endl;}
             };
             struct Song3 : public state<>
             {
                 template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: Third song" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: Third Song" << std::endl;}
+ void on_entry(Event const& ) {std::cout << "starting: Third song" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: Third Song" << std::endl;}
             };
             // the initial state. Must be defined
             typedef Song1 initial_state;
@@ -99,7 +99,7 @@
             void start_next_song(NextSong const&) { std::cout << "Playing::start_next_song\n"; }
             void start_prev_song(PreviousSong const&) { std::cout << "Playing::start_prev_song\n"; }
             // guard conditions
-
+
             // friend definition needed.
             friend class state_machine<Playing>;
             typedef Playing pl; // makes transition table cleaner
@@ -107,10 +107,10 @@
             struct transition_table : mpl::vector4<
                 // Start Event Next Action Guard
                 // +---------+-------------+---------+---------------------+----------------------+
- a_row < Song1 , NextSong , Song2 , &pl::start_next_song >,
- a_row < Song2 , PreviousSong, Song1 , &pl::start_prev_song >,
- a_row < Song2 , NextSong , Song3 , &pl::start_next_song >,
- a_row < Song3 , PreviousSong, Song2 , &pl::start_prev_song >
+ a_row < Song1 , NextSong , Song2 , &pl::start_next_song >,
+ a_row < Song2 , PreviousSong, Song1 , &pl::start_prev_song >,
+ a_row < Song2 , NextSong , Song3 , &pl::start_next_song >,
+ a_row < Song3 , PreviousSong, Song2 , &pl::start_prev_song >
                 // +---------+-------------+---------+---------------------+----------------------+
> {};
             // Replaces the default no-transition response.
@@ -150,7 +150,7 @@
         void stop_and_open(open_close const&) { std::cout << "player::stop_and_open\n"; }
         void stopped_again(stop const&) {std::cout << "player::stopped_again\n";}
         // guard conditions
-
+
 
 #ifdef __MWERKS__
     private:
@@ -163,22 +163,22 @@
         struct transition_table : mpl::vector<
             // Start Event Next Action Guard
             // +---------+-------------+---------+---------------------+----------------------+
- a_row < Stopped , play , Playing , &p::start_playback >,
- a_row < Stopped , open_close , Open , &p::open_drawer >,
- a_row < Stopped , stop , Stopped , &p::stopped_again >,
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Open , open_close , Empty , &p::close_drawer >,
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Empty , open_close , Open , &p::open_drawer >,
- a_row < Empty , cd_detected , Stopped , &p::store_cd_info >,
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Playing , stop , Stopped , &p::stop_playback >,
- a_row < Playing , pause , Paused , &p::pause_playback >,
- a_row < Playing , open_close , Open , &p::stop_and_open >,
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Paused , end_pause , Playing , &p::resume_playback >,
- a_row < Paused , stop , Stopped , &p::stop_playback >,
- a_row < Paused , open_close , Open , &p::stop_and_open >
+ a_row < Stopped , play , Playing , &p::start_playback >,
+ a_row < Stopped , open_close , Open , &p::open_drawer >,
+ a_row < Stopped , stop , Stopped , &p::stopped_again >,
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Open , open_close , Empty , &p::close_drawer >,
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Empty , open_close , Open , &p::open_drawer >,
+ a_row < Empty , cd_detected , Stopped , &p::store_cd_info >,
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Playing , stop , Stopped , &p::stop_playback >,
+ a_row < Playing , pause , Paused , &p::pause_playback >,
+ a_row < Playing , open_close , Open , &p::stop_and_open >,
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Paused , end_pause , Playing , &p::resume_playback >,
+ a_row < Paused , stop , Stopped , &p::stop_playback >,
+ a_row < Paused , open_close , Open , &p::stop_and_open >
             // +---------+-------------+---------+---------------------+----------------------+
> {};
 

Modified: sandbox/msm/libs/msm/doc/DirectEntryTutorial.cpp
==============================================================================
--- sandbox/msm/libs/msm/doc/DirectEntryTutorial.cpp (original)
+++ sandbox/msm/libs/msm/doc/DirectEntryTutorial.cpp 2009-02-16 16:49:41 EST (Mon, 16 Feb 2009)
@@ -119,9 +119,9 @@
             struct transition_table : mpl::vector<
                 // Start Event Next Action Guard
                 // +--------------+-------------+------------+------------------------+----------------------+
- a_row < PseudoEntry1 , event4 , SubState3 ,&SubFsm2::entry_action >,
- _row < SubState2 , event6 , SubState1 >,
- _row < SubState3 , event5 , PseudoExit1 >
+ a_row < PseudoEntry1 , event4 , SubState3 ,&SubFsm2::entry_action >,
+ _row < SubState2 , event6 , SubState1 >,
+ _row < SubState3 , event5 , PseudoExit1 >
                 // +--------------+-------------+------------+------------------------+----------------------+
> {};
             // Replaces the default no-transition response.
@@ -141,7 +141,7 @@
 #endif
         // transition actions
         // guard conditions
-
+
 
 #ifdef __MWERKS__
     private:
@@ -156,7 +156,7 @@
             _row < State1 , event1 , SubFsm2 >,
             _row < State1 , event2 , SubFsm2::SubState2 >,
             _row < State1 , event3 , mpl::vector<SubFsm2::SubState2,
- SubFsm2::SubState2b> >,
+ SubFsm2::SubState2b> >,
             _row < State1 , event4 , SubFsm2::PseudoEntry1 >,
             // +---------------------+-------------+------------------------------------+-------+-------+
             _row < SubFsm2 , event1 , State1 >,
@@ -205,7 +205,7 @@
         p.process_event(event4()); pstate(p);
         std::cout << "using exit pseudo state" << std::endl;
         p.process_event(event5()); pstate(p);
- }
+ }
 }
 
 int main()

Modified: sandbox/msm/libs/msm/doc/Flags.cpp
==============================================================================
--- sandbox/msm/libs/msm/doc/Flags.cpp (original)
+++ sandbox/msm/libs/msm/doc/Flags.cpp 2009-02-16 16:49:41 EST (Mon, 16 Feb 2009)
@@ -44,7 +44,7 @@
             // every (optional) entry/exit methods get the event passed.
             template <class Event>
             void on_entry(Event const& ) {std::cout << "entering: Empty" << std::endl;}
- template <class Event>
+ template <class Event>
             void on_exit(Event const& ) {std::cout << "leaving: Empty" << std::endl;}
         };
         struct Open : public state<>
@@ -52,7 +52,7 @@
             typedef mpl::vector1<CDLoaded> flag_list;
             template <class Event>
             void on_entry(Event const& ) {std::cout << "entering: Open" << std::endl;}
- template <class Event>
+ template <class Event>
             void on_exit(Event const& ) {std::cout << "leaving: Open" << std::endl;}
         };
 
@@ -62,7 +62,7 @@
             typedef mpl::vector1<CDLoaded> flag_list;
             template <class Event>
             void on_entry(Event const& ) {std::cout << "entering: Stopped" << std::endl;}
- template <class Event>
+ template <class Event>
             void on_exit(Event const& ) {std::cout << "leaving: Stopped" << std::endl;}
         };
 
@@ -76,7 +76,7 @@
 
             template <class Event>
             void on_entry(Event const& ) {std::cout << "entering: Playing" << std::endl;}
- template <class Event>
+ template <class Event>
             void on_exit(Event const& ) {std::cout << "leaving: Playing" << std::endl;}
 
             // The list of FSM states
@@ -84,24 +84,24 @@
             {
                 typedef mpl::vector1<FirstSongPlaying> flag_list;
                 template <class Event>
- 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 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;}
 
             };
             struct Song2 : public state<>
             {
                 template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: Second song" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: Second Song" << std::endl;}
+ void on_entry(Event const& ) {std::cout << "starting: Second song" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: Second Song" << std::endl;}
             };
             struct Song3 : public state<>
             {
                 template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: Third song" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: Third Song" << std::endl;}
+ void on_entry(Event const& ) {std::cout << "starting: Third song" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: Third Song" << std::endl;}
             };
             // the initial state. Must be defined
             typedef Song1 initial_state;
@@ -109,7 +109,7 @@
             void start_next_song(NextSong const&) { std::cout << "Playing::start_next_song\n"; }
             void start_prev_song(PreviousSong const&) { std::cout << "Playing::start_prev_song\n"; }
             // guard conditions
-
+
             // friend definition needed.
             friend class state_machine<Playing>;
             typedef Playing pl; // makes transition table cleaner
@@ -117,10 +117,10 @@
             struct transition_table : mpl::vector4<
                 // Start Event Next Action Guard
                 // +---------+-------------+---------+---------------------+----------------------+
- a_row < Song1 , NextSong , Song2 , &pl::start_next_song >,
- a_row < Song2 , PreviousSong, Song1 , &pl::start_prev_song >,
- a_row < Song2 , NextSong , Song3 , &pl::start_next_song >,
- a_row < Song3 , PreviousSong, Song2 , &pl::start_prev_song >
+ a_row < Song1 , NextSong , Song2 , &pl::start_next_song >,
+ a_row < Song2 , PreviousSong, Song1 , &pl::start_prev_song >,
+ a_row < Song2 , NextSong , Song3 , &pl::start_next_song >,
+ a_row < Song3 , PreviousSong, Song2 , &pl::start_prev_song >
                 // +---------+-------------+---------+---------------------+----------------------+
> {};
             // Replaces the default no-transition response.
@@ -161,7 +161,7 @@
         void stop_and_open(open_close const&) { std::cout << "player::stop_and_open\n"; }
         void stopped_again(stop const&) {std::cout << "player::stopped_again\n";}
         // guard conditions
-
+
 
 #ifdef __MWERKS__
     private:
@@ -174,22 +174,22 @@
         struct transition_table : mpl::vector<
             // Start Event Next Action Guard
             // +---------+-------------+---------+---------------------+----------------------+
- a_row < Stopped , play , Playing , &p::start_playback >,
- a_row < Stopped , open_close , Open , &p::open_drawer >,
- a_row < Stopped , stop , Stopped , &p::stopped_again >,
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Open , open_close , Empty , &p::close_drawer >,
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Empty , open_close , Open , &p::open_drawer >,
- a_row < Empty , cd_detected , Stopped , &p::store_cd_info >,
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Playing , stop , Stopped , &p::stop_playback >,
- a_row < Playing , pause , Paused , &p::pause_playback >,
- a_row < Playing , open_close , Open , &p::stop_and_open >,
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Paused , end_pause , Playing , &p::resume_playback >,
- a_row < Paused , stop , Stopped , &p::stop_playback >,
- a_row < Paused , open_close , Open , &p::stop_and_open >
+ a_row < Stopped , play , Playing , &p::start_playback >,
+ a_row < Stopped , open_close , Open , &p::open_drawer >,
+ a_row < Stopped , stop , Stopped , &p::stopped_again >,
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Open , open_close , Empty , &p::close_drawer >,
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Empty , open_close , Open , &p::open_drawer >,
+ a_row < Empty , cd_detected , Stopped , &p::store_cd_info >,
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Playing , stop , Stopped , &p::stop_playback >,
+ a_row < Playing , pause , Paused , &p::pause_playback >,
+ a_row < Playing , open_close , Open , &p::stop_and_open >,
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Paused , end_pause , Playing , &p::resume_playback >,
+ a_row < Paused , stop , Stopped , &p::stop_playback >,
+ a_row < Paused , open_close , Open , &p::stop_and_open >
             // +---------+-------------+---------+---------------------+----------------------+
> {};
 

Modified: sandbox/msm/libs/msm/doc/HarelWithEntry.cpp
==============================================================================
--- sandbox/msm/libs/msm/doc/HarelWithEntry.cpp (original)
+++ sandbox/msm/libs/msm/doc/HarelWithEntry.cpp 2009-02-16 16:49:41 EST (Mon, 16 Feb 2009)
@@ -65,12 +65,12 @@
         struct transition_table : mpl::vector<
             // Start Event Next Action Guard
             // +-----------+-------------+-------------------------+----------+----------------------+
- _row < Displays , P1 , AlarmBeeps::Alarm1Beeps >,
- _row < Displays , P2 , AlarmBeeps::Alarm2Beeps >,
- _row < Displays , P , AlarmBeeps::BothBeep >,
- _row < AlarmBeeps,AnyBtnPressed, Displays >,
- _row < AlarmBeeps,AlarmBeeps30s, Displays >
- // +-----------+-------------+--------------------------+----------+----------------------+
+ _row < Displays , P1 , AlarmBeeps::Alarm1Beeps >,
+ _row < Displays , P2 , AlarmBeeps::Alarm2Beeps >,
+ _row < Displays , P , AlarmBeeps::BothBeep >,
+ _row < AlarmBeeps,AnyBtnPressed, Displays >,
+ _row < AlarmBeeps,AlarmBeeps30s, Displays >
+ // +-----------+-------------+--------------------------+----------+----------------------+
> {};
     };
 }

Modified: sandbox/msm/libs/msm/doc/HarelWithoutEntry.cpp
==============================================================================
--- sandbox/msm/libs/msm/doc/HarelWithoutEntry.cpp (original)
+++ sandbox/msm/libs/msm/doc/HarelWithoutEntry.cpp 2009-02-16 16:49:41 EST (Mon, 16 Feb 2009)
@@ -57,7 +57,7 @@
                 struct transition_table : mpl::vector<
                     // Start Event Next Action Guard
                     // +---------+-------------+---------+------------------------+----------------------+
- g_row < NoBeep , P , Beeps ,&A::check_beep >
+ g_row < NoBeep , P , Beeps ,&A::check_beep >
                     // +---------+-------------+---------+------------------------+----------------------+
> {};
             };
@@ -78,9 +78,9 @@
         struct transition_table : mpl::vector<
             // Start Event Next Action Guard
             // +-----------+-------------+------------+------------------------+----------------------+
- _row < Displays , P , AlarmBeeps >,
- _row < AlarmBeeps,AnyBtnPressed, Displays >,
- _row < AlarmBeeps,AlarmBeeps30s, Displays >
+ _row < Displays , P , AlarmBeeps >,
+ _row < AlarmBeeps,AnyBtnPressed, Displays >,
+ _row < AlarmBeeps,AlarmBeeps30s, Displays >
             // +-----------+-------------+------------+------------------------+----------------------+
> {};
     };

Modified: sandbox/msm/libs/msm/doc/HarelWithoutEntryNoTemplateSM.cpp
==============================================================================
--- sandbox/msm/libs/msm/doc/HarelWithoutEntryNoTemplateSM.cpp (original)
+++ sandbox/msm/libs/msm/doc/HarelWithoutEntryNoTemplateSM.cpp 2009-02-16 16:49:41 EST (Mon, 16 Feb 2009)
@@ -31,7 +31,7 @@
             // g++ refuses to compile if the Alarm submachines are template
             struct AlarmImpl : public state_machine<AlarmImpl >
             {
- AlarmImpl(int index):Index(index){}
+ AlarmImpl(int index):Index(index){}
                 struct NoBeep : public state<> {};
                 struct Beeps : public state<> {};
                 // friend definition needed.
@@ -42,9 +42,9 @@
                 // guard
                 bool check_beep(const P& evt)
                 {
- bool beep = ((evt.index & Index)!=0);
- if (beep)
- std::cout << "Beeping alarm:"<< Index << std::endl;
+ bool beep = ((evt.index & Index)!=0);
+ if (beep)
+ std::cout << "Beeping alarm:"<< Index << std::endl;
                     // check if our bit is set in the event
                     return beep;
                 }
@@ -52,20 +52,20 @@
                 struct transition_table : mpl::vector<
                     // Start Event Next Action Guard
                     // +---------+-------------+---------+------------------------+----------------------+
- g_row < NoBeep , P , Beeps ,&A::check_beep >
+ g_row < NoBeep , P , Beeps ,&A::check_beep >
                     // +---------+-------------+---------+------------------------+----------------------+
> {};
             private:
- int Index;
+ int Index;
             };
- struct Alarm1 : public AlarmImpl
- {
- Alarm1():AlarmImpl(1){}
- };
- struct Alarm2 : public AlarmImpl
- {
- Alarm2():AlarmImpl(2){}
- };
+ struct Alarm1 : public AlarmImpl
+ {
+ Alarm1():AlarmImpl(1){}
+ };
+ struct Alarm2 : public AlarmImpl
+ {
+ Alarm2():AlarmImpl(2){}
+ };
 
             // friend definition needed.
             friend class state_machine<AlarmBeeps>;
@@ -83,9 +83,9 @@
         struct transition_table : mpl::vector<
             // Start Event Next Action Guard
             // +-----------+-------------+------------+------------------------+----------------------+
- _row < Displays , P , AlarmBeeps >,
- _row < AlarmBeeps,AnyBtnPressed, Displays >,
- _row < AlarmBeeps,AlarmBeeps30s, Displays >
+ _row < Displays , P , AlarmBeeps >,
+ _row < AlarmBeeps,AnyBtnPressed, Displays >,
+ _row < AlarmBeeps,AlarmBeeps30s, Displays >
             // +-----------+-------------+------------+------------------------+----------------------+
> {};
     };

Modified: sandbox/msm/libs/msm/doc/History.cpp
==============================================================================
--- sandbox/msm/libs/msm/doc/History.cpp (original)
+++ sandbox/msm/libs/msm/doc/History.cpp 2009-02-16 16:49:41 EST (Mon, 16 Feb 2009)
@@ -39,14 +39,14 @@
             // every (optional) entry/exit methods get the event passed
             template <class Event>
             void on_entry(Event const& ) {std::cout << "entering: Empty" << std::endl;}
- template <class Event>
+ template <class Event>
             void on_exit(Event const& ) {std::cout << "leaving: Empty" << std::endl;}
         };
         struct Open : public state<>
         {
             template <class Event>
             void on_entry(Event const& ) {std::cout << "entering: Open" << std::endl;}
- template <class Event>
+ template <class Event>
             void on_exit(Event const& ) {std::cout << "leaving: Open" << std::endl;}
         };
 
@@ -55,7 +55,7 @@
             // when stopped, the CD is loaded
             template <class Event>
             void on_entry(Event const& ) {std::cout << "entering: Stopped" << std::endl;}
- template <class Event>
+ template <class Event>
             void on_exit(Event const& ) {std::cout << "leaving: Stopped" << std::endl;}
         };
 
@@ -68,30 +68,30 @@
             // when playing, the CD is loaded and we are in either pause or playing (duh)
             template <class Event>
             void on_entry(Event const& ) {std::cout << "entering: Playing" << std::endl;}
- template <class Event>
+ template <class Event>
             void on_exit(Event const& ) {std::cout << "leaving: Playing" << std::endl;}
 
             // The list of FSM states
             struct Song1 : public state<>
             {
                 template <class Event>
- 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 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;}
             };
             struct Song2 : public state<>
             {
                 template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: Second song" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: Second Song" << std::endl;}
+ void on_entry(Event const& ) {std::cout << "starting: Second song" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: Second Song" << std::endl;}
             };
             struct Song3 : public state<>
             {
                 template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: Third song" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: Third Song" << std::endl;}
+ void on_entry(Event const& ) {std::cout << "starting: Third song" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: Third Song" << std::endl;}
             };
             // the initial state. Must be defined
             typedef Song1 initial_state;
@@ -99,7 +99,7 @@
             void start_next_song(NextSong const&) { std::cout << "Playing::start_next_song\n"; }
             void start_prev_song(PreviousSong const&) { std::cout << "Playing::start_prev_song\n"; }
             // guard conditions
-
+
             // friend definition needed.
             friend class state_machine<Playing>;
             typedef Playing pl; // makes transition table cleaner
@@ -107,10 +107,10 @@
             struct transition_table : mpl::vector4<
                 // Start Event Next Action Guard
                 // +---------+-------------+---------+---------------------+----------------------+
- a_row < Song1 , NextSong , Song2 , &pl::start_next_song >,
- a_row < Song2 , PreviousSong, Song1 , &pl::start_prev_song >,
- a_row < Song2 , NextSong , Song3 , &pl::start_next_song >,
- a_row < Song3 , PreviousSong, Song2 , &pl::start_prev_song >
+ a_row < Song1 , NextSong , Song2 , &pl::start_next_song >,
+ a_row < Song2 , PreviousSong, Song1 , &pl::start_prev_song >,
+ a_row < Song2 , NextSong , Song3 , &pl::start_next_song >,
+ a_row < Song3 , PreviousSong, Song2 , &pl::start_prev_song >
                 // +---------+-------------+---------+---------------------+----------------------+
> {};
             // Replaces the default no-transition response.
@@ -154,7 +154,7 @@
         void stop_and_open(open_close const&) { std::cout << "player::stop_and_open\n"; }
         void stopped_again(stop const&) {std::cout << "player::stopped_again\n";}
         // guard conditions
-
+
 
 #ifdef __MWERKS__
     private:
@@ -167,22 +167,22 @@
         struct transition_table : mpl::vector<
             // Start Event Next Action Guard
             // +---------+-------------+---------+---------------------+----------------------+
- a_row < Stopped , play , Playing , &p::start_playback >,
- a_row < Stopped , open_close , Open , &p::open_drawer >,
- a_row < Stopped , stop , Stopped , &p::stopped_again >,
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Open , open_close , Empty , &p::close_drawer >,
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Empty , open_close , Open , &p::open_drawer >,
- a_row < Empty , cd_detected , Stopped , &p::store_cd_info >,
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Playing , stop , Stopped , &p::stop_playback >,
- a_row < Playing , pause , Paused , &p::pause_playback >,
- a_row < Playing , open_close , Open , &p::stop_and_open >,
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Paused , end_pause , Playing , &p::resume_playback >,
- a_row < Paused , stop , Stopped , &p::stop_playback >,
- a_row < Paused , open_close , Open , &p::stop_and_open >
+ a_row < Stopped , play , Playing , &p::start_playback >,
+ a_row < Stopped , open_close , Open , &p::open_drawer >,
+ a_row < Stopped , stop , Stopped , &p::stopped_again >,
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Open , open_close , Empty , &p::close_drawer >,
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Empty , open_close , Open , &p::open_drawer >,
+ a_row < Empty , cd_detected , Stopped , &p::store_cd_info >,
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Playing , stop , Stopped , &p::stop_playback >,
+ a_row < Playing , pause , Paused , &p::pause_playback >,
+ a_row < Playing , open_close , Open , &p::stop_and_open >,
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Paused , end_pause , Playing , &p::resume_playback >,
+ a_row < Paused , stop , Stopped , &p::stop_playback >,
+ a_row < Paused , open_close , Open , &p::stop_and_open >
             // +---------+-------------+---------+---------------------+----------------------+
> {};
 

Modified: sandbox/msm/libs/msm/doc/Orthogonal-deferred.cpp
==============================================================================
--- sandbox/msm/libs/msm/doc/Orthogonal-deferred.cpp (original)
+++ sandbox/msm/libs/msm/doc/Orthogonal-deferred.cpp 2009-02-16 16:49:41 EST (Mon, 16 Feb 2009)
@@ -49,7 +49,7 @@
             // every (optional) entry/exit methods get the event passed.
             template <class Event>
             void on_entry(Event const& ) {std::cout << "entering: Empty" << std::endl;}
- template <class Event>
+ template <class Event>
             void on_exit(Event const& ) {std::cout << "leaving: Empty" << std::endl;}
         };
         struct Open : public state<>
@@ -60,7 +60,7 @@
             typedef mpl::vector1<CDLoaded> flag_list;
             template <class Event>
             void on_entry(Event const& ) {std::cout << "entering: Open" << std::endl;}
- template <class Event>
+ template <class Event>
             void on_exit(Event const& ) {std::cout << "leaving: Open" << std::endl;}
         };
 
@@ -70,7 +70,7 @@
             typedef mpl::vector1<CDLoaded> flag_list;
             template <class Event>
             void on_entry(Event const& ) {std::cout << "entering: Stopped" << std::endl;}
- template <class Event>
+ template <class Event>
             void on_exit(Event const& ) {std::cout << "leaving: Stopped" << std::endl;}
         };
 
@@ -84,30 +84,30 @@
 
             template <class Event>
             void on_entry(Event const& ) {std::cout << "entering: Playing" << std::endl;}
- template <class Event>
+ template <class Event>
             void on_exit(Event const& ) {std::cout << "leaving: Playing" << std::endl;}
             // The list of FSM states
             struct Song1 : public state<>
             {
                 typedef mpl::vector1<FirstSongPlaying> flag_list;
- template <class Event>
- 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;}
+ template <class Event>
+ 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;}
             };
             struct Song2 : public state<>
             {
                 template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: Second song" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: Second Song" << std::endl;}
+ void on_entry(Event const& ) {std::cout << "starting: Second song" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: Second Song" << std::endl;}
             };
             struct Song3 : public state<>
             {
                 template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: Third song" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: Third Song" << std::endl;}
+ void on_entry(Event const& ) {std::cout << "starting: Third song" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: Third Song" << std::endl;}
             };
             // the initial state. Must be defined
             typedef Song1 initial_state;
@@ -115,7 +115,7 @@
             void start_next_song(NextSong const&) { std::cout << "Playing::start_next_song\n"; }
             void start_prev_song(PreviousSong const&) { std::cout << "Playing::start_prev_song\n"; }
             // guard conditions
-
+
             // friend definition needed.
             friend class state_machine<Playing>;
             typedef Playing pl; // makes transition table cleaner
@@ -123,10 +123,10 @@
             struct transition_table : mpl::vector4<
                 // Start Event Next Action Guard
                 // +---------+-------------+---------+---------------------+----------------------+
- a_row < Song1 , NextSong , Song2 , &pl::start_next_song >,
- a_row < Song2 , PreviousSong, Song1 , &pl::start_prev_song >,
- a_row < Song2 , NextSong , Song3 , &pl::start_next_song >,
- a_row < Song3 , PreviousSong, Song2 , &pl::start_prev_song >
+ a_row < Song1 , NextSong , Song2 , &pl::start_next_song >,
+ a_row < Song2 , PreviousSong, Song1 , &pl::start_prev_song >,
+ a_row < Song2 , NextSong , Song3 , &pl::start_next_song >,
+ a_row < Song3 , PreviousSong, Song2 , &pl::start_prev_song >
                 // +---------+-------------+---------+---------------------+----------------------+
> {};
             // Replaces the default no-transition response.
@@ -146,20 +146,20 @@
         };
         struct AllOk : public state<>
         {
- template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: AllOk" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: AllOk" << std::endl;}
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "starting: AllOk" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: AllOk" << std::endl;}
         };
         // this state is also made terminal so that all the events are blocked
         struct ErrorMode : public terminate_state<> // ErrorMode terminates the state machine
- //public interrupt_state<end_error> // ErroMode just interrupts. Will resume if
- // the event end_error is generated
+ //public interrupt_state<end_error> // ErroMode just interrupts. Will resume if
+ // the event end_error is generated
         {
- template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: ErrorMode" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: ErrorMode" << std::endl;}
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "starting: ErrorMode" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: ErrorMode" << std::endl;}
         };
         // the initial state of the player SM. Must be defined
         typedef mpl::vector<Empty,AllOk> initial_state;
@@ -184,7 +184,7 @@
         void report_end_error(end_error const&) {std::cout << "player::report_end_error\n";}
 
         // guard conditions
-
+
 
 #ifdef __MWERKS__
     private:
@@ -197,25 +197,25 @@
         struct transition_table : mpl::vector<
             // Start Event Next Action Guard
             // +---------+-------------+---------+---------------------+----------------------+
- a_row < Stopped , play , Playing , &p::start_playback >,
- a_row < Stopped , open_close , Open , &p::open_drawer >,
- a_row < Stopped , stop , Stopped , &p::stopped_again >,
+ a_row < Stopped , play , Playing , &p::start_playback >,
+ a_row < Stopped , open_close , Open , &p::open_drawer >,
+ a_row < Stopped , stop , Stopped , &p::stopped_again >,
             // +---------+-------------+---------+---------------------+----------------------+
- a_row < Open , open_close , Empty , &p::close_drawer >,
+ a_row < Open , open_close , Empty , &p::close_drawer >,
             // +---------+-------------+---------+---------------------+----------------------+
- a_row < Empty , open_close , Open , &p::open_drawer >,
- a_row < Empty , cd_detected , Stopped , &p::store_cd_info >,
+ a_row < Empty , open_close , Open , &p::open_drawer >,
+ a_row < Empty , cd_detected , Stopped , &p::store_cd_info >,
             // +---------+-------------+---------+---------------------+----------------------+
- a_row < Playing , stop , Stopped , &p::stop_playback >,
- a_row < Playing , pause , Paused , &p::pause_playback >,
- a_row < Playing , open_close , Open , &p::stop_and_open >,
+ a_row < Playing , stop , Stopped , &p::stop_playback >,
+ a_row < Playing , pause , Paused , &p::pause_playback >,
+ a_row < Playing , open_close , Open , &p::stop_and_open >,
             // +---------+-------------+---------+---------------------+----------------------+
- a_row < Paused , end_pause , Playing , &p::resume_playback >,
- a_row < Paused , stop , Stopped , &p::stop_playback >,
- a_row < Paused , open_close , Open , &p::stop_and_open >,
+ a_row < Paused , end_pause , Playing , &p::resume_playback >,
+ a_row < Paused , stop , Stopped , &p::stop_playback >,
+ a_row < Paused , open_close , Open , &p::stop_and_open >,
             // +---------+-------------+---------+---------------------+----------------------+
- a_row < AllOk , error_found ,ErrorMode, &p::report_error >,
- a_row <ErrorMode,end_error ,AllOk , &p::report_end_error >
+ a_row < AllOk , error_found ,ErrorMode, &p::report_error >,
+ a_row <ErrorMode,end_error ,AllOk , &p::report_end_error >
             // +---------+-------------+---------+---------------------+----------------------+
> {};
 

Modified: sandbox/msm/libs/msm/doc/SC Composite.cpp
==============================================================================
--- sandbox/msm/libs/msm/doc/SC Composite.cpp (original)
+++ sandbox/msm/libs/msm/doc/SC Composite.cpp 2009-02-16 16:49:41 EST (Mon, 16 Feb 2009)
@@ -186,7 +186,7 @@
         struct Playing : public state_machine<Playing>
         {
             // when playing, the CD is loaded and we are in either pause or playing (duh)
-
+
 
             // The list of FSM states
             struct Song1 : public state<>

Modified: sandbox/msm/libs/msm/doc/SC Simple.cpp
==============================================================================
--- sandbox/msm/libs/msm/doc/SC Simple.cpp (original)
+++ sandbox/msm/libs/msm/doc/SC Simple.cpp 2009-02-16 16:49:41 EST (Mon, 16 Feb 2009)
@@ -21,90 +21,90 @@
 namespace test_sc
 {
 
-//events
-struct play : sc::event< play > {};
-struct end_pause : sc::event< end_pause > {};
-struct stop : sc::event< stop > {};
-struct pause : sc::event< pause > {};
-struct open_close : sc::event< open_close > {};
-struct cd_detected : sc::event< cd_detected > {};
-
-
-struct Empty;
-struct Open;
-struct Stopped;
-struct Playing;
-struct Paused;
-// SM
-struct player : sc::state_machine< player, Empty >
-{
- void open_drawer(open_close const&) { /*std::cout << "player::open_drawer\n";*/ }
- void store_cd_info(cd_detected const& cd) {/*std::cout << "player::store_cd_info\n";*/ }
- void close_drawer(open_close const&) { /*std::cout << "player::close_drawer\n";*/ }
- void start_playback(play const&) { /*std::cout << "player::start_playback\n";*/ }
- void stopped_again(stop const&) {/*std::cout << "player::stopped_again\n";*/}
- void stop_playback(stop const&) { /*std::cout << "player::stop_playback\n";*/ }
- void pause_playback(pause const&) { /*std::cout << "player::pause_playback\n"; */}
- void stop_and_open(open_close const&) { /*std::cout << "player::stop_and_open\n";*/ }
- void resume_playback(end_pause const&) { /*std::cout << "player::resume_playback\n";*/ }
-};
+ //events
+ struct play : sc::event< play > {};
+ struct end_pause : sc::event< end_pause > {};
+ struct stop : sc::event< stop > {};
+ struct pause : sc::event< pause > {};
+ struct open_close : sc::event< open_close > {};
+ struct cd_detected : sc::event< cd_detected > {};
+
+
+ struct Empty;
+ struct Open;
+ struct Stopped;
+ struct Playing;
+ struct Paused;
+ // SM
+ struct player : sc::state_machine< player, Empty >
+ {
+ void open_drawer(open_close const&) { /*std::cout << "player::open_drawer\n";*/ }
+ void store_cd_info(cd_detected const& cd) {/*std::cout << "player::store_cd_info\n";*/ }
+ void close_drawer(open_close const&) { /*std::cout << "player::close_drawer\n";*/ }
+ void start_playback(play const&) { /*std::cout << "player::start_playback\n";*/ }
+ void stopped_again(stop const&) {/*std::cout << "player::stopped_again\n";*/}
+ void stop_playback(stop const&) { /*std::cout << "player::stop_playback\n";*/ }
+ void pause_playback(pause const&) { /*std::cout << "player::pause_playback\n"; */}
+ void stop_and_open(open_close const&) { /*std::cout << "player::stop_and_open\n";*/ }
+ void resume_playback(end_pause const&) { /*std::cout << "player::resume_playback\n";*/ }
+ };
 
-struct Empty : sc::simple_state< Empty, player >
-{
- Empty() { /*std::cout << "entering Empty" << std::endl;*/ } // entry
- ~Empty() { /*std::cout << "leaving Empty" << std::endl;*/ } // exit
- typedef mpl::list<
- sc::transition< open_close, Open,
- player, &player::open_drawer >,
- sc::transition< cd_detected, Stopped,
- player, &player::store_cd_info > > reactions;
+ struct Empty : sc::simple_state< Empty, player >
+ {
+ Empty() { /*std::cout << "entering Empty" << std::endl;*/ } // entry
+ ~Empty() { /*std::cout << "leaving Empty" << std::endl;*/ } // exit
+ typedef mpl::list<
+ sc::transition< open_close, Open,
+ player, &player::open_drawer >,
+ sc::transition< cd_detected, Stopped,
+ player, &player::store_cd_info > > reactions;
 
-};
-struct Open : sc::simple_state< Open, player >
-{
- Open() { /*std::cout << "entering Open" << std::endl;*/ } // entry
- ~Open() { /*std::cout << "leaving Open" << std::endl;*/ } // exit
- typedef sc::transition< open_close, Empty,
- player, &player::close_drawer > reactions;
+ };
+ struct Open : sc::simple_state< Open, player >
+ {
+ Open() { /*std::cout << "entering Open" << std::endl;*/ } // entry
+ ~Open() { /*std::cout << "leaving Open" << std::endl;*/ } // exit
+ typedef sc::transition< open_close, Empty,
+ player, &player::close_drawer > reactions;
 
-};
-struct Stopped : sc::simple_state< Stopped, player >
-{
- Stopped() { /*std::cout << "entering Stopped" << std::endl;*/ } // entry
- ~Stopped() { /*std::cout << "leaving Stopped" << std::endl;*/ } // exit
- typedef mpl::list<
- sc::transition< play, Playing,
- player, &player::start_playback >,
- sc::transition< open_close, Open,
- player, &player::open_drawer >,
- sc::transition< stop, Stopped,
- player, &player::stopped_again > > reactions;
+ };
+ struct Stopped : sc::simple_state< Stopped, player >
+ {
+ Stopped() { /*std::cout << "entering Stopped" << std::endl;*/ } // entry
+ ~Stopped() { /*std::cout << "leaving Stopped" << std::endl;*/ } // exit
+ typedef mpl::list<
+ sc::transition< play, Playing,
+ player, &player::start_playback >,
+ sc::transition< open_close, Open,
+ player, &player::open_drawer >,
+ sc::transition< stop, Stopped,
+ player, &player::stopped_again > > reactions;
 
-};
-struct Playing : sc::simple_state< Playing, player >
-{
- Playing() { /*std::cout << "entering Playing" << std::endl;*/ } // entry
- ~Playing() { /*std::cout << "leaving Playing" << std::endl;*/ } // exit
- typedef mpl::list<
- sc::transition< stop, Stopped,
- player, &player::stop_playback >,
- sc::transition< pause, Paused,
- player, &player::pause_playback >,
- sc::transition< open_close, Open,
- player, &player::stop_and_open > > reactions;
-};
-struct Paused : sc::simple_state< Paused, player >
-{
- Paused() { /*std::cout << "entering Paused" << std::endl;*/ } // entry
- ~Paused() { /*std::cout << "leaving Paused" << std::endl;*/ } // exit
- typedef mpl::list<
- sc::transition< end_pause, Playing,
- player, &player::resume_playback >,
- sc::transition< stop, Stopped,
- player, &player::stop_playback >,
- sc::transition< open_close, Open,
- player, &player::stop_and_open > > reactions;
-};
+ };
+ struct Playing : sc::simple_state< Playing, player >
+ {
+ Playing() { /*std::cout << "entering Playing" << std::endl;*/ } // entry
+ ~Playing() { /*std::cout << "leaving Playing" << std::endl;*/ } // exit
+ typedef mpl::list<
+ sc::transition< stop, Stopped,
+ player, &player::stop_playback >,
+ sc::transition< pause, Paused,
+ player, &player::pause_playback >,
+ sc::transition< open_close, Open,
+ player, &player::stop_and_open > > reactions;
+ };
+ struct Paused : sc::simple_state< Paused, player >
+ {
+ Paused() { /*std::cout << "entering Paused" << std::endl;*/ } // entry
+ ~Paused() { /*std::cout << "leaving Paused" << std::endl;*/ } // exit
+ typedef mpl::list<
+ sc::transition< end_pause, Playing,
+ player, &player::resume_playback >,
+ sc::transition< stop, Stopped,
+ player, &player::stop_playback >,
+ sc::transition< open_close, Open,
+ player, &player::stop_and_open > > reactions;
+ };
 }
 
 //FSM
@@ -128,16 +128,16 @@
         struct Empty : public state<>
         {
             // optional entry/exit methods
- template <class Event>
+ template <class Event>
             void on_entry(Event const& ) {/*std::cout << "entering: Empty" << std::endl;*/}
- template <class Event>
+ template <class Event>
             void on_exit(Event const& ) {/*std::cout << "leaving: Empty" << std::endl;*/}
         };
         struct Open : public state<>
         {
             template <class Event>
             void on_entry(Event const& ) {/*std::cout << "entering: Open" << std::endl;*/}
- template <class Event>
+ template <class Event>
             void on_exit(Event const& ) {/*std::cout << "leaving: Open" << std::endl;*/}
         };
 
@@ -146,7 +146,7 @@
             // when stopped, the CD is loaded
             template <class Event>
             void on_entry(Event const& ) {/*std::cout << "entering: Stopped" << std::endl;*/}
- template <class Event>
+ template <class Event>
             void on_exit(Event const& ) {/*std::cout << "leaving: Stopped" << std::endl;*/}
         };
 
@@ -154,16 +154,16 @@
         {
             template <class Event>
             void on_entry(Event const& ) {/*std::cout << "entering: Playing" << std::endl;*/}
- template <class Event>
+ template <class Event>
             void on_exit(Event const& ) {/*std::cout << "leaving: Playing" << std::endl;*/}
         };
 
         // state not defining any entry or exit
         struct Paused : public state<>
         {
- template <class Event>
+ template <class Event>
             void on_entry(Event const& ) {/*std::cout << "entering: Paused" << std::endl;*/}
- template <class Event>
+ template <class Event>
             void on_exit(Event const& ) {/*std::cout << "leaving: Paused" << std::endl;*/}
         };
 
@@ -184,7 +184,7 @@
         void stop_and_open(open_close const&) { }
         void stopped_again(stop const&) {}
         // guard conditions
-
+
 #ifdef __MWERKS__
     private:
 #endif
@@ -320,6 +320,6 @@
 #else
     std::cout << "msm took in us:" << mtime(tv1,tv2) <<"\n" <<std::endl;
 #endif
- return 0;
+ return 0;
 }
 

Modified: sandbox/msm/libs/msm/doc/SM-0arg.cpp
==============================================================================
--- sandbox/msm/libs/msm/doc/SM-0arg.cpp (original)
+++ sandbox/msm/libs/msm/doc/SM-0arg.cpp 2009-02-16 16:49:41 EST (Mon, 16 Feb 2009)
@@ -10,463 +10,463 @@
 
 namespace // Concrete FSM implementation
 {
- // events
- struct play {};
- struct end_pause {};
- struct stop {};
- struct pause {};
- struct open_close {};
- struct NextSong {};
- struct PreviousSong {};
- struct ThreeSec {};
- struct TenSec {};
- struct go_sleep {};
- struct error_found {};
- struct end_error {};
-
- // Flags. Allow information about a property of the current state
- struct PlayingPaused{};
- struct CDLoaded {};
- struct FirstSongPlaying {};
-
- // A "complicated" event type that carries some data.
- // forward
- struct player;
- struct cd_detected
- {
- cd_detected(std::string name, player& p)
- : name(name)
- , m_player(p)
- {}
-
- std::string name;
- player& m_player;
- };
-
- // overwrite of the base state (not default)
- struct my_visitable_state
- {
- // signature of the accept function
- typedef args<void> accept_sig;
-
- // we also want polymorphic states
- virtual ~my_visitable_state() {}
- // default implementation for states who do not need to be visited
- void accept() const {}
- };
-
- // Concrete FSM implementation
- struct player : public state_machine<player,NoHistory,my_visitable_state>
- {
- // The list of FSM states
- struct Empty : public state<my_visitable_state>
- {
- typedef mpl::vector<play> deferred_events;
- // every (optional) entry/exit methods get the event packed as boost::any. Not useful very often.
- template <class Event>
- 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;}
+ // events
+ struct play {};
+ struct end_pause {};
+ struct stop {};
+ struct pause {};
+ struct open_close {};
+ struct NextSong {};
+ struct PreviousSong {};
+ struct ThreeSec {};
+ struct TenSec {};
+ struct go_sleep {};
+ struct error_found {};
+ struct end_error {};
+
+ // Flags. Allow information about a property of the current state
+ struct PlayingPaused{};
+ struct CDLoaded {};
+ struct FirstSongPlaying {};
+
+ // A "complicated" event type that carries some data.
+ // forward
+ struct player;
+ struct cd_detected
+ {
+ cd_detected(std::string name, player& p)
+ : name(name)
+ , m_player(p)
+ {}
+
+ std::string name;
+ player& m_player;
+ };
+
+ // overwrite of the base state (not default)
+ struct my_visitable_state
+ {
+ // signature of the accept function
+ typedef args<void> accept_sig;
+
+ // we also want polymorphic states
+ virtual ~my_visitable_state() {}
+ // default implementation for states who do not need to be visited
+ void accept() const {}
+ };
+
+ // Concrete FSM implementation
+ struct player : public state_machine<player,NoHistory,my_visitable_state>
+ {
+ // The list of FSM states
+ struct Empty : public state<my_visitable_state>
+ {
+ typedef mpl::vector<play> deferred_events;
+ // every (optional) entry/exit methods get the event packed as boost::any. Not useful very often.
+ template <class Event>
+ 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() const
             {
                 std::cout << "visiting state:" << typeid(*this).name() << std::endl;
             }
- };
- struct Open : public state<my_visitable_state>
- {
- typedef mpl::vector1<CDLoaded> flag_list;
- typedef mpl::vector<play> deferred_events;
- template <class Event>
- 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;}
+ };
+ struct Open : public state<my_visitable_state>
+ {
+ typedef mpl::vector1<CDLoaded> flag_list;
+ typedef mpl::vector<play> deferred_events;
+ template <class Event>
+ 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() const
             {
                 std::cout << "visiting state:" << typeid(*this).name() << std::endl;
             }
- };
- // a state needing a pointer to the containing state machine
- // and using for this the non-default policy
- // if policy used, set_sm_ptr is needed
- struct Stopped : public state<my_visitable_state,SMPtr>
- {
- // when stopped, the CD is loaded
- typedef mpl::vector1<CDLoaded> flag_list;
- template <class Event>
- void on_entry(Event const& ) {std::cout << "entering: Stopped" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "leaving: Stopped" << std::endl;}
- void set_sm_ptr(player* pl){m_player=pl;}
- player* m_player;
- };
- // the player state machine contains a state which is himself a state machine
- // it demonstrates Shallow History: if the state gets activated with end_pause
- // 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> >,my_visitable_state >
- {
- // when playing, the CD is loaded and we are in either pause or playing (duh)
- typedef mpl::vector2<PlayingPaused,CDLoaded> flag_list;
- template <class Event>
- 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;}
+ };
+ // a state needing a pointer to the containing state machine
+ // and using for this the non-default policy
+ // if policy used, set_sm_ptr is needed
+ struct Stopped : public state<my_visitable_state,SMPtr>
+ {
+ // when stopped, the CD is loaded
+ typedef mpl::vector1<CDLoaded> flag_list;
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "entering: Stopped" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "leaving: Stopped" << std::endl;}
+ void set_sm_ptr(player* pl){m_player=pl;}
+ player* m_player;
+ };
+ // the player state machine contains a state which is himself a state machine
+ // it demonstrates Shallow History: if the state gets activated with end_pause
+ // 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> >,my_visitable_state >
+ {
+ // when playing, the CD is loaded and we are in either pause or playing (duh)
+ typedef mpl::vector2<PlayingPaused,CDLoaded> flag_list;
+ template <class Event>
+ 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()
             {
                 std::cout << "visiting state:" << typeid(*this).name() << std::endl;
                 // visit substates
                 visit_current_states();
             }
- // 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
- struct Song1 : public state_machine<Song1,NoHistory,my_visitable_state>
- {
- typedef mpl::vector1<FirstSongPlaying> flag_list;
- template <class Event>
- 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()
- {
- std::cout << "visiting state:" << typeid(*this).name() << std::endl;
- }
- struct LightOn : public state<my_visitable_state>
- {
- template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: LightOn" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: LightOn" << std::endl;}
- };
- struct LightOff : public state<my_visitable_state>
- {
- template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: LightOff" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: LightOff" << std::endl;}
- };
- // the initial state. Must be defined
- typedef LightOn initial_state;
- // transition actions
- void turn_light_off(ThreeSec const&) { std::cout << "3s off::turn light off\n"; }
- // guard conditions
-
- // friend definition needed.
- friend class state_machine<Song1>;
- typedef Song1 s; // makes transition table cleaner
- // Transition table for Song1
- struct transition_table : mpl::vector1<
- // Start Event Next Action Guard
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < LightOn , ThreeSec , LightOff, &s::turn_light_off >
- // +---------+-------------+---------+---------------------+----------------------+
- > {};
- // Replaces the default no-transition response.
- template <class Event>
- int no_transition(int state, Event const& )
- {
- std::cout << "no transition from state " << state
- << " on event " << typeid(Event).name() << std::endl;
- return state;
- }
-
- };
- struct Song2 : public state<my_visitable_state>
- {
- template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: Second song" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: Second Song" << std::endl;}
- };
- struct Song3 : public state<my_visitable_state>
- {
- template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: Third song" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: Third Song" << std::endl;}
- };
- // the initial state. Must be defined
- typedef Song1 initial_state;
- // transition actions
- void start_next_song(NextSong const&) { std::cout << "Playing::start_next_song\n"; }
- void start_prev_song(PreviousSong const&) { std::cout << "Playing::start_prev_song\n"; }
- // guard conditions
-
- // friend definition needed.
- friend class state_machine<Playing>;
- typedef Playing pl; // makes transition table cleaner
- // Transition table for Playing
- struct transition_table : mpl::vector4<
- // Start Event Next Action Guard
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Song1 , NextSong , Song2 , &pl::start_next_song >,
- a_row < Song2 , PreviousSong, Song1 , &pl::start_prev_song >,
- a_row < Song2 , NextSong , Song3 , &pl::start_next_song >,
- a_row < Song3 , PreviousSong, Song2 , &pl::start_prev_song >
- // +---------+-------------+---------+---------------------+----------------------+
- > {};
- // Replaces the default no-transition response.
- template <class Event>
- int no_transition(int state, Event const&)
- {
- std::cout << "no transition from state " << state
- << " on event " << typeid(Event).name() << std::endl;
- return state;
- }
- };
- // the player state machine contains a state which is himself a state machine (2 of them, Playing and Paused)
- struct Paused : public state_machine<Paused,NoHistory,my_visitable_state>
- {
- typedef mpl::vector2<PlayingPaused,CDLoaded> flag_list;
- template <class Event>
- void on_entry(Event const& ) {std::cout << "entering: Paused" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "leaving: Paused" << std::endl;}
-
- // The list of FSM states
- struct StartBlinking : public state<my_visitable_state>
- {
- template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: StartBlinking" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: StartBlinking" << std::endl;}
- };
- struct StopBlinking : public state<my_visitable_state>
- {
- template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: StopBlinking" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: StopBlinking" << std::endl;}
- };
- // the initial state. Must be defined
- typedef StartBlinking initial_state;
- // transition actions
- void start_blinking(TenSec const&) { std::cout << "Paused::start_blinking\n"; }
- void stop_blinking(TenSec const&) { std::cout << "Paused::stop_blinking\n"; }
- // guard conditions
-
- // friend definition needed.
- friend class state_machine<Paused>;
- typedef Paused pa; // makes transition table cleaner
- // Transition table
- struct transition_table : mpl::vector2<
- // Start Event Next Action Guard
- // +---------------+-------------+--------------+---------------------+----------------------+
- a_row < StartBlinking , TenSec , StopBlinking , &pa::stop_blinking >,
- a_row < StopBlinking , TenSec , StartBlinking , &pa::start_blinking >
- // +---------------+-------------+---------------+--------------------+----------------------+
- > {};
- // Replaces the default no-transition response.
- template <class Event>
- int no_transition(int state, Event const& )
- {
- std::cout << "no transition from state " << state
- << " on event " << typeid(Event).name() << std::endl;
- return state;
- }
- };
- struct SleepMode : public state<my_visitable_state> {}; // dumy state just to test the automatic id generation
-
- struct AllOk : public state<my_visitable_state>
- {
- template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: AllOk" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: AllOk" << std::endl;}
- };
- struct ErrorMode : //public terminate_state<>
- public interrupt_state<end_error,my_visitable_state>
- {
- template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: ErrorMode" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: ErrorMode" << std::endl;}
- };
-
- // the initial state of the player SM. Must be defined
- typedef mpl::vector<Empty,AllOk> initial_state;
- //typedef Empty initial_state; // this is to have only one active state
+ // 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
+ struct Song1 : public state_machine<Song1,NoHistory,my_visitable_state>
+ {
+ typedef mpl::vector1<FirstSongPlaying> flag_list;
+ template <class Event>
+ 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()
+ {
+ std::cout << "visiting state:" << typeid(*this).name() << std::endl;
+ }
+ struct LightOn : public state<my_visitable_state>
+ {
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "starting: LightOn" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: LightOn" << std::endl;}
+ };
+ struct LightOff : public state<my_visitable_state>
+ {
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "starting: LightOff" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: LightOff" << std::endl;}
+ };
+ // the initial state. Must be defined
+ typedef LightOn initial_state;
+ // transition actions
+ void turn_light_off(ThreeSec const&) { std::cout << "3s off::turn light off\n"; }
+ // guard conditions
+
+ // friend definition needed.
+ friend class state_machine<Song1>;
+ typedef Song1 s; // makes transition table cleaner
+ // Transition table for Song1
+ struct transition_table : mpl::vector1<
+ // Start Event Next Action Guard
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < LightOn , ThreeSec , LightOff, &s::turn_light_off >
+ // +---------+-------------+---------+---------------------+----------------------+
+ > {};
+ // Replaces the default no-transition response.
+ template <class Event>
+ int no_transition(int state, Event const& )
+ {
+ std::cout << "no transition from state " << state
+ << " on event " << typeid(Event).name() << std::endl;
+ return state;
+ }
+
+ };
+ struct Song2 : public state<my_visitable_state>
+ {
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "starting: Second song" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: Second Song" << std::endl;}
+ };
+ struct Song3 : public state<my_visitable_state>
+ {
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "starting: Third song" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: Third Song" << std::endl;}
+ };
+ // the initial state. Must be defined
+ typedef Song1 initial_state;
+ // transition actions
+ void start_next_song(NextSong const&) { std::cout << "Playing::start_next_song\n"; }
+ void start_prev_song(PreviousSong const&) { std::cout << "Playing::start_prev_song\n"; }
+ // guard conditions
+
+ // friend definition needed.
+ friend class state_machine<Playing>;
+ typedef Playing pl; // makes transition table cleaner
+ // Transition table for Playing
+ struct transition_table : mpl::vector4<
+ // Start Event Next Action Guard
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Song1 , NextSong , Song2 , &pl::start_next_song >,
+ a_row < Song2 , PreviousSong, Song1 , &pl::start_prev_song >,
+ a_row < Song2 , NextSong , Song3 , &pl::start_next_song >,
+ a_row < Song3 , PreviousSong, Song2 , &pl::start_prev_song >
+ // +---------+-------------+---------+---------------------+----------------------+
+ > {};
+ // Replaces the default no-transition response.
+ template <class Event>
+ int no_transition(int state, Event const&)
+ {
+ std::cout << "no transition from state " << state
+ << " on event " << typeid(Event).name() << std::endl;
+ return state;
+ }
+ };
+ // the player state machine contains a state which is himself a state machine (2 of them, Playing and Paused)
+ struct Paused : public state_machine<Paused,NoHistory,my_visitable_state>
+ {
+ typedef mpl::vector2<PlayingPaused,CDLoaded> flag_list;
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "entering: Paused" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "leaving: Paused" << std::endl;}
+
+ // The list of FSM states
+ struct StartBlinking : public state<my_visitable_state>
+ {
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "starting: StartBlinking" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: StartBlinking" << std::endl;}
+ };
+ struct StopBlinking : public state<my_visitable_state>
+ {
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "starting: StopBlinking" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: StopBlinking" << std::endl;}
+ };
+ // the initial state. Must be defined
+ typedef StartBlinking initial_state;
+ // transition actions
+ void start_blinking(TenSec const&) { std::cout << "Paused::start_blinking\n"; }
+ void stop_blinking(TenSec const&) { std::cout << "Paused::stop_blinking\n"; }
+ // guard conditions
+
+ // friend definition needed.
+ friend class state_machine<Paused>;
+ typedef Paused pa; // makes transition table cleaner
+ // Transition table
+ struct transition_table : mpl::vector2<
+ // Start Event Next Action Guard
+ // +---------------+-------------+--------------+---------------------+----------------------+
+ a_row < StartBlinking , TenSec , StopBlinking , &pa::stop_blinking >,
+ a_row < StopBlinking , TenSec , StartBlinking , &pa::start_blinking >
+ // +---------------+-------------+---------------+--------------------+----------------------+
+ > {};
+ // Replaces the default no-transition response.
+ template <class Event>
+ int no_transition(int state, Event const& )
+ {
+ std::cout << "no transition from state " << state
+ << " on event " << typeid(Event).name() << std::endl;
+ return state;
+ }
+ };
+ struct SleepMode : public state<my_visitable_state> {}; // dumy state just to test the automatic id generation
+
+ struct AllOk : public state<my_visitable_state>
+ {
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "starting: AllOk" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: AllOk" << std::endl;}
+ };
+ struct ErrorMode : //public terminate_state<>
+ public interrupt_state<end_error,my_visitable_state>
+ {
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "starting: ErrorMode" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: ErrorMode" << std::endl;}
+ };
+
+ // the initial state of the player SM. Must be defined
+ typedef mpl::vector<Empty,AllOk> initial_state;
+ //typedef Empty initial_state; // this is to have only one active state
 
 #ifdef __MWERKS__
- public: // Codewarrior bug workaround. Tested at 0x3202
+ public: // Codewarrior bug workaround. Tested at 0x3202
 #endif
- // transition actions
- void start_playback(play const&) { std::cout << "player::start_playback\n"; }
- void open_drawer(open_close const&) { std::cout << "player::open_drawer\n"; }
- void close_drawer(open_close const&) { std::cout << "player::close_drawer\n"; }
- void store_cd_info(cd_detected const&)
- {
- std::cout << "player::store_cd_info\n";
- // generate another event to test the queue
- //cd.m_player.process_event(play());
- }
- void stop_playback(stop const&) { std::cout << "player::stop_playback\n"; }
- void pause_playback(pause const&) { std::cout << "player::pause_playback\n"; }
- void resume_playback(end_pause const&) { std::cout << "player::resume_playback\n"; }
- void stop_and_open(open_close const&) { std::cout << "player::stop_and_open\n"; }
- void stopped_again(stop const&) {std::cout << "player::stopped_again\n";}
- void start_sleep(go_sleep const&) { }
- void report_error(error_found const&) {std::cout << "player::report_error\n";}
- void report_end_error(end_error const&) {std::cout << "player::report_end_error\n";}
- // guard conditions
+ // transition actions
+ void start_playback(play const&) { std::cout << "player::start_playback\n"; }
+ void open_drawer(open_close const&) { std::cout << "player::open_drawer\n"; }
+ void close_drawer(open_close const&) { std::cout << "player::close_drawer\n"; }
+ void store_cd_info(cd_detected const&)
+ {
+ std::cout << "player::store_cd_info\n";
+ // generate another event to test the queue
+ //cd.m_player.process_event(play());
+ }
+ void stop_playback(stop const&) { std::cout << "player::stop_playback\n"; }
+ void pause_playback(pause const&) { std::cout << "player::pause_playback\n"; }
+ void resume_playback(end_pause const&) { std::cout << "player::resume_playback\n"; }
+ void stop_and_open(open_close const&) { std::cout << "player::stop_and_open\n"; }
+ void stopped_again(stop const&) {std::cout << "player::stopped_again\n";}
+ void start_sleep(go_sleep const&) { }
+ void report_error(error_found const&) {std::cout << "player::report_error\n";}
+ void report_end_error(end_error const&) {std::cout << "player::report_end_error\n";}
+ // guard conditions
 
 
 #ifdef __MWERKS__
- private:
+ private:
 #endif
- // friend definition needed.
- friend class state_machine<player>;
- typedef player p; // makes transition table cleaner
-
- // Transition table for player
- struct transition_table : mpl::vector<
- // Start Event Next Action Guard
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Stopped , play , Playing , &p::start_playback >,
- a_row < Stopped , open_close , Open , &p::open_drawer >,
- a_row < Stopped , stop , Stopped , &p::stopped_again >,
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Open , open_close , Empty , &p::close_drawer >,
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Empty , open_close , Open , &p::open_drawer >,
- a_row < Empty , cd_detected , Stopped , &p::store_cd_info >,
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Playing , stop , Stopped , &p::stop_playback >,
- a_row < Playing , pause , Paused , &p::pause_playback >,
- a_row < Playing , open_close , Open , &p::stop_and_open >,
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Paused , end_pause , Playing , &p::resume_playback >,
- a_row < Paused , stop , Stopped , &p::stop_playback >,
- a_row < Paused , open_close , Open , &p::stop_and_open >,
- a_row < Paused , go_sleep ,SleepMode, &p::start_sleep >,
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < AllOk , error_found ,ErrorMode, &p::report_error >,
- a_row <ErrorMode,end_error ,AllOk , &p::report_end_error >
- // +---------+-------------+---------+---------------------+----------------------+
- > {};
-
- // Replaces the default no-transition response.
- template <class Event>
- int no_transition(int state, Event const& )
- {
- std::cout << "no transition from state " << state
- << " on event " << typeid(Event).name() << std::endl;
- return state;
- }
- };
-
- //
- // Testing utilities.
- //
-
- void pstate(player const& p)
- {
- // instead of the hard-coded array we can use fill_state_names:
- //static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused","AllOk","ErrorMode","SleepMode" };
- typedef player::transition_table stt;
- typedef generate_state_set<stt>::type all_states;
- static char const* state_names[mpl::size<all_states>::value];
- // fill the names of the states defined in the state machine
- mpl::for_each<all_states,boost::msm::wrap<mpl::placeholders::_1> >(fill_state_names<stt>(state_names));
-
- for (unsigned int i=0;i<p.current_state().size();++i)
- {
- std::cout << " -> " << state_names[p.current_state()[i]] << std::endl;
- }
- }
- void test()
- {
- player p;
- // get a pointer to a state
- // just to show how to do it as Stopped gets a pointer to player anyway
- player::Stopped* tempstate = p.get_state<player::Stopped*>();
- tempstate->m_player = &p;
- // get a reference to a state
- player::Stopped& tempstate2 = p.get_state<player::Stopped&>();
- tempstate2.m_player = &p;
- // make a copy of a state
- player::Stopped tempstate3 = p.get_state<player::Stopped&>();
-
- // needed to start the highest-level SM. This will call on_entry and mark the start of the SM
- p.start();
- std::cout << "CDLoaded active:" << std::boolalpha << p.is_flag_active<CDLoaded>() << std::endl; //=> false (no CD yet)
-
- // test deferred event
- // deferred in Empty and Open, will be handled only after event cd_detected
- p.process_event(play());
-
- // 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
- p.visit_current_states();
- p.process_event(open_close()); pstate(p);
- // visiting Empty and AllOk, but only Empty cares
- p.visit_current_states();
-
-
- p.process_event(cd_detected("louie, louie",p));
- // no need to call play() as the previous event does it in its action method
- //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();
-
- 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
- p.process_event(pause()); pstate(p);
- std::cout << "PlayingPaused active:" << std::boolalpha << p.is_flag_active<PlayingPaused>() << std::endl;//=> true
- // forward events to Paused
- p.process_event(TenSec());
- p.process_event(TenSec());
- // go back to Playing
- p.process_event(end_pause()); pstate(p);
- std::cout << "FirstSong active:" << std::boolalpha << p.is_flag_active<FirstSongPlaying>() << std::endl; //=> true
- p.process_event(ThreeSec()); pstate(p);
- 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();
-
- p.process_event(NextSong());pstate(p);
- // 2nd song active
- p.process_event(PreviousSong());pstate(p);
- // Pause
- p.process_event(pause()); pstate(p);
- // go back to Playing
- // but end_pause is an event activating the History
- // => keep the last active State (SecondSong)
- p.process_event(end_pause()); pstate(p);
- // test of an event from a state to itself. According to UML spec, call again exit/entry from Stopped
- p.process_event(stop()); pstate(p);
- p.process_event(stop()); pstate(p);
- std::cout << "CDLoaded active:" << std::boolalpha << p.is_flag_active<CDLoaded>() << std::endl;//=> true
- std::cout << "PlayingPaused active:" << std::boolalpha << p.is_flag_active<PlayingPaused>() << std::endl;//=> false
- std::cout << "FirstSong active:" << std::boolalpha << p.is_flag_active<FirstSongPlaying>() << std::endl;//=> false
- std::cout << "CDLoaded active with AND:" << std::boolalpha << p.is_flag_active<CDLoaded,player::Flag_AND>() << std::endl;//=> false
- std::cout << "CDLoaded active with OR:" << std::boolalpha << p.is_flag_active<CDLoaded,player::Flag_OR>() << std::endl;//=> true
-
- // go back to Playing
- // but play is not leading to Shallow History => do not remember the last active State (SecondSong)
- // and activate again FirstSong and LightOn
- p.process_event(play()); pstate(p);
- p.process_event(error_found()); pstate(p);
-
- // try generating more events
- std::cout << "Trying to generate another event" << std::endl; // will not work, fsm is terminated or interrupted
- p.process_event(NextSong());pstate(p);
-
- std::cout << "Trying to end the error" << std::endl; // will work only if ErrorMode is interrupt state
- p.process_event(end_error());pstate(p);
- std::cout << "Trying to generate another event" << std::endl; // will work only if ErrorMode is interrupt state
- p.process_event(NextSong());pstate(p);
-
- std::cout << "Simulate error. Event play is not valid" << std::endl;
- p.process_event(play()); pstate(p);
- }
+ // friend definition needed.
+ friend class state_machine<player>;
+ typedef player p; // makes transition table cleaner
+
+ // Transition table for player
+ struct transition_table : mpl::vector<
+ // Start Event Next Action Guard
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Stopped , play , Playing , &p::start_playback >,
+ a_row < Stopped , open_close , Open , &p::open_drawer >,
+ a_row < Stopped , stop , Stopped , &p::stopped_again >,
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Open , open_close , Empty , &p::close_drawer >,
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Empty , open_close , Open , &p::open_drawer >,
+ a_row < Empty , cd_detected , Stopped , &p::store_cd_info >,
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Playing , stop , Stopped , &p::stop_playback >,
+ a_row < Playing , pause , Paused , &p::pause_playback >,
+ a_row < Playing , open_close , Open , &p::stop_and_open >,
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Paused , end_pause , Playing , &p::resume_playback >,
+ a_row < Paused , stop , Stopped , &p::stop_playback >,
+ a_row < Paused , open_close , Open , &p::stop_and_open >,
+ a_row < Paused , go_sleep ,SleepMode, &p::start_sleep >,
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < AllOk , error_found ,ErrorMode, &p::report_error >,
+ a_row <ErrorMode,end_error ,AllOk , &p::report_end_error >
+ // +---------+-------------+---------+---------------------+----------------------+
+ > {};
+
+ // Replaces the default no-transition response.
+ template <class Event>
+ int no_transition(int state, Event const& )
+ {
+ std::cout << "no transition from state " << state
+ << " on event " << typeid(Event).name() << std::endl;
+ return state;
+ }
+ };
+
+ //
+ // Testing utilities.
+ //
+
+ void pstate(player const& p)
+ {
+ // instead of the hard-coded array we can use fill_state_names:
+ //static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused","AllOk","ErrorMode","SleepMode" };
+ typedef player::transition_table stt;
+ typedef generate_state_set<stt>::type all_states;
+ static char const* state_names[mpl::size<all_states>::value];
+ // fill the names of the states defined in the state machine
+ mpl::for_each<all_states,boost::msm::wrap<mpl::placeholders::_1> >(fill_state_names<stt>(state_names));
+
+ for (unsigned int i=0;i<p.current_state().size();++i)
+ {
+ std::cout << " -> " << state_names[p.current_state()[i]] << std::endl;
+ }
+ }
+ void test()
+ {
+ player p;
+ // get a pointer to a state
+ // just to show how to do it as Stopped gets a pointer to player anyway
+ player::Stopped* tempstate = p.get_state<player::Stopped*>();
+ tempstate->m_player = &p;
+ // get a reference to a state
+ player::Stopped& tempstate2 = p.get_state<player::Stopped&>();
+ tempstate2.m_player = &p;
+ // make a copy of a state
+ player::Stopped tempstate3 = p.get_state<player::Stopped&>();
+
+ // needed to start the highest-level SM. This will call on_entry and mark the start of the SM
+ p.start();
+ std::cout << "CDLoaded active:" << std::boolalpha << p.is_flag_active<CDLoaded>() << std::endl; //=> false (no CD yet)
+
+ // test deferred event
+ // deferred in Empty and Open, will be handled only after event cd_detected
+ p.process_event(play());
+
+ // 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
+ p.visit_current_states();
+ p.process_event(open_close()); pstate(p);
+ // visiting Empty and AllOk, but only Empty cares
+ p.visit_current_states();
+
+
+ p.process_event(cd_detected("louie, louie",p));
+ // no need to call play() as the previous event does it in its action method
+ //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();
+
+ 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
+ p.process_event(pause()); pstate(p);
+ std::cout << "PlayingPaused active:" << std::boolalpha << p.is_flag_active<PlayingPaused>() << std::endl;//=> true
+ // forward events to Paused
+ p.process_event(TenSec());
+ p.process_event(TenSec());
+ // go back to Playing
+ p.process_event(end_pause()); pstate(p);
+ std::cout << "FirstSong active:" << std::boolalpha << p.is_flag_active<FirstSongPlaying>() << std::endl; //=> true
+ p.process_event(ThreeSec()); pstate(p);
+ 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();
+
+ p.process_event(NextSong());pstate(p);
+ // 2nd song active
+ p.process_event(PreviousSong());pstate(p);
+ // Pause
+ p.process_event(pause()); pstate(p);
+ // go back to Playing
+ // but end_pause is an event activating the History
+ // => keep the last active State (SecondSong)
+ p.process_event(end_pause()); pstate(p);
+ // test of an event from a state to itself. According to UML spec, call again exit/entry from Stopped
+ p.process_event(stop()); pstate(p);
+ p.process_event(stop()); pstate(p);
+ std::cout << "CDLoaded active:" << std::boolalpha << p.is_flag_active<CDLoaded>() << std::endl;//=> true
+ std::cout << "PlayingPaused active:" << std::boolalpha << p.is_flag_active<PlayingPaused>() << std::endl;//=> false
+ std::cout << "FirstSong active:" << std::boolalpha << p.is_flag_active<FirstSongPlaying>() << std::endl;//=> false
+ std::cout << "CDLoaded active with AND:" << std::boolalpha << p.is_flag_active<CDLoaded,player::Flag_AND>() << std::endl;//=> false
+ std::cout << "CDLoaded active with OR:" << std::boolalpha << p.is_flag_active<CDLoaded,player::Flag_OR>() << std::endl;//=> true
+
+ // go back to Playing
+ // but play is not leading to Shallow History => do not remember the last active State (SecondSong)
+ // and activate again FirstSong and LightOn
+ p.process_event(play()); pstate(p);
+ p.process_event(error_found()); pstate(p);
+
+ // try generating more events
+ std::cout << "Trying to generate another event" << std::endl; // will not work, fsm is terminated or interrupted
+ p.process_event(NextSong());pstate(p);
+
+ std::cout << "Trying to end the error" << std::endl; // will work only if ErrorMode is interrupt state
+ p.process_event(end_error());pstate(p);
+ std::cout << "Trying to generate another event" << std::endl; // will work only if ErrorMode is interrupt state
+ p.process_event(NextSong());pstate(p);
+
+ std::cout << "Simulate error. Event play is not valid" << std::endl;
+ p.process_event(play()); pstate(p);
+ }
 }
 
 int main()

Modified: sandbox/msm/libs/msm/doc/SM-1arg.cpp
==============================================================================
--- sandbox/msm/libs/msm/doc/SM-1arg.cpp (original)
+++ sandbox/msm/libs/msm/doc/SM-1arg.cpp 2009-02-16 16:49:41 EST (Mon, 16 Feb 2009)
@@ -10,473 +10,473 @@
 
 namespace // Concrete FSM implementation
 {
- // events
- struct play {};
- struct end_pause {};
- struct stop {};
- struct pause {};
- struct open_close {};
- struct NextSong {};
- struct PreviousSong {};
- struct ThreeSec {};
- struct TenSec {};
- struct go_sleep {};
- struct error_found {};
- struct end_error {};
-
- // Flags. Allow information about a property of the current state
- struct PlayingPaused{};
- struct CDLoaded {};
- struct FirstSongPlaying {};
-
- // A "complicated" event type that carries some data.
- // forward
- struct player;
- struct cd_detected
- {
- cd_detected(std::string name, player& p)
- : name(name)
- , m_player(p)
- {}
-
- std::string name;
- player& m_player;
- };
-
- // an easy visitor
- struct SomeVisitor
- {
- template <class T>
- void visit_state(T* astate)
- {
- std::cout << "visiting state:" << typeid(*astate).name() << std::endl;
- }
- };
- // overwrite of the base state (not default)
- struct my_visitable_state
- {
- // signature of the accept function
- typedef args<void,SomeVisitor&> accept_sig;
-
- // we also want polymorphic states
- virtual ~my_visitable_state() {}
- // default implementation for states who do not need to be visited
- void accept(SomeVisitor&) const {}
- };
-
- // Concrete FSM implementation
- struct player : public state_machine<player,NoHistory,my_visitable_state>
- {
- // The list of FSM states
- struct Empty : public state<my_visitable_state>
- {
- typedef mpl::vector<play> deferred_events;
- // every (optional) entry/exit methods get the event packed as boost::any. Not useful very often.
- template <class Event>
- 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;}
+ // events
+ struct play {};
+ struct end_pause {};
+ struct stop {};
+ struct pause {};
+ struct open_close {};
+ struct NextSong {};
+ struct PreviousSong {};
+ struct ThreeSec {};
+ struct TenSec {};
+ struct go_sleep {};
+ struct error_found {};
+ struct end_error {};
+
+ // Flags. Allow information about a property of the current state
+ struct PlayingPaused{};
+ struct CDLoaded {};
+ struct FirstSongPlaying {};
+
+ // A "complicated" event type that carries some data.
+ // forward
+ struct player;
+ struct cd_detected
+ {
+ cd_detected(std::string name, player& p)
+ : name(name)
+ , m_player(p)
+ {}
+
+ std::string name;
+ player& m_player;
+ };
+
+ // an easy visitor
+ struct SomeVisitor
+ {
+ template <class T>
+ void visit_state(T* astate)
+ {
+ std::cout << "visiting state:" << typeid(*astate).name() << std::endl;
+ }
+ };
+ // overwrite of the base state (not default)
+ struct my_visitable_state
+ {
+ // signature of the accept function
+ typedef args<void,SomeVisitor&> accept_sig;
+
+ // we also want polymorphic states
+ virtual ~my_visitable_state() {}
+ // default implementation for states who do not need to be visited
+ void accept(SomeVisitor&) const {}
+ };
+
+ // Concrete FSM implementation
+ struct player : public state_machine<player,NoHistory,my_visitable_state>
+ {
+ // The list of FSM states
+ struct Empty : public state<my_visitable_state>
+ {
+ typedef mpl::vector<play> deferred_events;
+ // every (optional) entry/exit methods get the event packed as boost::any. Not useful very often.
+ template <class Event>
+ 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(SomeVisitor& vis) const
             {
                 vis.visit_state(this);
             }
- };
- struct Open : public state<my_visitable_state>
- {
- typedef mpl::vector1<CDLoaded> flag_list;
- typedef mpl::vector<play> deferred_events;
- template <class Event>
- 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;}
+ };
+ struct Open : public state<my_visitable_state>
+ {
+ typedef mpl::vector1<CDLoaded> flag_list;
+ typedef mpl::vector<play> deferred_events;
+ template <class Event>
+ 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(SomeVisitor& vis) const
             {
                 vis.visit_state(this);
             }
- };
- // a state needing a pointer to the containing state machine
- // and using for this the non-default policy
- // if policy used, set_sm_ptr is needed
- struct Stopped : public state<my_visitable_state,SMPtr>
- {
- // when stopped, the CD is loaded
- typedef mpl::vector1<CDLoaded> flag_list;
- template <class Event>
- void on_entry(Event const& ) {std::cout << "entering: Stopped" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "leaving: Stopped" << std::endl;}
- void set_sm_ptr(player* pl){m_player=pl;}
- player* m_player;
- };
- // the player state machine contains a state which is himself a state machine
- // it demonstrates Shallow History: if the state gets activated with end_pause
- // 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> >,my_visitable_state >
- {
- // when playing, the CD is loaded and we are in either pause or playing (duh)
- typedef mpl::vector2<PlayingPaused,CDLoaded> flag_list;
- template <class Event>
- 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;}
+ };
+ // a state needing a pointer to the containing state machine
+ // and using for this the non-default policy
+ // if policy used, set_sm_ptr is needed
+ struct Stopped : public state<my_visitable_state,SMPtr>
+ {
+ // when stopped, the CD is loaded
+ typedef mpl::vector1<CDLoaded> flag_list;
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "entering: Stopped" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "leaving: Stopped" << std::endl;}
+ void set_sm_ptr(player* pl){m_player=pl;}
+ player* m_player;
+ };
+ // the player state machine contains a state which is himself a state machine
+ // it demonstrates Shallow History: if the state gets activated with end_pause
+ // 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> >,my_visitable_state >
+ {
+ // when playing, the CD is loaded and we are in either pause or playing (duh)
+ typedef mpl::vector2<PlayingPaused,CDLoaded> flag_list;
+ template <class Event>
+ 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(SomeVisitor& vis)
             {
                 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
- struct Song1 : public state_machine<Song1,NoHistory,my_visitable_state>
- {
- typedef mpl::vector1<FirstSongPlaying> flag_list;
- template <class Event>
- 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(SomeVisitor& vis)
- {
- vis.visit_state(this);
- }
- struct LightOn : public state<my_visitable_state>
- {
- template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: LightOn" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: LightOn" << std::endl;}
- };
- struct LightOff : public state<my_visitable_state>
- {
- template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: LightOff" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: LightOff" << std::endl;}
- };
- // the initial state. Must be defined
- typedef LightOn initial_state;
- // transition actions
- void turn_light_off(ThreeSec const&) { std::cout << "3s off::turn light off\n"; }
- // guard conditions
-
- // friend definition needed.
- friend class state_machine<Song1>;
- typedef Song1 s; // makes transition table cleaner
- // Transition table for Song1
- struct transition_table : mpl::vector1<
- // Start Event Next Action Guard
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < LightOn , ThreeSec , LightOff, &s::turn_light_off >
- // +---------+-------------+---------+---------------------+----------------------+
- > {};
- // Replaces the default no-transition response.
- template <class Event>
- int no_transition(int state, Event const& )
- {
- std::cout << "no transition from state " << state
- << " on event " << typeid(Event).name() << std::endl;
- return state;
- }
-
- };
- struct Song2 : public state<my_visitable_state>
- {
- template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: Second song" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: Second Song" << std::endl;}
- };
- struct Song3 : public state<my_visitable_state>
- {
- template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: Third song" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: Third Song" << std::endl;}
- };
- // the initial state. Must be defined
- typedef Song1 initial_state;
- // transition actions
- void start_next_song(NextSong const&) { std::cout << "Playing::start_next_song\n"; }
- void start_prev_song(PreviousSong const&) { std::cout << "Playing::start_prev_song\n"; }
- // guard conditions
-
- // friend definition needed.
- friend class state_machine<Playing>;
- typedef Playing pl; // makes transition table cleaner
- // Transition table for Playing
- struct transition_table : mpl::vector4<
- // Start Event Next Action Guard
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Song1 , NextSong , Song2 , &pl::start_next_song >,
- a_row < Song2 , PreviousSong, Song1 , &pl::start_prev_song >,
- a_row < Song2 , NextSong , Song3 , &pl::start_next_song >,
- a_row < Song3 , PreviousSong, Song2 , &pl::start_prev_song >
- // +---------+-------------+---------+---------------------+----------------------+
- > {};
- // Replaces the default no-transition response.
- template <class Event>
- int no_transition(int state, Event const&)
- {
- std::cout << "no transition from state " << state
- << " on event " << typeid(Event).name() << std::endl;
- return state;
- }
- };
- // the player state machine contains a state which is himself a state machine (2 of them, Playing and Paused)
- struct Paused : public state_machine<Paused,NoHistory,my_visitable_state>
- {
- typedef mpl::vector2<PlayingPaused,CDLoaded> flag_list;
- template <class Event>
- void on_entry(Event const& ) {std::cout << "entering: Paused" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "leaving: Paused" << std::endl;}
-
- // The list of FSM states
- struct StartBlinking : public state<my_visitable_state>
- {
- template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: StartBlinking" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: StartBlinking" << std::endl;}
- };
- struct StopBlinking : public state<my_visitable_state>
- {
- template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: StopBlinking" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: StopBlinking" << std::endl;}
- };
- // the initial state. Must be defined
- typedef StartBlinking initial_state;
- // transition actions
- void start_blinking(TenSec const&) { std::cout << "Paused::start_blinking\n"; }
- void stop_blinking(TenSec const&) { std::cout << "Paused::stop_blinking\n"; }
- // guard conditions
-
- // friend definition needed.
- friend class state_machine<Paused>;
- typedef Paused pa; // makes transition table cleaner
- // Transition table
- struct transition_table : mpl::vector2<
- // Start Event Next Action Guard
- // +---------------+-------------+--------------+---------------------+----------------------+
- a_row < StartBlinking , TenSec , StopBlinking , &pa::stop_blinking >,
- a_row < StopBlinking , TenSec , StartBlinking , &pa::start_blinking >
- // +---------------+-------------+---------------+--------------------+----------------------+
- > {};
- // Replaces the default no-transition response.
- template <class Event>
- int no_transition(int state, Event const& )
- {
- std::cout << "no transition from state " << state
- << " on event " << typeid(Event).name() << std::endl;
- return state;
- }
- };
- struct SleepMode : public state<my_visitable_state> {}; // dumy state just to test the automatic id generation
-
- struct AllOk : public state<my_visitable_state>
- {
- template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: AllOk" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: AllOk" << std::endl;}
- };
- struct ErrorMode : //public terminate_state<>
- public interrupt_state<end_error,my_visitable_state>
- {
- template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: ErrorMode" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: ErrorMode" << std::endl;}
- };
-
- // the initial state of the player SM. Must be defined
- typedef mpl::vector<Empty,AllOk> initial_state;
- //typedef Empty initial_state; // this is to have only one active state
+ // 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
+ struct Song1 : public state_machine<Song1,NoHistory,my_visitable_state>
+ {
+ typedef mpl::vector1<FirstSongPlaying> flag_list;
+ template <class Event>
+ 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(SomeVisitor& vis)
+ {
+ vis.visit_state(this);
+ }
+ struct LightOn : public state<my_visitable_state>
+ {
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "starting: LightOn" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: LightOn" << std::endl;}
+ };
+ struct LightOff : public state<my_visitable_state>
+ {
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "starting: LightOff" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: LightOff" << std::endl;}
+ };
+ // the initial state. Must be defined
+ typedef LightOn initial_state;
+ // transition actions
+ void turn_light_off(ThreeSec const&) { std::cout << "3s off::turn light off\n"; }
+ // guard conditions
+
+ // friend definition needed.
+ friend class state_machine<Song1>;
+ typedef Song1 s; // makes transition table cleaner
+ // Transition table for Song1
+ struct transition_table : mpl::vector1<
+ // Start Event Next Action Guard
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < LightOn , ThreeSec , LightOff, &s::turn_light_off >
+ // +---------+-------------+---------+---------------------+----------------------+
+ > {};
+ // Replaces the default no-transition response.
+ template <class Event>
+ int no_transition(int state, Event const& )
+ {
+ std::cout << "no transition from state " << state
+ << " on event " << typeid(Event).name() << std::endl;
+ return state;
+ }
+
+ };
+ struct Song2 : public state<my_visitable_state>
+ {
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "starting: Second song" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: Second Song" << std::endl;}
+ };
+ struct Song3 : public state<my_visitable_state>
+ {
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "starting: Third song" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: Third Song" << std::endl;}
+ };
+ // the initial state. Must be defined
+ typedef Song1 initial_state;
+ // transition actions
+ void start_next_song(NextSong const&) { std::cout << "Playing::start_next_song\n"; }
+ void start_prev_song(PreviousSong const&) { std::cout << "Playing::start_prev_song\n"; }
+ // guard conditions
+
+ // friend definition needed.
+ friend class state_machine<Playing>;
+ typedef Playing pl; // makes transition table cleaner
+ // Transition table for Playing
+ struct transition_table : mpl::vector4<
+ // Start Event Next Action Guard
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Song1 , NextSong , Song2 , &pl::start_next_song >,
+ a_row < Song2 , PreviousSong, Song1 , &pl::start_prev_song >,
+ a_row < Song2 , NextSong , Song3 , &pl::start_next_song >,
+ a_row < Song3 , PreviousSong, Song2 , &pl::start_prev_song >
+ // +---------+-------------+---------+---------------------+----------------------+
+ > {};
+ // Replaces the default no-transition response.
+ template <class Event>
+ int no_transition(int state, Event const&)
+ {
+ std::cout << "no transition from state " << state
+ << " on event " << typeid(Event).name() << std::endl;
+ return state;
+ }
+ };
+ // the player state machine contains a state which is himself a state machine (2 of them, Playing and Paused)
+ struct Paused : public state_machine<Paused,NoHistory,my_visitable_state>
+ {
+ typedef mpl::vector2<PlayingPaused,CDLoaded> flag_list;
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "entering: Paused" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "leaving: Paused" << std::endl;}
+
+ // The list of FSM states
+ struct StartBlinking : public state<my_visitable_state>
+ {
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "starting: StartBlinking" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: StartBlinking" << std::endl;}
+ };
+ struct StopBlinking : public state<my_visitable_state>
+ {
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "starting: StopBlinking" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: StopBlinking" << std::endl;}
+ };
+ // the initial state. Must be defined
+ typedef StartBlinking initial_state;
+ // transition actions
+ void start_blinking(TenSec const&) { std::cout << "Paused::start_blinking\n"; }
+ void stop_blinking(TenSec const&) { std::cout << "Paused::stop_blinking\n"; }
+ // guard conditions
+
+ // friend definition needed.
+ friend class state_machine<Paused>;
+ typedef Paused pa; // makes transition table cleaner
+ // Transition table
+ struct transition_table : mpl::vector2<
+ // Start Event Next Action Guard
+ // +---------------+-------------+--------------+---------------------+----------------------+
+ a_row < StartBlinking , TenSec , StopBlinking , &pa::stop_blinking >,
+ a_row < StopBlinking , TenSec , StartBlinking , &pa::start_blinking >
+ // +---------------+-------------+---------------+--------------------+----------------------+
+ > {};
+ // Replaces the default no-transition response.
+ template <class Event>
+ int no_transition(int state, Event const& )
+ {
+ std::cout << "no transition from state " << state
+ << " on event " << typeid(Event).name() << std::endl;
+ return state;
+ }
+ };
+ struct SleepMode : public state<my_visitable_state> {}; // dumy state just to test the automatic id generation
+
+ struct AllOk : public state<my_visitable_state>
+ {
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "starting: AllOk" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: AllOk" << std::endl;}
+ };
+ struct ErrorMode : //public terminate_state<>
+ public interrupt_state<end_error,my_visitable_state>
+ {
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "starting: ErrorMode" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: ErrorMode" << std::endl;}
+ };
+
+ // the initial state of the player SM. Must be defined
+ typedef mpl::vector<Empty,AllOk> initial_state;
+ //typedef Empty initial_state; // this is to have only one active state
 
 #ifdef __MWERKS__
- public: // Codewarrior bug workaround. Tested at 0x3202
+ public: // Codewarrior bug workaround. Tested at 0x3202
 #endif
- // transition actions
- void start_playback(play const&) { std::cout << "player::start_playback\n"; }
- void open_drawer(open_close const&) { std::cout << "player::open_drawer\n"; }
- void close_drawer(open_close const&) { std::cout << "player::close_drawer\n"; }
- void store_cd_info(cd_detected const&)
- {
- std::cout << "player::store_cd_info\n";
- // generate another event to test the queue
- //cd.m_player.process_event(play());
- }
- void stop_playback(stop const&) { std::cout << "player::stop_playback\n"; }
- void pause_playback(pause const&) { std::cout << "player::pause_playback\n"; }
- void resume_playback(end_pause const&) { std::cout << "player::resume_playback\n"; }
- void stop_and_open(open_close const&) { std::cout << "player::stop_and_open\n"; }
- void stopped_again(stop const&) {std::cout << "player::stopped_again\n";}
- void start_sleep(go_sleep const&) { }
- void report_error(error_found const&) {std::cout << "player::report_error\n";}
- void report_end_error(end_error const&) {std::cout << "player::report_end_error\n";}
- // guard conditions
+ // transition actions
+ void start_playback(play const&) { std::cout << "player::start_playback\n"; }
+ void open_drawer(open_close const&) { std::cout << "player::open_drawer\n"; }
+ void close_drawer(open_close const&) { std::cout << "player::close_drawer\n"; }
+ void store_cd_info(cd_detected const&)
+ {
+ std::cout << "player::store_cd_info\n";
+ // generate another event to test the queue
+ //cd.m_player.process_event(play());
+ }
+ void stop_playback(stop const&) { std::cout << "player::stop_playback\n"; }
+ void pause_playback(pause const&) { std::cout << "player::pause_playback\n"; }
+ void resume_playback(end_pause const&) { std::cout << "player::resume_playback\n"; }
+ void stop_and_open(open_close const&) { std::cout << "player::stop_and_open\n"; }
+ void stopped_again(stop const&) {std::cout << "player::stopped_again\n";}
+ void start_sleep(go_sleep const&) { }
+ void report_error(error_found const&) {std::cout << "player::report_error\n";}
+ void report_end_error(end_error const&) {std::cout << "player::report_end_error\n";}
+ // guard conditions
 
 
 #ifdef __MWERKS__
- private:
+ private:
 #endif
- // friend definition needed.
- friend class state_machine<player>;
- typedef player p; // makes transition table cleaner
-
- // Transition table for player
- struct transition_table : mpl::vector<
- // Start Event Next Action Guard
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Stopped , play , Playing , &p::start_playback >,
- a_row < Stopped , open_close , Open , &p::open_drawer >,
- a_row < Stopped , stop , Stopped , &p::stopped_again >,
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Open , open_close , Empty , &p::close_drawer >,
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Empty , open_close , Open , &p::open_drawer >,
- a_row < Empty , cd_detected , Stopped , &p::store_cd_info >,
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Playing , stop , Stopped , &p::stop_playback >,
- a_row < Playing , pause , Paused , &p::pause_playback >,
- a_row < Playing , open_close , Open , &p::stop_and_open >,
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Paused , end_pause , Playing , &p::resume_playback >,
- a_row < Paused , stop , Stopped , &p::stop_playback >,
- a_row < Paused , open_close , Open , &p::stop_and_open >,
- a_row < Paused , go_sleep ,SleepMode, &p::start_sleep >,
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < AllOk , error_found ,ErrorMode, &p::report_error >,
- a_row <ErrorMode,end_error ,AllOk , &p::report_end_error >
- // +---------+-------------+---------+---------------------+----------------------+
- > {};
-
- // Replaces the default no-transition response.
- template <class Event>
- int no_transition(int state, Event const& )
- {
- std::cout << "no transition from state " << state
- << " on event " << typeid(Event).name() << std::endl;
- return state;
- }
- };
-
- //
- // Testing utilities.
- //
-
- void pstate(player const& p)
- {
- // instead of the hard-coded array we can use fill_state_names:
- //static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused","AllOk","ErrorMode","SleepMode" };
- typedef player::transition_table stt;
- typedef generate_state_set<stt>::type all_states;
- static char const* state_names[mpl::size<all_states>::value];
- // fill the names of the states defined in the state machine
- mpl::for_each<all_states,boost::msm::wrap<mpl::placeholders::_1> >(fill_state_names<stt>(state_names));
-
- for (unsigned int i=0;i<p.current_state().size();++i)
- {
- std::cout << " -> " << state_names[p.current_state()[i]] << std::endl;
- }
- }
- void test()
- {
- player p;
- // get a pointer to a state
- // just to show how to do it as Stopped gets a pointer to player anyway
- player::Stopped* tempstate = p.get_state<player::Stopped*>();
- tempstate->m_player = &p;
- // get a reference to a state
- player::Stopped& tempstate2 = p.get_state<player::Stopped&>();
- tempstate2.m_player = &p;
- // make a copy of a state
- player::Stopped tempstate3 = p.get_state<player::Stopped&>();
-
- // needed to start the highest-level SM. This will call on_entry and mark the start of the SM
- p.start();
- std::cout << "CDLoaded active:" << std::boolalpha << p.is_flag_active<CDLoaded>() << std::endl; //=> false (no CD yet)
-
- // test deferred event
- // deferred in Empty and Open, will be handled only after event cd_detected
- p.process_event(play());
-
- // 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(boost::ref(vis));
- p.process_event(open_close()); pstate(p);
- // visiting Empty and AllOk, but only Empty cares
- p.visit_current_states(boost::ref(vis));
-
-
- p.process_event(cd_detected("louie, louie",p));
- // no need to call play() as the previous event does it in its action method
- //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(boost::ref(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
- p.process_event(pause()); pstate(p);
- std::cout << "PlayingPaused active:" << std::boolalpha << p.is_flag_active<PlayingPaused>() << std::endl;//=> true
- // forward events to Paused
- p.process_event(TenSec());
- p.process_event(TenSec());
- // go back to Playing
- p.process_event(end_pause()); pstate(p);
- std::cout << "FirstSong active:" << std::boolalpha << p.is_flag_active<FirstSongPlaying>() << std::endl; //=> true
- p.process_event(ThreeSec()); pstate(p);
- 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);
- // Pause
- p.process_event(pause()); pstate(p);
- // go back to Playing
- // but end_pause is an event activating the History
- // => keep the last active State (SecondSong)
- p.process_event(end_pause()); pstate(p);
- // test of an event from a state to itself. According to UML spec, call again exit/entry from Stopped
- p.process_event(stop()); pstate(p);
- p.process_event(stop()); pstate(p);
- std::cout << "CDLoaded active:" << std::boolalpha << p.is_flag_active<CDLoaded>() << std::endl;//=> true
- std::cout << "PlayingPaused active:" << std::boolalpha << p.is_flag_active<PlayingPaused>() << std::endl;//=> false
- std::cout << "FirstSong active:" << std::boolalpha << p.is_flag_active<FirstSongPlaying>() << std::endl;//=> false
- std::cout << "CDLoaded active with AND:" << std::boolalpha << p.is_flag_active<CDLoaded,player::Flag_AND>() << std::endl;//=> false
- std::cout << "CDLoaded active with OR:" << std::boolalpha << p.is_flag_active<CDLoaded,player::Flag_OR>() << std::endl;//=> true
-
- // go back to Playing
- // but play is not leading to Shallow History => do not remember the last active State (SecondSong)
- // and activate again FirstSong and LightOn
- p.process_event(play()); pstate(p);
- p.process_event(error_found()); pstate(p);
-
- // try generating more events
- std::cout << "Trying to generate another event" << std::endl; // will not work, fsm is terminated or interrupted
- p.process_event(NextSong());pstate(p);
-
- std::cout << "Trying to end the error" << std::endl; // will work only if ErrorMode is interrupt state
- p.process_event(end_error());pstate(p);
- std::cout << "Trying to generate another event" << std::endl; // will work only if ErrorMode is interrupt state
- p.process_event(NextSong());pstate(p);
-
- std::cout << "Simulate error. Event play is not valid" << std::endl;
- p.process_event(play()); pstate(p);
- }
+ // friend definition needed.
+ friend class state_machine<player>;
+ typedef player p; // makes transition table cleaner
+
+ // Transition table for player
+ struct transition_table : mpl::vector<
+ // Start Event Next Action Guard
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Stopped , play , Playing , &p::start_playback >,
+ a_row < Stopped , open_close , Open , &p::open_drawer >,
+ a_row < Stopped , stop , Stopped , &p::stopped_again >,
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Open , open_close , Empty , &p::close_drawer >,
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Empty , open_close , Open , &p::open_drawer >,
+ a_row < Empty , cd_detected , Stopped , &p::store_cd_info >,
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Playing , stop , Stopped , &p::stop_playback >,
+ a_row < Playing , pause , Paused , &p::pause_playback >,
+ a_row < Playing , open_close , Open , &p::stop_and_open >,
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Paused , end_pause , Playing , &p::resume_playback >,
+ a_row < Paused , stop , Stopped , &p::stop_playback >,
+ a_row < Paused , open_close , Open , &p::stop_and_open >,
+ a_row < Paused , go_sleep ,SleepMode, &p::start_sleep >,
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < AllOk , error_found ,ErrorMode, &p::report_error >,
+ a_row <ErrorMode,end_error ,AllOk , &p::report_end_error >
+ // +---------+-------------+---------+---------------------+----------------------+
+ > {};
+
+ // Replaces the default no-transition response.
+ template <class Event>
+ int no_transition(int state, Event const& )
+ {
+ std::cout << "no transition from state " << state
+ << " on event " << typeid(Event).name() << std::endl;
+ return state;
+ }
+ };
+
+ //
+ // Testing utilities.
+ //
+
+ void pstate(player const& p)
+ {
+ // instead of the hard-coded array we can use fill_state_names:
+ //static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused","AllOk","ErrorMode","SleepMode" };
+ typedef player::transition_table stt;
+ typedef generate_state_set<stt>::type all_states;
+ static char const* state_names[mpl::size<all_states>::value];
+ // fill the names of the states defined in the state machine
+ mpl::for_each<all_states,boost::msm::wrap<mpl::placeholders::_1> >(fill_state_names<stt>(state_names));
+
+ for (unsigned int i=0;i<p.current_state().size();++i)
+ {
+ std::cout << " -> " << state_names[p.current_state()[i]] << std::endl;
+ }
+ }
+ void test()
+ {
+ player p;
+ // get a pointer to a state
+ // just to show how to do it as Stopped gets a pointer to player anyway
+ player::Stopped* tempstate = p.get_state<player::Stopped*>();
+ tempstate->m_player = &p;
+ // get a reference to a state
+ player::Stopped& tempstate2 = p.get_state<player::Stopped&>();
+ tempstate2.m_player = &p;
+ // make a copy of a state
+ player::Stopped tempstate3 = p.get_state<player::Stopped&>();
+
+ // needed to start the highest-level SM. This will call on_entry and mark the start of the SM
+ p.start();
+ std::cout << "CDLoaded active:" << std::boolalpha << p.is_flag_active<CDLoaded>() << std::endl; //=> false (no CD yet)
+
+ // test deferred event
+ // deferred in Empty and Open, will be handled only after event cd_detected
+ p.process_event(play());
+
+ // 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(boost::ref(vis));
+ p.process_event(open_close()); pstate(p);
+ // visiting Empty and AllOk, but only Empty cares
+ p.visit_current_states(boost::ref(vis));
+
+
+ p.process_event(cd_detected("louie, louie",p));
+ // no need to call play() as the previous event does it in its action method
+ //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(boost::ref(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
+ p.process_event(pause()); pstate(p);
+ std::cout << "PlayingPaused active:" << std::boolalpha << p.is_flag_active<PlayingPaused>() << std::endl;//=> true
+ // forward events to Paused
+ p.process_event(TenSec());
+ p.process_event(TenSec());
+ // go back to Playing
+ p.process_event(end_pause()); pstate(p);
+ std::cout << "FirstSong active:" << std::boolalpha << p.is_flag_active<FirstSongPlaying>() << std::endl; //=> true
+ p.process_event(ThreeSec()); pstate(p);
+ 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);
+ // Pause
+ p.process_event(pause()); pstate(p);
+ // go back to Playing
+ // but end_pause is an event activating the History
+ // => keep the last active State (SecondSong)
+ p.process_event(end_pause()); pstate(p);
+ // test of an event from a state to itself. According to UML spec, call again exit/entry from Stopped
+ p.process_event(stop()); pstate(p);
+ p.process_event(stop()); pstate(p);
+ std::cout << "CDLoaded active:" << std::boolalpha << p.is_flag_active<CDLoaded>() << std::endl;//=> true
+ std::cout << "PlayingPaused active:" << std::boolalpha << p.is_flag_active<PlayingPaused>() << std::endl;//=> false
+ std::cout << "FirstSong active:" << std::boolalpha << p.is_flag_active<FirstSongPlaying>() << std::endl;//=> false
+ std::cout << "CDLoaded active with AND:" << std::boolalpha << p.is_flag_active<CDLoaded,player::Flag_AND>() << std::endl;//=> false
+ std::cout << "CDLoaded active with OR:" << std::boolalpha << p.is_flag_active<CDLoaded,player::Flag_OR>() << std::endl;//=> true
+
+ // go back to Playing
+ // but play is not leading to Shallow History => do not remember the last active State (SecondSong)
+ // and activate again FirstSong and LightOn
+ p.process_event(play()); pstate(p);
+ p.process_event(error_found()); pstate(p);
+
+ // try generating more events
+ std::cout << "Trying to generate another event" << std::endl; // will not work, fsm is terminated or interrupted
+ p.process_event(NextSong());pstate(p);
+
+ std::cout << "Trying to end the error" << std::endl; // will work only if ErrorMode is interrupt state
+ p.process_event(end_error());pstate(p);
+ std::cout << "Trying to generate another event" << std::endl; // will work only if ErrorMode is interrupt state
+ p.process_event(NextSong());pstate(p);
+
+ std::cout << "Simulate error. Event play is not valid" << std::endl;
+ p.process_event(play()); pstate(p);
+ }
 }
 
 int main()

Modified: sandbox/msm/libs/msm/doc/SM-3arg.cpp
==============================================================================
--- sandbox/msm/libs/msm/doc/SM-3arg.cpp (original)
+++ sandbox/msm/libs/msm/doc/SM-3arg.cpp 2009-02-16 16:49:41 EST (Mon, 16 Feb 2009)
@@ -12,475 +12,475 @@
 
 namespace // Concrete FSM implementation
 {
- // events
- struct play {};
- struct end_pause {};
- struct stop {};
- struct pause {};
- struct open_close {};
- struct NextSong {};
- struct PreviousSong {};
- struct ThreeSec {};
- struct TenSec {};
- struct go_sleep {};
- struct error_found {};
- struct end_error {};
-
- // Flags. Allow information about a property of the current state
- struct PlayingPaused{};
- struct CDLoaded {};
- struct FirstSongPlaying {};
-
- // A "complicated" event type that carries some data.
- // forward
- struct player;
- struct cd_detected
- {
- cd_detected(std::string name, player& p)
- : name(name)
- , m_player(p)
- {}
-
- std::string name;
- player& m_player;
- };
-
- // an easy visitor
- struct SomeVisitor
- {
- template <class T>
- void visit_state(T* astate,int i,const char* s)
- {
- std::cout << "visiting state:" << typeid(*astate).name()
- << " with data:" << i << " and:" << s << std::endl;
- }
- };
- // overwrite of the base state (not default)
- struct my_visitable_state
- {
- // signature of the accept function
- typedef args<void,SomeVisitor&,int,const char*> accept_sig;
-
- // we also want polymorphic states
- virtual ~my_visitable_state() {}
- // default implementation for states who do not need to be visited
- void accept(SomeVisitor&,int,const char*) const {}
- };
-
- // Concrete FSM implementation
- struct player : public state_machine<player,NoHistory,my_visitable_state>
- {
- // The list of FSM states
- struct Empty : public state<my_visitable_state>
- {
- typedef mpl::vector<play> deferred_events;
- // every (optional) entry/exit methods get the event packed as boost::any. Not useful very often.
- template <class Event>
- 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;}
+ // events
+ struct play {};
+ struct end_pause {};
+ struct stop {};
+ struct pause {};
+ struct open_close {};
+ struct NextSong {};
+ struct PreviousSong {};
+ struct ThreeSec {};
+ struct TenSec {};
+ struct go_sleep {};
+ struct error_found {};
+ struct end_error {};
+
+ // Flags. Allow information about a property of the current state
+ struct PlayingPaused{};
+ struct CDLoaded {};
+ struct FirstSongPlaying {};
+
+ // A "complicated" event type that carries some data.
+ // forward
+ struct player;
+ struct cd_detected
+ {
+ cd_detected(std::string name, player& p)
+ : name(name)
+ , m_player(p)
+ {}
+
+ std::string name;
+ player& m_player;
+ };
+
+ // an easy visitor
+ struct SomeVisitor
+ {
+ template <class T>
+ void visit_state(T* astate,int i,const char* s)
+ {
+ std::cout << "visiting state:" << typeid(*astate).name()
+ << " with data:" << i << " and:" << s << std::endl;
+ }
+ };
+ // overwrite of the base state (not default)
+ struct my_visitable_state
+ {
+ // signature of the accept function
+ typedef args<void,SomeVisitor&,int,const char*> accept_sig;
+
+ // we also want polymorphic states
+ virtual ~my_visitable_state() {}
+ // default implementation for states who do not need to be visited
+ void accept(SomeVisitor&,int,const char*) const {}
+ };
+
+ // Concrete FSM implementation
+ struct player : public state_machine<player,NoHistory,my_visitable_state>
+ {
+ // The list of FSM states
+ struct Empty : public state<my_visitable_state>
+ {
+ typedef mpl::vector<play> deferred_events;
+ // every (optional) entry/exit methods get the event packed as boost::any. Not useful very often.
+ template <class Event>
+ 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(SomeVisitor& vis,int i,const char* s) const
             {
                 vis.visit_state(this,i,s);
             }
- };
- struct Open : public state<my_visitable_state>
- {
- typedef mpl::vector1<CDLoaded> flag_list;
- typedef mpl::vector<play> deferred_events;
- template <class Event>
- 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;}
+ };
+ struct Open : public state<my_visitable_state>
+ {
+ typedef mpl::vector1<CDLoaded> flag_list;
+ typedef mpl::vector<play> deferred_events;
+ template <class Event>
+ 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(SomeVisitor& vis,int i,const char* s) const
             {
                 vis.visit_state(this,i,s);
             }
- };
- // a state needing a pointer to the containing state machine
- // and using for this the non-default policy
- // if policy used, set_sm_ptr is needed
- struct Stopped : public state<my_visitable_state,SMPtr>
- {
- // when stopped, the CD is loaded
- typedef mpl::vector1<CDLoaded> flag_list;
- template <class Event>
- void on_entry(Event const& ) {std::cout << "entering: Stopped" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "leaving: Stopped" << std::endl;}
- void set_sm_ptr(player* pl){m_player=pl;}
- player* m_player;
- };
- // the player state machine contains a state which is himself a state machine
- // it demonstrates Shallow History: if the state gets activated with end_pause
- // 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> >,my_visitable_state >
- {
- // when playing, the CD is loaded and we are in either pause or playing (duh)
- typedef mpl::vector2<PlayingPaused,CDLoaded> flag_list;
- template <class Event>
- 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;}
+ };
+ // a state needing a pointer to the containing state machine
+ // and using for this the non-default policy
+ // if policy used, set_sm_ptr is needed
+ struct Stopped : public state<my_visitable_state,SMPtr>
+ {
+ // when stopped, the CD is loaded
+ typedef mpl::vector1<CDLoaded> flag_list;
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "entering: Stopped" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "leaving: Stopped" << std::endl;}
+ void set_sm_ptr(player* pl){m_player=pl;}
+ player* m_player;
+ };
+ // the player state machine contains a state which is himself a state machine
+ // it demonstrates Shallow History: if the state gets activated with end_pause
+ // 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> >,my_visitable_state >
+ {
+ // when playing, the CD is loaded and we are in either pause or playing (duh)
+ typedef mpl::vector2<PlayingPaused,CDLoaded> flag_list;
+ template <class Event>
+ 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(SomeVisitor& vis,int i,const char* s)
             {
                 vis.visit_state(this,i,s);
                 // visit substates
                 visit_current_states(vis,i,s);
             }
- // 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
- struct Song1 : public state_machine<Song1,NoHistory,my_visitable_state>
- {
- typedef mpl::vector1<FirstSongPlaying> flag_list;
- template <class Event>
- 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(SomeVisitor& vis,int i,const char* s)
- {
- vis.visit_state(this,i,s);
- }
- struct LightOn : public state<my_visitable_state>
- {
- template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: LightOn" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: LightOn" << std::endl;}
- };
- struct LightOff : public state<my_visitable_state>
- {
- template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: LightOff" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: LightOff" << std::endl;}
- };
- // the initial state. Must be defined
- typedef LightOn initial_state;
- // transition actions
- void turn_light_off(ThreeSec const&) { std::cout << "3s off::turn light off\n"; }
- // guard conditions
-
- // friend definition needed.
- friend class state_machine<Song1>;
- typedef Song1 s; // makes transition table cleaner
- // Transition table for Song1
- struct transition_table : mpl::vector1<
- // Start Event Next Action Guard
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < LightOn , ThreeSec , LightOff, &s::turn_light_off >
- // +---------+-------------+---------+---------------------+----------------------+
- > {};
- // Replaces the default no-transition response.
- template <class Event>
- int no_transition(int state, Event const& )
- {
- std::cout << "no transition from state " << state
- << " on event " << typeid(Event).name() << std::endl;
- return state;
- }
-
- };
- struct Song2 : public state<my_visitable_state>
- {
- template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: Second song" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: Second Song" << std::endl;}
- };
- struct Song3 : public state<my_visitable_state>
- {
- template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: Third song" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: Third Song" << std::endl;}
- };
- // the initial state. Must be defined
- typedef Song1 initial_state;
- // transition actions
- void start_next_song(NextSong const&) { std::cout << "Playing::start_next_song\n"; }
- void start_prev_song(PreviousSong const&) { std::cout << "Playing::start_prev_song\n"; }
- // guard conditions
-
- // friend definition needed.
- friend class state_machine<Playing>;
- typedef Playing pl; // makes transition table cleaner
- // Transition table for Playing
- struct transition_table : mpl::vector4<
- // Start Event Next Action Guard
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Song1 , NextSong , Song2 , &pl::start_next_song >,
- a_row < Song2 , PreviousSong, Song1 , &pl::start_prev_song >,
- a_row < Song2 , NextSong , Song3 , &pl::start_next_song >,
- a_row < Song3 , PreviousSong, Song2 , &pl::start_prev_song >
- // +---------+-------------+---------+---------------------+----------------------+
- > {};
- // Replaces the default no-transition response.
- template <class Event>
- int no_transition(int state, Event const&)
- {
- std::cout << "no transition from state " << state
- << " on event " << typeid(Event).name() << std::endl;
- return state;
- }
- };
- // the player state machine contains a state which is himself a state machine (2 of them, Playing and Paused)
- struct Paused : public state_machine<Paused,NoHistory,my_visitable_state>
- {
- typedef mpl::vector2<PlayingPaused,CDLoaded> flag_list;
- template <class Event>
- void on_entry(Event const& ) {std::cout << "entering: Paused" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "leaving: Paused" << std::endl;}
-
- // The list of FSM states
- struct StartBlinking : public state<my_visitable_state>
- {
- template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: StartBlinking" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: StartBlinking" << std::endl;}
- };
- struct StopBlinking : public state<my_visitable_state>
- {
- template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: StopBlinking" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: StopBlinking" << std::endl;}
- };
- // the initial state. Must be defined
- typedef StartBlinking initial_state;
- // transition actions
- void start_blinking(TenSec const&) { std::cout << "Paused::start_blinking\n"; }
- void stop_blinking(TenSec const&) { std::cout << "Paused::stop_blinking\n"; }
- // guard conditions
-
- // friend definition needed.
- friend class state_machine<Paused>;
- typedef Paused pa; // makes transition table cleaner
- // Transition table
- struct transition_table : mpl::vector2<
- // Start Event Next Action Guard
- // +---------------+-------------+--------------+---------------------+----------------------+
- a_row < StartBlinking , TenSec , StopBlinking , &pa::stop_blinking >,
- a_row < StopBlinking , TenSec , StartBlinking , &pa::start_blinking >
- // +---------------+-------------+---------------+--------------------+----------------------+
- > {};
- // Replaces the default no-transition response.
- template <class Event>
- int no_transition(int state, Event const& )
- {
- std::cout << "no transition from state " << state
- << " on event " << typeid(Event).name() << std::endl;
- return state;
- }
- };
- struct SleepMode : public state<my_visitable_state> {}; // dumy state just to test the automatic id generation
-
- struct AllOk : public state<my_visitable_state>
- {
- template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: AllOk" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: AllOk" << std::endl;}
- };
- struct ErrorMode : //public terminate_state<>
- public interrupt_state<end_error,my_visitable_state>
- {
- template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: ErrorMode" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: ErrorMode" << std::endl;}
- };
-
- // the initial state of the player SM. Must be defined
- typedef mpl::vector<Empty,AllOk> initial_state;
- //typedef Empty initial_state; // this is to have only one active state
+ // 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
+ struct Song1 : public state_machine<Song1,NoHistory,my_visitable_state>
+ {
+ typedef mpl::vector1<FirstSongPlaying> flag_list;
+ template <class Event>
+ 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(SomeVisitor& vis,int i,const char* s)
+ {
+ vis.visit_state(this,i,s);
+ }
+ struct LightOn : public state<my_visitable_state>
+ {
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "starting: LightOn" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: LightOn" << std::endl;}
+ };
+ struct LightOff : public state<my_visitable_state>
+ {
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "starting: LightOff" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: LightOff" << std::endl;}
+ };
+ // the initial state. Must be defined
+ typedef LightOn initial_state;
+ // transition actions
+ void turn_light_off(ThreeSec const&) { std::cout << "3s off::turn light off\n"; }
+ // guard conditions
+
+ // friend definition needed.
+ friend class state_machine<Song1>;
+ typedef Song1 s; // makes transition table cleaner
+ // Transition table for Song1
+ struct transition_table : mpl::vector1<
+ // Start Event Next Action Guard
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < LightOn , ThreeSec , LightOff, &s::turn_light_off >
+ // +---------+-------------+---------+---------------------+----------------------+
+ > {};
+ // Replaces the default no-transition response.
+ template <class Event>
+ int no_transition(int state, Event const& )
+ {
+ std::cout << "no transition from state " << state
+ << " on event " << typeid(Event).name() << std::endl;
+ return state;
+ }
+
+ };
+ struct Song2 : public state<my_visitable_state>
+ {
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "starting: Second song" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: Second Song" << std::endl;}
+ };
+ struct Song3 : public state<my_visitable_state>
+ {
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "starting: Third song" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: Third Song" << std::endl;}
+ };
+ // the initial state. Must be defined
+ typedef Song1 initial_state;
+ // transition actions
+ void start_next_song(NextSong const&) { std::cout << "Playing::start_next_song\n"; }
+ void start_prev_song(PreviousSong const&) { std::cout << "Playing::start_prev_song\n"; }
+ // guard conditions
+
+ // friend definition needed.
+ friend class state_machine<Playing>;
+ typedef Playing pl; // makes transition table cleaner
+ // Transition table for Playing
+ struct transition_table : mpl::vector4<
+ // Start Event Next Action Guard
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Song1 , NextSong , Song2 , &pl::start_next_song >,
+ a_row < Song2 , PreviousSong, Song1 , &pl::start_prev_song >,
+ a_row < Song2 , NextSong , Song3 , &pl::start_next_song >,
+ a_row < Song3 , PreviousSong, Song2 , &pl::start_prev_song >
+ // +---------+-------------+---------+---------------------+----------------------+
+ > {};
+ // Replaces the default no-transition response.
+ template <class Event>
+ int no_transition(int state, Event const&)
+ {
+ std::cout << "no transition from state " << state
+ << " on event " << typeid(Event).name() << std::endl;
+ return state;
+ }
+ };
+ // the player state machine contains a state which is himself a state machine (2 of them, Playing and Paused)
+ struct Paused : public state_machine<Paused,NoHistory,my_visitable_state>
+ {
+ typedef mpl::vector2<PlayingPaused,CDLoaded> flag_list;
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "entering: Paused" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "leaving: Paused" << std::endl;}
+
+ // The list of FSM states
+ struct StartBlinking : public state<my_visitable_state>
+ {
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "starting: StartBlinking" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: StartBlinking" << std::endl;}
+ };
+ struct StopBlinking : public state<my_visitable_state>
+ {
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "starting: StopBlinking" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: StopBlinking" << std::endl;}
+ };
+ // the initial state. Must be defined
+ typedef StartBlinking initial_state;
+ // transition actions
+ void start_blinking(TenSec const&) { std::cout << "Paused::start_blinking\n"; }
+ void stop_blinking(TenSec const&) { std::cout << "Paused::stop_blinking\n"; }
+ // guard conditions
+
+ // friend definition needed.
+ friend class state_machine<Paused>;
+ typedef Paused pa; // makes transition table cleaner
+ // Transition table
+ struct transition_table : mpl::vector2<
+ // Start Event Next Action Guard
+ // +---------------+-------------+--------------+---------------------+----------------------+
+ a_row < StartBlinking , TenSec , StopBlinking , &pa::stop_blinking >,
+ a_row < StopBlinking , TenSec , StartBlinking , &pa::start_blinking >
+ // +---------------+-------------+---------------+--------------------+----------------------+
+ > {};
+ // Replaces the default no-transition response.
+ template <class Event>
+ int no_transition(int state, Event const& )
+ {
+ std::cout << "no transition from state " << state
+ << " on event " << typeid(Event).name() << std::endl;
+ return state;
+ }
+ };
+ struct SleepMode : public state<my_visitable_state> {}; // dumy state just to test the automatic id generation
+
+ struct AllOk : public state<my_visitable_state>
+ {
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "starting: AllOk" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: AllOk" << std::endl;}
+ };
+ struct ErrorMode : //public terminate_state<>
+ public interrupt_state<end_error,my_visitable_state>
+ {
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "starting: ErrorMode" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: ErrorMode" << std::endl;}
+ };
+
+ // the initial state of the player SM. Must be defined
+ typedef mpl::vector<Empty,AllOk> initial_state;
+ //typedef Empty initial_state; // this is to have only one active state
 
 #ifdef __MWERKS__
- public: // Codewarrior bug workaround. Tested at 0x3202
+ public: // Codewarrior bug workaround. Tested at 0x3202
 #endif
- // transition actions
- void start_playback(play const&) { std::cout << "player::start_playback\n"; }
- void open_drawer(open_close const&) { std::cout << "player::open_drawer\n"; }
- void close_drawer(open_close const&) { std::cout << "player::close_drawer\n"; }
- void store_cd_info(cd_detected const&)
- {
- std::cout << "player::store_cd_info\n";
- // generate another event to test the queue
- //cd.m_player.process_event(play());
- }
- void stop_playback(stop const&) { std::cout << "player::stop_playback\n"; }
- void pause_playback(pause const&) { std::cout << "player::pause_playback\n"; }
- void resume_playback(end_pause const&) { std::cout << "player::resume_playback\n"; }
- void stop_and_open(open_close const&) { std::cout << "player::stop_and_open\n"; }
- void stopped_again(stop const&) {std::cout << "player::stopped_again\n";}
- void start_sleep(go_sleep const&) { }
- void report_error(error_found const&) {std::cout << "player::report_error\n";}
- void report_end_error(end_error const&) {std::cout << "player::report_end_error\n";}
- // guard conditions
+ // transition actions
+ void start_playback(play const&) { std::cout << "player::start_playback\n"; }
+ void open_drawer(open_close const&) { std::cout << "player::open_drawer\n"; }
+ void close_drawer(open_close const&) { std::cout << "player::close_drawer\n"; }
+ void store_cd_info(cd_detected const&)
+ {
+ std::cout << "player::store_cd_info\n";
+ // generate another event to test the queue
+ //cd.m_player.process_event(play());
+ }
+ void stop_playback(stop const&) { std::cout << "player::stop_playback\n"; }
+ void pause_playback(pause const&) { std::cout << "player::pause_playback\n"; }
+ void resume_playback(end_pause const&) { std::cout << "player::resume_playback\n"; }
+ void stop_and_open(open_close const&) { std::cout << "player::stop_and_open\n"; }
+ void stopped_again(stop const&) {std::cout << "player::stopped_again\n";}
+ void start_sleep(go_sleep const&) { }
+ void report_error(error_found const&) {std::cout << "player::report_error\n";}
+ void report_end_error(end_error const&) {std::cout << "player::report_end_error\n";}
+ // guard conditions
 
 
 #ifdef __MWERKS__
- private:
+ private:
 #endif
- // friend definition needed.
- friend class state_machine<player>;
- typedef player p; // makes transition table cleaner
-
- // Transition table for player
- struct transition_table : mpl::vector<
- // Start Event Next Action Guard
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Stopped , play , Playing , &p::start_playback >,
- a_row < Stopped , open_close , Open , &p::open_drawer >,
- a_row < Stopped , stop , Stopped , &p::stopped_again >,
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Open , open_close , Empty , &p::close_drawer >,
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Empty , open_close , Open , &p::open_drawer >,
- a_row < Empty , cd_detected , Stopped , &p::store_cd_info >,
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Playing , stop , Stopped , &p::stop_playback >,
- a_row < Playing , pause , Paused , &p::pause_playback >,
- a_row < Playing , open_close , Open , &p::stop_and_open >,
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Paused , end_pause , Playing , &p::resume_playback >,
- a_row < Paused , stop , Stopped , &p::stop_playback >,
- a_row < Paused , open_close , Open , &p::stop_and_open >,
- a_row < Paused , go_sleep ,SleepMode, &p::start_sleep >,
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < AllOk , error_found ,ErrorMode, &p::report_error >,
- a_row <ErrorMode,end_error ,AllOk , &p::report_end_error >
- // +---------+-------------+---------+---------------------+----------------------+
- > {};
-
- // Replaces the default no-transition response.
- template <class Event>
- int no_transition(int state, Event const& )
- {
- std::cout << "no transition from state " << state
- << " on event " << typeid(Event).name() << std::endl;
- return state;
- }
- };
-
- //
- // Testing utilities.
- //
-
- void pstate(player const& p)
- {
- // instead of the hard-coded array we can use fill_state_names:
- //static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused","AllOk","ErrorMode","SleepMode" };
- typedef player::transition_table stt;
- typedef generate_state_set<stt>::type all_states;
- static char const* state_names[mpl::size<all_states>::value];
- // fill the names of the states defined in the state machine
- mpl::for_each<all_states,boost::msm::wrap<mpl::placeholders::_1> >(fill_state_names<stt>(state_names));
-
- for (unsigned int i=0;i<p.current_state().size();++i)
- {
- std::cout << " -> " << state_names[p.current_state()[i]] << std::endl;
- }
- }
- void test()
- {
- player p;
- // get a pointer to a state
- // just to show how to do it as Stopped gets a pointer to player anyway
- player::Stopped* tempstate = p.get_state<player::Stopped*>();
- tempstate->m_player = &p;
- // get a reference to a state
- player::Stopped& tempstate2 = p.get_state<player::Stopped&>();
- tempstate2.m_player = &p;
- // make a copy of a state
- player::Stopped tempstate3 = p.get_state<player::Stopped&>();
-
- // needed to start the highest-level SM. This will call on_entry and mark the start of the SM
- p.start();
- std::cout << "CDLoaded active:" << std::boolalpha << p.is_flag_active<CDLoaded>() << std::endl; //=> false (no CD yet)
-
- // test deferred event
- // deferred in Empty and Open, will be handled only after event cd_detected
- p.process_event(play());
-
- // 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(boost::ref(vis),1,"first");
- p.process_event(open_close()); pstate(p);
- // visiting Empty and AllOk, but only Empty cares
- p.visit_current_states(boost::ref(vis),2,"second");
-
-
- p.process_event(cd_detected("louie, louie",p));
- // no need to call play() as the previous event does it in its action method
- //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(boost::ref(vis),3,"third");
-
- 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
- p.process_event(pause()); pstate(p);
- std::cout << "PlayingPaused active:" << std::boolalpha << p.is_flag_active<PlayingPaused>() << std::endl;//=> true
- // forward events to Paused
- p.process_event(TenSec());
- p.process_event(TenSec());
- // go back to Playing
- p.process_event(end_pause()); pstate(p);
- std::cout << "FirstSong active:" << std::boolalpha << p.is_flag_active<FirstSongPlaying>() << std::endl; //=> true
- p.process_event(ThreeSec()); pstate(p);
- 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,4,"fourth");
-
- p.process_event(NextSong());pstate(p);
- // 2nd song active
- p.process_event(PreviousSong());pstate(p);
- // Pause
- p.process_event(pause()); pstate(p);
- // go back to Playing
- // but end_pause is an event activating the History
- // => keep the last active State (SecondSong)
- p.process_event(end_pause()); pstate(p);
- // test of an event from a state to itself. According to UML spec, call again exit/entry from Stopped
- p.process_event(stop()); pstate(p);
- p.process_event(stop()); pstate(p);
- std::cout << "CDLoaded active:" << std::boolalpha << p.is_flag_active<CDLoaded>() << std::endl;//=> true
- std::cout << "PlayingPaused active:" << std::boolalpha << p.is_flag_active<PlayingPaused>() << std::endl;//=> false
- std::cout << "FirstSong active:" << std::boolalpha << p.is_flag_active<FirstSongPlaying>() << std::endl;//=> false
- std::cout << "CDLoaded active with AND:" << std::boolalpha << p.is_flag_active<CDLoaded,player::Flag_AND>() << std::endl;//=> false
- std::cout << "CDLoaded active with OR:" << std::boolalpha << p.is_flag_active<CDLoaded,player::Flag_OR>() << std::endl;//=> true
-
- // go back to Playing
- // but play is not leading to Shallow History => do not remember the last active State (SecondSong)
- // and activate again FirstSong and LightOn
- p.process_event(play()); pstate(p);
- p.process_event(error_found()); pstate(p);
-
- // try generating more events
- std::cout << "Trying to generate another event" << std::endl; // will not work, fsm is terminated or interrupted
- p.process_event(NextSong());pstate(p);
-
- std::cout << "Trying to end the error" << std::endl; // will work only if ErrorMode is interrupt state
- p.process_event(end_error());pstate(p);
- std::cout << "Trying to generate another event" << std::endl; // will work only if ErrorMode is interrupt state
- p.process_event(NextSong());pstate(p);
+ // friend definition needed.
+ friend class state_machine<player>;
+ typedef player p; // makes transition table cleaner
+
+ // Transition table for player
+ struct transition_table : mpl::vector<
+ // Start Event Next Action Guard
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Stopped , play , Playing , &p::start_playback >,
+ a_row < Stopped , open_close , Open , &p::open_drawer >,
+ a_row < Stopped , stop , Stopped , &p::stopped_again >,
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Open , open_close , Empty , &p::close_drawer >,
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Empty , open_close , Open , &p::open_drawer >,
+ a_row < Empty , cd_detected , Stopped , &p::store_cd_info >,
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Playing , stop , Stopped , &p::stop_playback >,
+ a_row < Playing , pause , Paused , &p::pause_playback >,
+ a_row < Playing , open_close , Open , &p::stop_and_open >,
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Paused , end_pause , Playing , &p::resume_playback >,
+ a_row < Paused , stop , Stopped , &p::stop_playback >,
+ a_row < Paused , open_close , Open , &p::stop_and_open >,
+ a_row < Paused , go_sleep ,SleepMode, &p::start_sleep >,
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < AllOk , error_found ,ErrorMode, &p::report_error >,
+ a_row <ErrorMode,end_error ,AllOk , &p::report_end_error >
+ // +---------+-------------+---------+---------------------+----------------------+
+ > {};
+
+ // Replaces the default no-transition response.
+ template <class Event>
+ int no_transition(int state, Event const& )
+ {
+ std::cout << "no transition from state " << state
+ << " on event " << typeid(Event).name() << std::endl;
+ return state;
+ }
+ };
+
+ //
+ // Testing utilities.
+ //
+
+ void pstate(player const& p)
+ {
+ // instead of the hard-coded array we can use fill_state_names:
+ //static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused","AllOk","ErrorMode","SleepMode" };
+ typedef player::transition_table stt;
+ typedef generate_state_set<stt>::type all_states;
+ static char const* state_names[mpl::size<all_states>::value];
+ // fill the names of the states defined in the state machine
+ mpl::for_each<all_states,boost::msm::wrap<mpl::placeholders::_1> >(fill_state_names<stt>(state_names));
+
+ for (unsigned int i=0;i<p.current_state().size();++i)
+ {
+ std::cout << " -> " << state_names[p.current_state()[i]] << std::endl;
+ }
+ }
+ void test()
+ {
+ player p;
+ // get a pointer to a state
+ // just to show how to do it as Stopped gets a pointer to player anyway
+ player::Stopped* tempstate = p.get_state<player::Stopped*>();
+ tempstate->m_player = &p;
+ // get a reference to a state
+ player::Stopped& tempstate2 = p.get_state<player::Stopped&>();
+ tempstate2.m_player = &p;
+ // make a copy of a state
+ player::Stopped tempstate3 = p.get_state<player::Stopped&>();
+
+ // needed to start the highest-level SM. This will call on_entry and mark the start of the SM
+ p.start();
+ std::cout << "CDLoaded active:" << std::boolalpha << p.is_flag_active<CDLoaded>() << std::endl; //=> false (no CD yet)
+
+ // test deferred event
+ // deferred in Empty and Open, will be handled only after event cd_detected
+ p.process_event(play());
+
+ // 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(boost::ref(vis),1,"first");
+ p.process_event(open_close()); pstate(p);
+ // visiting Empty and AllOk, but only Empty cares
+ p.visit_current_states(boost::ref(vis),2,"second");
+
+
+ p.process_event(cd_detected("louie, louie",p));
+ // no need to call play() as the previous event does it in its action method
+ //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(boost::ref(vis),3,"third");
+
+ 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
+ p.process_event(pause()); pstate(p);
+ std::cout << "PlayingPaused active:" << std::boolalpha << p.is_flag_active<PlayingPaused>() << std::endl;//=> true
+ // forward events to Paused
+ p.process_event(TenSec());
+ p.process_event(TenSec());
+ // go back to Playing
+ p.process_event(end_pause()); pstate(p);
+ std::cout << "FirstSong active:" << std::boolalpha << p.is_flag_active<FirstSongPlaying>() << std::endl; //=> true
+ p.process_event(ThreeSec()); pstate(p);
+ 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,4,"fourth");
+
+ p.process_event(NextSong());pstate(p);
+ // 2nd song active
+ p.process_event(PreviousSong());pstate(p);
+ // Pause
+ p.process_event(pause()); pstate(p);
+ // go back to Playing
+ // but end_pause is an event activating the History
+ // => keep the last active State (SecondSong)
+ p.process_event(end_pause()); pstate(p);
+ // test of an event from a state to itself. According to UML spec, call again exit/entry from Stopped
+ p.process_event(stop()); pstate(p);
+ p.process_event(stop()); pstate(p);
+ std::cout << "CDLoaded active:" << std::boolalpha << p.is_flag_active<CDLoaded>() << std::endl;//=> true
+ std::cout << "PlayingPaused active:" << std::boolalpha << p.is_flag_active<PlayingPaused>() << std::endl;//=> false
+ std::cout << "FirstSong active:" << std::boolalpha << p.is_flag_active<FirstSongPlaying>() << std::endl;//=> false
+ std::cout << "CDLoaded active with AND:" << std::boolalpha << p.is_flag_active<CDLoaded,player::Flag_AND>() << std::endl;//=> false
+ std::cout << "CDLoaded active with OR:" << std::boolalpha << p.is_flag_active<CDLoaded,player::Flag_OR>() << std::endl;//=> true
+
+ // go back to Playing
+ // but play is not leading to Shallow History => do not remember the last active State (SecondSong)
+ // and activate again FirstSong and LightOn
+ p.process_event(play()); pstate(p);
+ p.process_event(error_found()); pstate(p);
+
+ // try generating more events
+ std::cout << "Trying to generate another event" << std::endl; // will not work, fsm is terminated or interrupted
+ p.process_event(NextSong());pstate(p);
+
+ std::cout << "Trying to end the error" << std::endl; // will work only if ErrorMode is interrupt state
+ p.process_event(end_error());pstate(p);
+ std::cout << "Trying to generate another event" << std::endl; // will work only if ErrorMode is interrupt state
+ p.process_event(NextSong());pstate(p);
 
- std::cout << "Simulate error. Event play is not valid" << std::endl;
- p.process_event(play()); pstate(p);
+ std::cout << "Simulate error. Event play is not valid" << std::endl;
+ p.process_event(play()); pstate(p);
 
- }
+ }
 }
 
 int main()

Modified: sandbox/msm/libs/msm/doc/SM.cpp
==============================================================================
--- sandbox/msm/libs/msm/doc/SM.cpp (original)
+++ sandbox/msm/libs/msm/doc/SM.cpp 2009-02-16 16:49:41 EST (Mon, 16 Feb 2009)
@@ -1,494 +1,472 @@
 #include <vector>
 #include <iostream>
+#include <string>
 #include <boost/mpl/vector/vector50.hpp>
 #include <boost/msm/state_machine.hpp>
 #include <boost/msm/tools.hpp>
 
 using namespace boost::msm;
+using namespace std;
 
 namespace // Concrete FSM implementation
 {
- // events
- struct play {};
- struct end_pause {};
- struct stop {};
- struct pause {};
- struct open_close {};
- struct NextSong {};
- struct PreviousSong {};
- struct ThreeSec {};
- struct TenSec {};
- struct go_sleep {};
- struct error_found {};
- struct end_error {};
-
- // Flags. Allow information about a property of the current state
- struct PlayingPaused{};
- struct CDLoaded {};
- struct FirstSongPlaying {};
-
- // A "complicated" event type that carries some data.
- // forward
- struct player;
- struct cd_detected
- {
- cd_detected(std::string name, player& p)
- : name(name)
- , m_player(p)
- {}
-
- std::string name;
- 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,NoHistory,VisitableStates>
- {
- // The list of FSM states
- struct Empty : public state<>
- {
- typedef mpl::vector<play> deferred_events;
- // every (optional) entry/exit methods get the event packed as boost::any. Not useful very often.
- template <class Event>
- 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)
+ // events
+ struct play {};
+ struct end_pause {};
+ struct stop {};
+ struct pause {};
+ struct open_close {};
+ struct NextSong {};
+ struct PreviousSong {};
+ struct ThreeSec {};
+ struct TenSec {};
+ struct go_sleep {};
+ struct error_found {};
+ struct end_error {};
+
+ // Flags. Allow information about a property of the current state
+ struct PlayingPaused{};
+ struct CDLoaded {};
+ struct FirstSongPlaying {};
+
+ // A "complicated" event type that carries some data.
+ // forward
+ struct player;
+ struct cd_detected
+ {
+ cd_detected(std::string name, player& p)
+ : name(name)
+ , m_player(p)
+ {}
+
+ std::string name;
+ player& m_player;
+ };
+
+ // overwrite of the base state (not default)
+ struct my_visitable_state
+ {
+ // signature of the accept function
+ typedef args<void> accept_sig;
+
+ // we also want polymorphic states
+ virtual ~my_visitable_state() {}
+ // default implementation for states who do not need to be visited
+ void accept() const {}
+ };
+
+ // Concrete FSM implementation
+ struct player : public state_machine<player,NoHistory,my_visitable_state>
+ {
+ // The list of FSM states
+ struct Empty : public state<my_visitable_state>
+ {
+ typedef mpl::vector<play> deferred_events;
+ // every (optional) entry/exit methods get the event packed as boost::any. Not useful very often.
+ template <class Event>
+ 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() const
             {
- static_cast<SomeVisitor*>(&vis)->visit_state(this);
+ std::cout << "visiting state:" << typeid(*this).name() << std::endl;
             }
- };
- struct Open : public state<>
- {
- typedef mpl::vector1<CDLoaded> flag_list;
- typedef mpl::vector<play> deferred_events;
- template <class Event>
- 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)
+ };
+ struct Open : public state<my_visitable_state>
+ {
+ typedef mpl::vector1<CDLoaded> flag_list;
+ typedef mpl::vector<play> deferred_events;
+ template <class Event>
+ 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() const
             {
- static_cast<SomeVisitor*>(&vis)->visit_state(this);
+ std::cout << "visiting state:" << typeid(*this).name() << std::endl;
             }
- };
- // a state needing a pointer to the containing state machine
- // and using for this the non-default policy
- // if policy used, set_sm_ptr is needed
- struct Stopped : public state<SMPtr>
- {
- // when stopped, the CD is loaded
- typedef mpl::vector1<CDLoaded> flag_list;
- template <class Event>
- void on_entry(Event const& ) {std::cout << "entering: Stopped" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "leaving: Stopped" << std::endl;}
- void set_sm_ptr(player* pl){m_player=pl;}
- player* m_player;
- };
- // the player state machine contains a state which is himself a state machine
- // it demonstrates Shallow History: if the state gets activated with end_pause
- // 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> >,VisitableStates >
- {
- // when playing, the CD is loaded and we are in either pause or playing (duh)
- typedef mpl::vector2<PlayingPaused,CDLoaded> flag_list;
- template <class Event>
- 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)
+ };
+ // a state needing a pointer to the containing state machine
+ // and using for this the non-default policy
+ // if policy used, set_sm_ptr is needed
+ struct Stopped : public state<my_visitable_state,sm_ptr>
+ {
+ // when stopped, the CD is loaded
+ typedef mpl::vector1<CDLoaded> flag_list;
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "entering: Stopped" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "leaving: Stopped" << std::endl;}
+ void set_sm_ptr(player* pl){m_player=pl;}
+ player* m_player;
+ };
+ // the player state machine contains a state which is himself a state machine
+ // it demonstrates Shallow History: if the state gets activated with end_pause
+ // 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> >,my_visitable_state >
+ {
+ // when playing, the CD is loaded and we are in either pause or playing (duh)
+ typedef mpl::vector2<PlayingPaused,CDLoaded> flag_list;
+ template <class Event>
+ 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()
             {
- static_cast<SomeVisitor*>(&vis)->visit_state(this);
+ std::cout << "visiting state:" << typeid(*this).name() << std::endl;
                 // visit substates
- visit_current_states(vis);
+ visit_current_states();
             }
- // 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
- struct Song1 : public state_machine<Song1>
- {
- typedef mpl::vector1<FirstSongPlaying> flag_list;
- template <class Event>
- 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>
- void on_entry(Event const& ) {std::cout << "starting: LightOn" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: LightOn" << std::endl;}
- };
- struct LightOff : public state<>
- {
- template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: LightOff" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: LightOff" << std::endl;}
- };
- // the initial state. Must be defined
- typedef LightOn initial_state;
- // transition actions
- void turn_light_off(ThreeSec const&) { std::cout << "3s off::turn light off\n"; }
- // guard conditions
-
- // friend definition needed.
- friend class state_machine<Song1>;
- typedef Song1 s; // makes transition table cleaner
- // Transition table for Song1
- struct transition_table : mpl::vector1<
- // Start Event Next Action Guard
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < LightOn , ThreeSec , LightOff, &s::turn_light_off >
- // +---------+-------------+---------+---------------------+----------------------+
- > {};
- // Replaces the default no-transition response.
- template <class Event>
- int no_transition(int state, Event const& )
- {
- std::cout << "no transition from state " << state
- << " on event " << typeid(Event).name() << std::endl;
- return state;
- }
-
- };
- struct Song2 : public state<>
- {
- template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: Second song" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: Second Song" << std::endl;}
- };
- struct Song3 : public state<>
- {
- template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: Third song" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: Third Song" << std::endl;}
- };
- // the initial state. Must be defined
- typedef Song1 initial_state;
- // transition actions
- void start_next_song(NextSong const&) { std::cout << "Playing::start_next_song\n"; }
- void start_prev_song(PreviousSong const&) { std::cout << "Playing::start_prev_song\n"; }
- // guard conditions
-
- // friend definition needed.
- friend class state_machine<Playing>;
- typedef Playing pl; // makes transition table cleaner
- // Transition table for Playing
- struct transition_table : mpl::vector4<
- // Start Event Next Action Guard
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Song1 , NextSong , Song2 , &pl::start_next_song >,
- a_row < Song2 , PreviousSong, Song1 , &pl::start_prev_song >,
- a_row < Song2 , NextSong , Song3 , &pl::start_next_song >,
- a_row < Song3 , PreviousSong, Song2 , &pl::start_prev_song >
- // +---------+-------------+---------+---------------------+----------------------+
- > {};
- // Replaces the default no-transition response.
- template <class Event>
- int no_transition(int state, Event const&)
- {
- std::cout << "no transition from state " << state
- << " on event " << typeid(Event).name() << std::endl;
- return state;
- }
- };
- // the player state machine contains a state which is himself a state machine (2 of them, Playing and Paused)
- struct Paused : public state_machine<Paused>
- {
- typedef mpl::vector2<PlayingPaused,CDLoaded> flag_list;
- template <class Event>
- void on_entry(Event const& ) {std::cout << "entering: Paused" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "leaving: Paused" << std::endl;}
-
- // The list of FSM states
- struct StartBlinking : public state<>
- {
- template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: StartBlinking" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: StartBlinking" << std::endl;}
- };
- struct StopBlinking : public state<>
- {
- template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: StopBlinking" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: StopBlinking" << std::endl;}
- };
- // the initial state. Must be defined
- typedef StartBlinking initial_state;
- // transition actions
- void start_blinking(TenSec const&) { std::cout << "Paused::start_blinking\n"; }
- void stop_blinking(TenSec const&) { std::cout << "Paused::stop_blinking\n"; }
- // guard conditions
-
- // friend definition needed.
- friend class state_machine<Paused>;
- typedef Paused pa; // makes transition table cleaner
- // Transition table
- struct transition_table : mpl::vector2<
- // Start Event Next Action Guard
- // +---------------+-------------+--------------+---------------------+----------------------+
- a_row < StartBlinking , TenSec , StopBlinking , &pa::stop_blinking >,
- a_row < StopBlinking , TenSec , StartBlinking , &pa::start_blinking >
- // +---------------+-------------+---------------+--------------------+----------------------+
- > {};
- // Replaces the default no-transition response.
- template <class Event>
- int no_transition(int state, Event const& )
- {
- std::cout << "no transition from state " << state
- << " on event " << typeid(Event).name() << std::endl;
- return state;
- }
- };
- struct SleepMode : public state<> {}; // dumy state just to test the automatic id generation
-
- struct AllOk : public state<>
- {
- template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: AllOk" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: AllOk" << std::endl;}
- };
- struct ErrorMode : //public terminate_state<>
- public interrupt_state<end_error>
- {
- template <class Event>
- void on_entry(Event const& ) {std::cout << "starting: ErrorMode" << std::endl;}
- template <class Event>
- void on_exit(Event const& ) {std::cout << "finishing: ErrorMode" << std::endl;}
- };
-
- // the initial state of the player SM. Must be defined
- typedef mpl::vector<Empty,AllOk> initial_state;
- //typedef Empty initial_state; // this is to have only one active state
+ // 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
+ struct Song1 : public state_machine<Song1,NoHistory,my_visitable_state>
+ {
+ typedef mpl::vector1<FirstSongPlaying> flag_list;
+ template <class Event>
+ 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()
+ {
+ std::cout << "visiting state:" << typeid(*this).name() << std::endl;
+ }
+ struct LightOn : public state<my_visitable_state>
+ {
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "starting: LightOn" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: LightOn" << std::endl;}
+ };
+ struct LightOff : public state<my_visitable_state>
+ {
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "starting: LightOff" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: LightOff" << std::endl;}
+ };
+ // the initial state. Must be defined
+ typedef LightOn initial_state;
+ // transition actions
+ void turn_light_off(ThreeSec const&) { std::cout << "3s off::turn light off\n"; }
+ // guard conditions
+
+ // friend definition needed.
+ friend class state_machine<Song1>;
+ typedef Song1 s; // makes transition table cleaner
+ // Transition table for Song1
+ struct transition_table : mpl::vector1<
+ // Start Event Next Action Guard
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < LightOn , ThreeSec , LightOff, &s::turn_light_off >
+ // +---------+-------------+---------+---------------------+----------------------+
+ > {};
+ // Replaces the default no-transition response.
+ template <class Event>
+ int no_transition(int state, Event const& )
+ {
+ std::cout << "no transition from state " << state
+ << " on event " << typeid(Event).name() << std::endl;
+ return state;
+ }
+
+ };
+ struct Song2 : public state<my_visitable_state>
+ {
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "starting: Second song" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: Second Song" << std::endl;}
+ };
+ struct Song3 : public state<my_visitable_state>
+ {
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "starting: Third song" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: Third Song" << std::endl;}
+ };
+ // the initial state. Must be defined
+ typedef Song1 initial_state;
+ // transition actions
+ void start_next_song(NextSong const&) { std::cout << "Playing::start_next_song\n"; }
+ void start_prev_song(PreviousSong const&) { std::cout << "Playing::start_prev_song\n"; }
+ // guard conditions
+
+ // friend definition needed.
+ friend class state_machine<Playing>;
+ typedef Playing pl; // makes transition table cleaner
+ // Transition table for Playing
+ struct transition_table : mpl::vector4<
+ // Start Event Next Action Guard
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Song1 , NextSong , Song2 , &pl::start_next_song >,
+ a_row < Song2 , PreviousSong, Song1 , &pl::start_prev_song >,
+ a_row < Song2 , NextSong , Song3 , &pl::start_next_song >,
+ a_row < Song3 , PreviousSong, Song2 , &pl::start_prev_song >
+ // +---------+-------------+---------+---------------------+----------------------+
+ > {};
+ // Replaces the default no-transition response.
+ template <class Event>
+ int no_transition(int state, Event const&)
+ {
+ std::cout << "no transition from state " << state
+ << " on event " << typeid(Event).name() << std::endl;
+ return state;
+ }
+ };
+ // the player state machine contains a state which is himself a state machine (2 of them, Playing and Paused)
+ struct Paused : public state_machine<Paused,NoHistory,my_visitable_state>
+ {
+ typedef mpl::vector2<PlayingPaused,CDLoaded> flag_list;
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "entering: Paused" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "leaving: Paused" << std::endl;}
+
+ // The list of FSM states
+ struct StartBlinking : public state<my_visitable_state>
+ {
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "starting: StartBlinking" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: StartBlinking" << std::endl;}
+ };
+ struct StopBlinking : public state<my_visitable_state>
+ {
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "starting: StopBlinking" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: StopBlinking" << std::endl;}
+ };
+ // the initial state. Must be defined
+ typedef StartBlinking initial_state;
+ // transition actions
+ void start_blinking(TenSec const&) { std::cout << "Paused::start_blinking\n"; }
+ void stop_blinking(TenSec const&) { std::cout << "Paused::stop_blinking\n"; }
+ // guard conditions
+
+ // friend definition needed.
+ friend class state_machine<Paused>;
+ typedef Paused pa; // makes transition table cleaner
+ // Transition table
+ struct transition_table : mpl::vector2<
+ // Start Event Next Action Guard
+ // +---------------+-------------+--------------+---------------------+----------------------+
+ a_row < StartBlinking , TenSec , StopBlinking , &pa::stop_blinking >,
+ a_row < StopBlinking , TenSec , StartBlinking , &pa::start_blinking >
+ // +---------------+-------------+---------------+--------------------+----------------------+
+ > {};
+ // Replaces the default no-transition response.
+ template <class Event>
+ int no_transition(int state, Event const& )
+ {
+ std::cout << "no transition from state " << state
+ << " on event " << typeid(Event).name() << std::endl;
+ return state;
+ }
+ };
+ struct SleepMode : public state<my_visitable_state> {}; // dumy state just to test the automatic id generation
+
+ struct AllOk : public state<my_visitable_state>
+ {
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "starting: AllOk" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: AllOk" << std::endl;}
+ };
+ struct ErrorMode : //public terminate_state<>
+ public interrupt_state<end_error,my_visitable_state>
+ {
+ template <class Event>
+ void on_entry(Event const& ) {std::cout << "starting: ErrorMode" << std::endl;}
+ template <class Event>
+ void on_exit(Event const& ) {std::cout << "finishing: ErrorMode" << std::endl;}
+ };
+
+ // the initial state of the player SM. Must be defined
+ typedef mpl::vector<Empty,AllOk> initial_state;
+ //typedef Empty initial_state; // this is to have only one active state
 
 #ifdef __MWERKS__
- public: // Codewarrior bug workaround. Tested at 0x3202
+ public: // Codewarrior bug workaround. Tested at 0x3202
 #endif
- // transition actions
- void start_playback(play const&) { std::cout << "player::start_playback\n"; }
- void open_drawer(open_close const&) { std::cout << "player::open_drawer\n"; }
- void close_drawer(open_close const&) { std::cout << "player::close_drawer\n"; }
- void store_cd_info(cd_detected const&)
- {
- std::cout << "player::store_cd_info\n";
- // generate another event to test the queue
- //cd.m_player.process_event(play());
- }
- void stop_playback(stop const&) { std::cout << "player::stop_playback\n"; }
- void pause_playback(pause const&) { std::cout << "player::pause_playback\n"; }
- void resume_playback(end_pause const&) { std::cout << "player::resume_playback\n"; }
- void stop_and_open(open_close const&) { std::cout << "player::stop_and_open\n"; }
- void stopped_again(stop const&) {std::cout << "player::stopped_again\n";}
- void start_sleep(go_sleep const&) { }
- void report_error(error_found const&) {std::cout << "player::report_error\n";}
- void report_end_error(end_error const&) {std::cout << "player::report_end_error\n";}
- // guard conditions
+ // transition actions
+ void start_playback(play const&) { std::cout << "player::start_playback\n"; }
+ void open_drawer(open_close const&) { std::cout << "player::open_drawer\n"; }
+ void close_drawer(open_close const&) { std::cout << "player::close_drawer\n"; }
+ void store_cd_info(cd_detected const&)
+ {
+ std::cout << "player::store_cd_info\n";
+ // generate another event to test the queue
+ //cd.m_player.process_event(play());
+ }
+ void stop_playback(stop const&) { std::cout << "player::stop_playback\n"; }
+ void pause_playback(pause const&) { std::cout << "player::pause_playback\n"; }
+ void resume_playback(end_pause const&) { std::cout << "player::resume_playback\n"; }
+ void stop_and_open(open_close const&) { std::cout << "player::stop_and_open\n"; }
+ void stopped_again(stop const&) {std::cout << "player::stopped_again\n";}
+ void start_sleep(go_sleep const&) { }
+ void report_error(error_found const&) {std::cout << "player::report_error\n";}
+ void report_end_error(end_error const&) {std::cout << "player::report_end_error\n";}
+ // guard conditions
 
 
 #ifdef __MWERKS__
- private:
+ private:
 #endif
- // friend definition needed.
- friend class state_machine<player>;
- typedef player p; // makes transition table cleaner
-
- // Transition table for player
- struct transition_table : mpl::vector<
- // Start Event Next Action Guard
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Stopped , play , Playing , &p::start_playback >,
- a_row < Stopped , open_close , Open , &p::open_drawer >,
- a_row < Stopped , stop , Stopped , &p::stopped_again >,
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Open , open_close , Empty , &p::close_drawer >,
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Empty , open_close , Open , &p::open_drawer >,
- a_row < Empty , cd_detected , Stopped , &p::store_cd_info >,
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Playing , stop , Stopped , &p::stop_playback >,
- a_row < Playing , pause , Paused , &p::pause_playback >,
- a_row < Playing , open_close , Open , &p::stop_and_open >,
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Paused , end_pause , Playing , &p::resume_playback >,
- a_row < Paused , stop , Stopped , &p::stop_playback >,
- a_row < Paused , open_close , Open , &p::stop_and_open >,
- a_row < Paused , go_sleep ,SleepMode, &p::start_sleep >,
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < AllOk , error_found ,ErrorMode, &p::report_error >,
- a_row <ErrorMode,end_error ,AllOk , &p::report_end_error >
- // +---------+-------------+---------+---------------------+----------------------+
- > {};
-
- // Replaces the default no-transition response.
- template <class Event>
- int no_transition(int state, Event const& )
- {
- std::cout << "no transition from state " << state
- << " on event " << typeid(Event).name() << std::endl;
- return state;
- }
- };
-
- //
- // Testing utilities.
- //
-
- void pstate(player const& p)
- {
- // instead of the hard-coded array we can use fill_state_names:
- //static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused","AllOk","ErrorMode","SleepMode" };
- typedef player::transition_table stt;
- typedef generate_state_set<stt>::type all_states;
- static char const* state_names[mpl::size<all_states>::value];
- // fill the names of the states defined in the state machine
- mpl::for_each<all_states,boost::msm::wrap<mpl::placeholders::_1> >(fill_state_names<stt>(state_names));
-
- for (unsigned int i=0;i<p.current_state().size();++i)
- {
- std::cout << " -> " << state_names[p.current_state()[i]] << std::endl;
- }
- }
- void test()
- {
- player p;
- // get a pointer to a state
- // just to show how to do it as Stopped gets a pointer to player anyway
- player::Stopped* tempstate = p.get_state<player::Stopped*>();
- tempstate->m_player = &p;
- // get a reference to a state
- player::Stopped& tempstate2 = p.get_state<player::Stopped&>();
- tempstate2.m_player = &p;
- // make a copy of a state
- player::Stopped tempstate3 = p.get_state<player::Stopped&>();
-
- // needed to start the highest-level SM. This will call on_entry and mark the start of the SM
- p.start();
- std::cout << "CDLoaded active:" << std::boolalpha << p.is_flag_active<CDLoaded>() << std::endl; //=> false (no CD yet)
-
- // test deferred event
- // deferred in Empty and Open, will be handled only after event cd_detected
- p.process_event(play());
-
- // 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));
- // no need to call play() as the previous event does it in its action method
- //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
- p.process_event(pause()); pstate(p);
- std::cout << "PlayingPaused active:" << std::boolalpha << p.is_flag_active<PlayingPaused>() << std::endl;//=> true
- // forward events to Paused
- p.process_event(TenSec());
- p.process_event(TenSec());
- // go back to Playing
- p.process_event(end_pause()); pstate(p);
- std::cout << "FirstSong active:" << std::boolalpha << p.is_flag_active<FirstSongPlaying>() << std::endl; //=> true
- p.process_event(ThreeSec()); pstate(p);
- 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);
- // Pause
- p.process_event(pause()); pstate(p);
- // go back to Playing
- // but end_pause is an event activating the History
- // => keep the last active State (SecondSong)
- p.process_event(end_pause()); pstate(p);
- // test of an event from a state to itself. According to UML spec, call again exit/entry from Stopped
- p.process_event(stop()); pstate(p);
- p.process_event(stop()); pstate(p);
- std::cout << "CDLoaded active:" << std::boolalpha << p.is_flag_active<CDLoaded>() << std::endl;//=> true
- std::cout << "PlayingPaused active:" << std::boolalpha << p.is_flag_active<PlayingPaused>() << std::endl;//=> false
- std::cout << "FirstSong active:" << std::boolalpha << p.is_flag_active<FirstSongPlaying>() << std::endl;//=> false
- std::cout << "CDLoaded active with AND:" << std::boolalpha << p.is_flag_active<CDLoaded,player::Flag_AND>() << std::endl;//=> false
- std::cout << "CDLoaded active with OR:" << std::boolalpha << p.is_flag_active<CDLoaded,player::Flag_OR>() << std::endl;//=> true
-
- // go back to Playing
- // but play is not leading to Shallow History => do not remember the last active State (SecondSong)
- // and activate again FirstSong and LightOn
- p.process_event(play()); pstate(p);
- p.process_event(error_found()); pstate(p);
-
- // try generating more events
- std::cout << "Trying to generate another event" << std::endl; // will not work, fsm is terminated or interrupted
- p.process_event(NextSong());pstate(p);
-
- std::cout << "Trying to end the error" << std::endl; // will work only if ErrorMode is interrupt state
- p.process_event(end_error());pstate(p);
- std::cout << "Trying to generate another event" << std::endl; // will work only if ErrorMode is interrupt state
- p.process_event(NextSong());pstate(p);
-
- std::cout << "Simulate error. Event play is not valid" << std::endl;
- p.process_event(play()); pstate(p);
-
-
- // the states and events of the higher level FSM (player)
- typedef player::transition_table stt;
- typedef generate_state_set<stt>::type simple_states;
-
- std::cout << "the state list:" << std::endl;
- mpl::for_each<simple_states,boost::msm::wrap<mpl::placeholders::_1> >(display_type ());
-
- std::cout << "the event list:" << std::endl;
- typedef generate_event_set<stt>::type event_list;
- mpl::for_each<event_list,boost::msm::wrap<mpl::placeholders::_1> >(display_type ());
- std::cout << std::endl;
-
- // the states and events recursively searched
- typedef recursive_get_transition_table<player>::type recursive_stt;
-
- std::cout << "the state list (including sub-SMs):" << std::endl;
-
- typedef generate_state_set<recursive_stt>::type all_states;
- mpl::for_each<all_states,boost::msm::wrap<mpl::placeholders::_1> >(display_type ());
-
- std::cout << "the event list (including sub-SMs):" << std::endl;
- typedef generate_event_set<recursive_stt>::type all_events;
- mpl::for_each<all_events,boost::msm::wrap<mpl::placeholders::_1> >(display_type ());
-
- }
+ // friend definition needed.
+ friend class state_machine<player>;
+ typedef player p; // makes transition table cleaner
+
+ // Transition table for player
+ struct transition_table : mpl::vector<
+ // Start Event Next Action Guard
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Stopped , play , Playing , &p::start_playback >,
+ a_row < Stopped , open_close , Open , &p::open_drawer >,
+ a_row < Stopped , stop , Stopped , &p::stopped_again >,
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Open , open_close , Empty , &p::close_drawer >,
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Empty , open_close , Open , &p::open_drawer >,
+ a_row < Empty , cd_detected , Stopped , &p::store_cd_info >,
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Playing , stop , Stopped , &p::stop_playback >,
+ a_row < Playing , pause , Paused , &p::pause_playback >,
+ a_row < Playing , open_close , Open , &p::stop_and_open >,
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Paused , end_pause , Playing , &p::resume_playback >,
+ a_row < Paused , stop , Stopped , &p::stop_playback >,
+ a_row < Paused , open_close , Open , &p::stop_and_open >,
+ a_row < Paused , go_sleep ,SleepMode, &p::start_sleep >,
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < AllOk , error_found ,ErrorMode, &p::report_error >,
+ a_row <ErrorMode,end_error ,AllOk , &p::report_end_error >
+ // +---------+-------------+---------+---------------------+----------------------+
+ > {};
+
+ // Replaces the default no-transition response.
+ template <class Event>
+ int no_transition(int state, Event const& )
+ {
+ std::cout << "no transition from state " << state
+ << " on event " << typeid(Event).name() << std::endl;
+ return state;
+ }
+ };
+
+ //
+ // Testing utilities.
+ //
+
+ void pstate(player const& p)
+ {
+ // instead of the hard-coded array we can use fill_state_names:
+ //static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused","AllOk","ErrorMode","SleepMode" };
+ typedef player::transition_table stt;
+ typedef generate_state_set<stt>::type all_states;
+ static char const* state_names[mpl::size<all_states>::value];
+ // fill the names of the states defined in the state machine
+ mpl::for_each<all_states,boost::msm::wrap<mpl::placeholders::_1> >(fill_state_names<stt>(state_names));
+
+ for (unsigned int i=0;i<p.current_state().size();++i)
+ {
+ std::cout << " -> " << state_names[p.current_state()[i]] << std::endl;
+ }
+ }
+ void test()
+ {
+ player p;
+ // get a pointer to a state
+ // just to show how to do it as Stopped gets a pointer to player anyway
+ player::Stopped* tempstate = p.get_state<player::Stopped*>();
+ tempstate->m_player = &p;
+ // get a reference to a state
+ player::Stopped& tempstate2 = p.get_state<player::Stopped&>();
+ tempstate2.m_player = &p;
+ // make a copy of a state
+ player::Stopped tempstate3 = p.get_state<player::Stopped&>();
+
+ // needed to start the highest-level SM. This will call on_entry and mark the start of the SM
+ p.start();
+ std::cout << "CDLoaded active:" << std::boolalpha << p.is_flag_active<CDLoaded>() << std::endl; //=> false (no CD yet)
+
+ // test deferred event
+ // deferred in Empty and Open, will be handled only after event cd_detected
+ p.process_event(play());
+
+ // 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
+ p.visit_current_states();
+ p.process_event(open_close()); pstate(p);
+ // visiting Empty and AllOk, but only Empty cares
+ p.visit_current_states();
+
+
+ p.process_event(cd_detected("louie, louie",p));
+ // no need to call play() as the previous event does it in its action method
+ //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();
+
+ 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
+ p.process_event(pause()); pstate(p);
+ std::cout << "PlayingPaused active:" << std::boolalpha << p.is_flag_active<PlayingPaused>() << std::endl;//=> true
+ // forward events to Paused
+ p.process_event(TenSec());
+ p.process_event(TenSec());
+ // go back to Playing
+ p.process_event(end_pause()); pstate(p);
+ std::cout << "FirstSong active:" << std::boolalpha << p.is_flag_active<FirstSongPlaying>() << std::endl; //=> true
+ p.process_event(ThreeSec()); pstate(p);
+ 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();
+
+ p.process_event(NextSong());pstate(p);
+ // 2nd song active
+ p.process_event(PreviousSong());pstate(p);
+ // Pause
+ p.process_event(pause()); pstate(p);
+ // go back to Playing
+ // but end_pause is an event activating the History
+ // => keep the last active State (SecondSong)
+ p.process_event(end_pause()); pstate(p);
+ // test of an event from a state to itself. According to UML spec, call again exit/entry from Stopped
+ p.process_event(stop()); pstate(p);
+ p.process_event(stop()); pstate(p);
+ std::cout << "CDLoaded active:" << std::boolalpha << p.is_flag_active<CDLoaded>() << std::endl;//=> true
+ std::cout << "PlayingPaused active:" << std::boolalpha << p.is_flag_active<PlayingPaused>() << std::endl;//=> false
+ std::cout << "FirstSong active:" << std::boolalpha << p.is_flag_active<FirstSongPlaying>() << std::endl;//=> false
+ std::cout << "CDLoaded active with AND:" << std::boolalpha << p.is_flag_active<CDLoaded,player::Flag_AND>() << std::endl;//=> false
+ std::cout << "CDLoaded active with OR:" << std::boolalpha << p.is_flag_active<CDLoaded,player::Flag_OR>() << std::endl;//=> true
+
+ // go back to Playing
+ // but play is not leading to Shallow History => do not remember the last active State (SecondSong)
+ // and activate again FirstSong and LightOn
+ p.process_event(play()); pstate(p);
+ p.process_event(error_found()); pstate(p);
+
+ // try generating more events
+ std::cout << "Trying to generate another event" << std::endl; // will not work, fsm is terminated or interrupted
+ p.process_event(NextSong());pstate(p);
+
+ std::cout << "Trying to end the error" << std::endl; // will work only if ErrorMode is interrupt state
+ p.process_event(end_error());pstate(p);
+ std::cout << "Trying to generate another event" << std::endl; // will work only if ErrorMode is interrupt state
+ p.process_event(NextSong());pstate(p);
+
+ std::cout << "Simulate error. Event play is not valid" << std::endl;
+ p.process_event(play()); pstate(p);
+ }
 }
 
 int main()

Modified: sandbox/msm/libs/msm/doc/SimpleTutorial.cpp
==============================================================================
--- sandbox/msm/libs/msm/doc/SimpleTutorial.cpp (original)
+++ sandbox/msm/libs/msm/doc/SimpleTutorial.cpp 2009-02-16 16:49:41 EST (Mon, 16 Feb 2009)
@@ -44,34 +44,34 @@
             // every (optional) entry/exit methods get the event passed.
             template <class Event>
             void on_entry(Event const& ) {std::cout << "entering: Empty" << std::endl;}
- template <class Event>
+ template <class Event>
             void on_exit(Event const& ) {std::cout << "leaving: Empty" << std::endl;}
         };
         struct Open : public state<>
         {
             template <class Event>
             void on_entry(Event const& ) {std::cout << "entering: Open" << std::endl;}
- template <class Event>
+ template <class Event>
             void on_exit(Event const& ) {std::cout << "leaving: Open" << std::endl;}
         };
-
+
         struct Stopped : public state<>
         {
             // when stopped, the CD is loaded
             template <class Event>
             void on_entry(Event const& ) {std::cout << "entering: Stopped" << std::endl;}
- template <class Event>
+ template <class Event>
             void on_exit(Event const& ) {std::cout << "leaving: Stopped" << std::endl;}
         };
-
+
         struct Playing : public state<>
         {
             template <class Event>
             void on_entry(Event const& ) {std::cout << "entering: Playing" << std::endl;}
- template <class Event>
+ template <class Event>
             void on_exit(Event const& ) {std::cout << "leaving: Playing" << std::endl;}
         };
-
+
         // state not defining any entry or exit
         struct Paused : public state<>
         {
@@ -129,23 +129,23 @@
         struct transition_table : mpl::vector<
             // Start Event Next Action Guard
             // +---------+-------------+---------+---------------------+----------------------+
- a_row < Stopped , play , Playing , &p::start_playback >,
- a_row < Stopped , open_close , Open , &p::open_drawer >,
- _row < Stopped , stop , Stopped >,
+ a_row < Stopped , play , Playing , &p::start_playback >,
+ a_row < Stopped , open_close , Open , &p::open_drawer >,
+ _row < Stopped , stop , Stopped >,
             // +---------+-------------+---------+---------------------+----------------------+
- a_row < Open , open_close , Empty , &p::close_drawer >,
+ a_row < Open , open_close , Empty , &p::close_drawer >,
             // +---------+-------------+---------+---------------------+----------------------+
- a_row < Empty , open_close , Open , &p::open_drawer >,
+ a_row < Empty , open_close , Open , &p::open_drawer >,
             row < Empty , cd_detected , Stopped , &p::store_cd_info ,&p::good_disk_format>,
             row < Empty , cd_detected , Playing , &p::store_cd_info ,&p::auto_start >,
             // +---------+-------------+---------+---------------------+----------------------+
- a_row < Playing , stop , Stopped , &p::stop_playback >,
- a_row < Playing , pause , Paused , &p::pause_playback >,
- a_row < Playing , open_close , Open , &p::stop_and_open >,
- // +---------+-------------+---------+---------------------+----------------------+
- a_row < Paused , end_pause , Playing , &p::resume_playback >,
- a_row < Paused , stop , Stopped , &p::stop_playback >,
- a_row < Paused , open_close , Open , &p::stop_and_open >
+ a_row < Playing , stop , Stopped , &p::stop_playback >,
+ a_row < Playing , pause , Paused , &p::pause_playback >,
+ a_row < Playing , open_close , Open , &p::stop_and_open >,
+ // +---------+-------------+---------+---------------------+----------------------+
+ a_row < Paused , end_pause , Playing , &p::resume_playback >,
+ a_row < Paused , stop , Stopped , &p::stop_playback >,
+ a_row < Paused , open_close , Open , &p::stop_and_open >
             // +---------+-------------+---------+---------------------+----------------------+
> {};
 
@@ -183,7 +183,7 @@
         p.process_event(
             cd_detected("louie, louie",DISK_CD,p)); pstate(p);
         // no need to call play() as the previous event does it in its action method
-
+
         // at this point, Play is active
         p.process_event(pause()); pstate(p);
         // go back to Playing

Modified: sandbox/msm/libs/msm/doc/index.html
==============================================================================
--- sandbox/msm/libs/msm/doc/index.html (original)
+++ sandbox/msm/libs/msm/doc/index.html 2009-02-16 16:49:41 EST (Mon, 16 Feb 2009)
@@ -6,7 +6,7 @@
         <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="20090215;22424300">
+ <META NAME="CHANGED" CONTENT="20090216;22481600">
         <META NAME="Info 1" CONTENT="">
         <META NAME="Info 2" CONTENT="">
         <META NAME="Info 3" CONTENT="">
@@ -14,6 +14,8 @@
         <META NAME="CHANGEDBY" CONTENT="Christophe Henry">
         <META NAME="CHANGEDBY" CONTENT="Christophe Henry">
         <META NAME="CHANGEDBY" CONTENT="Christophe Henry">
+ <META NAME="CHANGEDBY" CONTENT="Christophe Henry">
+ <META NAME="CHANGEDBY" CONTENT="Christophe Henry">
         <META NAME="CHANGEDBY" CONTENT="xtoff">
         <META NAME="CHANGEDBY" CONTENT="xtoff">
         <META NAME="CHANGEDBY" CONTENT="xtoff">
@@ -133,6 +135,16 @@
 </P>
 <H1 CLASS="western" STYLE="page-break-before: always"><A NAME="2.Changes compared to previous version|outline"></A>
 Changes compared to previous version</H1>
+<P>Changes from 1.10 to 1.20 (RC1)</P>
+<UL>
+ <LI><P>Added visitor implementation</P>
+ <LI><P>Added by state&lt;&gt;, terminate_state&lt;&gt;... a BASE
+ template parameter in first position defaulting to
+ default_base_state. No breaking change if no SMPtr policy chosen.</P>
+ <LI><P>Renamed SMPtr/NoSMPtr to sm_ptr / no_sm_ptr. Old names
+ deprecated by still supported.</P>
+</UL>
+<P>Changes from 1.0 to 1.10</P>
 <UL>
         <LI><P>Corrected bugs that events were not forwarded to the sub-
         state machine if this sub- state machine appeared only as target in
@@ -1832,7 +1844,7 @@
 <P STYLE="margin-bottom: 0cm"><CODE><FONT COLOR="#0000ff"><FONT SIZE=2>struct</FONT></FONT></CODE><CODE><FONT COLOR="#000000">
 </FONT></CODE><CODE><FONT COLOR="#030003"><FONT SIZE=2>Stopped</FONT></FONT></CODE><CODE><FONT COLOR="#000000">
 </FONT></CODE><CODE><FONT COLOR="#000000"><FONT SIZE=2>: </FONT></FONT></CODE><CODE><FONT COLOR="#0000ff"><FONT SIZE=2>public</FONT></FONT></CODE><CODE><FONT COLOR="#000000">
-</FONT></CODE><CODE><FONT COLOR="#030003"><FONT SIZE=2>state</FONT></FONT></CODE><CODE><FONT COLOR="#000000"><FONT SIZE=2>&lt;</FONT></FONT></CODE><CODE><FONT COLOR="#030003"><FONT SIZE=2>SMPtr</FONT></FONT></CODE><CODE><FONT COLOR="#000000"><FONT SIZE=2>&gt;</FONT></FONT></CODE></P>
+</FONT></CODE><CODE><FONT COLOR="#030003"><FONT SIZE=2>state</FONT></FONT></CODE><CODE><FONT COLOR="#000000"><FONT SIZE=2>&lt;</FONT></FONT></CODE><CODE><FONT COLOR="#030003"><FONT SIZE=2>sm_ptr</FONT></FONT></CODE><CODE><FONT COLOR="#000000"><FONT SIZE=2>&gt;</FONT></FONT></CODE></P>
 <P STYLE="margin-bottom: 0cm"><BR>
 </P>
 <P STYLE="margin-bottom: 0cm">And to provide a set_sm_ptr function:</P>
@@ -2309,7 +2321,7 @@
 </FONT><FONT COLOR="#000000"><FONT SIZE=3>Alarm...</FONT></FONT></P>
 <P><FONT COLOR="#000000"><FONT SIZE=3>And identify each instance in
 alarmBeeps as Alarm&lt;1&gt;, Alarm&lt;2&gt;, etc. in the
-<FONT FACE="Courier New, monospace">initial_state</FONT> typedef of
+<FONT FACE="Courier New, monospace">initial_state</FONT> typedef of
 alarmBeeps, which can therefore do without a single row in its
 transition table:</FONT></FONT></P>
 <P><FONT COLOR="#000000"><FONT FACE="Courier New, monospace"><FONT SIZE=3>typedef


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