Procházet zdrojové kódy

Merge branch 'master' into vulkan

rdb před 8 roky
rodič
revize
5d2bad2c8f
100 změnil soubory, kde provedl 1116 přidání a 1314 odebrání
  1. 28 8
      README.md
  2. 7 0
      direct/src/actor/__init__.py
  3. 4 0
      direct/src/controls/__init__.py
  4. 16 1
      direct/src/directbase/DirectStart.py
  5. 12 0
      direct/src/directbase/__init__.py
  6. 51 28
      direct/src/directdevices/DirectDeviceManager.py
  7. 1 1
      direct/src/directdevices/DirectRadamec.py
  8. 5 0
      direct/src/directdevices/__init__.py
  9. 3 0
      direct/src/directnotify/__init__.py
  10. 8 0
      direct/src/directtools/__init__.py
  11. 3 0
      direct/src/directutil/__init__.py
  12. 4 2
      direct/src/distributed/DistributedObject.py
  13. 8 6
      direct/src/distributed/DistributedSmoothNode.py
  14. 0 1
      direct/src/distributed/DoCollectionManager.py
  15. 0 7
      direct/src/distributed/StagedObject.py
  16. 5 0
      direct/src/distributed/__init__.py
  17. 4 1
      direct/src/extensions_native/__init__.py
  18. 11 0
      direct/src/filter/__init__.py
  19. 6 6
      direct/src/fsm/ClassicFSM.py
  20. 1 1
      direct/src/fsm/FSM.py
  21. 19 21
      direct/src/fsm/FourState.py
  22. 25 27
      direct/src/fsm/FourStateAI.py
  23. 6 0
      direct/src/fsm/__init__.py
  24. 1 1
      direct/src/gui/DirectButton.py
  25. 3 1
      direct/src/gui/DirectCheckButton.py
  26. 1 1
      direct/src/gui/DirectDialog.py
  27. 2 1
      direct/src/gui/DirectEntry.py
  28. 14 9
      direct/src/gui/DirectFrame.py
  29. 24 25
      direct/src/gui/DirectGuiBase.py
  30. 3 5
      direct/src/gui/DirectGuiGlobals.py
  31. 1 1
      direct/src/gui/DirectLabel.py
  32. 1 1
      direct/src/gui/DirectOptionMenu.py
  33. 4 1
      direct/src/gui/DirectRadioButton.py
  34. 1 1
      direct/src/gui/DirectScrollBar.py
  35. 1 1
      direct/src/gui/DirectScrolledFrame.py
  36. 1 1
      direct/src/gui/DirectScrolledList.py
  37. 1 1
      direct/src/gui/DirectSlider.py
  38. 1 1
      direct/src/gui/DirectWaitBar.py
  39. 16 1
      direct/src/gui/OnscreenText.py
  40. 12 0
      direct/src/gui/__init__.py
  41. 4 1
      direct/src/interval/IntervalGlobal.py
  42. 3 3
      direct/src/interval/IntervalManager.py
  43. 4 1
      direct/src/interval/MetaInterval.py
  44. 2 4
      direct/src/interval/ParticleInterval.py
  45. 3 5
      direct/src/interval/TestInterval.py
  46. 12 0
      direct/src/interval/__init__.py
  47. 3 0
      direct/src/motiontrail/__init__.py
  48. 5 2
      direct/src/p3d/AppRunner.py
  49. 4 0
      direct/src/p3d/__init__.py
  50. 7 0
      direct/src/particles/__init__.py
  51. 2 0
      direct/src/showbase/AppRunnerGlobal.py
  52. 1 1
      direct/src/showbase/Audio3DManager.py
  53. 3 1
      direct/src/showbase/BufferViewer.py
  54. 1 1
      direct/src/showbase/BulletinBoard.py
  55. 1 1
      direct/src/showbase/BulletinBoardWatcher.py
  56. 2 1
      direct/src/showbase/DirectObject.py
  57. 1 1
      direct/src/showbase/EventGroup.py
  58. 2 1
      direct/src/showbase/EventManager.py
  59. 2 1
      direct/src/showbase/EventManagerGlobal.py
  60. 1 1
      direct/src/showbase/Factory.py
  61. 2 4
      direct/src/showbase/FindCtaPaths.py
  62. 1 1
      direct/src/showbase/Finder.py
  63. 1 1
      direct/src/showbase/GarbageReport.py
  64. 2 3
      direct/src/showbase/Messenger.py
  65. 2 4
      direct/src/showbase/MirrorDemo.py
  66. 1 1
      direct/src/showbase/ObjectPool.py
  67. 10 12
      direct/src/showbase/ObjectReport.py
  68. 1 1
      direct/src/showbase/OnScreenDebug.py
  69. 7 10
      direct/src/showbase/Pool.py
  70. 2 4
      direct/src/showbase/SfxPlayer.py
  71. 2 5
      direct/src/showbase/ShadowDemo.py
  72. 2 4
      direct/src/showbase/ShadowPlacer.py
  73. 4 1
      direct/src/showbase/TaskThreaded.py
  74. 2 1
      direct/src/showbase/ThreeUpShow.py
  75. 3 1
      direct/src/showbase/Transitions.py
  76. 4 1
      direct/src/showbase/VerboseImport.py
  77. 90 83
      direct/src/showutil/pfreeze.py
  78. 5 0
      direct/src/stdpy/__init__.py
  79. 1 0
      direct/src/task/TaskManagerGlobal.py
  80. 4 3
      direct/src/task/TaskTester.py
  81. 1 1
      direct/src/task/Timer.py
  82. 8 0
      direct/src/task/__init__.py
  83. 1 1
      direct/src/tkpanels/NotifyPanel.py
  84. 4 1
      direct/src/tkwidgets/SceneGraphExplorer.py
  85. 1 1
      direct/src/tkwidgets/Tree.py
  86. 1 1
      direct/src/tkwidgets/WidgetPropertiesDialog.py
  87. 15 0
      doc/ReleaseNotes
  88. 243 583
      dtool/src/cppparser/cppBison.cxx.prebuilt
  89. 159 176
      dtool/src/cppparser/cppBison.h.prebuilt
  90. 13 2
      dtool/src/cppparser/cppBison.yxx
  91. 1 0
      dtool/src/cppparser/cppClosureType.cxx
  92. 6 1
      dtool/src/cppparser/cppExpression.cxx
  93. 6 6
      dtool/src/dtoolbase/deletedBufferChain.cxx
  94. 60 85
      dtool/src/dtoolbase/deletedChain.T
  95. 2 2
      dtool/src/dtoolbase/deletedChain.h
  96. 1 3
      dtool/src/dtoolbase/dtool_platform.h
  97. 45 12
      dtool/src/dtoolbase/dtoolbase.h
  98. 3 3
      dtool/src/dtoolbase/dtoolbase_cc.h
  99. 2 2
      dtool/src/dtoolbase/memoryBase.h
  100. 21 107
      dtool/src/dtoolbase/memoryHook.I

+ 28 - 8
README.md

@@ -18,6 +18,23 @@ resources. If you get stuck, ask for help from our active
 Panda3D is licensed under the Modified BSD License.  See the LICENSE file for
 more details.
 
+Installing Panda3D
+==================
+
+By far, the easiest way to install the latest development build of Panda3D
+into an existing Python installation is using the following command:
+
+```bash
+pip install --pre --extra-index-url https://archive.panda3d.org/ panda3d
+```
+
+If you prefer to install the full SDK with all tools, the latest development
+builds can be obtained from this page:
+
+https://www.panda3d.org/download.php?sdk&version=devel
+
+These are automatically kept up-to-date with the latest GitHub version of Panda.
+
 Building Panda3D
 ================
 
@@ -31,8 +48,8 @@ are included as part of the Windows 7.1 SDK.
 You will also need to have the third-party dependency libraries available for
 the build scripts to use.  These are available from one of these two URLs,
 depending on whether you are on a 32-bit or 64-bit system:
-https://www.panda3d.org/download/panda3d-1.9.2/panda3d-1.9.2-tools-win32.zip
-https://www.panda3d.org/download/panda3d-1.9.2/panda3d-1.9.2-tools-win64.zip
+https://www.panda3d.org/download/panda3d-1.9.4/panda3d-1.9.4-tools-win32.zip
+https://www.panda3d.org/download/panda3d-1.9.4/panda3d-1.9.4-tools-win64.zip
 
 After acquiring these dependencies, you may simply build Panda3D from the
 command prompt using the following command:
@@ -64,7 +81,7 @@ for you to install, depending on your distribution).
 The following command illustrates how to build Panda3D with some common
 options:
 ```bash
-python2.7 makepanda/makepanda.py --everything --installer --no-egl --no-gles --no-gles2
+python makepanda/makepanda.py --everything --installer --no-egl --no-gles --no-gles2 --no-opencv
 ```
 
 You will probably see some warnings saying that it's unable to find several
@@ -93,11 +110,14 @@ may have to use the installpanda.py script instead, which will directly copy the
 files into the appropriate locations on your computer.  You may have to run the
 `ldconfig` tool in order to update your library cache after installing Panda3D.
 
-Mac OS X
---------
+Alternatively, you can add the `--wheel` option, which will produce a .whl
+file that can be installed into a Python installation using `pip`.
+
+macOS
+-----
 
