~ubuntu-branches/debian/sid/boost1.49/sid

« back to all changes in this revision

Viewing changes to libs/msm/doc/PDF/examples/SimpleTutorialEuml2.cpp

  • Committer: Package Import Robot
  • Author(s): Steve M. Robbins
  • Date: 2012-02-26 00:31:44 UTC
  • Revision ID: package-import@ubuntu.com-20120226003144-eaytp12cbf6ubpms
Tags: upstream-1.49.0
ImportĀ upstreamĀ versionĀ 1.49.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2010 Christophe Henry
 
2
// henry UNDERSCORE christophe AT hotmail DOT com
 
3
// This is an extended version of the state machine available in the boost::mpl library
 
4
// Distributed under the same license as the original.
 
5
// Copyright for the original version:
 
6
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
 
7
// under the Boost Software License, Version 1.0. (See accompanying
 
8
// file LICENSE_1_0.txt or copy at
 
9
// http://www.boost.org/LICENSE_1_0.txt)
 
10
 
 
11
#include <vector>
 
12
#include <iostream>
 
13
 
 
14
#include <boost/msm/back/state_machine.hpp>
 
15
#include <boost/msm/front/euml/euml.hpp>
 
16
 
 
17
using namespace std;
 
18
using namespace boost::msm::front::euml;
 
19
namespace msm = boost::msm;
 
20
 
 
21
// entry/exit/action/guard logging functors
 
22
#include "logging_functors.h"
 
23
 
 
24
namespace  // Concrete FSM implementation
 
25
{
 
26
    // events
 
27
    // note that unlike the SimpleTutorial, events must derive from euml_event.
 
28
    BOOST_MSM_EUML_EVENT(play)
 
29
    BOOST_MSM_EUML_EVENT(end_pause)
 
30
    BOOST_MSM_EUML_EVENT(stop)
 
31
    BOOST_MSM_EUML_EVENT(pause)
 
32
    BOOST_MSM_EUML_EVENT(open_close)
 
33
 
 
34
    // A "complicated" event type that carries some data.
 
35
    BOOST_MSM_EUML_DECLARE_ATTRIBUTE(std::string,cd_name)
 
36
    BOOST_MSM_EUML_DECLARE_ATTRIBUTE(DiskTypeEnum,cd_type)
 
37
    BOOST_MSM_EUML_ATTRIBUTES((attributes_ << cd_name << cd_type ), cd_detected_attributes)
 
38
    BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES(cd_detected,cd_detected_attributes)
 
39
 
 
40
    // Concrete FSM implementation 
 
41
 
 
42
    // The list of FSM states
 
43
 
 
44
    // state not needing any entry or exit
 
45
    BOOST_MSM_EUML_STATE((),Paused)
 
46
    BOOST_MSM_EUML_STATE(( Empty_Entry,Empty_Exit ),Empty)
 
47
    BOOST_MSM_EUML_STATE(( Open_Entry,Open_Exit ),Open)
 
48
    BOOST_MSM_EUML_STATE(( Stopped_Entry,Stopped_Exit ),Stopped)
 
49
    BOOST_MSM_EUML_STATE(( Playing_Entry,Playing_Exit ),Playing)
 
50
    
 
51
    // guard conditions
 
52
    BOOST_MSM_EUML_ACTION(good_disk_format)
 
53
    {
 
54
        template <class FSM,class EVT,class SourceState,class TargetState>
 
55
        bool operator()(EVT const& evt,FSM&,SourceState& ,TargetState& )
 
56
        {
 
57
            // to test a guard condition, let's say we understand only CDs, not DVD
 
58
            if (evt.get_attribute(cd_type)!=DISK_CD)
 
59
            {
 
60
                std::cout << "wrong disk, sorry" << std::endl;
 
61
                // just for logging, does not block any transition
 
62
                return true;
 
63
            }
 
64
            std::cout << "good disk" << std::endl;
 
65
            return true;
 
66
        }
 
67
    };
 
68
    // replaces the old transition table
 
69
    BOOST_MSM_EUML_TRANSITION_TABLE((
 
70
          Stopped + play        / start_playback  == Playing                        ,
 
71
          Stopped + open_close  / open_drawer     == Open                           ,
 
72
          Stopped + stop                          == Stopped,
 
73
          //  +------------------------------------------------------------------------------+
 
74
          Open    + open_close  / close_drawer    == Empty                          ,
 
75
          //  +------------------------------------------------------------------------------+
 
76
          Empty   + open_close  / open_drawer     == Open                           ,
 
77
          Empty   + cd_detected
 
78
            [good_disk_format &&(event_(cd_type)==Int_<DISK_CD>())]
 
79
            / (store_cd_info,process_(play))      == Stopped                        ,
 
80
         //  +------------------------------------------------------------------------------+
 
81
          Playing + stop        / stop_playback   == Stopped                        ,
 
82
          Playing + pause       / pause_playback  == Paused                         ,
 
83
          Playing + open_close  / stop_and_open   == Open                           ,
 
84
          //  +------------------------------------------------------------------------------+
 
85
          Paused  + end_pause   / resume_playback == Playing                        ,
 
86
          Paused  + stop        / stop_playback   == Stopped                        ,
 
87
          Paused  + open_close  / stop_and_open   == Open     
 
88
          //  +------------------------------------------------------------------------------+
 
89
          ),transition_table)
 
90
 
 
91
    // create a state machine "on the fly"
 
92
    BOOST_MSM_EUML_DECLARE_STATE_MACHINE(( transition_table, //STT
 
93
                                    init_ << Empty, // Init State
 
94
                                    no_action, // Entry
 
95
                                    no_action, // Exit
 
96
                                    attributes_ << no_attributes_, // Attributes
 
97
                                    configure_ << no_configure_, // configuration
 
98
                                    Log_No_Transition // no_transition handler
 
99
                                    ),
 
100
                                  player_) //fsm name
 
101
 
 
102
    // choice of back-end
 
103
    typedef msm::back::state_machine<player_> player;
 
104
 
 
105
    //
 
106
    // Testing utilities.
 
107
    //
 
108
    static char const* const state_names[] = { "Stopped", "Open", "Empty", "Playing", "Paused" };
 
109
    void pstate(player const& p)
 
110
    {
 
111
        std::cout << " -> " << state_names[p.current_state()[0]] << std::endl;
 
112
    }
 
113
 
 
114
    void test()
 
115
    {        
 
116
        player p;
 
117
        // needed to start the highest-level SM. This will call on_entry and mark the start of the SM
 
118
        p.start(); 
 
119
        // go to Open, call on_exit on Empty, then action, then on_entry on Open
 
120
        p.process_event(open_close); pstate(p);
 
121
        p.process_event(open_close); pstate(p);
 
122
        // will be rejected, wrong disk type
 
123
        p.process_event(
 
124
            cd_detected("louie, louie",DISK_DVD)); pstate(p);
 
125
        p.process_event(
 
126
            cd_detected("louie, louie",DISK_CD)); pstate(p);
 
127
        // no need to call play as the previous event does it in its action method
 
128
        //p.process_event(play);
 
129
 
 
130
        // at this point, Play is active      
 
131
        p.process_event(pause); pstate(p);
 
132
        // go back to Playing
 
133
        p.process_event(end_pause);  pstate(p);
 
134
        p.process_event(pause); pstate(p);
 
135
        p.process_event(stop);  pstate(p);
 
136
        // event leading to the same state
 
137
        // no action method called as none is defined in the transition table
 
138
        p.process_event(stop);  pstate(p);
 
139
        // test call to no_transition
 
140
        p.process_event(pause); pstate(p);
 
141
    }
 
142
}
 
143
 
 
144
int main()
 
145
{
 
146
    test();
 
147
    return 0;
 
148
}
 
149