mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 01:44:06 -04:00
adding ability to define specialized behavior for particular transitions
This commit is contained in:
parent
60e2152767
commit
4d91590a26
@ -121,6 +121,14 @@ class FSM(DirectObject):
|
||||
function, and clean it up within the corresponding exitState()
|
||||
function.
|
||||
|
||||
There is a way to define specialized transition behavior between
|
||||
two particular states. This is done by defining a from<X>To<Y>()
|
||||
function, where X is the old state and Y is the new state. If this
|
||||
is defined, it will be run in place of the exit<X> and enter<Y>
|
||||
functions, so if you want that behavior, you'll have to call them
|
||||
specifically. Otherwise, you can completely replace that transition's
|
||||
behavior.
|
||||
|
||||
See the code in SampleFSM.py for further examples.
|
||||
"""
|
||||
|
||||
@ -180,6 +188,19 @@ class FSM(DirectObject):
|
||||
# functions will already have been called.
|
||||
return 'FSM-%s-%s-stateChange' % (self._serialNum, self.name)
|
||||
|
||||
def getCurrentFilter(self):
|
||||
if not self.state:
|
||||
error = "requested %s while FSM is in transition from %s to %s." % (request, self.oldState, self.newState)
|
||||
raise AlreadyInTransition, error
|
||||
|
||||
filter = getattr(self, "filter" + self.state, None)
|
||||
if not filter:
|
||||
# If there's no matching filterState() function, call
|
||||
# defaultFilter() instead.
|
||||
filter = self.defaultFilter
|
||||
|
||||
return filter
|
||||
|
||||
def getCurrentOrNextState(self):
|
||||
# Returns the current state if we are in a state now, or the
|
||||
# state we are transitioning into if we are currently within
|
||||
@ -289,16 +310,8 @@ class FSM(DirectObject):
|
||||
self.notify.debug("%s.request(%s, %s" % (
|
||||
self.name, request, str(args)[1:]))
|
||||
|
||||
if not self.state:
|
||||
error = "requested %s while FSM is in transition from %s to %s." % (request, self.oldState, self.newState)
|
||||
raise AlreadyInTransition, error
|
||||
|
||||
func = getattr(self, "filter" + self.state, None)
|
||||
if not func:
|
||||
# If there's no matching filterState() function, call
|
||||
# defaultFilter() instead.
|
||||
func = self.defaultFilter
|
||||
result = func(request, args)
|
||||
filter = self.getCurrentFilter()
|
||||
result = filter(request, args)
|
||||
if result:
|
||||
if isinstance(result, types.StringTypes):
|
||||
# If the return value is a string, it's just the name
|
||||
@ -439,8 +452,11 @@ class FSM(DirectObject):
|
||||
self.state = None
|
||||
|
||||
try:
|
||||
self.__callExitFunc(self.oldState)
|
||||
self.__callEnterFunc(self.newState, *args)
|
||||
if not self.__callFromToFunc(self.oldState, self.newState, *args):
|
||||
self.__callExitFunc(self.oldState)
|
||||
self.__callEnterFunc(self.newState, *args)
|
||||
pass
|
||||
pass
|
||||
except:
|
||||
# If we got an exception during the enter or exit methods,
|
||||
# go directly to state "InternalError" and raise up the
|
||||
@ -476,6 +492,17 @@ class FSM(DirectObject):
|
||||
func = self.defaultEnter
|
||||
func(*args)
|
||||
|
||||
def __callFromToFunc(self, oldState, newState, *args):
|
||||
# Calls the appropriate fromTo function when transitioning into
|
||||
# a new state, if it exists.
|
||||
assert self.state == None and self.oldState == oldState and self.newState == newState
|
||||
|
||||
func = getattr(self, "from%sTo%s" % (oldState,newState), None)
|
||||
if func:
|
||||
func(*args)
|
||||
return True
|
||||
return False
|
||||
|
||||
def __callExitFunc(self, name):
|
||||
# Calls the appropriate exit function when leaving a
|
||||
# state, if it exists.
|
||||
@ -501,7 +528,7 @@ class FSM(DirectObject):
|
||||
if self.state:
|
||||
str = ('%s FSM:%s in state "%s"' % (className, self.name, self.state))
|
||||
else:
|
||||
str = ('%s FSM:%s not in any state' % (className, self.name))
|
||||
str = ('%s FSM:%s in transition from \'%s\' to \'%s\'' % (className, self.name, self.oldState, self.newState))
|
||||
return str
|
||||
finally:
|
||||
self.fsmLock.release()
|
||||
|
Loading…
x
Reference in New Issue
Block a user