Skip to content

Instantly share code, notes, and snippets.

@marklap
Last active August 29, 2015 14:01
Show Gist options
  • Save marklap/6181ee529699888fe92a to your computer and use it in GitHub Desktop.
Save marklap/6181ee529699888fe92a to your computer and use it in GitHub Desktop.
A simple example of a state machine
from __future__ import print_function
import sys
from collections import namedtuple
from pprint import pprint
STATE_CONST = (
'STOPPED',
'STARTING',
'RUNNING',
'STOPPING',
'ABORTED',
)
STATES = {}
i = 0
m = sys.modules[__name__]
for s in STATE_CONST:
v = 1 << i
STATES[s] = v
setattr(m, s, v)
i += 1
State = type('State', (), STATES)
STATES.update({v: k for k, v in STATES.items()})
class StateMachine(object):
def __init__(self, state=None):
if state is None:
self.state = State.STOPPED
elif state in STATES and state != State.ABORTED:
self.state = state
else:
self.state = State.ABORTED
def log(self, to_state):
print('Changing from {0} to {1}'.format(STATES[self.state], STATES[to_state]))
def error(self, to_state):
print('ERROR: Can not change from {0} to {1}'.format(STATES[self.state], STATES[to_state]))
def control(self, to_state):
if self.state == to_state:
self.error(to_state)
elif self.state == State.STOPPED:
if to_state == State.STARTING:
self.log(to_state)
self.state = State.STARTING
else:
self.error(to_state)
elif self.state == State.STARTING:
if to_state == State.RUNNING:
self.log(to_state)
self.state = State.RUNNING
elif to_state == State.ABORTED:
self.log(to_state)
self.state = State.ABORTED
else:
self.error(to_state)
elif self.state == State.RUNNING:
if to_state == State.STOPPING:
self.log(to_state)
self.state = State.STOPPING
elif to_state == State.ABORTED:
self.log(to_state)
self.state = State.ABORTED
else:
self.error(to_state)
elif self.state == State.STOPPING:
if to_state == State.STOPPED:
self.log(to_state)
self.state = State.STOPPED
elif to_state == State.ABORTED:
self.log(to_state)
self.state = State.ABORTED
else:
self.error(to_state)
else:
self.error(to_state)
if __name__ == '__main__':
m = StateMachine(State.STARTING)
m.control(State.STARTING)
m.control(State.RUNNING)
m.control(State.STOPPING)
m.control(State.ABORTED)
m.control(State.STOPPED)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment