Sfoglia il codice sorgente

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

David Rose 9 anni fa
parent
commit
05d74624ee
100 ha cambiato i file con 2235 aggiunte e 2009 eliminazioni
  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
  * @date 2009-09-08
  */
  */
 
 
-#pragma warning (disable:4996)
-#pragma warning (disable:4005)
-#pragma warning(disable:4275)
-
 #ifndef _AIBEHAVIORS_H
 #ifndef _AIBEHAVIORS_H
 #define _AIBEHAVIORS_H
 #define _AIBEHAVIORS_H
 
 

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

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

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

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

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

@@ -11,11 +11,6 @@
  * @date 2009-09-08
  * @date 2009-09-08
  */
  */
 
 
-#pragma warning (disable:4996)
-#pragma warning (disable:4005)
-#pragma warning(disable:4275)
-
-
 #ifndef _AIWORLD_H
 #ifndef _AIWORLD_H
 #define _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();
   CPT(BoundingSphere) np_sphere = np_bounds->as_bounding_sphere();
   LVecBase3 avoidance(0.0, 0.0, 0.0);
   LVecBase3 avoidance(0.0, 0.0, 0.0);
   double distance = 0x7fff ;
   double distance = 0x7fff ;
-  double expanded_radius;
+  double expanded_radius = 0;
   LVecBase3 to_obstacle;
   LVecBase3 to_obstacle;
   LVecBase3 prev_avoidance;
   LVecBase3 prev_avoidance;
   for(unsigned int i = 0; i < _ai_char->_world->_obstacles.size(); ++i) {
   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();
   CPT(BoundingSphere) bsphere = bounds->as_bounding_sphere();
   PT(BoundingVolume) np_bounds = _ai_char->get_node_path().get_bounds();
   PT(BoundingVolume) np_bounds = _ai_char->get_node_path().get_bounds();
   CPT(BoundingSphere) np_sphere = np_bounds->as_bounding_sphere();
   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());
     LVecBase3 direction = _ai_char->get_char_render().get_relative_vector(_ai_char->get_node_path(), LVector3::forward());
     direction.normalize();
     direction.normalize();
     float forward_component = offset.dot(direction);
     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.showbase.InputStateGlobal import inputState
 from direct.task.Task import Task
 from direct.task.Task import Task
-from pandac.PandaModules import *
+from panda3d.core import *
 from . import GravityWalker
 from . import GravityWalker
 
 
 BattleStrafe = 0
 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.controls.ControlManager import CollisionHandlerRayStart
 from direct.showbase.InputStateGlobal import inputState
 from direct.showbase.InputStateGlobal import inputState
 from direct.task.Task import Task
 from direct.task.Task import Task
-from pandac.PandaModules import *
+from panda3d.core import *
 
 
 class NonPhysicsWalker(DirectObject.DirectObject):
 class NonPhysicsWalker(DirectObject.DirectObject):
     notify = DirectNotifyGlobal.directNotify.newCategory("NonPhysicsWalker")
     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
  * parameter type accepts an arbitrary (or possibly fixed) number of nested
  * fields, all of which are of the same type.
  * fields, all of which are of the same type.
  */
  */
