staccato/staccato/common/state_machine.py
2013-05-16 13:08:01 -10:00

69 lines
2.5 KiB
Python

from staccato.common import exceptions
class StateMachine(object):
def __init__(self):
# set up the transition table
self._transitions = {}
self._state_funcs = {}
def set_state_func(self, state, func):
self._state_funcs[state] = func
def set_mapping(self, state, event, next_state, func=None):
if state not in self._transitions:
self._transitions[state] = {}
event_dict = self._transitions[state]
if event not in event_dict:
event_dict[event] = {}
if func is None:
func = self._state_funcs[next_state]
self._transitions[state][event] = (next_state, func)
def _state_changed(self, current_state, event, new_state, **kwvals):
raise Exception("this needs to be implemented")
def _get_current_state(self, **kwvals):
raise Exception("This needs to be implemented")
def event_occurred(self, event, **kwvals):
current_state = self._get_current_state(**kwvals)
if current_state not in self._transitions:
raise exceptions.StaccatoInvalidStateTransitionException(
"Undefined event %s at state %s" % (event, current_state))
state_ent = self._transitions[current_state]
if event not in state_ent:
raise exceptions.StaccatoInvalidStateTransitionException(
"Undefined event %s at state %s" % (event, current_state))
next_state, function = state_ent[event]
self._state_changed(current_state, event, next_state, **kwvals)
# log the change
if function:
try:
function(current_state, event, next_state, **kwvals)
except Exception, ex:
# TODO: deal with the exception in a sane way. we likely need
# to trigger an event signifying and error occured but we
# may not want to recurse
raise
def mapping_to_digraph(self):
print 'digraph {'
for start_state in self._transitions:
for event in self._transitions[start_state]:
ent = self._transitions[start_state][event]
if ent is not None:
p_end_state = ent[0].replace("STATE_", '')
p_start_state = start_state.replace("STATE_", '')
p_event = event.replace("EVENT_", '')
print '%s -> %s [ label = "%s" ];'\
% (p_start_state, p_end_state, p_event)
print '}'