1# -*- coding: utf-8 -*-
2#
3# Copyright 2011 Google Inc. All Rights Reserved.
4#
5
6__author__ = 'kbaclawski@google.com (Krystian Baclawski)'
7
8from automation.common import events
9
10
11class 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