lewis.core.statemachine
The statemachine module contains one of lewis’ central parts, the cycle-based
StateMachine
. The module also contains classes that make it easier to define the
state machine (State
, Transition
). Despite its central nature, it’s unlikely
to be used directly in client code for device simulations - these should be based on
StateMachineDevice
, which provides a more convenient interface for that purpose.
Members
Mixin to provide a Context. |
|
StateMachine state handler base class. |
|
Cycle based state machine. |
|
Classes in this module should only raise this type of Exception. |
|
StateMachine transition condition base class. |
- class lewis.core.statemachine.HasContext[source]
Bases:
object
Mixin to provide a Context.
Creates a _context member variable that can be assigned with
set_context()
.Any state handler or transition callable that derives from this mixin will receive a context from its
StateMachine
upon initialization (assuming the StateMachine was provided with a context itself).
- class lewis.core.statemachine.State[source]
Bases:
HasContext
StateMachine state handler base class.
Provides a way to implement StateMachine event handling behaviour using an object-oriented interface. Once the StateMachine is configured to do so, it will automatically invoke the events in this class when appropriate.
To use this class, create a derived class and override any events that need custom behaviour. Device context is provided via
HasContext
mixin.- in_state(dt) None [source]
Handle in-state event.
Raised repeatedly, once per cycle, while idling in this state. Exactly one in-state event occurs per cycle for every StateMachine. This is always the last event of the cycle.
- Parameters:
dt – Delta T since last cycle.
- class lewis.core.statemachine.StateMachine(cfg, context=None)[source]
Bases:
CanProcess
Cycle based state machine.
- Parameters:
cfg – dict which contains state machine configuration.
context – object which is assigned to State and Transition objects as their _context.
The configuration dict may contain the following keys:
initial: Name of the initial state of this machine
states: [optional] Dict of custom state handlers
transitions: [optional] Dict of transitions in this state machine.
State handlers may be given as a dict, list or State class:
dict: May contain keys ‘on_entry’, ‘in_state’ and ‘on_exit’.
list: May contain up to 3 entries, above events in that order.
class: Should be an instance of a class that derives from State.
In case of handlers being provided as a dict or a list, values should be callable and may take a single parameter: the Delta T since the last cycle.
Transitions should be provided as a dict where:
Each key is a tuple of two values, the FROM and TO states respectively.
Each value is a callable transition condition that return True or False.
Transition conditions are called once per cycle when in the FROM state. If one of the transition conditions returns True, the transition is executed that cycle. The remaining conditions aren’t called.
Consider using an OrderedDict if order matters.
Only one transition may occur per cycle. Every cycle will, at the very least, trigger an in_state event against the current state.
See also
See
doProcess()
for details.- bind_handlers_by_name(instance, override=False, prefix=None) None [source]
Auto-bind state handlers based on naming convention.
- Parameters:
instance – Target object instance to search for handlers and bind events to.
override – If set to True, matching handlers will replace previously registered handlers.
prefix – Dict or list of prefixes to override defaults (keys: on_entry, in_state, on_exit)
This function enables automatically binding state handlers to events without having to specify them in the constructor. When called, this function searches instance for member functions that match the following patterns for all known states (states mentioned in ‘states’ or ‘transitions’ dicts of cfg):
instance._on_entry_[state]
instance._in_state_[state]
instance._on_exit_[state]
The default prefixes may be overridden using the prefix parameter. Supported keys are ‘on_entry’, ‘in_state’, and ‘on_exit’. Values should include any and all desired underscores.
Matching functions are assigned as handlers to the corresponding state events, iff no handler was previously assigned to that event.
If a state event already had a handler assigned (during construction or previous call to this function), no changes are made even if a matching function is found. To force previously assigned handlers to be overwritten, set the third parameter to True. This may be useful to implement inheritance-like specialization using multiple implementation classes but only one StateMachine instance.
- can(state)[source]
Returns true if the transition to ‘state’ is allowed from the current state.
- Parameters:
state – State to check transition to
- Returns:
True if state is reachable from current
- doProcess(dt) None [source]
Process a cycle of this state machine.
- Parameters:
dt – Delta T. “Time” passed since last cycle, passed on to event handlers.
A cycle will perform at most one transition and exactly one in_state event.
A transition will only occur if one of the transition condition functions leaving the current state returns True.
- When a transition occurs, the following events are raised:
on_exit_old_state()
on_entry_new_state()
in_state_new_state()
The first cycle after init or reset will never call transition checks and, instead, always performs on_entry and in_state on the initial state.
Whether a transition occurs or not, and regardless of any other circumstances, a cycle always ends by raising an in_state event on the current (potentially new) state.
- reset() None [source]
Reset the state machine to before the first cycle. The next process() will enter the initial state.
- property state
Name of the current state.
- exception lewis.core.statemachine.StateMachineException[source]
Bases:
Exception
Classes in this module should only raise this type of Exception.
- class lewis.core.statemachine.Transition[source]
Bases:
HasContext
StateMachine transition condition base class.
Provides a way to implement a transition that requires access to the device context. The device context is provided via
HasContext
mixin, and can be accessed as self._context.To use this class, create a derived class and override the
__call__()
attribute.