Hi there,
having tested Boost.MSM, I'm pretty happy with it.
It's interesting, in that it seems to handle all states in a static table.
No "new" operator etc.
Since there is no "new" and all is static, I cannot use the runtime, to
specialize my transitions. So instead, I have to use templates!
Unfortunately I'm not a template master, and the compiler is giving me an
error.
Here's what I'm trying:
template <typename EventT>
struct Machine_ : public msm::front::state_machine_def {
// ...
struct transition_table : mpl::vector<
g_row,
g_row,
g_row,
g_row,
g_row,
g_row,
g_row,
g_row,
g_row,
g_row,
g_row,
g_row
>{};
// ...
}
Unfortunately
gcc gives this error:
d.cpp:119:5: error: ‘g_row’ was not declared in this scope
g_row,
etc.
Can somebody help in this regard?
Thanks.
nicesw123
In case you're interested.
Here's the code of the complete example that I'm trying to get working:
#include <iostream>
#include
#include
namespace msm = boost::msm;
namespace mpl = boost::mpl;
// events
struct EventNumber1 { // int number!
EventNumber1(int num_) : num{num_} {}
int getNum() const { return num; }
private:
int num;
};
struct EventNumber2 { // double number!
EventNumber2(double num_) : num{num_} {}
double getNum() const { return num; }
private:
double num;
};
typedef EventNumber2 MyEvent; // using doubles
// StateBase -- a base (parent) state
struct StateBase : public msm::front::state<> {
StateBase(const std::string& stateName = "") : stateName{stateName} {}
template
void on_entry(const Event&, FSM&) {
std::cout << "Entering " << stateName << std::endl;
}
template
void on_exit(const Event&, FSM&) {
std::cout << "Leaving " << stateName << std::endl;
}
private:
std::string stateName;
};
#if 0
// not used (just an idea)
template <typename T>
struct StateMachineFront_Base : public
msm::front::state_machine_def
{
StateMachineFront_Base(const std::string& stateMachineName = "") :
stateMachineName{stateMachineName} {}
template
void on_entry(const Event&, FSM&) {
std::cout << "Entering " << stateMachineName << std::endl;
}
template
void on_exit(const Event&, FSM&) {
std::cout << "Leaving " << stateMachineName << std::endl;
}
private:
std::string stateMachineName;
};
#endif
template <typename EventT>
struct Machine_ : public msm::front::state_machine_def {
Machine_(const std::string& stateMachineName = "Machine_") :
stateMachineName{stateMachineName} {}
template
void on_entry(const Event&, FSM&) {
std::cout << "Entering " << stateMachineName << std::endl;
}
template
void on_exit(const Event&, FSM&) {
std::cout << "Leaving " << stateMachineName << std::endl;
}
// states
struct StateInitial : public StateBase {
StateInitial(const std::string name = "StateInitial") : StateBase{name}
{}
};
struct StateEven : public StateBase {
StateEven(const std::string name = "StateEven") : StateBase{name} {}
};
struct StateOdd : public StateBase {
StateOdd(const std::string name = "StateOdd") : StateBase{name} {}
};
struct StateFloat : public StateBase {
StateFloat(const std::string name = "StateFloat") : StateBase{name} {}
};
// guards
bool guardToEven(const EventT& num) {
const long long x = static_cast<long long>(num.getNum());
return ((x == num.getNum()) // is Integral type
&& ((x % 2) == 0));
}
bool guardToOdd(const EventT& num) {
const long long x = static_cast<long long>(num.getNum());
return ((x == num.getNum()) // is Integral type
&& ((x % 2) != 0));
}
bool guardToFloat(const EventT& num) {
const long long x = static_cast<long long>(num.getNum());
return (x != num.getNum()); // is Floating type
}
typedef StateInitial initial_state;
struct transition_table : mpl::vector<
g_row,
g_row,
g_row,
g_row,
g_row,
g_row,
g_row,
g_row,
g_row,
g_row,
g_row,
g_row
>{};
private:
std::string stateMachineName;
};
typedef msm::back::state_machine Machine;
template <typename T>
void postEvents(Machine& machine)
{
for (T i; std::cin >> i; ) {
machine.process_event(MyEvent{i});
}
}
int main()
{
Machine machine;
machine.start();
postEvents<double>(machine);
machine.stop();
return 0;
}