Преглед изворни кода

Merge branch 'master' of https://github.com/panda3d/panda3d

David Rose пре 9 година
родитељ
комит
05d74624ee
100 измењених фајлова са 2235 додато и 2009 уклоњено
  1. 47 4
      .gitignore
  2. 0 4
      contrib/src/ai/aiBehaviors.h
  3. 0 5
      contrib/src/ai/aiCharacter.h
  4. 0 4
      contrib/src/ai/aiGlobals.h
  5. 0 5
      contrib/src/ai/aiWorld.h
  6. 3 3
      contrib/src/ai/obstacleAvoidance.cxx
  7. 1 1
      direct/src/controls/BattleWalker.py
  8. 1 1
      direct/src/controls/NonPhysicsWalker.py
  9. 1 1
      direct/src/dcparser/dcArrayParameter.h
  10. 1 1
      direct/src/dcparser/dcAtomicField.h
  11. 1 1
      direct/src/dcparser/dcClass.h
  12. 1 1
      direct/src/dcparser/dcClassParameter.h
  13. 1 1
      direct/src/dcparser/dcDeclaration.h
  14. 1 1
      direct/src/dcparser/dcField.h
  15. 1 1
      direct/src/dcparser/dcFile.h
  16. 1 1
      direct/src/dcparser/dcKeyword.h
  17. 1 1
      direct/src/dcparser/dcKeywordList.h
  18. 1 1
      direct/src/dcparser/dcMolecularField.h
  19. 1 1
      direct/src/dcparser/dcPackData.h
  20. 2 2
      direct/src/dcparser/dcPacker.h
  21. 1 1
      direct/src/dcparser/dcPackerCatalog.h
  22. 1 1
      direct/src/dcparser/dcPackerInterface.h
  23. 1 1
      direct/src/dcparser/dcParameter.h
  24. 1 1
      direct/src/dcparser/dcSimpleParameter.h
  25. 1 1
      direct/src/dcparser/dcSwitch.h
  26. 1 1
      direct/src/dcparser/dcSwitchParameter.h
  27. 1 1
      direct/src/dcparser/dcTypedef.h
  28. 1 1
      direct/src/distributed/CartesianGridBase.py
  29. 2 1
      direct/src/distributed/ClientRepositoryBase.py
  30. 2 1
      direct/src/distributed/ConnectionRepository.py
  31. 2 1
      direct/src/distributed/DistributedCamera.py
  32. 2 1
      direct/src/distributed/DistributedCameraOV.py
  33. 2 1
      direct/src/distributed/DistributedCartesianGrid.py
  34. 2 1
      direct/src/distributed/DistributedCartesianGridAI.py
  35. 1 1
      direct/src/distributed/DistributedNodeAI.py
  36. 2 2
      direct/src/distributed/DistributedObjectGlobalUD.py
  37. 2 1
      direct/src/distributed/DistributedObjectUD.py
  38. 2 1
      direct/src/distributed/DistributedSmoothNode.py
  39. 2 1
      direct/src/distributed/DoInterestManager.py
  40. 2 1
      direct/src/distributed/GridParent.py
  41. 2 1
      direct/src/distributed/ServerRepository.py
  42. 1 1
      direct/src/distributed/TimeManager.py
  43. 1 1
      direct/src/distributed/TimeManagerAI.py
  44. 22 2
      direct/src/distributed/cConnectionRepository.cxx
  45. 10 10
      direct/src/fsm/FSM.py
  46. 4 4
      direct/src/p3d/FileSpec.py
  47. 0 2
      direct/src/plugin/p3dCInstance.h
  48. 12 3
      direct/src/showbase/BufferViewer.py
  49. 1 0
      direct/src/showbase/ExceptionVarDump.py
  50. 1 1
      direct/src/showbase/LeakDetectors.py
  51. 50 41
      direct/src/showbase/Loader.py
  52. 1 1
      direct/src/showbase/MirrorDemo.py
  53. 1 1
      direct/src/showbase/ShadowDemo.py
  54. 1 1
      direct/src/showbase/ShadowPlacer.py
  55. 4 1
      direct/src/showutil/FreezeTool.py
  56. 10 10
      direct/src/stdpy/thread.py
  57. 32 0
      doc/ReleaseNotes
  58. 1570 1576
      dtool/src/cppparser/cppBison.cxx.prebuilt
  59. 31 88
      dtool/src/cppparser/cppBison.yxx
  60. 1 0
      dtool/src/cppparser/cppEnumType.h
  61. 4 0
      dtool/src/cppparser/cppInstance.h
  62. 0 2
      dtool/src/cppparser/cppManifest.cxx
  63. 3 4
      dtool/src/cppparser/cppPreprocessor.cxx
  64. 1 0
      dtool/src/cppparser/cppScope.cxx
  65. 1 1
      dtool/src/cppparser/cppToken.cxx
  66. 2 0
      dtool/src/cppparser/cppTypedefType.cxx
  67. 11 9
      dtool/src/dtoolbase/dtoolbase.h
  68. 6 0
      dtool/src/dtoolbase/typeRegistry.cxx
  69. 5 1
      dtool/src/dtoolutil/filename.cxx
  70. 1 1
      dtool/src/dtoolutil/pandaFileStreamBuf.cxx
  71. 49 5
      dtool/src/interrogate/interfaceMakerPythonNative.cxx
  72. 2 1
      dtool/src/interrogate/interfaceMakerPythonNative.h
  73. 0 4
      dtool/src/interrogate/interrogate.cxx
  74. 4 4
      dtool/src/interrogate/interrogateBuilder.cxx
  75. 0 4
      dtool/src/interrogate/interrogate_module.cxx
  76. 3 2
      dtool/src/interrogate/typeManager.cxx
  77. 1 1
      dtool/src/interrogatedb/extension.h
  78. 4 0
      dtool/src/interrogatedb/interrogate_request.cxx
  79. 8 0
      dtool/src/interrogatedb/py_panda.I
  80. 4 2
      dtool/src/interrogatedb/py_panda.cxx
  81. 4 3
      dtool/src/interrogatedb/py_panda.h
  82. 1 1
      dtool/src/parser-inc/Python.h
  83. 21 9
      dtool/src/prc/configVariableFilename.cxx
  84. 1 2
      dtool/src/prc/configVariableString.I
  85. 21 0
      dtool/src/prc/configVariableString.cxx
  86. 3 0
      dtool/src/prc/configVariableString.h
  87. 7 2
      dtool/src/prc/notifyCategory.cxx
  88. 0 1
      dtool/src/test_interrogate/test_interrogate.cxx
  89. 134 127
      makepanda/makepanda.py
  90. 0 4
      panda/src/android/pview.cxx
  91. 2 2
      panda/src/audio/audioManager.cxx
  92. 17 0
      panda/src/chan/animChannelFixed.cxx
  93. 2 0
      panda/src/chan/animChannelFixed.h
  94. 1 0
      panda/src/chan/p3chan_composite1.cxx
  95. 1 1
      panda/src/char/character.cxx
  96. 20 0
      panda/src/cocoadisplay/cocoaGraphicsStateGuardian.mm
  97. 9 0
      panda/src/display/config_display.cxx
  98. 1 0
      panda/src/display/config_display.h
  99. 0 3
      panda/src/display/displayRegion.cxx
  100. 30 8
      panda/src/display/graphicsEngine.cxx

+ 47 - 4
.gitignore

@@ -1,4 +1,47 @@
-/built_x64
-/built
-/thirdparty
-/targetroot
+# makepanda directories
+/built*/
+/thirdparty/
+/targetroot/
+/dstroot/
+
+# Core dumps
+core
+core.*
+vgcore.*
+
+# Editor files/directories
+*.save
+*.save.1
+*.sublime-workspace
+.vscode/
+
+# Temporary build files
+/_vfsimporter.*
+*.pdb
+*.obj
+*.o
+*.gch
+*.pch
+
+# Produced installer/executables
+/*.exe
+/*.deb
+/*.rpm
+/*.app
+/*.pkg
+/*.dmg
+/*.whl
+
+# CMake
+/build/
+CMakeCache.txt
+CMakeFiles/
+CMakeScripts/
+Makefile
+cmake_install.cmake
+install_manifest.txt
+CTestTestfile.cmake
+
+# Windows
+Thumbs.db
+ehthumbs.db

+ 0 - 4
contrib/src/ai/aiBehaviors.h

@@ -11,10 +11,6 @@
  * @date 2009-09-08
  */
 
-#pragma warning (disable:4996)
-#pragma warning (disable:4005)
-#pragma warning(disable:4275)
-
 #ifndef _AIBEHAVIORS_H
 #define _AIBEHAVIORS_H
 

+ 0 - 5
contrib/src/ai/aiCharacter.h

@@ -11,11 +11,6 @@
  * @date 2009-09-08
  */
 
-#pragma warning (disable:4996)
-#pragma warning (disable:4005)
-#pragma warning(disable:4275)
-
-
 #ifndef _AICHARACTER_H
 #define _AICHARACTER_H
 

+ 0 - 4
contrib/src/ai/aiGlobals.h

@@ -11,10 +11,6 @@
  * @date 2009-09-08
  */
 
-#pragma warning (disable:4996)
-#pragma warning (disable:4005)
-#pragma warning(disable:4275)
-
 #ifndef _AI_GLOBALS_H
 #define _AI_GLOBALS_H
 

+ 0 - 5
contrib/src/ai/aiWorld.h

@@ -11,11 +11,6 @@
  * @date 2009-09-08
  */
 
-#pragma warning (disable:4996)
-#pragma warning (disable:4005)
-#pragma warning(disable:4275)
-
-
 #ifndef _AIWORLD_H
 #define _AIWORLD_H
 

+ 3 - 3
contrib/src/ai/obstacleAvoidance.cxx

