Browse Source

toon optimizations

Joe Shochet 21 years ago
parent
commit
15db33d2ff

+ 65 - 91
direct/src/actor/Actor.py

@@ -578,16 +578,11 @@ class Actor(PandaObject, NodePath):
         """getPart(self, string, key="lodRoot")
         """getPart(self, string, key="lodRoot")
         Find the named part in the optional named lod and return it, or
         Find the named part in the optional named lod and return it, or
         return None if not present"""
         return None if not present"""
-        if (self.__partBundleDict.has_key(lodName)):
-            partBundleDict = self.__partBundleDict[lodName]
-        else:
+        partBundleDict = self.__partBundleDict.get(lodName)
+        if not partBundleDict:
             Actor.notify.warning("no lod named: %s" % (lodName))
             Actor.notify.warning("no lod named: %s" % (lodName))
             return None
             return None
-                
-        if (partBundleDict.has_key(partName)):
-            return partBundleDict[partName]
-        else:
-            return None
+        return partBundleDict.get(partName)
 
 
     def removePart(self, partName, lodName="lodRoot"):
     def removePart(self, partName, lodName="lodRoot"):
         """removePart(self, string, key="lodRoot")
         """removePart(self, string, key="lodRoot")
@@ -595,18 +590,16 @@ class Actor(PandaObject, NodePath):
         optional named lod if present.
         optional named lod if present.
         NOTE: this will remove child geometry also!"""
         NOTE: this will remove child geometry also!"""
         # find the corresponding part bundle dict
         # find the corresponding part bundle dict
-        if (self.__partBundleDict.has_key(lodName)):
-            partBundleDict = self.__partBundleDict[lodName]
-        else:
+        partBundleDict = self.__partBundleDict.get(lodName)
+        if not partBundleDict:
             Actor.notify.warning("no lod named: %s" % (lodName))
             Actor.notify.warning("no lod named: %s" % (lodName))
-            return None
+            return
 
 
         # find the corresponding anim control dict
         # find the corresponding anim control dict
-        if (self.__animControlDict.has_key(lodName)):
-            animControlDict = self.__animControlDict[lodName]
-        else:
+        animControlDict = self.__animControlDict.get(lodName)
+        if not animControlDict:
             Actor.notify.warning("no lod named: %s" % (lodName))
             Actor.notify.warning("no lod named: %s" % (lodName))
-            return None
+            return
 
 
         # remove the part
         # remove the part
         if (partBundleDict.has_key(partName)):
         if (partBundleDict.has_key(partName)):
@@ -622,14 +615,13 @@ class Actor(PandaObject, NodePath):
         Make the given part of the optionally given lod not render,
         Make the given part of the optionally given lod not render,
         even though still in the tree.
         even though still in the tree.
         NOTE: this will affect child geometry"""
         NOTE: this will affect child geometry"""
-        if (self.__partBundleDict.has_key(lodName)):
-            partBundleDict = self.__partBundleDict[lodName]
-        else:
+        partBundleDict = self.__partBundleDict.get(lodName)
+        if not partBundleDict:
             Actor.notify.warning("no lod named: %s" % (lodName))
             Actor.notify.warning("no lod named: %s" % (lodName))
-            return None
-
-        if (partBundleDict.has_key(partName)):
-            partBundleDict[partName].hide()
+            return
+        part = partBundleDict.get(partName)
+        if part:
+            part.hide()
         else:
         else:
             Actor.notify.warning("no part named %s!" % (partName))
             Actor.notify.warning("no part named %s!" % (partName))
 
 
@@ -637,14 +629,13 @@ class Actor(PandaObject, NodePath):
         """showPart(self, string, key="lodRoot")
         """showPart(self, string, key="lodRoot")
         Make the given part render while in the tree.
         Make the given part render while in the tree.
         NOTE: this will affect child geometry"""
         NOTE: this will affect child geometry"""
-        if (self.__partBundleDict.has_key(lodName)):
-            partBundleDict = self.__partBundleDict[lodName]
-        else:
+        partBundleDict = self.__partBundleDict.get(lodName)
+        if not partBundleDict:
             Actor.notify.warning("no lod named: %s" % (lodName))
             Actor.notify.warning("no lod named: %s" % (lodName))
