panda3d/direct/src/showbase/LeakDetectors.py
2007-04-20 06:55:44 +00:00

63 lines
2.1 KiB
Python
Executable File

# objects that report different types of leaks to the ContainerLeakDetector
from pandac.PandaModules import *
from direct.showbase.PythonUtil import gcDebugOn
import __builtin__, gc
class LeakDetector:
def __init__(self):
# put this object just under __builtins__ where the
# ContainerLeakDetector will find it quickly
if not hasattr(__builtin__, "leakDetectors"):
__builtin__.leakDetectors = {}
leakDetectors[id(self)] = self
def destroy(self):
del leakDetectors[id(self)]
class GarbageLeakDetector(LeakDetector):
# are we accumulating Python garbage?
def __len__(self):
# do a garbage collection
wasOn = gcDebugOn()
oldFlags = gc.get_debug()
if not wasOn:
gc.set_debug(gc.DEBUG_SAVEALL)
gc.collect()
numGarbage = len(gc.garbage)
del gc.garbage[:]
if not wasOn:
gc.set_debug(oldFlags)
return numGarbage
class SceneGraphLeakDetector(LeakDetector):
# is a scene graph leaking nodes?
def __init__(self, render):
LeakDetector.__init__(self)
self._render = render
if config.GetBool('leak-scene-graph', 0):
self._leakTaskName = 'leakNodes-%s' % serialNum()
self._leakNode()
def destroy(self):
if hasattr(self, '_leakTaskName'):
taskMgr.remove(self._leakTaskName)
del self._render
LeakDetector.destroy(self)
def __len__(self):
try:
# this will be available when the build server finishes
return self._render.countNumDescendants()
except:
return self._render.getNumDescendants()
def __repr__(self):
return 'SceneGraphLeakDetector(%s)' % self._render
def _leakNode(self, task=None):
self._render.attachNewNode('leakNode-%s' % serialNum())
taskMgr.doMethodLater(10, self._leakNode, self._leakTaskName)
class CppMemoryUsage(LeakDetector):
def __len__(self):
if config.GetBool('track-memory-usage', 0):
return int(MemoryUsage.getCppSize())
else:
return 0