@@ -34,7 +34,7 @@ obstacle_detection() {
   CPT(BoundingSphere) np_sphere = np_bounds->as_bounding_sphere();
   LVecBase3 avoidance(0.0, 0.0, 0.0);
   double distance = 0x7fff ;
-  double expanded_radius;
+  double expanded_radius = 0;
   LVecBase3 to_obstacle;
   LVecBase3 prev_avoidance;
   for(unsigned int i = 0; i < _ai_char->_world->_obstacles.size(); ++i) {
@@ -89,8 +89,8 @@ do_obstacle_avoidance() {
   CPT(BoundingSphere) bsphere = bounds->as_bounding_sphere();
   PT(BoundingVolume) np_bounds = _ai_char->get_node_path().get_bounds();
   CPT(BoundingSphere) np_sphere = np_bounds->as_bounding_sphere();
-  double distance_needed = offset.length() - bsphere->get_radius() - np_sphere->get_radius();
-  if((obstacle_detection())) {
+
+  if (obstacle_detection()) {
     LVecBase3 direction = _ai_char->get_char_render().get_relative_vector(_ai_char->get_node_path(), LVector3::forward());
     direction.normalize();
     float forward_component = offset.dot(direction);

+ 1 - 1
direct/src/controls/BattleWalker.py

@@ -1,7 +1,7 @@
 
 from direct.showbase.InputStateGlobal import inputState
 from direct.task.Task import Task
-from pandac.PandaModules import *
+from panda3d.core import *
 from . import GravityWalker
 
 BattleStrafe = 0

+ 1 - 1
direct/src/controls/NonPhysicsWalker.py

@@ -19,7 +19,7 @@ from direct.showbase import DirectObject
 from direct.controls.ControlManager import CollisionHandlerRayStart
 from direct.showbase.InputStateGlobal import inputState
 from direct.task.Task import Task
-from pandac.PandaModules import *
+from panda3d.core import *
 
 class NonPhysicsWalker(DirectObject.DirectObject):
     notify = DirectNotifyGlobal.directNotify.newCategory("NonPhysicsWalker")

+ 1 - 1
direct/src/dcparser/dcArrayParameter.h

@@ -23,7 +23,7 @@
  * parameter type accepts an arbitrary (or possibly fixed) number of nested
  * fields, all of which are of the same type.
  */
-class EXPCL_DIRECT DCArrayParameter : public DCParameter {
+class DCArrayParameter : public DCParameter {
 public:
   DCArrayParameter(DCParameter *element_type,
                    const DCUnsignedIntRange &size = DCUnsignedIntRange());

+ 1 - 1
direct/src/dcparser/dcAtomicField.h

@@ -27,7 +27,7 @@
  * This defines an interface to the Distributed Class, and is always
  * implemented as a remote procedure method.
  */
-class EXPCL_DIRECT DCAtomicField : public DCField {
+class DCAtomicField : public DCField {
 public:
   DCAtomicField(const string &name, DCClass *dclass, bool bogus_field);
   virtual ~DCAtomicField();

+ 1 - 1
direct/src/dcparser/dcClass.h

@@ -41,7 +41,7 @@ class DCParameter;
 /**
  * Defines a particular DistributedClass as read from an input .dc file.
  */
-class EXPCL_DIRECT DCClass : public DCDeclaration {
+class DCClass : public DCDeclaration {
 public:
   DCClass(DCFile *dc_file, const string &name,
           bool is_struct, bool bogus_class);

+ 1 - 1
direct/src/dcparser/dcClassParameter.h

@@ -23,7 +23,7 @@ class DCClass;
  * This represents a class (or struct) object used as a parameter itself.
  * This means that all the fields of the class get packed into the message.
  */
-class EXPCL_DIRECT DCClassParameter : public DCParameter {
+class DCClassParameter : public DCParameter {
 public:
   DCClassParameter(const DCClass *dclass);
   DCClassParameter(const DCClassParameter &copy);

+ 1 - 1
direct/src/dcparser/dcDeclaration.h

@@ -26,7 +26,7 @@ class DCSwitch;
  * only purpose is so that classes and typedefs can be stored in one list
  * together so they can be ordered correctly on output.
  */
-class EXPCL_DIRECT DCDeclaration {
+class DCDeclaration {
 public:
   virtual ~DCDeclaration();
 

+ 1 - 1
direct/src/dcparser/dcField.h

@@ -34,7 +34,7 @@ class HashGenerator;
 /**
  * A single field of a Distributed Class, either atomic or molecular.
  */
-class EXPCL_DIRECT DCField : public DCPackerInterface, public DCKeywordList {
+class DCField : public DCPackerInterface, public DCKeywordList {
 public:
   DCField();
   DCField(const string &name, DCClass *dclass);

+ 1 - 1
direct/src/dcparser/dcFile.h

@@ -29,7 +29,7 @@ class DCDeclaration;
  * Represents the complete list of Distributed Class descriptions as read from
  * a .dc file.
  */
-class EXPCL_DIRECT DCFile {
+class DCFile {
 PUBLISHED:
   DCFile();
   ~DCFile();

+ 1 - 1
direct/src/dcparser/dcKeyword.h

@@ -25,7 +25,7 @@ class HashGenerator;
  * define a communication property associated with a field, for instance
  * "broadcast" or "airecv".
  */
-class EXPCL_DIRECT DCKeyword : public DCDeclaration {
+class DCKeyword : public DCDeclaration {
 public:
   DCKeyword(const string &name, int historical_flag = ~0);
   virtual ~DCKeyword();

+ 1 - 1
direct/src/dcparser/dcKeywordList.h

@@ -23,7 +23,7 @@ class HashGenerator;
  * This is a list of keywords (see DCKeyword) that may be set on a particular
  * field.
  */
-class EXPCL_DIRECT DCKeywordList {
+class DCKeywordList {
 public:
   DCKeywordList();
   DCKeywordList(const DCKeywordList &copy);

+ 1 - 1
direct/src/dcparser/dcMolecularField.h

@@ -25,7 +25,7 @@ class DCParameter;
  * This represents a combination of two or more related atomic fields, that
  * will often be treated as a unit.
  */
-class EXPCL_DIRECT DCMolecularField : public DCField {
+class DCMolecularField : public DCField {
 public:
   DCMolecularField(const string &name, DCClass *dclass);
 

+ 1 - 1
direct/src/dcparser/dcPackData.h

@@ -19,7 +19,7 @@
 /**
  * This is a block of data that receives the results of DCPacker.
  */
-class EXPCL_DIRECT DCPackData {
+class DCPackData {
 PUBLISHED:
   INLINE DCPackData();
   INLINE ~DCPackData();

+ 2 - 2
direct/src/dcparser/dcPacker.h

@@ -31,7 +31,7 @@ class DCSwitchParameter;
  * See also direct/src/doc/dcPacker.txt for a more complete description and
  * examples of using this class.
  */
-class EXPCL_DIRECT DCPacker {
+class DCPacker {
 PUBLISHED:
   DCPacker();
   ~DCPacker();
@@ -216,7 +216,7 @@ private:
   const DCPackerCatalog *_catalog;
   const DCPackerCatalog::LiveCatalog *_live_catalog;
 
-  class EXPCL_DIRECT StackElement {
+  class StackElement {
   public:
     // As an optimization, we implement operator new and delete here to
     // minimize allocation overhead during push() and pop().

+ 1 - 1
direct/src/dcparser/dcPackerCatalog.h

@@ -26,7 +26,7 @@ class DCSwitchParameter;
  * requested from a particular field; its ownership is retained by the field
  * so it must not be deleted.
  */
-class EXPCL_DIRECT DCPackerCatalog {
+class DCPackerCatalog {
 private:
   DCPackerCatalog(const DCPackerInterface *root);
   DCPackerCatalog(const DCPackerCatalog &copy);

+ 1 - 1
direct/src/dcparser/dcPackerInterface.h

@@ -64,7 +64,7 @@ END_PUBLISH
  * Normally these methods are called only by the DCPacker object; the user
  * wouldn't normally call these directly.
  */
-class EXPCL_DIRECT DCPackerInterface {
+class DCPackerInterface {
 public:
   DCPackerInterface(const string &name = string());
   DCPackerInterface(const DCPackerInterface &copy);

+ 1 - 1
direct/src/dcparser/dcParameter.h

@@ -32,7 +32,7 @@ class HashGenerator;
  * This may also be a typedef reference to another type, which has the same
  * properties as the referenced type, but a different name.
  */
-class EXPCL_DIRECT DCParameter : public DCField {
+class DCParameter : public DCField {
 protected:
   DCParameter();
   DCParameter(const DCParameter &copy);

+ 1 - 1
direct/src/dcparser/dcSimpleParameter.h

@@ -25,7 +25,7 @@
  * divisor, which is meaningful only for the numeric type elements (and
  * represents a fixed-point numeric convention).
  */
-class EXPCL_DIRECT DCSimpleParameter : public DCParameter {
+class DCSimpleParameter : public DCParameter {
 public:
   DCSimpleParameter(DCSubatomicType type, unsigned int divisor = 1);
   DCSimpleParameter(const DCSimpleParameter &copy);

+ 1 - 1
direct/src/dcparser/dcSwitch.h

@@ -27,7 +27,7 @@ class DCField;
  * and represents two or more alternative unpacking schemes based on the first
  * field read.
  */
-class EXPCL_DIRECT DCSwitch : public DCDeclaration {
+class DCSwitch : public DCDeclaration {
 public:
   DCSwitch(const string &name, DCField *key_parameter);
   virtual ~DCSwitch();

+ 1 - 1
direct/src/dcparser/dcSwitchParameter.h

@@ -23,7 +23,7 @@ class DCSwitch;
  * This represents a switch object used as a parameter itself, which packs the
  * appropriate fields of the switch into the message.
  */
-class EXPCL_DIRECT DCSwitchParameter : public DCParameter {
+class DCSwitchParameter : public DCParameter {
 public:
   DCSwitchParameter(const DCSwitch *dswitch);
   DCSwitchParameter(const DCSwitchParameter &copy);

+ 1 - 1
direct/src/dcparser/dcTypedef.h

@@ -23,7 +23,7 @@ class DCParameter;
  * This represents a single typedef declaration in the dc file.  It assigns a
  * particular type to a new name, just like a C typedef.
  */
-class EXPCL_DIRECT DCTypedef : public DCDeclaration {
+class DCTypedef : public DCDeclaration {
 public:
   DCTypedef(DCParameter *parameter, bool implicit = false);
   DCTypedef(const string &name);

+ 1 - 1
direct/src/distributed/CartesianGridBase.py

@@ -1,4 +1,4 @@
-from pandac.PandaModules import Vec3
+from panda3d.core import Vec3
 # Utility functions that are useful to both AI and client CartesianGrid code
 
 class CartesianGridBase:

+ 2 - 1
direct/src/distributed/ClientRepositoryBase.py

@@ -1,4 +1,5 @@
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from .MsgTypes import *
 from direct.task import Task
 from direct.directnotify import DirectNotifyGlobal

+ 2 - 1
direct/src/distributed/ConnectionRepository.py

@@ -1,4 +1,5 @@
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from direct.task import Task
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.distributed.DoInterestManager import DoInterestManager

+ 2 - 1
direct/src/distributed/DistributedCamera.py

@@ -1,4 +1,5 @@
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from direct.fsm.FSM import FSM
 from direct.interval.IntervalGlobal import *
 from direct.distributed.DistributedObject import DistributedObject

+ 2 - 1
direct/src/distributed/DistributedCameraOV.py

@@ -1,4 +1,5 @@
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from direct.distributed.DistributedObjectOV import DistributedObjectOV
 
 class DistributedCameraOV(DistributedObjectOV):

+ 2 - 1
direct/src/distributed/DistributedCartesianGrid.py

@@ -1,5 +1,6 @@
 
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from direct.interval.IntervalGlobal import *
 from direct.directnotify.DirectNotifyGlobal import directNotify
 

+ 2 - 1
direct/src/distributed/DistributedCartesianGridAI.py

@@ -1,5 +1,6 @@
 
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.task import Task
 from .DistributedNodeAI import DistributedNodeAI

+ 1 - 1
direct/src/distributed/DistributedNodeAI.py

@@ -1,4 +1,4 @@
-from pandac.PandaModules import NodePath
+from panda3d.core import NodePath
 from . import DistributedObjectAI
 from . import GridParent
 

+ 2 - 2
direct/src/distributed/DistributedObjectGlobalUD.py

@@ -35,9 +35,9 @@ class DistributedObjectGlobalUD(DistributedObjectUD):
     def __execMessage(self, message):
         if not self.ExecNamespace:
             # Import some useful variables into the ExecNamespace initially.
-            import pandac.PandaModules
+            import panda3d.core
 
-            for key, value in pandac.PandaModules.__dict__.items():
+            for key, value in panda3d.core.__dict__.items():
                 if not key.startswith('__'):
                     self.ExecNamespace[key] = value
             #self.importExecNamespace()

+ 2 - 1
direct/src/distributed/DistributedObjectUD.py

@@ -3,7 +3,8 @@
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.distributed.DistributedObjectBase import DistributedObjectBase
 from direct.showbase import PythonUtil
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 #from PyDatagram import PyDatagram
 #from PyDatagramIterator import PyDatagramIterator
 

+ 2 - 1
direct/src/distributed/DistributedSmoothNode.py

@@ -1,6 +1,7 @@
 """DistributedSmoothNode module: contains the DistributedSmoothNode class"""
 
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from .ClockDelta import *
 from . import DistributedNode
 from . import DistributedSmoothNodeBase

+ 2 - 1
direct/src/distributed/DoInterestManager.py

@@ -7,7 +7,8 @@ zone, remove interest in that zone.
 p.s. A great deal of this code is just code moved from ClientRepository.py.
 """
 
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from .MsgTypes import *
 from direct.showbase.PythonUtil import *
 from direct.showbase import DirectObject

+ 2 - 1
direct/src/distributed/GridParent.py

@@ -1,5 +1,6 @@
 
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 
 #
 # GridParent.py

+ 2 - 1
direct/src/distributed/ServerRepository.py

@@ -1,6 +1,7 @@
 """ServerRepository module: contains the ServerRepository class"""
 
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from direct.distributed.MsgTypesCMU import *
 from direct.task import Task
 from direct.directnotify import DirectNotifyGlobal

+ 1 - 1
direct/src/distributed/TimeManager.py

@@ -1,5 +1,5 @@
 from direct.showbase.DirectObject import *
-from pandac.PandaModules import *
+from panda3d.core import *
 from direct.task import Task
 from direct.distributed import DistributedObject
 from direct.directnotify import DirectNotifyGlobal

+ 1 - 1
direct/src/distributed/TimeManagerAI.py

@@ -1,5 +1,5 @@
 from direct.distributed.ClockDelta import *
-from pandac.PandaModules import *
+from panda3d.core import *
 from direct.distributed import DistributedObjectAI
 
 class TimeManagerAI(DistributedObjectAI.DistributedObjectAI):

+ 22 - 2
direct/src/distributed/cConnectionRepository.cxx

@@ -402,8 +402,28 @@ send_datagram(const Datagram &dg) {
   }
 
 #ifdef WANT_NATIVE_NET
-  if(_native)
-    return _bdc.SendMessage(dg);
+  if (_native) {
+    bool result = _bdc.SendMessage();
+    if (!result && _bdc.IsConnected()) {
+#ifdef HAVE_PYTHON
+      ostringstream s;
+
+#if PY_VERSION_HEX >= 0x03030000
+      PyObject *exc_type = PyExc_ConnectionError;
+#else
+      PyObject *exc_type = PyExc_OSError;
+#endif
+
+      s << endl << "Error sending message: " << endl;
+      msg.dump_hex(s);
+      s << "Message data: " << msg.get_data() << endl;
+
+      string message = s.str();
+      PyErr_SetString(exc_type, message.c_str());
+#endif
+    }
+    return result;
+  }
 #endif
 
 #ifdef HAVE_NET

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

@@ -149,7 +149,7 @@ class FSM(DirectObject):
 
     def __init__(self, name):
         self.fsmLock = RLock()
-        self.name = name
+        self._name = name
         self.stateArray = []
         self._serialNum = FSM.SerialNum
         FSM.SerialNum += 1
@@ -185,7 +185,7 @@ class FSM(DirectObject):
         # the messenger on every state change. The new and old states are
         # accessible as self.oldState and self.newState, and the transition
         # functions will already have been called.
-        return 'FSM-%s-%s-stateChange' % (self._serialNum, self.name)
+        return 'FSM-%s-%s-stateChange' % (self._serialNum, self._name)
 
     def getCurrentFilter(self):
         if not self.state:
@@ -240,7 +240,7 @@ class FSM(DirectObject):
         try:
             assert isinstance(request, str)
             self.notify.debug("%s.forceTransition(%s, %s" % (
-                self.name, request, str(args)[1:]))
+                self._name, request, str(args)[1:]))
 
             if not self.state:
                 # Queue up the request.
@@ -268,7 +268,7 @@ class FSM(DirectObject):
         try:
             assert isinstance(request, str)
             self.notify.debug("%s.demand(%s, %s" % (
-                self.name, request, str(args)[1:]))
+                self._name, request, str(args)[1:]))
             if not self.state:
                 # Queue up the request.
                 self.__requestQueue.append(PythonUtil.Functor(
@@ -307,7 +307,7 @@ class FSM(DirectObject):
         try:
             assert isinstance(request, str)
             self.notify.debug("%s.request(%s, %s" % (
-                self.name, request, str(args)[1:]))
+                self._name, request, str(args)[1:]))
 
             filter = self.getCurrentFilter()
             result = filter(request, args)
@@ -385,7 +385,7 @@ class FSM(DirectObject):
 
         # In either case, we quietly ignore unhandled command
         # (lowercase) requests.
-        assert self.notify.debug("%s ignoring request %s from state %s." % (self.name, request, self.state))
+        assert self.notify.debug("%s ignoring request %s from state %s." % (self._name, request, self.state))
         return None
 
     def filterOff(self, request, args):
@@ -444,7 +444,7 @@ class FSM(DirectObject):
         # Internal function to change unconditionally to the indicated
         # state.
         assert self.state
-        assert self.notify.debug("%s to state %s." % (self.name, newState))
+        assert self.notify.debug("%s to state %s." % (self._name, newState))
 
         self.oldState = self.state
         self.newState = newState
@@ -476,7 +476,7 @@ class FSM(DirectObject):
 
         if self.__requestQueue:
             request = self.__requestQueue.pop(0)
-            assert self.notify.debug("%s continued queued request." % (self.name))
+            assert self.notify.debug("%s continued queued request." % (self._name))
             request()
 
     def __callEnterFunc(self, name, *args):
@@ -525,9 +525,9 @@ class FSM(DirectObject):
         try:
             className = self.__class__.__name__
             if self.state:
-                str = ('%s FSM:%s in state "%s"' % (className, self.name, self.state))
+                str = ('%s FSM:%s in state "%s"' % (className, self._name, self.state))
             else:
-                str = ('%s FSM:%s in transition from \'%s\' to \'%s\'' % (className, self.name, self.oldState, self.newState))
+                str = ('%s FSM:%s in transition from \'%s\' to \'%s\'' % (className, self._name, self.oldState, self.newState))
             return str
         finally:
             self.fsmLock.release()

+ 4 - 4
direct/src/p3d/FileSpec.py

@@ -33,7 +33,7 @@ class FileSpec:
         if st is None:
             st = os.stat(pathname.toOsSpecific())
         self.size = st.st_size
-        self.timestamp = st.st_mtime
+        self.timestamp = int(st.st_mtime)
 
         self.readHash(pathname)
 
@@ -124,7 +124,7 @@ class FileSpec:
                 self.__correctHash(packageDir, pathname, st, notify)
             return False
 
-        if st.st_mtime == self.timestamp:
+        if int(st.st_mtime) == self.timestamp:
             # If the size is right and the timestamp is right, the
             # file passes.
             if notify:
@@ -198,7 +198,7 @@ class FileSpec:
         # The hash is OK.  If the timestamp is wrong, change it back
         # to what we expect it to be, so we can quick-verify it
         # successfully next time.
-        if st.st_mtime != self.timestamp:
+        if int(st.st_mtime) != self.timestamp:
             self.__updateTimestamp(pathname, st)
 
         return True
@@ -219,7 +219,7 @@ class FileSpec:
         if notify:
             notify.info("Correcting timestamp of %s to %d (%s)" % (
                 self.filename, st.st_mtime, time.asctime(time.localtime(st.st_mtime))))
-        self.timestamp = st.st_mtime
+        self.timestamp = int(st.st_mtime)
 
     def checkHash(self, packageDir, pathname, st):
         """ Returns true if the file has the expected md5 hash, false

+ 0 - 2
direct/src/plugin/p3dCInstance.h

@@ -21,8 +21,6 @@
 #include "get_tinyxml.h"
 #include "windowHandle.h"
 
-#include <Python.h>
-
 class P3DSession;
 
 /**

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

@@ -278,6 +278,15 @@ class BufferViewer(DirectObject):
         self.analyzeTextureSet(self.exclude, exclude)
         self.analyzeTextureSet(self.include, include)
 
+        # Use a custom sampler when applying the textures.  This fixes
+        # wrap issues and prevents depth compare on shadow maps.
+        sampler = SamplerState()
+        sampler.setWrapU(SamplerState.WM_clamp)
+        sampler.setWrapV(SamplerState.WM_clamp)
+        sampler.setWrapW(SamplerState.WM_clamp)
+        sampler.setMinfilter(SamplerState.FT_linear)
+        sampler.setMagfilter(SamplerState.FT_nearest)
+
         # Generate a list of cards and the corresponding windows.
         cards = []
         wins = []
@@ -290,7 +299,7 @@ class BufferViewer(DirectObject):
                         for face in range(6):
                             self.cardmaker.setUvRangeCube(face)
                             card = NodePath(self.cardmaker.generate())
-                            card.setTexture(tex)
+                            card.setTexture(tex, sampler)
                             cards.append(card)
                     elif (tex.getTextureType() == Texture.TT2dTextureArray):
                         for layer in range(tex.getZSize()):
@@ -301,11 +310,11 @@ class BufferViewer(DirectObject):
                             # the fixed-function pipeline, so we need to
                             # enable the shader generator to view them.
                             card.setShaderAuto()
-                            card.setTexture(tex)
+                            card.setTexture(tex, sampler)
                             cards.append(card)
                     else:
                         card = win.getTextureCard()
-                        card.setTexture(tex)
+                        card.setTexture(tex, sampler)
                         cards.append(card)
                     wins.append(win)
                     exclude[tex] = 1

+ 1 - 0
direct/src/showbase/ExceptionVarDump.py

@@ -1,5 +1,6 @@
 __all__ = ["install"]
 
+from panda3d.core import *
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.showbase.PythonUtil import fastRepr
 import sys

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

@@ -1,6 +1,6 @@
 # objects that report different types of leaks to the ContainerLeakDetector
 
-from pandac.PandaModules import *
+from panda3d.core import *
 from direct.showbase.DirectObject import DirectObject
 from direct.showbase.Job import Job
 import gc, sys

+ 50 - 41
direct/src/showbase/Loader.py

@@ -28,7 +28,7 @@ class Loader(DirectObject):
             self.extraArgs = extraArgs
             self.numRemaining = numObjects
             self.cancelled = False
-            self.requests = {}
+            self.requests = set()
 
         def gotObject(self, index, object):
             self.objects[index] = object
@@ -45,6 +45,8 @@ class Loader(DirectObject):
         self.base = base
         self.loader = PandaLoader.getGlobalPtr()
 
+        self.__requests = {}
+
         self.hook = "async_loader_%s" % (Loader.loaderIndex)
         Loader.loaderIndex += 1
         self.accept(self.hook, self.__gotAsyncObject)
@@ -116,7 +118,7 @@ class Loader(DirectObject):
         """
 
         assert Loader.notify.debug("Loading model: %s" % (modelPath))
-        if loaderOptions == None:
+        if loaderOptions is None:
             loaderOptions = LoaderOptions()
         else:
             loaderOptions = LoaderOptions(loaderOptions)
@@ -156,7 +158,7 @@ class Loader(DirectObject):
             result = []
             for modelPath in modelList:
                 node = self.loader.loadSync(Filename(modelPath), loaderOptions)
-                if (node != None):
+                if node is not None:
                     nodePath = NodePath(node)
                 else:
                     nodePath = None
@@ -179,16 +181,16 @@ class Loader(DirectObject):
             # callback (passing it the models on the parameter list).
 
             cb = Loader.Callback(len(modelList), gotList, callback, extraArgs)
-            i=0
+            i = 0
             for modelPath in modelList:
                 request = self.loader.makeAsyncRequest(Filename(modelPath), loaderOptions)
                 if priority is not None:
                     request.setPriority(priority)
                 request.setDoneEvent(self.hook)
-                request.setPythonObject((cb, i))
-                i+=1
                 self.loader.loadAsync(request)
-                cb.requests[request] = True
+                cb.requests.add(request)
+                self.__requests[request] = (cb, i)
+                i += 1
             return cb
 
     def cancelRequest(self, cb):
@@ -200,6 +202,7 @@ class Loader(DirectObject):
             cb.cancelled = True
             for request in cb.requests:
                 self.loader.remove(request)
+                del self.__requests[request]
             cb.requests = None
 
     def isRequestPending(self, cb):
@@ -273,7 +276,7 @@ class Loader(DirectObject):
             # to resolve it for us.
             options = LoaderOptions(LoaderOptions.LFSearch | LoaderOptions.LFNoDiskCache | LoaderOptions.LFCacheOnly)
             modelNode = self.loader.loadSync(Filename(model), options)
-            if modelNode == None:
+            if modelNode is None:
                 # Model not found.
                 assert Loader.notify.debug("Unloading model not loaded: %s" % (model))
                 return
@@ -293,7 +296,7 @@ class Loader(DirectObject):
         a callback is used, the model is saved asynchronously, and the
         true/false status is passed to the callback function. """
 
-        if loaderOptions == None:
+        if loaderOptions is None:
             loaderOptions = LoaderOptions()
         else:
             loaderOptions = LoaderOptions(loaderOptions)
@@ -342,16 +345,16 @@ class Loader(DirectObject):
             # callback (passing it the models on the parameter list).
 
             cb = Loader.Callback(len(modelList), gotList, callback, extraArgs)
-            i=0
+            i = 0
             for modelPath, node in modelList:
                 request = self.loader.makeAsyncSaveRequest(Filename(modelPath), loaderOptions, node)
                 if priority is not None:
                     request.setPriority(priority)
                 request.setDoneEvent(self.hook)
-                request.setPythonObject((cb, i))
-                i+=1
                 self.loader.saveAsync(request)
-                cb.requests[request] = True
+                cb.requests.add(request)
+                self.__requests[request] = (cb, i)
+                i += 1
             return cb
 
 
@@ -496,7 +499,7 @@ class Loader(DirectObject):
             phaseChecker(modelPath, loaderOptions)
 
         font = FontPool.loadFont(modelPath)
-        if font == None:
+        if font is None:
             if not okMissing:
                 message = 'Could not load font file: %s' % (modelPath)
                 raise IOError(message)
@@ -506,21 +509,21 @@ class Loader(DirectObject):
 
         # The following properties may only be set for dynamic fonts.
         if hasattr(font, "setPointSize"):
-            if pointSize != None:
+            if pointSize is not None:
                 font.setPointSize(pointSize)
-            if pixelsPerUnit != None:
+            if pixelsPerUnit is not None:
                 font.setPixelsPerUnit(pixelsPerUnit)
-            if scaleFactor != None:
+            if scaleFactor is not None:
                 font.setScaleFactor(scaleFactor)
-            if textureMargin != None:
+            if textureMargin is not None:
                 font.setTextureMargin(textureMargin)
-            if polyMargin != None:
+            if polyMargin is not None:
                 font.setPolyMargin(polyMargin)
-            if minFilter != None:
+            if minFilter is not None:
                 font.setMinfilter(minFilter)
-            if magFilter != None:
+            if magFilter is not None:
                 font.setMagfilter(magFilter)
-            if anisotropicDegree != None:
+            if anisotropicDegree is not None:
                 font.setAnisotropicDegree(anisotropicDegree)
             if color:
                 font.setFg(color)
@@ -577,10 +580,10 @@ class Loader(DirectObject):
         the texture and the number of expected mipmap images.
 
         If minfilter or magfilter is not None, they should be a symbol
-        like Texture.FTLinear or Texture.FTNearest.  (minfilter may be
-        further one of the Mipmap filter type symbols.)  These specify
-        the filter mode that will automatically be applied to the
-        texture when it is loaded.  Note that this setting may
+        like SamplerState.FTLinear or SamplerState.FTNearest.  (minfilter
+        may be further one of the Mipmap filter type symbols.)  These
+        specify the filter mode that will automatically be applied to
+        the texture when it is loaded.  Note that this setting may
         override the texture's existing settings, even if it has
         already been loaded.  See egg-texture-cards for a more robust
         way to apply per-texture filter types and settings.
@@ -596,7 +599,7 @@ class Loader(DirectObject):
         left image and '1' for the right image.  Larger numbers are
         also allowed if you need more than two views.
         """
-        if loaderOptions == None:
+        if loaderOptions is None:
             loaderOptions = LoaderOptions()
         else:
             loaderOptions = LoaderOptions(loaderOptions)
@@ -657,7 +660,7 @@ class Loader(DirectObject):
         numbered 8 - 15 will be part of the right eye view.
         """
         assert Loader.notify.debug("Loading 3-D texture: %s" % (texturePattern))
-        if loaderOptions == None:
+        if loaderOptions is None:
             loaderOptions = LoaderOptions()
         else:
             loaderOptions = LoaderOptions(loaderOptions)
@@ -711,7 +714,7 @@ class Loader(DirectObject):
         and each six images will define a new view.
         """
         assert Loader.notify.debug("Loading cube map: %s" % (texturePattern))
-        if loaderOptions == None:
+        if loaderOptions is None:
             loaderOptions = LoaderOptions()
         else:
             loaderOptions = LoaderOptions(loaderOptions)
@@ -821,13 +824,12 @@ class Loader(DirectObject):
             # callback (passing it the sounds on the parameter list).
 
             cb = Loader.Callback(len(soundList), gotList, callback, extraArgs)
-            for i in range(len(soundList)):
-                soundPath = soundList[i]
+            for i, soundPath in enumerate(soundList):
                 request = AudioLoadRequest(manager, soundPath, positional)
                 request.setDoneEvent(self.hook)
-                request.setPythonObject((cb, i))
                 self.loader.loadAsync(request)
-                cb.requests[request] = True
+                cb.requests.add(request)
+                self.__requests[request] = (cb, i)
             return cb
 
     def unloadSfx(self, sfx):
@@ -852,7 +854,7 @@ class Loader(DirectObject):
         return shader
 
     def unloadShader(self, shaderPath):
-        if (shaderPath != None):
+        if shaderPath is not None:
             ShaderPool.releaseShader(shaderPath)
 
     def asyncFlattenStrong(self, model, inPlace = True,
@@ -886,14 +888,14 @@ class Loader(DirectObject):
             gotList = True
 
         cb = Loader.Callback(len(modelList), gotList, callback, extraArgs)
-        i=0
+        i = 0
         for model in modelList:
             request = ModelFlattenRequest(model.node())
             request.setDoneEvent(self.hook)
-            request.setPythonObject((cb, i))
-            i+=1
             self.loader.loadAsync(request)
-            cb.requests[request] = True
+            cb.requests.add(request)
+            self.__requests[request] = (cb, i)
+            i += 1
         return cb
 
     def __asyncFlattenDone(self, models,
@@ -921,16 +923,23 @@ class Loader(DirectObject):
         of loaded objects, and call the appropriate callback when it's
         time."""
 
-        cb, i = request.getPythonObject()
+        if request not in self.__requests:
+            return
+
+        cb, i = self.__requests[request]
         if cb.cancelled:
+            # Shouldn't be here.
+            del self.__requests[request]
             return
 
-        del cb.requests[request]
+        cb.requests.discard(request)
+        if not cb.requests:
+            del self.__requests[request]
 
         object = None
         if hasattr(request, "getModel"):
             node = request.getModel()
-            if (node != None):
+            if node is not None:
                 object = NodePath(node)
 
         elif hasattr(request, "getSound"):

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

@@ -23,7 +23,7 @@ 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."""
 
-from pandac.PandaModules import *
+from panda3d.core import *
 from direct.task import Task
 
 def setupMirror(name, width, height, rootCamera = None):

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

@@ -14,7 +14,7 @@ multitexture rendering techniques.  It's not a particularly great
 way to do shadows.
 """
 
-from pandac.PandaModules import *
+from panda3d.core import *
 from direct.task import Task
 
 sc = None

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

@@ -12,7 +12,7 @@ the its parent node.
 
 from direct.controls.ControlManager import CollisionHandlerRayStart
 from direct.directnotify import DirectNotifyGlobal
-from pandac.PandaModules import *
+from panda3d.core import *
 from . import DirectObject
 
 class ShadowPlacer(DirectObject.DirectObject):

+ 4 - 1
direct/src/showutil/FreezeTool.py

@@ -984,7 +984,10 @@ class Freezer:
             try:
                 self.__loadModule(mdef)
             except ImportError as ex:
-                print("Unknown module: %s (%s)" % (mdef.moduleName, str(ex)))
+                message = "Unknown module: %s" % (mdef.moduleName)
+                if str(ex) != "No module named " + str(mdef.moduleName):
+                    message += " (%s)" % (ex)
+                print(message)
 
         # Also attempt to import any implicit modules.  If any of
         # these fail to import, we don't really care.

+ 10 - 10
direct/src/stdpy/thread.py

@@ -102,7 +102,7 @@ def start_new_thread(function, args, kwargs = {}, name = None):
             name = 'PythonThread-%s' % (threadId)
 
         thread = core.PythonThread(threadFunc, [threadId], name, name)
-        thread.setPythonData(threadId)
+        thread.setPythonIndex(threadId)
         _threads[threadId] = (thread, {}, None)
 
         thread.start(core.TPNormal, False)
@@ -121,7 +121,7 @@ def _add_thread(thread, wrapper):
         threadId = _nextThreadId
         _nextThreadId += 1
 
-        thread.setPythonData(threadId)
+        thread.setPythonIndex(threadId)
         _threads[threadId] = (thread, {}, wrapper)
         return threadId
 
@@ -133,8 +133,8 @@ def _get_thread_wrapper(thread, wrapperClass):
     is not one, creates an instance of the indicated wrapperClass
     instead. """
 
-    threadId = thread.getPythonData()
-    if threadId is None:
+    threadId = thread.getPythonIndex()
+    if threadId == -1:
         # The thread has never been assigned a threadId.  Go assign one.
 
         global _nextThreadId
@@ -143,7 +143,7 @@ def _get_thread_wrapper(thread, wrapperClass):
             threadId = _nextThreadId
             _nextThreadId += 1
 
-            thread.setPythonData(threadId)
+            thread.setPythonIndex(threadId)
             wrapper = wrapperClass(thread, threadId)
             _threads[threadId] = (thread, {}, wrapper)
             return wrapper
@@ -169,8 +169,8 @@ def _get_thread_locals(thread, i):
     """ Returns the locals dictionary for the indicated thread.  If
     there is not one, creates an empty dictionary. """
 
-    threadId = thread.getPythonData()
-    if threadId is None:
+    threadId = thread.getPythonIndex()
+    if threadId == -1:
         # The thread has never been assigned a threadId.  Go assign one.
 
         global _nextThreadId
@@ -179,7 +179,7 @@ def _get_thread_locals(thread, i):
             threadId = _nextThreadId
             _nextThreadId += 1
 
-            thread.setPythonData(threadId)
+            thread.setPythonIndex(threadId)
             locals = {}
             _threads[threadId] = (thread, locals, None)
             return locals.setdefault(i, {})
@@ -205,9 +205,9 @@ def _remove_thread_id(threadId):
     _threadsLock.acquire()
     try:
         thread, locals, wrapper = _threads[threadId]
-        assert thread.getPythonData() == threadId
+        assert thread.getPythonIndex() == threadId
         del _threads[threadId]
-        thread.setPythonData(None)
+        thread.setPythonIndex(-1)
 
     finally:
         _threadsLock.release()

+ 32 - 0
doc/ReleaseNotes

@@ -1,3 +1,35 @@
+------------------------  RELEASE 1.9.3  ------------------------
+
+This issue fixes several bugs that were still found in 1.9.2.
+
+* Fix crash when running in Steam on Linux when using OpenAL
+* Fix crash using wx/tkinter on Mac as long as want-wx/tk is set
+* Fix loading models from 'models' package with models/ prefix
+* Fix random crashes in task system
+* Fix memory leaks in BulletTriangleMesh
+* Fix loading old models with MovingPart<LMatrix4f>
+* Improve performance of CPU vertex animation somewhat
+* Show framebuffer properties when fbprop request fails
+* Show error instead of crash on use of object before __init__
+* Fix hang on exit when using Python task on threaded task chain
+* Fix inability to get RGBA renderbuffer in certain cases
+* Work around GLSL issue with #pragma and certain Intel drivers
+* Improve performance of texture load and store operations
+* Fix crashes with pbuffers on Intel cards on Windows
+* Support for Autodesk Maya 2016.5
+* Add shadow-depth-bits config var to control shadow map depth
+* Fix cull issue when rendering cube map (or any multi-lens setup)
+* Fix crash rendering with the same camera to different contexts
+* Fix compile error when making static build with DX9 renderer
+* Fix assertion when using aux render targets in DX9
+* Work around Cg bug generating invalid ASM for saturated tex loads
+* Fix issues with certain Cg shader inputs in DX9
+* Support uint8 index buffers in DX9
+* Fix occasional frame lag when loading a big model asynchronously
+* Fix race condition reading string config var
+* Fix interrogate parsing issue with "const static"
+* Add back missing libp3pystub.a to Mac OS X SDK
+
 ------------------------  RELEASE 1.9.2  ------------------------
 
 This is a minor bugfix release, fixing a few minor issues that

Разлика између датотеке није приказан због своје велике величине
+ 1570 - 1576
dtool/src/cppparser/cppBison.cxx.prebuilt


+ 31 - 88
dtool/src/cppparser/cppBison.yxx

@@ -783,6 +783,11 @@ storage_class:
         empty
 {
   $$ = 0;
+}
+        | KW_CONST storage_class
+{
+  // This isn't really a storage class, but it helps with parsing.
+  $$ = $2 | (int)CPPInstance::SC_const;
 }
         | KW_EXTERN storage_class
 {
@@ -861,10 +866,22 @@ attribute_specifier:
         ;
 
 type_like_declaration:
-        multiple_var_declaration
+        storage_class var_type_decl
+{
+  // We don't need to push/pop type, because we can't nest
+  // type_like_declaration.
+  if ($2->as_type_declaration()) {
+    current_type = $2->as_type_declaration()->_type;
+  } else {
+    current_type = $2->as_type();
+  }
+  push_storage_class($1);
+}
+        multiple_instance_identifiers
 {
-  /* multiple_var_declaration adds itself to the scope. */
+  pop_storage_class();
 }
+
         | storage_class type_decl ';'
 {
   // We don't really care about the storage class here.  In fact, it's
@@ -891,39 +908,6 @@ type_like_declaration:
   }
 }
         | using_declaration
-        ;
-
-multiple_var_declaration:
-        storage_class var_type_decl
-{
-  // We don't need to push/pop type, because we can't nest
-  // multiple_var_declarations.
-  if ($2->as_type_declaration()) {
-    current_type = $2->as_type_declaration()->_type;
-  } else {
-    current_type = $2->as_type();
-  }
-  push_storage_class($1);
-}
-        multiple_instance_identifiers
-{
-  pop_storage_class();
-}
-        | storage_class KW_CONST var_type_decl
-{
-  // We don't need to push/pop type, because we can't nest
-  // multiple_var_declarations.
-  if ($3->as_type_declaration()) {
-    current_type = $3->as_type_declaration()->_type;
-  } else {
-    current_type = $3->as_type();
-  }
-  push_storage_class($1);
-}
-        multiple_const_instance_identifiers
-{
-  pop_storage_class();
-}
 
         /* We don't need to include a rule for variables that point to
            functions, because we get those from the function_prototype
@@ -933,6 +917,9 @@ multiple_var_declaration:
 multiple_instance_identifiers:
         instance_identifier_and_maybe_trailing_return_type maybe_initialize_or_function_body
 {
+  if (current_storage_class & CPPInstance::SC_const) {
+    $1->add_modifier(IIT_const);
+  }
   CPPInstance *inst = new CPPInstance(current_type, $1,
                                       current_storage_class,
                                       @1.file);
@@ -941,27 +928,9 @@ multiple_instance_identifiers:
 }
         | instance_identifier_and_maybe_trailing_return_type maybe_initialize ',' multiple_instance_identifiers
 {
-  CPPInstance *inst = new CPPInstance(current_type, $1,
-                                      current_storage_class,
-                                      @1.file);
-  inst->set_initializer($2);
-  current_scope->add_declaration(inst, global_scope, current_lexer, @1);
-}
-        ;
-
-multiple_const_instance_identifiers:
-        instance_identifier_and_maybe_trailing_return_type maybe_initialize_or_function_body
-{
-  $1->add_modifier(IIT_const);
-  CPPInstance *inst = new CPPInstance(current_type, $1,
-                                      current_storage_class,
-                                      @1.file);
-  inst->set_initializer($2);
-  current_scope->add_declaration(inst, global_scope, current_lexer, @1);
-}
-        | instance_identifier_and_maybe_trailing_return_type maybe_initialize ',' multiple_const_instance_identifiers
-{
-  $1->add_modifier(IIT_const);
+  if (current_storage_class & CPPInstance::SC_const) {
+    $1->add_modifier(IIT_const);
+  }
   CPPInstance *inst = new CPPInstance(current_type, $1,
                                       current_storage_class,
                                       @1.file);
@@ -986,21 +955,6 @@ typedef_declaration:
         typedef_instance_identifiers
 {
   pop_storage_class();
-}
-        | storage_class KW_CONST var_type_decl
-{
-  // We don't need to push/pop type, because we can't nest
-  // multiple_var_declarations.
-  if ($3->as_type_declaration()) {
-    current_type = $3->as_type_declaration()->_type;
-  } else {
-    current_type = $3->as_type();
-  }
-  push_storage_class($1);
-}
-        typedef_const_instance_identifiers
-{
-  pop_storage_class();
 }
         | storage_class function_prototype maybe_initialize_or_function_body
 {
@@ -1019,29 +973,18 @@ typedef_declaration:
 typedef_instance_identifiers:
         instance_identifier_and_maybe_trailing_return_type maybe_initialize_or_function_body
 {
+  if (current_storage_class & CPPInstance::SC_const) {
+    $1->add_modifier(IIT_const);
+  }
   CPPType *target_type = current_type;
   CPPTypedefType *typedef_type = new CPPTypedefType(target_type, $1, current_scope, @1.file);
   current_scope->add_declaration(CPPType::new_type(typedef_type), global_scope, current_lexer, @1);
 }
         | instance_identifier_and_maybe_trailing_return_type maybe_initialize ',' typedef_instance_identifiers
 {
-  CPPType *target_type = current_type;
-  CPPTypedefType *typedef_type = new CPPTypedefType(target_type, $1, current_scope, @1.file);
-  current_scope->add_declaration(CPPType::new_type(typedef_type), global_scope, current_lexer, @1);
-}
-        ;
-
-typedef_const_instance_identifiers:
-        instance_identifier_and_maybe_trailing_return_type maybe_initialize_or_function_body
-{
-  $1->add_modifier(IIT_const);
-  CPPType *target_type = current_type;
-  CPPTypedefType *typedef_type = new CPPTypedefType(target_type, $1, current_scope, @1.file);
-  current_scope->add_declaration(CPPType::new_type(typedef_type), global_scope, current_lexer, @1);
-}
-        | instance_identifier_and_maybe_trailing_return_type maybe_initialize ',' typedef_const_instance_identifiers
-{
-  $1->add_modifier(IIT_const);
+  if (current_storage_class & CPPInstance::SC_const) {
+    $1->add_modifier(IIT_const);
+  }
   CPPType *target_type = current_type;
   CPPTypedefType *typedef_type = new CPPTypedefType(target_type, $1, current_scope, @1.file);
   current_scope->add_declaration(CPPType::new_type(typedef_type), global_scope, current_lexer, @1);

+ 1 - 0
dtool/src/cppparser/cppEnumType.h

@@ -16,6 +16,7 @@
 
 #include "dtoolbase.h"
 
+#include "cppBisonDefs.h"
 #include "cppExtensionType.h"
 
 #include <vector>

+ 4 - 0
dtool/src/cppparser/cppInstance.h

@@ -64,6 +64,10 @@ public:
     SC_deleted      = 0x8000,
 
     SC_thread_local = 0x10000,
+
+    // This isn't really a storage class.  It's only used temporarily by the
+    // parser, to make parsing specifier sequences a bit easier.
+    SC_const        = 0x20000,
   };
 
   CPPInstance(CPPType *type, const string &name, int storage_class = 0);

+ 0 - 2
dtool/src/cppparser/cppManifest.cxx

@@ -370,10 +370,8 @@ save_expansion(const string &exp, const vector_string &parameter_names) {
 
       // Is this identifier one of our parameters?
       int pnum = -1;
-      bool va_args = false;
 
       if (ident == "__VA_ARGS__") {
-        va_args = true;
         // C99-style variadics, ie.  #define macro(...) __VA_ARGS__
         pnum = _variadic_param;
 

+ 3 - 4
dtool/src/cppparser/cppPreprocessor.cxx

@@ -806,7 +806,7 @@ expand_manifests(const string &input_expr, bool expand_undefined,
           Manifests::const_iterator mi = _manifests.find(ident);
           if (mi != _manifests.end()) {
             const CPPManifest *manifest = (*mi).second;
-            expand_manifest_inline(expr, q, p, (*mi).second);
+            expand_manifest_inline(expr, q, p, manifest);
             manifest_found = true;
 
           } else if (expand_undefined && ident != "true" && ident != "false") {
@@ -1192,8 +1192,6 @@ skip_c_comment(int c) {
 
   } else {
     CPPFile first_file = get_file();
-    int first_line_number = get_line_number();
-    int first_col_number = get_col_number() - 2;
 
     while (c != EOF) {
       if (c == '*') {
@@ -1816,8 +1814,9 @@ get_identifier(int c) {
       type = CPPExpression::T_u16string;
     } else if (name == "U") {
       type = CPPExpression::T_u32string;
+    } else {
+      type = CPPExpression::T_string;
     }
-
     get();
     string str = scan_quoted(c);
 

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

@@ -18,6 +18,7 @@
 #include "cppTypedefType.h"
 #include "cppTypeDeclaration.h"
 #include "cppExtensionType.h"
+#include "cppEnumType.h"
 #include "cppInstance.h"
 #include "cppInstanceIdentifier.h"
 #include "cppIdentifier.h"

+ 1 - 1
dtool/src/cppparser/cppToken.cxx

@@ -40,7 +40,7 @@ CPPToken(int token, int line_number, int col_number,
  */
 CPPToken::
 CPPToken(int token, const YYLTYPE &loc, const string &str, const YYSTYPE &val) :
-  _token(token), _lloc(loc), _lval(val)
+  _token(token), _lval(val), _lloc(loc)
 {
   _lval.str = str;
 }

+ 2 - 0
dtool/src/cppparser/cppTypedefType.cxx

@@ -14,6 +14,8 @@
 #include "cppTypedefType.h"
 #include "cppIdentifier.h"
 #include "cppInstanceIdentifier.h"
+#include "cppTemplateScope.h"
+#include "indent.h"
 
 /**
  *

+ 11 - 9
dtool/src/dtoolbase/dtoolbase.h

@@ -70,23 +70,25 @@
 #else
 // #pragma message("VC 6.0")
 #endif
+#endif  /* WIN32_VC */
+
+#ifndef __has_builtin
+#define __has_builtin(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')
 #ifdef _DEBUG
-# define NODEFAULT  default: assert(0);
+#define NODEFAULT  default: assert(0); break;
+#elif defined(_MSC_VER)
+#define NODEFAULT  default: __assume(0);   // special VC keyword
+#elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) || __has_builtin(__builtin_unreachable)
+#define NODEFAULT  default: __builtin_unreachable();
 #else
-# define NODEFAULT  default: __assume(0);   // special VC keyword
+#define NODEFAULT
 #endif
 
-#else /* if !WIN32_VC */
-#ifdef _DEBUG
-# define NODEFAULT   default: assert(0);
-#else
-# define NODEFAULT
-#endif
-#endif  /* WIN32_VC */
 
 /*
   include win32 defns for everything up to WinServer2003, and assume

+ 6 - 0
dtool/src/dtoolbase/typeRegistry.cxx

@@ -341,6 +341,8 @@ get_root_class(int n) {
   TypeHandle handle;
   if (n >= 0 && n < (int)_root_classes.size()) {
     handle = _root_classes[n]->_handle;
+  } else {
+    handle = TypeHandle::none();
   }
   _lock->release();
 
@@ -380,6 +382,8 @@ get_parent_class(TypeHandle child, int index) const {
   assert(rnode != (TypeRegistryNode *)NULL);
   if (index >= 0 && index < (int)rnode->_parent_classes.size()) {
     handle = rnode->_parent_classes[index]->_handle;
+  } else {
+    handle = TypeHandle::none();
   }
   _lock->release();
   return handle;
@@ -415,6 +419,8 @@ get_child_class(TypeHandle child, int index) const {
   assert(rnode != (TypeRegistryNode *)NULL);
   if (index >= 0 && index < (int)rnode->_child_classes.size()) {
     handle = rnode->_child_classes[index]->_handle;
+  } else {
+    handle = TypeHandle::none();
   }
   _lock->release();
   return handle;

+ 5 - 1
dtool/src/dtoolutil/filename.cxx

@@ -443,7 +443,11 @@ temporary(const string &dirname, const string &prefix, const string &suffix,
     // generate a 6-character hex code.
     int hash = (clock() * time(NULL)) & 0xffffff;
     char hex_code[10];
-    sprintf(hex_code, "%06x", hash);
+#ifdef _WIN32
+    sprintf_s(hex_code, 10, "%06x", hash);
+#else
+    snprintf(hex_code, 10, "%06x", hash);
+#endif
     result = Filename(fdirname, Filename(prefix + hex_code + suffix));
     result.set_type(type);
   } while (result.exists());

+ 1 - 1
dtool/src/dtoolutil/pandaFileStreamBuf.cxx

@@ -323,7 +323,7 @@ seekoff(streamoff off, ios_seekdir dir, ios_openmode which) {
       // Posix case.
       {
         off_t li = lseek(_fd, off, SEEK_END);
-        if (li == (size_t)-1) {
+        if (li == (off_t)-1) {
           return -1;
         }
         new_pos = (size_t)li;

+ 49 - 5
dtool/src/interrogate/interfaceMakerPythonNative.cxx

@@ -1259,9 +1259,16 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
       if (is_cpp_type_legal(object->_itype._cpptype) &&
           isExportThisRun(object->_itype._cpptype)) {
         string class_name = make_safe_name(object->_itype.get_scoped_name());
-        bool is_typed = HasAGetClassTypeFunction(object->_itype._cpptype);
+        bool is_typed = has_get_class_type_function(object->_itype._cpptype);
 
         if (is_typed) {
+          if (has_init_type_function(object->_itype._cpptype)) {
+            // Call the init_type function.  This isn't necessary for all
+            // types as many of them are automatically initialized at static
+            // init type, but for some extension classes it's useful.
+            out << "  " << object->_itype._cpptype->get_local_name(&parser)
+                << "::init_type();\n";
+          }
           out << "  Dtool_" << class_name << "._type = "
               << object->_itype._cpptype->get_local_name(&parser)
               << "::get_class_type();\n"
@@ -1291,7 +1298,7 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
     string class_name = (*ii)->get_local_name(&parser);
     string safe_name = make_safe_name(class_name);
 
-    if (HasAGetClassTypeFunction(*ii)) {
+    if (has_get_class_type_function(*ii)) {
       out << "  Dtool_Ptr_" << safe_name << " = LookupRuntimeTypedClass(" << class_name << "::get_class_type());\n";
     } else {
       out << "  Dtool_Ptr_" << safe_name << " = LookupNamedClass(\"" << class_name << "\");\n";
@@ -1541,7 +1548,7 @@ write_module_class(ostream &out, Object *obj) {
   std::string export_class_name = classNameFromCppName(obj->_itype.get_name(), false);
 
   bool is_runtime_typed = IsPandaTypedObject(obj->_itype._cpptype->as_struct_type());
-  if (!is_runtime_typed && HasAGetClassTypeFunction(obj->_itype._cpptype)) {
+  if (!is_runtime_typed && has_get_class_type_function(obj->_itype._cpptype)) {
     is_runtime_typed = true;
   }
 
@@ -4196,7 +4203,7 @@ write_function_forset(ostream &out,
     return;
   }
 
-  FunctionRemap *remap;
+  FunctionRemap *remap = NULL;
   std::set<FunctionRemap *>::iterator sii;
 
   bool all_nonconst = false;
@@ -7010,7 +7017,7 @@ DoesInheritFromIsClass(const CPPStructType *inclass, const std::string &name) {
 
  */
 bool InterfaceMakerPythonNative::
-HasAGetClassTypeFunction(CPPType *type) {
+has_get_class_type_function(CPPType *type) {
   while (type->get_subtype() == CPPDeclaration::ST_typedef) {
     type = type->as_typedef_type()->_type;
   }
@@ -7025,6 +7032,43 @@ HasAGetClassTypeFunction(CPPType *type) {
   return scope->_functions.find("get_class_type") != scope->_functions.end();
 }
 
+/**
+ *
+ */
+bool InterfaceMakerPythonNative::
+has_init_type_function(CPPType *type) {
+  while (type->get_subtype() == CPPDeclaration::ST_typedef) {
+    type = type->as_typedef_type()->_type;
+  }
+
+  CPPStructType *struct_type = type->as_struct_type();
+  if (struct_type == NULL) {
+    return false;
+  }
+
+  CPPScope *scope = struct_type->get_scope();
+  CPPScope::Functions::const_iterator it = scope->_functions.find("init_type");
+  if (it == scope->_functions.end()) {
+    return false;
+  }
+  const CPPFunctionGroup *group = it->second;
+
+  CPPFunctionGroup::Instances::const_iterator ii;
+  for (ii = group->_instances.begin(); ii != group->_instances.end(); ++ii) {
+    const CPPInstance *cppinst = *ii;
+    const CPPFunctionType *cppfunc = cppinst->_type->as_function_type();
+
+    if (cppfunc != NULL &&
+        cppfunc->_parameters != NULL &&
+        cppfunc->_parameters->_parameters.size() == 0 &&
+        (cppinst->_storage_class & CPPInstance::SC_static) != 0) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
 /**
  * Returns -1 if the class does not define write() (and therefore cannot
  * support a __str__ function).

+ 2 - 1
dtool/src/interrogate/interfaceMakerPythonNative.h

@@ -201,7 +201,8 @@ public:
   bool DoesInheritFromIsClass(const CPPStructType * inclass, const std::string &name);
   bool IsPandaTypedObject(CPPStructType * inclass) { return DoesInheritFromIsClass(inclass,"TypedObject"); };
   void write_python_instance(ostream &out, int indent_level, const std::string &return_expr, bool owns_memory, const InterrogateType &itype, bool is_const);
-  bool HasAGetClassTypeFunction(CPPType *type);
+  bool has_get_class_type_function(CPPType *type);
+  bool has_init_type_function(CPPType *type);
   int NeedsAStrFunction(const InterrogateType &itype_class);
   int NeedsAReprFunction(const InterrogateType &itype_class);
   bool NeedsARichCompareFunction(const InterrogateType &itype_class);

+ 0 - 4
dtool/src/interrogate/interrogate.cxx

@@ -19,7 +19,6 @@
 #include "pnotify.h"
 #include "panda_getopt_long.h"
 #include "preprocess_argv.h"
-#include "pystub.h"
 #include <time.h>
 
 CPPParser parser;
@@ -306,9 +305,6 @@ predefine_macro(CPPParser& parser, const string& inoption) {
 
 int
 main(int argc, char **argv) {
-  // A call to pystub() to force libpystub.so to be linked in.
-  pystub();
-
   preprocess_argv(argc, argv);
   string command_line;
   int i;

+ 4 - 4
dtool/src/interrogate/interrogateBuilder.cxx

@@ -1851,9 +1851,9 @@ get_make_property(CPPMakeProperty *make_property, CPPStructType *struct_type, CP
       }
 
       // The getter must either take no arguments, or all defaults.
-      if (ftype->_parameters->_parameters.size() == (int)is_seq ||
-          (ftype->_parameters->_parameters.size() > (int)is_seq &&
-           ftype->_parameters->_parameters[(int)is_seq]->_initializer != NULL)) {
+      if (ftype->_parameters->_parameters.size() == (size_t)is_seq ||
+          (ftype->_parameters->_parameters.size() > (size_t)is_seq &&
+           ftype->_parameters->_parameters[(size_t)is_seq]->_initializer != NULL)) {
         // If this is a sequence getter, it must take an index argument.
         if (is_seq && !TypeManager::is_integer(ftype->_parameters->_parameters[0]->_type)) {
           continue;
@@ -1909,7 +1909,7 @@ get_make_property(CPPMakeProperty *make_property, CPPStructType *struct_type, CP
     for (fi = fgroup->_instances.begin(); fi != fgroup->_instances.end(); ++fi) {
       CPPInstance *function = (*fi);
       CPPFunctionType *ftype = function->_type->as_function_type();
-      if (ftype != NULL && ftype->_parameters->_parameters.size() == (int)is_seq) {
+      if (ftype != NULL && ftype->_parameters->_parameters.size() == (size_t)is_seq) {
         deleter = function;
         break;
       }

+ 0 - 4
dtool/src/interrogate/interrogate_module.cxx

@@ -19,7 +19,6 @@
 #include "interrogate_interface.h"
 #include "interrogate_request.h"
 #include "load_dso.h"
-#include "pystub.h"
 #include "pnotify.h"
 #include "panda_getopt_long.h"
 #include "preprocess_argv.h"
@@ -380,9 +379,6 @@ int main(int argc, char *argv[]) {
   extern int optind;
   int flag;
 
-  // A call to pystub() to force libpystub.so to be linked in.
-  pystub();
-
   preprocess_argv(argc, argv);
   flag = getopt_long_only(argc, argv, short_options, long_options, NULL);
   while (flag != EOF) {

+ 3 - 2
dtool/src/interrogate/typeManager.cxx

@@ -41,7 +41,7 @@ resolve_type(CPPType *type, CPPScope *scope) {
     scope = &parser;
   }
 
-  CPPType *orig_type = type;
+  //CPPType *orig_type = type;
   type = type->resolve_type(scope, &parser);
   string name = type->get_local_name(&parser);
   if (name.empty()) {
@@ -1740,7 +1740,8 @@ is_Py_buffer(CPPType *type) {
 
   case CPPDeclaration::ST_extension:
   case CPPDeclaration::ST_struct:
-    return (type->get_local_name(&parser) == "Py_buffer");
+    return (type->get_local_name(&parser) == "Py_buffer" ||
+            type->get_local_name(&parser) == "bufferinfo");
 
   case CPPDeclaration::ST_typedef:
     return is_Py_buffer(type->as_typedef_type()->_type);

+ 1 - 1
dtool/src/interrogatedb/extension.h

@@ -31,7 +31,7 @@ public:
  * extended should create a specialization of this class template.
  */
 template<class T>
-class EXPCL_INTERROGATEDB Extension : public ExtensionBase<T> {
+class Extension : public ExtensionBase<T> {
 };
 
 /**

+ 4 - 0
dtool/src/interrogatedb/interrogate_request.cxx

@@ -20,7 +20,11 @@ void
 interrogate_request_database(const char *database_filename) {
   InterrogateModuleDef *def = new InterrogateModuleDef;
   memset(def, 0, sizeof(InterrogateModuleDef));
+#ifdef _WIN32
+  def->database_filename = _strdup(database_filename);
+#else
   def->database_filename = strdup(database_filename);
+#endif
 
   // Don't think of this as a leak; think of it as a one-time database
   // allocation.

+ 8 - 0
dtool/src/interrogatedb/py_panda.I

@@ -107,7 +107,15 @@ ALWAYS_INLINE PyObject *Dtool_WrapValue(long long value) {
 }
 
 ALWAYS_INLINE PyObject *Dtool_WrapValue(unsigned long long value) {
+  // size_t is sometimes defined as unsigned long long, and we want to map
+  // that to int in Python 2 so it can be returned from a __len__.
+#if PY_MAJOR_VERSION >= 3
   return PyLong_FromUnsignedLongLong(value);
+#else
+  return (value > LONG_MAX)
+    ? PyLong_FromUnsignedLongLong(value)
+    : PyInt_FromLong((long)value);
+#endif
 }
 
 ALWAYS_INLINE PyObject *Dtool_WrapValue(bool value) {

+ 4 - 2
dtool/src/interrogatedb/py_panda.cxx

@@ -67,7 +67,7 @@ void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject *c
  * was of the wrong type, raises an AttributeError.
  */
 bool Dtool_Call_ExtractThisPointer(PyObject *self, Dtool_PyTypedObject &classdef, void **answer) {
-  if (self == NULL || !DtoolCanThisBeAPandaInstance(self)) {
+  if (self == NULL || !DtoolCanThisBeAPandaInstance(self) || ((Dtool_PyInstDef *)self)->_ptr_to_object == NULL) {
     Dtool_Raise_TypeError("C++ object is not yet constructed, or already destructed.");
     return false;
   }
@@ -87,7 +87,7 @@ bool Dtool_Call_ExtractThisPointer(PyObject *self, Dtool_PyTypedObject &classdef
 bool Dtool_Call_ExtractThisPointer_NonConst(PyObject *self, Dtool_PyTypedObject &classdef,
                                             void **answer, const char *method_name) {
 
-  if (self == NULL || !DtoolCanThisBeAPandaInstance(self)) {
+  if (self == NULL || !DtoolCanThisBeAPandaInstance(self) || ((Dtool_PyInstDef *)self)->_ptr_to_object == NULL) {
     Dtool_Raise_TypeError("C++ object is not yet constructed, or already destructed.");
     return false;
   }
@@ -816,6 +816,7 @@ PyObject *DTOOL_PyObject_RichCompare(PyObject *v1, PyObject *v2, int op) {
   int cmpval = DTOOL_PyObject_Compare(v1, v2);
   bool result;
   switch (op) {
+  NODEFAULT
   case Py_LT:
     result = (cmpval < 0);
     break;
@@ -833,6 +834,7 @@ PyObject *DTOOL_PyObject_RichCompare(PyObject *v1, PyObject *v2, int op) {
     break;
   case Py_GE:
     result = (cmpval >= 0);
+    break;
   }
   return PyBool_FromLong(result);
 }

+ 4 - 3
dtool/src/interrogatedb/py_panda.h

@@ -219,9 +219,10 @@ static PyObject *Dtool_new_##CLASS_NAME(PyTypeObject *type, PyObject *args, PyOb
 }
 
 // The following used to be in the above macro, but it doesn't seem to be
-// necessary as tp_alloc memsets the object to 0. ((Dtool_PyInstDef
-// *)self)->_ptr_to_object = NULL;\ ((Dtool_PyInstDef *)self)->_memory_rules =
-// false;\ ((Dtool_PyInstDef *)self)->_is_const = false;\
+// necessary as tp_alloc memsets the object to 0.
+//  ((Dtool_PyInstDef *)self)->_ptr_to_object = NULL;
+//  ((Dtool_PyInstDef *)self)->_memory_rules = false;
+//  ((Dtool_PyInstDef *)self)->_is_const = false;
 
 // Delete functions..
 #ifdef NDEBUG

+ 1 - 1
dtool/src/parser-inc/Python.h

@@ -30,7 +30,7 @@ typedef struct {} PyUnicodeObject;
 
 class PyThreadState;
 typedef int Py_ssize_t;
-struct Py_buffer;
+typedef struct bufferinfo Py_buffer;
 
 // We need to define these accurately since interrogate may want to
 // write these out to default value assignments.

+ 21 - 9
dtool/src/prc/configVariableFilename.cxx

@@ -19,16 +19,28 @@
  */
 void ConfigVariableFilename::
 reload_cache() {
-  nassertv(_core != (ConfigVariableCore *)NULL);
-  mark_cache_valid(_local_modified);
+  // NB. MSVC doesn't guarantee that this mutex is initialized in a
+  // thread-safe manner.  But chances are that the first time this is called
+  // is at static init time, when there is no risk of data races.
+  static MutexImpl lock;
+  lock.acquire();
 
-  const ConfigDeclaration *decl = _core->get_declaration(0);
-  const ConfigPage *page = decl->get_page();
+  // We check again for cache validity since another thread may have beaten
+  // us to the punch while we were waiting for the lock.
+  if (!is_cache_valid(_local_modified)) {
+    nassertv(_core != (ConfigVariableCore *)NULL);
 
-  Filename page_filename(page->get_name());
-  Filename page_dirname = page_filename.get_dirname();
-  ExecutionEnvironment::shadow_environment_variable("THIS_PRC_DIR", page_dirname.to_os_specific());
+    const ConfigDeclaration *decl = _core->get_declaration(0);
+    const ConfigPage *page = decl->get_page();
 
-  _cache = Filename::expand_from(decl->get_string_value());
-  ExecutionEnvironment::clear_shadow("THIS_PRC_DIR");
+    Filename page_filename(page->get_name());
+    Filename page_dirname = page_filename.get_dirname();
+    ExecutionEnvironment::shadow_environment_variable("THIS_PRC_DIR", page_dirname.to_os_specific());
+
+    _cache = Filename::expand_from(decl->get_string_value());
+    ExecutionEnvironment::clear_shadow("THIS_PRC_DIR");
+
+    mark_cache_valid(_local_modified);
+  }
+  lock.release();
 }

+ 1 - 2
dtool/src/prc/configVariableString.I

@@ -127,8 +127,7 @@ INLINE const string &ConfigVariableString::
 get_value() const {
   TAU_PROFILE("const string &ConfigVariableString::get_value() const", " ", TAU_USER);
   if (!is_cache_valid(_local_modified)) {
-    mark_cache_valid(((ConfigVariableString *)this)->_local_modified);
-    ((ConfigVariableString *)this)->_cache = get_string_value();
+    ((ConfigVariableString *)this)->reload_cache();
   }
   return _cache;
 }

+ 21 - 0
dtool/src/prc/configVariableString.cxx

@@ -12,3 +12,24 @@
  */
 
 #include "configVariableString.h"
+
+/**
+ * Refreshes the variable's cached value.
+ */
+void ConfigVariableString::
+reload_cache() {
+  // NB. MSVC doesn't guarantee that this mutex is initialized in a
+  // thread-safe manner.  But chances are that the first time this is called
+  // is at static init time, when there is no risk of data races.
+  static MutexImpl lock;
+  lock.acquire();
+
+  // We check again for cache validity since another thread may have beaten
+  // us to the punch while we were waiting for the lock.
+  if (!is_cache_valid(_local_modified)) {
+    _cache = get_string_value();
+    mark_cache_valid(_local_modified);
+  }
+
+  lock.release();
+}

+ 3 - 0
dtool/src/prc/configVariableString.h

@@ -49,6 +49,9 @@ PUBLISHED:
   INLINE string get_word(size_t n) const;
   INLINE void set_word(size_t n, const string &value);
 
+private:
+  void reload_cache();
+
 private:
   AtomicAdjust::Integer _local_modified;
   string _cache;

+ 7 - 2
dtool/src/prc/notifyCategory.cxx

@@ -74,10 +74,15 @@ out(NotifySeverity severity, bool prefix) const {
       if (get_notify_timestamp()) {
         // Format a timestamp to include as a prefix as well.
         time_t now = time(NULL) + _server_delta;
-        struct tm *ptm = localtime(&now);
+        struct tm atm;
+#ifdef _WIN32
+        localtime_s(&atm, &now);
+#else
+        localtime_r(&now, &atm);
+#endif
 
         char buffer[128];
-        strftime(buffer, 128, ":%m-%d-%Y %H:%M:%S ", ptm);
+        strftime(buffer, 128, ":%m-%d-%Y %H:%M:%S ", &atm);
         nout << buffer;
       }
 

+ 0 - 1
dtool/src/test_interrogate/test_interrogate.cxx

@@ -17,7 +17,6 @@
 #include "interrogate_request.h"
 #include "load_dso.h"
 #include "filename.h"
-#include "pystub.h"
 #include "panda_getopt.h"
 #include "preprocess_argv.h"
 

Разлика између датотеке није приказан због своје велике величине
+ 134 - 127
makepanda/makepanda.py


+ 0 - 4
panda/src/android/pview.cxx

@@ -13,7 +13,6 @@
 
 #include "pandaFramework.h"
 #include "pandaSystem.h"
-#include "pystub.h"
 #include "texturePool.h"
 #include "multitexReducer.h"
 #include "sceneGraphReducer.h"
@@ -29,9 +28,6 @@
 #include "checkPandaVersion.h"
 
 int main(int argc, char **argv) {
-  // A call to pystub() to force libpystub.so to be linked in.
-  pystub();
-
   PandaFramework framework;
   framework.open_framework(argc, argv);
   framework.set_window_title("Panda Viewer");

+ 2 - 2
panda/src/audio/audioManager.cxx

@@ -40,7 +40,7 @@ Create_AudioManager_proc *AudioManager::_create_AudioManager = NULL;
 
 void AudioManager::
 register_AudioManager_creator(Create_AudioManager_proc* proc) {
-  nassertv(_create_AudioManager == NULL);
+  nassertv(_create_AudioManager == NULL || _create_AudioManager == proc);
   _create_AudioManager = proc;
 }
 
@@ -71,7 +71,7 @@ PT(AudioManager) AudioManager::create_AudioManager() {
       if (handle == (void *)NULL) {
         audio_error("  load_dso(" << dl_name << ") failed, will use NullAudioManager");
         audio_error("    "<<load_dso_error());
-        nassertr(_create_AudioManager == create_NullAudioManager, NULL);
+        nassertr(_create_AudioManager == NULL, NULL);
       } else {
         // Get the special function from the dso, which should return the
         // AudioManager factory function.

+ 17 - 0
panda/src/chan/animChannelFixed.cxx

@@ -0,0 +1,17 @@
+/**
+ * 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 animChannelFixed.cxx
+ * @author rdb
+ * @date 2016-05-29
+ */
+
+#include "animChannelFixed.h"
+
+template class AnimChannelFixed<ACMatrixSwitchType>;
+template class AnimChannelFixed<ACScalarSwitchType>;

+ 2 - 0
panda/src/chan/animChannelFixed.h

@@ -62,6 +62,8 @@ private:
   static TypeHandle _type_handle;
 };
 
+EXPORT_TEMPLATE_CLASS(EXPCL_PANDA_CHAN, EXPTP_PANDA_CHAN, AnimChannelFixed<ACMatrixSwitchType>);
+EXPORT_TEMPLATE_CLASS(EXPCL_PANDA_CHAN, EXPTP_PANDA_CHAN, AnimChannelFixed<ACScalarSwitchType>);
 
 #include "animChannelFixed.I"
 

+ 1 - 0
panda/src/chan/p3chan_composite1.cxx

@@ -3,6 +3,7 @@
 #include "animBundleNode.cxx"
 #include "animChannel.cxx"
 #include "animChannelBase.cxx"
+#include "animChannelFixed.cxx"
 #include "animChannelMatrixDynamic.cxx"
 #include "animChannelMatrixFixed.cxx"
 #include "animChannelMatrixXfmTable.cxx"

+ 1 - 1
panda/src/char/character.cxx

@@ -228,7 +228,7 @@ calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point, bool &found_any,
   // around this, we will force-recompute all of the bounding volumes of our
   // parent nodes immediately.
   Parents parents = get_parents();
-  for (int i = 0; i < parents.get_num_parents(); ++i) {
+  for (size_t i = 0; i < parents.get_num_parents(); ++i) {
     PandaNode *parent = parents.get_parent(i);
     parent->get_bounds();
   }

+ 20 - 0
panda/src/cocoadisplay/cocoaGraphicsStateGuardian.mm

@@ -97,6 +97,26 @@ get_properties(FrameBufferProperties &properties, NSOpenGLPixelFormat* pixel_for
   }
   // TODO: add aux buffers
 
+  // Cocoa doesn't provide individual RGB bits.  Make assumptions.
+  // Note that color_size seems to be returning values like 32, which
+  // suggests that it contains the alpha size as well.
+
+  if (color_size == 24 || color_size == 32) {
+    properties.set_rgba_bits(8, 8, 8, alpha_size);
+
+  } else if (color_size == 64) {
+    properties.set_rgba_bits(16, 16, 16, alpha_size);
+
+  } else if (color_size == 128) {
+    properties.set_rgba_bits(32, 32, 32, alpha_size);
+
+  } else if (color_size >= 3) {
+    // Assume it's giving us at least one of each.
+    properties.set_red_bits(1);
+    properties.set_green_bits(1);
+    properties.set_blue_bits(1);
+  }
+
   // Extract the renderer ID bits and check if our renderer matches the known
   // software renderers.
   renderer_id &= kCGLRendererIDMatchingMask;

+ 9 - 0
panda/src/display/config_display.cxx

@@ -298,6 +298,15 @@ ConfigVariableBool allow_incomplete_render
           "geometry is always paged in immediately when needed, holding up "
           "the frame render if necessary."));
 
+ConfigVariableBool old_alpha_blend
+("old-alpha-blend", false,
+ PRC_DESC("Set this to true to enable the old alpha blending behavior from "
+          "Panda 1.9 in which the alpha value written out to the framebuffer "
+          "is squared.  The new behavior is more intuitive when compositing "
+          "an semitransparent image produced using render-to-texture.  You "
+          "should generally leave this false unless you have an effect that "
+          "relies on the old behavior, or you suspect an implementation bug."));
+
 ConfigVariableInt win_size
 ("win-size", "800 600",
  PRC_DESC("This is the default size at which to open a new window.  This "

+ 1 - 0
panda/src/display/config_display.h

@@ -68,6 +68,7 @@ extern EXPCL_PANDA_DISPLAY ConfigVariableBool default_stereo_camera;
 extern EXPCL_PANDA_DISPLAY ConfigVariableBool color_scale_via_lighting;
 extern EXPCL_PANDA_DISPLAY ConfigVariableBool alpha_scale_via_texture;
 extern EXPCL_PANDA_DISPLAY ConfigVariableBool allow_incomplete_render;
+extern EXPCL_PANDA_DISPLAY ConfigVariableBool old_alpha_blend;
 
 extern EXPCL_PANDA_DISPLAY ConfigVariableInt win_size;
 extern EXPCL_PANDA_DISPLAY ConfigVariableInt win_origin;

+ 0 - 3
panda/src/display/displayRegion.cxx

@@ -638,9 +638,6 @@ do_compute_pixels(int i, int x_size, int y_size, CData *cdata) {
 
   Region &region = cdata->_regions[i];
 
-  int old_w = region._pixels[1] - region._pixels[0];
-  int old_h = region._pixels[3] - region._pixels[2];
-
   region._pixels[0] = int((region._dimensions[0] * x_size) + 0.5);
   region._pixels[1] = int((region._dimensions[1] * x_size) + 0.5);
   region._pixels_i[0] = region._pixels[0];

+ 30 - 8
panda/src/display/graphicsEngine.cxx

@@ -118,6 +118,23 @@ PStatCollector GraphicsEngine::_occlusion_passed_pcollector("Occlusion results:V
 PStatCollector GraphicsEngine::_occlusion_failed_pcollector("Occlusion results:Occluded");
 PStatCollector GraphicsEngine::_occlusion_tests_pcollector("Occlusion tests");
 
+// This is used to keep track of which scenes we have already culled.
+struct CullKey {
+  GraphicsStateGuardian *_gsg;
+  NodePath _camera;
+  int _lens_index;
+};
+
+INLINE static bool operator < (const CullKey &a, const CullKey &b) {
+  if (a._gsg != b._gsg) {
+    return a._gsg < b._gsg;
+  }
+  if (a._camera != b._camera) {
+    return a._camera < b._camera;
+  }
+  return a._lens_index < b._lens_index;
+}
+
 /**
  * Creates a new GraphicsEngine object.  The Pipeline is normally left to
  * default to NULL, which indicates the global render pipeline, but it may be
@@ -597,6 +614,9 @@ remove_all_windows() {
   // And, hey, let's stop the vertex paging threads, if any.
   VertexDataPage::stop_threads();
 
+  // Stopping the tasks means we have to release the Python GIL while
+  // this method runs (hence it is marked BLOCKING), so that any
+  // Python tasks on other threads won't deadlock grabbing the GIL.
   AsyncTaskManager::get_global_ptr()->stop_threads();
 
 #ifdef DO_PSTATS
@@ -1372,7 +1392,6 @@ cull_to_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
 
   // Keep track of the cameras we have already used in this thread to render
   // DisplayRegions.
-  typedef pair<NodePath, int> CullKey;
   typedef pmap<CullKey, DisplayRegion *> AlreadyCulled;
   AlreadyCulled already_culled;
 
@@ -1387,10 +1406,13 @@ cull_to_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
         if (dr != (DisplayRegion *)NULL) {
           DisplayRegionPipelineReader *dr_reader =
             new DisplayRegionPipelineReader(dr, current_thread);
-          NodePath camera = dr_reader->get_camera();
-          int lens_index = dr_reader->get_lens_index();
 
-          AlreadyCulled::iterator aci = already_culled.insert(AlreadyCulled::value_type(CullKey(camera, lens_index), (DisplayRegion *)NULL)).first;
+          CullKey key;
+          key._gsg = win->get_gsg();
+          key._camera = dr_reader->get_camera();
+          key._lens_index = dr_reader->get_lens_index();
+
+          AlreadyCulled::iterator aci = already_culled.insert(AlreadyCulled::value_type(key, (DisplayRegion *)NULL)).first;
           if ((*aci).second == NULL) {
             // We have not used this camera already in this thread.  Perform
             // the cull operation.
@@ -1505,7 +1527,7 @@ draw_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
         // We have to place this collector inside begin_frame, because we need
         // a current context for PStatGPUTimer to work.
         {
-          PStatGPUTimer timer(win->get_gsg(), win->get_draw_window_pcollector(), current_thread);
+          PStatGPUTimer timer(gsg, win->get_draw_window_pcollector(), current_thread);
           win->clear(current_thread);
 
           if (display_cat.is_spam()) {
@@ -1525,8 +1547,8 @@ draw_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
         if (_auto_flip) {
 #ifdef DO_PSTATS
           // This is a good time to perform a latency query.
-          if (win->get_gsg()->get_timer_queries_active()) {
-            win->get_gsg()->issue_timer_query(GraphicsStateGuardian::_command_latency_pcollector.get_index());
+          if (gsg->get_timer_queries_active()) {
+            gsg->issue_timer_query(GraphicsStateGuardian::_command_latency_pcollector.get_index());
           }
 #endif
 
@@ -1538,7 +1560,7 @@ draw_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
               win->begin_flip();
             }
             {
-              PStatGPUTimer timer(win->get_gsg(), GraphicsEngine::_flip_end_pcollector, current_thread);
+              PStatGPUTimer timer(gsg, GraphicsEngine::_flip_end_pcollector, current_thread);
               win->end_flip();
             }
           }

Неке датотеке нису приказане због велике количине промена