• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // same as iPodSearch.cpp but using eUML
12 // requires boost >= v1.40 because using mpl::string
13 
14 #include <vector>
15 #include <iostream>
16 
17 #include <boost/msm/back/state_machine.hpp>
18 #include <boost/msm/front/euml/euml.hpp>
19 #include <boost/msm/front/euml/stl.hpp>
20 
21 using namespace std;
22 using namespace boost::msm::front::euml;
23 namespace msm = boost::msm;
24 namespace mpl = boost::mpl;
25 
26 // how long the timer will ring when countdown elapsed.
27 #define RINGING_TIME 5
28 
29 namespace  // Concrete FSM implementation
30 {
31     // events
32     BOOST_MSM_EUML_DECLARE_ATTRIBUTE(std::string,m_song)
33     BOOST_MSM_EUML_ATTRIBUTES((attributes_ << m_song ), OneSongDef)
34     struct OneSong_impl : euml_event<OneSong_impl>,OneSongDef
35     {
OneSong_impl__anon33af734a0111::OneSong_impl36         OneSong_impl(){}
OneSong_impl__anon33af734a0111::OneSong_impl37         OneSong_impl(const string& asong)
38         {
39             get_attribute(m_song)=asong;
40         }
OneSong_impl__anon33af734a0111::OneSong_impl41         OneSong_impl(const char* asong)
42         {
43             get_attribute(m_song)=asong;
44         }
OneSong_impl__anon33af734a0111::OneSong_impl45         OneSong_impl(const OneSong_impl& asong)
46         {
47             get_attribute(m_song)=asong.get_attribute(m_song);
48         }
get_data__anon33af734a0111::OneSong_impl49         const string& get_data() const {return get_attribute(m_song);}
50     };
51     OneSong_impl const OneSong;
52 
53     // attribute definitions
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(vector<OneSong_impl>,m_src_container)54     BOOST_MSM_EUML_DECLARE_ATTRIBUTE(vector<OneSong_impl>,m_src_container)
55     BOOST_MSM_EUML_DECLARE_ATTRIBUTE(vector<OneSong_impl>,m_tgt_container)
56     BOOST_MSM_EUML_DECLARE_ATTRIBUTE(std::string,m_letters)
57     BOOST_MSM_EUML_DECLARE_ATTRIBUTE(vector<OneSong_impl>::iterator,m_src_it)
58 
59     // the same attribute name can be reused
60     BOOST_MSM_EUML_ATTRIBUTES((attributes_ << m_song ), NotFoundDef)
61     BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES(NotFound,NotFoundDef)
62 
63     BOOST_MSM_EUML_ATTRIBUTES((attributes_ << m_song ), FoundDef)
64     BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES(Found,FoundDef)
65 
66     BOOST_MSM_EUML_EVENT(Done)
67 
68     // Concrete FSM implementation
69 
70     // The list of FSM states
71     BOOST_MSM_EUML_STATE(( (push_back_(fsm_(m_tgt_container),event_(m_song))
72                             ,process_(Done)),
73                            no_action ),Insert)
74 
75     BOOST_MSM_EUML_STATE(( if_then_else_( string_find_(event_(m_song),state_(m_letters)) != Npos_<string>() ,
76                                           process2_(Found,event_(m_song)),
77                                           process2_(NotFound,event_(m_song)) ) ,
78                            no_action,
79                            attributes_ << m_letters ),StringFind)
80 
81     BOOST_MSM_EUML_STATE(( if_then_( state_(m_src_it) != end_(fsm_(m_src_container)),
82                                      process2_(OneSong,*(state_(m_src_it)++)) ),
83                            no_action,
84                            attributes_ << m_src_it ),Foreach)
85 
86     // replaces the old transition table
87     BOOST_MSM_EUML_TRANSITION_TABLE((
88           StringFind  == Foreach     + OneSong ,
89           Insert      == StringFind  + Found  ,
90           Foreach     == StringFind  + NotFound ,
91           Foreach     == Insert      + Done
92           //  +------------------------------------------------------------------------------+
93           ),transition_table )
94 
95     BOOST_MSM_EUML_ACTION(Log_No_Transition)
96     {
97         template <class FSM,class Event>
98         void operator()(Event const& e,FSM&,int state)
99         {
100             std::cout << "no transition from state " << state
101                 << " on event " << typeid(e).name() << std::endl;
102         }
103     };
104     // create a state machine "on the fly"
105     BOOST_MSM_EUML_DECLARE_STATE_MACHINE((     transition_table, //STT
106                                             init_ << Foreach, // Init
107                                             (
108                                             clear_(fsm_(m_src_container)), //clear source
109                                             clear_(fsm_(m_tgt_container)), //clear results
110                                             push_back_(fsm_(m_src_container),
111                                                        String_<mpl::string<'Let ','it ','be'> >()),//add a song
112                                             push_back_(fsm_(m_src_container),
113                                                        String_<mpl::string<'Yell','ow s','ubma','rine'> >()),//add a song
114                                             push_back_(fsm_(m_src_container),
115                                                        String_<mpl::string<'Twis','t an','d Sh','out'> >()),//add a song
116                                             push_back_(fsm_(m_src_container),
117                                                        String_<mpl::string<'She ','love','s yo','u'> >()),//add a song
118                                             attribute_(substate_(Foreach()),m_src_it)
119                                                 = begin_(fsm_(m_src_container)) //set the search begin
120                                             ), // Entry
121                                             no_action, // Exit
122                                             attributes_ << m_src_container // song list
123                                                         << m_tgt_container, // result
124                                             configure_<< no_configure_,
125                                             Log_No_Transition
126                                         ),
127                                         iPodSearch_) //fsm name
128 
129 
130     // choice of back-end
131     typedef msm::back::state_machine<iPodSearch_> iPodSearch;
132 
test()133     void test()
134     {
135         iPodSearch search;
136 
137         // look for "She Loves You" using the first letters
138         search.get_state<BOOST_MSM_EUML_STATE_NAME(StringFind)&>().get_attribute(m_letters)="Sh";// will find 2 songs
139 
140         // needed to start the highest-level SM. This will call on_entry and mark the start of the SM
141         search.start();
142         // display all the songs
143         for (vector<OneSong_impl>::const_iterator it = search.get_attribute(m_tgt_container).begin();
144              it != search.get_attribute(m_tgt_container).end();++it)
145         {
146             cout << "candidate song:" << (*it).get_attribute(m_song) << endl;
147         }
148 
149         cout << "search using more letters" << endl;
150         // look for "She Loves You" using more letters
151         search.get_state<BOOST_MSM_EUML_STATE_NAME(StringFind)&>().get_attribute(m_letters)="She";// will find 1 song
152         search.start();
153         // display all the songs
154         for (vector<OneSong_impl>::const_iterator it = search.get_attribute(m_tgt_container).begin();
155              it != search.get_attribute(m_tgt_container).end();++it)
156         {
157             cout << "candidate song:" << (*it).get_attribute(m_song) << endl;
158         }
159     }
160 }
161 
main()162 int main()
163 {
164     test();
165     return 0;
166 }
167