Как распределить / разбить реализацию конечного автомата boost :: msm на несколько файлов? - PullRequest
0 голосов
/ 29 мая 2018

Я хочу разбить реализацию boost :: msm statemachine на несколько файлов.Я ищу что-то вроде:

1) Один заголовок на состояние

2) Один заголовок для основного конечного автомата (внешний SM) Но я не знаю, как этофайл должен быть записан

3) клиентский код, который использует SM.

Ниже приводится то, что я придумал (который не компилируется, выдавая ошибки в виде: «недопустимое использование»неполного типа "и другие ошибки).

Первое состояние выборки:

//State1.h
#include <iostream>
#include <boost/msm/back/state_machine.hpp>
#include <boost/msm/front/state_machine_def.hpp>
#include <boost/msm/front/functor_row.hpp>

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

struct State1:msmf::state<> 
{
    // Entry action
    template <class Event,class Fsm>
    void on_entry(Event const&, Fsm&) const {
        std::cout << "State1::on_entry()" << std::endl;
    }
    // Exit action
    template <class Event,class Fsm>
    void on_exit(Event const&, Fsm&) const {
        std::cout << "State1::on_exit()" << std::endl;
    }
};

Второе состояние выборки:

//State2.h
#include <iostream>
#include <boost/msm/back/state_machine.hpp>
#include <boost/msm/front/state_machine_def.hpp>
#include <boost/msm/front/functor_row.hpp>

namespace msm = boost::msm;
namespace msmf = boost::msm::front;
namespace mpl = boost::mpl;
struct State2:msmf::state<> 
{
   // Entry action
   template <class Event,class Fsm>
   void on_entry(Event const&, Fsm&) const {
   std::cout << "State2::on_entry()" << std::endl;
   }
   // Exit action
   template <class Event,class Fsm>
   void on_exit(Event const&, Fsm&) const {
        std::cout << "State2::on_exit()" << std::endl;
   }
};

Основной SM:

//MyFsm.h
#include <iostream>
#include <boost/msm/back/state_machine.hpp>     
#include <boost/msm/front/state_machine_def.hpp>
#include <boost/msm/front/functor_row.hpp>

#include "state1.h"
#include "state2.h"     

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

// ----- Events
struct Event1 {};
struct Event2 {};

struct MyFsm_ : msmf::state_machine_def<MyFsm_>
{    
    struct State1;//??? is this the correct way
    struct State2;//???

   // Set initial state
   typedef State1 initial_state;

   // Transition table
   struct transition_table:mpl::vector<
   ...
   >{};
};
// Pick a back-end
typedef msm::back::state_machine<MyFsm_> MyFsm;

Код клиента:

//main.h
#include "myfsm.h"

int main()
{
   MyFsm fsm;
   fsm.start();

   fsm.process_event(Event1());
} 

Любая помощь и подсказка о том, как разделить повышение: msm на несколько файлов, приветствуется.

1 Ответ

0 голосов
/ 30 мая 2018

Вы можете ввести State1 и State2 в MyFsm, используя публичное наследование, следующим образом:

struct MyFsm_ : msmf::state_machine_def<MyFsm_>
{    
    struct State1_ : State1 {}; // use public inheritance
    struct State2_ : State2 {}; // use public inheritance

   // Set initial state
   typedef State1_ initial_state;

   // Transition table
   struct transition_table:mpl::vector<
         msmf::Row < State1_, Event1, State2_, msmf::none, msmf::none >
   >{};
};

В MyFsm_ используйте State1_ и State2_ вместо State1 и State2.

Я обновил вашкод, тогда он работает.

Здесь работает демо: https://wandbox.org/permlink/ZrIVQY38C51fZNFY

Вы можете увидеть весь исходный код.Вкладка соответствует заголовочным файлам.Самый левый имеет фиксированное имя prog.cc.Обычно используется для размещения int main().

...