Как повторно использовать код (Guard), определенный в подсистеме в родительском SM (используя boost-msm)?
Я определил охрану в подсистеме состояний, и теперь я хочу использовать точную логику / охрану в родительском SM (используя boost-msm). использование той же защиты в файле transition_table приводит к ошибке компиляции: неизвестное имя типа 'GuardSS'.
Я определил охрану (и его соответствующее значение) на вспомогательном компьютере, но его можно переместить в родительский SM, если это помогает в решении проблемы и позволяет мне повторно использовать охрану.
Пример кода можно найти здесь.
Как я могу повторно использовать код, используемый в охране?
Код в комплекте:
#include <iostream>
#include "myfsm.h"
int main()
{
std::cout << "Testing boost::msm ..." << std::endl;
MyFsm fsm;
fsm.start();
fsm.process_event(Event12());
fsm.process_event(Event_ss12());
//guard valu changes
MyFsm_::State2 &state = fsm.get_state<MyFsm_::State2&>();
state.m_guardVal = true;
fsm.process_event(Event_ss12());
fsm.process_event(Event21());//?protect this transition using the same Guard
}
fsm.h:
#ifndef MYFSM
#define MYFSM
#include <iostream>
#include <boost/msm/back/state_machine.hpp>
#include <boost/msm/front/state_machine_def.hpp>
#include <boost/msm/front/functor_row.hpp>
struct Event12{};
struct Event21{};
struct Event_ss12{};
struct Event_ss21{};
namespace msm = boost::msm;
namespace msmf = boost::msm::front;
namespace mpl = boost::mpl;
struct MyFsm_ : msmf::state_machine_def<MyFsm_>
{
struct State1 : msmf::state<>{
template<class Event, class Fsm> void on_entry(const Event&, Fsm&) const {std::cout << "State1::on_entry()" << std::endl;}
template<class Event, class Fsm> void on_exit(const Event&, Fsm&) const {std::cout << "State1::on_exit()" << std::endl;}
};
struct State2_ : msmf::state_machine_def<State2_>{
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 << "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;}
};
struct SubState2 : msmf::state<> {
template <class Event,class Fsm> void on_entry(Event const&, Fsm&) const {std::cout << "SubState2::on_entry()" << std::endl;}
template <class Event,class Fsm> void on_exit(Event const&, Fsm&) const {std::cout << "SubState2::on_exit()" << std::endl;}
};
// Guards
struct GuardSS {
template <class Event, class Fsm, class SourceState, class TargetState>
bool operator()(Event const&, Fsm& fsm, SourceState&, TargetState&)
{
if (fsm.m_guardVal == true){
std::cout << "Transition Approved by Guard \n";
return true;
}
std::cout << "Transition Rejected by Guard \n";
return false;
}
};
typedef SubState1 initial_state;
struct transition_table:mpl::vector<
// Start Event Next Action Guard
msmf::Row < SubState1, Event_ss12, SubState2, msmf::none, GuardSS >,
msmf::Row < SubState2, Event_ss21, SubState1, msmf::none, msmf::none >
> {};
bool m_guardVal=false;
};
typedef msm::back::state_machine<State2_> State2;
// Set initial state
typedef State1 initial_state;
// Transition table
struct transition_table:mpl::vector<
msmf::Row < State1, Event12, State2, msmf::none, msmf::none >,
msmf::Row < State2, Event21, State1, msmf::none, GuardSS/*msmf::none*/ >
>{};
template<class Event, class Fsm>
void no_transition(Event const&, Fsm&, int state){
std::cout<<"no_transiton detected from state: "<< state << std::endl;
}
};
// Pick a back-end
typedef msm::back::state_machine<MyFsm_> MyFsm;
#endif // MYFSM
1 ответ
Вам нужно переместить охранника GuardSS
в родительское состояние MyFsm_
, Так как MyFsm_
не может получить доступ к GuardSS
в оригинальном коде.
Кроме того, вам нужно определить переменную-член bool m_guardVal=false;
в MyFsm_
, Потому что это указано GuardSS
,
Вот обновленный код:
struct MyFsm_ : msmf::state_machine_def<MyFsm_>
{
// Guards (moved to parent from sub)
struct GuardSS {
template <class Event, class Fsm, class SourceState, class TargetState>
bool operator()(Event const&, Fsm& fsm, SourceState&, TargetState&)
{
if (fsm.m_guardVal == true){
std::cout << "Transition Approved by Guard \n";
return true;
}
std::cout << "Transition Rejected by Guard \n";
return false;
}
};
bool m_guardVal=false; // added
struct State1 : msmf::state<>{
// ... snip ...
Демонстрационная версия работает по https://wandbox.org/permlink/V4UJJo3csX427rYi