-            return None
-
-        if (partBundleDict.has_key(partName)):
-            partBundleDict[partName].show()
+            return
+        part = partBundleDict.get(partName)
+        if part:
+            part.show()
         else:
         else:
             Actor.notify.warning("no part named %s!" % (partName))
             Actor.notify.warning("no part named %s!" % (partName))
 
 
@@ -652,18 +643,14 @@ class Actor(PandaObject, NodePath):
         """showAllParts(self, string, key="lodRoot")
         """showAllParts(self, string, key="lodRoot")
         Make the given part and all its children render while in the tree.
         Make the given part and all its children render while in the tree.
         NOTE: this will affect child geometry"""
         NOTE: this will affect child geometry"""
-        if (self.__partBundleDict.has_key(lodName)):
-            partBundleDict = self.__partBundleDict[lodName]
-        else:
+        partBundleDict = self.__partBundleDict.get(lodName)
+        if not partBundleDict:
             Actor.notify.warning("no lod named: %s" % (lodName))
             Actor.notify.warning("no lod named: %s" % (lodName))
-            return None
-
-        if (partBundleDict.has_key(partName)):
-            partBundleDict[partName].show()
-            children = partBundleDict[partName].getChildren()
-            numChildren = children.getNumPaths()
-            for childNum in range(0, numChildren):
-                (children.getPath(childNum)).show()
+            return
+        part = partBundleDict.get(partName)
+        if part:
+            part.show()
+            part.getChildren().show()
         else:
         else:
             Actor.notify.warning("no part named %s!" % (partName))
             Actor.notify.warning("no part named %s!" % (partName))
 
 
@@ -673,15 +660,14 @@ class Actor(PandaObject, NodePath):
         animates, it will transform the node by the corresponding
         animates, it will transform the node by the corresponding
         amount.  This will replace whatever matrix is on the node each
         amount.  This will replace whatever matrix is on the node each
         frame."""
         frame."""
-        
-        if (self.__partBundleDict.has_key(lodName)):
-            partBundleDict = self.__partBundleDict[lodName]
-        else:
+        partBundleDict = self.__partBundleDict.get(lodName)
+        if not partBundleDict:
             Actor.notify.warning("no lod named: %s" % (lodName))
             Actor.notify.warning("no lod named: %s" % (lodName))
             return None
             return None
 
 
-        if (partBundleDict.has_key(partName)):
-            bundle = partBundleDict[partName].node().getBundle()
+        part = partBundleDict.get(partName)
+        if part:
+            bundle = part.node().getBundle()
         else:
         else:
             Actor.notify.warning("no part named %s!" % (partName))
             Actor.notify.warning("no part named %s!" % (partName))
             return None
             return None
@@ -704,14 +690,14 @@ class Actor(PandaObject, NodePath):
         Stops the joint from animating external nodes.  If the joint
         Stops the joint from animating external nodes.  If the joint
         is animating a transform on a node, this will permanently stop
         is animating a transform on a node, this will permanently stop
         it.  However, this does not affect vertex animations."""
         it.  However, this does not affect vertex animations."""
-        if (self.__partBundleDict.has_key(lodName)):
-            partBundleDict = self.__partBundleDict[lodName]
-        else:
+        partBundleDict = self.__partBundleDict.get(lodName)
+        if not partBundleDict:
             Actor.notify.warning("no lod named: %s" % (lodName))
             Actor.notify.warning("no lod named: %s" % (lodName))
             return None
             return None
 
 
-        if (partBundleDict.has_key(partName)):
-            bundle = partBundleDict[partName].node().getBundle()
+        part = partBundleDict.get(partName)
+        if part:
+            bundle = part.node().getBundle()
         else:
         else:
             Actor.notify.warning("no part named %s!" % (partName))
             Actor.notify.warning("no part named %s!" % (partName))
             return None
             return None
@@ -737,14 +723,14 @@ class Actor(PandaObject, NodePath):
         animation has been loaded and bound to the character, it will
         animation has been loaded and bound to the character, it will
         be too late to add a new control during that animation.
         be too late to add a new control during that animation.
         """
         """
