Browse Source

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

rdb 9 years ago
parent
commit
0d03207d1b

+ 3 - 1
direct/src/directutil/Verify.py

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

+ 0 - 8
direct/src/gui/DirectGuiBase.py

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

+ 0 - 7
direct/src/interval/ProjectileInterval.py

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

+ 3 - 3
direct/src/showbase/ExceptionVarDump.py

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

+ 3 - 3
direct/src/showbase/GarbageReport.py

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

+ 2 - 7
direct/src/showbase/ObjectPool.py

@@ -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:
-                    for line in getNumberedTypedSortedStringWithReferrersGen(self._type2objs[typ]):
-                        print line
-                else:
-                    print getNumberedTypedSortedString(self._type2objs[typ])
+                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
+ 431 - 494
direct/src/showbase/PythonUtil.py


+ 59 - 48
direct/src/showbase/ShowBase.py

@@ -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 direct.showbase import PythonUtil
-#from direct.interval.IntervalManager import ivalMgr
+#from PythonUtil import *
 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()
-        builtins.onScreenDebug = self.onScreenDebug
+            self.onScreenDebug = OnScreenDebug.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
-                self.particleMgr = particleMgr
+                PMG = importlib.import_module('direct.particles.ParticleManagerGlobal')
+                self.particleMgr = PMG.particleMgr
                 self.particleMgr.setFrameStepping(1)
                 self.particleMgr.setFrameStepping(1)
 
 
             if not self.physicsMgr:
             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.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
-        # as we reasonably can before the renderFrame().
-        self.onScreenDebug.render()
+        if __debug__:
+            # We render the watch variables for the onScreenDebug as soon
+            # 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
-        # as we reasonably can after the renderFrame().
-        self.onScreenDebug.clear()
+        if __debug__:
+            # We clear the text buffer for the onScreenDebug as soon
+            # 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
-        # as we reasonably can before the renderFrame().
-        self.onScreenDebug.render()
+        if __debug__:
+            # We render the watch variables for the onScreenDebug as soon
+            # 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
-        # as we reasonably can after the renderFrame().
-        self.onScreenDebug.clear()
+        if __debug__:
+            # We clear the text buffer for the onScreenDebug as soon
+            # 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
-        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):
     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:
-                    GarbageReport.b_checkForGarbageLeaks()
+                if __debug__:
+                    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:
-                    GarbageReport.b_checkForGarbageLeaks()
+                if __debug__:
+                    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
-        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.
         # 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
-            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()
             self.direct.enable()
             builtins.direct = self.direct
             builtins.direct = self.direct
         else:
         else:

+ 1 - 1
direct/src/showbase/Transitions.py

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

+ 2 - 2
direct/src/showutil/FreezeTool.py

@@ -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',
-    '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.
 # These are missing modules that we've reported already this session.

+ 7 - 0
direct/src/stdpy/thread.py

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

+ 106 - 105
direct/src/stdpy/threading.py

@@ -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 = threading2._newname()
+            name = _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():
-
-    from collections import deque
-    _sleep = core.Thread.sleep
-
-    _VERBOSE = False
-
-    class _Verbose(object):
-
-        def __init__(self, verbose=None):
-            if verbose is None:
-                verbose = _VERBOSE
-            self.__verbose = verbose
-
-        def _note(self, format, *args):
-            if self.__verbose:
-                format = format % args
-                format = "%s: %s\n" % (
-                    currentThread().getName(), format)
-                _sys.stderr.write(format)
-
-    class BoundedQueue(_Verbose):
-
-        def __init__(self, limit):
-            _Verbose.__init__(self)
-            self.mon = Lock(name = "BoundedQueue.mon")
-            self.rc = Condition(self.mon)
-            self.wc = Condition(self.mon)
-            self.limit = limit
-            self.queue = deque()
-
-        def put(self, item):
-            self.mon.acquire()
-            while len(self.queue) >= self.limit:
-                self._note("put(%s): queue full", item)
-                self.wc.wait()
-            self.queue.append(item)
-            self._note("put(%s): appended, length now %d",
-                       item, len(self.queue))
-            self.rc.notify()
-            self.mon.release()
-
-        def get(self):
-            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 run(self):
-            from random import random
-            counter = 0
-            while counter < self.quota:
-                counter = counter + 1
-                self.queue.put("%s.%d" % (self.getName(), counter))
-                _sleep(random() * 0.00001)
-
-
-    class ConsumerThread(Thread):
-
-        def __init__(self, queue, count):
-            Thread.__init__(self, name="Consumer")
-            self.queue = queue
-            self.count = count
-
-        def run(self):
-            while self.count > 0:
-                item = self.queue.get()
-                print item
-                self.count = self.count - 1
-
-    NP = 3
-    QL = 4
-    NI = 5
-
-    Q = BoundedQueue(QL)
-    P = []
-    for i in range(NP):
-        t = ProducerThread(Q, NI)
-        t.setName("Producer-%d" % (i+1))
-        P.append(t)
-    C = ConsumerThread(Q, NI*NP)
-    for t in P:
-        t.start()
-        _sleep(0.000001)
-    C.start()
-    for t in P:
-        t.join()
-    C.join()
-
-if __name__ == '__main__':
-    _test()
+if __debug__:
+    def _test():
+        from collections import deque
+
+        _sleep = core.Thread.sleep
+
+        _VERBOSE = False
+
+        class _Verbose(object):
+
+            def __init__(self, verbose=None):
+                if verbose is None:
+                    verbose = _VERBOSE
+                self.__verbose = verbose
+
+            def _note(self, format, *args):
+                if self.__verbose:
+                    format = format % args
+                    format = "%s: %s\n" % (
+                        currentThread().getName(), format)
+                    _sys.stderr.write(format)
+
+        class BoundedQueue(_Verbose):
+
+            def __init__(self, limit):
+                _Verbose.__init__(self)
+                self.mon = Lock(name = "BoundedQueue.mon")
+                self.rc = Condition(self.mon)
+                self.wc = Condition(self.mon)
+                self.limit = limit
+                self.queue = deque()
+
+            def put(self, item):
+                self.mon.acquire()
+                while len(self.queue) >= self.limit:
+                    self._note("put(%s): queue full", item)
+                    self.wc.wait()
+                self.queue.append(item)
+                self._note("put(%s): appended, length now %d",
+                           item, len(self.queue))
+                self.rc.notify()
+                self.mon.release()
+
+            def get(self):
+                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 run(self):
+                from random import random
+                counter = 0
+                while counter < self.quota:
+                    counter = counter + 1
+                    self.queue.put("%s.%d" % (self.getName(), counter))
+                    _sleep(random() * 0.00001)
+
+
+        class ConsumerThread(Thread):
+
+            def __init__(self, queue, count):
+                Thread.__init__(self, name="Consumer")
+                self.queue = queue
+                self.count = count
+
+            def run(self):
+                while self.count > 0:
+                    item = self.queue.get()
+                    print item
+                    self.count = self.count - 1
+
+        NP = 3
+        QL = 4
+        NI = 5
+
+        Q = BoundedQueue(QL)
+        P = []
+        for i in range(NP):
+            t = ProducerThread(Q, NI)
+            t.setName("Producer-%d" % (i+1))
+            P.append(t)
+        C = ConsumerThread(Q, NI*NP)
+        for t in P:
+            t.start()
+            _sleep(0.000001)
+        C.start()
+        for t in P:
+            t.join()
+        C.join()
+
+    if __name__ == '__main__':
+        _test()

