mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 01:44:06 -04:00
allow extra args to enter function, don't pass oldState, newState but store them instead
This commit is contained in:
parent
88ef2acf35
commit
bbea3902db
@ -22,22 +22,22 @@ class FSM(DirectObject.DirectObject):
|
|||||||
particular state, define a method named enterState() and/or
|
particular state, define a method named enterState() and/or
|
||||||
exitState(), where "State" is the name of the state, e.g.:
|
exitState(), where "State" is the name of the state, e.g.:
|
||||||
|
|
||||||
def enterRed(self, oldState, newState):
|
def enterRed(self):
|
||||||
... do stuff ...
|
... do stuff ...
|
||||||
|
|
||||||
def exitRed(self, oldState, newState):
|
def exitRed(self):
|
||||||
... cleanup stuff ...
|
... cleanup stuff ...
|
||||||
|
|
||||||
def enterYellow(self, oldState, newState):
|
def enterYellow(self):
|
||||||
... do stuff ...
|
... do stuff ...
|
||||||
|
|
||||||
def exitYellow(self, oldState, newState):
|
def exitYellow(self):
|
||||||
... cleanup stuff ...
|
... cleanup stuff ...
|
||||||
|
|
||||||
def enterGreen(self, oldState, newState):
|
def enterGreen(self):
|
||||||
... do stuff ...
|
... do stuff ...
|
||||||
|
|
||||||
def exitGreen(self, oldState, newState):
|
def exitGreen(self):
|
||||||
... cleanup stuff ...
|
... cleanup stuff ...
|
||||||
|
|
||||||
Both functions are supplied the previous state name and the new
|
Both functions are supplied the previous state name and the new
|
||||||
@ -134,7 +134,7 @@ class FSM(DirectObject.DirectObject):
|
|||||||
bypasses the filterState() function, and just calls
|
bypasses the filterState() function, and just calls
|
||||||
exitState() followed by enterState()."""
|
exitState() followed by enterState()."""
|
||||||
|
|
||||||
assert(isinstance(newState, types.StringType))
|
assert(isinstance(newState, types.StringTypes))
|
||||||
|
|
||||||
self.__setState(newState)
|
self.__setState(newState)
|
||||||
|
|
||||||
@ -147,13 +147,14 @@ class FSM(DirectObject.DirectObject):
|
|||||||
|
|
||||||
The return value is the same as the return value of
|
The return value is the same as the return value of
|
||||||
filterState() (that is, None if the request does not provoke a
|
filterState() (that is, None if the request does not provoke a
|
||||||
state transition, or the name of the new state otherwise.)
|
state transition, otherwise it is a tuple containing the name
|
||||||
|
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), the request is
|
executing an enterState or exitState function), the request is
|
||||||
denied and None is returned."""
|
denied and None is returned."""
|
||||||
|
|
||||||
assert(isinstance(request, types.StringType))
|
assert(isinstance(request, types.StringTypes))
|
||||||
self.notify.debug("%s.request(%s, %s" % (self.name, request, str(args)[1:]))
|
self.notify.debug("%s.request(%s, %s" % (self.name, request, str(args)[1:]))
|
||||||
|
|
||||||
if not self.state:
|
if not self.state:
|
||||||
@ -167,8 +168,13 @@ class FSM(DirectObject.DirectObject):
|
|||||||
func = self.defaultFilter
|
func = self.defaultFilter
|
||||||
result = func(request, args)
|
result = func(request, args)
|
||||||
if result:
|
if result:
|
||||||
assert(isinstance(result, types.StringType))
|
if isinstance(result, types.StringTypes):
|
||||||
self.__setState(result)
|
# If the return value is a string, it's just the name
|
||||||
|
# of the state. Wrap it in a tuple for consistency.
|
||||||
|
result = (result,)
|
||||||
|
|
||||||
|
# Otherwise, assume it's a (name, *args) tuple
|
||||||
|
self.__setState(*result)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@ -182,14 +188,14 @@ class FSM(DirectObject.DirectObject):
|
|||||||
|
|
||||||
if request == 'Off':
|
if request == 'Off':
|
||||||
# We can always go to the "Off" state.
|
# We can always go to the "Off" state.
|
||||||
return request
|
return (request,) + args
|
||||||
|
|
||||||
if self.defaultTransitions is None:
|
if self.defaultTransitions is None:
|
||||||
# If self.defaultTransitions is None, it means to accept
|
# If self.defaultTransitions is None, it means to accept
|
||||||
# all requests whose name begins with a capital letter.
|
# all requests whose name begins with a capital letter.
|
||||||
# These are direct requests to a particular state.
|
# These are direct requests to a particular state.
|
||||||
if request[0] in string.uppercase:
|
if request[0] in string.uppercase:
|
||||||
return request
|
return (request,) + args
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# If self.defaultTransitions is not None, it is a map of
|
# If self.defaultTransitions is not None, it is a map of
|
||||||
@ -200,7 +206,7 @@ class FSM(DirectObject.DirectObject):
|
|||||||
if request in self.defaultTransitions.get(self.state, []):
|
if request in self.defaultTransitions.get(self.state, []):
|
||||||
# This transition is listed in the defaultTransitions map;
|
# This transition is listed in the defaultTransitions map;
|
||||||
# accept it.
|
# accept it.
|
||||||
return request
|
return (request,) + args
|
||||||
|
|
||||||
# If self.defaultTransitions is not None, it is an error
|
# If self.defaultTransitions is not None, it is an error
|
||||||
# to request a direct state transition (capital letter
|
# to request a direct state transition (capital letter
|
||||||
@ -222,26 +228,29 @@ class FSM(DirectObject.DirectObject):
|
|||||||
return self.defaultFilter(request, args)
|
return self.defaultFilter(request, args)
|
||||||
|
|
||||||
|
|
||||||
def __setState(self, newState):
|
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)
|
||||||
|
|
||||||
oldState = self.state
|
self.oldState = self.state
|
||||||
|
self.newState = newState
|
||||||
self.state = None
|
self.state = None
|
||||||
self.__callTransitionFunc("exit" + oldState, oldState, newState)
|
self.__callTransitionFunc("exit" + self.oldState)
|
||||||
self.__callTransitionFunc("enter" + newState, oldState, newState)
|
self.__callTransitionFunc("enter" + self.newState, *args)
|
||||||
self.state = newState
|
self.state = newState
|
||||||
|
del self.oldState
|
||||||
|
del self.newState
|
||||||
|
|
||||||
|
|
||||||
def __callTransitionFunc(self, name, oldState, newState):
|
def __callTransitionFunc(self, name, *args):
|
||||||
# Calls the appropriate enter or exit function when
|
# Calls the appropriate enter or exit function when
|
||||||
# transitioning between states, if it exists.
|
# transitioning between states, if it exists.
|
||||||
assert(self.state == None)
|
assert(self.state == None)
|
||||||
|
|
||||||
func = getattr(self, name, None)
|
func = getattr(self, name, None)
|
||||||
if func:
|
if func:
|
||||||
func(oldState, newState)
|
func(*args)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return self.__str__()
|
return self.__str__()
|
||||||
|
@ -15,29 +15,29 @@ class ClassicStyle(FSM.FSM):
|
|||||||
'Green' : ['Yellow'],
|
'Green' : ['Yellow'],
|
||||||
}
|
}
|
||||||
|
|
||||||
def enterRed(self, oldState, newState):
|
def enterRed(self):
|
||||||
print "enterRed(self, '%s', '%s')" % (oldState, newState)
|
print "enterRed(self, '%s', '%s')" % (self.oldState, self.newState)
|
||||||
|
|
||||||
def exitRed(self, oldState, newState):
|
def exitRed(self):
|
||||||
print "exitRed(self, '%s', '%s')" % (oldState, newState)
|
print "exitRed(self, '%s', '%s')" % (self.oldState, self.newState)
|
||||||
|
|
||||||
def enterYellow(self, oldState, newState):
|
def enterYellow(self):
|
||||||
print "enterYellow(self, '%s', '%s')" % (oldState, newState)
|
print "enterYellow(self, '%s', '%s')" % (self.oldState, self.newState)
|
||||||
|
|
||||||
def exitYellow(self, oldState, newState):
|
def exitYellow(self):
|
||||||
print "exitYellow(self, '%s', '%s')" % (oldState, newState)
|
print "exitYellow(self, '%s', '%s')" % (self.oldState, self.newState)
|
||||||
|
|
||||||
def enterGreen(self, oldState, newState):
|
def enterGreen(self):
|
||||||
print "enterGreen(self, '%s', '%s')" % (oldState, newState)
|
print "enterGreen(self, '%s', '%s')" % (self.oldState, self.newState)
|
||||||
|
|
||||||
def exitGreen(self, oldState, newState):
|
def exitGreen(self):
|
||||||
print "exitGreen(self, '%s', '%s')" % (oldState, newState)
|
print "exitGreen(self, '%s', '%s')" % (self.oldState, self.newState)
|
||||||
|
|
||||||
|
|
||||||
class NewStyle(FSM.FSM):
|
class NewStyle(FSM.FSM):
|
||||||
|
|
||||||
def enterRed(self, oldState, newState):
|
def enterRed(self):
|
||||||
print "enterRed(self, '%s', '%s')" % (oldState, newState)
|
print "enterRed(self, '%s', '%s')" % (self.oldState, self.newState)
|
||||||
|
|
||||||
def filterRed(self, request, args):
|
def filterRed(self, request, args):
|
||||||
print "filterRed(self, '%s', %s)" % (request, args)
|
print "filterRed(self, '%s', %s)" % (request, args)
|
||||||
@ -45,11 +45,11 @@ class NewStyle(FSM.FSM):
|
|||||||
return 'Green'
|
return 'Green'
|
||||||
return self.defaultFilter(request, args)
|
return self.defaultFilter(request, args)
|
||||||
|
|
||||||
def exitRed(self, oldState, newState):
|
def exitRed(self):
|
||||||
print "exitRed(self, '%s', '%s')" % (oldState, newState)
|
print "exitRed(self, '%s', '%s')" % (self.oldState, self.newState)
|
||||||
|
|
||||||
def enterYellow(self, oldState, newState):
|
def enterYellow(self):
|
||||||
print "enterYellow(self, '%s', '%s')" % (oldState, newState)
|
print "enterYellow(self, '%s', '%s')" % (self.oldState, self.newState)
|
||||||
|
|
||||||
def filterYellow(self, request, args):
|
def filterYellow(self, request, args):
|
||||||
print "filterYellow(self, '%s', %s)" % (request, args)
|
print "filterYellow(self, '%s', %s)" % (request, args)
|
||||||
@ -57,11 +57,11 @@ class NewStyle(FSM.FSM):
|
|||||||
return 'Red'
|
return 'Red'
|
||||||
return self.defaultFilter(request, args)
|
return self.defaultFilter(request, args)
|
||||||
|
|
||||||
def exitYellow(self, oldState, newState):
|
def exitYellow(self):
|
||||||
print "exitYellow(self, '%s', '%s')" % (oldState, newState)
|
print "exitYellow(self, '%s', '%s')" % (self.oldState, self.newState)
|
||||||
|
|
||||||
def enterGreen(self, oldState, newState):
|
def enterGreen(self):
|
||||||
print "enterGreen(self, '%s', '%s')" % (oldState, newState)
|
print "enterGreen(self, '%s', '%s')" % (self.oldState, self.newState)
|
||||||
|
|
||||||
def filterGreen(self, request, args):
|
def filterGreen(self, request, args):
|
||||||
print "filterGreen(self, '%s', %s)" % (request, args)
|
print "filterGreen(self, '%s', %s)" % (request, args)
|
||||||
@ -69,8 +69,8 @@ class NewStyle(FSM.FSM):
|
|||||||
return 'Yellow'
|
return 'Yellow'
|
||||||
return self.defaultFilter(request, args)
|
return self.defaultFilter(request, args)
|
||||||
|
|
||||||
def exitGreen(self, oldState, newState):
|
def exitGreen(self):
|
||||||
print "exitGreen(self, '%s', '%s')" % (oldState, newState)
|
print "exitGreen(self, '%s', '%s')" % (self.oldState, self.newState)
|
||||||
|
|
||||||
|
|
||||||
class ToonEyes(FSM.FSM):
|
class ToonEyes(FSM.FSM):
|
||||||
@ -91,7 +91,7 @@ class ToonEyes(FSM.FSM):
|
|||||||
# Unexpected command requests are quietly ignored.
|
# Unexpected command requests are quietly ignored.
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def enterOpen(self, oldState, newState):
|
def enterOpen(self):
|
||||||
print "swap in eyes open model"
|
print "swap in eyes open model"
|
||||||
|
|
||||||
def filterOpen(self, request, args):
|
def filterOpen(self, request, args):
|
||||||
@ -105,7 +105,7 @@ class ToonEyes(FSM.FSM):
|
|||||||
self.request('unblink')
|
self.request('unblink')
|
||||||
return Task.done
|
return Task.done
|
||||||
|
|
||||||
def enterClosed(self, oldState, newState):
|
def enterClosed(self):
|
||||||
print "swap in eyes closed model"
|
print "swap in eyes closed model"
|
||||||
|
|
||||||
def filterClosed(self, request, args):
|
def filterClosed(self, request, args):
|
||||||
@ -113,10 +113,10 @@ class ToonEyes(FSM.FSM):
|
|||||||
return 'Open'
|
return 'Open'
|
||||||
return self.defaultFilter(request, args)
|
return self.defaultFilter(request, args)
|
||||||
|
|
||||||
def enterSurprised(self, oldState, newState):
|
def enterSurprised(self):
|
||||||
print "swap in eyes surprised model"
|
print "swap in eyes surprised model"
|
||||||
|
|
||||||
def enterOff(self, oldState, newState):
|
def enterOff(self):
|
||||||
taskMgr.remove(self.__unblinkName)
|
taskMgr.remove(self.__unblinkName)
|
||||||
|
|
||||||
|
|
||||||
@ -127,7 +127,7 @@ class ToonEyes(FSM.FSM):
|
|||||||
## >>> foo = SampleFSM.ClassicStyle('foo')
|
## >>> foo = SampleFSM.ClassicStyle('foo')
|
||||||
## >>> foo.request('Red')
|
## >>> foo.request('Red')
|
||||||
## enterRed(self, 'Off', 'Red')
|
## enterRed(self, 'Off', 'Red')
|
||||||
## 'Red'
|
## ('Red',)
|
||||||
## >>> foo.request('Yellow')
|
## >>> foo.request('Yellow')
|
||||||
## Traceback (most recent call last):
|
## Traceback (most recent call last):
|
||||||
## File "<stdin>", line 1, in ?
|
## File "<stdin>", line 1, in ?
|
||||||
@ -141,7 +141,7 @@ class ToonEyes(FSM.FSM):
|
|||||||
## >>> foo.request('Green')
|
## >>> foo.request('Green')
|
||||||
## exitRed(self, 'Red', 'Green')
|
## exitRed(self, 'Red', 'Green')
|
||||||
## enterGreen(self, 'Red', 'Green')
|
## enterGreen(self, 'Red', 'Green')
|
||||||
## 'Green'
|
## ('Green',)
|
||||||
## >>>
|
## >>>
|
||||||
|
|
||||||
####
|
####
|
||||||
@ -151,27 +151,27 @@ class ToonEyes(FSM.FSM):
|
|||||||
## >>> foo = SampleFSM.NewStyle('foo')
|
## >>> foo = SampleFSM.NewStyle('foo')
|
||||||
## >>> foo.request('Red')
|
## >>> foo.request('Red')
|
||||||
## enterRed(self, 'Off', 'Red')
|
## enterRed(self, 'Off', 'Red')
|
||||||
## 'Red'
|
## ('Red',)
|
||||||
## >>> foo.request('advance')
|
## >>> foo.request('advance')
|
||||||
## filterRed(self, 'advance', ())
|
## filterRed(self, 'advance', ())
|
||||||
## exitRed(self, 'Red', 'Green')
|
## exitRed(self, 'Red', 'Green')
|
||||||
## enterGreen(self, 'Red', 'Green')
|
## enterGreen(self, 'Red', 'Green')
|
||||||
## 'Green'
|
## ('Green',)
|
||||||
## >>> foo.request('advance')
|
## >>> foo.request('advance')
|
||||||
## filterGreen(self, 'advance', ())
|
## filterGreen(self, 'advance', ())
|
||||||
## exitGreen(self, 'Green', 'Yellow')
|
## exitGreen(self, 'Green', 'Yellow')
|
||||||
## enterYellow(self, 'Green', 'Yellow')
|
## enterYellow(self, 'Green', 'Yellow')
|
||||||
## 'Yellow'
|
## ('Yellow',)
|
||||||
## >>> foo.request('advance')
|
## >>> foo.request('advance')
|
||||||
## filterYellow(self, 'advance', ())
|
## filterYellow(self, 'advance', ())
|
||||||
## exitYellow(self, 'Yellow', 'Red')
|
## exitYellow(self, 'Yellow', 'Red')
|
||||||
## enterRed(self, 'Yellow', 'Red')
|
## enterRed(self, 'Yellow', 'Red')
|
||||||
## 'Red'
|
## ('Red',)
|
||||||
## >>> foo.request('advance')
|
## >>> foo.request('advance')
|
||||||
## filterRed(self, 'advance', ())
|
## filterRed(self, 'advance', ())
|
||||||
## exitRed(self, 'Red', 'Green')
|
## exitRed(self, 'Red', 'Green')
|
||||||
## enterGreen(self, 'Red', 'Green')
|
## enterGreen(self, 'Red', 'Green')
|
||||||
## 'Green'
|
## ('Green',)
|
||||||
## >>>
|
## >>>
|
||||||
|
|
||||||
####
|
####
|
||||||
@ -183,11 +183,11 @@ class ToonEyes(FSM.FSM):
|
|||||||
## swap in eyes open model
|
## swap in eyes open model
|
||||||
## >>> eyes.request('blink')
|
## >>> eyes.request('blink')
|
||||||
## swap in eyes closed model
|
## swap in eyes closed model
|
||||||
## 'Closed'
|
## ('Closed',)
|
||||||
## >>> run()
|
## >>> run()
|
||||||
## swap in eyes open model
|
## swap in eyes open model
|
||||||
## >>> eyes.request('Surprised')
|
## >>> eyes.request('Surprised')
|
||||||
## swap in eyes surprised model
|
## swap in eyes surprised model
|
||||||
## 'Surprised'
|
## ('Surprised',)
|
||||||
## >>> eyes.request('blink')
|
## >>> eyes.request('blink')
|
||||||
## >>>
|
## >>>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user