首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从子状态机延迟事件

从子状态机延迟事件
EN

Stack Overflow用户
提问于 2018-12-21 14:33:04
回答 1查看 400关注 0票数 0

在我的项目中,有一个使用boost元状态机实现的状态机。这个主状态机有一个状态(为了简单起见,我们称它为SubMachineEntry ),它表示子状态机的入口点:

代码语言:javascript
复制
namespace msmf = boost::msm::front;
namespace msmb = boost::msm::back;
...
msmf::Row < SomeState, enterSub, SubMachineEntry, msmf::none, msmf::none >
...
using SubMachine = msmb::state_machine<SubMachine_>;

这个子状态机执行一些处理,然后我们返回到外部状态机,状态。

代码语言:javascript
复制
using SubMachineFinished = SubMachine::exit_pt<...>;

,它表示子机器的退出状态。我的问题是,在子状态机退出之前,可能会分派某个事件(toProcessInOuter),并且应该在子状态机退出之后在外部状态机中处理它。将该事件作为在子状态机中所有状态中延迟的事件不工作,它不会传播到SubMachineFinished之后的状态。是否有一种方法可以使用boost MSM的某种机制来实现事件的转发,而无需使用一些自定义的解决方法?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-12-23 00:48:27

不幸的是,子机器上的延迟事件不能在MSM上的父状态机上进行评估.因此,您需要在父状态下编写延迟转换。

事件从内部状态机到外部状态机进行评估。如果要延迟事件,可以在父状态下写入延迟转换。我写的例子证明了这一点。

见附图。假设Event2是您想要推迟的事件。您需要编写到State1的延迟转换。

以下是整个代码:

代码语言:javascript
复制
#include <iostream>
#include <boost/msm/back/state_machine.hpp>

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

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

// ----- Events
struct Event1 {};
struct Event2 {};

// ----- 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 {
            std::cout << "State1::on_entry()" << std::endl;
        }
        template <class Event,class Fsm>
        void on_exit(Event const&, Fsm&) const {
            std::cout << "State1::on_exit()" << std::endl;
        }

        struct SubState1:msmf::state<> {
            template <class Event,class Fsm>
            void on_entry(Event const&, Fsm&) const {
                std::cout << "SubState1::on_entry()" << std::endl;
            }
            template <class Event,class Fsm>
            void on_exit(Event const&, Fsm&) const {
                std::cout << "SubState1::on_exit()" << std::endl;
            }
        };
        template <class Fsm,class Event> 
        void no_transition(Event const& e, Fsm& ,int state) {
            std::cout << "No handled event in InnerSm " << typeid(e).name() << " on State " << state << std::endl;
        }
        struct Exit1:msmf::exit_pseudo_state<msmf::none> {};
        // Set initial state
        typedef mpl::vector<SubState1> initial_state;
        // Transition table
        struct transition_table:mpl::vector<
            //          Start      Event   Next        Action       Guard
            msmf::Row < SubState1, Event1, Exit1,      msmf::none,  msmf::none >
            > {};
    };
    struct State2:msmf::state<> {
        template <class Event,class Fsm>
        void on_entry(Event const&, Fsm&) const {
            std::cout << "State2::on_entry()" << std::endl;
        }
        template <class Event,class Fsm>
        void on_exit(Event const&, Fsm&) const {
            std::cout << "State2::on_exit()" << std::endl;
        }
    };
    template <class Fsm,class Event> 
    void no_transition(Event const& e, Fsm& ,int state) {
        std::cout << "No handled event in OuterSm " << typeid(e).name() << " on State " << state << std::endl;
    }

    typedef msm::back::state_machine<State1_> State1;
    // Actions
    struct Action {
        template <class Event, class Fsm, class SourceState, class TargetState>
        void operator()(Event const&, Fsm&, SourceState&, TargetState&) const {
            std::cout << "Action()" << std::endl;
        }
    };
    // enable deferred events
    typedef int activate_deferred_events;
    // Set initial state
    typedef State1 initial_state;
    // Transition table
    struct transition_table:mpl::vector<
        //          Start             Event       Next        Action       Guard
        msmf::Row < State1::exit_pt
                    <State1_::Exit1>, msmf::none, State2,     msmf::none,  msmf::none >,
        msmf::Row < State1,           Event2,     msmf::none, msmf::Defer, msmf::none >,
        msmf::Row < State2,           Event2,     msmf::none, Action,      msmf::none >
    > {};
};

// Pick a back-end
typedef msm::back::state_machine<OuterSm_> Osm;


int main() {
    Osm osm;
    osm.start(); 

    std::cout << "> Send Event2()" << std::endl;
    osm.process_event(Event2());
    std::cout << "> Send Event1()" << std::endl;
    osm.process_event(Event1());
    return 0;
}

运行演示:https://wandbox.org/permlink/WQixcoGGQwAWou34

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53886486

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档