i have some trouble implementing a sub-sub-statemachine with boost::msm. I'm trying to minimize my code here...
Test.cpp:
struct SM_ : StateMachineA<SM_> {};
// Pick a back-end
typedef boost::msm::back::state_machine<SM_> SM;
int main()
{
std::cout << "Starting State Machine" << std::endl;
SM sm1;
// sm1.start();
return 0;
}
StateMachineA is defined in StateMachineA.h
namespace msmf = boost::msm::front;
namespace mpl = boost::mpl;
template<typename Derived>
struct StateMachineA: protected msmf::state_machine_def < Derived, msmf::default_base_state >
{
public:
//// Entry point to state machine.
//// Set initial state
typedef mpl::vector<initState, allOk> initial_state;
//// Exit Point
struct Exit :msmf::terminate_state<> {};
// ----- Sub State machine
struct SSM_ : StateMachineB<SSM_> {};
// Pick a back-end
typedef boost::msm::back::state_machine<SSM_> stateMachineB;
//// Transition table
struct transition_table : mpl::vector<
msmf::Row < initState, go, stateMachineB, msmf::none, msmf::none >,
msmf::Row < allOk, fatalThrown, Exit, msmf::none, msmf::none >,
msmf::Row < error, fatalThrown, Exit, msmf::none, msmf::none >
> {};
protected:
template <class FSM, class Event>
void no_transition(Event const&, FSM&, int)
{
std::cout << "ERROR: Unallowed transition detected" << std::endl;
}
};
StateMachineB has a StateMachineC included using the exact same code (replace B by C...).
Putting StateMachineC as a submachine to StateMachineA (omitting StateMachineB) works fine. Same for A -> B without including C works fine as well. Reordering the state machines (A -> C -> B) produces the same error. To sum up: Every combination of two state machines is working, every combination of three state machines is failing.
The error occurs when having SM sm1;
in my main function. -> While resolving the templates?
Without that line, everything compiles fine.
The error log is lengthy (long enough to cause visual studio to crash when hovering it...). First error is:
D:\boost_1_59_0\boost/mpl/aux_/push_front_impl.hpp(45) : error C2664: 'int boost::mpl::assertion_failed<false>(boost::mpl::assert<false>::type)' : cannot convert argument 1 from 'boost::mpl::failed ************(__thiscall boost::mpl::push_front_impl<boost::mpl::aux::vector_tag<20>>::apply<Sequence,T>::REQUESTED_PUSH_FRONT_SPECIALIZATION_FOR_SEQUENCE_DOES_NOT_EXIST::* ***********)(Sequence)' to 'boost::mpl::assert<false>::type'
with ... and around 200 "with" lines to follow. After that, many errors of type:
D:\boost_1_59_0\boost/mpl/aux_/insert_impl.hpp(60) : error C3203: 'type' : unspecialized class template can't be used as a template argument for template parameter 'State', expected a real type
D:\boost_1_59_0\boost/mpl/insert.hpp(32) : error C2903: 'apply' : symbol is neither a class template nor a function template
D:\boost_1_59_0\boost/mpl/aux_/has_type.hpp(20) : see reference to class template instantiation 'boost::mpl::insert<U1,U2,U3>' being compiled
follow.
Any ideas?
Thanks!
I couldn't reproduce your situation but I can show you how to implement SubSub state machine. Here is a document that I wrote. It describes about sub state machine. http://redboltz.wikidot.com/sub-machine-state
To implement SubSub state machine, just apply sub machine implementation twice.
Here is a code that contains SubSub state machine:
You can compile, run and modify it on Wandbox, online-compiler.
https://wandbox.org/permlink/tBCSQDNhkBQkXxh0