statemap.py
Go to the documentation of this file.
00001 #
00002 # The contents of this file are subject to the Mozilla Public
00003 # License Version 1.1 (the "License"); you may not use this file
00004 # except in compliance with the License. You may obtain a copy of
00005 # the License at http://www.mozilla.org/MPL/
00006 #
00007 # Software distributed under the License is distributed on an "AS
00008 # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
00009 # implied. See the License for the specific language governing
00010 # rights and limitations under the License.
00011 #
00012 # The Original Code is State Machine Compiler (SMC).
00013 #
00014 # The Initial Developer of the Original Code is Charles W. Rapp.
00015 # Portions created by Charles W. Rapp are
00016 # Copyright (C) 2005. Charles W. Rapp.
00017 # All Rights Reserved.
00018 #
00019 # Port to Python by Francois Perrad, francois.perrad@gadz.org
00020 # Copyright 2004, Francois Perrad.
00021 # All Rights Reserved.
00022 #
00023 # Contributor(s):
00024 #
00025 # RCS ID
00026 # $Id: statemap.py,v 1.7 2009/11/24 20:42:39 cwrapp Exp $
00027 #
00028 # See: http://smc.sourceforge.net/
00029 #
00030 
00031 import sys
00032 
00033 
00034 class StateUndefinedException(Exception):
00035     """A StateUndefinedException is thrown by
00036     an SMC-generated state machine whenever a transition is taken
00037     and there is no state currently set. This occurs when a
00038     transition is issued from within a transition action."""
00039     pass
00040 
00041 
00042 class TransitionUndefinedException(Exception):
00043     """A TransitionUndefinedException is thrown by
00044     an SMC-generated state machine whenever a transition is taken
00045     which:
00046      - Is not explicitly defined in the current state.
00047      - Is not explicitly defined in the current FSM's default state.
00048      - There is no Default transition in the current state."""
00049     pass
00050 
00051 
00052 class State(object):
00053     """base State class"""
00054 
00055     def __init__(self, name, id):
00056         self._name = name
00057         self._id = id
00058 
00059     def getName(self):
00060         """Returns the state's printable name."""
00061         return self._name
00062 
00063     def getId(self):
00064         """Returns the state's unique identifier."""
00065         return self._id
00066 
00067 
00068 class FSMContext(object):
00069     """The user can derive FSM contexts from this class and interface
00070     to them with the methods of this class.
00071 
00072     The finite state machine needs to be initialized to the starting
00073     state of the FSM.  This must be done manually in the constructor
00074     of the derived class.
00075     """
00076 
00077     def __init__(self, state):
00078         self._state = state
00079         self._previous_state = None
00080         self._state_stack = []
00081         self._transition = None
00082         self._debug_flag = False
00083         self._debug_stream = sys.stderr
00084 
00085     def getDebugFlag(self):
00086         """Returns the debug flag's current setting."""
00087         return self._debug_flag
00088 
00089     def setDebugFlag(self, flag):
00090         """Sets the debug flag.
00091         A true value means debugging is on and false means off."""
00092         self._debug_flag = flag
00093 
00094     def getDebugStream(self):
00095         """Returns the stream to which debug output is written."""
00096         return self._debug_stream
00097 
00098     def setDebugStream(self, stream):
00099         """Sets the debug output stream."""
00100         self._debug_stream = stream
00101 
00102     def getState(self):
00103         """Returns the current state."""
00104         if self._state is None:
00105             raise StateUndefinedException
00106         return self._state
00107 
00108     def isInTransition(self):
00109         """Is this state machine already inside a transition?
00110         True if state is undefined."""
00111         if self._state is None:
00112             return True
00113         else:
00114             return False
00115 
00116     def getTransition(self):
00117         """Returns the current transition's name.
00118         Used only for debugging purposes."""
00119         return self._transition
00120 
00121     def clearState(self):
00122         """Clears the current state."""
00123         self._previous_state = self._state
00124         self._state = None
00125 
00126     def getPreviousState(self):
00127         """Returns the state which a transition left.
00128         May be None"""
00129         return self._previous_state
00130 
00131     def setState(self, state):
00132         """Sets the current state to the specified state."""
00133         if not isinstance(state, State):
00134             raise ValueError("state should be a statemap.State")
00135         self._state = state
00136         if self._debug_flag:
00137             self._debug_stream.write("NEW STATE       : %s\n" % self._state.getName())
00138 
00139     def isStateStackEmpty(self):
00140         """Returns True if the state stack is empty and False otherwise."""
00141         return len(self._state_stack) == 0
00142 
00143     def getStateStackDepth(self):
00144         """Returns the state stack's depth."""
00145         return len(self._state_stack)
00146 
00147     def pushState(self, state):
00148         """Push the current state on top of the state stack
00149         and make the specified state the current state."""
00150         if not isinstance(state, State):
00151             raise ValueError("state should be a statemap.State")
00152         if self._state is not None:
00153             self._state_stack.append(self._state)
00154         self._state = state
00155         if self._debug_flag:
00156             self._debug_stream.write("PUSH TO STATE   : %s\n" % self._state.getName())
00157 
00158     def popState(self):
00159         """Make the state on top of the state stack the current state."""
00160         if len(self._state_stack) == 0:
00161             if self._debug_flag:
00162                 self._debug_stream.write("POPPING ON EMPTY STATE STACK.\n")
00163             raise ValueError("empty state stack")
00164         else:
00165             self._state = self._state_stack.pop()
00166             if self._debug_flag:
00167                 self._debug_stream.write("POP TO STATE    : %s\n" % self._state.getName())
00168 
00169     def emptyStateStack(self):
00170         """Remove all states from the state stack."""
00171         self._state_stack = []


smclib
Author(s): Various
autogenerated on Thu Aug 17 2017 03:12:46