Отсрочка событий от подчиненного автомата

В моем проекте есть конечный автомат, реализованный с использованием расширенного мета-конечного автомата. Это основной конечный автомат, есть состояние (назовем его SubMachineEntry для простоты), которая представляет точку входа в подчиненный автомат:

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_>;

Этот подчиненный конечный автомат выполняет некоторую обработку, а затем мы возвращаемся к внешнему конечному автомату, чтобы определить

using SubMachineFinished = SubMachine::exit_pt<...>;

, который представляет состояние выхода вспомогательной машины. Моя проблема заключается в том, что перед выходом из машины состояний возникает определенное событие (toProcessInOuter) может быть отправлено, и оно должно быть обработано во внешнем автомате после выхода из вспомогательного автомата. Помещение этого события как отложенного во всех состояниях в подчиненном автомате не работает, оно не передается в состояние, которое приходит после SubMachineFinished, Есть ли способ реализовать это перенаправление события, используя какой-то механизм повышения MSM, не используя какой-либо пользовательский обходной путь?

0

Решение

К сожалению, отложенные события на подчиненном компьютере не могут оцениваться на родительском автомате на MSM. Таким образом, вам нужно написать переход отсрочки в родительском состоянии.

События оцениваются от внутреннего конечного автомата до внешнего конечного автомата. Если вы хотите отложить событие, вы можете записать переход defer в родительское состояние.
Я написал пример, который демонстрирует это.

введите описание изображения здесь

Смотрите прилагаемую схему. Скажем Event2 это событие, которое вы хотите отложить. Вам нужно написать отложенный переход к State1,

Вот весь код:

#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

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector