I understood that if the transition for handling the event of Derived was not declared. I will got an error of no transition. It's OK. Here is the example about it.
#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 <stdint.h>
#include <assert.h>
struct Base {};
struct Derived : public Base {};
namespace {
namespace msm = boost::msm;
namespace msmf = boost::msm::front;
namespace mpl = boost::mpl;
// ----- State machine
struct Sm1_ :msmf::state_machine_def<Sm1_>
{
template <class FSM, class Event>
void no_transition(Event const&, FSM&, int)
{
std::cout << "no_transition" << std::endl;
}
struct transition1 {
template <class Event, class Fsm, class SourceState, class TargetState>
void operator()(Event const& e, Fsm&, SourceState&, TargetState&) const
{
std::cout << "transition1()" << std::endl;
}
};
struct transition2 {
template <class Event, class Fsm, class SourceState, class TargetState>
void operator()(Event const& e, Fsm&, SourceState&, TargetState&) const
{
std::cout << "transition2()" << std::endl;
}
};
// States
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;
}
};
// Set initial state
typedef State1 initial_state;
// Internal Transition table
struct internal_transition_table :mpl::vector<
// Event Action Guard
msmf::Internal < Base, transition1, msmf::none >
//msmf::Internal < Derived, transition2, msmf::none >
> {};
};
// Pick a back-end
typedef msm::back::state_machine<Sm1_> Sm1;
void test()
{
Sm1 sm1;
sm1.start();
std::cout << "\n> Send Base" << std::endl;
sm1.process_event(Base());
std::cout << "\n> Send Derived" << std::endl;
sm1.process_event(Derived());
}
}
int main()
{
test();
return 0;
}
output:
> Send Base
transition1()
> Send Derived
no_transition
But if I moved the transition table to the State1, then, the event of Derived was handled by the transition1().
Here is the full example,
#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 <stdint.h>
#include <assert.h>
struct Base {};
struct Derived : public Base {};
namespace {
namespace msm = boost::msm;
namespace msmf = boost::msm::front;
namespace mpl = boost::mpl;
// ----- State machine
struct Sm1_ :msmf::state_machine_def<Sm1_>
{
template <class FSM, class Event>
void no_transition(Event const&, FSM&, int)
{
std::cout << "no_transition" << std::endl;
}
struct transition1 {
template <class Event, class Fsm, class SourceState, class TargetState>
void operator()(Event const& e, Fsm&, SourceState&, TargetState&) const
{
std::cout << "transition1()" << std::endl;
}
};
struct transition2 {
template <class Event, class Fsm, class SourceState, class TargetState>
void operator()(Event const& e, Fsm&, SourceState&, TargetState&) const
{
std::cout << "transition2()" << std::endl;
}
};
// States
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;
}
// Internal Transition table
struct internal_transition_table :mpl::vector<
// Event Action Guard
msmf::Internal < Base, transition1, msmf::none >
//msmf::Internal < Derived, transition2, msmf::none >
> {};
};
// Set initial state
typedef State1 initial_state;
};
// Pick a back-end
typedef msm::back::state_machine<Sm1_> Sm1;
void test()
{
Sm1 sm1;
sm1.start();
std::cout << "\n> Send Base" << std::endl;
sm1.process_event(Base());
std::cout << "\n> Send Derived" << std::endl;
sm1.process_event(Derived());
}
}
int main()
{
test();
return 0;
}
output:
> Send Base
transition1()
> Send Derived
transition1()
My question are as follows,
- Is that attempting to use a parent class name to declare the transition meanwhile expecting the stat machine to handle the event of derived class, which won't work. (yes, I found there is a similar question boost msm cannot processing polymorphic event?)
- But why did it work in the second example?