-        if (self.__partBundleDict.has_key(lodName)):
-            partBundleDict = self.__partBundleDict[lodName]
-        else:
+        partBundleDict = self.__partBundleDict.get(lodName)
+        if partBundleDict:
             Actor.notify.warning("no lod named: %s" % (lodName))
             Actor.notify.warning("no lod named: %s" % (lodName))
             return None
             return None
 
 
-        if (partBundleDict.has_key(partName)):
-            bundle = partBundleDict[partName].node().getBundle()
+        part = partBundleDict.get(partName)
+        if part:
+            bundle = part.node().getBundle()
         else:
         else:
             Actor.notify.warning("no part named %s!" % (partName))
             Actor.notify.warning("no part named %s!" % (partName))
             return None
             return None
@@ -767,36 +753,39 @@ class Actor(PandaObject, NodePath):
 
 
         return node
         return node
             
             
-    def instance(self, path, part, jointName, lodName="lodRoot"):
+    def instance(self, path, partName, jointName, lodName="lodRoot"):
         """instance(self, NodePath, string, string, key="lodRoot")
         """instance(self, NodePath, string, string, key="lodRoot")
         Instance a nodePath to an actor part at a joint called jointName"""
         Instance a nodePath to an actor part at a joint called jointName"""
-        if (self.__partBundleDict.has_key(lodName)):
-            partBundleDict = self.__partBundleDict[lodName]
-            if (partBundleDict.has_key(part)):
-                joint = partBundleDict[part].find("**/" + jointName)
+        partBundleDict = self.__partBundleDict.get(lodName)
+        if partBundleDict:
+            part = partBundleDict.get(partName)
+            if part:
+                joint = part.find("**/" + jointName)
                 if (joint.isEmpty()):
                 if (joint.isEmpty()):
                     Actor.notify.warning("%s not found!" % (jointName))
                     Actor.notify.warning("%s not found!" % (jointName))
                 else:
                 else:
                     return path.instanceTo(joint)
                     return path.instanceTo(joint)
             else:
             else:
-                Actor.notify.warning("no part named %s!" % (part))
+                Actor.notify.warning("no part named %s!" % (partName))
         else:
         else:
             Actor.notify.warning("no lod named %s!" % (lodName))
             Actor.notify.warning("no lod named %s!" % (lodName))
 
 
-    def attach(self, partName, anotherPart, jointName, lodName="lodRoot"):
+    def attach(self, partName, anotherPartName, jointName, lodName="lodRoot"):
         """attach(self, string, string, string, key="lodRoot")
         """attach(self, string, string, string, key="lodRoot")
         Attach one actor part to another at a joint called jointName"""
         Attach one actor part to another at a joint called jointName"""
-        if (self.__partBundleDict.has_key(lodName)):
-            partBundleDict = self.__partBundleDict[lodName]
-            if (partBundleDict.has_key(partName)):
-                if (partBundleDict.has_key(anotherPart)):
-                    joint = partBundleDict[anotherPart].find("**/" + jointName)
+        partBundleDict = self.__partBundleDict.get(lodName)
+        if partBundleDict:
+            part = partBundleDict.get(partName)
+            if part:
+                anotherPart = partBundleDict.get(anotherPartName)
+                if anotherPart:
+                    joint = anotherPart.find("**/" + jointName)
                     if (joint.isEmpty()):
                     if (joint.isEmpty()):
                         Actor.notify.warning("%s not found!" % (jointName))
                         Actor.notify.warning("%s not found!" % (jointName))
                     else:
                     else:
-                        partBundleDict[partName].reparentTo(joint)
+                        part.reparentTo(joint)
                 else:
                 else:
-                    Actor.notify.warning("no part named %s!" % (anotherPart))
+                    Actor.notify.warning("no part named %s!" % (anotherPartName))
             else:
             else:
                 Actor.notify.warning("no part named %s!" % (partName))
                 Actor.notify.warning("no part named %s!" % (partName))
         else:
         else:
