class StateMachine:
'A class that implements a flexible state machine'
def __init__( self, transitions, first=None ):
if type( transitions ) == dict:
self.sm = transitions
else:
self.first = first or transitions.split(',')[0]
smtext = [ term.split(':') for term in transitions.split() ]
self.sm = dict( [ tuple(a.split(',')), tuple(b.split(',')) ]
for a,b in smtext )
self.setstate()
def setstate( self, state=None ):
self.state = state or self.first
def __call__( self, event ):
return self.signal( event )
def signal( self, event ):
change = self.sm.get( (self.state,event) )
change = change or self.sm.get( (self.state,'*') )
change = change or self.sm.get( ('*',event) )
change = change or self.sm.get( ('*','*') )
emit, newstate = change or ('**ERROR**',self.first)
if newstate == '*':
newstate = self.state
elif newstate == '':
newstate = self.first
if callable( emit ):
result = emit( self.state, event, newstate )
else:
result = ( emit, newstate )
self.state = newstate
return result
if __name__ == '__main__':
# Example for demonstration and test.
transitions = '''
garden,climb:go-up-to-roof,roof
roof,jump:fall-through,cottage
cottage,leave:unlock-door,garden
*,need-help:can-choose-climb-jump-leave,*
*,jump:feel-tired,*
*,sleep:feel-refreshed,*
*,*:cannot-do,*
'''
houseguy = StateMachine( transitions, first='garden' )
print 'I start at location: %s' % houseguy.state
actionlist = 'sleep jump need-help climb jump jump leave climb climb'.split()
for action in actionlist:
result, newstate = houseguy( action )
print 'I %s. I %s. Location: %s.' % (action, result, newstate)
Diff to Previous Revision
--- revision 1 2011-05-18 14:27:00
+++ revision 2 2011-05-18 15:17:02
@@ -42,8 +42,8 @@
*,*:cannot-do,*
'''
houseguy = StateMachine( transitions, first='garden' )
- print ' I start at location: %s' % houseguy.state
+ print 'I start at location: %s' % houseguy.state
actionlist = 'sleep jump need-help climb jump jump leave climb climb'.split()
for action in actionlist:
result, newstate = houseguy( action )
- print ' I %s. I %s. Location: %s.' % (action, result, newstate)
+ print 'I %s. I %s. Location: %s.' % (action, result, newstate)