mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -04:00
adding ability to find all non-cyclic reference paths for a given object
This commit is contained in:
parent
8fd806a5c9
commit
55955862aa
@ -2486,6 +2486,7 @@ def _getSafeReprNotify():
|
|||||||
global safeReprNotify
|
global safeReprNotify
|
||||||
from direct.directnotify.DirectNotifyGlobal import directNotify
|
from direct.directnotify.DirectNotifyGlobal import directNotify
|
||||||
safeReprNotify = directNotify.newCategory("safeRepr")
|
safeReprNotify = directNotify.newCategory("safeRepr")
|
||||||
|
return safeReprNotify
|
||||||
|
|
||||||
def safeRepr(obj):
|
def safeRepr(obj):
|
||||||
global dtoolSuperBase
|
global dtoolSuperBase
|
||||||
@ -4139,6 +4140,7 @@ def startSuperLog(customFunction = None):
|
|||||||
superLogFile.write( "after = %s\n"%customFunction())
|
superLogFile.write( "after = %s\n"%customFunction())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return trace_dispatch
|
return trace_dispatch
|
||||||
sys.settrace(trace_dispatch)
|
sys.settrace(trace_dispatch)
|
||||||
|
|
||||||
|
231
direct/src/showbase/ReferrerSearch.py
Executable file
231
direct/src/showbase/ReferrerSearch.py
Executable file
@ -0,0 +1,231 @@
|
|||||||
|
import inspect
|
||||||
|
import sys
|
||||||
|
import gc
|
||||||
|
from direct.showbase.PythonUtil import _getSafeReprNotify
|
||||||
|
from direct.showbase.Job import Job
|
||||||
|
|
||||||
|
class ReferrerSearch(Job):
|
||||||
|
def __init__(self, obj):
|
||||||
|
Job.__init__(self, 'ReferrerSearch')
|
||||||
|
self.obj = obj
|
||||||
|
self.found = set()
|
||||||
|
|
||||||
|
def __call__(self):
|
||||||
|
safeReprNotify = _getSafeReprNotify()
|
||||||
|
info = safeReprNotify.getInfo()
|
||||||
|
safeReprNotify.setInfo(0)
|
||||||
|
|
||||||
|
self.found = set()
|
||||||
|
try:
|
||||||
|
self.step(0, [self.obj])
|
||||||
|
finally:
|
||||||
|
self.obj = None
|
||||||
|
pass
|
||||||
|
|
||||||
|
safeReprNotify.setInfo(info)
|
||||||
|
pass
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
safeReprNotify = _getSafeReprNotify()
|
||||||
|
info = safeReprNotify.getInfo()
|
||||||
|
safeReprNotify.setInfo(0)
|
||||||
|
|
||||||
|
print 'RefPath: Beginning ReferrerSearch for', fastRepr(self.obj)
|
||||||
|
|
||||||
|
self.found = set()
|
||||||
|
for x in self.stepGenerator(0, [self.obj]):
|
||||||
|
yield None
|
||||||
|
pass
|
||||||
|
|
||||||
|
self.obj = None
|
||||||
|
pass
|
||||||
|
|
||||||
|
safeReprNotify.setInfo(info)
|
||||||
|
|
||||||
|
yield Job.Done
|
||||||
|
pass
|
||||||
|
|
||||||
|
def finished(self):
|
||||||
|
print 'RefPath: Completed ReferrerSearch for', fastRepr(self.obj)
|
||||||
|
self.obj = None
|
||||||
|
|
||||||
|
|
||||||
|
def truncateAtNewLine(self, s):
|
||||||
|
if s.find('\n') == -1:
|
||||||
|
return s
|
||||||
|
else:
|
||||||
|
return s[:s.find('\n')]
|
||||||
|
|
||||||
|
def myrepr(self, referrer, refersTo):
|
||||||
|
pre = ''
|
||||||
|
if (isinstance(referrer, dict)):
|
||||||
|
for k,v in referrer.iteritems():
|
||||||
|
if v is refersTo:
|
||||||
|
pre = self.truncateAtNewLine(fastRepr(k)) + ']-> '
|
||||||
|
break
|
||||||
|
elif (isinstance(referrer, (list, tuple))):
|
||||||
|
for x in xrange(len(referrer)):
|
||||||
|
if referrer[x] is refersTo:
|
||||||
|
pre = '%s]-> ' % (x)
|
||||||
|
break
|
||||||
|
|
||||||
|
if (isinstance(refersTo, dict)):
|
||||||
|
post = 'dict['
|
||||||
|
elif (isinstance(refersTo, list)):
|
||||||
|
post = 'list['
|
||||||
|
elif (isinstance(refersTo, tuple)):
|
||||||
|
post = 'tuple['
|
||||||
|
elif (isinstance(refersTo, set)):
|
||||||
|
post = 'set->'
|
||||||
|
else:
|
||||||
|
post = self.truncateAtNewLine(fastRepr(refersTo)) + "-> "
|
||||||
|
|
||||||
|
return '%s%s' % (pre, post)
|
||||||
|
|
||||||
|
def step(self, depth, path):
|
||||||
|
at = path[-1]
|
||||||
|
|
||||||
|
if inspect.isframe(at) or \
|
||||||
|
(isinstance(at, dict) and \
|
||||||
|
at.keys() == locals().keys()) or \
|
||||||
|
at is self.__dict__ or \
|
||||||
|
id(at) in self.found:
|
||||||
|
# don't continue down this path
|
||||||
|
return
|
||||||
|
|
||||||
|
# Now we define our 'roots'
|
||||||
|
|
||||||
|
# __builtins__
|
||||||
|
if at is __builtins__:
|
||||||
|
sys.stdout.write("RefPath: __builtins__-> ")
|
||||||
|
path = list(reversed(path))
|
||||||
|
path.insert(0,0)
|
||||||
|
for x in xrange(len(path)-1):
|
||||||
|
sys.stdout.write(self.myrepr(path[x], path[x+1]))
|
||||||
|
pass
|
||||||
|
print
|
||||||
|
return
|
||||||
|
|
||||||
|
# any module scope
|
||||||
|
if inspect.ismodule(at):
|
||||||
|
sys.stdout.write("RefPath: Module(%s)-> " % (at.__name__))
|
||||||
|
path = list(reversed(path))
|
||||||
|
for x in xrange(len(path)-1):
|
||||||
|
sys.stdout.write(self.myrepr(path[x], path[x+1]))
|
||||||
|
pass
|
||||||
|
print
|
||||||
|
return
|
||||||
|
|
||||||
|
# simbase
|
||||||
|
if at is simbase:
|
||||||
|
sys.stdout.write("RefPath: simbase-> ")
|
||||||
|
path = list(reversed(path))
|
||||||
|
path.insert(0,0)
|
||||||
|
for x in xrange(len(path)-1):
|
||||||
|
sys.stdout.write(self.myrepr(path[x], path[x+1]))
|
||||||
|
pass
|
||||||
|
print
|
||||||
|
return
|
||||||
|
|
||||||
|
# simbase.air
|
||||||
|
if at is simbase.air:
|
||||||
|
sys.stdout.write("RefPath: simbase.air-> ")
|
||||||
|
path = list(reversed(path))
|
||||||
|
path.insert(0,0)
|
||||||
|
for x in xrange(len(path)-1):
|
||||||
|
sys.stdout.write(self.myrepr(path[x], path[x+1]))
|
||||||
|
pass
|
||||||
|
print
|
||||||
|
return
|
||||||
|
|
||||||
|
self.found.add(id(at))
|
||||||
|
|
||||||
|
referrers = gc.get_referrers(at)
|
||||||
|
while(referrers):
|
||||||
|
ref = referrers.pop()
|
||||||
|
if (ref != path):
|
||||||
|
self.step(depth + 1, path + [ref])
|
||||||
|
pass
|
||||||
|
pass
|
||||||
|
pass
|
||||||
|
|
||||||
|
def stepGenerator(self, depth, path):
|
||||||
|
at = path[-1]
|
||||||
|
|
||||||
|
if inspect.isframe(at) or \
|
||||||
|
(isinstance(at, dict) and \
|
||||||
|
at.keys() == locals().keys()) or \
|
||||||
|
at is self.__dict__ or \
|
||||||
|
id(at) in self.found:
|
||||||
|
# don't continue down this path
|
||||||
|
raise StopIteration
|
||||||
|
|
||||||
|
# Now we define our 'roots'
|
||||||
|
|
||||||
|
# __builtins__
|
||||||
|
if at is __builtins__:
|
||||||
|
sys.stdout.write("RefPath: __builtins__-> ")
|
||||||
|
path = list(reversed(path))
|
||||||
|
path.insert(0,0)
|
||||||
|
for x in xrange(len(path)-1):
|
||||||
|
sys.stdout.write(self.myrepr(path[x], path[x+1]))
|
||||||
|
pass
|
||||||
|
print
|
||||||
|
raise StopIteration
|
||||||
|
|
||||||
|
# any module scope
|
||||||
|
if inspect.ismodule(at):
|
||||||
|
sys.stdout.write("RefPath: Module(%s)-> " % (at.__name__))
|
||||||
|
path = list(reversed(path))
|
||||||
|
for x in xrange(len(path)-1):
|
||||||
|
sys.stdout.write(self.myrepr(path[x], path[x+1]))
|
||||||
|
pass
|
||||||
|
print
|
||||||
|
raise StopIteration
|
||||||
|
|
||||||
|
# simbase
|
||||||
|
if at is simbase:
|
||||||
|
sys.stdout.write("RefPath: simbase-> ")
|
||||||
|
path = list(reversed(path))
|
||||||
|
path.insert(0,0)
|
||||||
|
for x in xrange(len(path)-1):
|
||||||
|
sys.stdout.write(self.myrepr(path[x], path[x+1]))
|
||||||
|
pass
|
||||||
|
print
|
||||||
|
raise StopIteration
|
||||||
|
|
||||||
|
# simbase.air
|
||||||
|
if at is simbase.air:
|
||||||
|
sys.stdout.write("RefPath: simbase.air-> ")
|
||||||
|
path = list(reversed(path))
|
||||||
|
path.insert(0,0)
|
||||||
|
for x in xrange(len(path)-1):
|
||||||
|
sys.stdout.write(self.myrepr(path[x], path[x+1]))
|
||||||
|
pass
|
||||||
|
print
|
||||||
|
raise StopIteration
|
||||||
|
|
||||||
|
self.found.add(id(at))
|
||||||
|
|
||||||
|
referrers = gc.get_referrers(at)
|
||||||
|
while(referrers):
|
||||||
|
ref = referrers.pop()
|
||||||
|
if (ref != path):
|
||||||
|
for x in self.stepGenerator(depth + 1, path + [ref]):
|
||||||
|
yield None
|
||||||
|
pass
|
||||||
|
pass
|
||||||
|
|
||||||
|
yield None
|
||||||
|
pass
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
from direct.showbase.ReferrerSearch import ReferrerSearch
|
||||||
|
door = simbase.air.doFind("DistributedBuildingDoorAI")
|
||||||
|
class A: pass
|
||||||
|
door = A()
|
||||||
|
ReferrerSearch()(door)
|
||||||
|
reload(ReferrerSearch); from direct.showbase.PythonUtil import ReferrerSearch
|
||||||
|
"""
|
Loading…
x
Reference in New Issue
Block a user