]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/msm/doc/HTML/examples/iPodSearch.cpp
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)
14 #include <boost/msm/back/state_machine.hpp>
15 #include <boost/msm/front/state_machine_def.hpp>
18 namespace msm
= boost::msm
;
20 namespace // Concrete FSM implementation
25 OneSong(string
const& asong
):m_Song(asong
){}
26 const string
& get_data() const {return m_Song
;}
33 DATA
get_data() const {return m_Data
;}
39 DATA
get_data() const {return m_Data
;}
44 template <class Container
,class BASE_TYPE
,class FSMType
>
45 struct Insert
: public boost::msm::front::state
<BASE_TYPE
,boost::msm::front::sm_ptr
>
47 template <class Event
,class FSM
>
48 void on_entry(Event
const& evt
,FSM
& )
50 //TODO other containers
53 m_Cont
->insert(evt
.get_data());
55 m_fsm
->process_event(Done());
57 void set_sm_ptr(FSMType
* fsm
){m_fsm
=fsm
;}
58 void set_container(Container
* cont
){m_Cont
=cont
;}
64 template <class BASE_TYPE
,class FSMType
>
65 struct StringFind
: public boost::msm::front::state
<BASE_TYPE
,boost::msm::front::sm_ptr
>
67 template <class Event
,class FSM
>
68 void on_entry(Event
const& evt
,FSM
& )
70 //TODO other containers
71 // if the element in the event is found
72 if (evt
.get_data().find(m_Cont
) != std::string::npos
)
74 Found
<std::string
> res
;
75 res
.m_Data
= evt
.get_data();
76 m_fsm
->process_event(res
);
81 NotFound
<std::string
> res
;
82 res
.m_Data
= evt
.get_data();
83 m_fsm
->process_event(res
);
86 void set_sm_ptr(FSMType
* fsm
){m_fsm
=fsm
;}
87 void set_container(const char* cont
){m_Cont
=cont
;}
92 template <class EventType
,class Container
,class BASE_TYPE
,class FSMType
>
93 struct Foreach
: public boost::msm::front::state
<BASE_TYPE
,boost::msm::front::sm_ptr
>
95 template <class Event
,class FSM
>
96 void on_entry(Event
const& evt
,FSM
& )
98 //TODO other containers
101 typename
Container::value_type next_event
= *m_Cont
.begin();
102 m_Cont
.erase(m_Cont
.begin());
103 m_fsm
->process_event(EventType(next_event
));
106 void set_sm_ptr(FSMType
* fsm
){m_fsm
=fsm
;}
107 void set_container(Container
* cont
){m_Cont
=*cont
;}
115 // Concrete FSM implementation
116 struct iPodSearch_
: public msm::front::state_machine_def
<iPodSearch_
>
118 typedef msm::back::state_machine
<iPodSearch_
> iPodSearch
;
119 // The list of FSM states
120 typedef std::set
<std::string
> Songset
;
121 typedef Insert
<Songset
,boost::msm::front::default_base_state
,iPodSearch
> MyInsert
;
122 typedef StringFind
<boost::msm::front::default_base_state
,iPodSearch
> MyFind
;
123 typedef Foreach
<OneSong
,Songset
,boost::msm::front::default_base_state
,iPodSearch
> MyForeach
;
125 // the initial state of the player SM. Must be defined
126 typedef MyForeach initial_state
;
128 // transition actions
132 typedef iPodSearch_ fsm
; // makes transition table cleaner
134 // Transition table for player
135 struct transition_table
: mpl::vector4
<
136 // Start Event Next Action Guard
137 // +-----------+------------------+------------+---------------------+----------------------+
138 _row
< MyForeach
, OneSong
, MyFind
>,
139 _row
< MyFind
, NotFound
<string
> , MyForeach
>,
140 _row
< MyFind
, Found
<string
> , MyInsert
>,
141 _row
< MyInsert
, Done
, MyForeach
>
142 // +-----------+------------------+------------+---------------------+----------------------+
144 iPodSearch_():m_AllSongs(),m_ResultSearch()
146 // add a few songs for testing
147 m_AllSongs
.insert("Let it be");
148 m_AllSongs
.insert("Yellow submarine");
149 m_AllSongs
.insert("Twist and Shout");
150 m_AllSongs
.insert("She Loves You");
152 template <class Event
,class FSM
>
153 void on_entry(Event
const&,FSM
& fsm
)
155 fsm
.template get_state
<MyForeach
&>().set_container(&m_AllSongs
);
156 fsm
.template get_state
<MyInsert
&>().set_container(&m_ResultSearch
);
158 const Songset
& get_result(){return m_ResultSearch
;}
159 void reset_search(){m_ResultSearch
.clear();}
161 // Replaces the default no-transition response.
162 template <class FSM
,class Event
>
163 void no_transition(Event
const& e
, FSM
&,int state
)
165 std::cout
<< "no transition from state " << state
166 << " on event " << typeid(e
).name() << std::endl
;
171 Songset m_ResultSearch
;
173 typedef msm::back::state_machine
<iPodSearch_
> iPodSearch
;
179 // look for "She Loves You" using the first letters
180 search
.get_state
<iPodSearch::MyFind
*>()->set_container("Sh");// will find 2 songs
182 // needed to start the highest-level SM. This will call on_entry and mark the start of the SM
184 // display all the songs
185 const iPodSearch::Songset
& res
= search
.get_result();
186 for (iPodSearch::Songset::const_iterator it
= res
.begin();it
!= res
.end();++it
)
188 cout
<< "candidate song:" << *it
<< endl
;
190 cout
<< "search using more letters" << endl
;
191 // look for "She Loves You" using more letters
192 search
.reset_search();
193 search
.get_state
<iPodSearch::MyFind
*>()->set_container("She");// will find 1 song
195 const iPodSearch::Songset
& res2
= search
.get_result();
196 for (iPodSearch::Songset::const_iterator it
= res2
.begin();it
!= res2
.end();++it
)
198 cout
<< "candidate song:" << *it
<< endl
;