@@ -1206,28 +1195,15 @@ class Actor(PandaObject, NodePath):
         anims in the form animName:animPath{}"""
         anims in the form animName:animPath{}"""
         
         
         Actor.notify.debug("in loadAnims: %s, part: %s, lod: %s" %
         Actor.notify.debug("in loadAnims: %s, part: %s, lod: %s" %
-                          (anims, partName, lodName))
+                           (anims, partName, lodName))
 
 
         for animName in anims.keys():
         for animName in anims.keys():
             # make sure this lod in in anim control dict
             # make sure this lod in in anim control dict
-            if not (self.__animControlDict.has_key(lodName)):
-                lodDict = {}
-                self.__animControlDict[lodName] = lodDict
-
-            # make sure this part dict exists
-            if not (self.__animControlDict[lodName].has_key(partName)):
-                partDict = {}
-                self.__animControlDict[lodName][partName] = partDict
-
-            # make sure this an anim dict exists
-            if not (len(self.__animControlDict[lodName][partName].keys())):
-                animDict = {}
-                self.__animControlDict[lodName][partName] = animDict
-
+            self.__animControlDict.setdefault(lodName, {})
+            self.__animControlDict[lodName].setdefault(partName, {})
             # store the file path and None in place of the animControl.
             # store the file path and None in place of the animControl.
             # we will bind it only when played
             # we will bind it only when played
-            self.__animControlDict[lodName][partName][animName] = \
-                                                                [anims[animName], None]
+            self.__animControlDict[lodName][partName][animName] = [anims[animName], None]
 
 
 
 
     def unloadAnims(self, anims, partName="modelRoot", lodName="lodRoot"):
     def unloadAnims(self, anims, partName="modelRoot", lodName="lodRoot"):
@@ -1308,9 +1284,7 @@ class Actor(PandaObject, NodePath):
         anim = loader.loadModelOnce(animPath)
         anim = loader.loadModelOnce(animPath)
         if anim == None:
         if anim == None:
             return None
             return None
-        animBundle = \
-                   (anim.find("**/+AnimBundleNode").node()).getBundle()
-
+        animBundle = (anim.find("**/+AnimBundleNode").node()).getBundle()
         bundle = self.__partBundleDict[lodName][partName].node().getBundle()
         bundle = self.__partBundleDict[lodName][partName].node().getBundle()
 
 
         # Are there any controls requested for joints in this bundle?
         # Are there any controls requested for joints in this bundle?

+ 25 - 36
direct/src/fsm/ClassicFSM.py

@@ -97,14 +97,6 @@ class ClassicFSM(DirectObject):
         self.__enter(self.__initialState, argList)
         self.__enter(self.__initialState, argList)
         assert(not self.__internalStateInFlux)
         assert(not self.__internalStateInFlux)
 
 
-    # Jesse decided that simpler was better with the __str__ function
-    def __str_not__(self):
-        """__str__(self)"""
-        return "ClassicFSM: name = %s \n states = %s \n initial = %s \n final = %s \n current = %s" \
-            % (self.__name, self.__states, self.__initialState,
-               self.__finalState, self.__currentState)
-
-
     # setters and getters
     # setters and getters
 
 
     def getName(self):
     def getName(self):
@@ -115,14 +107,17 @@ class ClassicFSM(DirectObject):
         self.__name = name
         self.__name = name
 
 
     def getStates(self):
     def getStates(self):
-        return(self.__states)
+        return self.__states.values()
 
 
     def setStates(self, states):
     def setStates(self, states):
         """setStates(self, State[])"""
         """setStates(self, State[])"""
-        self.__states = states
+        # Make a dictionary from stateName -> state
+        self.__states = {}
+        for state in states:
+            self.__states[state.getName()] = state
 
 
     def addState(self, state):
     def addState(self, state):
-        self.__states.append(state)
+        self.__states[state.getName()] = state
 
 
     def getInitialState(self):
     def getInitialState(self):
         return(self.__initialState)
         return(self.__initialState)
