mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
quicker discovery of LeakDetector objects
This commit is contained in:
parent
09926188fd
commit
61550870cb
@ -265,6 +265,14 @@ class FindContainers(Job):
|
|||||||
# set up the base containers, the ones that hold most objects
|
# set up the base containers, the ones that hold most objects
|
||||||
ref = ContainerRef(Indirection(evalStr='__builtin__.__dict__'))
|
ref = ContainerRef(Indirection(evalStr='__builtin__.__dict__'))
|
||||||
self._id2baseStartRef[id(__builtin__.__dict__)] = ref
|
self._id2baseStartRef[id(__builtin__.__dict__)] = ref
|
||||||
|
# container for objects that want to make sure they are found by
|
||||||
|
# the object exploration algorithm, including objects that exist
|
||||||
|
# just to measure things such as C++ memory usage, scene graph size,
|
||||||
|
# framerate, etc. See LeakDetectors.py
|
||||||
|
if not hasattr(__builtin__, "leakDetectors"):
|
||||||
|
__builtin__.leakDetectors = {}
|
||||||
|
ref = ContainerRef(Indirection(evalStr='leakDetectors'))
|
||||||
|
self._id2baseStartRef[id(leakDetectors)] = ref
|
||||||
for i in self._addContainerGen(__builtin__.__dict__, ref):
|
for i in self._addContainerGen(__builtin__.__dict__, ref):
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
@ -369,9 +377,9 @@ class FindContainers(Job):
|
|||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
try:
|
try:
|
||||||
# this toggles between the sets of start refs every time we start a new traversal
|
# this yields a different set of start refs every time we start a new traversal
|
||||||
workingListSelector = loopGen([self._baseStartRefWorkingList,
|
# force creation of a new workingListSelector inside the while loop right off the bat
|
||||||
self._discoveredStartRefWorkingList])
|
workingListSelector = nullGen()
|
||||||
# this holds the current step of the current traversal
|
# this holds the current step of the current traversal
|
||||||
curObjRef = None
|
curObjRef = None
|
||||||
while True:
|
while True:
|
||||||
@ -381,7 +389,19 @@ class FindContainers(Job):
|
|||||||
#import pdb;pdb.set_trace()
|
#import pdb;pdb.set_trace()
|
||||||
if curObjRef is None:
|
if curObjRef is None:
|
||||||
# choose an object to start a traversal from
|
# choose an object to start a traversal from
|
||||||
startRefWorkingList = workingListSelector.next()
|
try:
|
||||||
|
startRefWorkingList = workingListSelector.next()
|
||||||
|
except StopIteration:
|
||||||
|
# do relative # of traversals on each set based on how many refs it contains
|
||||||
|
baseLen = len(self._baseStartRefWorkingList.source)
|
||||||
|
discLen = len(self._discoveredStartRefWorkingList.source)
|
||||||
|
minLen = float(max(1, min(baseLen, discLen)))
|
||||||
|
# this will cut down the traversals of the larger set by 2/3
|
||||||
|
minLen *= 3.
|
||||||
|
workingListSelector = flywheel([self._baseStartRefWorkingList, self._discoveredStartRefWorkingList],
|
||||||
|
[baseLen/minLen, discLen/minLen])
|
||||||
|
yield None
|
||||||
|
continue
|
||||||
|
|
||||||
# grab the next start ref from this sequence and see if it's still valid
|
# grab the next start ref from this sequence and see if it's still valid
|
||||||
while True:
|
while True:
|
||||||
@ -396,12 +416,12 @@ class FindContainers(Job):
|
|||||||
break
|
break
|
||||||
# make a generator that yields containers a # of times that is
|
# make a generator that yields containers a # of times that is
|
||||||
# proportional to their length
|
# proportional to their length
|
||||||
for flywheel in makeFlywheelGen(
|
for fw in makeFlywheelGen(
|
||||||
startRefWorkingList.source.values(),
|
startRefWorkingList.source.values(),
|
||||||
countFunc=lambda x: self.getStartObjAffinity(x),
|
countFunc=lambda x: self.getStartObjAffinity(x),
|
||||||
scale=.05):
|
scale=.05):
|
||||||
yield None
|
yield None
|
||||||
startRefWorkingList.refGen = flywheel
|
startRefWorkingList.refGen = fw
|
||||||
if curObjRef is None:
|
if curObjRef is None:
|
||||||
# this ref set is empty, choose another
|
# this ref set is empty, choose another
|
||||||
# the base set should never be empty (__builtin__ etc.)
|
# the base set should never be empty (__builtin__ etc.)
|
||||||
@ -540,8 +560,7 @@ class FindContainers(Job):
|
|||||||
except Exception, e:
|
except Exception, e:
|
||||||
print 'FindContainers job caught exception: %s' % e
|
print 'FindContainers job caught exception: %s' % e
|
||||||
if __dev__:
|
if __dev__:
|
||||||
#raise e
|
raise
|
||||||
pass
|
|
||||||
yield Job.Done
|
yield Job.Done
|
||||||
|
|
||||||
class CheckContainers(Job):
|
class CheckContainers(Job):
|
||||||
@ -680,8 +699,7 @@ class CheckContainers(Job):
|
|||||||
except Exception, e:
|
except Exception, e:
|
||||||
print 'CheckContainers job caught exception: %s' % e
|
print 'CheckContainers job caught exception: %s' % e
|
||||||
if __dev__:
|
if __dev__:
|
||||||
#raise e
|
raise
|
||||||
pass
|
|
||||||
yield Job.Done
|
yield Job.Done
|
||||||
|
|
||||||
class PruneContainerRefs(Job):
|
class PruneContainerRefs(Job):
|
||||||
@ -736,8 +754,7 @@ class PruneContainerRefs(Job):
|
|||||||
except Exception, e:
|
except Exception, e:
|
||||||
print 'PruneContainerRefs job caught exception: %s' % e
|
print 'PruneContainerRefs job caught exception: %s' % e
|
||||||
if __dev__:
|
if __dev__:
|
||||||
#raise e
|
raise
|
||||||
pass
|
|
||||||
yield Job.Done
|
yield Job.Done
|
||||||
|
|
||||||
class ContainerLeakDetector(Job):
|
class ContainerLeakDetector(Job):
|
||||||
|
@ -1,8 +1,21 @@
|
|||||||
# objects that report different types of leaks to the ContainerLeakDetector
|
# objects that report different types of leaks to the ContainerLeakDetector
|
||||||
|
|
||||||
class SceneGraphLeakDetector:
|
import __builtin__
|
||||||
|
|
||||||
|
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 SceneGraphLeakDetector(LeakDetector):
|
||||||
# is a scene graph leaking nodes?
|
# is a scene graph leaking nodes?
|
||||||
def __init__(self, render):
|
def __init__(self, render):
|
||||||
|
LeakDetector.__init__(self)
|
||||||
self._render = render
|
self._render = render
|
||||||
if config.GetBool('leak-scene-graph', 0):
|
if config.GetBool('leak-scene-graph', 0):
|
||||||
self._leakTaskName = 'leakNodes-%s' % serialNum()
|
self._leakTaskName = 'leakNodes-%s' % serialNum()
|
||||||
@ -11,8 +24,13 @@ class SceneGraphLeakDetector:
|
|||||||
if hasattr(self, '_leakTaskName'):
|
if hasattr(self, '_leakTaskName'):
|
||||||
taskMgr.remove(self._leakTaskName)
|
taskMgr.remove(self._leakTaskName)
|
||||||
del self._render
|
del self._render
|
||||||
|
LeakDetector.destroy(self)
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
return self._render.getNumDescendants()
|
try:
|
||||||
|
# this will be available when the build server finishes
|
||||||
|
return self._render.countNumDescendants()
|
||||||
|
except:
|
||||||
|
return self._render.getNumDescendants()
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return 'SceneGraphLeakDetector(%s)' % self._render
|
return 'SceneGraphLeakDetector(%s)' % self._render
|
||||||
def _leakNode(self, task=None):
|
def _leakNode(self, task=None):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user