I want to split the implementation of boost::msm statemachine into multiple files. I am looking for sth like:
1) One header per State
2) One header for the main state-machine (the out-most SM) But I don't know how this file should be written
3) the client code that uses the SM.
What I've come up with follows (which does not compile, giving errors in the form of : "invalid use of incomplete type" & other errors).
The first Sample state:
//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;
}
};
The 2nd Sample state:
//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;
}
};
The Main 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;
The client Code:
//main.h
#include "myfsm.h"
int main()
{
MyFsm fsm;
fsm.start();
fsm.process_event(Event1());
}
Any help and hint on how to split a boost:msm into multiple files is appreciated.
You can introduce State1 and State2 to MyFsm using public inheritance as follows:
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 >
>{};
};
In MyFsm_
, use State1_ and State2_ instead of State1 and State2.
I updated your code, then it works.
Here is running demo: https://wandbox.org/permlink/ZrIVQY38C51fZNFY
You can see whole source code. The tab is corresponding to the header files. The left most one has fixed name prog.cc
. Is is usually used to place int main()
.