-class EXPCL_DIRECT DCArrayParameter : public DCParameter {
+class DCArrayParameter : public DCParameter {
 public:
 public:
   DCArrayParameter(DCParameter *element_type,
   DCArrayParameter(DCParameter *element_type,
                    const DCUnsignedIntRange &size = DCUnsignedIntRange());
                    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
  * This defines an interface to the Distributed Class, and is always
  * implemented as a remote procedure method.
  * implemented as a remote procedure method.
  */
  */
-class EXPCL_DIRECT DCAtomicField : public DCField {
+class DCAtomicField : public DCField {
 public:
 public:
   DCAtomicField(const string &name, DCClass *dclass, bool bogus_field);
   DCAtomicField(const string &name, DCClass *dclass, bool bogus_field);
   virtual ~DCAtomicField();
   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.
  * Defines a particular DistributedClass as read from an input .dc file.
  */
  */
-class EXPCL_DIRECT DCClass : public DCDeclaration {
+class DCClass : public DCDeclaration {
 public:
 public:
   DCClass(DCFile *dc_file, const string &name,
   DCClass(DCFile *dc_file, const string &name,
           bool is_struct, bool bogus_class);
           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 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.
  * 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:
 public:
   DCClassParameter(const DCClass *dclass);
   DCClassParameter(const DCClass *dclass);
   DCClassParameter(const DCClassParameter &copy);
   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
  * only purpose is so that classes and typedefs can be stored in one list
  * together so they can be ordered correctly on output.
  * together so they can be ordered correctly on output.
  */
  */
-class EXPCL_DIRECT DCDeclaration {
+class DCDeclaration {
 public:
 public:
   virtual ~DCDeclaration();
   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.
  * 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:
 public:
   DCField();
   DCField();
   DCField(const string &name, DCClass *dclass);
   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
  * Represents the complete list of Distributed Class descriptions as read from
  * a .dc file.
  * a .dc file.
  */
  */
-class EXPCL_DIRECT DCFile {
+class DCFile {
 PUBLISHED:
 PUBLISHED:
   DCFile();
   DCFile();
   ~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
  * define a communication property associated with a field, for instance
  * "broadcast" or "airecv".
  * "broadcast" or "airecv".
  */
  */
-class EXPCL_DIRECT DCKeyword : public DCDeclaration {
+class DCKeyword : public DCDeclaration {
 public:
 public:
   DCKeyword(const string &name, int historical_flag = ~0);
   DCKeyword(const string &name, int historical_flag = ~0);
   virtual ~DCKeyword();
   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
  * This is a list of keywords (see DCKeyword) that may be set on a particular
  * field.
  * field.
  */
  */
-class EXPCL_DIRECT DCKeywordList {
+class DCKeywordList {
 public:
 public:
   DCKeywordList();
   DCKeywordList();
   DCKeywordList(const DCKeywordList &copy);
   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
  * This represents a combination of two or more related atomic fields, that
  * will often be treated as a unit.
  * will often be treated as a unit.
  */
  */
-class EXPCL_DIRECT DCMolecularField : public DCField {
+class DCMolecularField : public DCField {
 public:
 public:
   DCMolecularField(const string &name, DCClass *dclass);
   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.
  * This is a block of data that receives the results of DCPacker.
  */
  */
-class EXPCL_DIRECT DCPackData {
+class DCPackData {
 PUBLISHED:
 PUBLISHED:
   INLINE DCPackData();
   INLINE DCPackData();
   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
  * See also direct/src/doc/dcPacker.txt for a more complete description and
  * examples of using this class.
  * examples of using this class.
  */
  */
-class EXPCL_DIRECT DCPacker {
+class DCPacker {
 PUBLISHED:
 PUBLISHED:
   DCPacker();
   DCPacker();
   ~DCPacker();
   ~DCPacker();
@@ -216,7 +216,7 @@ private:
   const DCPackerCatalog *_catalog;
   const DCPackerCatalog *_catalog;
   const DCPackerCatalog::LiveCatalog *_live_catalog;
   const DCPackerCatalog::LiveCatalog *_live_catalog;
 
 
-  class EXPCL_DIRECT StackElement {
+  class StackElement {
   public:
   public:
     // As an optimization, we implement operator new and delete here to
     // As an optimization, we implement operator new and delete here to
     // minimize allocation overhead during push() and pop().
     // 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
  * requested from a particular field; its ownership is retained by the field
  * so it must not be deleted.
  * so it must not be deleted.
  */
  */
-class EXPCL_DIRECT DCPackerCatalog {
+class DCPackerCatalog {
 private:
 private:
   DCPackerCatalog(const DCPackerInterface *root);
   DCPackerCatalog(const DCPackerInterface *root);
   DCPackerCatalog(const DCPackerCatalog &copy);
   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
  * Normally these methods are called only by the DCPacker object; the user
  * wouldn't normally call these directly.
  * wouldn't normally call these directly.
  */
  */
-class EXPCL_DIRECT DCPackerInterface {
+class DCPackerInterface {
 public:
 public:
   DCPackerInterface(const string &name = string());
   DCPackerInterface(const string &name = string());
   DCPackerInterface(const DCPackerInterface &copy);
   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
  * This may also be a typedef reference to another type, which has the same
  * properties as the referenced type, but a different name.
  * properties as the referenced type, but a different name.
  */
  */
-class EXPCL_DIRECT DCParameter : public DCField {
+class DCParameter : public DCField {
 protected:
 protected:
   DCParameter();
   DCParameter();
   DCParameter(const DCParameter &copy);
   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
  * divisor, which is meaningful only for the numeric type elements (and
  * represents a fixed-point numeric convention).
  * represents a fixed-point numeric convention).
  */
  */
-class EXPCL_DIRECT DCSimpleParameter : public DCParameter {
+class DCSimpleParameter : public DCParameter {
 public:
 public:
   DCSimpleParameter(DCSubatomicType type, unsigned int divisor = 1);
   DCSimpleParameter(DCSubatomicType type, unsigned int divisor = 1);
   DCSimpleParameter(const DCSimpleParameter &copy);
   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
  * and represents two or more alternative unpacking schemes based on the first
  * field read.
  * field read.
  */
  */
-class EXPCL_DIRECT DCSwitch : public DCDeclaration {
+class DCSwitch : public DCDeclaration {
 public:
 public:
   DCSwitch(const string &name, DCField *key_parameter);
   DCSwitch(const string &name, DCField *key_parameter);
   virtual ~DCSwitch();
   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
  * This represents a switch object used as a parameter itself, which packs the
  * appropriate fields of the switch into the message.
  * appropriate fields of the switch into the message.
  */
  */
-class EXPCL_DIRECT DCSwitchParameter : public DCParameter {
+class DCSwitchParameter : public DCParameter {
 public:
 public:
   DCSwitchParameter(const DCSwitch *dswitch);
   DCSwitchParameter(const DCSwitch *dswitch);
   DCSwitchParameter(const DCSwitchParameter &copy);
   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
  * This represents a single typedef declaration in the dc file.  It assigns a
  * particular type to a new name, just like a C typedef.
  * particular type to a new name, just like a C typedef.
  */
  */
-class EXPCL_DIRECT DCTypedef : public DCDeclaration {
+class DCTypedef : public DCDeclaration {
 public:
 public:
   DCTypedef(DCParameter *parameter, bool implicit = false);
   DCTypedef(DCParameter *parameter, bool implicit = false);
   DCTypedef(const string &name);
   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
 # Utility functions that are useful to both AI and client CartesianGrid code
 
 
 class CartesianGridBase:
 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 .MsgTypes import *
 from direct.task import Task
 from direct.task import Task
 from direct.directnotify import DirectNotifyGlobal
 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.task import Task
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.distributed.DoInterestManager import DoInterestManager
 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.fsm.FSM import FSM
 from direct.interval.IntervalGlobal import *
 from direct.interval.IntervalGlobal import *
 from direct.distributed.DistributedObject import DistributedObject
 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
 from direct.distributed.DistributedObjectOV import DistributedObjectOV
 
 
 class DistributedCameraOV(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.interval.IntervalGlobal import *
 from direct.directnotify.DirectNotifyGlobal import directNotify
 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.directnotify.DirectNotifyGlobal import directNotify
 from direct.task import Task
 from direct.task import Task
 from .DistributedNodeAI import DistributedNodeAI
 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 DistributedObjectAI
 from . import GridParent
 from . import GridParent
 
 

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

@@ -35,9 +35,9 @@ class DistributedObjectGlobalUD(DistributedObjectUD):
     def __execMessage(self, message):
     def __execMessage(self, message):
         if not self.ExecNamespace:
         if not self.ExecNamespace:
             # Import some useful variables into the ExecNamespace initially.
             # 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('__'):
                 if not key.startswith('__'):
                     self.ExecNamespace[key] = value
                     self.ExecNamespace[key] = value
             #self.importExecNamespace()
             #self.importExecNamespace()

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

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

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

@@ -1,6 +1,7 @@
 """DistributedSmoothNode module: contains the DistributedSmoothNode class"""
 """DistributedSmoothNode module: contains the DistributedSmoothNode class"""
 
 
-from pandac.PandaModules import *
+from panda3d.core import *
+from panda3d.direct import *
 from .ClockDelta import *
 from .ClockDelta import *
 from . import DistributedNode
 from . import DistributedNode
 from . import DistributedSmoothNodeBase
 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.
 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 .MsgTypes import *
 from direct.showbase.PythonUtil import *
 from direct.showbase.PythonUtil import *
 from direct.showbase import DirectObject
 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
 # GridParent.py

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

@@ -1,6 +1,7 @@
 """ServerRepository module: contains the ServerRepository class"""
 """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.distributed.MsgTypesCMU import *
 from direct.task import Task
 from direct.task import Task
 from direct.directnotify import DirectNotifyGlobal
 from direct.directnotify import DirectNotifyGlobal

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

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

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

@@ -1,5 +1,5 @@
 from direct.distributed.ClockDelta import *
 from direct.distributed.ClockDelta import *
-from pandac.PandaModules import *
+from panda3d.core import *
 from direct.distributed import DistributedObjectAI
 from direct.distributed import DistributedObjectAI
 
 
 class TimeManagerAI(DistributedObjectAI.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
 #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
 #endif
 
 
 #ifdef HAVE_NET
 #ifdef HAVE_NET

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

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

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

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

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

@@ -278,6 +278,15 @@ class BufferViewer(DirectObject):
         self.analyzeTextureSet(self.exclude, exclude)
         self.analyzeTextureSet(self.exclude, exclude)
         self.analyzeTextureSet(self.include, include)
         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.
         # Generate a list of cards and the corresponding windows.
         cards = []
         cards = []
         wins = []
         wins = []
@@ -290,7 +299,7 @@ class BufferViewer(DirectObject):
                         for face in range(6):
                         for face in range(6):
                             self.cardmaker.setUvRangeCube(face)
                             self.cardmaker.setUvRangeCube(face)
                             card = NodePath(self.cardmaker.generate())
                             card = NodePath(self.cardmaker.generate())
-                            card.setTexture(tex)
+                            card.setTexture(tex, sampler)
                             cards.append(card)
                             cards.append(card)
                     elif (tex.getTextureType() == Texture.TT2dTextureArray):
                     elif (tex.getTextureType() == Texture.TT2dTextureArray):
                         for layer in range(tex.getZSize()):
                         for layer in range(tex.getZSize()):
@@ -301,11 +310,11 @@ class BufferViewer(DirectObject):
                             # the fixed-function pipeline, so we need to
                             # the fixed-function pipeline, so we need to
                             # enable the shader generator to view them.
                             # enable the shader generator to view them.
                             card.setShaderAuto()
                             card.setShaderAuto()
-                            card.setTexture(tex)
+                            card.setTexture(tex, sampler)
                             cards.append(card)
                             cards.append(card)
                     else:
                     else:
                         card = win.getTextureCard()
                         card = win.getTextureCard()
-                        card.setTexture(tex)
+                        card.setTexture(tex, sampler)
                         cards.append(card)
                         cards.append(card)
                     wins.append(win)
                     wins.append(win)
                     exclude[tex] = 1
                     exclude[tex] = 1

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

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

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

@@ -1,6 +1,6 @@
 # objects that report different types of leaks to the ContainerLeakDetector
 # 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.DirectObject import DirectObject
 from direct.showbase.Job import Job
 from direct.showbase.Job import Job
 import gc, sys
 import gc, sys

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

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

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

@@ -984,7 +984,10 @@ class Freezer:
             try:
             try:
                 self.__loadModule(mdef)
                 self.__loadModule(mdef)
             except ImportError as ex:
             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
         # Also attempt to import any implicit modules.  If any of
         # these fail to import, we don't really care.
         # 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)
             name = 'PythonThread-%s' % (threadId)
 
 
         thread = core.PythonThread(threadFunc, [threadId], name, name)
         thread = core.PythonThread(threadFunc, [threadId], name, name)
-        thread.setPythonData(threadId)
+        thread.setPythonIndex(threadId)
         _threads[threadId] = (thread, {}, None)
         _threads[threadId] = (thread, {}, None)
 
 
         thread.start(core.TPNormal, False)
         thread.start(core.TPNormal, False)
@@ -121,7 +121,7 @@ def _add_thread(thread, wrapper):
         threadId = _nextThreadId
         threadId = _nextThreadId
         _nextThreadId += 1
         _nextThreadId += 1
 
 
-        thread.setPythonData(threadId)
+        thread.setPythonIndex(threadId)
         _threads[threadId] = (thread, {}, wrapper)
         _threads[threadId] = (thread, {}, wrapper)
         return threadId
         return threadId
 
 
@@ -133,8 +133,8 @@ def _get_thread_wrapper(thread, wrapperClass):
     is not one, creates an instance of the indicated wrapperClass
     is not one, creates an instance of the indicated wrapperClass
     instead. """
     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.
         # The thread has never been assigned a threadId.  Go assign one.
 
 
         global _nextThreadId
         global _nextThreadId
@@ -143,7 +143,7 @@ def _get_thread_wrapper(thread, wrapperClass):
             threadId = _nextThreadId
             threadId = _nextThreadId
             _nextThreadId += 1
             _nextThreadId += 1
 
 
-            thread.setPythonData(threadId)
+            thread.setPythonIndex(threadId)
             wrapper = wrapperClass(thread, threadId)
             wrapper = wrapperClass(thread, threadId)
             _threads[threadId] = (thread, {}, wrapper)
             _threads[threadId] = (thread, {}, wrapper)
             return wrapper
             return wrapper
@@ -169,8 +169,8 @@ def _get_thread_locals(thread, i):
     """ Returns the locals dictionary for the indicated thread.  If
     """ Returns the locals dictionary for the indicated thread.  If
     there is not one, creates an empty dictionary. """
     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.
         # The thread has never been assigned a threadId.  Go assign one.
 
 
         global _nextThreadId
         global _nextThreadId
@@ -179,7 +179,7 @@ def _get_thread_locals(thread, i):
             threadId = _nextThreadId
             threadId = _nextThreadId
             _nextThreadId += 1
             _nextThreadId += 1
 
 
-            thread.setPythonData(threadId)
+            thread.setPythonIndex(threadId)
             locals = {}
             locals = {}
             _threads[threadId] = (thread, locals, None)
             _threads[threadId] = (thread, locals, None)
             return locals.setdefault(i, {})
             return locals.setdefault(i, {})
@@ -205,9 +205,9 @@ def _remove_thread_id(threadId):
     _threadsLock.acquire()
     _threadsLock.acquire()
     try:
     try:
         thread, locals, wrapper = _threads[threadId]
         thread, locals, wrapper = _threads[threadId]
-        assert thread.getPythonData() == threadId
+        assert thread.getPythonIndex() == threadId
         del _threads[threadId]
         del _threads[threadId]
-        thread.setPythonData(None)
+        thread.setPythonIndex(-1)
 
 
     finally:
     finally:
         _threadsLock.release()
         _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  ------------------------
 ------------------------  RELEASE 1.9.2  ------------------------
 
 
 This is a minor bugfix release, fixing a few minor issues that
 This is a minor bugfix release, fixing a few minor issues that

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


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

@@ -783,6 +783,11 @@ storage_class:
         empty
         empty
 {
 {
   $$ = 0;
   $$ = 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
         | KW_EXTERN storage_class
 {
 {
@@ -861,10 +866,22 @@ attribute_specifier:
         ;
         ;
 
 
 type_like_declaration:
 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 ';'
         | storage_class type_decl ';'
 {
 {
   // We don't really care about the storage class here.  In fact, it's
   // We don't really care about the storage class here.  In fact, it's
@@ -891,39 +908,6 @@ type_like_declaration:
   }
   }
 }
 }
         | using_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
         /* We don't need to include a rule for variables that point to
            functions, because we get those from the function_prototype
            functions, because we get those from the function_prototype
@@ -933,6 +917,9 @@ multiple_var_declaration:
 multiple_instance_identifiers:
 multiple_instance_identifiers:
         instance_identifier_and_maybe_trailing_return_type maybe_initialize_or_function_body
         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,
   CPPInstance *inst = new CPPInstance(current_type, $1,
                                       current_storage_class,
                                       current_storage_class,
                                       @1.file);
                                       @1.file);
@@ -941,27 +928,9 @@ multiple_instance_identifiers:
 }
 }
         | instance_identifier_and_maybe_trailing_return_type maybe_initialize ',' 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,
   CPPInstance *inst = new CPPInstance(current_type, $1,
                                       current_storage_class,
                                       current_storage_class,
                                       @1.file);
                                       @1.file);
@@ -986,21 +955,6 @@ typedef_declaration:
         typedef_instance_identifiers
         typedef_instance_identifiers
 {
 {
   pop_storage_class();
   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
         | storage_class function_prototype maybe_initialize_or_function_body
 {
 {
@@ -1019,29 +973,18 @@ typedef_declaration:
 typedef_instance_identifiers:
 typedef_instance_identifiers:
         instance_identifier_and_maybe_trailing_return_type maybe_initialize_or_function_body
         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;
   CPPType *target_type = current_type;
   CPPTypedefType *typedef_type = new CPPTypedefType(target_type, $1, current_scope, @1.file);
   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);
   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
         | 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;
   CPPType *target_type = current_type;
   CPPTypedefType *typedef_type = new CPPTypedefType(target_type, $1, current_scope, @1.file);
   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);
   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 "dtoolbase.h"
 
 
+#include "cppBisonDefs.h"
 #include "cppExtensionType.h"
 #include "cppExtensionType.h"
 
 
 #include <vector>
 #include <vector>

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

@@ -64,6 +64,10 @@ public:
     SC_deleted      = 0x8000,
     SC_deleted      = 0x8000,
 
 
     SC_thread_local = 0x10000,
     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);
   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?
       // Is this identifier one of our parameters?
       int pnum = -1;
       int pnum = -1;
-      bool va_args = false;
 
 
       if (ident == "__VA_ARGS__") {
       if (ident == "__VA_ARGS__") {
-        va_args = true;
         // C99-style variadics, ie.  #define macro(...) __VA_ARGS__
         // C99-style variadics, ie.  #define macro(...) __VA_ARGS__
         pnum = _variadic_param;
         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);
           Manifests::const_iterator mi = _manifests.find(ident);
           if (mi != _manifests.end()) {
           if (mi != _manifests.end()) {
             const CPPManifest *manifest = (*mi).second;
             const CPPManifest *manifest = (*mi).second;
-            expand_manifest_inline(expr, q, p, (*mi).second);
+            expand_manifest_inline(expr, q, p, manifest);
             manifest_found = true;
             manifest_found = true;
 
 
           } else if (expand_undefined && ident != "true" && ident != "false") {
           } else if (expand_undefined && ident != "true" && ident != "false") {
@@ -1192,8 +1192,6 @@ skip_c_comment(int c) {
 
 
   } else {
   } else {
     CPPFile first_file = get_file();
     CPPFile first_file = get_file();
-    int first_line_number = get_line_number();
-    int first_col_number = get_col_number() - 2;
 
 
     while (c != EOF) {
     while (c != EOF) {
       if (c == '*') {
       if (c == '*') {
@@ -1816,8 +1814,9 @@ get_identifier(int c) {
       type = CPPExpression::T_u16string;
       type = CPPExpression::T_u16string;
     } else if (name == "U") {
     } else if (name == "U") {
       type = CPPExpression::T_u32string;
       type = CPPExpression::T_u32string;
+    } else {
+      type = CPPExpression::T_string;
     }
     }
-
     get();
     get();
     string str = scan_quoted(c);
     string str = scan_quoted(c);
 
 

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

@@ -18,6 +18,7 @@
 #include "cppTypedefType.h"
 #include "cppTypedefType.h"
 #include "cppTypeDeclaration.h"
 #include "cppTypeDeclaration.h"
 #include "cppExtensionType.h"
 #include "cppExtensionType.h"
+#include "cppEnumType.h"
 #include "cppInstance.h"
 #include "cppInstance.h"
 #include "cppInstanceIdentifier.h"
 #include "cppInstanceIdentifier.h"
 #include "cppIdentifier.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::
 CPPToken(int token, const YYLTYPE &loc, const string &str, const YYSTYPE &val) :
 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;
   _lval.str = str;
 }
 }

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

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

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

@@ -70,23 +70,25 @@
 #else
 #else
 // #pragma message("VC 6.0")
 // #pragma message("VC 6.0")
 #endif
 #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
 // 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.
 // 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')
 // 'assume at least one of the cases is always true')
 #ifdef _DEBUG
 #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
 #else
-# define NODEFAULT  default: __assume(0);   // special VC keyword
+#define NODEFAULT
 #endif
 #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
   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;
   TypeHandle handle;
   if (n >= 0 && n < (int)_root_classes.size()) {
   if (n >= 0 && n < (int)_root_classes.size()) {
     handle = _root_classes[n]->_handle;
     handle = _root_classes[n]->_handle;
+  } else {
+    handle = TypeHandle::none();
   }
   }
   _lock->release();
   _lock->release();
 
 
@@ -380,6 +382,8 @@ get_parent_class(TypeHandle child, int index) const {
   assert(rnode != (TypeRegistryNode *)NULL);
   assert(rnode != (TypeRegistryNode *)NULL);
   if (index >= 0 && index < (int)rnode->_parent_classes.size()) {
   if (index >= 0 && index < (int)rnode->_parent_classes.size()) {
     handle = rnode->_parent_classes[index]->_handle;
     handle = rnode->_parent_classes[index]->_handle;
+  } else {
+    handle = TypeHandle::none();
   }
   }
   _lock->release();
   _lock->release();
   return handle;
   return handle;
@@ -415,6 +419,8 @@ get_child_class(TypeHandle child, int index) const {
   assert(rnode != (TypeRegistryNode *)NULL);
   assert(rnode != (TypeRegistryNode *)NULL);
   if (index >= 0 && index < (int)rnode->_child_classes.size()) {
   if (index >= 0 && index < (int)rnode->_child_classes.size()) {
     handle = rnode->_child_classes[index]->_handle;
     handle = rnode->_child_classes[index]->_handle;
+  } else {
+    handle = TypeHandle::none();
   }
   }
   _lock->release();
   _lock->release();
   return handle;
   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.
     // generate a 6-character hex code.
     int hash = (clock() * time(NULL)) & 0xffffff;
     int hash = (clock() * time(NULL)) & 0xffffff;
     char hex_code[10];
     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 = Filename(fdirname, Filename(prefix + hex_code + suffix));
     result.set_type(type);
     result.set_type(type);
   } while (result.exists());
   } 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.
       // Posix case.
       {
       {
         off_t li = lseek(_fd, off, SEEK_END);
         off_t li = lseek(_fd, off, SEEK_END);
-        if (li == (size_t)-1) {
+        if (li == (off_t)-1) {
           return -1;
           return -1;
         }
         }
         new_pos = (size_t)li;
         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) &&
       if (is_cpp_type_legal(object->_itype._cpptype) &&
           isExportThisRun(object->_itype._cpptype)) {
           isExportThisRun(object->_itype._cpptype)) {
         string class_name = make_safe_name(object->_itype.get_scoped_name());
         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 (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 = "
           out << "  Dtool_" << class_name << "._type = "
               << object->_itype._cpptype->get_local_name(&parser)
               << object->_itype._cpptype->get_local_name(&parser)
               << "::get_class_type();\n"
               << "::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 class_name = (*ii)->get_local_name(&parser);
     string safe_name = make_safe_name(class_name);
     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";
       out << "  Dtool_Ptr_" << safe_name << " = LookupRuntimeTypedClass(" << class_name << "::get_class_type());\n";
     } else {
     } else {
       out << "  Dtool_Ptr_" << safe_name << " = LookupNamedClass(\"" << class_name << "\");\n";
       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);
   std::string export_class_name = classNameFromCppName(obj->_itype.get_name(), false);
 
 
   bool is_runtime_typed = IsPandaTypedObject(obj->_itype._cpptype->as_struct_type());
   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;
     is_runtime_typed = true;
   }
   }
 
 
@@ -4196,7 +4203,7 @@ write_function_forset(ostream &out,
     return;
     return;
   }
   }
 
 
-  FunctionRemap *remap;
+  FunctionRemap *remap = NULL;
   std::set<FunctionRemap *>::iterator sii;
   std::set<FunctionRemap *>::iterator sii;
 
 
   bool all_nonconst = false;
   bool all_nonconst = false;
@@ -7010,7 +7017,7 @@ DoesInheritFromIsClass(const CPPStructType *inclass, const std::string &name) {
 
 
  */
  */
 bool InterfaceMakerPythonNative::
 bool InterfaceMakerPythonNative::
-HasAGetClassTypeFunction(CPPType *type) {
+has_get_class_type_function(CPPType *type) {
   while (type->get_subtype() == CPPDeclaration::ST_typedef) {
   while (type->get_subtype() == CPPDeclaration::ST_typedef) {
     type = type->as_typedef_type()->_type;
     type = type->as_typedef_type()->_type;
   }
   }
@@ -7025,6 +7032,43 @@ HasAGetClassTypeFunction(CPPType *type) {
   return scope->_functions.find("get_class_type") != scope->_functions.end();
   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
  * Returns -1 if the class does not define write() (and therefore cannot
  * support a __str__ function).
  * 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 DoesInheritFromIsClass(const CPPStructType * inclass, const std::string &name);
   bool IsPandaTypedObject(CPPStructType * inclass) { return DoesInheritFromIsClass(inclass,"TypedObject"); };
   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);
   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 NeedsAStrFunction(const InterrogateType &itype_class);
   int NeedsAReprFunction(const InterrogateType &itype_class);
   int NeedsAReprFunction(const InterrogateType &itype_class);
   bool NeedsARichCompareFunction(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 "pnotify.h"
 #include "panda_getopt_long.h"
 #include "panda_getopt_long.h"
 #include "preprocess_argv.h"
 #include "preprocess_argv.h"
-#include "pystub.h"
 #include <time.h>
 #include <time.h>
 
 
 CPPParser parser;
 CPPParser parser;
@@ -306,9 +305,6 @@ predefine_macro(CPPParser& parser, const string& inoption) {
 
 
 int
 int
 main(int argc, char **argv) {
 main(int argc, char **argv) {
-  // A call to pystub() to force libpystub.so to be linked in.
-  pystub();
-
   preprocess_argv(argc, argv);
   preprocess_argv(argc, argv);
   string command_line;
   string command_line;
   int i;
   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.
       // 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 this is a sequence getter, it must take an index argument.
         if (is_seq && !TypeManager::is_integer(ftype->_parameters->_parameters[0]->_type)) {
         if (is_seq && !TypeManager::is_integer(ftype->_parameters->_parameters[0]->_type)) {
           continue;
           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) {
     for (fi = fgroup->_instances.begin(); fi != fgroup->_instances.end(); ++fi) {
       CPPInstance *function = (*fi);
       CPPInstance *function = (*fi);
       CPPFunctionType *ftype = function->_type->as_function_type();
       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;
         deleter = function;
         break;
         break;
       }
       }

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

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

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

@@ -41,7 +41,7 @@ resolve_type(CPPType *type, CPPScope *scope) {
     scope = &parser;
     scope = &parser;
   }
   }
 
 
-  CPPType *orig_type = type;
+  //CPPType *orig_type = type;
   type = type->resolve_type(scope, &parser);
   type = type->resolve_type(scope, &parser);
   string name = type->get_local_name(&parser);
   string name = type->get_local_name(&parser);
   if (name.empty()) {
   if (name.empty()) {
@@ -1740,7 +1740,8 @@ is_Py_buffer(CPPType *type) {
 
 
   case CPPDeclaration::ST_extension:
   case CPPDeclaration::ST_extension:
   case CPPDeclaration::ST_struct:
   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:
   case CPPDeclaration::ST_typedef:
     return is_Py_buffer(type->as_typedef_type()->_type);
     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.
  * extended should create a specialization of this class template.
  */
  */
 template<class T>
 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) {
 interrogate_request_database(const char *database_filename) {
   InterrogateModuleDef *def = new InterrogateModuleDef;
   InterrogateModuleDef *def = new InterrogateModuleDef;
   memset(def, 0, sizeof(InterrogateModuleDef));
   memset(def, 0, sizeof(InterrogateModuleDef));
+#ifdef _WIN32
+  def->database_filename = _strdup(database_filename);
+#else
   def->database_filename = strdup(database_filename);
   def->database_filename = strdup(database_filename);
+#endif
 
 
   // Don't think of this as a leak; think of it as a one-time database
   // Don't think of this as a leak; think of it as a one-time database
   // allocation.
   // 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) {
 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);
   return PyLong_FromUnsignedLongLong(value);
+#else
+  return (value > LONG_MAX)
+    ? PyLong_FromUnsignedLongLong(value)
+    : PyInt_FromLong((long)value);
+#endif
 }
 }
 
 
 ALWAYS_INLINE PyObject *Dtool_WrapValue(bool value) {
 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.
  * was of the wrong type, raises an AttributeError.
  */
  */
 bool Dtool_Call_ExtractThisPointer(PyObject *self, Dtool_PyTypedObject &classdef, void **answer) {
 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.");
     Dtool_Raise_TypeError("C++ object is not yet constructed, or already destructed.");
     return false;
     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,
 bool Dtool_Call_ExtractThisPointer_NonConst(PyObject *self, Dtool_PyTypedObject &classdef,
                                             void **answer, const char *method_name) {
                                             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.");
     Dtool_Raise_TypeError("C++ object is not yet constructed, or already destructed.");
     return false;
     return false;
   }
   }
@@ -816,6 +816,7 @@ PyObject *DTOOL_PyObject_RichCompare(PyObject *v1, PyObject *v2, int op) {
   int cmpval = DTOOL_PyObject_Compare(v1, v2);
   int cmpval = DTOOL_PyObject_Compare(v1, v2);
   bool result;
   bool result;
   switch (op) {
   switch (op) {
+  NODEFAULT
   case Py_LT:
   case Py_LT:
     result = (cmpval < 0);
     result = (cmpval < 0);
     break;
     break;
@@ -833,6 +834,7 @@ PyObject *DTOOL_PyObject_RichCompare(PyObject *v1, PyObject *v2, int op) {
     break;
     break;
   case Py_GE:
   case Py_GE:
     result = (cmpval >= 0);
     result = (cmpval >= 0);
+    break;
   }
   }
   return PyBool_FromLong(result);
   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
 // 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..
 // Delete functions..
 #ifdef NDEBUG
 #ifdef NDEBUG

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

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

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

@@ -19,16 +19,28 @@
  */
  */
 void ConfigVariableFilename::
 void ConfigVariableFilename::
 reload_cache() {
 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 {
 get_value() const {
   TAU_PROFILE("const string &ConfigVariableString::get_value() const", " ", TAU_USER);
   TAU_PROFILE("const string &ConfigVariableString::get_value() const", " ", TAU_USER);
   if (!is_cache_valid(_local_modified)) {
   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;
   return _cache;
 }
 }

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

@@ -12,3 +12,24 @@
  */
  */
 
 
 #include "configVariableString.h"
 #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 string get_word(size_t n) const;
   INLINE void set_word(size_t n, const string &value);
   INLINE void set_word(size_t n, const string &value);
 
 
+private:
+  void reload_cache();
+
 private:
 private:
   AtomicAdjust::Integer _local_modified;
   AtomicAdjust::Integer _local_modified;
   string _cache;
   string _cache;

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

@@ -74,10 +74,15 @@ out(NotifySeverity severity, bool prefix) const {
       if (get_notify_timestamp()) {
       if (get_notify_timestamp()) {
         // Format a timestamp to include as a prefix as well.
         // Format a timestamp to include as a prefix as well.
         time_t now = time(NULL) + _server_delta;
         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];
         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;
         nout << buffer;
       }
       }
 
 

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

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

File diff suppressed because it is too large
+ 134 - 127
makepanda/makepanda.py


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

@@ -13,7 +13,6 @@
 
 
 #include "pandaFramework.h"
 #include "pandaFramework.h"
 #include "pandaSystem.h"
 #include "pandaSystem.h"
-#include "pystub.h"
 #include "texturePool.h"
 #include "texturePool.h"
 #include "multitexReducer.h"
 #include "multitexReducer.h"
 #include "sceneGraphReducer.h"
 #include "sceneGraphReducer.h"
@@ -29,9 +28,6 @@
 #include "checkPandaVersion.h"
 #include "checkPandaVersion.h"
 
 
 int main(int argc, char **argv) {
 int main(int argc, char **argv) {
-  // A call to pystub() to force libpystub.so to be linked in.
-  pystub();
-
   PandaFramework framework;
   PandaFramework framework;
   framework.open_framework(argc, argv);
   framework.open_framework(argc, argv);
   framework.set_window_title("Panda Viewer");
   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::
 void AudioManager::
 register_AudioManager_creator(Create_AudioManager_proc* proc) {
 register_AudioManager_creator(Create_AudioManager_proc* proc) {
-  nassertv(_create_AudioManager == NULL);
+  nassertv(_create_AudioManager == NULL || _create_AudioManager == proc);
   _create_AudioManager = proc;
   _create_AudioManager = proc;
 }
 }
 
 
@@ -71,7 +71,7 @@ PT(AudioManager) AudioManager::create_AudioManager() {
       if (handle == (void *)NULL) {
       if (handle == (void *)NULL) {
         audio_error("  load_dso(" << dl_name << ") failed, will use NullAudioManager");
         audio_error("  load_dso(" << dl_name << ") failed, will use NullAudioManager");
         audio_error("    "<<load_dso_error());
         audio_error("    "<<load_dso_error());
-        nassertr(_create_AudioManager == create_NullAudioManager, NULL);
+        nassertr(_create_AudioManager == NULL, NULL);
       } else {
       } else {
         // Get the special function from the dso, which should return the
         // Get the special function from the dso, which should return the
         // AudioManager factory function.
         // 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;
   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"
 #include "animChannelFixed.I"
 
 

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

@@ -3,6 +3,7 @@
 #include "animBundleNode.cxx"
 #include "animBundleNode.cxx"
 #include "animChannel.cxx"
 #include "animChannel.cxx"
 #include "animChannelBase.cxx"
 #include "animChannelBase.cxx"
+#include "animChannelFixed.cxx"
 #include "animChannelMatrixDynamic.cxx"
 #include "animChannelMatrixDynamic.cxx"
 #include "animChannelMatrixFixed.cxx"
 #include "animChannelMatrixFixed.cxx"
 #include "animChannelMatrixXfmTable.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
   // around this, we will force-recompute all of the bounding volumes of our
   // parent nodes immediately.
   // parent nodes immediately.
   Parents parents = get_parents();
   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);
     PandaNode *parent = parents.get_parent(i);
     parent->get_bounds();
     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
   // 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
   // Extract the renderer ID bits and check if our renderer matches the known
   // software renderers.
   // software renderers.
   renderer_id &= kCGLRendererIDMatchingMask;
   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 "
           "geometry is always paged in immediately when needed, holding up "
           "the frame render if necessary."));
           "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
 ConfigVariableInt win_size
 ("win-size", "800 600",
 ("win-size", "800 600",
  PRC_DESC("This is the default size at which to open a new window.  This "
  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 color_scale_via_lighting;
 extern EXPCL_PANDA_DISPLAY ConfigVariableBool alpha_scale_via_texture;
 extern EXPCL_PANDA_DISPLAY ConfigVariableBool alpha_scale_via_texture;
 extern EXPCL_PANDA_DISPLAY ConfigVariableBool allow_incomplete_render;
 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_size;
 extern EXPCL_PANDA_DISPLAY ConfigVariableInt win_origin;
 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];
   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[0] = int((region._dimensions[0] * x_size) + 0.5);
   region._pixels[1] = int((region._dimensions[1] * x_size) + 0.5);
   region._pixels[1] = int((region._dimensions[1] * x_size) + 0.5);
   region._pixels_i[0] = region._pixels[0];
   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_failed_pcollector("Occlusion results:Occluded");
 PStatCollector GraphicsEngine::_occlusion_tests_pcollector("Occlusion tests");
 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
  * Creates a new GraphicsEngine object.  The Pipeline is normally left to
  * default to NULL, which indicates the global render pipeline, but it may be
  * 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.
   // And, hey, let's stop the vertex paging threads, if any.
   VertexDataPage::stop_threads();
   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();
   AsyncTaskManager::get_global_ptr()->stop_threads();
 
 
 #ifdef DO_PSTATS
 #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
   // Keep track of the cameras we have already used in this thread to render
   // DisplayRegions.
   // DisplayRegions.
-  typedef pair<NodePath, int> CullKey;
   typedef pmap<CullKey, DisplayRegion *> AlreadyCulled;
   typedef pmap<CullKey, DisplayRegion *> AlreadyCulled;
   AlreadyCulled already_culled;
   AlreadyCulled already_culled;
 
 
@@ -1387,10 +1406,13 @@ cull_to_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
         if (dr != (DisplayRegion *)NULL) {
         if (dr != (DisplayRegion *)NULL) {
           DisplayRegionPipelineReader *dr_reader =
           DisplayRegionPipelineReader *dr_reader =
             new DisplayRegionPipelineReader(dr, current_thread);
             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) {
           if ((*aci).second == NULL) {
             // We have not used this camera already in this thread.  Perform
             // We have not used this camera already in this thread.  Perform
             // the cull operation.
             // 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
         // We have to place this collector inside begin_frame, because we need
         // a current context for PStatGPUTimer to work.
         // 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);
           win->clear(current_thread);
 
 
           if (display_cat.is_spam()) {
           if (display_cat.is_spam()) {
@@ -1525,8 +1547,8 @@ draw_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
         if (_auto_flip) {
         if (_auto_flip) {
 #ifdef DO_PSTATS
 #ifdef DO_PSTATS
           // This is a good time to perform a latency query.
           // 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
 #endif
 
 
@@ -1538,7 +1560,7 @@ draw_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) {
               win->begin_flip();
               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();
               win->end_flip();
             }
             }
           }
           }

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