mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 18:31:55 -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.
|
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):
|
def verify(assertion):
|
||||||
|
@ -12,7 +12,6 @@ from OnscreenImage import *
|
|||||||
from direct.directtools.DirectUtil import ROUND_TO
|
from direct.directtools.DirectUtil import ROUND_TO
|
||||||
from direct.showbase import DirectObject
|
from direct.showbase import DirectObject
|
||||||
from direct.task import Task
|
from direct.task import Task
|
||||||
from direct.showbase.PythonUtil import recordCreationStackStr
|
|
||||||
import types
|
import types
|
||||||
|
|
||||||
guiObjectCollector = PStatCollector("Client::GuiObjects")
|
guiObjectCollector = PStatCollector("Client::GuiObjects")
|
||||||
@ -651,13 +650,6 @@ def toggleGuiGridSnap():
|
|||||||
def setGuiGridSpacing(spacing):
|
def setGuiGridSpacing(spacing):
|
||||||
DirectGuiWidget.gridSpacing = 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):
|
class DirectGuiWidget(DirectGuiBase, NodePath):
|
||||||
# Toggle if you wish widget's to snap to grid when draggin
|
# Toggle if you wish widget's to snap to grid when draggin
|
||||||
|
@ -72,13 +72,6 @@ class ProjectileInterval(Interval):
|
|||||||
self.projectileIntervalNum)
|
self.projectileIntervalNum)
|
||||||
ProjectileInterval.projectileIntervalNum += 1
|
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,
|
args = (startPos, endPos, duration, startVel, endZ,
|
||||||
wayPoint, timeToWayPoint, gravityMult)
|
wayPoint, timeToWayPoint, gravityMult)
|
||||||
self.implicitStartPos = 0
|
self.implicitStartPos = 0
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
from panda3d.direct import get_config_showbase
|
__all__ = ["install"]
|
||||||
|
|
||||||
from direct.directnotify.DirectNotifyGlobal import directNotify
|
from direct.directnotify.DirectNotifyGlobal import directNotify
|
||||||
from direct.showbase.PythonUtil import fastRepr
|
from direct.showbase.PythonUtil import fastRepr
|
||||||
import sys
|
import sys
|
||||||
@ -6,7 +7,6 @@ import types
|
|||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
notify = directNotify.newCategory("ExceptionVarDump")
|
notify = directNotify.newCategory("ExceptionVarDump")
|
||||||
config = get_config_showbase()
|
|
||||||
|
|
||||||
reentry = 0
|
reentry = 0
|
||||||
|
|
||||||
@ -187,7 +187,7 @@ def install(log, upload):
|
|||||||
wantStackDumpLog = log
|
wantStackDumpLog = log
|
||||||
wantStackDumpUpload = upload
|
wantStackDumpUpload = upload
|
||||||
|
|
||||||
dumpOnExceptionInit = config.GetBool('variable-dump-on-exception-init', 0)
|
dumpOnExceptionInit = ConfigVariableBool('variable-dump-on-exception-init', False)
|
||||||
if dumpOnExceptionInit:
|
if dumpOnExceptionInit:
|
||||||
# this mode doesn't completely work because exception objects
|
# this mode doesn't completely work because exception objects
|
||||||
# thrown by the interpreter don't get created until the
|
# thrown by the interpreter don't get created until the
|
||||||
|
@ -281,7 +281,7 @@ class GarbageReport(Job):
|
|||||||
if self._args.findCycles:
|
if self._args.findCycles:
|
||||||
s = ['===== GarbageReport: \'%s\' (%s %s) =====' % (
|
s = ['===== GarbageReport: \'%s\' (%s %s) =====' % (
|
||||||
self._args.name, self.numCycles,
|
self._args.name, self.numCycles,
|
||||||
choice(self.numCycles == 1, 'cycle', 'cycles'))]
|
('cycle' if self.numCycles == 1 else 'cycles'))]
|
||||||
else:
|
else:
|
||||||
s = ['===== GarbageReport: \'%s\' =====' % (
|
s = ['===== GarbageReport: \'%s\' =====' % (
|
||||||
self._args.name)]
|
self._args.name)]
|
||||||
@ -499,7 +499,7 @@ class GarbageReport(Job):
|
|||||||
rootId = index
|
rootId = index
|
||||||
# check if the root object is one of the garbage instances (has __del__)
|
# check if the root object is one of the garbage instances (has __del__)
|
||||||
objId = id(self.garbage[rootId])
|
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))
|
stateStack.push(([rootId], rootId, numDelInstances, 0))
|
||||||
while True:
|
while True:
|
||||||
yield None
|
yield None
|
||||||
@ -535,7 +535,7 @@ class GarbageReport(Job):
|
|||||||
elif refId is not None:
|
elif refId is not None:
|
||||||
# check if this object is one of the garbage instances (has __del__)
|
# check if this object is one of the garbage instances (has __del__)
|
||||||
objId = id(self.garbage[refId])
|
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
|
# this refId does not complete a cycle. Mark down
|
||||||
# where we are in this list of referents, then
|
# where we are in this list of referents, then
|
||||||
# start looking through the referents of the new refId
|
# start looking through the referents of the new refId
|
||||||
|
@ -5,7 +5,6 @@ __all__ = ['Diff', 'ObjectPool']
|
|||||||
from direct.directnotify.DirectNotifyGlobal import directNotify
|
from direct.directnotify.DirectNotifyGlobal import directNotify
|
||||||
from direct.showbase.PythonUtil import invertDictLossless, makeList, safeRepr
|
from direct.showbase.PythonUtil import invertDictLossless, makeList, safeRepr
|
||||||
from direct.showbase.PythonUtil import getNumberedTypedString, getNumberedTypedSortedString
|
from direct.showbase.PythonUtil import getNumberedTypedString, getNumberedTypedSortedString
|
||||||
from direct.showbase.PythonUtil import getNumberedTypedSortedStringWithReferrersGen
|
|
||||||
import gc
|
import gc
|
||||||
|
|
||||||
class Diff:
|
class Diff:
|
||||||
@ -97,7 +96,7 @@ class ObjectPool:
|
|||||||
s += '\n%s\t%s' % (count, typ)
|
s += '\n%s\t%s' % (count, typ)
|
||||||
return s
|
return s
|
||||||
|
|
||||||
def printObjsByType(self, printReferrers=False):
|
def printObjsByType(self):
|
||||||
print 'Object Pool: Objects By Type'
|
print 'Object Pool: Objects By Type'
|
||||||
print '\n============================'
|
print '\n============================'
|
||||||
counts = list(set(self._count2types.keys()))
|
counts = list(set(self._count2types.keys()))
|
||||||
@ -109,11 +108,7 @@ class ObjectPool:
|
|||||||
types = makeList(self._count2types[count])
|
types = makeList(self._count2types[count])
|
||||||
for typ in types:
|
for typ in types:
|
||||||
print 'TYPE: %s, %s objects' % (repr(typ), len(self._type2objs[typ]))
|
print 'TYPE: %s, %s objects' % (repr(typ), len(self._type2objs[typ]))
|
||||||
if printReferrers:
|
print getNumberedTypedSortedString(self._type2objs[typ])
|
||||||
for line in getNumberedTypedSortedStringWithReferrersGen(self._type2objs[typ]):
|
|
||||||
print line
|
|
||||||
else:
|
|
||||||
print getNumberedTypedSortedString(self._type2objs[typ])
|
|
||||||
|
|
||||||
def containerLenStr(self):
|
def containerLenStr(self):
|
||||||
s = 'Object Pool: Container Lengths'
|
s = 'Object Pool: Container Lengths'
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -26,24 +26,22 @@ from BulletinBoardGlobal import bulletinBoard
|
|||||||
from direct.task.TaskManagerGlobal import taskMgr
|
from direct.task.TaskManagerGlobal import taskMgr
|
||||||
from JobManagerGlobal import jobMgr
|
from JobManagerGlobal import jobMgr
|
||||||
from EventManagerGlobal import eventMgr
|
from EventManagerGlobal import eventMgr
|
||||||
from PythonUtil import *
|
#from PythonUtil import *
|
||||||
from direct.showbase import PythonUtil
|
|
||||||
#from direct.interval.IntervalManager import ivalMgr
|
|
||||||
from direct.interval import IntervalManager
|
from direct.interval import IntervalManager
|
||||||
from direct.showbase.BufferViewer import BufferViewer
|
from direct.showbase.BufferViewer import BufferViewer
|
||||||
from direct.task import Task
|
from direct.task import Task
|
||||||
from direct.directutil import Verify
|
|
||||||
from direct.showbase import GarbageReport
|
|
||||||
import sys
|
import sys
|
||||||
import Loader
|
import Loader
|
||||||
import time
|
import time
|
||||||
import atexit
|
import atexit
|
||||||
|
import importlib
|
||||||
from direct.showbase import ExceptionVarDump
|
from direct.showbase import ExceptionVarDump
|
||||||
import DirectObject
|
import DirectObject
|
||||||
import SfxPlayer
|
import SfxPlayer
|
||||||
if __debug__:
|
if __debug__:
|
||||||
|
from direct.showbase import GarbageReport
|
||||||
from direct.directutil import DeltaProfiler
|
from direct.directutil import DeltaProfiler
|
||||||
import OnScreenDebug
|
import OnScreenDebug
|
||||||
import AppRunnerGlobal
|
import AppRunnerGlobal
|
||||||
|
|
||||||
def legacyRun():
|
def legacyRun():
|
||||||
@ -73,7 +71,8 @@ class ShowBase(DirectObject.DirectObject):
|
|||||||
if logStackDump or uploadStackDump:
|
if logStackDump or uploadStackDump:
|
||||||
ExceptionVarDump.install(logStackDump, uploadStackDump)
|
ExceptionVarDump.install(logStackDump, uploadStackDump)
|
||||||
|
|
||||||
self.__autoGarbageLogging = self.__dev__ and self.config.GetBool('auto-garbage-logging', False)
|
if __debug__:
|
||||||
|
self.__autoGarbageLogging = self.__dev__ and self.config.GetBool('auto-garbage-logging', False)
|
||||||
|
|
||||||
## The directory containing the main Python file of this application.
|
## The directory containing the main Python file of this application.
|
||||||
self.mainDir = ExecutionEnvironment.getEnvironmentVariable("MAIN_DIR")
|
self.mainDir = ExecutionEnvironment.getEnvironmentVariable("MAIN_DIR")
|
||||||
@ -88,9 +87,6 @@ class ShowBase(DirectObject.DirectObject):
|
|||||||
#debug running multiplier
|
#debug running multiplier
|
||||||
self.debugRunningMultiplier = 4
|
self.debugRunningMultiplier = 4
|
||||||
|
|
||||||
# Setup wantVerifyPdb as soon as reasonable:
|
|
||||||
Verify.wantVerifyPdb = self.config.GetBool('want-verify-pdb', 0)
|
|
||||||
|
|
||||||
# [gjeon] to disable sticky keys
|
# [gjeon] to disable sticky keys
|
||||||
if self.config.GetBool('disable-sticky-keys', 0):
|
if self.config.GetBool('disable-sticky-keys', 0):
|
||||||
storeAccessibilityShortcutKeys()
|
storeAccessibilityShortcutKeys()
|
||||||
@ -373,8 +369,8 @@ class ShowBase(DirectObject.DirectObject):
|
|||||||
builtins.wantUberdog = self.config.GetBool('want-uberdog', 1)
|
builtins.wantUberdog = self.config.GetBool('want-uberdog', 1)
|
||||||
if __debug__:
|
if __debug__:
|
||||||
builtins.deltaProfiler = DeltaProfiler.DeltaProfiler("ShowBase")
|
builtins.deltaProfiler = DeltaProfiler.DeltaProfiler("ShowBase")
|
||||||
self.onScreenDebug = OnScreenDebug.OnScreenDebug()
|
self.onScreenDebug = OnScreenDebug.OnScreenDebug()
|
||||||
builtins.onScreenDebug = self.onScreenDebug
|
builtins.onScreenDebug = self.onScreenDebug
|
||||||
|
|
||||||
if self.wantRender2dp:
|
if self.wantRender2dp:
|
||||||
builtins.render2dp = self.render2dp
|
builtins.render2dp = self.render2dp
|
||||||
@ -388,10 +384,6 @@ class ShowBase(DirectObject.DirectObject):
|
|||||||
|
|
||||||
self.createBaseAudioManagers()
|
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.__dev__ or self.config.GetBool('want-e3-hacks', False):
|
||||||
if self.config.GetBool('track-gui-items', True):
|
if self.config.GetBool('track-gui-items', True):
|
||||||
# dict of guiId to gui item, for tracking down leaks
|
# dict of guiId to gui item, for tracking down leaks
|
||||||
@ -465,7 +457,8 @@ class ShowBase(DirectObject.DirectObject):
|
|||||||
some Panda config settings. """
|
some Panda config settings. """
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import profile, pstats
|
profile = importlib.import_module('profile')
|
||||||
|
pstats = importlib.import_module('pstats')
|
||||||
except ImportError:
|
except ImportError:
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -1647,23 +1640,26 @@ class ShowBase(DirectObject.DirectObject):
|
|||||||
|
|
||||||
def addAngularIntegrator(self):
|
def addAngularIntegrator(self):
|
||||||
if not self.physicsMgrAngular:
|
if not self.physicsMgrAngular:
|
||||||
from panda3d.physics import AngularEulerIntegrator
|
physics = importlib.import_module('panda3d.physics')
|
||||||
self.physicsMgrAngular = 1
|
self.physicsMgrAngular = 1
|
||||||
integrator = AngularEulerIntegrator()
|
integrator = physics.AngularEulerIntegrator()
|
||||||
self.physicsMgr.attachAngularIntegrator(integrator)
|
self.physicsMgr.attachAngularIntegrator(integrator)
|
||||||
|
|
||||||
def enableParticles(self):
|
def enableParticles(self):
|
||||||
if not self.particleMgrEnabled:
|
if not self.particleMgrEnabled:
|
||||||
|
# Use importlib to prevent this import from being picked up
|
||||||
|
# by modulefinder when packaging an application.
|
||||||
|
|
||||||
if not self.particleMgr:
|
if not self.particleMgr:
|
||||||
from direct.particles.ParticleManagerGlobal import particleMgr
|
PMG = importlib.import_module('direct.particles.ParticleManagerGlobal')
|
||||||
self.particleMgr = particleMgr
|
self.particleMgr = PMG.particleMgr
|
||||||
self.particleMgr.setFrameStepping(1)
|
self.particleMgr.setFrameStepping(1)
|
||||||
|
|
||||||
if not self.physicsMgr:
|
if not self.physicsMgr:
|
||||||
from PhysicsManagerGlobal import physicsMgr
|
PMG = importlib.import_module('direct.showbase.PhysicsManagerGlobal')
|
||||||
from panda3d.physics import LinearEulerIntegrator
|
physics = importlib.import_module('panda3d.physics')
|
||||||
self.physicsMgr = physicsMgr
|
self.physicsMgr = PMG.physicsMgr
|
||||||
integrator = LinearEulerIntegrator()
|
integrator = physics.LinearEulerIntegrator()
|
||||||
self.physicsMgr.attachLinearIntegrator(integrator)
|
self.physicsMgr.attachLinearIntegrator(integrator)
|
||||||
|
|
||||||
self.particleMgrEnabled = 1
|
self.particleMgrEnabled = 1
|
||||||
@ -1886,9 +1882,10 @@ class ShowBase(DirectObject.DirectObject):
|
|||||||
return Task.cont
|
return Task.cont
|
||||||
|
|
||||||
def __igLoop(self, state):
|
def __igLoop(self, state):
|
||||||
# We render the watch variables for the onScreenDebug as soon
|
if __debug__:
|
||||||
# as we reasonably can before the renderFrame().
|
# We render the watch variables for the onScreenDebug as soon
|
||||||
self.onScreenDebug.render()
|
# as we reasonably can before the renderFrame().
|
||||||
|
self.onScreenDebug.render()
|
||||||
|
|
||||||
if self.recorder:
|
if self.recorder:
|
||||||
self.recorder.recordFrame()
|
self.recorder.recordFrame()
|
||||||
@ -1900,9 +1897,10 @@ class ShowBase(DirectObject.DirectObject):
|
|||||||
if self.multiClientSleep:
|
if self.multiClientSleep:
|
||||||
time.sleep(0)
|
time.sleep(0)
|
||||||
|
|
||||||
# We clear the text buffer for the onScreenDebug as soon
|
if __debug__:
|
||||||
# as we reasonably can after the renderFrame().
|
# We clear the text buffer for the onScreenDebug as soon
|
||||||
self.onScreenDebug.clear()
|
# as we reasonably can after the renderFrame().
|
||||||
|
self.onScreenDebug.clear()
|
||||||
|
|
||||||
if self.recorder:
|
if self.recorder:
|
||||||
self.recorder.playFrame()
|
self.recorder.playFrame()
|
||||||
@ -1925,9 +1923,10 @@ class ShowBase(DirectObject.DirectObject):
|
|||||||
|
|
||||||
|
|
||||||
def __igLoopSync(self, state):
|
def __igLoopSync(self, state):
|
||||||
# We render the watch variables for the onScreenDebug as soon
|
if __debug__:
|
||||||
# as we reasonably can before the renderFrame().
|
# We render the watch variables for the onScreenDebug as soon
|
||||||
self.onScreenDebug.render()
|
# as we reasonably can before the renderFrame().
|
||||||
|
self.onScreenDebug.render()
|
||||||
|
|
||||||
if self.recorder:
|
if self.recorder:
|
||||||
self.recorder.recordFrame()
|
self.recorder.recordFrame()
|
||||||
@ -1941,9 +1940,10 @@ class ShowBase(DirectObject.DirectObject):
|
|||||||
if self.multiClientSleep:
|
if self.multiClientSleep:
|
||||||
time.sleep(0)
|
time.sleep(0)
|
||||||
|
|
||||||
# We clear the text buffer for the onScreenDebug as soon
|
if __debug__:
|
||||||
# as we reasonably can after the renderFrame().
|
# We clear the text buffer for the onScreenDebug as soon
|
||||||
self.onScreenDebug.clear()
|
# as we reasonably can after the renderFrame().
|
||||||
|
self.onScreenDebug.clear()
|
||||||
|
|
||||||
if self.recorder:
|
if self.recorder:
|
||||||
self.recorder.playFrame()
|
self.recorder.playFrame()
|
||||||
@ -2178,8 +2178,10 @@ class ShowBase(DirectObject.DirectObject):
|
|||||||
self.texmem = None
|
self.texmem = None
|
||||||
return
|
return
|
||||||
|
|
||||||
from direct.showutil.TexMemWatcher import TexMemWatcher
|
# Use importlib to prevent this import from being picked up
|
||||||
self.texmem = TexMemWatcher()
|
# by modulefinder when packaging an application.
|
||||||
|
TMW = importlib.import_module('direct.showutil.TexMemWatcher')
|
||||||
|
self.texmem = TMW.TexMemWatcher()
|
||||||
|
|
||||||
def toggleShowVertices(self):
|
def toggleShowVertices(self):
|
||||||
""" Toggles a mode that visualizes vertex density per screen
|
""" Toggles a mode that visualizes vertex density per screen
|
||||||
@ -2675,16 +2677,18 @@ class ShowBase(DirectObject.DirectObject):
|
|||||||
if not properties.getOpen():
|
if not properties.getOpen():
|
||||||
# If the user closes the main window, we should exit.
|
# If the user closes the main window, we should exit.
|
||||||
self.notify.info("User closed main window.")
|
self.notify.info("User closed main window.")
|
||||||
if self.__autoGarbageLogging:
|
if __debug__:
|
||||||
GarbageReport.b_checkForGarbageLeaks()
|
if self.__autoGarbageLogging:
|
||||||
|
GarbageReport.b_checkForGarbageLeaks()
|
||||||
self.userExit()
|
self.userExit()
|
||||||
|
|
||||||
if properties.getForeground() and not self.mainWinForeground:
|
if properties.getForeground() and not self.mainWinForeground:
|
||||||
self.mainWinForeground = 1
|
self.mainWinForeground = 1
|
||||||
elif not properties.getForeground() and self.mainWinForeground:
|
elif not properties.getForeground() and self.mainWinForeground:
|
||||||
self.mainWinForeground = 0
|
self.mainWinForeground = 0
|
||||||
if self.__autoGarbageLogging:
|
if __debug__:
|
||||||
GarbageReport.b_checkForGarbageLeaks()
|
if self.__autoGarbageLogging:
|
||||||
|
GarbageReport.b_checkForGarbageLeaks()
|
||||||
|
|
||||||
if properties.getMinimized() and not self.mainWinMinimized:
|
if properties.getMinimized() and not self.mainWinMinimized:
|
||||||
# If the main window is minimized, throw an event to
|
# If the main window is minimized, throw an event to
|
||||||
@ -2814,7 +2818,10 @@ class ShowBase(DirectObject.DirectObject):
|
|||||||
|
|
||||||
init_app_for_gui()
|
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.
|
# Create a new base.wxApp.
|
||||||
self.wxApp = wx.PySimpleApp(redirect = False)
|
self.wxApp = wx.PySimpleApp(redirect = False)
|
||||||
|
|
||||||
@ -2889,8 +2896,10 @@ class ShowBase(DirectObject.DirectObject):
|
|||||||
# Don't do this twice.
|
# Don't do this twice.
|
||||||
return
|
return
|
||||||
|
|
||||||
from Tkinter import tkinter
|
# Use importlib to prevent this import from being picked up
|
||||||
import Pmw
|
# by modulefinder when packaging an application.
|
||||||
|
tkinter = importlib.import_module('Tkinter').tkinter
|
||||||
|
Pmw = importlib.import_module('Pmw')
|
||||||
|
|
||||||
# Create a new Tk root.
|
# Create a new Tk root.
|
||||||
self.tkRoot = Pmw.initialise()
|
self.tkRoot = Pmw.initialise()
|
||||||
@ -2953,8 +2962,10 @@ class ShowBase(DirectObject.DirectObject):
|
|||||||
self.startWx(fWantWx)
|
self.startWx(fWantWx)
|
||||||
self.wantDirect = fWantDirect
|
self.wantDirect = fWantDirect
|
||||||
if self.wantDirect:
|
if self.wantDirect:
|
||||||
from direct.directtools.DirectSession import DirectSession
|
# Use importlib to prevent this import from being picked up
|
||||||
self.direct = DirectSession()
|
# by modulefinder when packaging an application.
|
||||||
|
DirectSession = importlib.import_module('direct.directtools.DirectSession')
|
||||||
|
self.direct = DirectSession.DirectSession()
|
||||||
self.direct.enable()
|
self.direct.enable()
|
||||||
builtins.direct = self.direct
|
builtins.direct = self.direct
|
||||||
else:
|
else:
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
__all__ = ['Transitions']
|
__all__ = ['Transitions']
|
||||||
|
|
||||||
from panda3d.core import *
|
from panda3d.core import *
|
||||||
from direct.gui.DirectGui import *
|
from direct.gui.DirectGui import DirectFrame
|
||||||
from direct.gui import DirectGuiGlobals as DGG
|
from direct.gui import DirectGuiGlobals as DGG
|
||||||
from direct.interval.LerpInterval import LerpColorScaleInterval, LerpColorInterval, LerpScaleInterval, LerpPosInterval
|
from direct.interval.LerpInterval import LerpColorScaleInterval, LerpColorInterval, LerpScaleInterval, LerpPosInterval
|
||||||
from direct.interval.MetaInterval import Sequence, Parallel
|
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
|
# These are modules that Python always tries to import up-front. They
|
||||||
# must be frozen in any main.exe.
|
# must be frozen in any main.exe.
|
||||||
startupModules = [
|
startupModules = [
|
||||||
'site', 'sitecustomize', 'os', 'encodings.cp1252',
|
'os', 'encodings.cp1252',
|
||||||
'encodings.latin_1', 'encodings.utf_8', 'io', 'org',
|
'encodings.latin_1', 'encodings.utf_8', 'io',
|
||||||
]
|
]
|
||||||
|
|
||||||
# These are missing modules that we've reported already this session.
|
# These are missing modules that we've reported already this session.
|
||||||
|
@ -70,6 +70,13 @@ class LockType:
|
|||||||
def __exit__(self, t, v, tb):
|
def __exit__(self, t, v, tb):
|
||||||
self.release()
|
self.release()
|
||||||
|
|
||||||
|
# Helper to generate new thread names
|
||||||
|
_counter = 0
|
||||||
|
def _newname(template="Thread-%d"):
|
||||||
|
global _counter
|
||||||
|
_counter = _counter + 1
|
||||||
|
return template % _counter
|
||||||
|
|
||||||
_threads = {}
|
_threads = {}
|
||||||
_nextThreadId = 0
|
_nextThreadId = 0
|
||||||
_threadsLock = core.Mutex('thread._threadsLock')
|
_threadsLock = core.Mutex('thread._threadsLock')
|
||||||
|
@ -42,6 +42,7 @@ __all__ = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
local = _thread._local
|
local = _thread._local
|
||||||
|
_newname = _thread._newname
|
||||||
|
|
||||||
class ThreadBase:
|
class ThreadBase:
|
||||||
""" A base class for both Thread and ExternalThread in this
|
""" A base class for both Thread and ExternalThread in this
|
||||||
@ -98,8 +99,7 @@ class Thread(ThreadBase):
|
|||||||
self.__kwargs = kwargs
|
self.__kwargs = kwargs
|
||||||
|
|
||||||
if not name:
|
if not name:
|
||||||
import threading2
|
name = _newname()
|
||||||
name = threading2._newname()
|
|
||||||
|
|
||||||
current = current_thread()
|
current = current_thread()
|
||||||
self.__dict__['daemon'] = current.daemon
|
self.__dict__['daemon'] = current.daemon
|
||||||
@ -404,106 +404,107 @@ def setprofile(func):
|
|||||||
def stack_size(size = None):
|
def stack_size(size = None):
|
||||||
raise ThreadError
|
raise ThreadError
|
||||||
|
|
||||||
def _test():
|
if __debug__:
|
||||||
|
def _test():
|
||||||
|
from collections import deque
|
||||||
|
|
||||||
from collections import deque
|
_sleep = core.Thread.sleep
|
||||||
_sleep = core.Thread.sleep
|
|
||||||
|
|
||||||
_VERBOSE = False
|
_VERBOSE = False
|
||||||
|
|
||||||
class _Verbose(object):
|
class _Verbose(object):
|
||||||
|
|
||||||
def __init__(self, verbose=None):
|
def __init__(self, verbose=None):
|
||||||
if verbose is None:
|
if verbose is None:
|
||||||
verbose = _VERBOSE
|
verbose = _VERBOSE
|
||||||
self.__verbose = verbose
|
self.__verbose = verbose
|
||||||
|
|
||||||
def _note(self, format, *args):
|
def _note(self, format, *args):
|
||||||
if self.__verbose:
|
if self.__verbose:
|
||||||
format = format % args
|
format = format % args
|
||||||
format = "%s: %s\n" % (
|
format = "%s: %s\n" % (
|
||||||
currentThread().getName(), format)
|
currentThread().getName(), format)
|
||||||
_sys.stderr.write(format)
|
_sys.stderr.write(format)
|
||||||
|
|
||||||
class BoundedQueue(_Verbose):
|
class BoundedQueue(_Verbose):
|
||||||
|
|
||||||
def __init__(self, limit):
|
def __init__(self, limit):
|
||||||
_Verbose.__init__(self)
|
_Verbose.__init__(self)
|
||||||
self.mon = Lock(name = "BoundedQueue.mon")
|
self.mon = Lock(name = "BoundedQueue.mon")
|
||||||
self.rc = Condition(self.mon)
|
self.rc = Condition(self.mon)
|
||||||
self.wc = Condition(self.mon)
|
self.wc = Condition(self.mon)
|
||||||
self.limit = limit
|
self.limit = limit
|
||||||
self.queue = deque()
|
self.queue = deque()
|
||||||
|
|
||||||
def put(self, item):
|
def put(self, item):
|
||||||
self.mon.acquire()
|
self.mon.acquire()
|
||||||
while len(self.queue) >= self.limit:
|
while len(self.queue) >= self.limit:
|
||||||
self._note("put(%s): queue full", item)
|
self._note("put(%s): queue full", item)
|
||||||
self.wc.wait()
|
self.wc.wait()
|
||||||
self.queue.append(item)
|
self.queue.append(item)
|
||||||
self._note("put(%s): appended, length now %d",
|
self._note("put(%s): appended, length now %d",
|
||||||
item, len(self.queue))
|
item, len(self.queue))
|
||||||
self.rc.notify()
|
self.rc.notify()
|
||||||
self.mon.release()
|
self.mon.release()
|
||||||
|
|
||||||
def get(self):
|
def get(self):
|
||||||
self.mon.acquire()
|
self.mon.acquire()
|
||||||
while not self.queue:
|
while not self.queue:
|
||||||
self._note("get(): queue empty")
|
self._note("get(): queue empty")
|
||||||
self.rc.wait()
|
self.rc.wait()
|
||||||
item = self.queue.popleft()
|
item = self.queue.popleft()
|
||||||
self._note("get(): got %s, %d left", item, len(self.queue))
|
self._note("get(): got %s, %d left", item, len(self.queue))
|
||||||
self.wc.notify()
|
self.wc.notify()
|
||||||
self.mon.release()
|
self.mon.release()
|
||||||
return item
|
return item
|
||||||
|
|
||||||
class ProducerThread(Thread):
|
class ProducerThread(Thread):
|
||||||
|
|
||||||
def __init__(self, queue, quota):
|
def __init__(self, queue, quota):
|
||||||
Thread.__init__(self, name="Producer")
|
Thread.__init__(self, name="Producer")
|
||||||
self.queue = queue
|
self.queue = queue
|
||||||
self.quota = quota
|
self.quota = quota
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
from random import random
|
from random import random
|
||||||
counter = 0
|
counter = 0
|
||||||
while counter < self.quota:
|
while counter < self.quota:
|
||||||
counter = counter + 1
|
counter = counter + 1
|
||||||
self.queue.put("%s.%d" % (self.getName(), counter))
|
self.queue.put("%s.%d" % (self.getName(), counter))
|
||||||
_sleep(random() * 0.00001)
|
_sleep(random() * 0.00001)
|
||||||
|
|
||||||
|
|
||||||
class ConsumerThread(Thread):
|
class ConsumerThread(Thread):
|
||||||
|
|
||||||
def __init__(self, queue, count):
|
def __init__(self, queue, count):
|
||||||
Thread.__init__(self, name="Consumer")
|
Thread.__init__(self, name="Consumer")
|
||||||
self.queue = queue
|
self.queue = queue
|
||||||
self.count = count
|
self.count = count
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
while self.count > 0:
|
while self.count > 0:
|
||||||
item = self.queue.get()
|
item = self.queue.get()
|
||||||
print item
|
print item
|
||||||
self.count = self.count - 1
|
self.count = self.count - 1
|
||||||
|
|
||||||
NP = 3
|
NP = 3
|
||||||
QL = 4
|
QL = 4
|
||||||
NI = 5
|
NI = 5
|
||||||
|
|
||||||
Q = BoundedQueue(QL)
|
Q = BoundedQueue(QL)
|
||||||
P = []
|
P = []
|
||||||
for i in range(NP):
|
for i in range(NP):
|
||||||
t = ProducerThread(Q, NI)
|
t = ProducerThread(Q, NI)
|
||||||
t.setName("Producer-%d" % (i+1))
|
t.setName("Producer-%d" % (i+1))
|
||||||
P.append(t)
|
P.append(t)
|
||||||
C = ConsumerThread(Q, NI*NP)
|
C = ConsumerThread(Q, NI*NP)
|
||||||
for t in P:
|
for t in P:
|
||||||
t.start()
|
t.start()
|
||||||
_sleep(0.000001)
|
_sleep(0.000001)
|
||||||
C.start()
|
C.start()
|
||||||
for t in P:
|
for t in P:
|
||||||
t.join()
|
t.join()
|
||||||
C.join()
|
C.join()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
_test()
|
_test()
|
||||||
|
@ -16,13 +16,12 @@ implementation. """
|
|||||||
import sys as _sys
|
import sys as _sys
|
||||||
|
|
||||||
from direct.stdpy import thread
|
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
|
from panda3d import core
|
||||||
_sleep = core.Thread.sleep
|
_sleep = core.Thread.sleep
|
||||||
|
|
||||||
from time import time as _time
|
from time import time as _time
|
||||||
from traceback import format_exc as _format_exc
|
from traceback import format_exc as _format_exc
|
||||||
from collections import deque
|
|
||||||
|
|
||||||
# Rename some stuff so "from threading import *" is safe
|
# Rename some stuff so "from threading import *" is safe
|
||||||
__all__ = ['activeCount', 'Condition', 'currentThread', 'enumerate', 'Event',
|
__all__ = ['activeCount', 'Condition', 'currentThread', 'enumerate', 'Event',
|
||||||
@ -377,13 +376,6 @@ class _Event(_Verbose):
|
|||||||
finally:
|
finally:
|
||||||
self.__cond.release()
|
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 thread administration
|
||||||
_active_limbo_lock = _allocate_lock()
|
_active_limbo_lock = _allocate_lock()
|
||||||
_active = {} # maps thread id to Thread object
|
_active = {} # maps thread id to Thread object
|
||||||
@ -741,88 +733,89 @@ _shutdown = _MainThread()._exitfunc
|
|||||||
|
|
||||||
|
|
||||||
# Self-test code
|
# Self-test code
|
||||||
|
if __debug__:
|
||||||
|
def _test():
|
||||||
|
from collections import deque
|
||||||
|
|
||||||
def _test():
|
class BoundedQueue(_Verbose):
|
||||||
|
|
||||||
class BoundedQueue(_Verbose):
|
def __init__(self, limit):
|
||||||
|
_Verbose.__init__(self)
|
||||||
|
self.mon = RLock()
|
||||||
|
self.rc = Condition(self.mon)
|
||||||
|
self.wc = Condition(self.mon)
|
||||||
|
self.limit = limit
|
||||||
|
self.queue = deque()
|
||||||
|
|
||||||
def __init__(self, limit):
|
def put(self, item):
|
||||||
_Verbose.__init__(self)
|
self.mon.acquire()
|
||||||
self.mon = RLock()
|
while len(self.queue) >= self.limit:
|
||||||
self.rc = Condition(self.mon)
|
self._note("put(%s): queue full", item)
|
||||||
self.wc = Condition(self.mon)
|
self.wc.wait()
|
||||||
self.limit = limit
|
self.queue.append(item)
|
||||||
self.queue = deque()
|
self._note("put(%s): appended, length now %d",
|
||||||
|
item, len(self.queue))
|
||||||
|
self.rc.notify()
|
||||||
|
self.mon.release()
|
||||||
|
|
||||||
def put(self, item):
|
def get(self):
|
||||||
self.mon.acquire()
|
self.mon.acquire()
|
||||||
while len(self.queue) >= self.limit:
|
while not self.queue:
|
||||||
self._note("put(%s): queue full", item)
|
self._note("get(): queue empty")
|
||||||
self.wc.wait()
|
self.rc.wait()
|
||||||
self.queue.append(item)
|
item = self.queue.popleft()
|
||||||
self._note("put(%s): appended, length now %d",
|
self._note("get(): got %s, %d left", item, len(self.queue))
|
||||||
item, len(self.queue))
|
self.wc.notify()
|
||||||
self.rc.notify()
|
self.mon.release()
|
||||||
self.mon.release()
|
return item
|
||||||
|
|
||||||
def get(self):
|
class ProducerThread(Thread):
|
||||||
self.mon.acquire()
|
|
||||||
while not self.queue:
|
|
||||||
self._note("get(): queue empty")
|
|
||||||
self.rc.wait()
|
|
||||||
item = self.queue.popleft()
|
|
||||||
self._note("get(): got %s, %d left", item, len(self.queue))
|
|
||||||
self.wc.notify()
|
|
||||||
self.mon.release()
|
|
||||||
return item
|
|
||||||
|
|
||||||
class ProducerThread(Thread):
|
def __init__(self, queue, quota):
|
||||||
|
Thread.__init__(self, name="Producer")
|
||||||
|
self.queue = queue
|
||||||
|
self.quota = quota
|
||||||
|
|
||||||
def __init__(self, queue, quota):
|
def run(self):
|
||||||
Thread.__init__(self, name="Producer")
|
from random import random
|
||||||
self.queue = queue
|
counter = 0
|
||||||
self.quota = quota
|
while counter < self.quota:
|
||||||
|
counter = counter + 1
|
||||||
def run(self):
|
self.queue.put("%s.%d" % (self.getName(), counter))
|
||||||
from random import random
|
_sleep(random() * 0.00001)
|
||||||
counter = 0
|
|
||||||
while counter < self.quota:
|
|
||||||
counter = counter + 1
|
|
||||||
self.queue.put("%s.%d" % (self.getName(), counter))
|
|
||||||
_sleep(random() * 0.00001)
|
|
||||||
|
|
||||||
|
|
||||||
class ConsumerThread(Thread):
|
class ConsumerThread(Thread):
|
||||||
|
|
||||||
def __init__(self, queue, count):
|
def __init__(self, queue, count):
|
||||||
Thread.__init__(self, name="Consumer")
|
Thread.__init__(self, name="Consumer")
|
||||||
self.queue = queue
|
self.queue = queue
|
||||||
self.count = count
|
self.count = count
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
while self.count > 0:
|
while self.count > 0:
|
||||||
item = self.queue.get()
|
item = self.queue.get()
|
||||||
print item
|
print item
|
||||||
self.count = self.count - 1
|
self.count = self.count - 1
|
||||||
|
|
||||||
NP = 3
|
NP = 3
|
||||||
QL = 4
|
QL = 4
|
||||||
NI = 5
|
NI = 5
|
||||||
|
|
||||||
Q = BoundedQueue(QL)
|
Q = BoundedQueue(QL)
|
||||||
P = []
|
P = []
|
||||||
for i in range(NP):
|
for i in range(NP):
|
||||||
t = ProducerThread(Q, NI)
|
t = ProducerThread(Q, NI)
|
||||||
t.setName("Producer-%d" % (i+1))
|
t.setName("Producer-%d" % (i+1))
|
||||||
P.append(t)
|
P.append(t)
|
||||||
C = ConsumerThread(Q, NI*NP)
|
C = ConsumerThread(Q, NI*NP)
|
||||||
for t in P:
|
for t in P:
|
||||||
t.start()
|
t.start()
|
||||||
_sleep(0.000001)
|
_sleep(0.000001)
|
||||||
C.start()
|
C.start()
|
||||||
for t in P:
|
for t in P:
|
||||||
t.join()
|
t.join()
|
||||||
C.join()
|
C.join()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
_test()
|
_test()
|
||||||
|
@ -12,6 +12,7 @@ from direct.showbase.PythonUtil import *
|
|||||||
from direct.showbase.MessengerGlobal import messenger
|
from direct.showbase.MessengerGlobal import messenger
|
||||||
import types
|
import types
|
||||||
import random
|
import random
|
||||||
|
import importlib
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import signal
|
import signal
|
||||||
@ -591,7 +592,6 @@ class TaskManager:
|
|||||||
def popupControls(self):
|
def popupControls(self):
|
||||||
# Don't use a regular import, to prevent ModuleFinder from picking
|
# Don't use a regular import, to prevent ModuleFinder from picking
|
||||||
# it up as a dependency when building a .p3d package.
|
# it up as a dependency when building a .p3d package.
|
||||||
import importlib
|
|
||||||
TaskManagerPanel = importlib.import_module('direct.tkpanels.TaskManagerPanel')
|
TaskManagerPanel = importlib.import_module('direct.tkpanels.TaskManagerPanel')
|
||||||
return TaskManagerPanel.TaskManagerPanel(self)
|
return TaskManagerPanel.TaskManagerPanel(self)
|
||||||
|
|
||||||
@ -602,8 +602,8 @@ class TaskManager:
|
|||||||
|
|
||||||
# Defer this import until we need it: some Python
|
# Defer this import until we need it: some Python
|
||||||
# distributions don't provide the profile and pstats modules.
|
# distributions don't provide the profile and pstats modules.
|
||||||
from direct.showbase.ProfileSession import ProfileSession
|
PS = importlib.import_module('direct.showbase.ProfileSession')
|
||||||
return ProfileSession(name)
|
return PS.ProfileSession(name)
|
||||||
|
|
||||||
def profileFrames(self, num=None, session=None, callback=None):
|
def profileFrames(self, num=None, session=None, callback=None):
|
||||||
if num is None:
|
if num is None:
|
||||||
@ -629,8 +629,8 @@ class TaskManager:
|
|||||||
self._profileFrames.set(profileFrames)
|
self._profileFrames.set(profileFrames)
|
||||||
if (not self._frameProfiler) and profileFrames:
|
if (not self._frameProfiler) and profileFrames:
|
||||||
# import here due to import dependencies
|
# import here due to import dependencies
|
||||||
from direct.task.FrameProfiler import FrameProfiler
|
FP = importlib.import_module('direct.task.FrameProfiler')
|
||||||
self._frameProfiler = FrameProfiler()
|
self._frameProfiler = FP.FrameProfiler()
|
||||||
|
|
||||||
def getProfileTasks(self):
|
def getProfileTasks(self):
|
||||||
return self._profileTasks.get()
|
return self._profileTasks.get()
|
||||||
@ -642,8 +642,8 @@ class TaskManager:
|
|||||||
self._profileTasks.set(profileTasks)
|
self._profileTasks.set(profileTasks)
|
||||||
if (not self._taskProfiler) and profileTasks:
|
if (not self._taskProfiler) and profileTasks:
|
||||||
# import here due to import dependencies
|
# import here due to import dependencies
|
||||||
from direct.task.TaskProfiler import TaskProfiler
|
TP = importlib.import_module('direct.task.TaskProfiler')
|
||||||
self._taskProfiler = TaskProfiler()
|
self._taskProfiler = TP.TaskProfiler()
|
||||||
|
|
||||||
def logTaskProfiles(self, name=None):
|
def logTaskProfiles(self, name=None):
|
||||||
if self._taskProfiler:
|
if self._taskProfiler:
|
||||||
@ -689,9 +689,9 @@ class TaskManager:
|
|||||||
|
|
||||||
# Defer this import until we need it: some Python
|
# Defer this import until we need it: some Python
|
||||||
# distributions don't provide the profile and pstats modules.
|
# distributions don't provide the profile and pstats modules.
|
||||||
from direct.showbase.ProfileSession import ProfileSession
|
PS = importlib.import_module('direct.showbase.ProfileSession')
|
||||||
profileSession = ProfileSession('profiled-task-%s' % task.getName(),
|
profileSession = PS.ProfileSession('profiled-task-%s' % task.getName(),
|
||||||
Functor(profileInfo.taskFunc, *profileInfo.taskArgs))
|
Functor(profileInfo.taskFunc, *profileInfo.taskArgs))
|
||||||
ret = profileSession.run()
|
ret = profileSession.run()
|
||||||
|
|
||||||
# set these values *after* profiling in case we're profiling the TaskProfiler
|
# set these values *after* profiling in case we're profiling the TaskProfiler
|
||||||
|
Loading…
x
Reference in New Issue
Block a user