Applied patch from Nemesis13 partially ;-)

This commit is contained in:
Hubert Grzeskowiak 2009-11-03 18:08:29 +00:00 committed by rdb
parent fcd2a2ec0d
commit 617e9d5e8c

View File

@ -1,11 +1,9 @@
"""Undocumented Module""" """The new Finite State Machine module. This replaces the module
previously called FSM.py (now called ClassicFSM.py).
"""
__all__ = ['FSMException', 'FSM'] __all__ = ['FSMException', 'FSM']
"""
The new Finite State Machine module. This replaces the modules
previously called FSM.py (now called ClassicFSM.py).
"""
from direct.showbase.DirectObject import DirectObject from direct.showbase.DirectObject import DirectObject
from direct.directnotify import DirectNotifyGlobal from direct.directnotify import DirectNotifyGlobal
@ -145,6 +143,7 @@ class FSM(DirectObject):
def __init__(self, name): def __init__(self, name):
self.fsmLock = RLock() self.fsmLock = RLock()
self.name = name self.name = name
self.stateArray = []
self._serialNum = FSM.SerialNum self._serialNum = FSM.SerialNum
FSM.SerialNum += 1 FSM.SerialNum += 1
self._broadcastStateChanges = False self._broadcastStateChanges = False
@ -211,7 +210,7 @@ class FSM(DirectObject):
return self.state == None return self.state == None
finally: finally:
self.fsmLock.release() self.fsmLock.release()
def forceTransition(self, request, *args): def forceTransition(self, request, *args):
"""Changes unconditionally to the indicated state. This """Changes unconditionally to the indicated state. This
bypasses the filterState() function, and just calls bypasses the filterState() function, and just calls
@ -277,7 +276,7 @@ class FSM(DirectObject):
filterState() (that is, None if the request does not provoke a filterState() (that is, None if the request does not provoke a
state transition, otherwise it is a tuple containing the name state transition, otherwise it is a tuple containing the name
of the state followed by any optional args.) of the state followed by any optional args.)
If the FSM is currently in transition (i.e. in the middle of If the FSM is currently in transition (i.e. in the middle of
executing an enterState or exitState function), an executing an enterState or exitState function), an
AlreadyInTransition exception is raised (but see demand(), AlreadyInTransition exception is raised (but see demand(),
@ -393,39 +392,48 @@ class FSM(DirectObject):
finally: finally:
self.fsmLock.release() self.fsmLock.release()
def requestNext(self, *args): def requestNext(self, *args):
"""request the 'next' state in the predefined state array""" """Request the 'next' state in the predefined state array."""
self.fsmLock.acquire() self.fsmLock.acquire()
try: try:
assert self.state in self.stateArray if self.stateArray:
if not self.state in self.stateArray:
self.request(self.stateArray[0])
else:
cur_index = self.stateArray.index(self.state)
new_index = (cur_index + 1) % len(self.stateArray)
self.request(self.stateArray[new_index], args)
else:
assert self.notifier.debug(
"stateArray empty. Can't switch to next.")
curIndex = self.stateArray.index(self.state)
newIndex = (curIndex + 1) % len(self.stateArray)
self.request(self.stateArray[newIndex], args)
finally: finally:
self.fsmLock.release() self.fsmLock.release()
def requestPrev(self, *args): def requestPrev(self, *args):
"""request the 'previous' state in the predefined state array""" """Request the 'previous' state in the predefined state array."""
self.fsmLock.acquire() self.fsmLock.acquire()
try: try:
assert self.state in self.stateArray if self.stateArray:
if not self.state in self.stateArray:
curIndex = self.stateArray.index(self.state) self.request(self.stateArray[0])
newIndex = (curIndex - 1) % len(self.stateArray) else:
cur_index = self.stateArray.index(self.state)
self.request(self.stateArray[newIndex], args) new_index = (cur_index - 1) % len(self.stateArray)
self.request(self.stateArray[new_index], args)
else:
assert self.notifier.debug(
"stateArray empty. Can't switch to next.")
finally: finally:
self.fsmLock.release() self.fsmLock.release()
def __setState(self, newState, *args): def __setState(self, newState, *args):
# Internal function to change unconditionally to the indicated # Internal function to change unconditionally to the indicated
# state. # state.
assert self.state assert self.state
assert self.notify.debug("%s to state %s." % (self.name, newState)) assert self.notify.debug("%s to state %s." % (self.name, newState))
self.oldState = self.state self.oldState = self.state
self.newState = newState self.newState = newState
self.state = None self.state = None
@ -438,7 +446,7 @@ class FSM(DirectObject):
# go directly to state "InternalError" and raise up the # go directly to state "InternalError" and raise up the
# exception. This might leave things a little unclean # exception. This might leave things a little unclean
# since we've partially transitioned, but what can you do? # since we've partially transitioned, but what can you do?
self.state = 'InternalError' self.state = 'InternalError'
del self.oldState del self.oldState
del self.newState del self.newState
@ -446,7 +454,7 @@ class FSM(DirectObject):
if self._broadcastStateChanges: if self._broadcastStateChanges:
messenger.send(self.getStateChangeEvent()) messenger.send(self.getStateChangeEvent())
self.state = newState self.state = newState
del self.oldState del self.oldState
del self.newState del self.newState
@ -479,7 +487,7 @@ class FSM(DirectObject):
# defaultExit() instead. # defaultExit() instead.
func = self.defaultExit func = self.defaultExit
func() func()
def __repr__(self): def __repr__(self):
return self.__str__() return self.__str__()