Browse Source

Merge branch 'master' into webgl-port

rdb 8 years ago
parent
commit
d7f0f82859
100 changed files with 1510 additions and 1026 deletions
  1. 5 0
      .gitignore
  2. 9 2
      .travis.yml
  3. 22 0
      README.md
  4. 94 0
      direct/src/actor/Actor.py
  5. 7 0
      direct/src/actor/__init__.py
  6. 13 0
      direct/src/controls/InputState.py
  7. 4 0
      direct/src/controls/__init__.py
  8. 16 1
      direct/src/directbase/DirectStart.py
  9. 12 0
      direct/src/directbase/__init__.py
  10. 51 28
      direct/src/directdevices/DirectDeviceManager.py
  11. 1 1
      direct/src/directdevices/DirectRadamec.py
  12. 5 0
      direct/src/directdevices/__init__.py
  13. 3 0
      direct/src/directnotify/__init__.py
  14. 8 0
      direct/src/directtools/__init__.py
  15. 3 0
      direct/src/directutil/__init__.py
  16. 8 6
      direct/src/distributed/DistributedSmoothNode.py
  17. 5 0
      direct/src/distributed/__init__.py
  18. 4 1
      direct/src/extensions_native/__init__.py
  19. 21 0
      direct/src/filter/CommonFilters.py
  20. 12 0
      direct/src/filter/FilterManager.py
  21. 11 0
      direct/src/filter/__init__.py
  22. 3 2
      direct/src/filter/filter-bloomx.sha
  23. 3 2
      direct/src/filter/filter-bloomy.sha
  24. 6 4
      direct/src/filter/filter-blurx.sha
  25. 6 4
      direct/src/filter/filter-blury.sha
  26. 6 6
      direct/src/fsm/ClassicFSM.py
  27. 1 1
      direct/src/fsm/FSM.py
  28. 2 4
      direct/src/fsm/FourState.py
  29. 2 4
      direct/src/fsm/FourStateAI.py
  30. 6 0
      direct/src/fsm/__init__.py
  31. 1 1
      direct/src/gui/DirectButton.py
  32. 3 1
      direct/src/gui/DirectCheckButton.py
  33. 1 1
      direct/src/gui/DirectDialog.py
  34. 2 1
      direct/src/gui/DirectEntry.py
  35. 14 9
      direct/src/gui/DirectFrame.py
  36. 24 25
      direct/src/gui/DirectGuiBase.py
  37. 3 5
      direct/src/gui/DirectGuiGlobals.py
  38. 1 1
      direct/src/gui/DirectLabel.py
  39. 1 1
      direct/src/gui/DirectOptionMenu.py
  40. 4 1
      direct/src/gui/DirectRadioButton.py
  41. 1 1
      direct/src/gui/DirectScrollBar.py
  42. 1 1
      direct/src/gui/DirectScrolledFrame.py
  43. 1 1
      direct/src/gui/DirectScrolledList.py
  44. 1 1
      direct/src/gui/DirectSlider.py
  45. 1 1
      direct/src/gui/DirectWaitBar.py
  46. 16 1
      direct/src/gui/OnscreenText.py
  47. 12 0
      direct/src/gui/__init__.py
  48. 4 1
      direct/src/interval/IntervalGlobal.py
  49. 3 3
      direct/src/interval/IntervalManager.py
  50. 4 1
      direct/src/interval/MetaInterval.py
  51. 2 4
      direct/src/interval/ParticleInterval.py
  52. 3 5
      direct/src/interval/TestInterval.py
  53. 12 0
      direct/src/interval/__init__.py
  54. 3 0
      direct/src/motiontrail/__init__.py
  55. 5 2
      direct/src/p3d/AppRunner.py
  56. 4 0
      direct/src/p3d/__init__.py
  57. 7 0
      direct/src/particles/__init__.py
  58. 2 0
      direct/src/showbase/AppRunnerGlobal.py
  59. 25 1
      direct/src/showbase/Audio3DManager.py
  60. 3 1
      direct/src/showbase/BufferViewer.py
  61. 1 1
      direct/src/showbase/BulletinBoard.py
  62. 1 1
      direct/src/showbase/BulletinBoardWatcher.py
  63. 14 1
      direct/src/showbase/DirectObject.py
  64. 1 1
      direct/src/showbase/EventGroup.py
  65. 2 1
      direct/src/showbase/EventManager.py
  66. 2 1
      direct/src/showbase/EventManagerGlobal.py
  67. 1 1
      direct/src/showbase/Factory.py
  68. 2 4
      direct/src/showbase/FindCtaPaths.py
  69. 1 1
      direct/src/showbase/Finder.py
  70. 1 1
      direct/src/showbase/GarbageReport.py
  71. 15 3
      direct/src/showbase/Messenger.py
  72. 2 4
      direct/src/showbase/MirrorDemo.py
  73. 1 1
      direct/src/showbase/ObjectPool.py
  74. 10 12
      direct/src/showbase/ObjectReport.py
  75. 1 1
      direct/src/showbase/OnScreenDebug.py
  76. 7 10
      direct/src/showbase/Pool.py
  77. 2 4
      direct/src/showbase/SfxPlayer.py
  78. 2 5
      direct/src/showbase/ShadowDemo.py
  79. 2 4
      direct/src/showbase/ShadowPlacer.py
  80. 4 1
      direct/src/showbase/TaskThreaded.py
  81. 2 1
      direct/src/showbase/ThreeUpShow.py
  82. 3 1
      direct/src/showbase/Transitions.py
  83. 4 1
      direct/src/showbase/VerboseImport.py
  84. 90 83
      direct/src/showutil/pfreeze.py
  85. 5 0
      direct/src/stdpy/__init__.py
  86. 35 11
      direct/src/stdpy/thread.py
  87. 33 11
      direct/src/stdpy/threading.py
  88. 43 26
      direct/src/stdpy/threading2.py
  89. 1 0
      direct/src/task/TaskManagerGlobal.py
  90. 4 3
      direct/src/task/TaskTester.py
  91. 1 1
      direct/src/task/Timer.py
  92. 8 0
      direct/src/task/__init__.py
  93. 1 1
      direct/src/tkpanels/NotifyPanel.py
  94. 4 1
      direct/src/tkwidgets/SceneGraphExplorer.py
  95. 1 1
      direct/src/tkwidgets/Tree.py
  96. 1 1
      direct/src/tkwidgets/WidgetPropertiesDialog.py
  97. 671 683
      dtool/src/cppparser/cppBison.cxx.prebuilt
  98. 15 2
      dtool/src/cppparser/cppBison.yxx
  99. 2 2
      dtool/src/dtoolbase/deletedBufferChain.cxx
  100. 1 3
      dtool/src/dtoolbase/dtool_platform.h

+ 5 - 0
.gitignore

@@ -8,6 +8,7 @@
 core
 core
 core.*
 core.*
 vgcore.*
 vgcore.*
+*.core
 
 
 # Editor files/directories
 # Editor files/directories
 *.save
 *.save
@@ -22,6 +23,9 @@ vgcore.*
 *.o
 *.o
 *.gch
 *.gch
 *.pch
 *.pch
