1 # -*- coding: utf-8 -*- 2 # 3 # Copyright 2011 Google Inc. All Rights Reserved. 4 # 5 6 __author__ = 'kbaclawski (at] google.com (Krystian Baclawski)' 7 8 from automation.common import events 9 10 11 class BasicStateMachine(object): 12 """Generic class for constructing state machines. 13 14 Keeps all states and possible transition of a state machine. Ensures that 15 transition between two states is always valid. Also stores transition events 16 in a timeline object. 17 """ 18 state_machine = {} 19 final_states = [] 20 21 def __init__(self, initial_state): 22 assert initial_state in self.state_machine,\ 23 'Initial state does not belong to this state machine' 24 25 self._state = initial_state 26 27 self.timeline = events.EventHistory() 28 self.timeline.AddEvent(self._state) 29 30 def __str__(self): 31 return self._state 32 33 def __eq__(self, value): 34 if isinstance(value, BasicStateMachine): 35 value = str(value) 36 37 return self._state == value 38 39 def __ne__(self, value): 40 return not self == value 41 42 def _TransitionAllowed(self, to_state): 43 return to_state in self.state_machine.get(self._state, []) 44 45 def Change(self, new_state): 46 assert self._TransitionAllowed(new_state),\ 47 'Transition from %s to %s not possible' % (self._state, new_state) 48 49 self._state = new_state 50 51 self.timeline.AddEvent(self._state) 52 53 if self._state in self.final_states: 54 self.timeline.last.Finish() 55