如何使用Boost MSM检索包含状态机

时间:2019-11-18 10:24:53

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

我使用Boost MSM,并且必须在状态机周围传递数据/使用功能。为此,我使用动作或on_entry挂钩从事件中获取数据,或使用get_state()从先前的使用状态获取数据。

但是,当我处于子状态机中时,我无法使用此技术访问底层状态机,也根本无法访问主状态机。

例如(with playground link):

#include <iostream>

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

namespace msm = boost::msm;
namespace msmf = boost::msm::front;
namespace mpl = boost::mpl;

// ----- Events
struct Ev1 { int data; };
struct Ev2 {};

// ----- State machine
struct MainStateMachine_front : msmf::state_machine_def<MainStateMachine_front>
{
    struct StartState: msmf::state<>
    {};

    struct SubStateMachine_front: msmf::state_machine_def<SubStateMachine_front>
    {
        struct StartSubState: msmf::state<>
        {};

        struct ProcessingState: msmf::state<>
        {
            template <class Event, class FSM>
            void on_entry(const Event &, FSM &fsm)
            {
                const SubStateMachine_front &subSm = fsm.template get_state<const SubStateMachine_front&>(); // Doesn't compile
                MainStateMachine_front &sm = fsm.template get_state<MainStateMachine_front&>(); // Doesn't compile

                // Doesn't compile either
                // const msmf::state_machine_def<SubStateMachine_front> &subSm = fsm.template get_state<const msmf::state_machine_def<SubStateMachine_front>&>(); // Doesn't compile
                // msmf::state_machine_def<MainStateMachine_front> &sm = fsm.template get_state<msmf::state_machine_def<MainStateMachine_front>&>(); // Doesn't compile

                Ev1 dataEvent = subSm.entry_event;
                sm.my_awesome_function(dataEvent.data);
            }
        };

        using initial_state = StartSubState;

        struct transition_table:mpl::vector<
            //          Start             Event     Target
            msmf::Row < StartSubState,    Ev2,      ProcessingState>
        > {};

        template <class FSM>
        void on_entry(const Ev1 &evt, FSM &)
        {
            entry_event = evt;
        }

        Ev1 entry_event;
    };

    using SubStateMachine = msm::back::state_machine<SubStateMachine_front>;

    // Set initial state
    using initial_state = StartState;
    // Transition table
    struct transition_table:mpl::vector<
        //          Start             Event     Target
        msmf::Row < StartState,       Ev1,      SubStateMachine>
    > {};

    void my_awesome_function(int data)
    {
        std::cout << "Awesome " << data << std::endl;
    }
};

using MainStateMachine = msm::back::state_machine<MainStateMachine_front>;

int main()
{
    MainStateMachine sm;
    sm.start();
    sm.process_event(Ev1 { .data = 42 } );
    sm.process_event(Ev2 {});
}

ProcessingState::on_entry中,我无法使用get_state来获取SubStateMachine,也不能使用MainStateMachine。 我知道FSM会解析为SubStateMachine,但是有没有办法获得MainStateMachine呢?

0 个答案:

没有答案