+/+DESC
+/+MANIFEST
+/pkg-plist
 
 
 # Produced installer/executables
 # Produced installer/executables
 /*.exe
 /*.exe
@@ -31,6 +35,7 @@ vgcore.*
 /*.pkg
 /*.pkg
 /*.dmg
 /*.dmg
 /*.whl
 /*.whl
+/*.txz
 
 
 # CMake
 # CMake
 /build/
 /build/

+ 9 - 2
.travis.yml

@@ -2,15 +2,22 @@ language: cpp
 sudo: false
 sudo: false
 matrix:
 matrix:
   include:
   include:
-    - compiler: gcc
-      env: PYTHONV=python2.7 FLAGS=--optimize=4
     - compiler: clang
     - compiler: clang
       env: PYTHONV=python3 FLAGS=--installer
       env: PYTHONV=python3 FLAGS=--installer
     - compiler: clang
     - compiler: clang
       env: PYTHONV=python2.7 FLAGS=--override=STDFLOAT_DOUBLE=1
       env: PYTHONV=python2.7 FLAGS=--override=STDFLOAT_DOUBLE=1
+    - compiler: gcc
+      env: PYTHONV=python2.7 FLAGS=--optimize=4
+      before_install:
+        - export CC=gcc-4.7
+        - export CXX=g++-4.7
 addons:
 addons:
   apt:
   apt:
+    sources:
+    - ubuntu-toolchain-r-test
     packages:
     packages:
+    - gcc-4.7
+    - g++-4.7
     - bison
     - bison
     - flex
     - flex
     - libfreetype6-dev
     - libfreetype6-dev

+ 22 - 0
README.md

@@ -134,6 +134,28 @@ If the build was successful, makepanda will have generated a .dmg file in
 the source directory containing the installer.  Simply open it and run the
 the source directory containing the installer.  Simply open it and run the
 package file in order to install the SDK onto your system.
 package file in order to install the SDK onto your system.
 
 
+FreeBSD
+-------
+
+Building on FreeBSD is very similar to building on Linux.  You will need to
+install the requisite packages using the system package manager.  To install
+the recommended set of dependencies, you can use this command:
+
+```bash
+pkg install pkgconf png jpeg-turbo tiff freetype2 eigen squish openal opusfile libvorbis libX11 libGL ode bullet assimp openexr
+```
+
+You will also need to choose which version of Python you want to use.
+Install the appropriate package for it (such as `python2` or `python36`) and
+run the makepanda script with your chosen Python version:
+
+```bash
+python3.6 makepanda/makepanda.py --everything --installer --no-egl --no-gles --no-gles2
+```
+
+If successful, this will produce a .pkg file in the root of the source
+directory which you can install using `pkg install`.
+
 Reporting Issues
 Reporting Issues
 ================
 ================
 
 

+ 94 - 0
direct/src/actor/Actor.py

@@ -50,6 +50,10 @@ class Actor(DirectObject, NodePath):
         def __repr__(self):
         def __repr__(self):
             return 'Actor.PartDef(%s, %s)' % (repr(self.partBundleNP), repr(self.partModel))
             return 'Actor.PartDef(%s, %s)' % (repr(self.partBundleNP), repr(self.partModel))
 
 
+
+        #snake_case alias:
+        get_bundle = getBundle
+
     class AnimDef:
     class AnimDef:
 
 
         """Instances of this class are stored within the
         """Instances of this class are stored within the
@@ -72,6 +76,10 @@ class Actor(DirectObject, NodePath):
         def __repr__(self):
         def __repr__(self):
             return 'Actor.AnimDef(%s)' % (repr(self.filename))
             return 'Actor.AnimDef(%s)' % (repr(self.filename))
 
 
+
+        #snake_case alias:
+        make_copy = makeCopy
+
     class SubpartDef:
     class SubpartDef:
 
 
         """Instances of this class are stored within the SubpartDict
         """Instances of this class are stored within the SubpartDict
@@ -2549,3 +2557,89 @@ class Actor(DirectObject, NodePath):
         for partBundleDict in self.__partBundleDict.values():
         for partBundleDict in self.__partBundleDict.values():
             partDef = partBundleDict.get(subpartDef.truePartName)
             partDef = partBundleDict.get(subpartDef.truePartName)
             partDef.getBundle().setName(newBundleName)
             partDef.getBundle().setName(newBundleName)
+
+    #snake_case alias:
+    control_joint = controlJoint
+    set_lod_animation = setLODAnimation
+    get_anim_control_dict = getAnimControlDict
+    get_actor_info = getActorInfo
+    clear_lod_animation = clearLODAnimation
+    reset_lod = resetLOD
+    fix_bounds = fixBounds
+    get_anim_filename = getAnimFilename
+    get_subparts_complete = getSubpartsComplete
+    verify_subparts_complete = verifySubpartsComplete
+    get_play_rate = getPlayRate
+    clear_python_data = clearPythonData
+    load_anims = loadAnims
+    set_subparts_complete = setSubpartsComplete
+    draw_in_front = drawInFront
+    get_lod_node = getLODNode
+    hide_part = hidePart
+    get_joint_transform_state = getJointTransformState
+    set_control_effect = setControlEffect
+    get_anim_controls = getAnimControls
+    release_joint = releaseJoint
+    print_anim_blends = printAnimBlends
+    get_lod = getLOD
+    disable_blend = disableBlend
+    show_part = showPart
+    get_joint_transform = getJointTransform
+    face_away_from_viewer = faceAwayFromViewer
+    set_lod = setLOD
+    osd_anim_blends = osdAnimBlends
+    get_current_frame = getCurrentFrame
+    set_play_rate = setPlayRate
+    bind_all_anims = bindAllAnims
+    unload_anims = unloadAnims
+    remove_part = removePart
+    use_lod = useLOD
+    get_anim_blends = getAnimBlends
+    get_lod_index = getLODIndex
+    get_num_frames = getNumFrames
+    post_flatten = postFlatten
+    get_lod_names = getLODNames
+    list_joints = listJoints
+    make_subpart = makeSubpart
+    get_anim_control = getAnimControl
+    get_part_bundle = getPartBundle
+    get_part_bundle_dict = getPartBundleDict
+    get_duration = getDuration
+    has_lod = hasLOD
+    print_lod = printLOD
+    fix_bounds_old = fixBounds_old
+    get_anim_names = getAnimNames
+    get_part_bundles = getPartBundles
+    anim_panel = animPanel
+    stop_joint = stopJoint
+    actor_interval = actorInterval
+    hide_all_bounds = hideAllBounds
+    show_all_bounds = showAllBounds
+    init_anims_on_all_lods = initAnimsOnAllLODs
+    get_part = getPart
+    add_lod = addLOD
+    show_all_parts = showAllParts
+    get_joints = getJoints
+    get_overlapping_joints = getOverlappingJoints
+    enable_blend = enableBlend
+    face_towards_viewer = faceTowardsViewer
+    bind_anim = bindAnim
+    set_blend = setBlend
+    get_frame_time = getFrameTime
+    remove_node = removeNode
+    wait_pending = waitPending
+    expose_joint = exposeJoint
+    set_lod_node = setLODNode
+    get_frame_rate = getFrameRate
+    get_current_anim = getCurrentAnim
+    get_part_names = getPartNames
+    freeze_joint = freezeJoint
+    set_center = setCenter
+    rename_part_bundles = renamePartBundles
+    get_geom_node = getGeomNode
+    set_geom_node = setGeomNode
+    load_model = loadModel
+    copy_actor = copyActor
+    get_base_frame_rate = getBaseFrameRate
+    remove_anim_control_dict = removeAnimControlDict
+    load_anims_on_all_lods = loadAnimsOnAllLODs

+ 7 - 0
direct/src/actor/__init__.py

@@ -0,0 +1,7 @@
+"""
+This package contains the :class:`.Actor` class as well as a
+distributed variant thereof.  Actor is a high-level interface around
+the lower-level :class:`panda3d.core.Character` implementation.
+It loads and controls an animated character and manages the animations
+playing on it.
+"""

+ 13 - 0
direct/src/controls/InputState.py

@@ -21,6 +21,9 @@ class InputStateToken:
     def __hash__(self):
     def __hash__(self):
         return self._hash
         return self._hash
 
 
+    #snake_case alias:
+    is_valid = isValid
+
 class InputStateWatchToken(InputStateToken, DirectObject.DirectObject):
 class InputStateWatchToken(InputStateToken, DirectObject.DirectObject):
     def release(self):
     def release(self):
         self._inputState._ignore(self)
         self._inputState._ignore(self)
@@ -39,6 +42,9 @@ class InputStateTokenGroup:
             token.release()
             token.release()
         self._tokens = []
         self._tokens = []
 
 
+    #snake_case alias:
+    add_token = addToken
+
 class InputState(DirectObject.DirectObject):
 class InputState(DirectObject.DirectObject):
     """
     """
     InputState is for tracking the on/off state of some events.
     InputState is for tracking the on/off state of some events.
@@ -235,3 +241,10 @@ class InputState(DirectObject.DirectObject):
         """for debugging"""
         """for debugging"""
         return self.notify.debug(
         return self.notify.debug(
             "%s (%s) %s"%(id(self), len(self._state), message))
             "%s (%s) %s"%(id(self), len(self._state), message))
+
+    #snake_case alias:
+    watch_with_modifiers = watchWithModifiers
+    is_set = isSet
+    get_event_name = getEventName
+    debug_print = debugPrint
+    release_inputs = releaseInputs

+ 4 - 0
direct/src/controls/__init__.py

@@ -0,0 +1,4 @@
+"""
+This package contains various types of character controllers, handling basic
+control mechanics and setting up collisions for them.
+"""

+ 16 - 1
direct/src/directbase/DirectStart.py

@@ -1,4 +1,19 @@
-""" This is a deprecated module that creates a global instance of ShowBase. """
+"""
+This is a shortcut that instantiates ShowBase automatically on import,
+opening a graphical window and setting up the scene graph.
+This example demonstrates its use:
+
+   import direct.directbase.DirectStart
+   run()
+
+While it may be considered useful for quick prototyping in the interactive
+Python shell, using it in applications is not considered good style.
+As such, it has been deprecated starting with Panda3D 1.9.  It is equivalent
+to and may be replaced by the following code:
+
+   from direct.showbase.ShowBase import ShowBase
+   base = ShowBase()
+"""
 
 
 __all__ = []
 __all__ = []
 
 

+ 12 - 0
direct/src/directbase/__init__.py

@@ -0,0 +1,12 @@
+"""
+This package contains modules to quickly set up a Panda environment for
+quick prototyping in the interactive Python shell.  Merely importing
+one of these modules will create a :class:`.ShowBase` instance, opening
+a graphical window and setting up the scene graph.
+
+The most commonly used module from this package is :mod:`.DirectStart`,
+importing which executes the following code::
+
+   from direct.showbase.ShowBase import ShowBase
+   base = ShowBase()
+"""

+ 51 - 28
direct/src/directdevices/DirectDeviceManager.py

@@ -9,10 +9,6 @@ ANALOG_MAX = 0.95
 ANALOG_DEADBAND = 0.125
 ANALOG_DEADBAND = 0.125
 ANALOG_CENTER = 0.0
 ANALOG_CENTER = 0.0
 
 
-try:
-    myBase = base
-except:
-    myBase = simbase
 
 
 class DirectDeviceManager(VrpnClient, DirectObject):
 class DirectDeviceManager(VrpnClient, DirectObject):
     def __init__(self, server = None):
     def __init__(self, server = None):
@@ -52,8 +48,13 @@ class DirectButtons(ButtonNode, DirectObject):
         ButtonNode.__init__(self, vrpnClient, device)
         ButtonNode.__init__(self, vrpnClient, device)
         # Create a unique name for this button object
         # Create a unique name for this button object
         self.name = 'DirectButtons-' + repr(DirectButtons.buttonCount)
         self.name = 'DirectButtons-' + repr(DirectButtons.buttonCount)
+
         # Attach node to data graph
         # Attach node to data graph
-        self.nodePath = myBase.dataRoot.attachNewNode(self)
+        try:
+            self._base = base
+        except:
+            self._base = simbase
+        self.nodePath = self._base.dataRoot.attachNewNode(self)
 
 
     def __getitem__(self, index):
     def __getitem__(self, index):
         if (index < 0) or (index >= self.getNumButtons()):
         if (index < 0) or (index >= self.getNumButtons()):
@@ -64,10 +65,10 @@ class DirectButtons(ButtonNode, DirectObject):
         return self.getNumButtons()
         return self.getNumButtons()
 
 
     def enable(self):
     def enable(self):
-        self.nodePath.reparentTo(myBase.dataRoot)
+        self.nodePath.reparentTo(self._base.dataRoot)
 
 
     def disable(self):
     def disable(self):
-        self.nodePath.reparentTo(myBase.dataUnused)
+        self.nodePath.reparentTo(self._base.dataUnused)
 
 
     def getName(self):
     def getName(self):
         return self.name
         return self.name
@@ -83,6 +84,12 @@ class DirectButtons(ButtonNode, DirectObject):
 
 
 class DirectAnalogs(AnalogNode, DirectObject):
 class DirectAnalogs(AnalogNode, DirectObject):
     analogCount = 0
     analogCount = 0
+
+    _analogDeadband = ConfigVariableDouble('vrpn-analog-deadband', ANALOG_DEADBAND)
+    _analogMin = ConfigVariableDouble('vrpn-analog-min', ANALOG_MIN)
+    _analogMax = ConfigVariableDouble('vrpn-analog-max', ANALOG_MAX)
+    _analogCenter = ConfigVariableDouble('vrpn-analog-center', ANALOG_CENTER)
+
     def __init__(self, vrpnClient, device):
     def __init__(self, vrpnClient, device):
         # Keep track of number of analogs created
         # Keep track of number of analogs created
         DirectAnalogs.analogCount += 1
         DirectAnalogs.analogCount += 1
@@ -90,20 +97,21 @@ class DirectAnalogs(AnalogNode, DirectObject):
         AnalogNode.__init__(self, vrpnClient, device)
         AnalogNode.__init__(self, vrpnClient, device)
         # Create a unique name for this analog object
         # Create a unique name for this analog object
         self.name = 'DirectAnalogs-' + repr(DirectAnalogs.analogCount)
         self.name = 'DirectAnalogs-' + repr(DirectAnalogs.analogCount)
+
         # Attach node to data graph
         # Attach node to data graph
-        self.nodePath = myBase.dataRoot.attachNewNode(self)
+        try:
+            self._base = base
+        except:
+            self._base = simbase
+        self.nodePath = self._base.dataRoot.attachNewNode(self)
+
         # See if any of the general analog parameters are dconfig'd
         # See if any of the general analog parameters are dconfig'd
-        self.analogDeadband = myBase.config.GetFloat('vrpn-analog-deadband',
-                                                     ANALOG_DEADBAND)
-        self.analogMin = myBase.config.GetFloat('vrpn-analog-min',
-                                                ANALOG_MIN)
-        self.analogMax = myBase.config.GetFloat('vrpn-analog-max',
-                                                ANALOG_MAX)
-        self.analogCenter = myBase.config.GetFloat('vrpn-analog-center',
-                                                   ANALOG_CENTER)
+        self.analogDeadband = self._analogDeadband.getValue()
+        self.analogMin = self._analogMin.getValue()
+        self.analogMax = self._analogMax.getValue()
+        self.analogCenter = self._analogCenter.getValue()
         self.analogRange = self.analogMax - self.analogMin
         self.analogRange = self.analogMax - self.analogMin
 
 
-
     def __getitem__(self, index):
     def __getitem__(self, index):
         if (index < 0) or (index >= self.getNumControls()):
         if (index < 0) or (index >= self.getNumControls()):
             raise IndexError
             raise IndexError
@@ -113,10 +121,10 @@ class DirectAnalogs(AnalogNode, DirectObject):
         return self.getNumControls()
         return self.getNumControls()
 
 
     def enable(self):
     def enable(self):
-        self.nodePath.reparentTo(myBase.dataRoot)
+        self.nodePath.reparentTo(self._base.dataRoot)
 
 
     def disable(self):
     def disable(self):
-        self.nodePath.reparentTo(myBase.dataUnused)
+        self.nodePath.reparentTo(self._base.dataUnused)
 
 
     def normalizeWithoutCentering(self, val, minVal = -1, maxVal = 1):
     def normalizeWithoutCentering(self, val, minVal = -1, maxVal = 1):
         #
         #
@@ -186,14 +194,19 @@ class DirectTracker(TrackerNode, DirectObject):
         TrackerNode.__init__(self, vrpnClient, device)
         TrackerNode.__init__(self, vrpnClient, device)
         # Create a unique name for this tracker object
         # Create a unique name for this tracker object
         self.name = 'DirectTracker-' + repr(DirectTracker.trackerCount)
         self.name = 'DirectTracker-' + repr(DirectTracker.trackerCount)
+
         # Attach node to data graph
         # Attach node to data graph
-        self.nodePath = myBase.dataRoot.attachNewNode(self)
+        try:
+            self._base = base
+        except:
+            self._base = simbase
+        self.nodePath = self._base.dataRoot.attachNewNode(self)
 
 
     def enable(self):
     def enable(self):
-        self.nodePath.reparentTo(myBase.dataRoot)
+        self.nodePath.reparentTo(self._base.dataRoot)
 
 
     def disable(self):
     def disable(self):
-        self.nodePath.reparentTo(myBase.dataUnused)
+        self.nodePath.reparentTo(self._base.dataUnused)
 
 
     def getName(self):
     def getName(self):
         return self.name
         return self.name
@@ -213,8 +226,13 @@ class DirectDials(DialNode, DirectObject):
         DialNode.__init__(self, vrpnClient, device)
         DialNode.__init__(self, vrpnClient, device)
         # Create a unique name for this dial object
         # Create a unique name for this dial object
         self.name = 'DirectDials-' + repr(DirectDials.dialCount)
         self.name = 'DirectDials-' + repr(DirectDials.dialCount)
+
         # Attach node to data graph
         # Attach node to data graph
-        self.nodePath = myBase.dataRoot.attachNewNode(self)
+        try:
+            self._base = base
+        except:
+            self._base = simbase
+        self.nodePath = self._base.dataRoot.attachNewNode(self)
 
 
     def __getitem__(self, index):
     def __getitem__(self, index):
         """
         """
@@ -227,10 +245,10 @@ class DirectDials(DialNode, DirectObject):
         return self.getNumDials()
         return self.getNumDials()
 
 
     def enable(self):
     def enable(self):
-        self.nodePath.reparentTo(myBase.dataRoot)
+        self.nodePath.reparentTo(self._base.dataRoot)
 
 
     def disable(self):
     def disable(self):
-        self.nodePath.reparentTo(myBase.dataUnused)
+        self.nodePath.reparentTo(self._base.dataUnused)
 
 
     def getName(self):
     def getName(self):
         return self.name
         return self.name
@@ -259,14 +277,19 @@ class DirectTimecodeReader(AnalogNode, DirectObject):
         self.seconds = 0
         self.seconds = 0
         self.minutes = 0
         self.minutes = 0
         self.hours = 0
         self.hours = 0
+
         # Attach node to data graph
         # Attach node to data graph
-        self.nodePath = myBase.dataRoot.attachNewNode(self)
+        try:
+            self._base = base
+        except:
+            self._base = simbase
+        self.nodePath = self._base.dataRoot.attachNewNode(self)
 
 
     def enable(self):
     def enable(self):
-        self.nodePath.reparentTo(myBase.dataRoot)
+        self.nodePath.reparentTo(self._base.dataRoot)
 
 
     def disable(self):
     def disable(self):
-        self.nodePath.reparentTo(myBase.dataUnused)
+        self.nodePath.reparentTo(self._base.dataUnused)
 
 
     def getName(self):
     def getName(self):
         return self.name
         return self.name

+ 1 - 1
direct/src/directdevices/DirectRadamec.py

@@ -21,7 +21,7 @@ class DirectRadamec(DirectObject):
     radamecCount = 0
     radamecCount = 0
     notify = DirectNotifyGlobal.directNotify.newCategory('DirectRadamec')
     notify = DirectNotifyGlobal.directNotify.newCategory('DirectRadamec')
 
 
-    def __init__(self, device = 'Analog0', nodePath = base.direct.camera):
+    def __init__(self, device = 'Analog0', nodePath = None):
         # See if device manager has been initialized
         # See if device manager has been initialized
         if base.direct.deviceManager == None:
         if base.direct.deviceManager == None:
             base.direct.deviceManager = DirectDeviceManager()
             base.direct.deviceManager = DirectDeviceManager()

+ 5 - 0
direct/src/directdevices/__init__.py

@@ -0,0 +1,5 @@
+"""
+This package contains a high-level interface for VRPN devices.
+
+Also see the :mod:`panda3d.vprn` module.
+"""

+ 3 - 0
direct/src/directnotify/__init__.py

@@ -0,0 +1,3 @@
+"""
+This package contains notification and logging utilities for Python code.
+"""

+ 8 - 0
direct/src/directtools/__init__.py

@@ -0,0 +1,8 @@
+"""
+This package contains the DIRECT tools, a set of tkinter tools for exploring
+and manipulating the Panda3D scene graph.  By default, these are disabled,
+but they can be explicitly enabled using the following PRC configuration::
+
+   want-directtools true
+   want-tk true
+"""

+ 3 - 0
direct/src/directutil/__init__.py

@@ -0,0 +1,3 @@
+"""
+This package contains assorted utility classes.
+"""

+ 8 - 6
direct/src/distributed/DistributedSmoothNode.py

@@ -7,19 +7,21 @@ from . import DistributedNode
 from . import DistributedSmoothNodeBase
 from . import DistributedSmoothNodeBase
 from direct.task.Task import cont
 from direct.task.Task import cont
 
 
+config = get_config_showbase()
+
 # This number defines our tolerance for out-of-sync telemetry packets.
 # This number defines our tolerance for out-of-sync telemetry packets.
 # If a packet appears to have originated from more than MaxFuture
 # If a packet appears to have originated from more than MaxFuture
 # seconds in the future, assume we're out of sync with the other
 # seconds in the future, assume we're out of sync with the other
 # avatar and suggest a resync for both.
 # avatar and suggest a resync for both.
-MaxFuture = base.config.GetFloat("smooth-max-future", 0.2)
+MaxFuture = config.GetFloat("smooth-max-future", 0.2)
 
 
 # How frequently can we suggest a resynchronize with another client?
 # How frequently can we suggest a resynchronize with another client?
-MinSuggestResync = base.config.GetFloat("smooth-min-suggest-resync", 15)
+MinSuggestResync = config.GetFloat("smooth-min-suggest-resync", 15)
 
 
 # These flags indicate whether global smoothing and/or prediction is
 # These flags indicate whether global smoothing and/or prediction is
 # allowed or disallowed.
 # allowed or disallowed.
-EnableSmoothing = base.config.GetBool("smooth-enable-smoothing", 1)
-EnablePrediction = base.config.GetBool("smooth-enable-prediction", 1)
+EnableSmoothing = config.GetBool("smooth-enable-smoothing", 1)
+EnablePrediction = config.GetBool("smooth-enable-prediction", 1)
 
 
 # These values represent the amount of time, in seconds, to delay the
 # These values represent the amount of time, in seconds, to delay the
 # apparent position of other avatars, when non-predictive and
 # apparent position of other avatars, when non-predictive and
@@ -27,8 +29,8 @@ EnablePrediction = base.config.GetBool("smooth-enable-prediction", 1)
 # addition to the automatic delay of the observed average latency from
 # addition to the automatic delay of the observed average latency from
 # each avatar, which is intended to compensate for relative clock
 # each avatar, which is intended to compensate for relative clock
 # skew.
 # skew.
-Lag = base.config.GetDouble("smooth-lag", 0.2)
-PredictionLag = base.config.GetDouble("smooth-prediction-lag", 0.0)
+Lag = config.GetDouble("smooth-lag", 0.2)
+PredictionLag = config.GetDouble("smooth-prediction-lag", 0.0)
 
 
 
 
 GlobalSmoothing = 0
 GlobalSmoothing = 0

+ 5 - 0
direct/src/distributed/__init__.py

@@ -0,0 +1,5 @@
+"""
+This package contains an implementation of the Distributed Networking
+API, a high-level networking system that automatically propagates
+changes made on distributed objects to interested clients.
+"""

+ 4 - 1
direct/src/extensions_native/__init__.py

@@ -1 +1,4 @@
-
+"""
+This package contains various Python methods that extend some of Panda's
+underlying C++ classes.
+"""

+ 21 - 0
direct/src/filter/CommonFilters.py

@@ -536,3 +536,24 @@ class CommonFilters:
             del self.configuration["GammaAdjust"]
             del self.configuration["GammaAdjust"]
             return self.reconfigure((old_gamma != 1.0), "GammaAdjust")
             return self.reconfigure((old_gamma != 1.0), "GammaAdjust")
         return True
         return True
+
+    #snake_case alias:
+    del_cartoon_ink = delCartoonInk
+    set_half_pixel_shift = setHalfPixelShift
+    del_half_pixel_shift = delHalfPixelShift
+    set_inverted = setInverted
+    del_inverted = delInverted
+    del_view_glow = delViewGlow
+    set_volumetric_lighting = setVolumetricLighting
+    del_gamma_adjust = delGammaAdjust
+    set_bloom = setBloom
+    set_view_glow = setViewGlow
+    set_ambient_occlusion = setAmbientOcclusion
+    set_cartoon_ink = setCartoonInk
+    del_bloom = delBloom
+    del_ambient_occlusion = delAmbientOcclusion
+    load_shader = loadShader
+    set_blur_sharpen = setBlurSharpen
+    del_blur_sharpen = delBlurSharpen
+    del_volumetric_lighting = delVolumetricLighting
+    set_gamma_adjust = setGammaAdjust

+ 12 - 0
direct/src/filter/FilterManager.py

@@ -349,3 +349,15 @@ class FilterManager(DirectObject):
         self.nextsort = self.win.getSort() - 1000
         self.nextsort = self.win.getSort() - 1000
         self.basex = 0
         self.basex = 0
         self.basey = 0
         self.basey = 0
+
+    #snake_case alias:
+    is_fullscreen = isFullscreen
+    resize_buffers = resizeBuffers
+    set_stacked_clears = setStackedClears
+    render_scene_into = renderSceneInto
+    get_scaled_size = getScaledSize
+    render_quad_into = renderQuadInto
+    get_clears = getClears
+    set_clears = setClears
+    create_buffer = createBuffer
+    window_event = windowEvent

+ 11 - 0
direct/src/filter/__init__.py

@@ -0,0 +1,11 @@
+"""
+This package contains functionality for applying post-processing
+filters to the result of rendering a 3-D scene.  This is done by
+rendering the scene to an off-screen buffer, and then applying this to
+a full-screen card that has a shader applied which manipulates the
+texture values as desired.
+
+The :class:`.CommonFilters` class contains various filters that are
+provided out of the box, whereas the :class:`.FilterManager` class
+is a lower-level class that allows you to set up your own filters.
+"""

+ 3 - 2
direct/src/filter/filter-bloomx.sha

@@ -12,8 +12,9 @@ void vshader(float4 vtx_position : POSITION,
   l_position=mul(mat_modelproj, vtx_position);
   l_position=mul(mat_modelproj, vtx_position);
   float2 c=(vtx_position.xz * texpad_src.xy) + texpad_src.xy;
   float2 c=(vtx_position.xz * texpad_src.xy) + texpad_src.xy;
   float offset = texpix_src.x;
   float offset = texpix_src.x;
-  l_texcoord0 = float4(c.x-offset* -4, c.x-offset* -3, c.x-offset* -2, c.y);
-  l_texcoord1 = float4(c.x-offset* -1, c.x-offset*  0, c.x-offset*  1, c.y);
+  float pad = texpad_src.x * 2;
+  l_texcoord0 = float4(min(c.x-offset* -4, pad), min(c.x-offset* -3, pad), min(c.x-offset* -2, pad), c.y);
+  l_texcoord1 = float4(min(c.x-offset* -1, pad), c.x-offset*  0, c.x-offset*  1, c.y);
   l_texcoord2 = float4(c.x-offset*  2, c.x-offset*  3, c.x-offset*  4, c.y);
   l_texcoord2 = float4(c.x-offset*  2, c.x-offset*  3, c.x-offset*  4, c.y);
 }
 }
 
 

+ 3 - 2
direct/src/filter/filter-bloomy.sha

@@ -12,8 +12,9 @@ void vshader(float4 vtx_position : POSITION,
   l_position=mul(mat_modelproj, vtx_position);
   l_position=mul(mat_modelproj, vtx_position);
   float2 c=(vtx_position.xz * texpad_src.xy) + texpad_src.xy;
   float2 c=(vtx_position.xz * texpad_src.xy) + texpad_src.xy;
   float offset = texpix_src.y;
   float offset = texpix_src.y;
-  l_texcoord0 = float4(c.y-offset* -4, c.y-offset* -3, c.y-offset* -2, c.x);
-  l_texcoord1 = float4(c.y-offset* -1, c.y-offset*  0, c.y-offset*  1, c.x);
+  float pad = texpad_src.y * 2;
+  l_texcoord0 = float4(min(c.y-offset* -4, pad), min(c.y-offset* -3, pad), min(c.y-offset* -2, pad), c.x);
+  l_texcoord1 = float4(min(c.y-offset* -1, pad), c.y-offset*  0, c.y-offset*  1, c.x);
   l_texcoord2 = float4(c.y-offset*  2, c.y-offset*  3, c.y-offset*  4, c.x);
   l_texcoord2 = float4(c.y-offset*  2, c.y-offset*  3, c.y-offset*  4, c.x);
 }
 }
 
 

+ 6 - 4
direct/src/filter/filter-blurx.sha

@@ -2,7 +2,7 @@
 //
 //
 //Cg profile arbvp1 arbfp1
 //Cg profile arbvp1 arbfp1
 
 
-void vshader(float4 vtx_position : POSITION, 
+void vshader(float4 vtx_position : POSITION,
              float2 vtx_texcoord0 : TEXCOORD0,
              float2 vtx_texcoord0 : TEXCOORD0,
              out float4 l_position : POSITION,
              out float4 l_position : POSITION,
       	     out float2 l_texcoord0 : TEXCOORD0,
       	     out float2 l_texcoord0 : TEXCOORD0,
@@ -17,16 +17,18 @@ void vshader(float4 vtx_position : POSITION,
 void fshader(float2 l_texcoord0 : TEXCOORD0,
 void fshader(float2 l_texcoord0 : TEXCOORD0,
              out float4 o_color : COLOR,
              out float4 o_color : COLOR,
              uniform float2 texpix_src,
              uniform float2 texpix_src,
+             uniform float4 texpad_src,
              uniform sampler2D k_src : TEXUNIT0)
              uniform sampler2D k_src : TEXUNIT0)
 {
 {
+  float pad = texpad_src.x * 2;
   float3 offset = float3(1.0*texpix_src.x, 2.0*texpix_src.x, 3.0*texpix_src.x);
   float3 offset = float3(1.0*texpix_src.x, 2.0*texpix_src.x, 3.0*texpix_src.x);
   o_color  = tex2D(k_src, l_texcoord0);
   o_color  = tex2D(k_src, l_texcoord0);
   o_color += tex2D(k_src, float2(l_texcoord0.x - offset.z, l_texcoord0.y));
   o_color += tex2D(k_src, float2(l_texcoord0.x - offset.z, l_texcoord0.y));
   o_color += tex2D(k_src, float2(l_texcoord0.x - offset.y, l_texcoord0.y));
   o_color += tex2D(k_src, float2(l_texcoord0.x - offset.y, l_texcoord0.y));
   o_color += tex2D(k_src, float2(l_texcoord0.x - offset.x, l_texcoord0.y));
   o_color += tex2D(k_src, float2(l_texcoord0.x - offset.x, l_texcoord0.y));
-  o_color += tex2D(k_src, float2(l_texcoord0.x + offset.x, l_texcoord0.y));
-  o_color += tex2D(k_src, float2(l_texcoord0.x + offset.y, l_texcoord0.y));
-  o_color += tex2D(k_src, float2(l_texcoord0.x + offset.z, l_texcoord0.y));
+  o_color += tex2D(k_src, float2(min(l_texcoord0.x + offset.x, pad), l_texcoord0.y));
+  o_color += tex2D(k_src, float2(min(l_texcoord0.x + offset.y, pad), l_texcoord0.y));
+  o_color += tex2D(k_src, float2(min(l_texcoord0.x + offset.z, pad), l_texcoord0.y));
   o_color /= 7;
   o_color /= 7;
   o_color.w = 1;
   o_color.w = 1;
 }
 }

+ 6 - 4
direct/src/filter/filter-blury.sha

@@ -2,7 +2,7 @@
 //
 //
 //Cg profile arbvp1 arbfp1
 //Cg profile arbvp1 arbfp1
 
 
-void vshader(float4 vtx_position : POSITION, 
+void vshader(float4 vtx_position : POSITION,
              float2 vtx_texcoord0 : TEXCOORD0,
              float2 vtx_texcoord0 : TEXCOORD0,
              out float4 l_position : POSITION,
              out float4 l_position : POSITION,
       	     out float2 l_texcoord0 : TEXCOORD0,
       	     out float2 l_texcoord0 : TEXCOORD0,
@@ -17,16 +17,18 @@ void vshader(float4 vtx_position : POSITION,
 void fshader(float2 l_texcoord0 : TEXCOORD0,
 void fshader(float2 l_texcoord0 : TEXCOORD0,
              out float4 o_color : COLOR,
              out float4 o_color : COLOR,
              uniform float2 texpix_src,
              uniform float2 texpix_src,
+             uniform float4 texpad_src,
              uniform sampler2D k_src : TEXUNIT0)
              uniform sampler2D k_src : TEXUNIT0)
 {
 {
+  float pad = texpad_src.y * 2;
   float3 offset = float3(1.0*texpix_src.y, 2.0*texpix_src.y, 3.0*texpix_src.y);
   float3 offset = float3(1.0*texpix_src.y, 2.0*texpix_src.y, 3.0*texpix_src.y);
   o_color  = tex2D(k_src, l_texcoord0);
   o_color  = tex2D(k_src, l_texcoord0);
   o_color += tex2D(k_src, float2(l_texcoord0.x, l_texcoord0.y - offset.z));
   o_color += tex2D(k_src, float2(l_texcoord0.x, l_texcoord0.y - offset.z));
   o_color += tex2D(k_src, float2(l_texcoord0.x, l_texcoord0.y - offset.y));
   o_color += tex2D(k_src, float2(l_texcoord0.x, l_texcoord0.y - offset.y));
   o_color += tex2D(k_src, float2(l_texcoord0.x, l_texcoord0.y - offset.x));
   o_color += tex2D(k_src, float2(l_texcoord0.x, l_texcoord0.y - offset.x));
-  o_color += tex2D(k_src, float2(l_texcoord0.x, l_texcoord0.y + offset.x));
-  o_color += tex2D(k_src, float2(l_texcoord0.x, l_texcoord0.y + offset.y));
-  o_color += tex2D(k_src, float2(l_texcoord0.x, l_texcoord0.y + offset.z));
+  o_color += tex2D(k_src, float2(l_texcoord0.x, min(l_texcoord0.y + offset.x, pad)));
+  o_color += tex2D(k_src, float2(l_texcoord0.x, min(l_texcoord0.y + offset.y, pad)));
+  o_color += tex2D(k_src, float2(l_texcoord0.x, min(l_texcoord0.y + offset.z, pad)));
   o_color /= 7;
   o_color /= 7;
   o_color.w = 1;
   o_color.w = 1;
 }
 }

+ 6 - 6
direct/src/fsm/ClassicFSM.py

@@ -1,13 +1,13 @@
-"""Undocumented Module"""
-
-__all__ = ['ClassicFSM']
-
 """Finite State Machine module: contains the ClassicFSM class.
 """Finite State Machine module: contains the ClassicFSM class.
 
 
-This module and class exist only for backward compatibility with
-existing code.  New code should use the FSM module instead.
+.. note::
+
+   This module and class exist only for backward compatibility with
+   existing code.  New code should use the :mod:`.FSM` module instead.
 """
 """
 
 
+__all__ = ['ClassicFSM']
+
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.DirectObject import DirectObject
 import weakref
 import weakref

+ 1 - 1
direct/src/fsm/FSM.py

@@ -1,5 +1,5 @@
 """The new Finite State Machine module. This replaces the module
 """The new Finite State Machine module. This replaces the module
-previously called FSM.py (now called ClassicFSM.py).
+previously called FSM (now called :mod:`.ClassicFSM`).
 """
 """
 
 
 __all__ = ['FSMException', 'FSM']
 __all__ = ['FSMException', 'FSM']

+ 2 - 4
direct/src/fsm/FourState.py

@@ -1,9 +1,7 @@
-"""Undocumented Module"""
+"""Contains the FourState class."""
 
 
 __all__ = ['FourState']
 __all__ = ['FourState']
 
 
-
-
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal
 #import DistributedObject
 #import DistributedObject
 from . import ClassicFSM
 from . import ClassicFSM
@@ -20,7 +18,7 @@ class FourState:
     Inherit from FourStateFSM and pass in your states.  Two of
     Inherit from FourStateFSM and pass in your states.  Two of
     the states should be oposites of each other and the other
     the states should be oposites of each other and the other
     two should be the transition states between the first two.
     two should be the transition states between the first two.
-    E.g.
+    E.g::
 
 
                     +--------+
                     +--------+
                  -->| closed | --
                  -->| closed | --

+ 2 - 4
direct/src/fsm/FourStateAI.py

@@ -1,9 +1,7 @@
-"""Undocumented Module"""
+"""Contains the FourStateAI class.  See also :mod:`.FourState`."""
 
 
 __all__ = ['FourStateAI']
 __all__ = ['FourStateAI']
 
 
-
-
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal
 #import DistributedObjectAI
 #import DistributedObjectAI
 from . import ClassicFSM
 from . import ClassicFSM
@@ -21,7 +19,7 @@ class FourStateAI:
     Inherit from FourStateFSM and pass in your states.  Two of
     Inherit from FourStateFSM and pass in your states.  Two of
     the states should be oposites of each other and the other
     the states should be oposites of each other and the other
     two should be the transition states between the first two.
     two should be the transition states between the first two.
-    E.g.
+    E.g::
 
 
                     +--------+
                     +--------+
                  -->| closed | --
                  -->| closed | --

+ 6 - 0
direct/src/fsm/__init__.py

@@ -0,0 +1,6 @@
+"""
+This package contains implementations of a Finite State Machine, an
+abstract construct that holds a particular state and can transition
+between several defined states.  These are useful for a range of logic
+programming tasks.
+"""

+ 1 - 1
direct/src/gui/DirectButton.py

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""This module contains the DirectButton class."""
 
 
 __all__ = ['DirectButton']
 __all__ = ['DirectButton']
 
 

+ 3 - 1
direct/src/gui/DirectCheckButton.py

@@ -1,4 +1,6 @@
-"""Undocumented Module"""
+"""A DirectCheckButton is a type of button that toggles between two states
+when clicked.  It also has a separate indicator that can be modified
+separately."""
 
 
 __all__ = ['DirectCheckButton']
 __all__ = ['DirectCheckButton']
 
 

+ 1 - 1
direct/src/gui/DirectDialog.py

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""This module defines various dialog windows for the DirectGUI system."""
 
 
 __all__ = ['findDialog', 'cleanupDialog', 'DirectDialog', 'OkDialog', 'OkCancelDialog', 'YesNoDialog', 'YesNoCancelDialog', 'RetryCancelDialog']
 __all__ = ['findDialog', 'cleanupDialog', 'DirectDialog', 'OkDialog', 'OkCancelDialog', 'YesNoDialog', 'YesNoCancelDialog', 'RetryCancelDialog']
 
 

+ 2 - 1
direct/src/gui/DirectEntry.py

@@ -1,4 +1,5 @@
-"""Undocumented Module"""
+"""Contains the DirectEntry class, a type of DirectGUI widget that accepts
+text entered using the keyboard."""
 
 
 __all__ = ['DirectEntry']
 __all__ = ['DirectEntry']
 
 

+ 14 - 9
direct/src/gui/DirectFrame.py

@@ -1,4 +1,17 @@
-"""Undocumented Module"""
+"""A DirectFrame is a basic DirectGUI component that acts as the base
+class for various other components, and can also serve as a basic
+container to hold other DirectGUI components.
+
+A DirectFrame can have:
+
+* A background texture (pass in path to image, or Texture Card)
+* A midground geometry item (pass in geometry)
+* A foreground text Node (pass in text string or OnscreenText)
+
+Each of these has 1 or more states.  The same object can be used for
+all states or each state can have a different text/geom/image (for
+radio button and check button indicators, for example).
+"""
 
 
 __all__ = ['DirectFrame']
 __all__ = ['DirectFrame']
 
 
@@ -19,14 +32,6 @@ class DirectFrame(DirectGuiWidget):
     DefDynGroups = ('text', 'geom', 'image')
     DefDynGroups = ('text', 'geom', 'image')
     def __init__(self, parent = None, **kw):
     def __init__(self, parent = None, **kw):
         # Inherits from DirectGuiWidget
         # Inherits from DirectGuiWidget
-        # A Direct Frame can have:
-        # - A background texture (pass in path to image, or Texture Card)
-        # - A midground geometry item (pass in geometry)
-        # - A foreground text Node (pass in text string or Onscreen Text)
-        # Each of these has 1 or more states
-        # The same object can be used for all states or each
-        # state can have a different text/geom/image (for radio button
-        # and check button indicators, for example).
         optiondefs = (
         optiondefs = (
             # Define type of DirectGuiWidget
             # Define type of DirectGuiWidget
             ('pgFunc',          PGItem,     None),
             ('pgFunc',          PGItem,     None),

+ 24 - 25
direct/src/gui/DirectGuiBase.py

@@ -1,32 +1,7 @@
-"""Undocumented Module"""
-
-__all__ = ['DirectGuiBase', 'DirectGuiWidget']
-
-
-from panda3d.core import *
-from panda3d.direct import get_config_showbase
-from . import DirectGuiGlobals as DGG
-from .OnscreenText import *
-from .OnscreenGeom import *
-from .OnscreenImage import *
-from direct.directtools.DirectUtil import ROUND_TO
-from direct.showbase import DirectObject
-from direct.task import Task
-import sys
-
-if sys.version_info >= (3, 0):
-    stringType = str
-else:
-    stringType = basestring
-
-guiObjectCollector = PStatCollector("Client::GuiObjects")
-
 """
 """
 Base class for all Direct Gui items.  Handles composite widgets and
 Base class for all Direct Gui items.  Handles composite widgets and
 command line argument parsing.
 command line argument parsing.
-"""
 
 
-"""
 Code Overview:
 Code Overview:
 
 
 1   Each widget defines a set of options (optiondefs) as a list of tuples
 1   Each widget defines a set of options (optiondefs) as a list of tuples
@@ -101,7 +76,31 @@ Code Overview:
     are left unused.  If so, an error is raised.
     are left unused.  If so, an error is raised.
 """
 """
 
 
+__all__ = ['DirectGuiBase', 'DirectGuiWidget']
+
+
+from panda3d.core import *
+from panda3d.direct import get_config_showbase
+from . import DirectGuiGlobals as DGG
+from .OnscreenText import *
+from .OnscreenGeom import *
+from .OnscreenImage import *
+from direct.directtools.DirectUtil import ROUND_TO
+from direct.showbase import DirectObject
+from direct.task import Task
+import sys
+
+if sys.version_info >= (3, 0):
+    stringType = str
+else:
+    stringType = basestring
+
+guiObjectCollector = PStatCollector("Client::GuiObjects")
+
+
 class DirectGuiBase(DirectObject.DirectObject):
 class DirectGuiBase(DirectObject.DirectObject):
+    """Base class of all DirectGUI widgets."""
+
     def __init__(self):
     def __init__(self):
         # Default id of all gui object, subclasses should override this
         # Default id of all gui object, subclasses should override this
         self.guiId = 'guiObject'
         self.guiId = 'guiObject'

+ 3 - 5
direct/src/gui/DirectGuiGlobals.py

@@ -1,12 +1,10 @@
-"""Undocumented Module"""
-
-__all__ = []
-
-
 """
 """
 Global definitions used by Direct Gui Classes and handy constants
 Global definitions used by Direct Gui Classes and handy constants
 that can be used during widget construction
 that can be used during widget construction
 """
 """
+
+__all__ = []
+
 from panda3d.core import *
 from panda3d.core import *
 
 
 defaultFont = None
 defaultFont = None

+ 1 - 1
direct/src/gui/DirectLabel.py

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Contains the DirectLabel class."""
 
 
 __all__ = ['DirectLabel']
 __all__ = ['DirectLabel']
 
 

+ 1 - 1
direct/src/gui/DirectOptionMenu.py

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Implements a pop-up menu containing multiple clickable options."""
 
 
 __all__ = ['DirectOptionMenu']
 __all__ = ['DirectOptionMenu']
 
 

+ 4 - 1
direct/src/gui/DirectRadioButton.py

@@ -1,4 +1,7 @@
-"""Undocumented Module"""
+"""A DirectRadioButton is a type of button that, similar to a
+DirectCheckButton, has a separate indicator and can be toggled between
+two states.  However, only one DirectRadioButton in a group can be enabled
+at a particular time."""
 
 
 __all__ = ['DirectRadioButton']
 __all__ = ['DirectRadioButton']
 
 

+ 1 - 1
direct/src/gui/DirectScrollBar.py

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Defines the DirectScrollBar class."""
 
 
 __all__ = ['DirectScrollBar']
 __all__ = ['DirectScrollBar']
 
 

+ 1 - 1
direct/src/gui/DirectScrolledFrame.py

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Contains the DirectScrolledFrame class."""
 
 
 __all__ = ['DirectScrolledFrame']
 __all__ = ['DirectScrolledFrame']
 
 

+ 1 - 1
direct/src/gui/DirectScrolledList.py

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Contains the DirectScrolledList class."""
 
 
 __all__ = ['DirectScrolledListItem', 'DirectScrolledList']
 __all__ = ['DirectScrolledListItem', 'DirectScrolledList']
 
 

+ 1 - 1
direct/src/gui/DirectSlider.py

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Defines the DirectSlider class."""
 
 
 __all__ = ['DirectSlider']
 __all__ = ['DirectSlider']
 
 

+ 1 - 1
direct/src/gui/DirectWaitBar.py

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Contains the DirectWaitBar class, a progress bar widget."""
 
 
 __all__ = ['DirectWaitBar']
 __all__ = ['DirectWaitBar']
 
 

+ 16 - 1
direct/src/gui/OnscreenText.py

@@ -35,7 +35,8 @@ class OnscreenText(NodePath):
                  font = None,
                  font = None,
                  parent = None,
                  parent = None,
                  sort = 0,
                  sort = 0,
-                 mayChange = True):
+                 mayChange = True,
+                 direction = None):
         """
         """
         Make a text node from string, put it into the 2d sg and set it
         Make a text node from string, put it into the 2d sg and set it
         up with all the indicated parameters.
         up with all the indicated parameters.
@@ -95,6 +96,9 @@ class OnscreenText(NodePath):
           mayChange: pass true if the text or its properties may need
           mayChange: pass true if the text or its properties may need
               to be changed at runtime, false if it is static once
               to be changed at runtime, false if it is static once
               created (which leads to better memory optimization).
               created (which leads to better memory optimization).
+
+          direction: this can be set to 'ltr' or 'rtl' to override the
+              direction of the text.
         """
         """
         if parent == None:
         if parent == None:
             parent = aspect2d
             parent = aspect2d
@@ -192,6 +196,17 @@ class OnscreenText(NodePath):
             textNode.setFrameColor(frame[0], frame[1], frame[2], frame[3])
             textNode.setFrameColor(frame[0], frame[1], frame[2], frame[3])
             textNode.setFrameAsMargin(0.1, 0.1, 0.1, 0.1)
             textNode.setFrameAsMargin(0.1, 0.1, 0.1, 0.1)
 
 
+        if direction is not None:
+            if isinstance(direction, str):
+                direction = direction.lower()
+                if direction == 'rtl':
+                    direction = TextProperties.D_rtl
+                elif direction == 'ltr':
+                    direction = TextProperties.D_ltr
+                else:
+                    raise ValueError('invalid direction')
+            textNode.setDirection(direction)
+
         # Create a transform for the text for our scale and position.
         # Create a transform for the text for our scale and position.
         # We'd rather do it here, on the text itself, rather than on
         # We'd rather do it here, on the text itself, rather than on
         # our NodePath, so we have one fewer transforms in the scene
         # our NodePath, so we have one fewer transforms in the scene

+ 12 - 0
direct/src/gui/__init__.py

@@ -0,0 +1,12 @@
+"""
+This package contains the DirectGui system, a set of classes
+responsible for drawing graphical widgets to the 2-D scene graph.
+
+It is based on the lower-level PGui system, which is implemented in
+C++.
+
+For convenience, all of the DirectGui widgets may be imported from a
+single module as follows::
+
+   from direct.gui.DirectGui import *
+"""

+ 4 - 1
direct/src/interval/IntervalGlobal.py

@@ -1,4 +1,7 @@
-"""IntervalGlobal module"""
+"""
+This module imports all of the other interval modules, to provide a
+single convenient module from which all interval types can be imported.
+"""
 
 
 # In this unusual case, I'm not going to declare __all__,
 # In this unusual case, I'm not going to declare __all__,
 # since the purpose of this module is to add up the contributions
 # since the purpose of this module is to add up the contributions

+ 3 - 3
direct/src/interval/IntervalManager.py

@@ -1,4 +1,5 @@
-"""Undocumented Module"""
+"""Defines the IntervalManager class as well as the global instance of
+this class, ivalMgr."""
 
 
 __all__ = ['IntervalManager', 'ivalMgr']
 __all__ = ['IntervalManager', 'ivalMgr']
 
 
@@ -136,6 +137,5 @@ class IntervalManager(CIntervalManager):
         assert self.ivals[index] == None or self.ivals[index] == interval
         assert self.ivals[index] == None or self.ivals[index] == interval
         self.ivals[index] = interval
         self.ivals[index] = interval
 
 
-# The global IntervalManager object.
+#: The global IntervalManager object.
 ivalMgr = IntervalManager(1)
 ivalMgr = IntervalManager(1)
-

+ 4 - 1
direct/src/interval/MetaInterval.py

@@ -1,4 +1,7 @@
-"""Undocumented Module"""
+"""
+This module defines the various "meta intervals", which execute other
+intervals either in parallel or in a specified sequential order.
+"""
 
 
 __all__ = ['MetaInterval', 'Sequence', 'Parallel', 'ParallelEndTogether', 'Track']
 __all__ = ['MetaInterval', 'Sequence', 'Parallel', 'ParallelEndTogether', 'Track']
 
 

+ 2 - 4
direct/src/interval/ParticleInterval.py

@@ -1,11 +1,9 @@
-"""Undocumented Module"""
-
-__all__ = ['ParticleInterval']
-
 """
 """
 Contains the ParticleInterval class
 Contains the ParticleInterval class
 """
 """
 
 
+__all__ = ['ParticleInterval']
+
 from panda3d.core import *
 from panda3d.core import *
 from panda3d.direct import *
 from panda3d.direct import *
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.directnotify.DirectNotifyGlobal import directNotify

+ 3 - 5
direct/src/interval/TestInterval.py

@@ -1,11 +1,9 @@
-"""Undocumented Module"""
-
-__all__ = ['TestInterval']
-
 """
 """
-Contains the ParticleInterval class
+Contains the TestInterval class
 """
 """
 
 
+__all__ = ['TestInterval']
+
 from panda3d.core import *
 from panda3d.core import *
 from panda3d.direct import *
 from panda3d.direct import *
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.directnotify.DirectNotifyGlobal import directNotify

+ 12 - 0
direct/src/interval/__init__.py

@@ -0,0 +1,12 @@
+"""
+This package contains the Python implementation of the interval system,
+which is a mechanism for playing back scripted actions.  A range of
+interval types has been defined to automate motion, animation, sounds,
+color, function calls, as well as other intervals and arbitrary
+properties.
+
+All interval types can be conveniently imported from the
+:mod:`.IntervalGlobal` module::
+
+   from direct.interval.IntervalGlobal import *
+"""

+ 3 - 0
direct/src/motiontrail/__init__.py

@@ -0,0 +1,3 @@
+"""
+This package contains only the :class:`.MotionTrail` class.
+"""

+ 5 - 2
direct/src/p3d/AppRunner.py

@@ -1,12 +1,15 @@
-
 """
 """
-
 This module is intended to be compiled into the Panda3D runtime
 This module is intended to be compiled into the Panda3D runtime
 distributable, to execute a packaged p3d application, but it can also
 distributable, to execute a packaged p3d application, but it can also
 be run directly via the Python interpreter (if the current Panda3D and
 be run directly via the Python interpreter (if the current Panda3D and
 Python versions match the version expected by the application).  See
 Python versions match the version expected by the application).  See
 runp3d.py for a command-line tool to invoke this module.
 runp3d.py for a command-line tool to invoke this module.
 
 
+The global AppRunner instance may be imported as follows::
+
+   from direct.showbase.AppRunnerGlobal import appRunner
+
+This will be None if Panda was not run from the runtime environment.
 """
 """
 
 
 __all__ = ["AppRunner", "dummyAppRunner", "ArgumentError"]
 __all__ = ["AppRunner", "dummyAppRunner", "ArgumentError"]

+ 4 - 0
direct/src/p3d/__init__.py

@@ -0,0 +1,4 @@
+"""
+This package provides the Python interface to functionality relating to
+the Panda3D Runtime environment.
+"""

+ 7 - 0
direct/src/particles/__init__.py

@@ -0,0 +1,7 @@
+"""
+This package contains the high-level Python interface to the particle
+system.
+
+Also see the :mod:`panda3d.physics` module, which contains the C++
+implementation of the particle system.
+"""

+ 2 - 0
direct/src/showbase/AppRunnerGlobal.py

@@ -6,4 +6,6 @@ This is needed for apps that start themselves by importing
 DirectStart; it provides a place for these apps to look for
 DirectStart; it provides a place for these apps to look for
 the AppRunner at startup. """
 the AppRunner at startup. """
 
 
+#: Contains the global AppRunner instance, or None if this application
+#: was not run from the runtime environment.
 appRunner = None
 appRunner = None

+ 25 - 1
direct/src/showbase/Audio3DManager.py

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Contains the Audio3DManager class."""
 
 
 __all__ = ['Audio3DManager']
 __all__ = ['Audio3DManager']
 
 
@@ -289,3 +289,27 @@ class Audio3DManager:
             for sound in self.sound_dict[object]:
             for sound in self.sound_dict[object]:
                 self.detachSound(sound)
                 self.detachSound(sound)
 
 
+    #snake_case alias:
+    get_doppler_factor = getDopplerFactor
+    set_listener_velocity_auto = setListenerVelocityAuto
+    attach_listener = attachListener
+    set_distance_factor = setDistanceFactor
+    attach_sound_to_object = attachSoundToObject
+    get_drop_off_factor = getDropOffFactor
+    set_doppler_factor = setDopplerFactor
+    get_sounds_on_object = getSoundsOnObject
+    set_sound_velocity_auto = setSoundVelocityAuto
+    get_sound_max_distance = getSoundMaxDistance
+    load_sfx = loadSfx
+    get_distance_factor = getDistanceFactor
+    set_listener_velocity = setListenerVelocity
+    set_sound_max_distance = setSoundMaxDistance
+    get_sound_velocity = getSoundVelocity
+    get_listener_velocity = getListenerVelocity
+    set_sound_velocity = setSoundVelocity
+    set_sound_min_distance = setSoundMinDistance
+    get_sound_min_distance = getSoundMinDistance
+    detach_listener = detachListener
+    set_drop_off_factor = setDropOffFactor
+    detach_sound = detachSound
+

+ 3 - 1
direct/src/showbase/BufferViewer.py

@@ -1,4 +1,6 @@
-"""Undocumented Module"""
+"""Contains the BufferViewer class, which is used as a debugging aid
+when debugging render-to-texture effects.  It shows different views at
+the bottom of the screen showing the various render targets."""
 
 
 __all__ = ['BufferViewer']
 __all__ = ['BufferViewer']
 
 

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

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Contains the BulletinBoard class."""
 
 
 __all__ = ['BulletinBoard']
 __all__ = ['BulletinBoard']
 
 

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

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Contains the BulletinBoardWatcher class."""
 
 
 __all__ = ['BulletinBoardWatcher']
 __all__ = ['BulletinBoardWatcher']
 
 

+ 14 - 1
direct/src/showbase/DirectObject.py

@@ -1,4 +1,5 @@
-"""Undocumented Module"""
+"""Defines the DirectObject class, a convenient class to inherit from if the
+object needs to be able to respond to events."""
 
 
 __all__ = ['DirectObject']
 __all__ = ['DirectObject']
 
 
@@ -100,3 +101,15 @@ class DirectObject:
             func = choice(getRepository()._crashOnProactiveLeakDetect,
             func = choice(getRepository()._crashOnProactiveLeakDetect,
                           self.notify.error, self.notify.warning)
                           self.notify.error, self.notify.warning)
             func('destroyed %s instance is still %s%s' % (self.__class__.__name__, estr, tstr))
             func('destroyed %s instance is still %s%s' % (self.__class__.__name__, estr, tstr))
+
+    #snake_case alias:
+    add_task = addTask
+    do_method_later = doMethodLater
+    detect_leaks = detectLeaks
+    accept_once = acceptOnce
+    ignore_all = ignoreAll
+    get_all_accepting = getAllAccepting
+    is_ignoring = isIgnoring
+    remove_all_tasks = removeAllTasks
+    remove_task = removeTask
+    is_accepting = isAccepting

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

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""This module defines the EventGroup class."""
 
 
 __all__ = ['EventGroup']
 __all__ = ['EventGroup']
 
 

+ 2 - 1
direct/src/showbase/EventManager.py

@@ -1,4 +1,5 @@
-"""Undocumented Module"""
+"""Contains the EventManager class.  See :mod:`.EventManagerGlobal` for the
+global eventMgr instance."""
 
 
 __all__ = ['EventManager']
 __all__ = ['EventManager']
 
 

+ 2 - 1
direct/src/showbase/EventManagerGlobal.py

@@ -1,7 +1,8 @@
-"""Undocumented Module"""
+"""Contains the global :class:`.EventManager` instance."""
 
 
 __all__ = ['eventMgr']
 __all__ = ['eventMgr']
 
 
 from . import EventManager
 from . import EventManager
 
 
+#: The global event manager.
 eventMgr = EventManager.EventManager()
 eventMgr = EventManager.EventManager()

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

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Contains the Factory class."""
 
 
 __all__ = ['Factory']
 __all__ = ['Factory']
 
 

+ 2 - 4
direct/src/showbase/FindCtaPaths.py

@@ -1,7 +1,3 @@
-"""Undocumented Module"""
-
-__all__ = ['deCygwinify', 'getPaths']
-
 """This module is used only by the VR Studio programmers who are using
 """This module is used only by the VR Studio programmers who are using
 the ctattach tools.  It is imported before any other package, and its
 the ctattach tools.  It is imported before any other package, and its
 job is to figure out the correct paths to each of the packages.
 job is to figure out the correct paths to each of the packages.
@@ -10,6 +6,8 @@ This module is not needed if you are not using ctattach; in this case
 all of the Panda packages will be collected under a common directory,
 all of the Panda packages will be collected under a common directory,
 which you will presumably have already on your PYTHONPATH. """
 which you will presumably have already on your PYTHONPATH. """
 
 
+__all__ = ['deCygwinify', 'getPaths']
+
 import os
 import os
 import sys
 import sys
 
 

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

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Contains various utility functions."""
 
 
 __all__ = ['findClass', 'rebindClass', 'copyFuncs', 'replaceMessengerFunc', 'replaceTaskMgrFunc', 'replaceStateFunc', 'replaceCRFunc', 'replaceAIRFunc', 'replaceIvalFunc']
 __all__ = ['findClass', 'rebindClass', 'copyFuncs', 'replaceMessengerFunc', 'replaceTaskMgrFunc', 'replaceStateFunc', 'replaceCRFunc', 'replaceAIRFunc', 'replaceIvalFunc']
 
 

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

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Contains utility classes for debugging memory leaks."""
 
 
 __all__ = ['FakeObject', '_createGarbage', 'GarbageReport', 'GarbageLogger']
 __all__ = ['FakeObject', '_createGarbage', 'GarbageReport', 'GarbageLogger']
 
 

+ 15 - 3
direct/src/showbase/Messenger.py

@@ -1,4 +1,5 @@
-"""Undocumented Module"""
+"""This defines the Messenger class, which is responsible for most of the
+event handling that happens on the Python side."""
 
 
 __all__ = ['Messenger']
 __all__ = ['Messenger']
 
 
@@ -531,7 +532,6 @@ class Messenger:
         keys.sort()
         keys.sort()
         for event in keys:
         for event in keys:
             if repr(event).find(needle) >= 0:
             if repr(event).find(needle) >= 0:
-                print(self.__eventRepr(event))
                 return {event: self.__callbacks[event]}
                 return {event: self.__callbacks[event]}
 
 
     def findAll(self, needle, limit=None):
     def findAll(self, needle, limit=None):
@@ -545,7 +545,6 @@ class Messenger:
         keys.sort()
         keys.sort()
         for event in keys:
         for event in keys:
             if repr(event).find(needle) >= 0:
             if repr(event).find(needle) >= 0:
-                print(self.__eventRepr(event))
                 matches[event] = self.__callbacks[event]
                 matches[event] = self.__callbacks[event]
                 # if the limit is not None, decrement and
                 # if the limit is not None, decrement and
                 # check for break:
                 # check for break:
@@ -636,3 +635,16 @@ class Messenger:
         str = str + '='*50 + '\n'
         str = str + '='*50 + '\n'
         return str
         return str
 
 
+    #snake_case alias:
+    get_events = getEvents
+    is_ignoring = isIgnoring
+    who_accepts = whoAccepts
+    find_all = findAll
+    replace_method = replaceMethod
+    ignore_all = ignoreAll
+    is_accepting = isAccepting
+    is_empty = isEmpty
+    detailed_repr = detailedRepr
+    get_all_accepting = getAllAccepting
+    toggle_verbose = toggleVerbose
+

+ 2 - 4
direct/src/showbase/MirrorDemo.py

@@ -1,7 +1,3 @@
-"""Undocumented Module"""
-
-__all__ = ['setupMirror', 'showFrustum']
-
 """This file demonstrates one way to create a mirror effect in Panda.
 """This file demonstrates one way to create a mirror effect in Panda.
 Call setupMirror() to create a mirror in the world that reflects
 Call setupMirror() to create a mirror in the world that reflects
 everything in front of it.
 everything in front of it.
@@ -23,6 +19,8 @@ surface are possible, like a funhouse mirror.  However, the reflection
 itself is always basically planar; for more accurate convex
 itself is always basically planar; for more accurate convex
 reflections, you will need to use a sphere map or a cube map."""
 reflections, you will need to use a sphere map or a cube map."""
 
 
+__all__ = ['setupMirror', 'showFrustum']
+
 from panda3d.core import *
 from panda3d.core import *
 from direct.task import Task
 from direct.task import Task
 
 

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

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Contains the ObjectPool utility class."""
 
 
 __all__ = ['Diff', 'ObjectPool']
 __all__ = ['Diff', 'ObjectPool']
 
 

+ 10 - 12
direct/src/showbase/ObjectReport.py

@@ -1,4 +1,13 @@
-"""Undocumented Module"""
+"""
+>>> from direct.showbase import ObjectReport
+
+>>> o=ObjectReport.ObjectReport('baseline')
+>>> run()
+...
+
+>>> o2=ObjectReport.ObjectReport('')
+>>> o.diff(o2)
+"""
 
 
 __all__ = ['ExclusiveObjectPool', 'ObjectReport']
 __all__ = ['ExclusiveObjectPool', 'ObjectReport']
 
 
@@ -13,17 +22,6 @@ if sys.version_info >= (3, 0):
 else:
 else:
     import __builtin__ as builtins
     import __builtin__ as builtins
 
 
-"""
->>> from direct.showbase import ObjectReport
-
->>> o=ObjectReport.ObjectReport('baseline')
->>> run()
-...
-
->>> o2=ObjectReport.ObjectReport('')
->>> o.diff(o2)
-"""
-
 class ExclusiveObjectPool(DirectObject.DirectObject):
 class ExclusiveObjectPool(DirectObject.DirectObject):
     # ObjectPool specialization that excludes particular objects
     # ObjectPool specialization that excludes particular objects
     # IDs of objects to globally exclude from reporting
     # IDs of objects to globally exclude from reporting

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

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Contains the OnScreenDebug class."""
 
 
 __all__ = ['OnScreenDebug']
 __all__ = ['OnScreenDebug']
 
 

+ 7 - 10
direct/src/showbase/Pool.py

@@ -1,9 +1,4 @@
-"""Undocumented Module"""
-
-__all__ = ['Pool']
-
 """
 """
-
 Pool is a collection of python objects that you can checkin and
 Pool is a collection of python objects that you can checkin and
 checkout. This is useful for a cache of objects that are expensive to load
 checkout. This is useful for a cache of objects that are expensive to load
 and can be reused over and over, like splashes on cannonballs, or
 and can be reused over and over, like splashes on cannonballs, or
@@ -12,12 +7,16 @@ or be the same type.
 
 
 Internally the pool is implemented with 2 lists, free items and used items.
 Internally the pool is implemented with 2 lists, free items and used items.
 
 
-p = Pool([1, 2, 3, 4, 5])
-x = p.checkout()
-p.checkin(x)
+Example::
+
+   p = Pool([1, 2, 3, 4, 5])
+   x = p.checkout()
+   p.checkin(x)
 
 
 """
 """
 
 
+__all__ = ['Pool']
+
 
 
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal
 
 
@@ -116,5 +115,3 @@ class Pool:
 
 
     def __repr__(self):
     def __repr__(self):
         return "free = %s\nused = %s" % (self.__free, self.__used)
         return "free = %s\nused = %s" % (self.__free, self.__used)
-
-

+ 2 - 4
direct/src/showbase/SfxPlayer.py

@@ -1,4 +1,5 @@
-"""Undocumented Module"""
+"""Contains the SfxPlayer class, a thin utility class for playing sounds at
+a particular location."""
 
 
 __all__ = ['SfxPlayer']
 __all__ = ['SfxPlayer']
 
 
@@ -95,6 +96,3 @@ class SfxPlayer:
             if node is not None:
             if node is not None:
                 finalVolume *= node.getNetAudioVolume()
                 finalVolume *= node.getNetAudioVolume()
             sfx.setVolume(finalVolume)
             sfx.setVolume(finalVolume)
-
-
-

+ 2 - 5
direct/src/showbase/ShadowDemo.py

@@ -1,8 +1,3 @@
-"""Undocumented Module"""
-
-__all__ = ['ShadowCaster', 'avatarShadow', 'piratesAvatarShadow', 'arbitraryShadow']
-
-
 """Create a cheesy shadow effect by rendering the view of an
 """Create a cheesy shadow effect by rendering the view of an
 object (e.g. the local avatar) from a special camera as seen from
 object (e.g. the local avatar) from a special camera as seen from
 above (as if from the sun), using a solid gray foreground and a
 above (as if from the sun), using a solid gray foreground and a
@@ -14,6 +9,8 @@ multitexture rendering techniques.  It's not a particularly great
 way to do shadows.
 way to do shadows.
 """
 """
 
 
+__all__ = ['ShadowCaster', 'avatarShadow', 'piratesAvatarShadow', 'arbitraryShadow']
+
 from panda3d.core import *
 from panda3d.core import *
 from direct.task import Task
 from direct.task import Task
 
 

+ 2 - 4
direct/src/showbase/ShadowPlacer.py

@@ -1,7 +1,3 @@
-"""Undocumented Module"""
-
-__all__ = ['ShadowPlacer']
-
 """
 """
 ShadowPlacer.py places a shadow.
 ShadowPlacer.py places a shadow.
 
 
@@ -10,6 +6,8 @@ Or it may do that later, right now it puts a node on the surface under
 the its parent node.
 the its parent node.
 """
 """
 
 
+__all__ = ['ShadowPlacer']
+
 from direct.controls.ControlManager import CollisionHandlerRayStart
 from direct.controls.ControlManager import CollisionHandlerRayStart
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal
 from panda3d.core import *
 from panda3d.core import *

+ 4 - 1
direct/src/showbase/TaskThreaded.py

@@ -1,10 +1,13 @@
-"""Undocumented Module"""
+"""Contains the TaskThreaded and TaskThread classes."""
 
 
 __all__ = ['TaskThreaded', 'TaskThread']
 __all__ = ['TaskThreaded', 'TaskThread']
 
 
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.task import Task
 from direct.task import Task
 
 
+from .PythonUtil import SerialNumGen
+
+
 class TaskThreaded:
 class TaskThreaded:
     """ derive from this if you need to do a bunch of CPU-intensive
     """ derive from this if you need to do a bunch of CPU-intensive
     processing and you don't want to hang up the show. Lets you break
     processing and you don't want to hang up the show. Lets you break

+ 2 - 1
direct/src/showbase/ThreeUpShow.py

@@ -1,4 +1,5 @@
-"""Undocumented Module"""
+"""ThreeUpShow is a variant of ShowBase that defines three cameras covering
+different parts of the window."""
 
 
 __all__ = ['ThreeUpShow']
 __all__ = ['ThreeUpShow']
 
 

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

@@ -1,4 +1,6 @@
-"""Undocumented Module"""
+"""This module defines various transition effects that can be used to
+graphically transition between two scenes, such as by fading the screen to
+a particular color."""
 
 
 __all__ = ['Transitions']
 __all__ = ['Transitions']
 
 

+ 4 - 1
direct/src/showbase/VerboseImport.py

@@ -1,4 +1,7 @@
-"""Undocumented Module"""
+"""
+This module hooks into Python's import mechanism to print out all imports to
+the standard output as they happen.
+"""
 
 
 __all__ = []
 __all__ = []
 
 

+ 90 - 83
direct/src/showutil/pfreeze.py

@@ -13,11 +13,11 @@ Python code into a standalone executable.  It also uses Python's
 built-in modulefinder module, which it uses to find all of the modules
 built-in modulefinder module, which it uses to find all of the modules
 imported directly or indirectly by the original startfile.py.
 imported directly or indirectly by the original startfile.py.
 
 
-Usage:
+Usage::
 
 
   pfreeze.py [opts] [startfile]
   pfreeze.py [opts] [startfile]
 
 
-Options:
+Options::
 
 
   -o output
   -o output
      Specifies the name of the resulting executable file to produce.
      Specifies the name of the resulting executable file to produce.
@@ -67,88 +67,95 @@ def usage(code, msg = ''):
     sys.stderr.write(str(msg) + '\n')
     sys.stderr.write(str(msg) + '\n')
     sys.exit(code)
     sys.exit(code)
 
 
-# We're not protecting the next part under a __name__ == __main__
-# check, just so we can import this file directly in ppython.cxx.
-
-freezer = FreezeTool.Freezer()
-
-basename = None
-addStartupModules = False
-
-try:
-    opts, args = getopt.getopt(sys.argv[1:], 'o:i:x:p:P:slkh')
-except getopt.error as msg:
-    usage(1, msg)
-
-for opt, arg in opts:
-    if opt == '-o':
-        basename = arg
-    elif opt == '-i':
-        for module in arg.split(','):
-            freezer.addModule(module)
-    elif opt == '-x':
-        for module in arg.split(','):
-            freezer.excludeModule(module)
-    elif opt == '-p':
-        for module in arg.split(','):
-            freezer.handleCustomPath(module)
-    elif opt == '-P':
-        sys.path.append(arg)
-    elif opt == '-s':
-        addStartupModules = True
-    elif opt == '-l':
-        freezer.linkExtensionModules = True
-    elif opt == '-k':
-        freezer.keepTemporaryFiles = True
-    elif opt == '-h':
-        usage(0)
-    else:
-        print('illegal option: ' + flag)
-        sys.exit(1)
-
-if not basename:
-    usage(1, 'You did not specify an output file.')
-
-if len(args) > 1:
-    usage(1, 'Only one main file may be specified.')
-
-outputType = 'exe'
-bl = basename.lower()
-if bl.endswith('.mf'):
-    outputType = 'mf'
-elif bl.endswith('.c'):
-    outputType = 'c'
-elif bl.endswith('.dll') or bl.endswith('.pyd') or bl.endswith('.so'):
-    basename = os.path.splitext(basename)[0]
-    outputType = 'dll'
-elif bl.endswith('.exe'):
-    basename = os.path.splitext(basename)[0]
-
-compileToExe = False
-if args:
-    startfile = args[0]
-    startmod = startfile
-    if startfile.endswith('.py') or startfile.endswith('.pyw') or \
-       startfile.endswith('.pyc') or startfile.endswith('.pyo'):
-        startmod = os.path.splitext(startfile)[0]
-
-    if outputType == 'dll' or outputType == 'c':
-        freezer.addModule(startmod, filename = startfile)
-    else:
-        freezer.addModule('__main__', filename = startfile)
-        compileToExe = True
-        addStartupModules = True
 
 
-elif outputType == 'exe':
-    # We must have a main module when making an executable.
-    usage(1, 'A main file needs to be specified when creating an executable.')
+def main(args=None):
+    if args is None:
+        args = sys.argv[1:]
+
+    freezer = FreezeTool.Freezer()
+
+    basename = None
+    addStartupModules = False
+
+    try:
+        opts, args = getopt.getopt(args, 'o:i:x:p:P:slkh')
+    except getopt.error as msg:
+        usage(1, msg)
+
+    for opt, arg in opts:
+        if opt == '-o':
+            basename = arg
+        elif opt == '-i':
+            for module in arg.split(','):
+                freezer.addModule(module)
+        elif opt == '-x':
+            for module in arg.split(','):
+                freezer.excludeModule(module)
+        elif opt == '-p':
+            for module in arg.split(','):
+                freezer.handleCustomPath(module)
+        elif opt == '-P':
+            sys.path.append(arg)
+        elif opt == '-s':
+            addStartupModules = True
+        elif opt == '-l':
+            freezer.linkExtensionModules = True
+        elif opt == '-k':
+            freezer.keepTemporaryFiles = True
+        elif opt == '-h':
+            usage(0)
+        else:
+            print('illegal option: ' + flag)
+            sys.exit(1)
+
+    if not basename:
+        usage(1, 'You did not specify an output file.')
+
+    if len(args) > 1:
+        usage(1, 'Only one main file may be specified.')
+
+    outputType = 'exe'
+    bl = basename.lower()
+    if bl.endswith('.mf'):
+        outputType = 'mf'
+    elif bl.endswith('.c'):
+        outputType = 'c'
+    elif bl.endswith('.dll') or bl.endswith('.pyd') or bl.endswith('.so'):
+        basename = os.path.splitext(basename)[0]
+        outputType = 'dll'
+    elif bl.endswith('.exe'):
+        basename = os.path.splitext(basename)[0]
+
+    compileToExe = False
+    if args:
+        startfile = args[0]
+        startmod = startfile
+        if startfile.endswith('.py') or startfile.endswith('.pyw') or \
+        startfile.endswith('.pyc') or startfile.endswith('.pyo'):
+            startmod = os.path.splitext(startfile)[0]
+
+        if outputType == 'dll' or outputType == 'c':
+            freezer.addModule(startmod, filename = startfile)
+        else:
+            freezer.addModule('__main__', filename = startfile)
+            compileToExe = True
+            addStartupModules = True
+
+    elif outputType == 'exe':
+        # We must have a main module when making an executable.
+        usage(1, 'A main file needs to be specified when creating an executable.')
+
+    freezer.done(addStartupModules = addStartupModules)
+
+    if outputType == 'mf':
+        freezer.writeMultifile(basename)
+    elif outputType == 'c':
+        freezer.writeCode(basename)
+    else:
+        freezer.generateCode(basename, compileToExe = compileToExe)
 
 
-freezer.done(addStartupModules = addStartupModules)
+    return 0
 
 
-if outputType == 'mf':
-    freezer.writeMultifile(basename)
-elif outputType == 'c':
-    freezer.writeCode(basename)
-else:
-    freezer.generateCode(basename, compileToExe = compileToExe)
 
 
+if __name__ == '__main__':
+    sys.exit(main())

+ 5 - 0
direct/src/stdpy/__init__.py

@@ -0,0 +1,5 @@
+"""
+This package contains various modules that provide a drop-in substitute
+for some of the built-in Python modules.  These substitutes make better
+use of Panda3D's virtual file system and threading system.
+"""

+ 35 - 11
direct/src/stdpy/thread.py

@@ -11,18 +11,32 @@ __all__ = [
     'interrupt_main',
     'interrupt_main',
     'exit', 'allocate_lock', 'get_ident',
     'exit', 'allocate_lock', 'get_ident',
     'stack_size',
     'stack_size',
+    'force_yield', 'consider_yield',
     'forceYield', 'considerYield',
     'forceYield', 'considerYield',
+    'TIMEOUT_MAX'
     ]
     ]
 
 
 from panda3d import core
 from panda3d import core
+import sys
+
+if sys.platform == "win32":
+    TIMEOUT_MAX = float(0xffffffff // 1000)
+else:
+    TIMEOUT_MAX = float(0x7fffffffffffffff // 1000000000)
 
 
 # These methods are defined in Panda, and are particularly useful if
 # These methods are defined in Panda, and are particularly useful if
 # you may be running in Panda's SIMPLE_THREADS compilation mode.
 # you may be running in Panda's SIMPLE_THREADS compilation mode.
-forceYield = core.Thread.forceYield
-considerYield = core.Thread.considerYield
+force_yield = core.Thread.force_yield
+consider_yield = core.Thread.consider_yield
 
 
-class error(Exception):
-    pass
+forceYield = force_yield
+considerYield = consider_yield
+
+if sys.version_info >= (3, 3):
+    error = RuntimeError
+else:
+    class error(Exception):
+        pass
 
 
 class LockType:
 class LockType:
     """ Implements a mutex lock.  Instead of directly subclassing
     """ Implements a mutex lock.  Instead of directly subclassing
@@ -36,13 +50,18 @@ class LockType:
         self.__cvar = core.ConditionVar(self.__lock)
         self.__cvar = core.ConditionVar(self.__lock)
         self.__locked = False
         self.__locked = False
 
 
-    def acquire(self, waitflag = 1):
+    def acquire(self, waitflag = 1, timeout = -1):
         self.__lock.acquire()
         self.__lock.acquire()
         try:
         try:
             if self.__locked and not waitflag:
             if self.__locked and not waitflag:
                 return False
                 return False
-            while self.__locked:
-                self.__cvar.wait()
+
+            if timeout >= 0:
+                while self.__locked:
+                    self.__cvar.wait(timeout)
+            else:
+                while self.__locked:
+                    self.__cvar.wait()
 
 
             self.__locked = True
             self.__locked = True
             return True
             return True
@@ -202,12 +221,17 @@ def _get_thread_locals(thread, i):
 def _remove_thread_id(threadId):
 def _remove_thread_id(threadId):
     """ Removes the thread with the indicated ID from the thread list. """
     """ Removes the thread with the indicated ID from the thread list. """
 
 
+    # On interpreter shutdown, Python may set module globals to None.
+    if _threadsLock is None or _threads is None:
+        return
+
     _threadsLock.acquire()
     _threadsLock.acquire()
     try:
     try:
-        thread, locals, wrapper = _threads[threadId]
-        assert thread.getPythonIndex() == threadId
-        del _threads[threadId]
-        thread.setPythonIndex(-1)
+        if threadId in _threads:
+            thread, locals, wrapper = _threads[threadId]
+            assert thread.getPythonIndex() == threadId
+            del _threads[threadId]
+            thread.setPythonIndex(-1)
 
 
     finally:
     finally:
         _threadsLock.release()
         _threadsLock.release()

+ 33 - 11
direct/src/stdpy/threading.py

@@ -35,11 +35,15 @@ __all__ = [
     'Event',
     'Event',
     'Timer',
     'Timer',
     'local',
     'local',
-    'current_thread', 'currentThread',
-    'enumerate', 'active_count', 'activeCount',
+    'current_thread',
+    'main_thread',
+    'enumerate', 'active_count',
     'settrace', 'setprofile', 'stack_size',
     'settrace', 'setprofile', 'stack_size',
+    'TIMEOUT_MAX',
     ]
     ]
 
 
+TIMEOUT_MAX = _thread.TIMEOUT_MAX
+
 local = _thread._local
 local = _thread._local
 _newname = _thread._newname
 _newname = _thread._newname
 
 
@@ -98,7 +102,15 @@ class Thread(ThreadBase):
         self.__dict__['daemon'] = current.daemon
         self.__dict__['daemon'] = current.daemon
         self.__dict__['name'] = name
         self.__dict__['name'] = name
 
 
-        self.__thread = core.PythonThread(self.run, None, name, name)
+        def call_run():
+            # As soon as the thread is done, break the circular reference.
+            try:
+                self.run()
+            finally:
+                self.__thread = None
+                _thread._remove_thread_id(self.ident)
+
+        self.__thread = core.PythonThread(call_run, None, name, name)
         threadId = _thread._add_thread(self.__thread, weakref.proxy(self))
         threadId = _thread._add_thread(self.__thread, weakref.proxy(self))
         self.__dict__['ident'] = threadId
         self.__dict__['ident'] = threadId
 
 
@@ -109,16 +121,17 @@ class Thread(ThreadBase):
             _thread._remove_thread_id(self.ident)
             _thread._remove_thread_id(self.ident)
 
 
     def is_alive(self):
     def is_alive(self):
-        return self.__thread.isStarted()
+        thread = self.__thread
+        return thread is not None and thread.is_started()
 
 
-    def isAlive(self):
-        return self.__thread.isStarted()
+    isAlive = is_alive
 
 
     def start(self):
     def start(self):
-        if self.__thread.isStarted():
+        thread = self.__thread
+        if thread is None or thread.is_started():
             raise RuntimeError
             raise RuntimeError
 
 
-        if not self.__thread.start(core.TPNormal, True):
+        if not thread.start(core.TPNormal, True):
             raise RuntimeError
             raise RuntimeError
 
 
     def run(self):
     def run(self):
@@ -132,8 +145,12 @@ class Thread(ThreadBase):
     def join(self, timeout = None):
     def join(self, timeout = None):
         # We don't support a timed join here, sorry.
         # We don't support a timed join here, sorry.
         assert timeout is None
         assert timeout is None
-        self.__thread.join()
-        self.__thread = None
+        thread = self.__thread
+        if thread is not None:
+            thread.join()
+            # Clear the circular reference.
+            self.__thread = None
+            _thread._remove_thread_id(self.ident)
 
 
     def setName(self, name):
     def setName(self, name):
         self.__dict__['name'] = name
         self.__dict__['name'] = name
@@ -379,6 +396,10 @@ def current_thread():
     t = core.Thread.getCurrentThread()
     t = core.Thread.getCurrentThread()
     return _thread._get_thread_wrapper(t, _create_thread_wrapper)
     return _thread._get_thread_wrapper(t, _create_thread_wrapper)
 
 
+def main_thread():
+    t = core.Thread.getMainThread()
+    return _thread._get_thread_wrapper(t, _create_thread_wrapper)
+
 currentThread = current_thread
 currentThread = current_thread
 
 
 def enumerate():
 def enumerate():
@@ -386,7 +407,7 @@ def enumerate():
     _thread._threadsLock.acquire()
     _thread._threadsLock.acquire()
     try:
     try:
         for thread, locals, wrapper in list(_thread._threads.values()):
         for thread, locals, wrapper in list(_thread._threads.values()):
-            if wrapper and thread.isStarted():
+            if wrapper and wrapper.is_alive():
                 tlist.append(wrapper)
                 tlist.append(wrapper)
         return tlist
         return tlist
     finally:
     finally:
@@ -394,6 +415,7 @@ def enumerate():
 
 
 def active_count():
 def active_count():
     return len(enumerate())
     return len(enumerate())
+
 activeCount = active_count
 activeCount = active_count
 
 
 _settrace_func = None
 _settrace_func = None

+ 43 - 26
direct/src/stdpy/threading2.py

@@ -15,7 +15,7 @@ implementation. """
 
 
 import sys as _sys
 import sys as _sys
 
 
-from direct.stdpy import thread
+from direct.stdpy import thread as _thread
 from direct.stdpy.thread import stack_size, _newname, _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
@@ -23,16 +23,19 @@ _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
 
 
-# Rename some stuff so "from threading import *" is safe
-__all__ = ['activeCount', 'Condition', 'currentThread', 'enumerate', 'Event',
-           'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Thread',
-           'Timer', 'setprofile', 'settrace', 'local', 'stack_size']
+__all__ = ['get_ident', 'active_count', 'Condition', 'current_thread',
+           'enumerate', 'main_thread', 'TIMEOUT_MAX',
+           'Event', 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Thread',
+           'Timer', 'ThreadError',
+           'setprofile', 'settrace', 'local', 'stack_size']
 
 
-_start_new_thread = thread.start_new_thread
-_allocate_lock = thread.allocate_lock
-_get_ident = thread.get_ident
-ThreadError = thread.error
-del thread
+# Rename some stuff so "from threading import *" is safe
+_start_new_thread = _thread.start_new_thread
+_allocate_lock = _thread.allocate_lock
+get_ident = _thread.get_ident
+ThreadError = _thread.error
+TIMEOUT_MAX = _thread.TIMEOUT_MAX
+del _thread
 
 
 
 
 # Debug support (adapted from ihooks.py).
 # Debug support (adapted from ihooks.py).
@@ -446,7 +449,7 @@ class Thread(_Verbose):
         try:
         try:
             self.__started = True
             self.__started = True
             _active_limbo_lock.acquire()
             _active_limbo_lock.acquire()
-            _active[_get_ident()] = self
+            _active[get_ident()] = self
             del _limbo[self]
             del _limbo[self]
             _active_limbo_lock.release()
             _active_limbo_lock.release()
             if __debug__:
             if __debug__:
@@ -537,7 +540,7 @@ class Thread(_Verbose):
         _active_limbo_lock.acquire()
         _active_limbo_lock.acquire()
         try:
         try:
             try:
             try:
-                del _active[_get_ident()]
+                del _active[get_ident()]
             except KeyError:
             except KeyError:
                 if 'dummy_threading' not in _sys.modules:
                 if 'dummy_threading' not in _sys.modules:
                     raise
                     raise
@@ -581,10 +584,12 @@ class Thread(_Verbose):
         assert self.__initialized, "Thread.__init__() not called"
         assert self.__initialized, "Thread.__init__() not called"
         self.__name = str(name)
         self.__name = str(name)
 
 
-    def isAlive(self):
+    def is_alive(self):
         assert self.__initialized, "Thread.__init__() not called"
         assert self.__initialized, "Thread.__init__() not called"
         return self.__started and not self.__stopped
         return self.__started and not self.__stopped
 
 
+    isAlive = is_alive
+
     def isDaemon(self):
     def isDaemon(self):
         assert self.__initialized, "Thread.__init__() not called"
         assert self.__initialized, "Thread.__init__() not called"
         return self.__daemonic
         return self.__daemonic
@@ -634,7 +639,7 @@ class _MainThread(Thread):
         Thread.__init__(self, name="MainThread")
         Thread.__init__(self, name="MainThread")
         self._Thread__started = True
         self._Thread__started = True
         _active_limbo_lock.acquire()
         _active_limbo_lock.acquire()
-        _active[_get_ident()] = self
+        _active[get_ident()] = self
         _active_limbo_lock.release()
         _active_limbo_lock.release()
 
 
     def _set_daemon(self):
     def _set_daemon(self):
@@ -653,12 +658,6 @@ class _MainThread(Thread):
             self._note("%s: exiting", self)
             self._note("%s: exiting", self)
         self._Thread__delete()
         self._Thread__delete()
 
 
-def _pickSomeNonDaemonThread():
-    for t in enumerate():
-        if not t.isDaemon() and t.isAlive():
-            return t
-    return None
-
 
 
 # Dummy thread class to represent threads not started here.
 # Dummy thread class to represent threads not started here.
 # These aren't garbage collected when they die, nor can they be waited for.
 # These aren't garbage collected when they die, nor can they be waited for.
@@ -680,7 +679,7 @@ class _DummyThread(Thread):
 
 
         self._Thread__started = True
         self._Thread__started = True
         _active_limbo_lock.acquire()
         _active_limbo_lock.acquire()
-        _active[_get_ident()] = self
+        _active[get_ident()] = self
         _active_limbo_lock.release()
         _active_limbo_lock.release()
 
 
     def _set_daemon(self):
     def _set_daemon(self):
@@ -692,19 +691,23 @@ class _DummyThread(Thread):
 
 
 # Global API functions
 # Global API functions
 
 
-def currentThread():
+def current_thread():
     try:
     try:
-        return _active[_get_ident()]
+        return _active[get_ident()]
     except KeyError:
     except KeyError:
-        ##print "currentThread(): no current thread for", _get_ident()
+        ##print "current_thread(): no current thread for", get_ident()
         return _DummyThread()
         return _DummyThread()
 
 
-def activeCount():
+currentThread = current_thread
+
+def active_count():
     _active_limbo_lock.acquire()
     _active_limbo_lock.acquire()
     count = len(_active) + len(_limbo)
     count = len(_active) + len(_limbo)
     _active_limbo_lock.release()
     _active_limbo_lock.release()
     return count
     return count
 
 
+activeCount = active_count
+
 def enumerate():
 def enumerate():
     _active_limbo_lock.acquire()
     _active_limbo_lock.acquire()
     active = list(_active.values()) + list(_limbo.values())
     active = list(_active.values()) + list(_limbo.values())
@@ -717,7 +720,21 @@ def enumerate():
 # and make it available for the interpreter
 # and make it available for the interpreter
 # (Py_Main) as threading._shutdown.
 # (Py_Main) as threading._shutdown.
 
 
-_shutdown = _MainThread()._exitfunc
+_main_thread = _MainThread()
+_shutdown = _main_thread._exitfunc
+
+def _pickSomeNonDaemonThread():
+    for t in enumerate():
+        if not t.isDaemon() and t.isAlive():
+            return t
+    return None
+
+def main_thread():
+    """Return the main thread object.
+    In normal conditions, the main thread is the thread from which the
+    Python interpreter was started.
+    """
+    return _main_thread
 
 
 # get thread-local implementation, either from the thread
 # get thread-local implementation, either from the thread
 # module, or from the python fallback
 # module, or from the python fallback

+ 1 - 0
direct/src/task/TaskManagerGlobal.py

@@ -4,4 +4,5 @@ __all__ = ['taskMgr']
 
 
 from . import Task
 from . import Task
 
 
+#: The global task manager.
 taskMgr = Task.TaskManager()
 taskMgr = Task.TaskManager()

+ 4 - 3
direct/src/task/TaskTester.py

@@ -24,7 +24,8 @@ def taskCallback(task):
     spawnNewTask()
     spawnNewTask()
     return Task.done
     return Task.done
 
 
-taskMgr.removeTasksMatching("taskTester*")
+if __name__ == '__main__':
+    taskMgr.removeTasksMatching("taskTester*")
 
 
-for i in range(numTasks):
-    spawnNewTask()
+    for i in range(numTasks):
+        spawnNewTask()

+ 1 - 1
direct/src/task/Timer.py

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Contains the Timer class."""
 
 
 __all__ = ['Timer']
 __all__ = ['Timer']
 
 

+ 8 - 0
direct/src/task/__init__.py

@@ -0,0 +1,8 @@
+"""
+This package contains the Python interface to the task system, which
+manages scheduled functions that are executed at designated intervals.
+
+The global task manager object can be imported as a singleton::
+
+   from direct.task.TaskManagerGlobal import taskMgr
+"""

+ 1 - 1
direct/src/tkpanels/NotifyPanel.py

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Contains the NotifyPanel class."""
 
 
 __all__ = ['NotifyPanel']
 __all__ = ['NotifyPanel']
 
 

+ 4 - 1
direct/src/tkwidgets/SceneGraphExplorer.py

@@ -1,4 +1,7 @@
-"""Undocumented Module"""
+"""This module defines a widget used to display a graphical overview of the
+scene graph using the tkinter GUI system.
+
+Requires Pmw."""
 
 
 __all__ = ['SceneGraphExplorer', 'SceneGraphExplorerItem', 'explore']
 __all__ = ['SceneGraphExplorer', 'SceneGraphExplorerItem', 'explore']
 
 

+ 1 - 1
direct/src/tkwidgets/Tree.py

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Defines tree widgets for the tkinter GUI system."""
 
 
 __all__ = ['TreeNode', 'TreeItem']
 __all__ = ['TreeNode', 'TreeItem']
 
 

+ 1 - 1
direct/src/tkwidgets/WidgetPropertiesDialog.py

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Contains the WidgetPropertiesDialog class."""
 
 
 __all__ = ['WidgetPropertiesDialog']
 __all__ = ['WidgetPropertiesDialog']
 
 

File diff suppressed because it is too large
+ 671 - 683
dtool/src/cppparser/cppBison.cxx.prebuilt


+ 15 - 2
dtool/src/cppparser/cppBison.yxx

@@ -928,12 +928,21 @@ type_like_declaration:
 
 
   current_scope->add_declaration($2, global_scope, current_lexer, @2);
   current_scope->add_declaration($2, global_scope, current_lexer, @2);
 }
 }
-        | storage_class constructor_prototype maybe_initialize_or_constructor_body
+        | storage_class constructor_prototype
 {
 {
   if ($2 != (CPPInstance *)NULL) {
   if ($2 != (CPPInstance *)NULL) {
+    // Push the scope so that the initializers can make use of things defined
+    // in the class body.
+    push_scope($2->get_scope(current_scope, global_scope));
     $2->_storage_class |= (current_storage_class | $1);
     $2->_storage_class |= (current_storage_class | $1);
+  }
+}
+        maybe_initialize_or_constructor_body
+{
+  if ($2 != (CPPInstance *)NULL) {
+    pop_scope();
     current_scope->add_declaration($2, global_scope, current_lexer, @2);
     current_scope->add_declaration($2, global_scope, current_lexer, @2);
-    $2->set_initializer($3);
+    $2->set_initializer($4);
   }
   }
 }
 }
         | storage_class function_prototype maybe_initialize_or_function_body
         | storage_class function_prototype maybe_initialize_or_function_body
@@ -4042,6 +4051,10 @@ name:
         | KW_STATIC
         | KW_STATIC
 {
 {
   $$ = new CPPIdentifier("static", @1);
   $$ = new CPPIdentifier("static", @1);
+}
+        | KW_DEFAULT
+{
+  $$ = new CPPIdentifier("default", @1);
 }
 }
         ;
         ;
 
 

+ 2 - 2
dtool/src/dtoolbase/deletedBufferChain.cxx

@@ -106,8 +106,8 @@ deallocate(void *ptr, TypeHandle type_handle) {
   assert(ptr != (void *)NULL);
   assert(ptr != (void *)NULL);
 
 
 #ifdef DO_MEMORY_USAGE
 #ifdef DO_MEMORY_USAGE
-  type_handle.dec_memory_usage(TypeHandle::MC_deleted_chain_active,
-                               _buffer_size + flag_reserved_bytes);
+  const size_t alloc_size = _buffer_size + flag_reserved_bytes + MEMORY_HOOK_ALIGNMENT - 1;
+  type_handle.dec_memory_usage(TypeHandle::MC_deleted_chain_active, alloc_size);
   // type_handle.inc_memory_usage(TypeHandle::MC_deleted_chain_inactive,
   // type_handle.inc_memory_usage(TypeHandle::MC_deleted_chain_inactive,
   // _buffer_size + flag_reserved_bytes);
   // _buffer_size + flag_reserved_bytes);
 
 

+ 1 - 3
dtool/src/dtoolbase/dtool_platform.h

@@ -75,10 +75,8 @@
 #define DTOOL_PLATFORM "linux_ppc"
 #define DTOOL_PLATFORM "linux_ppc"
 #endif
 #endif
 
 
-#ifndef DTOOL_PLATFORM
+#if !defined(DTOOL_PLATFORM) && !defined(CPPPARSER)
 #error "Can't determine platform; please define DTOOL_PLATFORM in Config.pp file."
 #error "Can't determine platform; please define DTOOL_PLATFORM in Config.pp file."
 #endif
 #endif
 
 
-
-
 #endif
 #endif

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