0

SM 全体とクライアント コード (つまり、SM 外のコード) だけでなく、州間でもデータとアクセスを共有したいと考えています。

私がネットで思いついたことに基づいて、最善の方法は、基本クラスからすべての状態を継承することです。

基本クラスを追加して、すべての状態とそれから継承する SM を作成するのは簡単ですが、この基本クラスのメンバーとして SM のバックエンド/フロントエンドにハンドラーを追加するにはどうすればよいですか?どのように初期化できますか?

このサンプル コードはコンパイルされますが、SubState に設定された fsmHandler にアクセスするとクラッシュします (通常、SubState はルート fsm にアクセスできません)。

質問:

SM 階層の深いサブマシンにあるルート SM とそのデータにアクセスするにはどうすればよいですか?

Q1) 実行時エラーを解決するにはどうすればよいですか?

Q2) クライアント コード (SM の外部) から SM にデータを渡す方法が正しくありません。これを行うより良い方法はありますか?スレッドセーフですか?

Q3) どうすればtypedef StateBase_<MyFsm_> StateBaseコンパイルできますか?

実用的なサンプルを提供していただければ幸いです。お時間をいただきありがとうございます。

コード:

main.cpp

int main()
{    
    std::cout << "Testing boost::msm ..." << std::endl;
    MyFsm fsm;
    fsm.start();

    MyFsm::State1& tempState = fsm.get_state<MyFsm::State1&>();    
    fsm.m_outerSMData=77;
    tempState.m_fsmHandler = &fsm;


    fsm.process_event(Event1());
    fsm.process_event(Event2());
}

myfsm.h

namespace msm = boost::msm;
namespace msmf = boost::msm::front;
namespace mpl = boost::mpl;

struct Event1{};
struct Event2{};

template<class Fsm>
struct StateBase_{
    //StateBase(Fsm *fsm):m_fsm(fsm){}
    StateBase_(){}
    ~StateBase_(){}

    Fsm *m_fsmHandler;
};

//typedef StateBase_<MyFsm_> StateBase;//How can I make this typedef work?

struct MyFsm_ : msmf::state_machine_def<MyFsm_, StateBase_<MyFsm_> >
{
    struct State1 : msmf::state<StateBase_<MyFsm_>>{
        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_, StateBase_>{
        template<class Event, class Fsm> void on_entry(const Event&, Fsm&) const {std::cout << "State2::on_entry()" << std::endl;}
        template<class Event, class Fsm> void on_exit(const Event&, Fsm&) const {std::cout << "State2::on_exit()" << std::endl;}

        struct SubState21 : msmf::state<StateBase_>{
            template<class Event, class Fsm> 
            void on_entry(const Event&, Fsm&) const {
                std::cout << "SubState21::on_entry()" 
                <<"OuterSMData= "<<m_fsmHandler->m_outerSMData <<std::endl;
            }
            template<class Event, class Fsm> 
            void on_exit(const Event&, Fsm&) const {
                std::cout << "SubState21::on_exit()" << std::endl;
            }
        };
        typedef mpl::vector<SubState21> initial_state;
    };
    typedef msm::back::state_machine<State2_> State2;
   // Set initial state
   typedef State1 initial_state;

   // Transition table
   struct transition_table:mpl::vector<
         msmf::Row < State1, Event1, State2, msmf::none, msmf::none >,
         msmf::Row < State2, Event2, State1, msmf::none, 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;
   }

   //void setPtr(int data/*MyFsm_ &fsm*/){State1::m_baseData=10;}
   int m_outerSMData=44;
};
// Pick a back-end
typedef msm::back::state_machine<MyFsm_> MyFsm;
4

1 に答える 1