diff --git a/direct/src/showbase/ShowBase.py b/direct/src/showbase/ShowBase.py index be7ab3bc96..762c909829 100644 --- a/direct/src/showbase/ShowBase.py +++ b/direct/src/showbase/ShowBase.py @@ -33,6 +33,7 @@ import EventManager import math,sys,os import Loader import time +import gc from direct.fsm import ClassicFSM from direct.fsm import State from direct.showbase import ExceptionVarDump @@ -53,6 +54,8 @@ class ShowBase(DirectObject.DirectObject): notify = directNotify.newCategory("ShowBase") + GarbageCollectTaskName = "allowGarbageCollect" + def __init__(self): __builtin__.__dev__ = config.GetBool('want-dev', 0) if config.GetBool('want-variable-dump', not __dev__): @@ -364,6 +367,13 @@ class ShowBase(DirectObject.DirectObject): if self.windowType != 'none': self.__doStartDirect() + + self._wantGcTask = config.GetBool('want-garbage-collect-task', 1) + self._gcTask = None + if self._wantGcTask: + # manual garbage-collect task + self._gcTask = taskMgr.add(self._garbageCollect, self.GarbageCollectTaskName, 200) + # Start IGLOOP self.restart() @@ -407,6 +417,10 @@ class ShowBase(DirectObject.DirectObject): This function is designed to be safe to call multiple times.""" + if self._gcTask: + self._gcTask.remove() + self._gcTask = None + taskMgr.destroy() if getattr(self, 'musicManager', None): @@ -2273,6 +2287,19 @@ class ShowBase(DirectObject.DirectObject): def run(self): self.taskMgr.run() + 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 Task.cont + +class GCTrigger: + # used to trigger garbage collection + pass + # A class to encapsulate information necessary for multiwindow support. class WindowControls: diff --git a/direct/src/task/TaskOrig.py b/direct/src/task/TaskOrig.py index 9776964652..e566e4f2e4 100644 --- a/direct/src/task/TaskOrig.py +++ b/direct/src/task/TaskOrig.py @@ -29,7 +29,6 @@ except: Dtool_PreloadDLL("libheapq") from libheapq import heappush, heappop, heapify import types -import gc if __debug__: # For pstats @@ -362,10 +361,6 @@ class TaskSortList(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 @@ -383,8 +378,6 @@ class TaskManager: OsdPrefix = 'task.' - GarbageCollectTaskName = "allowGarbageCollect" - # multiple of average frame duration DefTaskDurationWarningThreshold = 40. @@ -443,13 +436,7 @@ class TaskManager: # A default task. self._doLaterTask = 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._doLaterTask: self._doLaterTask.remove() if self._taskProfiler: @@ -571,15 +558,6 @@ 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, sort = None, priority = None, taskChain = None, uponDeath = None, appendTask = False, owner = None): @@ -1143,13 +1121,6 @@ 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, TaskManager.GarbageCollectTaskName, 200) - if not self._profileTasks: if 'base' in __builtins__ or \ 'simbase' in __builtins__: