mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
Dramatically reduce size of frozen/compiled code by pruning/masking unnecessary imports/code
This commit is contained in:
parent
591ce04ab1
commit
0d03207d1b
@ -41,7 +41,9 @@ only when debugging (i.e. when it won't be checked-in) or where it helps
|
||||
you resist using assert for error handling.
|
||||
"""
|
||||
|
||||
wantVerifyPdb = 0 # Set to true to load pdb on failure.
|
||||
from panda3d.core import ConfigVariableBool
|
||||
|
||||
wantVerifyPdb = ConfigVariableBool('want-verify-pdb', False) # Set to true to load pdb on failure.
|
||||
|
||||
|
||||
def verify(assertion):
|
||||
|
@ -12,7 +12,6 @@ from OnscreenImage import *
|
||||
from direct.directtools.DirectUtil import ROUND_TO
|
||||
from direct.showbase import DirectObject
|
||||
from direct.task import Task
|
||||
from direct.showbase.PythonUtil import recordCreationStackStr
|
||||
import types
|
||||
|
||||
guiObjectCollector = PStatCollector("Client::GuiObjects")
|
||||
@ -651,13 +650,6 @@ def toggleGuiGridSnap():
|
||||
def setGuiGridSpacing(spacing):
|
||||
DirectGuiWidget.gridSpacing = spacing
|
||||
|
||||
# this should trigger off of __dev__, but it's not available at this point.
|
||||
# __debug__ works because the production client is not __debug__ and the
|
||||
# production AI doesn't create any GUI.
|
||||
if get_config_showbase().GetBool('record-gui-creation-stack', __debug__):
|
||||
# this will help track down the code that created DirectGui objects
|
||||
# call obj.printCreationStackTrace() to figure out what code created it
|
||||
DirectGuiBase = recordCreationStackStr(DirectGuiBase)
|
||||
|
||||
class DirectGuiWidget(DirectGuiBase, NodePath):
|
||||
# Toggle if you wish widget's to snap to grid when draggin
|
||||
|
@ -72,13 +72,6 @@ class ProjectileInterval(Interval):
|
||||
self.projectileIntervalNum)
|
||||
ProjectileInterval.projectileIntervalNum += 1
|
||||
|
||||
"""
|
||||
# attempt to add info about the caller
|
||||
file, line, func = PythonUtil.callerInfo()
|
||||
if file is not None:
|
||||
name += '-%s:%s:%s' % (file, line, func)
|
||||
"""
|
||||
|
||||
args = (startPos, endPos, duration, startVel, endZ,
|
||||
wayPoint, timeToWayPoint, gravityMult)
|
||||
self.implicitStartPos = 0
|
||||
|
@ -1,4 +1,5 @@
|
||||
from panda3d.direct import get_config_showbase
|
||||
__all__ = ["install"]
|
||||
|
||||
from direct.directnotify.DirectNotifyGlobal import directNotify
|
||||
from direct.showbase.PythonUtil import fastRepr
|
||||
import sys
|
||||
@ -6,7 +7,6 @@ import types
|
||||
import traceback
|
||||
|
||||
notify = directNotify.newCategory("ExceptionVarDump")
|
||||
config = get_config_showbase()
|
||||
|
||||
reentry = 0
|
||||
|
||||
@ -187,7 +187,7 @@ def install(log, upload):
|
||||
wantStackDumpLog = log
|
||||
wantStackDumpUpload = upload
|
||||
|
||||
dumpOnExceptionInit = config.GetBool('variable-dump-on-exception-init', 0)
|
||||
dumpOnExceptionInit = ConfigVariableBool('variable-dump-on-exception-init', False)
|
||||
if dumpOnExceptionInit:
|
||||
# this mode doesn't completely work because exception objects
|
||||
# thrown by the interpreter don't get created until the
|
||||
|
@ -281,7 +281,7 @@ class GarbageReport(Job):
|
||||
if self._args.findCycles:
|
||||
s = ['===== GarbageReport: \'%s\' (%s %s) =====' % (
|
||||
self._args.name, self.numCycles,
|
||||
choice(self.numCycles == 1, 'cycle', 'cycles'))]
|
||||
('cycle' if self.numCycles == 1 else 'cycles'))]
|
||||
else:
|
||||
s = ['===== GarbageReport: \'%s\' =====' % (
|
||||
self._args.name)]
|
||||
@ -499,7 +499,7 @@ class GarbageReport(Job):
|
||||
rootId = index
|
||||
# check if the root object is one of the garbage instances (has __del__)
|
||||
objId = id(self.garbage[rootId])
|
||||
numDelInstances = choice(objId in self.garbageInstanceIds, 1, 0)
|
||||
numDelInstances = int(objId in self.garbageInstanceIds)
|
||||
stateStack.push(([rootId], rootId, numDelInstances, 0))
|
||||
while True:
|
||||
yield None
|
||||
@ -535,7 +535,7 @@ class GarbageReport(Job):
|
||||
elif refId is not None:
|
||||
# check if this object is one of the garbage instances (has __del__)
|
||||
objId = id(self.garbage[refId])
|
||||
numDelInstances += choice(objId in self.garbageInstanceIds, 1, 0)
|
||||
numDelInstances += int(objId in self.garbageInstanceIds)
|
||||
# this refId does not complete a cycle. Mark down
|
||||
# where we are in this list of referents, then
|
||||
# start looking through the referents of the new refId
|
||||
|
@ -5,7 +5,6 @@ __all__ = ['Diff', 'ObjectPool']
|
||||
from direct.directnotify.DirectNotifyGlobal import directNotify
|
||||
from direct.showbase.PythonUtil import invertDictLossless, makeList, safeRepr
|
||||
from direct.showbase.PythonUtil import getNumberedTypedString, getNumberedTypedSortedString
|
||||
from direct.showbase.PythonUtil import getNumberedTypedSortedStringWithReferrersGen
|
||||
import gc
|
||||
|
||||
class Diff:
|
||||
@ -97,7 +96,7 @@ class ObjectPool:
|
||||
s += '\n%s\t%s' % (count, typ)
|
||||
return s
|
||||
|
||||
def printObjsByType(self, printReferrers=False):
|
||||
def printObjsByType(self):
|
||||
print 'Object Pool: Objects By Type'
|
||||
print '\n============================'
|
||||
counts = list(set(self._count2types.keys()))
|
||||
@ -109,10 +108,6 @@ class ObjectPool:
|
||||
types = makeList(self._count2types[count])
|
||||
for typ in types:
|
||||
print 'TYPE: %s, %s objects' % (repr(typ), len(self._type2objs[typ]))
|
||||
if printReferrers:
|
||||
for line in getNumberedTypedSortedStringWithReferrersGen(self._type2objs[typ]):
|
||||
print line
|
||||
else:
|
||||
print getNumberedTypedSortedString(self._type2objs[typ])
|
||||
|
||||
def containerLenStr(self):
|
||||
|
@ -1,18 +1,14 @@
|
||||
|
||||
"""Undocumented Module"""
|
||||
"""Contains miscellaneous utility functions and classes."""
|
||||
|
||||
__all__ = ['indent',
|
||||
'StackTrace', 'traceFunctionCall', 'traceParentCall', 'printThisCall',
|
||||
'doc', 'adjust', 'difference', 'intersection', 'union',
|
||||
'sameElements', 'makeList', 'makeTuple', 'list2dict', 'invertDict',
|
||||
'invertDictLossless', 'uniqueElements', 'disjoint', 'contains',
|
||||
'replace', 'reduceAngle', 'fitSrcAngle2Dest', 'fitDestAngle2Src',
|
||||
'closestDestAngle2', 'closestDestAngle', 'binaryRepr', 'profileFunc',
|
||||
'profiled', 'startProfile', 'printProfile', 'getSetterName',
|
||||
'closestDestAngle2', 'closestDestAngle', 'getSetterName',
|
||||
'getSetter', 'Functor', 'Stack', 'Queue',
|
||||
'bound', 'clamp', 'lerp', 'average', 'addListsByValue',
|
||||
'boolEqual', 'lineupPos', 'formatElapsedSeconds', 'solveQuadratic',
|
||||
'stackEntryInfo', 'lineInfo', 'callerInfo', 'lineTag',
|
||||
'findPythonModule', 'mostDerivedLast',
|
||||
'weightedChoice', 'randFloat', 'normalDistrib',
|
||||
'weightedRand', 'randUint31', 'randInt32', 'randUint32',
|
||||
@ -20,41 +16,36 @@ __all__ = ['indent',
|
||||
'SingletonError', 'printListEnum', 'safeRepr',
|
||||
'fastRepr', 'isDefaultValue',
|
||||
'ScratchPad', 'Sync', 'itype', 'getNumberedTypedString',
|
||||
'getNumberedTypedSortedString', 'getNumberedTypedSortedStringWithReferrers',
|
||||
'getNumberedTypedSortedStringWithReferrersGen',
|
||||
'getNumberedTypedSortedString',
|
||||
'printNumberedTyped', 'DelayedCall', 'DelayedFunctor',
|
||||
'FrameDelayedCall', 'SubframeCall', 'getBase',
|
||||
'HotkeyBreaker','logMethodCalls','GoldenRatio',
|
||||
'FrameDelayedCall', 'SubframeCall', 'getBase', 'GoldenRatio',
|
||||
'GoldenRectangle', 'rad90', 'rad180', 'rad270', 'rad360',
|
||||
'nullGen', 'loopGen', 'makeFlywheelGen', 'flywheel', 'choice',
|
||||
'printStack', 'printReverseStack', 'listToIndex2item', 'listToItem2index',
|
||||
'pandaBreak','pandaTrace','formatTimeCompact',
|
||||
'deeptype','getProfileResultString','StdoutCapture','StdoutPassthrough',
|
||||
'nullGen', 'loopGen', 'makeFlywheelGen', 'flywheel',
|
||||
'listToIndex2item', 'listToItem2index',
|
||||
'formatTimeCompact','deeptype','StdoutCapture','StdoutPassthrough',
|
||||
'Averager', 'getRepository', 'formatTimeExact', 'startSuperLog', 'endSuperLog',
|
||||
'typeName', 'safeTypeName', 'histogramDict', 'unescapeHtmlString']
|
||||
|
||||
if __debug__:
|
||||
__all__ += ['StackTrace', 'traceFunctionCall', 'traceParentCall', 'printThisCall',
|
||||
'stackEntryInfo', 'lineInfo', 'callerInfo', 'lineTag',
|
||||
'profileFunc', 'profiled', 'startProfile', 'printProfile',
|
||||
'getProfileResultString', 'printStack', 'printReverseStack']
|
||||
|
||||
import types
|
||||
import string
|
||||
import math
|
||||
import operator
|
||||
import inspect
|
||||
import os
|
||||
import sys
|
||||
import random
|
||||
import time
|
||||
import gc
|
||||
#if __debug__:
|
||||
import traceback
|
||||
import __builtin__
|
||||
from StringIO import StringIO
|
||||
import marshal
|
||||
import importlib
|
||||
|
||||
__report_indent = 3
|
||||
|
||||
from panda3d.core import ConfigVariableBool
|
||||
|
||||
ScalarTypes = (types.FloatType, types.IntType, types.LongType)
|
||||
|
||||
"""
|
||||
# with one integer positional arg, this uses about 4/5 of the memory of the Functor class below
|
||||
def Functor(function, *args, **kArgs):
|
||||
@ -92,15 +83,6 @@ class Functor:
|
||||
_kargs.update(kargs)
|
||||
return self._function(*(self._args + args), **_kargs)
|
||||
|
||||
# this method is used in place of __call__ if we are recording creation stacks
|
||||
def _exceptionLoggedCreationStack__call__(self, *args, **kargs):
|
||||
try:
|
||||
return self._do__call__(*args, **kargs)
|
||||
except Exception, e:
|
||||
print '-->Functor creation stack (%s): %s' % (
|
||||
self.__name__, self.getCreationStackTraceCompactStr())
|
||||
raise
|
||||
|
||||
__call__ = _do__call__
|
||||
|
||||
def __repr__(self):
|
||||
@ -186,11 +168,11 @@ def indent(stream, numIndents, str):
|
||||
stream.write(' ' * numIndents + str)
|
||||
|
||||
|
||||
#if __debug__: #RAU accdg to Darren its's ok that StackTrace is not protected by __debug__
|
||||
# DCR: if somebody ends up using StackTrace in production, either
|
||||
# A) it will be OK because it hardly ever gets called, or
|
||||
# B) it will be easy to track it down (grep for StackTrace)
|
||||
class StackTrace:
|
||||
if __debug__:
|
||||
import traceback
|
||||
import marshal
|
||||
|
||||
class StackTrace:
|
||||
def __init__(self, label="", start=0, limit=None):
|
||||
"""
|
||||
label is a string (or anything that be be a string)
|
||||
@ -237,19 +219,19 @@ class StackTrace:
|
||||
r+="***** NOTE: This is not a crash. This is a debug stack trace. *****"
|
||||
return r
|
||||
|
||||
def printStack():
|
||||
def printStack():
|
||||
print StackTrace(start=1).compact()
|
||||
return True
|
||||
def printReverseStack():
|
||||
def printReverseStack():
|
||||
print StackTrace(start=1).reverseCompact()
|
||||
return True
|
||||
def printVerboseStack():
|
||||
def printVerboseStack():
|
||||
print StackTrace(start=1)
|
||||
return True
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
def traceFunctionCall(frame):
|
||||
def traceFunctionCall(frame):
|
||||
"""
|
||||
return a string that shows the call frame with calling arguments.
|
||||
e.g.
|
||||
@ -287,10 +269,10 @@ def traceFunctionCall(frame):
|
||||
else: r+="*** undefined ***"
|
||||
return r+')'
|
||||
|
||||
def traceParentCall():
|
||||
def traceParentCall():
|
||||
return traceFunctionCall(sys._getframe(2))
|
||||
|
||||
def printThisCall():
|
||||
def printThisCall():
|
||||
print traceFunctionCall(sys._getframe(1))
|
||||
return 1 # to allow "assert printThisCall()"
|
||||
|
||||
@ -327,7 +309,6 @@ def adjust(command = None, dim = 1, parent = None, **kw):
|
||||
# Make sure we enable Tk
|
||||
# Don't use a regular import, to prevent ModuleFinder from picking
|
||||
# it up as a dependency when building a .p3d package.
|
||||
import importlib
|
||||
Valuator = importlib.import_module('direct.tkwidgets.Valuator')
|
||||
# Set command if specified
|
||||
if command:
|
||||
@ -579,19 +560,6 @@ def closestDestAngle(src, dest):
|
||||
# otherwise just go to the original destination
|
||||
return dest
|
||||
|
||||
|
||||
def binaryRepr(number, max_length = 32):
|
||||
# This will only work reliably for relatively small numbers.
|
||||
# Increase the value of max_length if you think you're going
|
||||
# to use long integers
|
||||
assert number < 2L << max_length
|
||||
shifts = map (operator.rshift, max_length * [number], \
|
||||
range (max_length - 1, -1, -1))
|
||||
digits = map (operator.mod, shifts, max_length * [2])
|
||||
if not digits.count (1): return 0
|
||||
digits = digits [digits.index (1):]
|
||||
return ''.join([repr(digit) for digit in digits])
|
||||
|
||||
class StdoutCapture:
|
||||
# redirects stdout to a string
|
||||
def __init__(self):
|
||||
@ -618,20 +586,23 @@ class StdoutPassthrough(StdoutCapture):
|
||||
self._oldStdout.write(string)
|
||||
|
||||
# constant profile defaults
|
||||
PyUtilProfileDefaultFilename = 'profiledata'
|
||||
PyUtilProfileDefaultLines = 80
|
||||
PyUtilProfileDefaultSorts = ['cumulative', 'time', 'calls']
|
||||
if __debug__:
|
||||
from StringIO import StringIO
|
||||
|
||||
_ProfileResultStr = ''
|
||||
PyUtilProfileDefaultFilename = 'profiledata'
|
||||
PyUtilProfileDefaultLines = 80
|
||||
PyUtilProfileDefaultSorts = ['cumulative', 'time', 'calls']
|
||||
|
||||
def getProfileResultString():
|
||||
_ProfileResultStr = ''
|
||||
|
||||
def getProfileResultString():
|
||||
# if you called profile with 'log' not set to True,
|
||||
# you can call this function to get the results as
|
||||
# a string
|
||||
global _ProfileResultStr
|
||||
return _ProfileResultStr
|
||||
|
||||
def profileFunc(callback, name, terse, log=True):
|
||||
def profileFunc(callback, name, terse, log=True):
|
||||
global _ProfileResultStr
|
||||
if 'globalProfileFunc' in __builtin__.__dict__:
|
||||
# rats. Python profiler is not re-entrant...
|
||||
@ -658,7 +629,7 @@ def profileFunc(callback, name, terse, log=True):
|
||||
del __builtin__.__dict__['globalProfileResult']
|
||||
return result
|
||||
|
||||
def profiled(category=None, terse=False):
|
||||
def profiled(category=None, terse=False):
|
||||
""" decorator for profiling functions
|
||||
turn categories on and off via "want-profile-categoryName 1"
|
||||
|
||||
@ -701,16 +672,16 @@ def profiled(category=None, terse=False):
|
||||
return _profiled
|
||||
return profileDecorator
|
||||
|
||||
# intercept profile-related file operations to avoid disk access
|
||||
movedOpenFuncs = []
|
||||
movedDumpFuncs = []
|
||||
movedLoadFuncs = []
|
||||
profileFilenames = set()
|
||||
profileFilenameList = Stack()
|
||||
profileFilename2file = {}
|
||||
profileFilename2marshalData = {}
|
||||
# intercept profile-related file operations to avoid disk access
|
||||
movedOpenFuncs = []
|
||||
movedDumpFuncs = []
|
||||
movedLoadFuncs = []
|
||||
profileFilenames = set()
|
||||
profileFilenameList = Stack()
|
||||
profileFilename2file = {}
|
||||
profileFilename2marshalData = {}
|
||||
|
||||
def _profileOpen(filename, *args, **kArgs):
|
||||
def _profileOpen(filename, *args, **kArgs):
|
||||
# this is a replacement for the file open() builtin function
|
||||
# for use during profiling, to intercept the file open
|
||||
# operation used by the Python profiler and profile stats
|
||||
@ -728,7 +699,7 @@ def _profileOpen(filename, *args, **kArgs):
|
||||
file = movedOpenFuncs[-1](filename, *args, **kArgs)
|
||||
return file
|
||||
|
||||
def _profileMarshalDump(data, file):
|
||||
def _profileMarshalDump(data, file):
|
||||
# marshal.dump doesn't work with StringIO objects
|
||||
# simulate it
|
||||
if isinstance(file, StringIO) and hasattr(file, '_profFilename'):
|
||||
@ -737,7 +708,7 @@ def _profileMarshalDump(data, file):
|
||||
return None
|
||||
return movedDumpFuncs[-1](data, file)
|
||||
|
||||
def _profileMarshalLoad(file):
|
||||
def _profileMarshalLoad(file):
|
||||
# marshal.load doesn't work with StringIO objects
|
||||
# simulate it
|
||||
if isinstance(file, StringIO) and hasattr(file, '_profFilename'):
|
||||
@ -745,7 +716,7 @@ def _profileMarshalLoad(file):
|
||||
return profileFilename2marshalData[file._profFilename]
|
||||
return movedLoadFuncs[-1](file)
|
||||
|
||||
def _installProfileCustomFuncs(filename):
|
||||
def _installProfileCustomFuncs(filename):
|
||||
assert filename not in profileFilenames
|
||||
profileFilenames.add(filename)
|
||||
profileFilenameList.push(filename)
|
||||
@ -756,22 +727,22 @@ def _installProfileCustomFuncs(filename):
|
||||
movedLoadFuncs.append(marshal.load)
|
||||
marshal.load = _profileMarshalLoad
|
||||
|
||||
def _getProfileResultFileInfo(filename):
|
||||
def _getProfileResultFileInfo(filename):
|
||||
return (profileFilename2file.get(filename, None),
|
||||
profileFilename2marshalData.get(filename, None))
|
||||
|
||||
def _setProfileResultsFileInfo(filename, info):
|
||||
def _setProfileResultsFileInfo(filename, info):
|
||||
f, m = info
|
||||
if f:
|
||||
profileFilename2file[filename] = f
|
||||
if m:
|
||||
profileFilename2marshalData[filename] = m
|
||||
|
||||
def _clearProfileResultFileInfo(filename):
|
||||
def _clearProfileResultFileInfo(filename):
|
||||
profileFilename2file.pop(filename, None)
|
||||
profileFilename2marshalData.pop(filename, None)
|
||||
|
||||
def _removeProfileCustomFuncs(filename):
|
||||
def _removeProfileCustomFuncs(filename):
|
||||
assert profileFilenameList.top() == filename
|
||||
marshal.load = movedLoadFuncs.pop()
|
||||
marshal.dump = movedDumpFuncs.pop()
|
||||
@ -783,21 +754,21 @@ def _removeProfileCustomFuncs(filename):
|
||||
profileFilename2marshalData.pop(filename, None)
|
||||
|
||||
|
||||
# call this from the prompt, and break back out to the prompt
|
||||
# to stop profiling
|
||||
#
|
||||
# OR to do inline profiling, you must make a globally-visible
|
||||
# function to be profiled, i.e. to profile 'self.load()', do
|
||||
# something like this:
|
||||
#
|
||||
# def func(self=self):
|
||||
# self.load()
|
||||
# import __builtin__
|
||||
# __builtin__.func = func
|
||||
# PythonUtil.startProfile(cmd='func()', filename='profileData')
|
||||
# del __builtin__.func
|
||||
#
|
||||
def _profileWithoutGarbageLeak(cmd, filename):
|
||||
# call this from the prompt, and break back out to the prompt
|
||||
# to stop profiling
|
||||
#
|
||||
# OR to do inline profiling, you must make a globally-visible
|
||||
# function to be profiled, i.e. to profile 'self.load()', do
|
||||
# something like this:
|
||||
#
|
||||
# def func(self=self):
|
||||
# self.load()
|
||||
# import __builtin__
|
||||
# __builtin__.func = func
|
||||
# PythonUtil.startProfile(cmd='func()', filename='profileData')
|
||||
# del __builtin__.func
|
||||
#
|
||||
def _profileWithoutGarbageLeak(cmd, filename):
|
||||
# The profile module isn't necessarily installed on every Python
|
||||
# installation, so we import it here, instead of in the module
|
||||
# scope.
|
||||
@ -823,7 +794,7 @@ def _profileWithoutGarbageLeak(cmd, filename):
|
||||
del prof.dispatcher
|
||||
return retVal
|
||||
|
||||
def startProfile(filename=PyUtilProfileDefaultFilename,
|
||||
def startProfile(filename=PyUtilProfileDefaultFilename,
|
||||
lines=PyUtilProfileDefaultLines,
|
||||
sorts=PyUtilProfileDefaultSorts,
|
||||
silent=0,
|
||||
@ -846,8 +817,8 @@ def startProfile(filename=PyUtilProfileDefaultFilename,
|
||||
else:
|
||||
os.remove(filename)
|
||||
|
||||
# call these to see the results again, as a string or in the log
|
||||
def printProfile(filename=PyUtilProfileDefaultFilename,
|
||||
# call these to see the results again, as a string or in the log
|
||||
def printProfile(filename=PyUtilProfileDefaultFilename,
|
||||
lines=PyUtilProfileDefaultLines,
|
||||
sorts=PyUtilProfileDefaultSorts,
|
||||
callInfo=1):
|
||||
@ -861,8 +832,8 @@ def printProfile(filename=PyUtilProfileDefaultFilename,
|
||||
s.print_callees(lines)
|
||||
s.print_callers(lines)
|
||||
|
||||
# same args as printProfile
|
||||
def extractProfile(*args, **kArgs):
|
||||
# same args as printProfile
|
||||
def extractProfile(*args, **kArgs):
|
||||
global _ProfileResultStr
|
||||
# capture print output
|
||||
sc = StdoutCapture()
|
||||
@ -1032,7 +1003,8 @@ def solveQuadratic(a, b, c):
|
||||
root2 = ((-b) + sqrtD) / twoA
|
||||
return [root1, root2]
|
||||
|
||||
def stackEntryInfo(depth=0, baseFileName=1):
|
||||
if __debug__:
|
||||
def stackEntryInfo(depth=0, baseFileName=1):
|
||||
"""
|
||||
returns the sourcefilename, line number, and function name of
|
||||
an entry in the stack.
|
||||
@ -1042,6 +1014,8 @@ def stackEntryInfo(depth=0, baseFileName=1):
|
||||
returns (fileName, lineNum, funcName) --> (string, int, string)
|
||||
returns (None, None, None) on error
|
||||
"""
|
||||
import inspect
|
||||
|
||||
try:
|
||||
stack = None
|
||||
frame = None
|
||||
@ -1063,7 +1037,7 @@ def stackEntryInfo(depth=0, baseFileName=1):
|
||||
|
||||
return result
|
||||
|
||||
def lineInfo(baseFileName=1):
|
||||
def lineInfo(baseFileName=1):
|
||||
"""
|
||||
returns the sourcefilename, line number, and function name of the
|
||||
code that called this function
|
||||
@ -1072,7 +1046,7 @@ def lineInfo(baseFileName=1):
|
||||
"""
|
||||
return stackEntryInfo(1, baseFileName)
|
||||
|
||||
def callerInfo(baseFileName=1, howFarBack=0):
|
||||
def callerInfo(baseFileName=1, howFarBack=0):
|
||||
"""
|
||||
returns the sourcefilename, line number, and function name of the
|
||||
caller of the function that called this function
|
||||
@ -1081,7 +1055,7 @@ def callerInfo(baseFileName=1, howFarBack=0):
|
||||
"""
|
||||
return stackEntryInfo(2+howFarBack, baseFileName)
|
||||
|
||||
def lineTag(baseFileName=1, verbose=0, separator=':'):
|
||||
def lineTag(baseFileName=1, verbose=0, separator=':'):
|
||||
"""
|
||||
returns a string containing the sourcefilename and line number
|
||||
of the code that called this function
|
||||
@ -1756,43 +1730,6 @@ def getNumberedTypedSortedString(items, maxLen=5000, numPrefix=''):
|
||||
s += format % (i, itype(items[i]), strs[i])
|
||||
return s
|
||||
|
||||
def getNumberedTypedSortedStringWithReferrersGen(items, maxLen=10000, numPrefix=''):
|
||||
"""get a string that has each item of the list on its own line,
|
||||
the items are stringwise-sorted, the object's referrers are shown,
|
||||
and each item is numbered on the left from zero"""
|
||||
digits = 0
|
||||
n = len(items)
|
||||
while n > 0:
|
||||
digits += 1
|
||||
n //= 10
|
||||
digits = digits
|
||||
format = numPrefix + '%0' + '%s' % digits + 'i:%s @ %s \t%s'
|
||||
snip = '<SNIP>'
|
||||
strs = []
|
||||
for item in items:
|
||||
strs.append(fastRepr(item))
|
||||
strs.sort()
|
||||
for i in xrange(len(strs)):
|
||||
item = items[i]
|
||||
objStr = strs[i]
|
||||
objStr += ', \tREFERRERS=['
|
||||
referrers = gc.get_referrers(item)
|
||||
for ref in referrers:
|
||||
objStr += '%s@%s, ' % (itype(ref), id(ref))
|
||||
objStr += ']'
|
||||
if len(objStr) > maxLen:
|
||||
objStr = '%s%s' % (objStr[:(maxLen-len(snip))], snip)
|
||||
yield format % (i, itype(items[i]), id(items[i]), objStr)
|
||||
|
||||
def getNumberedTypedSortedStringWithReferrers(items, maxLen=10000, numPrefix=''):
|
||||
"""get a string that has each item of the list on its own line,
|
||||
the items are stringwise-sorted, the object's referrers are shown,
|
||||
and each item is numbered on the left from zero"""
|
||||
s = ''
|
||||
for line in getNumberedTypedSortedStringWithReferrersGen(items, maxLen, numPrefix):
|
||||
s += '%s\n' % line
|
||||
return s
|
||||
|
||||
def printNumberedTyped(items, maxLen=5000):
|
||||
"""print out each item of the list on its own line,
|
||||
with each item numbered on the left from zero"""
|
||||
@ -2114,7 +2051,7 @@ def report(types = [], prefix = '', xform = None, notifyFunc = None, dConfigPara
|
||||
except NameError,e:
|
||||
return decorator
|
||||
|
||||
from direct.distributed.ClockDelta import globalClockDelta
|
||||
globalClockDelta = importlib.import_module("direct.distributed.ClockDelta").globalClockDelta
|
||||
|
||||
def decorator(f):
|
||||
def wrap(*args,**kwargs):
|
||||
@ -2210,8 +2147,8 @@ def getRepository():
|
||||
return simbase.air
|
||||
|
||||
exceptionLoggedNotify = None
|
||||
|
||||
def exceptionLogged(append=True):
|
||||
if __debug__:
|
||||
def exceptionLogged(append=True):
|
||||
"""decorator that outputs the function name and all arguments
|
||||
if an exception passes back through the stack frame
|
||||
if append is true, string is appended to the __str__ output of
|
||||
@ -2262,76 +2199,6 @@ def exceptionLogged(append=True):
|
||||
return _exceptionLogged
|
||||
return _decoratorFunc
|
||||
|
||||
# class 'decorator' that records the stack at the time of creation
|
||||
# be careful with this, it creates a StackTrace, and that can take a
|
||||
# lot of CPU
|
||||
def recordCreationStack(cls):
|
||||
if not hasattr(cls, '__init__'):
|
||||
raise 'recordCreationStack: class \'%s\' must define __init__' % cls.__name__
|
||||
cls.__moved_init__ = cls.__init__
|
||||
def __recordCreationStack_init__(self, *args, **kArgs):
|
||||
self._creationStackTrace = StackTrace(start=1)
|
||||
return self.__moved_init__(*args, **kArgs)
|
||||
def getCreationStackTrace(self):
|
||||
return self._creationStackTrace
|
||||
def getCreationStackTraceCompactStr(self):
|
||||
return self._creationStackTrace.compact()
|
||||
def printCreationStackTrace(self):
|
||||
print self._creationStackTrace
|
||||
cls.__init__ = __recordCreationStack_init__
|
||||
cls.getCreationStackTrace = getCreationStackTrace
|
||||
cls.getCreationStackTraceCompactStr = getCreationStackTraceCompactStr
|
||||
cls.printCreationStackTrace = printCreationStackTrace
|
||||
return cls
|
||||
|
||||
# like recordCreationStack but stores the stack as a compact stack list-of-strings
|
||||
# scales well for memory usage
|
||||
def recordCreationStackStr(cls):
|
||||
if not hasattr(cls, '__init__'):
|
||||
raise 'recordCreationStackStr: class \'%s\' must define __init__' % cls.__name__
|
||||
cls.__moved_init__ = cls.__init__
|
||||
def __recordCreationStackStr_init__(self, *args, **kArgs):
|
||||
# store as list of strings to conserve memory
|
||||
self._creationStackTraceStrLst = StackTrace(start=1).compact().split(',')
|
||||
return self.__moved_init__(*args, **kArgs)
|
||||
def getCreationStackTraceCompactStr(self):
|
||||
return ','.join(self._creationStackTraceStrLst)
|
||||
def printCreationStackTrace(self):
|
||||
print ','.join(self._creationStackTraceStrLst)
|
||||
cls.__init__ = __recordCreationStackStr_init__
|
||||
cls.getCreationStackTraceCompactStr = getCreationStackTraceCompactStr
|
||||
cls.printCreationStackTrace = printCreationStackTrace
|
||||
return cls
|
||||
|
||||
|
||||
# class 'decorator' that logs all method calls for a particular class
|
||||
def logMethodCalls(cls):
|
||||
if not hasattr(cls, 'notify'):
|
||||
raise 'logMethodCalls: class \'%s\' must have a notify' % cls.__name__
|
||||
for name in dir(cls):
|
||||
method = getattr(cls, name)
|
||||
if hasattr(method, '__call__'):
|
||||
def getLoggedMethodCall(method):
|
||||
def __logMethodCall__(obj, *args, **kArgs):
|
||||
s = '%s(' % method.__name__
|
||||
for arg in args:
|
||||
try:
|
||||
argStr = repr(arg)
|
||||
except:
|
||||
argStr = 'bad repr: %s' % arg.__class__
|
||||
s += '%s, ' % argStr
|
||||
for karg, value in kArgs.items():
|
||||
s += '%s=%s, ' % (karg, repr(value))
|
||||
if len(args) or len(kArgs):
|
||||
s = s[:-2]
|
||||
s += ')'
|
||||
obj.notify.info(s)
|
||||
return method(obj, *args, **kArgs)
|
||||
return __logMethodCall__
|
||||
setattr(cls, name, getLoggedMethodCall(method))
|
||||
__logMethodCall__ = None
|
||||
return cls
|
||||
|
||||
# http://en.wikipedia.org/wiki/Golden_ratio
|
||||
GoldenRatio = (1. + math.sqrt(5.)) / 2.
|
||||
class GoldenRectangle:
|
||||
@ -2342,45 +2209,6 @@ class GoldenRectangle:
|
||||
def getShorterEdge(longer):
|
||||
return longer / GoldenRatio
|
||||
|
||||
class HotkeyBreaker:
|
||||
def __init__(self,breakKeys = []):
|
||||
from direct.showbase.DirectObject import DirectObject
|
||||
self.do = DirectObject()
|
||||
self.breakKeys = {}
|
||||
if not isinstance(breakKeys, (list,tuple)):
|
||||
breakKeys = (breakKeys,)
|
||||
for key in breakKeys:
|
||||
self.addBreakKey(key)
|
||||
|
||||
def addBreakKey(self,breakKey):
|
||||
if __dev__:
|
||||
self.do.accept(breakKey,self.breakFunc,extraArgs = [breakKey])
|
||||
|
||||
def removeBreakKey(self,breakKey):
|
||||
if __dev__:
|
||||
self.do.ignore(breakKey)
|
||||
|
||||
def breakFunc(self,breakKey):
|
||||
if __dev__:
|
||||
self.breakKeys[breakKey] = True
|
||||
|
||||
def setBreakPt(self, breakKey = None, persistent = False):
|
||||
if __dev__:
|
||||
if not breakKey:
|
||||
import pdb;pdb.set_trace()
|
||||
return True
|
||||
else:
|
||||
if self.breakKeys.get(breakKey,False):
|
||||
if not persistent:
|
||||
self.breakKeys.pop(breakKey)
|
||||
import pdb;pdb.set_trace()
|
||||
return True
|
||||
return True
|
||||
|
||||
def clearBreakPt(self, breakKey):
|
||||
if __dev__:
|
||||
return bool(self.breakKeys.pop(breakKey,None))
|
||||
|
||||
def nullGen():
|
||||
# generator that ends immediately
|
||||
if False:
|
||||
@ -2480,7 +2308,8 @@ if __debug__ and __name__ == '__main__':
|
||||
assert obj2count[3] == 3 * 3
|
||||
assert obj2count[4] == 4 * 3
|
||||
|
||||
def quickProfile(name="unnamed"):
|
||||
if __debug__:
|
||||
def quickProfile(name="unnamed"):
|
||||
import pstats
|
||||
def profileDecorator(f):
|
||||
if(not config.GetBool("use-profiler",0)):
|
||||
@ -2496,6 +2325,7 @@ def quickProfile(name="unnamed"):
|
||||
print "Function %s.%s took %s seconds"%(f.__module__, f.__name__,s)
|
||||
else:
|
||||
import profile as prof, pstats
|
||||
|
||||
#detailed profile, stored in base.stats under (
|
||||
if(not hasattr(base,"stats")):
|
||||
base.stats={}
|
||||
@ -2533,13 +2363,6 @@ def getAnnounceGenerateTime(stat):
|
||||
return val
|
||||
|
||||
|
||||
def choice(condition, ifTrue, ifFalse):
|
||||
# equivalent of C++ (condition ? ifTrue : ifFalse)
|
||||
if condition:
|
||||
return ifTrue
|
||||
else:
|
||||
return ifFalse
|
||||
|
||||
class MiniLog:
|
||||
def __init__(self, name):
|
||||
self.indent = 1
|
||||
@ -2611,14 +2434,6 @@ class HierarchyException(Exception):
|
||||
def __repr__(self):
|
||||
return 'HierarchyException(%s)' % (self.owner, )
|
||||
|
||||
# __dev__ is not defined at import time, call this after it's defined
|
||||
def recordFunctorCreationStacks():
|
||||
global Functor
|
||||
if not hasattr(Functor, '_functorCreationStacksRecorded'):
|
||||
Functor = recordCreationStackStr(Functor)
|
||||
Functor._functorCreationStacksRecorded = True
|
||||
Functor.__call__ = Functor._exceptionLoggedCreationStack__call__
|
||||
|
||||
def formatTimeCompact(seconds):
|
||||
# returns string in format '1d3h22m43s'
|
||||
result = ''
|
||||
@ -2735,57 +2550,6 @@ if __debug__ and __name__ == '__main__':
|
||||
testAlphabetCounter()
|
||||
del testAlphabetCounter
|
||||
|
||||
globalPdb = None
|
||||
|
||||
traceCalled = False
|
||||
|
||||
def setupPdb():
|
||||
import pdb;
|
||||
class pandaPdb(pdb.Pdb):
|
||||
def stop_here(self, frame):
|
||||
global traceCalled
|
||||
if(traceCalled):
|
||||
result = pdb.Pdb.stop_here(self, frame)
|
||||
if(result == True):
|
||||
traceCalled = False
|
||||
return result
|
||||
if frame is self.stopframe:
|
||||
return True
|
||||
return False
|
||||
global globalPdb
|
||||
globalPdb = pandaPdb()
|
||||
globalPdb.reset()
|
||||
sys.settrace(globalPdb.trace_dispatch)
|
||||
|
||||
def pandaTrace():
|
||||
if __dev__:
|
||||
if not globalPdb:
|
||||
setupPdb()
|
||||
global traceCalled
|
||||
globalPdb.set_trace(sys._getframe().f_back)
|
||||
traceCalled = True
|
||||
|
||||
packageMap = {
|
||||
"toontown":"$TOONTOWN",
|
||||
"direct":"$DIRECT",
|
||||
"otp":"$OTP",
|
||||
"pirates":"$PIRATES",
|
||||
}
|
||||
|
||||
|
||||
#assuming . dereferncing for nice linking to imports
|
||||
def pandaBreak(dotpath, linenum, temporary = 0, cond = None):
|
||||
if __dev__:
|
||||
from panda3d.core import Filename
|
||||
if not globalPdb:
|
||||
setupPdb()
|
||||
dirs = dotpath.split(".")
|
||||
root = Filename.expandFrom(packageMap[dirs[0]]).toOsSpecific()
|
||||
filename = root + "\\src"
|
||||
for d in dirs[1:]:
|
||||
filename="%s\\%s"%(filename,d)
|
||||
print filename
|
||||
globalPdb.set_break(filename+".py", linenum, temporary, cond)
|
||||
|
||||
class Default:
|
||||
# represents 'use the default value'
|
||||
@ -2917,18 +2681,20 @@ __builtin__.SerialMaskedGen = SerialMaskedGen
|
||||
__builtin__.ScratchPad = ScratchPad
|
||||
__builtin__.uniqueName = uniqueName
|
||||
__builtin__.serialNum = serialNum
|
||||
__builtin__.profiled = profiled
|
||||
if __debug__:
|
||||
__builtin__.profiled = profiled
|
||||
__builtin__.exceptionLogged = exceptionLogged
|
||||
__builtin__.itype = itype
|
||||
__builtin__.exceptionLogged = exceptionLogged
|
||||
__builtin__.appendStr = appendStr
|
||||
__builtin__.bound = bound
|
||||
__builtin__.clamp = clamp
|
||||
__builtin__.lerp = lerp
|
||||
__builtin__.makeList = makeList
|
||||
__builtin__.makeTuple = makeTuple
|
||||
__builtin__.printStack = printStack
|
||||
__builtin__.printReverseStack = printReverseStack
|
||||
__builtin__.printVerboseStack = printVerboseStack
|
||||
if __debug__:
|
||||
__builtin__.printStack = printStack
|
||||
__builtin__.printReverseStack = printReverseStack
|
||||
__builtin__.printVerboseStack = printVerboseStack
|
||||
__builtin__.DelayedCall = DelayedCall
|
||||
__builtin__.DelayedFunctor = DelayedFunctor
|
||||
__builtin__.FrameDelayedCall = FrameDelayedCall
|
||||
@ -2942,8 +2708,8 @@ __builtin__.fastRepr = fastRepr
|
||||
__builtin__.nullGen = nullGen
|
||||
__builtin__.flywheel = flywheel
|
||||
__builtin__.loopGen = loopGen
|
||||
__builtin__.StackTrace = StackTrace
|
||||
__builtin__.choice = choice
|
||||
if __debug__:
|
||||
__builtin__.StackTrace = StackTrace
|
||||
__builtin__.report = report
|
||||
__builtin__.pstatcollect = pstatcollect
|
||||
__builtin__.MiniLog = MiniLog
|
||||
|
@ -26,24 +26,22 @@ from BulletinBoardGlobal import bulletinBoard
|
||||
from direct.task.TaskManagerGlobal import taskMgr
|
||||
from JobManagerGlobal import jobMgr
|
||||
from EventManagerGlobal import eventMgr
|
||||
from PythonUtil import *
|
||||
from direct.showbase import PythonUtil
|
||||
#from direct.interval.IntervalManager import ivalMgr
|
||||
#from PythonUtil import *
|
||||
from direct.interval import IntervalManager
|
||||
from direct.showbase.BufferViewer import BufferViewer
|
||||
from direct.task import Task
|
||||
from direct.directutil import Verify
|
||||
from direct.showbase import GarbageReport
|
||||
import sys
|
||||
import Loader
|
||||
import time
|
||||
import atexit
|
||||
import importlib
|
||||
from direct.showbase import ExceptionVarDump
|
||||
import DirectObject
|
||||
import SfxPlayer
|
||||
if __debug__:
|
||||
from direct.showbase import GarbageReport
|
||||
from direct.directutil import DeltaProfiler
|
||||
import OnScreenDebug
|
||||
import OnScreenDebug
|
||||
import AppRunnerGlobal
|
||||
|
||||
def legacyRun():
|
||||
@ -73,6 +71,7 @@ class ShowBase(DirectObject.DirectObject):
|
||||
if logStackDump or uploadStackDump:
|
||||
ExceptionVarDump.install(logStackDump, uploadStackDump)
|
||||
|
||||
if __debug__:
|
||||
self.__autoGarbageLogging = self.__dev__ and self.config.GetBool('auto-garbage-logging', False)
|
||||
|
||||
## The directory containing the main Python file of this application.
|
||||
@ -88,9 +87,6 @@ class ShowBase(DirectObject.DirectObject):
|
||||
#debug running multiplier
|
||||
self.debugRunningMultiplier = 4
|
||||
|
||||
# Setup wantVerifyPdb as soon as reasonable:
|
||||
Verify.wantVerifyPdb = self.config.GetBool('want-verify-pdb', 0)
|
||||
|
||||
# [gjeon] to disable sticky keys
|
||||
if self.config.GetBool('disable-sticky-keys', 0):
|
||||
storeAccessibilityShortcutKeys()
|
||||
@ -388,10 +384,6 @@ class ShowBase(DirectObject.DirectObject):
|
||||
|
||||
self.createBaseAudioManagers()
|
||||
|
||||
# set up recording of Functor creation stacks in __dev__
|
||||
if self.__dev__ and self.config.GetBool('record-functor-creation-stacks', False):
|
||||
PythonUtil.recordFunctorCreationStacks()
|
||||
|
||||
if self.__dev__ or self.config.GetBool('want-e3-hacks', False):
|
||||
if self.config.GetBool('track-gui-items', True):
|
||||
# dict of guiId to gui item, for tracking down leaks
|
||||
@ -465,7 +457,8 @@ class ShowBase(DirectObject.DirectObject):
|
||||
some Panda config settings. """
|
||||
|
||||
try:
|
||||
import profile, pstats
|
||||
profile = importlib.import_module('profile')
|
||||
pstats = importlib.import_module('pstats')
|
||||
except ImportError:
|
||||
return
|
||||
|
||||
@ -1647,23 +1640,26 @@ class ShowBase(DirectObject.DirectObject):
|
||||
|
||||
def addAngularIntegrator(self):
|
||||
if not self.physicsMgrAngular:
|
||||
from panda3d.physics import AngularEulerIntegrator
|
||||
physics = importlib.import_module('panda3d.physics')
|
||||
self.physicsMgrAngular = 1
|
||||
integrator = AngularEulerIntegrator()
|
||||
integrator = physics.AngularEulerIntegrator()
|
||||
self.physicsMgr.attachAngularIntegrator(integrator)
|
||||
|
||||
def enableParticles(self):
|
||||
if not self.particleMgrEnabled:
|
||||
# Use importlib to prevent this import from being picked up
|
||||
# by modulefinder when packaging an application.
|
||||
|
||||
if not self.particleMgr:
|
||||
from direct.particles.ParticleManagerGlobal import particleMgr
|
||||
self.particleMgr = particleMgr
|
||||
PMG = importlib.import_module('direct.particles.ParticleManagerGlobal')
|
||||
self.particleMgr = PMG.particleMgr
|
||||
self.particleMgr.setFrameStepping(1)
|
||||
|
||||
if not self.physicsMgr:
|
||||
from PhysicsManagerGlobal import physicsMgr
|
||||
from panda3d.physics import LinearEulerIntegrator
|
||||
self.physicsMgr = physicsMgr
|
||||
integrator = LinearEulerIntegrator()
|
||||
PMG = importlib.import_module('direct.showbase.PhysicsManagerGlobal')
|
||||
physics = importlib.import_module('panda3d.physics')
|
||||
self.physicsMgr = PMG.physicsMgr
|
||||
integrator = physics.LinearEulerIntegrator()
|
||||
self.physicsMgr.attachLinearIntegrator(integrator)
|
||||
|
||||
self.particleMgrEnabled = 1
|
||||
@ -1886,6 +1882,7 @@ class ShowBase(DirectObject.DirectObject):
|
||||
return Task.cont
|
||||
|
||||
def __igLoop(self, state):
|
||||
if __debug__:
|
||||
# We render the watch variables for the onScreenDebug as soon
|
||||
# as we reasonably can before the renderFrame().
|
||||
self.onScreenDebug.render()
|
||||
@ -1900,6 +1897,7 @@ class ShowBase(DirectObject.DirectObject):
|
||||
if self.multiClientSleep:
|
||||
time.sleep(0)
|
||||
|
||||
if __debug__:
|
||||
# We clear the text buffer for the onScreenDebug as soon
|
||||
# as we reasonably can after the renderFrame().
|
||||
self.onScreenDebug.clear()
|
||||
@ -1925,6 +1923,7 @@ class ShowBase(DirectObject.DirectObject):
|
||||
|
||||
|
||||
def __igLoopSync(self, state):
|
||||
if __debug__:
|
||||
# We render the watch variables for the onScreenDebug as soon
|
||||
# as we reasonably can before the renderFrame().
|
||||
self.onScreenDebug.render()
|
||||
@ -1941,6 +1940,7 @@ class ShowBase(DirectObject.DirectObject):
|
||||
if self.multiClientSleep:
|
||||
time.sleep(0)
|
||||
|
||||
if __debug__:
|
||||
# We clear the text buffer for the onScreenDebug as soon
|
||||
# as we reasonably can after the renderFrame().
|
||||
self.onScreenDebug.clear()
|
||||
@ -2178,8 +2178,10 @@ class ShowBase(DirectObject.DirectObject):
|
||||
self.texmem = None
|
||||
return
|
||||
|
||||
from direct.showutil.TexMemWatcher import TexMemWatcher
|
||||
self.texmem = TexMemWatcher()
|
||||
# Use importlib to prevent this import from being picked up
|
||||
# by modulefinder when packaging an application.
|
||||
TMW = importlib.import_module('direct.showutil.TexMemWatcher')
|
||||
self.texmem = TMW.TexMemWatcher()
|
||||
|
||||
def toggleShowVertices(self):
|
||||
""" Toggles a mode that visualizes vertex density per screen
|
||||
@ -2675,6 +2677,7 @@ class ShowBase(DirectObject.DirectObject):
|
||||
if not properties.getOpen():
|
||||
# If the user closes the main window, we should exit.
|
||||
self.notify.info("User closed main window.")
|
||||
if __debug__:
|
||||
if self.__autoGarbageLogging:
|
||||
GarbageReport.b_checkForGarbageLeaks()
|
||||
self.userExit()
|
||||
@ -2683,6 +2686,7 @@ class ShowBase(DirectObject.DirectObject):
|
||||
self.mainWinForeground = 1
|
||||
elif not properties.getForeground() and self.mainWinForeground:
|
||||
self.mainWinForeground = 0
|
||||
if __debug__:
|
||||
if self.__autoGarbageLogging:
|
||||
GarbageReport.b_checkForGarbageLeaks()
|
||||
|
||||
@ -2814,7 +2818,10 @@ class ShowBase(DirectObject.DirectObject):
|
||||
|
||||
init_app_for_gui()
|
||||
|
||||
import wx
|
||||
# Use importlib to prevent this import from being picked up
|
||||
# by modulefinder when packaging an application.
|
||||
wx = importlib.import_module('wx')
|
||||
|
||||
# Create a new base.wxApp.
|
||||
self.wxApp = wx.PySimpleApp(redirect = False)
|
||||
|
||||
@ -2889,8 +2896,10 @@ class ShowBase(DirectObject.DirectObject):
|
||||
# Don't do this twice.
|
||||
return
|
||||
|
||||
from Tkinter import tkinter
|
||||
import Pmw
|
||||
# Use importlib to prevent this import from being picked up
|
||||
# by modulefinder when packaging an application.
|
||||
tkinter = importlib.import_module('Tkinter').tkinter
|
||||
Pmw = importlib.import_module('Pmw')
|
||||
|
||||
# Create a new Tk root.
|
||||
self.tkRoot = Pmw.initialise()
|
||||
@ -2953,8 +2962,10 @@ class ShowBase(DirectObject.DirectObject):
|
||||
self.startWx(fWantWx)
|
||||
self.wantDirect = fWantDirect
|
||||
if self.wantDirect:
|
||||
from direct.directtools.DirectSession import DirectSession
|
||||
self.direct = DirectSession()
|
||||
# Use importlib to prevent this import from being picked up
|
||||
# by modulefinder when packaging an application.
|
||||
DirectSession = importlib.import_module('direct.directtools.DirectSession')
|
||||
self.direct = DirectSession.DirectSession()
|
||||
self.direct.enable()
|
||||
builtins.direct = self.direct
|
||||
else:
|
||||
|
@ -3,7 +3,7 @@
|
||||
__all__ = ['Transitions']
|
||||
|
||||
from panda3d.core import *
|
||||
from direct.gui.DirectGui import *
|
||||
from direct.gui.DirectGui import DirectFrame
|
||||
from direct.gui import DirectGuiGlobals as DGG
|
||||
from direct.interval.LerpInterval import LerpColorScaleInterval, LerpColorInterval, LerpScaleInterval, LerpPosInterval
|
||||
from direct.interval.MetaInterval import Sequence, Parallel
|
||||
|
@ -30,8 +30,8 @@ isDebugBuild = (python.lower().endswith('_d'))
|
||||
# These are modules that Python always tries to import up-front. They
|
||||
# must be frozen in any main.exe.
|
||||
startupModules = [
|
||||
'site', 'sitecustomize', 'os', 'encodings.cp1252',
|
||||
'encodings.latin_1', 'encodings.utf_8', 'io', 'org',
|
||||
'os', 'encodings.cp1252',
|
||||
'encodings.latin_1', 'encodings.utf_8', 'io',
|
||||
]
|
||||
|
||||
# These are missing modules that we've reported already this session.
|
||||
|
@ -70,6 +70,13 @@ class LockType:
|
||||
def __exit__(self, t, v, tb):
|
||||
self.release()
|
||||
|
||||
# Helper to generate new thread names
|
||||
_counter = 0
|
||||
def _newname(template="Thread-%d"):
|
||||
global _counter
|
||||
_counter = _counter + 1
|
||||
return template % _counter
|
||||
|
||||
_threads = {}
|
||||
_nextThreadId = 0
|
||||
_threadsLock = core.Mutex('thread._threadsLock')
|
||||
|
@ -42,6 +42,7 @@ __all__ = [
|
||||
]
|
||||
|
||||
local = _thread._local
|
||||
_newname = _thread._newname
|
||||
|
||||
class ThreadBase:
|
||||
""" A base class for both Thread and ExternalThread in this
|
||||
@ -98,8 +99,7 @@ class Thread(ThreadBase):
|
||||
self.__kwargs = kwargs
|
||||
|
||||
if not name:
|
||||
import threading2
|
||||
name = threading2._newname()
|
||||
name = _newname()
|
||||
|
||||
current = current_thread()
|
||||
self.__dict__['daemon'] = current.daemon
|
||||
@ -404,9 +404,10 @@ def setprofile(func):
|
||||
def stack_size(size = None):
|
||||
raise ThreadError
|
||||
|
||||
def _test():
|
||||
|
||||
if __debug__:
|
||||
def _test():
|
||||
from collections import deque
|
||||
|
||||
_sleep = core.Thread.sleep
|
||||
|
||||
_VERBOSE = False
|
||||
@ -505,5 +506,5 @@ def _test():
|
||||
t.join()
|
||||
C.join()
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == '__main__':
|
||||
_test()
|
||||
|
@ -16,13 +16,12 @@ implementation. """
|
||||
import sys as _sys
|
||||
|
||||
from direct.stdpy import thread
|
||||
from direct.stdpy.thread import stack_size, _local as local
|
||||
from direct.stdpy.thread import stack_size, _newname, _local as local
|
||||
from panda3d import core
|
||||
_sleep = core.Thread.sleep
|
||||
|
||||
from time import time as _time
|
||||
from traceback import format_exc as _format_exc
|
||||
from collections import deque
|
||||
|
||||
# Rename some stuff so "from threading import *" is safe
|
||||
__all__ = ['activeCount', 'Condition', 'currentThread', 'enumerate', 'Event',
|
||||
@ -377,13 +376,6 @@ class _Event(_Verbose):
|
||||
finally:
|
||||
self.__cond.release()
|
||||
|
||||
# Helper to generate new thread names
|
||||
_counter = 0
|
||||
def _newname(template="Thread-%d"):
|
||||
global _counter
|
||||
_counter = _counter + 1
|
||||
return template % _counter
|
||||
|
||||
# Active thread administration
|
||||
_active_limbo_lock = _allocate_lock()
|
||||
_active = {} # maps thread id to Thread object
|
||||
@ -741,8 +733,9 @@ _shutdown = _MainThread()._exitfunc
|
||||
|
||||
|
||||
# Self-test code
|
||||
|
||||
def _test():
|
||||
if __debug__:
|
||||
def _test():
|
||||
from collections import deque
|
||||
|
||||
class BoundedQueue(_Verbose):
|
||||
|
||||
@ -824,5 +817,5 @@ def _test():
|
||||
t.join()
|
||||
C.join()
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == '__main__':
|
||||
_test()
|
||||
|
@ -12,6 +12,7 @@ from direct.showbase.PythonUtil import *
|
||||
from direct.showbase.MessengerGlobal import messenger
|
||||
import types
|
||||
import random
|
||||
import importlib
|
||||
|
||||
try:
|
||||
import signal
|
||||
@ -591,7 +592,6 @@ class TaskManager:
|
||||
def popupControls(self):
|
||||
# Don't use a regular import, to prevent ModuleFinder from picking
|
||||
# it up as a dependency when building a .p3d package.
|
||||
import importlib
|
||||
TaskManagerPanel = importlib.import_module('direct.tkpanels.TaskManagerPanel')
|
||||
return TaskManagerPanel.TaskManagerPanel(self)
|
||||
|
||||
@ -602,8 +602,8 @@ class TaskManager:
|
||||
|
||||
# Defer this import until we need it: some Python
|
||||
# distributions don't provide the profile and pstats modules.
|
||||
from direct.showbase.ProfileSession import ProfileSession
|
||||
return ProfileSession(name)
|
||||
PS = importlib.import_module('direct.showbase.ProfileSession')
|
||||
return PS.ProfileSession(name)
|
||||
|
||||
def profileFrames(self, num=None, session=None, callback=None):
|
||||
if num is None:
|
||||
@ -629,8 +629,8 @@ class TaskManager:
|
||||
self._profileFrames.set(profileFrames)
|
||||
if (not self._frameProfiler) and profileFrames:
|
||||
# import here due to import dependencies
|
||||
from direct.task.FrameProfiler import FrameProfiler
|
||||
self._frameProfiler = FrameProfiler()
|
||||
FP = importlib.import_module('direct.task.FrameProfiler')
|
||||
self._frameProfiler = FP.FrameProfiler()
|
||||
|
||||
def getProfileTasks(self):
|
||||
return self._profileTasks.get()
|
||||
@ -642,8 +642,8 @@ class TaskManager:
|
||||
self._profileTasks.set(profileTasks)
|
||||
if (not self._taskProfiler) and profileTasks:
|
||||
# import here due to import dependencies
|
||||
from direct.task.TaskProfiler import TaskProfiler
|
||||
self._taskProfiler = TaskProfiler()
|
||||
TP = importlib.import_module('direct.task.TaskProfiler')
|
||||
self._taskProfiler = TP.TaskProfiler()
|
||||
|
||||
def logTaskProfiles(self, name=None):
|
||||
if self._taskProfiler:
|
||||
@ -689,8 +689,8 @@ class TaskManager:
|
||||
|
||||
# Defer this import until we need it: some Python
|
||||
# distributions don't provide the profile and pstats modules.
|
||||
from direct.showbase.ProfileSession import ProfileSession
|
||||
profileSession = ProfileSession('profiled-task-%s' % task.getName(),
|
||||
PS = importlib.import_module('direct.showbase.ProfileSession')
|
||||
profileSession = PS.ProfileSession('profiled-task-%s' % task.getName(),
|
||||
Functor(profileInfo.taskFunc, *profileInfo.taskArgs))
|
||||
ret = profileSession.run()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user