如何重用在父SM的子计算机中定义的代码(Guard)(使用boost-msm)?

时间:2018-08-12 13:12:37

标签: boost template-meta-programming state-machine boost-msm

我已经在子状态机中定义了防护,现在我想在父级SM中使用确切的逻辑/防护(使用boost-msm)。在transition_table中使用相同的防护会导致编译错误:未知类型名称'GuardSS'。

我已经在子机中定义了防护(及其对应的值),但是如果可以帮助解决问题并允许我重用防护,则可以将其移至父级SM。

可以找到示例代码here

如何重用防护中使用的代码?

  

包含代码:

#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 个答案:

答案 0 :(得分:0)

您需要将防护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