tsm 0.1.0
|
For a primer on UML state machines, look here.
Create the state machine by first creating a context. The context is a structure that holds the states, events, actions and guards of the state machine. The context is a template parameter to the Hsm
class. The Hsm
class is a Mixin class that adds state machine like functionality to the context. In essence, it takes a context and converts it into a state machine.
Wrap the state machine around an execution policy. Currently, there are several options.
a. A state machine that executes in the context of the parent thread. This means that the client sending events to the state machine drives the event processing as well. Typically, this will be the 'main' thread of your application driving event processing. Note that several other threads can hold references to the state machine instance and queue up events (see 'd' below).
b. A state machine that processes incomming events in its own thread. i.e. Events will be immediately consumed as long as the state machine is not busy. Clients 'fire and forget' an event and desire no control over event processing.
c. Send events to the state machine by using sendEvent method provided by the policy.
d. If the state machine is running in parent thread context, invoke the step
method to process the first event in the event queue. As opposed to the SingleThreadedExecutionPolicy
, the ThreadedExecutionPolicy
will immediately process an event on completion of prior event processing.
Classes have been partitioned across policies so they can be mixed and matched for code reuse (in an ideal world)! The current architecture supports state machines with the following characterestics.
Other Policy classes can be implemented for distributed event processing. The existing mechanism can also be extended to incorporate custom behavior such as writing state transitions to disk. For e.g. see struct ThreadedExecWithObserver
in ThreadedExecutionPolicy.h
Clients need to include tsm.h file.
Place holder for your own application specific sate machine definition.
The make_hsm_t
meta-function is used to recursively examine a state transition table and convert all sub-contexts into state machines. Every state machine is a Hsm
class that is a mixin of the context.
Policy classes like ThreadedExecutionPolicy
and SingleThreadedExecutionPolicy
are mixins that operate on wrapped Hsm
s. Clients will typically interact with a Policy class at the bottom of the inheritance hierarcy. By convention, these Policy classes also provide a send_event
method as a public interface to the state machine. The SingleThreadedExecutionPolicy
class also provides a step
method for clients to initiate event processing. If the state machine is a ClockedHsm
, a tick
method is provided which will provide a reference to a ClockTickEvent
.
The ThreadedExecutionPolicy
processes events in its own thread. The processing of events is single threaded within all Hsms. So when a Hsm is started using a call to start()
, the StateMachine
will block waiting for next_event
to return an event. The main advantage is that the only external interface to the Hsm can be the set of Events. Any "client" can asynchronously send an event to the state machine long as they have a reference to it. As soon as the Hsm is done with its processing, it will pick up the next event in the queue and process it. This can be seen in the test/*.cpp files.
Create your own context definitions. The context hierarchy, its states (and sub-contexts if any), events, actions guards and transitions are all specified and defined in the definition. The relationships between Hsms.
Then choose a policy class for your state machine. Complete your state machine type by wrapping the policy class around it. The unit test provided below is illustrative.
Here, the TrafficLightHsm
is a hierarchical state machine. The LightHsm
and EmergencyOverrideHsm
are the leaf state machines. The TrafficLightHsm
is a parent state machine that can switch between the LightHsm
and EmergencyOverrideHsm
state machines. The EmergencyOverrideHsm
is a state machine that can override the LightHsm
state machine. The EmergencyOverrideHsm
is a "leaf" state machine that can switch between the G1
, Y1
, G2
and Y2
states. LightHsm
is another "leaf" state machine that can switch between the same G1
, Y1
, G2
and Y2
states. If the main LightHsm
needs to switch over to emergency mode, an EmergencySwitchOn
event is sent to the TrafficLightHsm
. The TrafficLightHsm
will then switch over to the EmergencyOverrideHsm
state machine.
The ThreadedExecutionPolicy is used to process events in a separate thread. If the ticks map to seconds, a PeriodicExecutionPolicy can be used to generate ticks every second. See tsm.h
for an example.