Dramatically reduce size of frozen/compiled code by pruning/masking unnecessary imports/code

This commit is contained in:
rdb 2016-02-12 22:20:27 +01:00
parent 591ce04ab1
commit 0d03207d1b
14 changed files with 767 additions and 1007 deletions

View File

@ -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):

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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):

View File

@ -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,10 +168,10 @@ 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)
if __debug__:
import traceback
import marshal
class StackTrace:
def __init__(self, label="", start=0, limit=None):
"""
@ -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,6 +586,9 @@ class StdoutPassthrough(StdoutCapture):
self._oldStdout.write(string)
# constant profile defaults
if __debug__:
from StringIO import StringIO
PyUtilProfileDefaultFilename = 'profiledata'
PyUtilProfileDefaultLines = 80
PyUtilProfileDefaultSorts = ['cumulative', 'time', 'calls']
@ -1032,6 +1003,7 @@ def solveQuadratic(a, b, c):
root2 = ((-b) + sqrtD) / twoA
return [root1, root2]
if __debug__:
def stackEntryInfo(depth=0, baseFileName=1):
"""
returns the sourcefilename, line number, and function name of
@ -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
@ -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,7 +2147,7 @@ def getRepository():
return simbase.air
exceptionLoggedNotify = None
if __debug__:
def exceptionLogged(append=True):
"""decorator that outputs the function name and all arguments
if an exception passes back through the stack frame
@ -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,6 +2308,7 @@ if __debug__ and __name__ == '__main__':
assert obj2count[3] == 3 * 3
assert obj2count[4] == 4 * 3
if __debug__:
def quickProfile(name="unnamed"):
import pstats
def profileDecorator(f):
@ -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,15 +2681,17 @@ __builtin__.SerialMaskedGen = SerialMaskedGen
__builtin__.ScratchPad = ScratchPad
__builtin__.uniqueName = uniqueName
__builtin__.serialNum = serialNum
if __debug__:
__builtin__.profiled = profiled
__builtin__.itype = itype
__builtin__.exceptionLogged = exceptionLogged
__builtin__.itype = itype
__builtin__.appendStr = appendStr
__builtin__.bound = bound
__builtin__.clamp = clamp
__builtin__.lerp = lerp
__builtin__.makeList = makeList
__builtin__.makeTuple = makeTuple
if __debug__:
__builtin__.printStack = printStack
__builtin__.printReverseStack = printReverseStack
__builtin__.printVerboseStack = printVerboseStack
@ -2942,8 +2708,8 @@ __builtin__.fastRepr = fastRepr
__builtin__.nullGen = nullGen
__builtin__.flywheel = flywheel
__builtin__.loopGen = loopGen
if __debug__:
__builtin__.StackTrace = StackTrace
__builtin__.choice = choice
__builtin__.report = report
__builtin__.pstatcollect = pstatcollect
__builtin__.MiniLog = MiniLog

View File

@ -26,22 +26,20 @@ 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 AppRunnerGlobal
@ -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:

View File

@ -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

View File

@ -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.

View File

@ -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')

View File

@ -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
if __debug__:
def _test():
from collections import deque
_sleep = core.Thread.sleep
_VERBOSE = False

View File

@ -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
if __debug__:
def _test():
from collections import deque
class BoundedQueue(_Verbose):

View File

@ -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()