0

我已经在子状态机中定义了一个保护,现在我想在父 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
4

1 回答 1

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

于 2018-09-21T07:26:17.387 回答