Browse Source

added explicit garbage collect task

Darren Ranalli 17 years ago
parent
commit
86d00a7024
1 changed files with 27 additions and 0 deletions
  1. 27 0
      direct/src/task/Task.py

+ 27 - 0
direct/src/task/Task.py

@@ -27,6 +27,7 @@ except:
     Dtool_PreloadDLL("libheapq")
     from libheapq import heappush, heappop, heapify
 import types
+import gc
 
 if __debug__:
     # For pstats
@@ -346,6 +347,10 @@ class TaskPriorityList(list):
             self[self.__emptyIndex-1] = None
             self.__emptyIndex -= 1
 
+class GCTrigger:
+    # used to trigger garbage collection
+    pass
+
 class TaskManager:
 
     # These class vars are generally overwritten by Config variables which
@@ -419,7 +424,13 @@ class TaskManager:
         # A default task.
         self.add(self.__doLaterProcessor, "doLaterProcessor", -10)
 
+        # start this when config is available
+        self._gcTask = None
+        self._wantGcTask = None
+
     def destroy(self):
+        if self._gcTask:
+            self._gcTask.remove()
         if self._taskProfiler:
             self._taskProfiler.destroy()
         del self.nameDict
@@ -534,6 +545,15 @@ class TaskManager:
             # TaskManager.notify.debug("filtered %s removed doLaters" % numRemoved)
         return cont
 
+    def _garbageCollect(self, task=None):
+        # enable automatic garbage collection
+        gc.enable()
+        # creating an object with gc enabled causes garbage collection to trigger if appropriate
+        gct = GCTrigger()
+        # disable the automatic garbage collect during the rest of the frame
+        gc.disable()
+        return cont
+
     def doMethodLater(self, delayTime, funcOrTask, name, extraArgs=None,
                       priority=0, uponDeath=None, appendTask=False, owner = None):
         if delayTime < 0:
@@ -1058,6 +1078,13 @@ class TaskManager:
             TaskManager._DidTests = True
             self._runTests()
 
+        if not self._gcTask:
+            if self._wantGcTask is None:
+                self._wantGcTask = config.GetBool('want-garbage-collect-task', 1)
+            if self._wantGcTask:
+                # manual garbage-collect task
+                self._gcTask = self.add(self._garbageCollect, "doGarbageCollect", 200)
+
         if not self._profileTasks:
             from direct.fsm.StatePush import StateVar
             self._profileTasks = StateVar(False)