mirror of
https://github.com/boostorg/msm.git
synced 2026-02-03 09:22:12 +00:00
msm v2.20
[SVN r67936]
This commit is contained in:
158
doc/HTML/examples/SimpleTutorialWithEumlTable.cpp
Normal file
158
doc/HTML/examples/SimpleTutorialWithEumlTable.cpp
Normal file
@@ -0,0 +1,158 @@
|
||||
#include <iostream>
|
||||
// back-end
|
||||
#include <boost/msm/back/state_machine.hpp>
|
||||
//front-end
|
||||
#include <boost/msm/front/state_machine_def.hpp>
|
||||
#include <boost/msm/front/euml/euml.hpp>
|
||||
|
||||
namespace msm = boost::msm;
|
||||
namespace mpl = boost::mpl;
|
||||
using namespace std;
|
||||
|
||||
// entry/exit/action/guard logging functors
|
||||
#include "logging_functors.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
// events
|
||||
struct play_impl : msm::front::euml::euml_event<play_impl> {};
|
||||
struct end_pause_impl : msm::front::euml::euml_event<end_pause_impl>{};
|
||||
struct stop_impl : msm::front::euml::euml_event<stop_impl>{};
|
||||
struct pause_impl : msm::front::euml::euml_event<pause_impl>{};
|
||||
struct open_close_impl : msm::front::euml::euml_event<open_close_impl>{};
|
||||
struct cd_detected_impl : msm::front::euml::euml_event<cd_detected_impl>{};
|
||||
|
||||
// define some dummy instances for use in the transition table
|
||||
// it is also possible to default-construct them instead:
|
||||
// struct play {};
|
||||
// inside the table: play()
|
||||
play_impl play;
|
||||
end_pause_impl end_pause;
|
||||
stop_impl stop;
|
||||
pause_impl pause;
|
||||
open_close_impl open_close;
|
||||
cd_detected_impl cd_detected;
|
||||
|
||||
// The list of FSM states
|
||||
// they have to be declared outside of the front-end only to make VC happy :(
|
||||
// note: gcc would have no problem
|
||||
struct Empty_impl : public msm::front::state<> , public msm::front::euml::euml_state<Empty_impl>
|
||||
{
|
||||
// every (optional) entry/exit methods get the event passed.
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {std::cout << "entering: Empty" << std::endl;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {std::cout << "leaving: Empty" << std::endl;}
|
||||
};
|
||||
struct Open_impl : public msm::front::state<> , public msm::front::euml::euml_state<Open_impl>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const& ,FSM&) {std::cout << "entering: Open" << std::endl;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {std::cout << "leaving: Open" << std::endl;}
|
||||
};
|
||||
|
||||
struct Stopped_impl : public msm::front::state<> , public msm::front::euml::euml_state<Stopped_impl>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const& ,FSM&) {std::cout << "entering: Stopped" << std::endl;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {std::cout << "leaving: Stopped" << std::endl;}
|
||||
};
|
||||
|
||||
struct Playing_impl : public msm::front::state<> , public msm::front::euml::euml_state<Playing_impl>
|
||||
{
|
||||
template <class Event,class FSM>
|
||||
void on_entry(Event const&,FSM& ) {std::cout << "entering: Playing" << std::endl;}
|
||||
template <class Event,class FSM>
|
||||
void on_exit(Event const&,FSM& ) {std::cout << "leaving: Playing" << std::endl;}
|
||||
};
|
||||
|
||||
// state not defining any entry or exit
|
||||
struct Paused_impl : public msm::front::state<> , public msm::front::euml::euml_state<Paused_impl>
|
||||
{
|
||||
};
|
||||
//to make the transition table more readable
|
||||
Empty_impl const Empty;
|
||||
Open_impl const Open;
|
||||
Stopped_impl const Stopped;
|
||||
Playing_impl const Playing;
|
||||
Paused_impl const Paused;
|
||||
|
||||
// front-end: define the FSM structure
|
||||
struct player_ : public msm::front::state_machine_def<player_>
|
||||
{
|
||||
|
||||
// the initial state of the player SM. Must be defined
|
||||
typedef Empty_impl initial_state;
|
||||
|
||||
// Transition table for player
|
||||
// replaces the old transition table
|
||||
BOOST_MSM_EUML_DECLARE_TRANSITION_TABLE((
|
||||
Stopped + play / start_playback == Playing ,
|
||||
Stopped + open_close / open_drawer == Open ,
|
||||
Stopped + stop == Stopped ,
|
||||
// +------------------------------------------------------------------------------+
|
||||
Open + open_close / close_drawer == Empty ,
|
||||
// +------------------------------------------------------------------------------+
|
||||
Empty + open_close / open_drawer == Open ,
|
||||
Empty + cd_detected /(store_cd_info,
|
||||
msm::front::euml::process_(play)) == Stopped ,
|
||||
// +------------------------------------------------------------------------------+
|
||||
Playing + stop / stop_playback == Stopped ,
|
||||
Playing + pause / pause_playback == Paused ,
|
||||
Playing + open_close / stop_and_open == Open ,
|
||||
// +------------------------------------------------------------------------------+
|
||||
Paused + end_pause / resume_playback == Playing ,
|
||||
Paused + stop / stop_playback == Stopped ,
|
||||
Paused + open_close / stop_and_open == Open
|
||||
// +------------------------------------------------------------------------------+
|
||||
),transition_table)
|
||||
|
||||
// Replaces the default no-transition response.
|
||||
template <class FSM,class Event>
|
||||
void no_transition(Event const& e, FSM&,int state)
|
||||
{
|
||||
std::cout << "no transition from state " << state
|
||||
<< " on event " << typeid(e).name() << std::endl;
|
||||
}
|
||||
};
|
||||
// Pick a back-end
|
||||
typedef msm::back::state_machine<player_> player;
|
||||
|
||||
//
|
||||
// Testing utilities.
|
||||
//
|
||||
static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused" };
|
||||
void pstate(player const& p)
|
||||
{
|
||||
std::cout << " -> " << state_names[p.current_state()[0]] << std::endl;
|
||||
}
|
||||
|
||||
void test()
|
||||
{
|
||||
player p;
|
||||
// needed to start the highest-level SM. This will call on_entry and mark the start of the SM
|
||||
p.start();
|
||||
// go to Open, call on_exit on Empty, then action, then on_entry on Open
|
||||
p.process_event(open_close); pstate(p);
|
||||
p.process_event(open_close); pstate(p);
|
||||
p.process_event(cd_detected); pstate(p);
|
||||
|
||||
// at this point, Play is active
|
||||
p.process_event(pause); pstate(p);
|
||||
// go back to Playing
|
||||
p.process_event(end_pause); pstate(p);
|
||||
p.process_event(pause); pstate(p);
|
||||
p.process_event(stop); pstate(p);
|
||||
// event leading to the same state
|
||||
// no action method called as it is not present in the transition table
|
||||
p.process_event(stop); pstate(p);
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test();
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user