@@ -150,11 +145,12 @@ class ClassicFSM(DirectObject):
     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"""
-        for state in self.__states:
-            if (state.getName() == stateName):
-                return state
-        ClassicFSM.notify.warning("[%s] : getStateNamed: %s, no such state" %
-                           (self.__name, str(stateName)))
+        state = self.__states.get(stateName)
+        if state:
+            return state
+        else:
+            ClassicFSM.notify.warning("[%s] : getStateNamed: %s, no such state" %
+                                      (self.__name, stateName))
 
 
 
 
     # basic ClassicFSM functionality
     # basic ClassicFSM functionality
@@ -163,9 +159,7 @@ class ClassicFSM(DirectObject):
         """__exitCurrent(self)
         """__exitCurrent(self)
         Exit the current state"""
         Exit the current state"""
         assert(self.__internalStateInFlux)
         assert(self.__internalStateInFlux)
-        if ClassicFSM.notify.getDebug():
-            ClassicFSM.notify.debug("[%s]: exiting %s" % (self.__name,
-                                                   self.__currentState.getName()))
+        assert(ClassicFSM.notify.debug("[%s]: exiting %s" % (self.__name, self.__currentState.getName())))
         self.__currentState.exit(argList)
         self.__currentState.exit(argList)
         # Only send the state change event if we are inspecting it
         # Only send the state change event if we are inspecting it
         # If this event turns out to be generally useful, we can
         # If this event turns out to be generally useful, we can
@@ -179,17 +173,15 @@ class ClassicFSM(DirectObject):
         """__enter(self, State)
         """__enter(self, State)
         Enter a given state, if it exists"""
         Enter a given state, if it exists"""
         assert(self.__internalStateInFlux)
         assert(self.__internalStateInFlux)
-        if (aState in self.__states):
-            if ClassicFSM.notify.getDebug():
-                ClassicFSM.notify.debug("[%s]: entering %s" % (self.__name,
-                                                        aState.getName()))
+        stateName = aState.getName()
+        if (stateName in self.__states):
+            assert(ClassicFSM.notify.debug("[%s]: entering %s" % (self.__name, stateName)))
             self.__currentState = aState
             self.__currentState = aState
             # Only send the state change event if we are inspecting it
             # Only send the state change event if we are inspecting it
             # If this event turns out to be generally useful, we can
             # If this event turns out to be generally useful, we can
             # turn it on all the time, but for now nobody else is using it
             # turn it on all the time, but for now nobody else is using it
             if self.inspecting:
             if self.inspecting:
-                messenger.send(self.getName() + '_' +
-                               aState.getName() + '_entered')
+                messenger.send(self.getName() + '_' + stateName + '_entered')
 
 
             # Once we begin entering the new state, we're allow to
             # Once we begin entering the new state, we're allow to
             # recursively request a transition to another state.
             # recursively request a transition to another state.
@@ -269,24 +261,21 @@ class ClassicFSM(DirectObject):
         elif (aStateName == self.__finalState.getName()):
         elif (aStateName == self.__finalState.getName()):
             if (self.__currentState == self.__finalState):
             if (self.__currentState == self.__finalState):
                 # Do not do the transition if we are already in the final state
                 # Do not do the transition if we are already in the final state
-                if ClassicFSM.notify.getDebug():
-                    ClassicFSM.notify.debug("[%s]: already in final state: %s" %
-                                     (self.__name, aStateName))
+                assert(ClassicFSM.notify.debug("[%s]: already in final state: %s" %
+                                               (self.__name, aStateName)))
                 return 1
                 return 1
             else:
             else:
                 # Force a transition to allow for cleanup
                 # Force a transition to allow for cleanup
-                if ClassicFSM.notify.getDebug():
-                    ClassicFSM.notify.debug("[%s]: implicit transition to final state: %s" %
-                                     (self.__name, aStateName))
+                assert(ClassicFSM.notify.debug("[%s]: implicit transition to final state: %s" %
+                                               (self.__name, aStateName)))
                 self.__transition(aState,
                 self.__transition(aState,
                                   enterArgList,
                                   enterArgList,
                                   exitArgList)
                                   exitArgList)
                 return 1
                 return 1
         # are we already in this state?
         # are we already in this state?
         elif (aStateName == self.__currentState.getName()):
         elif (aStateName == self.__currentState.getName()):
-            if ClassicFSM.notify.getDebug():
-                ClassicFSM.notify.debug("[%s]: already in state %s and no self transition" %
-                                 (self.__name, aStateName))
+            assert(ClassicFSM.notify.debug("[%s]: already in state %s and no self transition" %
+                                           (self.__name, aStateName)))
             return 0
             return 0
         else:
         else:
             msg = ("[%s]: no transition exists from %s to %s" %
             msg = ("[%s]: no transition exists from %s to %s" %
@@ -343,8 +332,8 @@ class ClassicFSM(DirectObject):
         if transitionDefined:
         if transitionDefined:
             return self.request(aStateName, enterArgList, exitArgList)
             return self.request(aStateName, enterArgList, exitArgList)
         else:
         else:
-            ClassicFSM.notify.debug("[%s]: condition_request: %s, transition doesnt exist" %
-                             (self.__name, aStateName))
+            assert(ClassicFSM.notify.debug("[%s]: condition_request: %s, transition doesnt exist" %
+                                           (self.__name, aStateName)))
             return 0
             return 0
 
 
     def view(self):
     def view(self):

+ 37 - 37
direct/src/fsm/State.py

@@ -81,16 +81,13 @@ class State(DirectObject):
         """__init__(self, string, func, func, string[], inspectorPos = [])
         """__init__(self, string, func, func, string[], inspectorPos = [])
         State constructor: takes name, enter func, exit func, and
         State constructor: takes name, enter func, exit func, and
         a list of states it can transition to (or State.Any)."""
         a list of states it can transition to (or State.Any)."""
-        self.__enterFunc = None
-        self.__exitFunc = None
-
-        self.setName(name)
-        self.setEnterFunc(enterFunc)
-        self.setExitFunc(exitFunc)
-        self.setTransitions(transitions)
-        self.setInspectorPos(inspectorPos)
+        self.__name = name
+        self.__enterFunc = enterFunc
+        self.__exitFunc = exitFunc
+        self.__transitions = transitions
         self.__FSMList = []
         self.__FSMList = []
-
+        if __debug__:
+            self.setInspectorPos(inspectorPos)
 
 
     # setters and getters
     # setters and getters
 
 
@@ -106,28 +103,30 @@ class State(DirectObject):
         """getEnterFunc(self)"""
         """getEnterFunc(self)"""
         return(self.__enterFunc)
         return(self.__enterFunc)
 
 
-    def redefineFunc(self, oldMethod, newMethod, map):
-        if not FsmRedefine:
-            return
-        # Methods are allowed to be None
-        if oldMethod is None:
-            return
-        if map.has_key(oldMethod):
-            # Get the list of states for the old function
-            stateList = map[oldMethod]
-            # Remove this state from that list of states
-            stateList.remove(self)
-            # If the stateList is now empty, remove this entry altogether
-            if not stateList:
-                del(map[oldMethod])
-        # Now add the new function, creating a starter state list
-        # if there is not one already
-        stateList = map.get(newMethod, [])
-        stateList.append(self)
-        map[newMethod] = stateList
+    if __debug__:
+        def redefineFunc(self, oldMethod, newMethod, map):
+            if not FsmRedefine:
+                return
+            # Methods are allowed to be None
+            if oldMethod is None:
+                return
+            if map.has_key(oldMethod):
+                # Get the list of states for the old function
+                stateList = map[oldMethod]
+                # Remove this state from that list of states
+                stateList.remove(self)
+                # If the stateList is now empty, remove this entry altogether
+                if not stateList:
+                    del(map[oldMethod])
+            # Now add the new function, creating a starter state list
+            # if there is not one already
+            stateList = map.get(newMethod, [])
+            stateList.append(self)
+            map[newMethod] = stateList
 
 
     def setEnterFunc(self, stateEnterFunc):
     def setEnterFunc(self, stateEnterFunc):
-        self.redefineFunc(self.__enterFunc, stateEnterFunc, EnterFuncRedefineMap)
+        if __debug__:
+            self.redefineFunc(self.__enterFunc, stateEnterFunc, EnterFuncRedefineMap)
         self.__enterFunc = stateEnterFunc
         self.__enterFunc = stateEnterFunc
 
 
     def getExitFunc(self):
     def getExitFunc(self):
@@ -136,7 +135,8 @@ class State(DirectObject):
 
 
     def setExitFunc(self, stateExitFunc):
     def setExitFunc(self, stateExitFunc):
         """setExitFunc(self, func)"""
         """setExitFunc(self, func)"""
-        self.redefineFunc(self.__exitFunc, stateExitFunc, ExitFuncRedefineMap)
+        if __debug__:
+            self.redefineFunc(self.__exitFunc, stateExitFunc, ExitFuncRedefineMap)
         self.__exitFunc = stateExitFunc
         self.__exitFunc = stateExitFunc
 
 
     def transitionsToAny(self):
     def transitionsToAny(self):
@@ -176,14 +176,14 @@ class State(DirectObject):
                 'attempted to add transition %s to state that '
                 'attempted to add transition %s to state that '
                 'transitions to any state')
                 'transitions to any state')
 
 
-    def getInspectorPos(self):
-        """getInspectorPos(self)"""
-        return(self.__inspectorPos)
-
-    def setInspectorPos(self, inspectorPos):
-        """setInspectorPos(self, [x, y])"""
-        self.__inspectorPos = inspectorPos
+    if __debug__:
+        def getInspectorPos(self):
+            """getInspectorPos(self)"""
+            return(self.__inspectorPos)
 
 
+        def setInspectorPos(self, inspectorPos):
+            """setInspectorPos(self, [x, y])"""
+            self.__inspectorPos = inspectorPos
 
 
     # support for HFSMs
     # support for HFSMs
 
 

+ 1 - 5
direct/src/task/Task.py

@@ -471,11 +471,7 @@ class TaskManager:
         if TaskManager.notify.getDebug():
         if TaskManager.notify.getDebug():
             TaskManager.notify.debug('__addPendingTask: %s' % (task.name))
             TaskManager.notify.debug('__addPendingTask: %s' % (task.name))
         pri = task.getPriority()
         pri = task.getPriority()
-        if self.pendingTaskDict.has_key(pri):
-            taskPriList = self.pendingTaskDict[pri]
-        else:
-            taskPriList = TaskPriorityList(pri)
-            self.pendingTaskDict[pri] = taskPriList
+        taskPriList = self.pendingTaskDict.setdefault(pri, TaskPriorityList(pri))
         taskPriList.add(task)
         taskPriList.add(task)
 
 
     def __addNewTask(self, task):
     def __addNewTask(self, task):

+ 24 - 0
panda/src/pgraph/nodePathCollection.cxx

@@ -378,6 +378,30 @@ detach() {
   }
   }
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: NodePathCollection::set_color
+//       Access: Published
+//  Description: Colors all NodePaths in the collection
+////////////////////////////////////////////////////////////////////
+void NodePathCollection::
+set_color(float r, float g, float b, float a, int priority) {
+  for (int i = 0; i < get_num_paths(); i++) {
+    get_path(i).set_color(Colorf(r, g, b, a), priority);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: NodePathCollection::set_color
+//       Access: Published
+//  Description: Colors all NodePaths in the collection
+////////////////////////////////////////////////////////////////////
+void NodePathCollection::
+set_color(const Colorf &color, int priority) {
+  for (int i = 0; i < get_num_paths(); i++) {
+    get_path(i).node()->set_attrib(ColorAttrib::make_flat(color), priority);
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: NodePathCollection::output
 //     Function: NodePathCollection::output
 //       Access: Published
 //       Access: Published

+ 4 - 0
panda/src/pgraph/nodePathCollection.h

@@ -64,6 +64,10 @@ PUBLISHED:
   void unstash();
   void unstash();
   void detach();
   void detach();
 
 
+  void set_color(float r, float g, float b, float a = 1.0,
+                 int priority = 0);
+  void set_color(const Colorf &color, int priority = 0);
+
   void output(ostream &out) const;
   void output(ostream &out) const;
   void write(ostream &out, int indent_level = 0) const;
   void write(ostream &out, int indent_level = 0) const;