Как повторно использовать код (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

Другие вопросы по тегам