mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
added Python syntax version of cycles
This commit is contained in:
parent
7cb642fc2f
commit
b8523833f7
@ -6,6 +6,7 @@ from direct.directnotify.DirectNotifyGlobal import directNotify
|
|||||||
from direct.showbase.PythonUtil import gcDebugOn, safeRepr, fastRepr, printListEnumGen, printNumberedTypesGen
|
from direct.showbase.PythonUtil import gcDebugOn, safeRepr, fastRepr, printListEnumGen, printNumberedTypesGen
|
||||||
from direct.showbase.Job import Job
|
from direct.showbase.Job import Job
|
||||||
import gc
|
import gc
|
||||||
|
import types
|
||||||
|
|
||||||
class FakeObject:
|
class FakeObject:
|
||||||
pass
|
pass
|
||||||
@ -89,6 +90,7 @@ class GarbageReport(Job):
|
|||||||
self.referentsByNumber = {}
|
self.referentsByNumber = {}
|
||||||
|
|
||||||
self.cycles = []
|
self.cycles = []
|
||||||
|
self.cyclesBySyntax = []
|
||||||
self.uniqueCycleSets = set()
|
self.uniqueCycleSets = set()
|
||||||
self.cycleIds = set()
|
self.cycleIds = set()
|
||||||
|
|
||||||
@ -131,6 +133,85 @@ class GarbageReport(Job):
|
|||||||
for newCycles in self._getCycles(i, self.uniqueCycleSets):
|
for newCycles in self._getCycles(i, self.uniqueCycleSets):
|
||||||
yield None
|
yield None
|
||||||
self.cycles.extend(newCycles)
|
self.cycles.extend(newCycles)
|
||||||
|
# create a representation of the cycle in human-readable form
|
||||||
|
newCyclesBySyntax = []
|
||||||
|
for cycle in newCycles:
|
||||||
|
cycleBySyntax = ''
|
||||||
|
objs = []
|
||||||
|
# leave off the last index, it's a repeat of the first index
|
||||||
|
for index in cycle[:-1]:
|
||||||
|
objs.append(self.garbage[index])
|
||||||
|
yield None
|
||||||
|
# make the list repeat so we can safely iterate off the end
|
||||||
|
numObjs = len(objs) - 1
|
||||||
|
objs.extend(objs)
|
||||||
|
|
||||||
|
# state variables for our loop below
|
||||||
|
numToSkip = 0
|
||||||
|
objAlreadyRepresented = False
|
||||||
|
|
||||||
|
# if cycle starts off with an instance dict, start with the instance instead
|
||||||
|
startIndex = 0
|
||||||
|
endIndex = numObjs
|
||||||
|
if type(objs[-1]) is types.InstanceType:
|
||||||
|
startIndex = -1
|
||||||
|
endIndex = numObjs - 1
|
||||||
|
|
||||||
|
for index in xrange(startIndex, endIndex):
|
||||||
|
if numToSkip:
|
||||||
|
numToSkip -= 1
|
||||||
|
continue
|
||||||
|
obj = objs[index]
|
||||||
|
if type(obj) is types.InstanceType:
|
||||||
|
if not objAlreadyRepresented:
|
||||||
|
cycleBySyntax += '%s' % obj.__class__.__name__
|
||||||
|
cycleBySyntax += '.'
|
||||||
|
# skip past the instance dict and get the member obj
|
||||||
|
numToSkip += 1
|
||||||
|
member = objs[index+2]
|
||||||
|
for key, value in obj.__dict__.iteritems():
|
||||||
|
if value is member:
|
||||||
|
break
|
||||||
|
yield None
|
||||||
|
else:
|
||||||
|
key = '<unknown member name>'
|
||||||
|
cycleBySyntax += '%s' % key
|
||||||
|
objAlreadyRepresented = True
|
||||||
|
elif type(obj) is types.DictType:
|
||||||
|
cycleBySyntax += '{'
|
||||||
|
# get object referred to by dict
|
||||||
|
val = objs[index+1]
|
||||||
|
for key, value in obj.iteritems():
|
||||||
|
if value is val:
|
||||||
|
break
|
||||||
|
yield None
|
||||||
|
else:
|
||||||
|
key = '<unknown key>'
|
||||||
|
cycleBySyntax += '%s}' % fastRepr(key)
|
||||||
|
objAlreadyRepresented = True
|
||||||
|
elif type(obj) in (types.TupleType, types.ListType):
|
||||||
|
brackets = {
|
||||||
|
types.TupleType: '()',
|
||||||
|
types.ListType: '[]',
|
||||||
|
}[type(obj)]
|
||||||
|
# get object being referenced by container
|
||||||
|
nextObj = objs[index+1]
|
||||||
|
cycleBySyntax += brackets[0]
|
||||||
|
for index in xrange(len(obj)):
|
||||||
|
if obj[index] is nextObj:
|
||||||
|
index = str(index)
|
||||||
|
break
|
||||||
|
yield None
|
||||||
|
else:
|
||||||
|
index = '<unknown index>'
|
||||||
|
cycleBySyntax += '%s%s' % (index, brackets[1])
|
||||||
|
objAlreadyRepresented = True
|
||||||
|
else:
|
||||||
|
cycleBySyntax += '%s->' % itype(obj)
|
||||||
|
objAlreadyRepresented = False
|
||||||
|
newCyclesBySyntax.append(cycleBySyntax)
|
||||||
|
yield None
|
||||||
|
self.cyclesBySyntax.extend(newCyclesBySyntax)
|
||||||
# if we're not doing a full report, add this cycle's IDs to the master set
|
# if we're not doing a full report, add this cycle's IDs to the master set
|
||||||
if not self._args.fullReport:
|
if not self._args.fullReport:
|
||||||
for cycle in newCycles:
|
for cycle in newCycles:
|
||||||
@ -194,11 +275,17 @@ class GarbageReport(Job):
|
|||||||
s.append(format % (idx, itype(self.garbage[idx]), objStr))
|
s.append(format % (idx, itype(self.garbage[idx]), objStr))
|
||||||
|
|
||||||
if self._args.findCycles:
|
if self._args.findCycles:
|
||||||
s.append('===== Garbage Cycles =====')
|
s.append('===== Garbage Cycles By Index =====')
|
||||||
for i in xrange(len(self.cycles)):
|
for i in xrange(len(self.cycles)):
|
||||||
yield None
|
yield None
|
||||||
s.append('%s' % self.cycles[i])
|
s.append('%s' % self.cycles[i])
|
||||||
|
|
||||||
|
if self._args.findCycles:
|
||||||
|
s.append('===== Garbage Cycles By Python Syntax =====')
|
||||||
|
for i in xrange(len(self.cyclesBySyntax)):
|
||||||
|
yield None
|
||||||
|
s.append('%s' % self.cyclesBySyntax[i])
|
||||||
|
|
||||||
if self._args.fullReport:
|
if self._args.fullReport:
|
||||||
format = '%0' + '%s' % digits + 'i:%s'
|
format = '%0' + '%s' % digits + 'i:%s'
|
||||||
s.append('===== Referrers By Number (what is referring to garbage item?) =====')
|
s.append('===== Referrers By Number (what is referring to garbage item?) =====')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user