boost复合状态机
来源:互联网 发布:免费空间 能用mysql 编辑:程序博客网 时间:2024/05/22 00:21
转载一个好的状态机介绍的网站
http://redboltz.wikidot.com/sub-machine-state
Composite state and sub-machine state
Boost.Msm supports composite state and sub-machine state. Consider the following diagrams. State1 is a composite state that has two sub states. They are simply mapped into the code.Naming rule (example)
Before describing the code, I introduce the naming rule. Name_, any name with underscore, is a state's name that inherited state_machine_def class template.
struct State1_:msmf::state_machine_def<State1_>
Name, any name without underscore, is a state's name that doesn't inherited it.
struct State2:msmf::state<>
Name is also used Boost.Msm back-end templates that have the template argument Name_.
typedef msm::back::state_machine<State1_> State1;
Let's see the code corresponds to the above diagrams.
#include <iostream>#include <boost/msm/back/state_machine.hpp> #include <boost/msm/front/state_machine_def.hpp>#include <boost/msm/front/functor_row.hpp>#include <boost/static_assert.hpp> namespace { namespace msm = boost::msm; namespace msmf = boost::msm::front; namespace mpl = boost::mpl; // ----- Events struct Event1 {}; struct Event2 {}; struct Event3 {}; // ----- State machine struct OuterSm_:msmf::state_machine_def<OuterSm_> { struct State1_:msmf::state_machine_def<State1_> { template <class Event,class Fsm> void on_entry(Event const&, Fsm&) const { BOOST_STATIC_ASSERT((boost::is_convertible<Fsm, OuterSm_>::value)); std::cout << "State1::on_entry()" << std::endl; } template <class Event,class Fsm> void on_exit(Event const&, Fsm&) const { BOOST_STATIC_ASSERT((boost::is_convertible<Fsm, OuterSm_>::value)); std::cout << "State1::on_exit()" << std::endl; } struct SubState1:msmf::state<> { template <class Event,class Fsm> void on_entry(Event const&, Fsm&) const { BOOST_STATIC_ASSERT((boost::is_convertible<Fsm, State1_>::value)); std::cout << "SubState1::on_entry()" << std::endl; } template <class Event,class Fsm> void on_exit(Event const&, Fsm&) const { BOOST_STATIC_ASSERT((boost::is_convertible<Fsm, State1_>::value)); std::cout << "SubState1::on_exit()" << std::endl; } }; struct SubState2:msmf::state<> { template <class Event,class Fsm> void on_entry(Event const&, Fsm&) const { BOOST_STATIC_ASSERT((boost::is_convertible<Fsm, State1_>::value)); std::cout << "SubState2::on_entry()" << std::endl; } template <class Event,class Fsm> void on_exit(Event const&, Fsm&) const { BOOST_STATIC_ASSERT((boost::is_convertible<Fsm, State1_>::value)); std::cout << "SubState2::on_exit()" << std::endl; } }; // Set initial state typedef mpl::vector<SubState1> initial_state; // Transition table struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < SubState1, Event2, SubState2, msmf::none, msmf::none >, msmf::Row < SubState2, Event3, SubState1, msmf::none, msmf::none > > {}; }; struct State2:msmf::state<> { template <class Event,class Fsm> void on_entry(Event const&, Fsm&) const { BOOST_STATIC_ASSERT((boost::is_convertible<Fsm, OuterSm_>::value)); std::cout << "State2::on_entry()" << std::endl; } template <class Event,class Fsm> void on_exit(Event const&, Fsm&) const { BOOST_STATIC_ASSERT((boost::is_convertible<Fsm, OuterSm_>::value)); std::cout << "State2::on_exit()" << std::endl; } }; typedef msm::back::state_machine<State1_> State1; // Set initial state typedef State1 initial_state; // Transition table struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < State1, Event1, State2, msmf::none, msmf::none > > {}; }; // Pick a back-end typedef msm::back::state_machine<OuterSm_> Osm; void test() { Osm osm; osm.start(); std::cout << "> Send Event2()" << std::endl; osm.process_event(Event2()); std::cout << "> Send Event1()" << std::endl; osm.process_event(Event1()); }} int main(){ test(); return 0;}// Output://// State1::on_entry()// SubState1::on_entry()// > Send Event2()// SubState1::on_exit()// SubState2::on_entry()// > Send Event1()// SubState2::on_exit()// State1::on_exit()// State2::on_entry()
To implement composite states, inherits state_machine_def class template same as parent state machine.
struct State1_:msmf::state_machine_def<State1_>
And then, connect to back-end state_machine class template.
typedef msm::back::state_machine<State1_> State1;
In parent state machine's transition table, you can use back-end state name.
// Transition table struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < State1, Event1, State2, msmf::none, msmf::none > > {};
These are sub-machine state diagram examples. These diagrams have the same behavior as above diagram that uses composite state. Sub-machine states are more reusable than composite states. For example, you can reuse StateSub as State2's sub-machine state.
This code corresponds to above sub-machine state diagrams.
#include <iostream>#include <boost/msm/back/state_machine.hpp> #include <boost/msm/front/state_machine_def.hpp>#include <boost/msm/front/functor_row.hpp>#include <boost/static_assert.hpp> namespace { namespace msm = boost::msm; namespace msmf = boost::msm::front; namespace mpl = boost::mpl; // ----- Events struct Event1 {}; struct Event2 {}; struct Event3 {}; // ----- State machine struct StateSub_:msmf::state_machine_def<StateSub_> { struct SubState1:msmf::state<> { template <class Event,class Fsm> void on_entry(Event const&, Fsm&) const { BOOST_STATIC_ASSERT((boost::is_convertible<Fsm, StateSub_>::value)); std::cout << "SubState1::on_entry()" << std::endl; } template <class Event,class Fsm> void on_exit(Event const&, Fsm&) const { BOOST_STATIC_ASSERT((boost::is_convertible<Fsm, StateSub_>::value)); std::cout << "SubState1::on_exit()" << std::endl; } }; struct SubState2:msmf::state<> { template <class Event,class Fsm> void on_entry(Event const&, Fsm&) const { BOOST_STATIC_ASSERT((boost::is_convertible<Fsm, StateSub_>::value)); std::cout << "SubState2::on_entry()" << std::endl; } template <class Event,class Fsm> void on_exit(Event const&, Fsm&) const { BOOST_STATIC_ASSERT((boost::is_convertible<Fsm, StateSub_>::value)); std::cout << "SubState2::on_exit()" << std::endl; } }; // Set initial state typedef mpl::vector<SubState1> initial_state; // Transition table struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < SubState1, Event2, SubState2, msmf::none, msmf::none >, msmf::Row < SubState2, Event3, SubState1, msmf::none, msmf::none > > {}; }; typedef msm::back::state_machine<StateSub_> StateSub; struct OuterSm_:msmf::state_machine_def<OuterSm_> { struct State1_:msmf::state_machine_def<State1_> { template <class Event,class Fsm> void on_entry(Event const&, Fsm&) const { BOOST_STATIC_ASSERT((boost::is_convertible<Fsm, OuterSm_>::value)); std::cout << "State1::on_entry()" << std::endl; } template <class Event,class Fsm> void on_exit(Event const&, Fsm&) const { BOOST_STATIC_ASSERT((boost::is_convertible<Fsm, OuterSm_>::value)); std::cout << "State1::on_exit()" << std::endl; } struct Sub_:StateSub {}; typedef Sub_ initial_state; }; // Pick a back-end typedef msm::back::state_machine<State1_> State1; struct State2:msmf::state<> { template <class Event,class Fsm> void on_entry(Event const&, Fsm&) const { BOOST_STATIC_ASSERT((boost::is_convertible<Fsm, OuterSm_>::value)); std::cout << "State2::on_entry()" << std::endl; } template <class Event,class Fsm> void on_exit(Event const&, Fsm&) const { BOOST_STATIC_ASSERT((boost::is_convertible<Fsm, OuterSm_>::value)); std::cout << "State2::on_exit()" << std::endl; } }; // Set initial state typedef State1 initial_state; // Transition table struct transition_table:mpl::vector< // Start Event Next Action Guard msmf::Row < State1, Event1, State2, msmf::none, msmf::none > > {}; }; // Pick a back-end typedef msm::back::state_machine<OuterSm_> Osm; void test() { Osm osm; osm.start(); std::cout << "> Send Event2()" << std::endl; osm.process_event(Event2()); std::cout << "> Send Event1()" << std::endl; osm.process_event(Event1()); }} int main(){ test(); return 0;} // Output://// State1::on_entry()// SubState1::on_entry()// > Send Event2()// SubState1::on_exit()// SubState2::on_entry()// > Send Event1()// SubState2::on_exit()// State1::on_exit()// State2::on_entry()
In the definition of State1_, embed StateSub as Sub_ using inheritance. And set it as an initial_state.
struct State1_:msmf::state_machine_def<State1_> { template <class Event,class Fsm> void on_entry(Event const&, Fsm&) const { BOOST_STATIC_ASSERT((boost::is_convertible<Fsm, OuterSm_>::value)); std::cout << "State1::on_entry()" << std::endl; } template <class Event,class Fsm> void on_exit(Event const&, Fsm&) const { BOOST_STATIC_ASSERT((boost::is_convertible<Fsm, OuterSm_>::value)); std::cout << "State1::on_exit()" << std::endl; } struct Sub_:StateSub {}; typedef Sub_ initial_state; };
0 0
- boost复合状态机
- [转]boost 状态机学习
- Boost状态机--中级篇
- BOOST Statechart 状态机若干注意事项
- boost状态机快速理解例程
- Boost-(MSM)元状态机文档翻译-前言
- 游戏角色并行状态机之boost::msm
- C++学习 Boost状态机说明statechart
- 状态机--状态机8,关于战斗兵种的复合状态和动作融合技术
- 一个很有代表性的boost状态机实例
- 状态机
- 状态机
- 状态机
- 状态机
- 状态机
- 状态机
- 状态机
- 状态机
- iOS去掉navigationBar底部黑线
- 免费WebService接口
- Spring中管理数据源,加密和解密账号密码的方法
- Git 命令行
- 你最好的同事也在背后说
- boost复合状态机
- 操作系统与网络实现 之二十(丁)
- xp系统之家官网纯净版系统下载
- ZCMU-1549-组合数
- 递归函数实现倒计时效果
- RxJava学习总结
- [leetcode]112. Path Sum
- java中窗口window的刷新
- 在Eclipse中设置自动生成注释