-On Mac OS X, you will need to download a set of precompiled thirdparty packages in order to
-compile Panda3D, which can be acquired from [here](https://www.panda3d.org/download/panda3d-1.9.2/panda3d-1.9.2-tools-mac.tar.gz).
+On macOS, you will need to download a set of precompiled thirdparty packages in order to
+compile Panda3D, which can be acquired from [here](https://www.panda3d.org/download/panda3d-1.9.4/panda3d-1.9.4-tools-mac.tar.gz).
 
 After placing the thirdparty directory inside the panda3d source directory,
 you may build Panda3D using a command like the following:
@@ -107,7 +127,7 @@ python makepanda/makepanda.py --everything --installer
 ```
 
 In order to make a universal build, pass the --universal flag.  You may also
-target a specific minimum Mac OS X version using the --osxtarget flag followed
+target a specific minimum macOS version using the --osxtarget flag followed
 by the release number, eg. 10.6 or 10.7.
 
 If the build was successful, makepanda will have generated a .dmg file in

+ 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.
+"""

+ 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__ = []
 

+ 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_CENTER = 0.0
 
-try:
-    myBase = base
-except:
-    myBase = simbase
 
 class DirectDeviceManager(VrpnClient, DirectObject):
     def __init__(self, server = None):
@@ -52,8 +48,13 @@ class DirectButtons(ButtonNode, DirectObject):
         ButtonNode.__init__(self, vrpnClient, device)
         # Create a unique name for this button object
         self.name = 'DirectButtons-' + repr(DirectButtons.buttonCount)
+
         # 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):
         if (index < 0) or (index >= self.getNumButtons()):
@@ -64,10 +65,10 @@ class DirectButtons(ButtonNode, DirectObject):
         return self.getNumButtons()
 
     def enable(self):
-        self.nodePath.reparentTo(myBase.dataRoot)
+        self.nodePath.reparentTo(self._base.dataRoot)
 
     def disable(self):
-        self.nodePath.reparentTo(myBase.dataUnused)
+        self.nodePath.reparentTo(self._base.dataUnused)
 
     def getName(self):
         return self.name
@@ -83,6 +84,12 @@ class DirectButtons(ButtonNode, DirectObject):
 
 class DirectAnalogs(AnalogNode, DirectObject):
     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):
         # Keep track of number of analogs created
         DirectAnalogs.analogCount += 1
@@ -90,20 +97,21 @@ class DirectAnalogs(AnalogNode, DirectObject):
         AnalogNode.__init__(self, vrpnClient, device)
         # Create a unique name for this analog object
         self.name = 'DirectAnalogs-' + repr(DirectAnalogs.analogCount)
+
         # 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
-        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
 
-
     def __getitem__(self, index):
         if (index < 0) or (index >= self.getNumControls()):
             raise IndexError
@@ -113,10 +121,10 @@ class DirectAnalogs(AnalogNode, DirectObject):
         return self.getNumControls()
 
     def enable(self):
-        self.nodePath.reparentTo(myBase.dataRoot)
+        self.nodePath.reparentTo(self._base.dataRoot)
 
     def disable(self):
-        self.nodePath.reparentTo(myBase.dataUnused)
+        self.nodePath.reparentTo(self._base.dataUnused)
 
     def normalizeWithoutCentering(self, val, minVal = -1, maxVal = 1):
         #
@@ -186,14 +194,19 @@ class DirectTracker(TrackerNode, DirectObject):
         TrackerNode.__init__(self, vrpnClient, device)
         # Create a unique name for this tracker object
         self.name = 'DirectTracker-' + repr(DirectTracker.trackerCount)
+
         # 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):
-        self.nodePath.reparentTo(myBase.dataRoot)
+        self.nodePath.reparentTo(self._base.dataRoot)
 
     def disable(self):
-        self.nodePath.reparentTo(myBase.dataUnused)
+        self.nodePath.reparentTo(self._base.dataUnused)
 
     def getName(self):
         return self.name
@@ -213,8 +226,13 @@ class DirectDials(DialNode, DirectObject):
         DialNode.__init__(self, vrpnClient, device)
         # Create a unique name for this dial object
         self.name = 'DirectDials-' + repr(DirectDials.dialCount)
+
         # 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):
         """
@@ -227,10 +245,10 @@ class DirectDials(DialNode, DirectObject):
         return self.getNumDials()
 
     def enable(self):
-        self.nodePath.reparentTo(myBase.dataRoot)
+        self.nodePath.reparentTo(self._base.dataRoot)
 
     def disable(self):
-        self.nodePath.reparentTo(myBase.dataUnused)
+        self.nodePath.reparentTo(self._base.dataUnused)
 
     def getName(self):
         return self.name
@@ -259,14 +277,19 @@ class DirectTimecodeReader(AnalogNode, DirectObject):
         self.seconds = 0
         self.minutes = 0
         self.hours = 0
+
         # 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):
-        self.nodePath.reparentTo(myBase.dataRoot)
+        self.nodePath.reparentTo(self._base.dataRoot)
 
     def disable(self):
-        self.nodePath.reparentTo(myBase.dataUnused)
+        self.nodePath.reparentTo(self._base.dataUnused)
 
     def getName(self):
         return self.name

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

@@ -21,7 +21,7 @@ class DirectRadamec(DirectObject):
     radamecCount = 0
     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
         if base.direct.deviceManager == None:
             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.
+"""

+ 4 - 2
direct/src/distributed/DistributedObject.py

@@ -4,7 +4,6 @@ from panda3d.core import *
 from panda3d.direct import *
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.distributed.DistributedObjectBase import DistributedObjectBase
-from direct.showbase.PythonUtil import StackTrace
 #from PyDatagram import PyDatagram
 #from PyDatagramIterator import PyDatagramIterator
 
@@ -259,7 +258,10 @@ class DistributedObject(DistributedObjectBase):
     def _destroyDO(self):
         # after this is called, the object is no longer a DistributedObject
         # but may still be used as a DelayDeleted object
-        self.destroyDoStackTrace = StackTrace()
+        if __debug__:
+            # StackTrace is omitted in packed versions
+            from direct.showbase.PythonUtil import StackTrace
+            self.destroyDoStackTrace = StackTrace()
         # check for leftover cached data that was not retrieved or flushed by this object
         # this will catch typos in the data name in calls to get/setCachedData
         if hasattr(self, '_cachedData'):

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

@@ -7,19 +7,21 @@ from . import DistributedNode
 from . import DistributedSmoothNodeBase
 from direct.task.Task import cont
 
+config = get_config_showbase()
+
 # This number defines our tolerance for out-of-sync telemetry packets.
 # If a packet appears to have originated from more than MaxFuture
 # seconds in the future, assume we're out of sync with the other
 # 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?
-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
 # 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
 # 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
 # each avatar, which is intended to compensate for relative clock
 # 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

+ 0 - 1
direct/src/distributed/DoCollectionManager.py

@@ -312,7 +312,6 @@ class DoCollectionManager:
         else:
             self.notify.warning('handleSetLocation: object %s not present' % self.getMsgChannel())
 
-    @exceptionLogged()
     def storeObjectLocation(self, object, parentId, zoneId):
         oldParentId = object.parentId
         oldZoneId = object.zoneId

+ 0 - 7
direct/src/distributed/StagedObject.py

@@ -17,7 +17,6 @@ class StagedObject:
         call any "handle" functions.
         """
         self.__state = initState
-        pass
 
     def goOnStage(self, *args, **kw):
         """
@@ -29,8 +28,6 @@ class StagedObject:
 
         if not self.isOnStage():
             self.handleOnStage(*args, **kw)
-            pass
-        pass
 
     def handleOnStage(self):
         """
@@ -39,7 +36,6 @@ class StagedObject:
         Don't forget to call down to this one, though.
         """
         self.__state = StagedObject.ON
-        pass
 
     def goOffStage(self, *args, **kw):
         """
@@ -51,8 +47,6 @@ class StagedObject:
 
         if not self.isOffStage():
             self.handleOffStage(*args, **kw)
-            pass
-        pass
 
     def handleOffStage(self):
         """
@@ -61,7 +55,6 @@ class StagedObject:
         Don't forget to call down to this one, though.
         """
         self.__state = StagedObject.OFF
-        pass
 
     def isOnStage(self):
         return self.__state == StagedObject.ON

+ 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.
+"""

+ 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.
+"""

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

@@ -1,13 +1,13 @@
-"""Undocumented Module"""
-
-__all__ = ['ClassicFSM']
-
 """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.showbase.DirectObject import DirectObject
 import weakref

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

@@ -1,5 +1,5 @@
 """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']

+ 19 - 21
direct/src/fsm/FourState.py

@@ -1,9 +1,7 @@
-"""Undocumented Module"""
+"""Contains the FourState class."""
 
 __all__ = ['FourState']
 
-
-
 from direct.directnotify import DirectNotifyGlobal
 #import DistributedObject
 from . import ClassicFSM
@@ -20,7 +18,7 @@ class FourState:
     Inherit from FourStateFSM and pass in your states.  Two of
     the states should be oposites of each other and the other
     two should be the transition states between the first two.
-    E.g.
+    E.g::
 
                     +--------+
                  -->| closed | --
@@ -90,7 +88,8 @@ class FourState:
         off (and so is state 2 which is oposite of 4 and therefore
         oposite of 'on').
         """
-        assert self.debugPrint("FourState(names=%s)"%(names))
+        self.stateIndex = 0
+        assert self.__debugPrint("FourState(names=%s)"%(names))
         self.track = None
         self.stateTime = 0.0
         self.names = names
@@ -120,7 +119,6 @@ class FourState:
                            self.exitState4,
                            [names[1]]),
             }
-        self.stateIndex = 0
         self.fsm = ClassicFSM.ClassicFSM('FourState',
                            list(self.states.values()),
                            # Initial State
@@ -131,7 +129,7 @@ class FourState:
         self.fsm.enterInitialState()
 
     def setTrack(self, track):
-        assert self.debugPrint("setTrack(track=%s)"%(track,))
+        assert self.__debugPrint("setTrack(track=%s)"%(track,))
         if self.track is not None:
             self.track.pause()
             self.track = None
@@ -147,27 +145,27 @@ class FourState:
     # If the client wants the state changed it needs to
     # send a request to the AI.
     #def setIsOn(self, isOn):
-    #    assert self.debugPrint("setIsOn(isOn=%s)"%(isOn,))
+    #    assert self.__debugPrint("setIsOn(isOn=%s)"%(isOn,))
     #    pass
 
     def isOn(self):
-        assert self.debugPrint("isOn() returning %s (stateIndex=%s)"%(self.stateIndex==4, self.stateIndex))
+        assert self.__debugPrint("isOn() returning %s (stateIndex=%s)"%(self.stateIndex==4, self.stateIndex))
         return self.stateIndex==4
 
     def changedOnState(self, isOn):
         """
         Allow derived classes to overide this.
         """
-        assert self.debugPrint("changedOnState(isOn=%s)"%(isOn,))
+        assert self.__debugPrint("changedOnState(isOn=%s)"%(isOn,))
 
     ##### state 0 #####
 
     def enterState0(self):
-        assert self.debugPrint("enter0()")
+        assert self.__debugPrint("enter0()")
         self.enterStateN(0)
 
     def exitState0(self):
-        assert self.debugPrint("exit0()")
+        assert self.__debugPrint("exit0()")
         # It's important for FourStates to broadcast their state
         # when they are generated on the client. Before I put this in,
         # if a door was generated and went directly to an 'open' state,
@@ -177,43 +175,43 @@ class FourState:
     ##### state 1 #####
 
     def enterState1(self):
-        assert self.debugPrint("enterState1()")
+        assert self.__debugPrint("enterState1()")
         self.enterStateN(1)
 
     def exitState1(self):
-        assert self.debugPrint("exitState1()")
+        assert self.__debugPrint("exitState1()")
 
     ##### state 2 #####
 
     def enterState2(self):
-        assert self.debugPrint("enterState2()")
+        assert self.__debugPrint("enterState2()")
         self.enterStateN(2)
 
     def exitState2(self):
-        assert self.debugPrint("exitState2()")
+        assert self.__debugPrint("exitState2()")
 
     ##### state 3 #####
 
     def enterState3(self):
-        assert self.debugPrint("enterState3()")
+        assert self.__debugPrint("enterState3()")
         self.enterStateN(3)
 
     def exitState3(self):
-        assert self.debugPrint("exitState3()")
+        assert self.__debugPrint("exitState3()")
 
     ##### state 4 #####
 
     def enterState4(self):
-        assert self.debugPrint("enterState4()")
+        assert self.__debugPrint("enterState4()")
         self.enterStateN(4)
         self.changedOnState(1)
 
     def exitState4(self):
-        assert self.debugPrint("exitState4()")
+        assert self.__debugPrint("exitState4()")
         self.changedOnState(0)
 
     if __debug__:
-        def debugPrint(self, message):
+        def __debugPrint(self, message):
             """for debugging"""
             return self.notify.debug("%d (%d) %s"%(
                     id(self), self.stateIndex==4, message))

+ 25 - 27
direct/src/fsm/FourStateAI.py

@@ -1,9 +1,7 @@
-"""Undocumented Module"""
+"""Contains the FourStateAI class.  See also :mod:`.FourState`."""
 
 __all__ = ['FourStateAI']
 
-
-
 from direct.directnotify import DirectNotifyGlobal
 #import DistributedObjectAI
 from . import ClassicFSM
@@ -21,7 +19,7 @@ class FourStateAI:
     Inherit from FourStateFSM and pass in your states.  Two of
     the states should be oposites of each other and the other
     two should be the transition states between the first two.
-    E.g.
+    E.g::
 
                     +--------+
                  -->| closed | --
@@ -93,11 +91,11 @@ class FourStateAI:
         off (and so is state 2 which is oposite of state 4 and therefore
         oposite of 'on').
         """
-        assert self.debugPrint(
+        self.stateIndex = 0
+        assert self.__debugPrint(
                 "FourStateAI(names=%s, durations=%s)"
                 %(names, durations))
         self.doLaterTask = None
-        self.stateIndex = 0
         assert len(names) == 5
         assert len(names) == len(durations)
         self.names = names
@@ -137,7 +135,7 @@ class FourStateAI:
         self.fsm.enterInitialState()
 
     def delete(self):
-        assert self.debugPrint("delete()")
+        assert self.__debugPrint("delete()")
         if self.doLaterTask is not None:
             self.doLaterTask.remove()
             del self.doLaterTask
@@ -145,15 +143,15 @@ class FourStateAI:
         del self.fsm
 
     def getState(self):
-        assert self.debugPrint("getState() returning %s"%(self.stateIndex,))
+        assert self.__debugPrint("getState() returning %s"%(self.stateIndex,))
         return [self.stateIndex]
 
     def sendState(self):
-        assert self.debugPrint("sendState()")
+        assert self.__debugPrint("sendState()")
         self.sendUpdate('setState', self.getState())
 
     def setIsOn(self, isOn):
-        assert self.debugPrint("setIsOn(isOn=%s)"%(isOn,))
+        assert self.__debugPrint("setIsOn(isOn=%s)"%(isOn,))
         if isOn:
             if self.stateIndex != 4:
                 # ...if it's not On; request turning on:
@@ -170,7 +168,7 @@ class FourStateAI:
         #    self.fsm.request(self.states[nextState])
 
     def isOn(self):
-        assert self.debugPrint("isOn() returning %s (stateIndex=%s)"%(self.stateIndex==4, self.stateIndex))
+        assert self.__debugPrint("isOn() returning %s (stateIndex=%s)"%(self.stateIndex==4, self.stateIndex))
         return self.stateIndex==4
 
     def changedOnState(self, isOn):
@@ -179,12 +177,12 @@ class FourStateAI:
         The self.isOn value has toggled.  Call getIsOn() to
         get the current state.
         """
-        assert self.debugPrint("changedOnState(isOn=%s)"%(isOn,))
+        assert self.__debugPrint("changedOnState(isOn=%s)"%(isOn,))
 
     ##### states #####
 
     def switchToNextStateTask(self, task):
-        assert self.debugPrint("switchToNextStateTask()")
+        assert self.__debugPrint("switchToNextStateTask()")
         self.fsm.request(self.states[self.nextStateIndex])
         return Task.done
 
@@ -193,11 +191,11 @@ class FourStateAI:
         This function is intentionaly simple so that derived classes
         may easily alter the network message.
         """
-        assert self.debugPrint("distributeStateChange()")
+        assert self.__debugPrint("distributeStateChange()")
         self.sendState()
 
     def enterStateN(self, stateIndex, nextStateIndex):
-        assert self.debugPrint(
+        assert self.__debugPrint(
             "enterStateN(stateIndex=%s, nextStateIndex=%s)"%
             (stateIndex, nextStateIndex))
         self.stateIndex = stateIndex
@@ -211,7 +209,7 @@ class FourStateAI:
                 "enterStateN-timer-%s"%id(self))
 
     def exitStateN(self):
-        assert self.debugPrint("exitStateN()")
+        assert self.__debugPrint("exitStateN()")
         if self.doLaterTask:
             taskMgr.remove(self.doLaterTask)
             self.doLaterTask=None
@@ -219,56 +217,56 @@ class FourStateAI:
     ##### state 0 #####
 
     def enterState0(self):
-        assert self.debugPrint("enter0()")
+        assert self.__debugPrint("enter0()")
         self.enterStateN(0, 0)
 
     def exitState0(self):
-        assert self.debugPrint("exit0()")
+        assert self.__debugPrint("exit0()")
 
     ##### state 1 #####
 
     def enterState1(self):
-        #assert self.debugPrint("enterState1()")
+        #assert self.__debugPrint("enterState1()")
         self.enterStateN(1, 2)
 
     def exitState1(self):
-        assert self.debugPrint("exitState1()")
+        assert self.__debugPrint("exitState1()")
         self.exitStateN()
 
     ##### state 2 #####
 
     def enterState2(self):
-        #assert self.debugPrint("enterState2()")
+        #assert self.__debugPrint("enterState2()")
         self.enterStateN(2, 3)
 
     def exitState2(self):
-        assert self.debugPrint("exitState2()")
+        assert self.__debugPrint("exitState2()")
         self.exitStateN()
 
     ##### state 3 #####
 
     def enterState3(self):
-        #assert self.debugPrint("enterState3()")
+        #assert self.__debugPrint("enterState3()")
         self.enterStateN(3, 4)
 
     def exitState3(self):
-        assert self.debugPrint("exitState3()")
+        assert self.__debugPrint("exitState3()")
         self.exitStateN()
 
     ##### state 4 #####
 
     def enterState4(self):
-        assert self.debugPrint("enterState4()")
+        assert self.__debugPrint("enterState4()")
         self.enterStateN(4, 1)
         self.changedOnState(1)
 
     def exitState4(self):
-        assert self.debugPrint("exitState4()")
+        assert self.__debugPrint("exitState4()")
         self.exitStateN()
         self.changedOnState(0)
 
     if __debug__:
-        def debugPrint(self, message):
+        def __debugPrint(self, message):
             """for debugging"""
             return self.notify.debug("%d (%d) %s"%(
                     id(self), self.stateIndex==4, message))

+ 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']
 

+ 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']
 

+ 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']
 

+ 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']
 

+ 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']
 
@@ -19,14 +32,6 @@ class DirectFrame(DirectGuiWidget):
     DefDynGroups = ('text', 'geom', 'image')
     def __init__(self, parent = None, **kw):
         # 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 = (
             # Define type of DirectGuiWidget
             ('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
 command line argument parsing.
-"""
 
-"""
 Code Overview:
 
 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.
 """
 
+__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):
+    """Base class of all DirectGUI widgets."""
+
     def __init__(self):
         # Default id of all gui object, subclasses should override this
         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
 that can be used during widget construction
 """
+
+__all__ = []
+
 from panda3d.core import *
 
 defaultFont = None

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

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Contains the DirectLabel class."""
 
 __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']
 

+ 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']
 

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

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

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

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

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

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

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

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Defines the DirectSlider class."""
 
 __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']
 

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

@@ -35,7 +35,8 @@ class OnscreenText(NodePath):
                  font = None,
                  parent = None,
                  sort = 0,
-                 mayChange = True):
+                 mayChange = True,
+                 direction = None):
         """
         Make a text node from string, put it into the 2d sg and set it
         up with all the indicated parameters.
@@ -95,6 +96,9 @@ class OnscreenText(NodePath):
           mayChange: pass true if the text or its properties may need
               to be changed at runtime, false if it is static once
               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:
             parent = aspect2d
@@ -192,6 +196,17 @@ class OnscreenText(NodePath):
             textNode.setFrameColor(frame[0], frame[1], frame[2], frame[3])
             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.
         # We'd rather do it here, on the text itself, rather than on
         # 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__,
 # 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']
 
@@ -136,6 +137,5 @@ class IntervalManager(CIntervalManager):
         assert self.ivals[index] == None or self.ivals[index] == interval
         self.ivals[index] = interval
 
-# The global IntervalManager object.
+#: The global IntervalManager object.
 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']
 

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

@@ -1,11 +1,9 @@
-"""Undocumented Module"""
-
-__all__ = ['ParticleInterval']
-
 """
 Contains the ParticleInterval class
 """
 
+__all__ = ['ParticleInterval']
+
 from panda3d.core import *
 from panda3d.direct import *
 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.direct import *
 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
 distributable, to execute a packaged p3d application, but it can also
 be run directly via the Python interpreter (if the current Panda3D and
 Python versions match the version expected by the application).  See
 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"]

+ 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
 the AppRunner at startup. """
 
+#: Contains the global AppRunner instance, or None if this application
+#: was not run from the runtime environment.
 appRunner = None

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

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

+ 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']
 

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

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

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

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

+ 2 - 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']
 

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

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""This module defines the EventGroup class."""
 
 __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']
 

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

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

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

@@ -1,4 +1,4 @@
-"""Undocumented Module"""
+"""Contains the Factory class."""
 
 __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
 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.
@@ -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,
 which you will presumably have already on your PYTHONPATH. """
 
+__all__ = ['deCygwinify', 'getPaths']
+
 import os
 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']
 

+ 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']
 

+ 2 - 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']
 
@@ -531,7 +532,6 @@ class Messenger:
         keys.sort()
         for event in keys:
             if repr(event).find(needle) >= 0:
-                print(self.__eventRepr(event))
                 return {event: self.__callbacks[event]}
 
     def findAll(self, needle, limit=None):
@@ -545,7 +545,6 @@ class Messenger:
         keys.sort()
         for event in keys:
             if repr(event).find(needle) >= 0:
-                print(self.__eventRepr(event))
                 matches[event] = self.__callbacks[event]
                 # if the limit is not None, decrement and
                 # check for break:

+ 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.
 Call setupMirror() to create a mirror in the world that reflects
 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
 reflections, you will need to use a sphere map or a cube map."""
 
+__all__ = ['setupMirror', 'showFrustum']
+
 from panda3d.core import *
 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']
 

+ 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']
 
@@ -13,17 +22,6 @@ if sys.version_info >= (3, 0):
 else:
     import __builtin__ as builtins
 
-"""
->>> from direct.showbase import ObjectReport
-
->>> o=ObjectReport.ObjectReport('baseline')
->>> run()
-...
-
->>> o2=ObjectReport.ObjectReport('')
->>> o.diff(o2)
-"""
-
 class ExclusiveObjectPool(DirectObject.DirectObject):
     # ObjectPool specialization that excludes particular objects
     # 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']
 

+ 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
 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
@@ -12,12 +7,16 @@ or be the same type.
 
 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
 
@@ -116,5 +115,3 @@ class Pool:
 
     def __repr__(self):
         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']
 
@@ -95,6 +96,3 @@ class SfxPlayer:
             if node is not None:
                 finalVolume *= node.getNetAudioVolume()
             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
 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
@@ -14,6 +9,8 @@ multitexture rendering techniques.  It's not a particularly great
 way to do shadows.
 """
 
+__all__ = ['ShadowCaster', 'avatarShadow', 'piratesAvatarShadow', 'arbitraryShadow']
+
 from panda3d.core import *
 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.
 
@@ -10,6 +6,8 @@ Or it may do that later, right now it puts a node on the surface under
 the its parent node.
 """
 
+__all__ = ['ShadowPlacer']
+
 from direct.controls.ControlManager import CollisionHandlerRayStart
 from direct.directnotify import DirectNotifyGlobal
 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']
 
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.task import Task
 
+from .PythonUtil import SerialNumGen
+
+
 class TaskThreaded:
     """ 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

+ 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']
 

+ 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']
 

+ 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__ = []
 

+ 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
 imported directly or indirectly by the original startfile.py.
 
-Usage:
+Usage::
 
   pfreeze.py [opts] [startfile]
 
-Options:
+Options::
 
   -o output
      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.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.
+"""

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

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

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

@@ -24,7 +24,8 @@ def taskCallback(task):
     spawnNewTask()
     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']
 

+ 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']
 

+ 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']
 

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

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

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

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

+ 15 - 0
doc/ReleaseNotes

@@ -1,3 +1,18 @@
+------------------------  RELEASE 1.9.4  ------------------------
+
+One of the bugfixes in the last 1.9.3 release introduced a regression,
+therefore it was decided to make another 1.9.x release.
+
+* Fix 1.9.3 regression with generating geometry in threaded pipeline
+* Various compile warning fixes
+* Fix occasional crash in PNMImage::quick_filter_from()
+* Fix issue taking screenshots from an OpenGL FBO buffer
+* Fix various issues with MeshDrawer
+* Fix issue with collision sphere generation in bam2egg
+* Fix compile errors with more obscure Python configurations
+* Fix assert when using Texture.load_sub_image to load whole image
+* Fix fsm FourState
+
 ------------------------  RELEASE 1.9.3  ------------------------
 
 This issue fixes several bugs that were still found in 1.9.2.

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 243 - 583
dtool/src/cppparser/cppBison.cxx.prebuilt


+ 159 - 176
dtool/src/cppparser/cppBison.h.prebuilt

@@ -1,8 +1,8 @@
-/* A Bison parser, made by GNU Bison 2.7.  */
+/* A Bison parser, made by GNU Bison 3.0.4.  */
 
 /* Bison interface for Yacc-like parsers in C
 
-      Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -30,9 +30,9 @@
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
 
-#ifndef YY_CPPYY_BUILT_X64_TMP_CPPBISON_YXX_H_INCLUDED
-# define YY_CPPYY_BUILT_X64_TMP_CPPBISON_YXX_H_INCLUDED
-/* Enabling traces.  */
+#ifndef YY_CPPYY_BUILT_TMP_CPPBISON_YXX_H_INCLUDED
+# define YY_CPPYY_BUILT_TMP_CPPBISON_YXX_H_INCLUDED
+/* Debug traces.  */
 #ifndef YYDEBUG
 # define YYDEBUG 0
 #endif
@@ -40,156 +40,155 @@
 extern int cppyydebug;
 #endif
 
-/* Tokens.  */
+/* Token type.  */
 #ifndef YYTOKENTYPE
 # define YYTOKENTYPE
-   /* Put the tokens into the symbol table, so that GDB and other debuggers
-      know about them.  */
-   enum yytokentype {
-     REAL = 258,
-     INTEGER = 259,
-     CHAR_TOK = 260,
-     SIMPLE_STRING = 261,
-     SIMPLE_IDENTIFIER = 262,
-     STRING_LITERAL = 263,
-     CUSTOM_LITERAL = 264,
-     IDENTIFIER = 265,
-     TYPENAME_IDENTIFIER = 266,
-     TYPEPACK_IDENTIFIER = 267,
-     SCOPING = 268,
-     TYPEDEFNAME = 269,
-     ELLIPSIS = 270,
-     OROR = 271,
-     ANDAND = 272,
-     EQCOMPARE = 273,
-     NECOMPARE = 274,
-     LECOMPARE = 275,
-     GECOMPARE = 276,
-     LSHIFT = 277,
-     RSHIFT = 278,
-     POINTSAT_STAR = 279,
-     DOT_STAR = 280,
-     UNARY = 281,
-     UNARY_NOT = 282,
-     UNARY_NEGATE = 283,
-     UNARY_MINUS = 284,
-     UNARY_PLUS = 285,
-     UNARY_STAR = 286,
-     UNARY_REF = 287,
-     POINTSAT = 288,
-     SCOPE = 289,
-     PLUSPLUS = 290,
-     MINUSMINUS = 291,
-     TIMESEQUAL = 292,
-     DIVIDEEQUAL = 293,
-     MODEQUAL = 294,
-     PLUSEQUAL = 295,
-     MINUSEQUAL = 296,
-     OREQUAL = 297,
-     ANDEQUAL = 298,
-     XOREQUAL = 299,
-     LSHIFTEQUAL = 300,
-     RSHIFTEQUAL = 301,
-     ATTR_LEFT = 302,
-     ATTR_RIGHT = 303,
-     KW_ALIGNAS = 304,
-     KW_ALIGNOF = 305,
-     KW_AUTO = 306,
-     KW_BEGIN_PUBLISH = 307,
-     KW_BLOCKING = 308,
-     KW_BOOL = 309,
-     KW_CATCH = 310,
-     KW_CHAR = 311,
-     KW_CHAR16_T = 312,
-     KW_CHAR32_T = 313,
-     KW_CLASS = 314,
-     KW_CONST = 315,
-     KW_CONSTEXPR = 316,
-     KW_CONST_CAST = 317,
-     KW_DECLTYPE = 318,
-     KW_DEFAULT = 319,
-     KW_DELETE = 320,
-     KW_DOUBLE = 321,
-     KW_DYNAMIC_CAST = 322,
-     KW_ELSE = 323,
-     KW_END_PUBLISH = 324,
-     KW_ENUM = 325,
-     KW_EXTENSION = 326,
-     KW_EXTERN = 327,
-     KW_EXPLICIT = 328,
-     KW_PUBLISHED = 329,
-     KW_FALSE = 330,
-     KW_FINAL = 331,
-     KW_FLOAT = 332,
-     KW_FRIEND = 333,
-     KW_FOR = 334,
-     KW_GOTO = 335,
-     KW_HAS_VIRTUAL_DESTRUCTOR = 336,
-     KW_IF = 337,
-     KW_INLINE = 338,
-     KW_INT = 339,
-     KW_IS_ABSTRACT = 340,
-     KW_IS_BASE_OF = 341,
-     KW_IS_CLASS = 342,
-     KW_IS_CONSTRUCTIBLE = 343,
-     KW_IS_CONVERTIBLE_TO = 344,
-     KW_IS_DESTRUCTIBLE = 345,
-     KW_IS_EMPTY = 346,
-     KW_IS_ENUM = 347,
-     KW_IS_FINAL = 348,
-     KW_IS_FUNDAMENTAL = 349,
-     KW_IS_POD = 350,
-     KW_IS_POLYMORPHIC = 351,
-     KW_IS_STANDARD_LAYOUT = 352,
-     KW_IS_TRIVIAL = 353,
-     KW_IS_UNION = 354,
-     KW_LONG = 355,
-     KW_MAKE_MAP_PROPERTY = 356,
-     KW_MAKE_PROPERTY = 357,
-     KW_MAKE_PROPERTY2 = 358,
-     KW_MAKE_SEQ = 359,
-     KW_MAKE_SEQ_PROPERTY = 360,
-     KW_MUTABLE = 361,
-     KW_NAMESPACE = 362,
-     KW_NEW = 363,
-     KW_NOEXCEPT = 364,
-     KW_NULLPTR = 365,
-     KW_OPERATOR = 366,
-     KW_OVERRIDE = 367,
-     KW_PRIVATE = 368,
-     KW_PROTECTED = 369,
-     KW_PUBLIC = 370,
-     KW_REGISTER = 371,
-     KW_REINTERPRET_CAST = 372,
-     KW_RETURN = 373,
-     KW_SHORT = 374,
-     KW_SIGNED = 375,
-     KW_SIZEOF = 376,
-     KW_STATIC = 377,
-     KW_STATIC_ASSERT = 378,
-     KW_STATIC_CAST = 379,
-     KW_STRUCT = 380,
-     KW_TEMPLATE = 381,
-     KW_THREAD_LOCAL = 382,
-     KW_THROW = 383,
-     KW_TRUE = 384,
-     KW_TRY = 385,
-     KW_TYPEDEF = 386,
-     KW_TYPEID = 387,
-     KW_TYPENAME = 388,
-     KW_UNDERLYING_TYPE = 389,
-     KW_UNION = 390,
-     KW_UNSIGNED = 391,
-     KW_USING = 392,
-     KW_VIRTUAL = 393,
-     KW_VOID = 394,
-     KW_VOLATILE = 395,
-     KW_WCHAR_T = 396,
-     KW_WHILE = 397,
-     START_CPP = 398,
-     START_CONST_EXPR = 399,
-     START_TYPE = 400
-   };
+  enum yytokentype
+  {
+    REAL = 258,
+    INTEGER = 259,
+    CHAR_TOK = 260,
+    SIMPLE_STRING = 261,
+    SIMPLE_IDENTIFIER = 262,
+    STRING_LITERAL = 263,
+    CUSTOM_LITERAL = 264,
+    IDENTIFIER = 265,
+    TYPENAME_IDENTIFIER = 266,
+    TYPEPACK_IDENTIFIER = 267,
+    SCOPING = 268,
+    TYPEDEFNAME = 269,
+    ELLIPSIS = 270,
+    OROR = 271,
+    ANDAND = 272,
+    EQCOMPARE = 273,
+    NECOMPARE = 274,
+    LECOMPARE = 275,
+    GECOMPARE = 276,
+    LSHIFT = 277,
+    RSHIFT = 278,
+    POINTSAT_STAR = 279,
+    DOT_STAR = 280,
+    UNARY = 281,
+    UNARY_NOT = 282,
+    UNARY_NEGATE = 283,
+    UNARY_MINUS = 284,
+    UNARY_PLUS = 285,
+    UNARY_STAR = 286,
+    UNARY_REF = 287,
+    POINTSAT = 288,
+    SCOPE = 289,
+    PLUSPLUS = 290,
+    MINUSMINUS = 291,
+    TIMESEQUAL = 292,
+    DIVIDEEQUAL = 293,
+    MODEQUAL = 294,
+    PLUSEQUAL = 295,
+    MINUSEQUAL = 296,
+    OREQUAL = 297,
+    ANDEQUAL = 298,
+    XOREQUAL = 299,
+    LSHIFTEQUAL = 300,
+    RSHIFTEQUAL = 301,
+    ATTR_LEFT = 302,
+    ATTR_RIGHT = 303,
+    KW_ALIGNAS = 304,
+    KW_ALIGNOF = 305,
+    KW_AUTO = 306,
+    KW_BEGIN_PUBLISH = 307,
+    KW_BLOCKING = 308,
+    KW_BOOL = 309,
+    KW_CATCH = 310,
+    KW_CHAR = 311,
+    KW_CHAR16_T = 312,
+    KW_CHAR32_T = 313,
+    KW_CLASS = 314,
+    KW_CONST = 315,
+    KW_CONSTEXPR = 316,
+    KW_CONST_CAST = 317,
+    KW_DECLTYPE = 318,
+    KW_DEFAULT = 319,
+    KW_DELETE = 320,
+    KW_DOUBLE = 321,
+    KW_DYNAMIC_CAST = 322,
+    KW_ELSE = 323,
+    KW_END_PUBLISH = 324,
+    KW_ENUM = 325,
+    KW_EXTENSION = 326,
+    KW_EXTERN = 327,
+    KW_EXPLICIT = 328,
+    KW_PUBLISHED = 329,
+    KW_FALSE = 330,
+    KW_FINAL = 331,
+    KW_FLOAT = 332,
+    KW_FRIEND = 333,
+    KW_FOR = 334,
+    KW_GOTO = 335,
+    KW_HAS_VIRTUAL_DESTRUCTOR = 336,
+    KW_IF = 337,
+    KW_INLINE = 338,
+    KW_INT = 339,
+    KW_IS_ABSTRACT = 340,
+    KW_IS_BASE_OF = 341,
+    KW_IS_CLASS = 342,
+    KW_IS_CONSTRUCTIBLE = 343,
+    KW_IS_CONVERTIBLE_TO = 344,
+    KW_IS_DESTRUCTIBLE = 345,
+    KW_IS_EMPTY = 346,
+    KW_IS_ENUM = 347,
+    KW_IS_FINAL = 348,
+    KW_IS_FUNDAMENTAL = 349,
+    KW_IS_POD = 350,
+    KW_IS_POLYMORPHIC = 351,
+    KW_IS_STANDARD_LAYOUT = 352,
+    KW_IS_TRIVIAL = 353,
+    KW_IS_UNION = 354,
+    KW_LONG = 355,
+    KW_MAKE_MAP_PROPERTY = 356,
+    KW_MAKE_PROPERTY = 357,
+    KW_MAKE_PROPERTY2 = 358,
+    KW_MAKE_SEQ = 359,
+    KW_MAKE_SEQ_PROPERTY = 360,
+    KW_MUTABLE = 361,
+    KW_NAMESPACE = 362,
+    KW_NEW = 363,
+    KW_NOEXCEPT = 364,
+    KW_NULLPTR = 365,
+    KW_OPERATOR = 366,
+    KW_OVERRIDE = 367,
+    KW_PRIVATE = 368,
+    KW_PROTECTED = 369,
+    KW_PUBLIC = 370,
+    KW_REGISTER = 371,
+    KW_REINTERPRET_CAST = 372,
+    KW_RETURN = 373,
+    KW_SHORT = 374,
+    KW_SIGNED = 375,
+    KW_SIZEOF = 376,
+    KW_STATIC = 377,
+    KW_STATIC_ASSERT = 378,
+    KW_STATIC_CAST = 379,
+    KW_STRUCT = 380,
+    KW_TEMPLATE = 381,
+    KW_THREAD_LOCAL = 382,
+    KW_THROW = 383,
+    KW_TRUE = 384,
+    KW_TRY = 385,
+    KW_TYPEDEF = 386,
+    KW_TYPEID = 387,
+    KW_TYPENAME = 388,
+    KW_UNDERLYING_TYPE = 389,
+    KW_UNION = 390,
+    KW_UNSIGNED = 391,
+    KW_USING = 392,
+    KW_VIRTUAL = 393,
+    KW_VOID = 394,
+    KW_VOLATILE = 395,
+    KW_WCHAR_T = 396,
+    KW_WHILE = 397,
+    START_CPP = 398,
+    START_CONST_EXPR = 399,
+    START_TYPE = 400
+  };
 #endif
 /* Tokens.  */
 #define REAL 258
@@ -336,40 +335,24 @@ extern int cppyydebug;
 #define START_CONST_EXPR 399
 #define START_TYPE 400
 
+/* Value type.  */
 
-
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
-# define YYSTYPE_IS_DECLARED 1
-#endif
-
+/* Location type.  */
 #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
-typedef struct YYLTYPE
+typedef struct YYLTYPE YYLTYPE;
+struct YYLTYPE
 {
   int first_line;
   int first_column;
   int last_line;
   int last_column;
-} YYLTYPE;
-# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
+};
 # define YYLTYPE_IS_DECLARED 1
 # define YYLTYPE_IS_TRIVIAL 1
 #endif
 
 
-#ifdef YYPARSE_PARAM
-#if defined __STDC__ || defined __cplusplus
-int cppyyparse (void *YYPARSE_PARAM);
-#else
-int cppyyparse ();
-#endif
-#else /* ! YYPARSE_PARAM */
-#if defined __STDC__ || defined __cplusplus
+
 int cppyyparse (void);
-#else
-int cppyyparse ();
-#endif
-#endif /* ! YYPARSE_PARAM */
 
-#endif /* !YY_CPPYY_BUILT_X64_TMP_CPPBISON_YXX_H_INCLUDED  */
+#endif /* !YY_CPPYY_BUILT_TMP_CPPBISON_YXX_H_INCLUDED  */

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

@@ -928,12 +928,21 @@ type_like_declaration:
 
   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) {
+    // 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);
+  }
+}
+        maybe_initialize_or_constructor_body
+{
+  if ($2 != (CPPInstance *)NULL) {
+    pop_scope();
     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
@@ -1451,6 +1460,7 @@ function_operator:
 more_template_declaration:
         type_like_declaration
         | template_declaration
+        | friend_declaration
         ;
 
 template_declaration:
@@ -1464,6 +1474,7 @@ template_declaration:
   pop_scope();
 }
         | KW_TEMPLATE type_like_declaration
+        | KW_TEMPLATE friend_declaration
         ;
 
 template_formal_parameters:

+ 1 - 0
dtool/src/cppparser/cppClosureType.cxx

@@ -12,6 +12,7 @@
  */
 
 #include "cppClosureType.h"
+#include "cppParameterList.h"
 #include "cppExpression.h"
 
 /**

+ 6 - 1
dtool/src/cppparser/cppExpression.cxx

@@ -1658,7 +1658,12 @@ output(ostream &out, int indent_level, CPPScope *scope, bool) const {
     break;
 
   case T_function:
-    out << _u._fgroup->_name;
+    // Pick any instance; they all have the same name anyway.
+    if (!_u._fgroup->_instances.empty() && _u._fgroup->_instances[0]->_ident != NULL) {
+      _u._fgroup->_instances[0]->_ident->output(out, scope);
+    } else {
+      out << _u._fgroup->_name;
+    }
     break;
 
   case T_unknown_ident:

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

@@ -39,7 +39,7 @@ allocate(size_t size, TypeHandle type_handle) {
   assert(size <= _buffer_size);
 
   // Determine how much space to allocate.
-  const size_t alloc_size = _buffer_size + flag_reserved_bytes + MemoryHook::get_memory_alignment() - 1;
+  const size_t alloc_size = _buffer_size + flag_reserved_bytes + MEMORY_HOOK_ALIGNMENT - 1;
 
   ObjectNode *obj;
 
@@ -71,8 +71,8 @@ allocate(size_t size, TypeHandle type_handle) {
 
   // Allocate memory, and make sure the object starts at the proper alignment.
   void *mem = NeverFreeMemory::alloc(alloc_size);
-  intptr_t pad = (-(intptr_t)flag_reserved_bytes - (intptr_t)mem) % MemoryHook::get_memory_alignment();
-  obj = (ObjectNode *)((uintptr_t)mem + pad);
+  uintptr_t aligned = ((uintptr_t)mem + flag_reserved_bytes + MEMORY_HOOK_ALIGNMENT - 1) & ~(MEMORY_HOOK_ALIGNMENT - 1);
+  obj = (ObjectNode *)(aligned - flag_reserved_bytes);
 
 #ifdef USE_DELETEDCHAINFLAG
   obj->_flag = DCF_alive;
@@ -81,7 +81,7 @@ allocate(size_t size, TypeHandle type_handle) {
   void *ptr = node_to_buffer(obj);
 
 #ifndef NDEBUG
-  assert(((uintptr_t)ptr % MemoryHook::get_memory_alignment()) == 0);
+  assert(((uintptr_t)ptr % MEMORY_HOOK_ALIGNMENT) == 0);
 #endif
 
 #ifdef DO_MEMORY_USAGE
@@ -106,8 +106,8 @@ deallocate(void *ptr, TypeHandle type_handle) {
   assert(ptr != (void *)NULL);
 
 #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,
   // _buffer_size + flag_reserved_bytes);
 

+ 60 - 85
dtool/src/dtoolbase/deletedChain.T

@@ -1,25 +1,22 @@
-// Filename: deletedChain.T
-// Created by:  drose (01Apr06)
-//
-////////////////////////////////////////////////////////////////////
-//
-// PANDA 3D SOFTWARE
-// Copyright (c) Carnegie Mellon University.  All rights reserved.
-//
-// All use of this software is subject to the terms of the revised BSD
-// license.  You should have received a copy of this license along
-// with this source code in a file named "LICENSE."
-//
-////////////////////////////////////////////////////////////////////
+/**
+ * PANDA 3D SOFTWARE
+ * Copyright (c) Carnegie Mellon University.  All rights reserved.
+ *
+ * All use of this software is subject to the terms of the revised BSD
+ * license.  You should have received a copy of this license along
+ * with this source code in a file named "LICENSE."
+ *
+ * @file deletedChain.T
+ * @author drose
+ * @date 2006-04-01
+ */
 
 template<class Type>
 DeletedChain<Type> StaticDeletedChain<Type>::_chain;
 
-////////////////////////////////////////////////////////////////////
-//     Function: DeletedChain::allocate
-//       Access: Public
-//  Description: Allocates the memory for a new object of Type.
-////////////////////////////////////////////////////////////////////
+/**
+ * Allocates the memory for a new object of Type.
+ */
 template<class Type>
 INLINE Type *DeletedChain<Type>::
 allocate(size_t size, TypeHandle type_handle) {
@@ -31,14 +28,12 @@ allocate(size_t size, TypeHandle type_handle) {
   memory_hook->mark_pointer(ptr, _chain->get_buffer_size(), make_ref_ptr(ptr));
 #endif  // DO_MEMORY_USAGE
 
-  return (Type *)ptr;
+  return (Type *)ASSUME_ALIGNED(ptr, MEMORY_HOOK_ALIGNMENT);
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: DeletedChain::deallocate
-//       Access: Public
-//  Description: Frees the memory for an object of Type.
-////////////////////////////////////////////////////////////////////
+/**
+ * Frees the memory for an object of Type.
+ */
 template<class Type>
 INLINE void DeletedChain<Type>::
 deallocate(Type *ptr, TypeHandle type_handle) {
@@ -57,16 +52,13 @@ deallocate(Type *ptr, TypeHandle type_handle) {
   _chain->deallocate(ptr, type_handle);
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: DeletedChain::validate
-//       Access: Public
-//  Description: Returns true if the pointer is valid, false if it has
-//               been deleted or if it was never a valid pointer.
-//
-//               This is only meaningful in debug mode, where
-//               USE_DELETEDCHAINFLAG is defined.  If not, this
-//               trivially returns true.
-////////////////////////////////////////////////////////////////////
+/**
+ * Returns true if the pointer is valid, false if it has been deleted or if it
+ * was never a valid pointer.
+ *
+ * This is only meaningful in debug mode, where USE_DELETEDCHAINFLAG is
+ * defined.  If not, this trivially returns true.
+ */
 template<class Type>
 INLINE bool DeletedChain<Type>::
 validate(const Type *ptr) {
@@ -80,48 +72,37 @@ validate(const Type *ptr) {
 #endif  // USE_DELETEDCHAINFLAG
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: DeletedChain::make_ref_ptr
-//       Access: Public, Static
-//  Description: This method has two overloads: one that accepts a
-//               void *, and one that accepts a ReferenceCount *.  We
-//               rely on the C++ compiler to select the most
-//               appropriate one for a given type to return the
-//               ReferenceCount pointer that corresponds to a
-//               particular type, or NULL if the type does not inherit
-//               from ReferenceCount.
-////////////////////////////////////////////////////////////////////
+/**
+ * This method has two overloads: one that accepts a void *, and one that
+ * accepts a ReferenceCount *.  We rely on the C++ compiler to select the most
+ * appropriate one for a given type to return the ReferenceCount pointer that
+ * corresponds to a particular type, or NULL if the type does not inherit from
+ * ReferenceCount.
+ */
 template<class Type>
 INLINE ReferenceCount *DeletedChain<Type>::
 make_ref_ptr(void *) {
   return NULL;
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: DeletedChain::make_ref_ptr
-//       Access: Public, Static
-//  Description: This method has two overloads: one that accepts a
-//               void *, and one that accepts a ReferenceCount *.  We
-//               rely on the C++ compiler to select the most
-//               appropriate one for a given type to return the
-//               ReferenceCount pointer that corresponds to a
-//               particular type, or NULL if the type does not inherit
-//               from ReferenceCount.
-////////////////////////////////////////////////////////////////////
+/**
+ * This method has two overloads: one that accepts a void *, and one that
+ * accepts a ReferenceCount *.  We rely on the C++ compiler to select the most
+ * appropriate one for a given type to return the ReferenceCount pointer that
+ * corresponds to a particular type, or NULL if the type does not inherit from
+ * ReferenceCount.
+ */
 template<class Type>
 INLINE ReferenceCount *DeletedChain<Type>::
 make_ref_ptr(ReferenceCount *ptr) {
   return ptr;
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: DeletedChain::init_deleted_chain
-//       Access: Private
-//  Description: Assigns the _chain pointer if it is not already
-//               assigned.  This can't be done by a constructor, since
-//               often the DeletedChain instance is used before its
-//               static construct has had a chance to be called.
-////////////////////////////////////////////////////////////////////
+/**
+ * Assigns the _chain pointer if it is not already assigned.  This can't be
+ * done by a constructor, since often the DeletedChain instance is used before
+ * its static construct has had a chance to be called.
+ */
 template<class Type>
 void DeletedChain<Type>::
 init_deleted_chain() {
@@ -131,38 +112,32 @@ init_deleted_chain() {
   }
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: StaticDeletedChain::allocate
-//       Access: Public, Static
-//  Description: Allocates the memory for a new object of Type.
-////////////////////////////////////////////////////////////////////
+/**
+ * Allocates the memory for a new object of Type.
+ */
 template<class Type>
 INLINE Type *StaticDeletedChain<Type>::
 allocate(size_t size, TypeHandle type_handle) {
-  return _chain.allocate(size, type_handle);
+  Type *ptr = _chain.allocate(size, type_handle);
+  return (Type *)ASSUME_ALIGNED(ptr, MEMORY_HOOK_ALIGNMENT);
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: StaticDeletedChain::deallocate
-//       Access: Public
-//  Description: Frees the memory for an object of Type.
-////////////////////////////////////////////////////////////////////
+/**
+ * Frees the memory for an object of Type.
+ */
 template<class Type>
 INLINE void StaticDeletedChain<Type>::
 deallocate(Type *ptr, TypeHandle type_handle) {
   _chain.deallocate(ptr, type_handle);
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: StaticDeletedChain::validate
-//       Access: Public
-//  Description: Returns true if the pointer is valid, false if it has
-//               been deleted or if it was never a valid pointer.
-//
-//               This is only meaningful in debug mode, where
-//               USE_DELETEDCHAINFLAG is defined.  If not, this
-//               trivially returns true.
-////////////////////////////////////////////////////////////////////
+/**
+ * Returns true if the pointer is valid, false if it has been deleted or if it
+ * was never a valid pointer.
+ *
+ * This is only meaningful in debug mode, where USE_DELETEDCHAINFLAG is
+ * defined.  If not, this trivially returns true.
+ */
 template<class Type>
 INLINE bool StaticDeletedChain<Type>::
 validate(const Type *ptr) {

+ 2 - 2
dtool/src/dtoolbase/deletedChain.h

@@ -77,7 +77,7 @@ public:
 // Place this macro within a class definition to define appropriate operator
 // new and delete methods that take advantage of DeletedChain.
 #define ALLOC_DELETED_CHAIN(Type)                            \
-  inline void *operator new(size_t size) {                   \
+  inline void *operator new(size_t size) RETURNS_ALIGNED(MEMORY_HOOK_ALIGNMENT) { \
     return (void *)StaticDeletedChain< Type >::allocate(size, get_type_handle(Type)); \
   }                                                          \
   inline void *operator new(size_t size, void *ptr) {        \
@@ -96,7 +96,7 @@ public:
 // Use this variant of the above macro in cases in which the compiler fails to
 // unify the static template pointers properly, to prevent leaks.
 #define ALLOC_DELETED_CHAIN_DECL(Type)                       \
-  inline void *operator new(size_t size) {                   \
+  inline void *operator new(size_t size) RETURNS_ALIGNED(MEMORY_HOOK_ALIGNMENT) { \
     return (void *)_deleted_chain.allocate(size, get_type_handle(Type)); \
   }                                                          \
   inline void *operator new(size_t size, void *ptr) {        \

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

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

+ 45 - 12
dtool/src/dtoolbase/dtoolbase.h

@@ -58,24 +58,16 @@
 #pragma warning (disable : 4267)
 /* C4577: 'noexcept' used with no exception handling mode specified */
 #pragma warning (disable : 4577)
-
-#if _MSC_VER >= 1300
- #if _MSC_VER >= 1310
-   #define USING_MSVC7_1
-// #pragma message("VC 7.1")
- #else
-// #pragma message("VC 7.0")
- #endif
-#define USING_MSVC7
-#else
-// #pragma message("VC 6.0")
-#endif
 #endif  /* WIN32_VC */
 
 #ifndef __has_builtin
 #define __has_builtin(x) 0
 #endif
 
+#ifndef __has_attribute
+#define __has_attribute(x) 0
+#endif
+
 // Use NODEFAULT to optimize a switch() stmt to tell MSVC to automatically go
 // to the final untested case after it has failed all the other cases (i.e.
 // 'assume at least one of the cases is always true')
@@ -89,6 +81,18 @@
 #define NODEFAULT
 #endif
 
+// Use this to hint the compiler that a memory address is aligned.
+#if __has_builtin(__builtin_assume_aligned) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
+#define ASSUME_ALIGNED(x, y) (__builtin_assume_aligned(x, y))
+#else
+#define ASSUME_ALIGNED(x, y) (x)
+#endif
+
+#if __has_attribute(assume_aligned) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)
+#define RETURNS_ALIGNED(x) __attribute__((assume_aligned(x)))
+#else
+#define RETURNS_ALIGNED(x)
+#endif
 
 /*
   include win32 defns for everything up to WinServer2003, and assume
@@ -394,6 +398,35 @@ typedef struct _object PyObject;
 
 #endif
 
+#ifdef LINMATH_ALIGN
+/* We require 16-byte alignment of certain structures, to support SSE2.  We
+   don't strictly have to align everything, but it's just easier to do so. */
+#if defined(HAVE_EIGEN) && defined(__AVX__) && defined(STDFLOAT_DOUBLE)
+/* Eigen uses AVX instructions, but let's only enable this when compiling with
+   double precision, so that we can keep our ABI a bit more stable. */
+#define MEMORY_HOOK_ALIGNMENT 32
+#else
+#define MEMORY_HOOK_ALIGNMENT 16
+#endif
+/* Otherwise, align to two words.  This seems to be pretty standard to the
+   point where some code may rely on this being the case. */
+#elif defined(IS_OSX) || NATIVE_WORDSIZE >= 64
+#define MEMORY_HOOK_ALIGNMENT 16
+#else
+#define MEMORY_HOOK_ALIGNMENT 8
+#endif
+
+#ifdef HAVE_EIGEN
+/* Make sure that Eigen doesn't assume alignment guarantees we don't offer. */
+#define EIGEN_MAX_ALIGN_BYTES MEMORY_HOOK_ALIGNMENT
+#ifndef EIGEN_MPL2_ONLY
+#define EIGEN_MPL2_ONLY 1
+#endif
+#if !defined(_DEBUG) && !defined(EIGEN_NO_DEBUG)
+#define EIGEN_NO_DEBUG 1
+#endif
+#endif
+
 /* Determine our memory-allocation requirements. */
 #if defined(USE_MEMORY_PTMALLOC2) || defined(USE_MEMORY_DLMALLOC) || defined(DO_MEMORY_USAGE) || defined(MEMORY_HOOK_DO_ALIGN)
 /* In this case we have some custom memory management requirements. */

+ 3 - 3
dtool/src/dtoolbase/dtoolbase_cc.h

@@ -290,10 +290,10 @@ EXPCL_DTOOL void init_memory_hook();
 
 // Now redefine some handy macros to hook into the above MemoryHook object.
 #ifndef USE_MEMORY_NOWRAPPERS
-#define PANDA_MALLOC_SINGLE(size) (memory_hook->heap_alloc_single(size))
+#define PANDA_MALLOC_SINGLE(size) (ASSUME_ALIGNED(memory_hook->heap_alloc_single(size), MEMORY_HOOK_ALIGNMENT))
 #define PANDA_FREE_SINGLE(ptr) memory_hook->heap_free_single(ptr)
-#define PANDA_MALLOC_ARRAY(size) (memory_hook->heap_alloc_array(size))
-#define PANDA_REALLOC_ARRAY(ptr, size) (memory_hook->heap_realloc_array(ptr, size))
+#define PANDA_MALLOC_ARRAY(size) (ASSUME_ALIGNED(memory_hook->heap_alloc_array(size), MEMORY_HOOK_ALIGNMENT))
+#define PANDA_REALLOC_ARRAY(ptr, size) (ASSUME_ALIGNED(memory_hook->heap_realloc_array(ptr, size), MEMORY_HOOK_ALIGNMENT))
 #define PANDA_FREE_ARRAY(ptr) memory_hook->heap_free_array(ptr)
 #else
 #define PANDA_MALLOC_SINGLE(size) ::malloc(size)

+ 2 - 2
dtool/src/dtoolbase/memoryBase.h

@@ -26,7 +26,7 @@
 #ifndef USE_MEMORY_NOWRAPPERS
 
 #define ALLOC_MEMORY_BASE                                    \
-  inline void *operator new(size_t size) {                   \
+  inline void *operator new(size_t size) RETURNS_ALIGNED(MEMORY_HOOK_ALIGNMENT) { \
     return PANDA_MALLOC_SINGLE(size);                        \
   }                                                          \
   inline void *operator new(size_t size, void *ptr) {        \
@@ -38,7 +38,7 @@
   }                                                          \
   inline void operator delete(void *, void *) {              \
   }                                                          \
-  inline void *operator new[](size_t size) {                 \
+  inline void *operator new[](size_t size) RETURNS_ALIGNED(MEMORY_HOOK_ALIGNMENT) { \
     return PANDA_MALLOC_ARRAY(size);                         \
   }                                                          \
   inline void *operator new[](size_t size, void *ptr) {      \

+ 21 - 107
dtool/src/dtoolbase/memoryHook.I

@@ -38,57 +38,9 @@ dec_heap(size_t size) {
  * Returns the global memory alignment.  This is the number of bytes at which
  * each allocated memory pointer will be aligned.
  */
-INLINE size_t MemoryHook::
+CONSTEXPR size_t MemoryHook::
 get_memory_alignment() {
-#ifdef LINMATH_ALIGN
-  // We require 16-byte alignment of certain structures, to support SSE2.  We
-  // don't strictly have to align *everything*, but it's just easier to do so.
-#ifdef __AVX__
-  // Eigen requires 32-byte alignment when using AVX instructions.
-  const size_t alignment_size = 32;
-#else
-  const size_t alignment_size = 16;
-#endif
-#else
-  // Otherwise, align to two words.  This seems to be pretty standard to the
-  // point where some code may rely on this being the case.
-  const size_t alignment_size = sizeof(void *) * 2;
-#endif
-  return alignment_size;
-}
-
-/**
- * Returns the number of additional bytes that are reserved at the beginning
- * of every allocated block to store a size_t.
- */
-INLINE size_t MemoryHook::
-get_header_reserved_bytes() {
-  // We need to figure out the minimum amount of additional space we need in
-  // order to place a single word at the start of each allocated block, to
-  // store the size of the block.
-
-#ifdef LINMATH_ALIGN
-  // If we're doing SSE2 alignment, we must reserve a full 16-byte block,
-  // since anything less than that will spoil the alignment.
-#ifdef __AVX__
-  // Eigen requires 32-byte alignment when using AVX instructions.
-  static const size_t header_reserved_bytes = 32;
-#else
-  static const size_t header_reserved_bytes = 16;
-#endif
-
-#elif defined(MEMORY_HOOK_DO_ALIGN)
-  // If we're just aligning to words, we reserve a block as big as two words,
-  // to allow us wiggle room to align the word precisely within that block.
-  static const size_t header_reserved_bytes = sizeof(size_t) + sizeof(size_t);
-
-#else
-  // Virtually all allocators align to two words, so we make sure we preserve
-  // that alignment for the benefit of anyone who relies upon that.
-  static const size_t header_reserved_bytes = sizeof(void *) * 2;
-#endif
-
-  return header_reserved_bytes;
+  return MEMORY_HOOK_ALIGNMENT;
 }
 
 /**
@@ -110,67 +62,29 @@ round_up_to_page_size(size_t size) const {
 }
 
 /**
- * Increments the amount of requested size as necessary to accommodate the
- * extra data we might piggyback on each allocated block.
+ * Given a pointer that was returned by a MemoryHook allocation, returns the
+ * number of bytes that were allocated for it.  This may be slightly larger
+ * than the number of bytes requested.
+ * The behavior of this function is undefined if the given pointer was not
+ * returned by the MemoryHook allocator or was already freed.
+ * May return 0 if not compiling with DO_MEMORY_USAGE.
+ *
+ * This is only defined publicly so TypeHandle can get at it; it really
+ * shouldn't be used outside of dtoolbase.
  */
 INLINE size_t MemoryHook::
-inflate_size(size_t size) {
-#if defined(MEMORY_HOOK_DO_ALIGN)
-  // If we're aligning, we need to request the header size, plus extra bytes
-  // to give us wiggle room to adjust the pointer.
-  return size + get_header_reserved_bytes() + get_memory_alignment() - 1;
-#elif defined(DO_MEMORY_USAGE)
-  // If we're not aligning, but we're tracking memory allocations, we just
-  // need the header size extra (this gives us a place to store the size of
-  // the allocated block).
-  return size + get_header_reserved_bytes();
-#else
-  // If we're not doing any of that, we can just allocate the precise
-  // requested amount.
-  return size;
-#endif  // DO_MEMORY_USAGE
-}
-
-/**
- * Converts an allocated pointer to a pointer returnable to the application.
- * Stuffs size in the first n bytes of the allocated space.
- */
-INLINE void *MemoryHook::
-alloc_to_ptr(void *alloc, size_t size) {
-#if defined(MEMORY_HOOK_DO_ALIGN)
-  size_t alignment = get_memory_alignment();
-  // Move the allocated pointer up to the next even alignment.
-  size_t *root = (size_t *)((((size_t)alloc + alignment - 1) / alignment) * alignment);
-  assert(alloc <= root && (size_t)((char *)root - (char *)alloc) < alignment);
-  root[0] = size;
-  root[1] = (size_t)alloc;  // Save the pointer we originally allocated.
-  return (void *)((char *)root + get_header_reserved_bytes());
-#elif defined(DO_MEMORY_USAGE)
-  size_t *root = (size_t *)alloc;
-  root[0] = size;
-  return (void *)((char *)root + get_header_reserved_bytes());
-#else
-  return alloc;
-#endif  // DO_MEMORY_USAGE
-}
-
-/**
- * Converts an application pointer back to the original allocated pointer.
- * Extracts size from the first n bytes of the allocated space.
- */
-INLINE void *MemoryHook::
-ptr_to_alloc(void *ptr, size_t &size) {
+get_ptr_size(void *ptr) {
 #if defined(MEMORY_HOOK_DO_ALIGN)
-  size_t *root = (size_t *)((char *)ptr - get_header_reserved_bytes());
-  size = root[0];
-  void *alloc = (void *)root[1]; // Get the pointer we originally allocated.
-  assert(alloc <= root && (size_t)((char *)root - (char *)alloc) < get_memory_alignment());
-  return alloc;
+  uintptr_t *root = (uintptr_t *)ptr;
+  return (size_t)root[-2];
+#elif defined(USE_MEMORY_DLMALLOC) || defined(USE_MEMORY_PTMALLOC2)
+  // If we are using dlmalloc, we know how it stores the size.
+  size_t *root = (size_t *)ptr;
+  return (root[-1] & ~0x7) - sizeof(size_t);
 #elif defined(DO_MEMORY_USAGE)
-  size_t *root = (size_t *)((char *)ptr - get_header_reserved_bytes());
-  size = root[0];
-  return (void *)root;
+  size_t *root = (size_t *)((char *)ptr - MEMORY_HOOK_ALIGNMENT);
+  return *root;
 #else
-  return ptr;
+  return 0;
 #endif  // DO_MEMORY_USAGE
 }

Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů