Browse Source

add conditional_request

cxgeorge 23 years ago
parent
commit
9a748df2d5
1 changed files with 50 additions and 11 deletions
  1. 50 11
      direct/src/fsm/FSM.py

+ 50 - 11
direct/src/fsm/FSM.py

@@ -10,7 +10,7 @@ class FSM(DirectObject):
     notify = directNotify.newCategory("FSM")
     notify = directNotify.newCategory("FSM")
 
 
     # special methods
     # special methods
-    
+
     def __init__(self, name, states=[], initialStateName=None,
     def __init__(self, name, states=[], initialStateName=None,
                  finalStateName=None):
                  finalStateName=None):
         """__init__(self, string, State[], string, string)
         """__init__(self, string, State[], string, string)
@@ -60,17 +60,17 @@ class FSM(DirectObject):
     def enterInitialState(self, argList=[]):
     def enterInitialState(self, argList=[]):
         self.__enter(self.__initialState, argList)
         self.__enter(self.__initialState, argList)
         return None
         return None
-        
+
     # Jesse decided that simpler was better with the __str__ function
     # Jesse decided that simpler was better with the __str__ function
     def __str_not__(self):
     def __str_not__(self):
         """__str__(self)"""
         """__str__(self)"""
         return "FSM: name = %s \n states = %s \n initial = %s \n final = %s \n current = %s" \
         return "FSM: name = %s \n states = %s \n initial = %s \n final = %s \n current = %s" \
-            % (self.__name, self.__states, self.__initialState, 
+            % (self.__name, self.__states, self.__initialState,
                self.__finalState, self.__currentState)
                self.__finalState, self.__currentState)
 
 
 
 
     # setters and getters
     # setters and getters
-    
+
     def getName(self):
     def getName(self):
         """getName(self)"""
         """getName(self)"""
         return(self.__name)
         return(self.__name)
@@ -109,14 +109,14 @@ class FSM(DirectObject):
 
 
     def requestFinalState(self):
     def requestFinalState(self):
         self.request(self.__finalState.getName())
         self.request(self.__finalState.getName())
-        
+
     def getCurrentState(self):
     def getCurrentState(self):
         """getCurrentState(self)"""
         """getCurrentState(self)"""
         return(self.__currentState)
         return(self.__currentState)
 
 
 
 
     # lookup funcs
     # lookup funcs
-    
+
     def getStateNamed(self, stateName):
     def getStateNamed(self, stateName):
         """getStateNamed(self, string)
         """getStateNamed(self, string)
         Return the state with given name if found, issue warning otherwise"""
         Return the state with given name if found, issue warning otherwise"""
@@ -128,7 +128,7 @@ class FSM(DirectObject):
 
 
 
 
     # basic FSM functionality
     # basic FSM functionality
-    
+
     def __exitCurrent(self, argList):
     def __exitCurrent(self, argList):
         """__exitCurrent(self)
         """__exitCurrent(self)
         Exit the current state"""
         Exit the current state"""
@@ -143,7 +143,7 @@ class FSM(DirectObject):
             messenger.send(self.getName() + '_' +
             messenger.send(self.getName() + '_' +
                            self.__currentState.getName() + '_exited')
                            self.__currentState.getName() + '_exited')
         self.__currentState = None
         self.__currentState = None
-                    
+
     def __enter(self, aState, argList=[]):
     def __enter(self, aState, argList=[]):
         """__enter(self, State)
         """__enter(self, State)
         Enter a given state, if it exists"""
         Enter a given state, if it exists"""
@@ -167,12 +167,12 @@ class FSM(DirectObject):
         Exit currentState and enter given one"""
         Exit currentState and enter given one"""
         self.__exitCurrent(exitArgList)
         self.__exitCurrent(exitArgList)
         self.__enter(aState, enterArgList)
         self.__enter(aState, enterArgList)
-        
+
     def request(self, aStateName, enterArgList=[], exitArgList=[]):
     def request(self, aStateName, enterArgList=[], exitArgList=[]):
         """request(self, string)
         """request(self, string)
         Attempt transition from currentState to given one.
         Attempt transition from currentState to given one.
         Return true is transition exists to given state,
         Return true is transition exists to given state,
-        false otherwise. 
+        false otherwise.
         """
         """
 
 
         if not self.__currentState:
         if not self.__currentState:
@@ -188,7 +188,7 @@ class FSM(DirectObject):
             # the name of a state.
             # the name of a state.
             aState = aStateName
             aState = aStateName
             aStateName = aState.getName()
             aStateName = aState.getName()
-            
+
         if aState == None:
         if aState == None:
             FSM.notify.error("[%s]: request: %s, no such state" %
             FSM.notify.error("[%s]: request: %s, no such state" %
                              (self.__name, aStateName))
                              (self.__name, aStateName))
@@ -229,6 +229,45 @@ class FSM(DirectObject):
                                     aStateName))
                                     aStateName))
             return 0
             return 0
 
 
+
+    def conditional_request(self, aStateName, enterArgList=[], exitArgList=[]):
+           """request(self, string)
+           Attempt transition from currentState to given one, if it exists.
+           Return true is transition exists to given state,
+           false otherwise.  It is NOT an error/warning to attempt a cond_request
+           if the transition doesnt exist.  This lets people be sloppy about
+           FSM transitions, letting the same fn be used for different states
+           that may not have the same out transitions.
+           """
+
+           if not self.__currentState:
+               # Make this a warning for now
+               FSM.notify.warning("[%s]: request: never entered initial state" %
+                                  (self.__name))
+               self.__currentState = self.__initialState
+
+           if isinstance(aStateName, types.StringType):
+               aState = self.getStateNamed(aStateName)
+           else:
+               # Allow the caller to pass in a state in itself, not just
+               # the name of a state.
+               aState = aStateName
+               aStateName = aState.getName()
+
+           if aState == None:
+               FSM.notify.error("[%s]: request: %s, no such state" %
+                                (self.__name, aStateName))
+
+           fulltransitionnameset = self.__currentState.getTransitions()
+           fulltransitionnameset.extend([self.__currentState.getName(),self.__finalState.getName()])
+
+           if (aStateName in fulltransitionnameset):
+               return self.request(aStateName, enterArgList, exitArgList)
+           else:
+               FSM.notify.debug("[%s]: condition_request: %s, transition doesnt exist" %
+                                (self.__name, aStateName))
+               return 0
+
     def view(self):
     def view(self):
         import FSMInspector
         import FSMInspector
         FSMInspector.FSMInspector(self)
         FSMInspector.FSMInspector(self)