e-mail: mikael.rosbacke@gmail.com
github: http://www.github.com/rosbacke
http://www.akaza.se
#include "MyFsm.h"
int main()
{
// The state machine is an ordinary object.
MyFsm fsm;
// Perform initial jump to start state. entry events called.
fsm.setStartState<state1>();
MyEvent ev1;
fsm.postEvent(ev1);
// ...
fsm.postEvent(ev1);
}
// Upon destruction, relevant exit events are called.
#include <StateChart.h>
// Ordinary class, needs to inherit from FsmBase.
// MyFsmDesc contain configuration information about the fsm.
class MyFsm : public FsmBase<MyFsmDesc> {
public:
// No special requirements on constructors.
MyFsm() {}
// Additional user defined data.
// Can be accessed from state classes.
int myFsmData = 0;
// FsmBase contain the 'postEvent' function.
};
// State classes inherits StateBase with needed template arguments.
class MyState1 : public StateBase<MyFsmDesc, States::state1> {
public:
// Required constructor. Use body for entry event code.
MyState1(StateArgs& args) : StateBase(args), stateData(0)
{ /* entry event code */ }
// Optional destructor. default is fine.
~MyState1() { /* exit event code */ }
// Handle all incoming events.
bool event(const MyEvent& ev) {
if (ev.foo()) {
transition<MyState2>();
return true; // We want to stop processing this event.
}
return false; // We want parent state to see the event.
}
int stateData; // Additional data possible as normal.
};
// States represented both with a type and an enum value.
enum class States { myState1, myState2, /* ... */ };
class MyEvent;
class MyFsm;
class MyFsmDesc {
public:
using Event = MyEvent; // Event class. Can be primitive.
using Fsm = MyFsm; // State machine class.
// Called during setup. Will build up the state hierarchy.
// Forward declared here.
static void setupStates(FsmSetup<MyFsmDesc>& sc);
};
void MyFsmDesc::setupStates(FsmSetup<UserFsmDesc>& sc)
{
// Add a root state. (level 0)
sc.addState<State1>();
// Another root state.
sc.addState<State2>();
// sub state to state 1. (level 1)
sc.addState<State3, State1>();
// sub state to state 2. (level 1)
sc.addState<State4, State2>();
}
// Typical support functions inherited from statebase
template </* ... */ > class StateBase
{
// All copy/move/assign deleted.
// Transition to new state once eventprocessing is done.
template <typename TargetState>
void transition();
void transition(StateId id);
/// Reference to our state machine object. (MyFsm in our case)
Fsm& fsm();
// Return a reference to the parent state.
template <class ParentState>
ParentState& parent();
};
// Typical support functions inherited from FsmBase
template </* ... */ > class FsmBase {
// Currently active state id.
StateId currentStateId() const;
// Get current active state object. nullptr if type mismatch.
template <class State>
const State* currentState() const;
// Get any of the currently active state object.
template <class State>
const State* activeState() const;
// (Planned): Set a callback to be called upon state change.
using StateCB = std::function<void(Fsm&, StateId)>;
void setStatechangedCB(StateCB cb);
};
Current status
Thank you for your attention
Code available at github:
http://www.github.com/rosbacke/MCU-tools
To get in touch:
email: mikael.rosbacke@gmail.com
web: http://www.akaza.se