+ 86 - 93
direct/src/stdpy/threading2.py

@@ -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
+
+        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 put(self, item):
+                self.mon.acquire()
+                while len(self.queue) >= self.limit:
+                    self._note("put(%s): queue full", item)
+                    self.wc.wait()
+                self.queue.append(item)
+                self._note("put(%s): appended, length now %d",
+                           item, len(self.queue))
+                self.rc.notify()
+                self.mon.release()
+
+            def get(self):
+                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 run(self):
+                from random import random
+                counter = 0
+                while counter < self.quota:
+                    counter = counter + 1
+                    self.queue.put("%s.%d" % (self.getName(), counter))
+                    _sleep(random() * 0.00001)
+
+
+        class ConsumerThread(Thread):
+
+            def __init__(self, queue, count):
+                Thread.__init__(self, name="Consumer")
+                self.queue = queue
+                self.count = count
+
+            def run(self):
+                while self.count > 0:
+                    item = self.queue.get()
+                    print item
+                    self.count = self.count - 1
+
+        NP = 3
+        QL = 4
+        NI = 5
+
+        Q = BoundedQueue(QL)
+        P = []
+        for i in range(NP):
+            t = ProducerThread(Q, NI)
+            t.setName("Producer-%d" % (i+1))
+            P.append(t)
+        C = ConsumerThread(Q, NI*NP)
+        for t in P:
+            t.start()
+            _sleep(0.000001)
+        C.start()
+        for t in P:
+            t.join()
+        C.join()
 
 
-def _test():
-
-    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 put(self, item):
-            self.mon.acquire()
-            while len(self.queue) >= self.limit:
-                self._note("put(%s): queue full", item)
-                self.wc.wait()
-            self.queue.append(item)
-            self._note("put(%s): appended, length now %d",
-                       item, len(self.queue))
-            self.rc.notify()
-            self.mon.release()
-
-        def get(self):
-            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 run(self):
-            from random import random
-            counter = 0
-            while counter < self.quota:
-                counter = counter + 1
-                self.queue.put("%s.%d" % (self.getName(), counter))
-                _sleep(random() * 0.00001)
-
-
-    class ConsumerThread(Thread):
-
-        def __init__(self, queue, count):
-            Thread.__init__(self, name="Consumer")
-            self.queue = queue
-            self.count = count
-
-        def run(self):
-            while self.count > 0:
-                item = self.queue.get()
-                print item
-                self.count = self.count - 1
-
-    NP = 3
-    QL = 4
-    NI = 5
-
-    Q = BoundedQueue(QL)
-    P = []
-    for i in range(NP):
-        t = ProducerThread(Q, NI)
-        t.setName("Producer-%d" % (i+1))
-        P.append(t)
-    C = ConsumerThread(Q, NI*NP)
-    for t in P:
-        t.start()
-        _sleep(0.000001)
-    C.start()
-    for t in P:
-        t.join()
-    C.join()
-
-if __name__ == '__main__':
-    _test()
+    if __name__ == '__main__':
+        _test()

+ 10 - 10
direct/src/task/Task.py

@@ -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
-        return ProfileSession(name)
+        PS = importlib.import_module('direct.showbase.ProfileSession')
+        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
-            self._frameProfiler = FrameProfiler()
+            FP = importlib.import_module('direct.task.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
-            self._taskProfiler = TaskProfiler()
+            TP = importlib.import_module('direct.task.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
-        profileSession = ProfileSession('profiled-task-%s' % task.getName(),
-                                        Functor(profileInfo.taskFunc, *profileInfo.taskArgs))
+        PS = importlib.import_module('direct.showbase.ProfileSession')
+        profileSession = PS.ProfileSession('profiled-task-%s' % task.getName(),
+                                           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

Some files were not shown because too many files changed in this diff