为什么Boost MMS两次呼叫后卫?

时间:2018-10-19 08:08:05

标签: c++ c++11 state-machine boost-msm

我正在实现一个状态机,如下图 state machine diagram

我向状态机触发“ event1”和“ event2”,当触发“ event1”时,状态机退出“ state1”状态,进入“ state3”子状态机并停留在“ state3-state1”状态。当触发“ event2”时,“ state3”子状态机输入退出指针并进入“ state1”状态。进入“ state1”状态后,我发现“后卫”被调用了两次。以下是我的代码

#include <boost/msm/back/state_machine.hpp>
#include <boost/msm/front/state_machine_def.hpp>
#include <boost/msm/front/internal_row.hpp>
#include <boost/msm/front/functor_row.hpp>

#include <string>
#include <iostream>

using namespace std;
namespace msmf = boost::msm::front;
namespace msmb = boost::msm::back;
namespace mpl = boost::mpl;

struct event1 {};
struct event2 {};

struct S_ : public msmf::state_machine_def<S_>
{
    typedef msmb::state_machine<S_> S;

    struct guard
    {
        template <class Event,class FSM,class SourceState,class TargetState>
        bool operator()(const Event& event, FSM&, SourceState&, TargetState&)
        {
            std::cout << "guard.\n";
            return false;
        }
    };

    struct State1 : public msmf::state<>
    {
        template<class Event, class FSM>
        void on_entry(const Event&, FSM&)
        {
            cout << "entering state: <state1>\n";
        }

        template <class Event,class FSM>
        void on_exit(const Event&, FSM&)
        {
            cout << "leaving state: <state1>\n";
        }
    };

    struct State2 : public msmf::state<>
    {
        template<class Event, class FSM>
        void on_entry(const Event&, FSM&)
        {
            cout << "entering state: <state2>\n";
        }

        template <class Event,class FSM>
        void on_exit(const Event&, FSM&)
        {
            cout << "leaving state: <state2>\n";
        }
    };

    struct State3_ : public msmf::state_machine_def<State3_>
    {
        template<class Event,class FSM>
        void on_entry(const Event&, FSM&)
        {
            cout << "entering state: <state3>\n";
        }

        template <class Event,class FSM>
        void on_exit(const Event&, FSM&)
        {
            cout << "leaving state: <state3>\n";
        }

        struct State1 : public msmf::state<>
        {
            template<class Event, class FSM>
            void on_entry(const Event&, FSM&)
            {
                cout << "entering state: <state3-state1>\n";
            }

            template <class Event,class FSM>
            void on_exit(const Event&, FSM&)
            {
                cout << "leaving state: <state3-state1>\n";
            }
        };

        struct Exit: msmf::exit_pseudo_state<event2>
        {

        };

        typedef State1 initial_state;

        struct transition_table : mpl::vector<
            msmf::Row<State1, event2, Exit, msmf::none, msmf::none>
        >{};

    };
    typedef msmb::state_machine<State3_> State3;
    typedef State1 initial_state;

    struct transition_table : mpl::vector<
        msmf::Row<State1,                         event1,     State3, msmf::none, msmf::none>,
        msmf::Row<State1,                         msmf::none, State2, msmf::none, guard>,
        msmf::Row<State3::exit_pt<State3_::Exit>, event2,     State1, msmf::none, msmf::none>
    >{};
};

typedef msmb::state_machine<S_> S;

int main()
{
    S s;
    s.start();
    s.process_event(event1());
    s.process_event(event2());

    return 0;
}

boost的版本为1.66,程序的输出为

entering state: <state1>
guard.
leaving state: <state1>
entering state: <state3>
entering state: <state3-state1>
leaving state: <state3-state1>
leaving state: <state3>
entering state: <state1>
guard.
guard.

我找到了一个更容易显示相同问题的圆顶,状态机图为here,代码为

#include <boost/msm/back/state_machine.hpp>
#include <boost/msm/front/state_machine_def.hpp>
#include <boost/msm/front/internal_row.hpp>
#include <boost/msm/front/functor_row.hpp>

#include <string>
#include <iostream>

using namespace std;
namespace msmf = boost::msm::front;
namespace msmb = boost::msm::back;
namespace mpl = boost::mpl;

struct event1 {};
struct event2 {};

struct S_ : public msmf::state_machine_def<S_>
{
    typedef msmb::state_machine<S_> S;

    struct guard
    {
        template <class Event,class FSM,class SourceState,class TargetState>
        bool operator()(const Event& event, FSM&, SourceState&, TargetState&)
        {
            std::cout << "guard.\n";
            return false;
        }
    };

    struct State1 : public msmf::state<>
    {
        template<class Event, class FSM>
        void on_entry(const Event&, FSM&)
        {
            cout << "entering state: <state1>\n";
        }

        template <class Event,class FSM>
        void on_exit(const Event&, FSM&)
        {
            cout << "leaving state: <state1>\n";
        }
    };

    struct State2_ : public msmf::state_machine_def<State2_>
    {
        template<class Event,class FSM>
        void on_entry(const Event&, FSM& fsm)
        {
            cout << "entering state: <state2>\n";
        }

        template <class Event,class FSM>
        void on_exit(const Event&, FSM&)
        {
            cout << "leaving state: <state2>\n";
        }

        struct State1 : public msmf::state<>
        {
            template<class Event, class FSM>
            void on_entry(const Event&, FSM&)
            {
                cout << "entering state: <state2-state1>\n";
            }

            template <class Event,class FSM>
            void on_exit(const Event&, FSM&)
            {
                cout << "leaving state: <state2-state1>\n";
            }
        };

        struct State2 : public msmf::state<>
        {
            template<class Event, class FSM>
            void on_entry(const Event&, FSM&)
            {
                cout << "entering state: <state2-state2>\n";
            }

            template <class Event,class FSM>
            void on_exit(const Event&, FSM&)
            {
                cout << "leaving state: <state2-state2>\n";
            }
        };

        typedef State1 initial_state;

        struct transition_table : mpl::vector<
            msmf::Row<State1, msmf::none, State2, msmf::none, guard>
        >{};

    };

    typedef msmb::state_machine<State2_> State2;
    typedef State1 initial_state;

    struct transition_table : mpl::vector<
        msmf::Row<State1, msmf::none, State2, msmf::none, msmf::none>
    >{};
};

typedef msmb::state_machine<S_> S;

int main()
{
    S s;
    s.start();
    return 0;
}

程序的输出是

entering state: <state1>
leaving state: <state1>
entering state: <state2>
entering state: <state2-state1>
guard.
guard.

0 个答案:

没有答案