This module implements a simple Finite State Machine (FSM).
We define the FSM by a simple-machine, that it’s running by the SMachine class.
A simple-machine is a dictionary with three keys:
FSM = {
'event_list': (),
'state_list': (),
'machine': {}
}
where:
item value is a tuple with all input-event event-name‘s supported by the machine.
item value is a tuple with all state‘s of the machine.
item value is another dictionary with the description of the machine.
If something is wrong in the simple-machine definition, a MachineError exception it will be raised.
The machine item value is a another dictionary describing which event-name‘s are supported by each state, the action to be executed for each event, and what is the next-state.
The dictionary’s keys are the state names. The values are a tuple of tuples with three items:
event-name: event name, a name of the event_list tuple.
action: function to be executed when the machine receives the event through SMachine.inject_event() method call.
Their prototype is:
def action(self, event):where event is the argument used in the inject_event() method call.
next-state: next state to set. Must be a name of state_list or None.
Note
The next state is changed before executing the action function. If you don’t like this behavior, set to the next-state to None. Then you can use the SMachine.set_new_state() method to change the state inside the action function, otherwise, the machine will remain in the same state.
A simple-machine example:
def ac_task1(self, event):
print 'TASK1'
def ac_task2(self, event):
print 'TASK2'
def ac_task3(self, event):
print 'TASK3'
def ac_task4(self, event):
print 'TASK4'
SAMPLE_FSM = {
'event_list': ('EV_EVENT1', 'EV_EVENT2'),
'state_list': ('ST_STATE1', 'ST_STATE2'),
'machine' = {
'ST_STATE1':
(
('EV_EVENT1', ac_task1, 'ST_STATE2'),
('EV_EVENT2', ac_task2, 'ST_STATE2'),
),
'ST_STATE2':
(
('EV_EVENT1', ac_task3, 'ST_STATE1'),
('EV_EVENT2', ac_task4, 'ST_STATE1'),
),
}
}
Warning
All event names and state names used in the machine must be defined in event-list and state-list respectively, otherwise a MachineError will be raised.
Note
You can too have output-event events. These events it’s not necessary to be in event-list.
Note
The list with output-event events is not used by SMachine. It is merely informative.
A class to run a simple-machine.
Parameters: | fsm – a simple-machine, the dictionary describing the fsm. |
---|
If the simple-machine has errors a MachineError exception will be raised.
Inject an event into the FSM.
Parameters: | event – a string event name or any object with an event_name attribute. |
---|
Warning
use this method if you use the SMachine class in isolation, otherwise use the methods to send events from the ginsfsm.gobj.GObj class.
Execute the associated action to the event in the current state.
If the event name doesn’t match any of the event-name of the machine’s event-list, then function returns EventNotAcceptedError.
If the event-name exists in the machine , but it’s not accepted by the current state, then function returns EventNotAcceptedError.
Note
The inject_event() method doesn’t raise EventNotAcceptedError because a machine should run under any circumstances. In any way an action can raise exceptions.
If the event is accepted by the machine, the returned value by inject_event() method it will be the returned value by the executed action.
Set a new state. Method to used inside actions, to force the change of state.
Parameters: | new_state – new state to set. |
---|
new_state must match some of the state names of the machine’s state-list or a StateError exception will be raised.
Return the name of the current state.
If there is no state it returns None.
Return the list with the output-event‘s names.
Raised when something is wrong in the simple-machine definition.
Raised when the event name doesn’t match any name of the event-list list.
Raised when the state name doesn’t match any name of the state-list list.