Browse Source

Merge branch 'master' into deploy-ng

rdb 7 years ago
parent
commit
b0cece7faf
100 changed files with 398 additions and 266 deletions
  1. 12 10
      README.md
  2. 2 0
      direct/src/dcparser/dcSimpleParameter.cxx
  3. 0 6
      direct/src/dcparser/dcbase.h
  4. 4 0
      direct/src/deadrec/config_deadrec.cxx
  5. 2 2
      direct/src/deadrec/config_deadrec.h
  6. 1 1
      direct/src/deadrec/smoothMover.h
  7. 54 4
      direct/src/directbase/directsymbols.h
  8. 4 0
      direct/src/directd/directd.cxx
  9. 1 1
      direct/src/directd/directd.h
  10. 1 1
      direct/src/distributed/ConnectionRepository.py
  11. 1 1
      direct/src/distributed/ServerRepository.py
  12. 4 2
      direct/src/distributed/cConnectionRepository.cxx
  13. 1 1
      direct/src/distributed/cConnectionRepository.h
  14. 1 1
      direct/src/distributed/cDistributedSmoothNodeBase.h
  15. 4 0
      direct/src/distributed/config_distributed.cxx
  16. 2 2
      direct/src/distributed/config_distributed.h
  17. 6 0
      direct/src/gui/DirectEntry.py
  18. 1 1
      direct/src/interval/cConstrainHprInterval.h
  19. 1 1
      direct/src/interval/cConstrainPosHprInterval.h
  20. 1 1
      direct/src/interval/cConstrainPosInterval.h
  21. 1 1
      direct/src/interval/cConstrainTransformInterval.h
  22. 1 1
      direct/src/interval/cConstraintInterval.h
  23. 2 2
      direct/src/interval/cInterval.h
  24. 1 1
      direct/src/interval/cIntervalManager.h
  25. 1 1
      direct/src/interval/cLerpAnimEffectInterval.h
  26. 1 1
      direct/src/interval/cLerpInterval.h
  27. 1 1
      direct/src/interval/cLerpNodePathInterval.h
  28. 1 1
      direct/src/interval/cMetaInterval.h
  29. 4 0
      direct/src/interval/config_interval.cxx
  30. 3 3
      direct/src/interval/config_interval.h
  31. 1 1
      direct/src/interval/hideInterval.h
  32. 5 5
      direct/src/interval/lerpblend.h
  33. 1 1
      direct/src/interval/showInterval.h
  34. 1 1
      direct/src/interval/waitInterval.h
  35. 1 1
      direct/src/motiontrail/cMotionTrail.h
  36. 5 1
      direct/src/motiontrail/config_motiontrail.cxx
  37. 2 2
      direct/src/motiontrail/config_motiontrail.h
  38. 4 0
      direct/src/showbase/showBase.cxx
  39. 11 11
      direct/src/showbase/showBase.h
  40. 4 0
      dtool/src/dconfig/config_dconfig.cxx
  41. 2 2
      dtool/src/dconfig/config_dconfig.h
  42. 1 1
      dtool/src/dconfig/dconfig.h
  43. 1 1
      dtool/src/dtoolbase/addHash.h
  44. 1 1
      dtool/src/dtoolbase/atomicAdjustDummyImpl.h
  45. 1 1
      dtool/src/dtoolbase/atomicAdjustGccImpl.h
  46. 1 1
      dtool/src/dtoolbase/atomicAdjustI386Impl.h
  47. 1 1
      dtool/src/dtoolbase/atomicAdjustPosixImpl.h
  48. 1 1
      dtool/src/dtoolbase/atomicAdjustWin32Impl.h
  49. 1 1
      dtool/src/dtoolbase/deletedBufferChain.h
  50. 4 0
      dtool/src/dtoolbase/dtoolbase.cxx
  51. 7 7
      dtool/src/dtoolbase/dtoolbase_cc.h
  52. 36 9
      dtool/src/dtoolbase/dtoolsymbols.h
  53. 1 1
      dtool/src/dtoolbase/indent.h
  54. 1 1
      dtool/src/dtoolbase/lookup3.h
  55. 1 1
      dtool/src/dtoolbase/memoryBase.h
  56. 1 1
      dtool/src/dtoolbase/memoryHook.h
  57. 1 1
      dtool/src/dtoolbase/mutexDummyImpl.h
  58. 2 2
      dtool/src/dtoolbase/mutexPosixImpl.h
  59. 1 1
      dtool/src/dtoolbase/mutexSpinlockImpl.h
  60. 1 1
      dtool/src/dtoolbase/mutexWin32Impl.h
  61. 1 1
      dtool/src/dtoolbase/neverFreeMemory.h
  62. 1 1
      dtool/src/dtoolbase/pdtoa.h
  63. 2 2
      dtool/src/dtoolbase/pstrtod.h
  64. 15 0
      dtool/src/dtoolbase/pvector.h
  65. 19 19
      dtool/src/dtoolbase/register_type.h
  66. 2 2
      dtool/src/dtoolbase/typeHandle.h
  67. 2 2
      dtool/src/dtoolbase/typeRegistry.h
  68. 1 1
      dtool/src/dtoolbase/typeRegistryNode.h
  69. 1 1
      dtool/src/dtoolbase/typedObject.h
  70. 4 0
      dtool/src/dtoolutil/config_dtoolutil.cxx
  71. 2 2
      dtool/src/dtoolutil/dSearchPath.h
  72. 1 1
      dtool/src/dtoolutil/executionEnvironment.h
  73. 1 1
      dtool/src/dtoolutil/filename.h
  74. 1 1
      dtool/src/dtoolutil/globPattern.h
  75. 1 1
      dtool/src/dtoolutil/lineStream.h
  76. 1 1
      dtool/src/dtoolutil/lineStreamBuf.h
  77. 4 4
      dtool/src/dtoolutil/load_dso.h
  78. 3 3
      dtool/src/dtoolutil/pandaFileStream.h
  79. 3 3
      dtool/src/dtoolutil/pandaFileStreamBuf.h
  80. 1 1
      dtool/src/dtoolutil/pandaSystem.h
  81. 5 5
      dtool/src/dtoolutil/panda_getopt_impl.h
  82. 2 2
      dtool/src/dtoolutil/pfstream.h
  83. 1 1
      dtool/src/dtoolutil/pfstreamBuf.h
  84. 1 1
      dtool/src/dtoolutil/preprocess_argv.h
  85. 1 1
      dtool/src/dtoolutil/stringDecoder.h
  86. 20 20
      dtool/src/dtoolutil/string_utils.h
  87. 4 4
      dtool/src/dtoolutil/textEncoder.h
  88. 1 1
      dtool/src/dtoolutil/unicodeLatinMap.h
  89. 2 7
      dtool/src/dtoolutil/vector_double.cxx
  90. 2 7
      dtool/src/dtoolutil/vector_double.h
  91. 2 7
      dtool/src/dtoolutil/vector_float.cxx
  92. 2 7
      dtool/src/dtoolutil/vector_float.h
  93. 2 7
      dtool/src/dtoolutil/vector_int.cxx
  94. 2 7
      dtool/src/dtoolutil/vector_int.h
  95. 2 7
      dtool/src/dtoolutil/vector_string.cxx
  96. 2 7
      dtool/src/dtoolutil/vector_string.h
  97. 2 7
      dtool/src/dtoolutil/vector_uchar.cxx
  98. 2 7
      dtool/src/dtoolutil/vector_uchar.h
  99. 1 1
      dtool/src/dtoolutil/win32ArgParser.h
  100. 56 8
      dtool/src/interrogate/interfaceMakerPythonNative.cxx

+ 12 - 10
README.md

@@ -43,24 +43,26 @@ Building Panda3D
 Windows
 -------
 
-We currently build using the Microsoft Visual C++ 2010 compiler.  You do not
-need Microsoft Visual Studio to build Panda3D, though - the relevant compilers
-are included as part of the Windows 7.1 SDK.
+We currently build using the Microsoft Visual C++ 2015 compiler.  You will
+also need to install the [Windows 10 SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk),
+and if you intend to target Windows XP, you will also need the
+[Windows 7.1 SDK](https://www.microsoft.com/en-us/download/details.aspx?id=8279).
 
 You will also need to have the third-party dependency libraries available for
 the build scripts to use.  These are available from one of these two URLs,
-depending on whether you are on a 32-bit or 64-bit system:
-https://www.panda3d.org/download/panda3d-1.9.4/panda3d-1.9.4-tools-win32.zip
-https://www.panda3d.org/download/panda3d-1.9.4/panda3d-1.9.4-tools-win64.zip
+depending on whether you are on a 32-bit or 64-bit system, or you can
+[click here](https://github.com/rdb/panda3d-thirdparty) for instructions on
+building them from source.
 
-(It is also possible to build using MSVC 2015 and 2017, which requires a
-different set of thirdparty libraries, but that is not described here.)
+http://rdb.name/thirdparty-vc14-x64.7z
+http://rdb.name/thirdparty-vc14.7z
 
 After acquiring these dependencies, you may simply build Panda3D from the
-command prompt using the following command:
+command prompt using the following command.  (Add the `--windows-sdk=10`
+option if you don't need to support Windows XP.)
 
 ```bash
-makepanda\makepanda.bat --everything --installer --no-eigen
+makepanda\makepanda.bat --everything --installer --no-eigen --threads=2
 ```
 
 When the build succeeds, it will produce an .exe file that you can use to

+ 2 - 0
direct/src/dcparser/dcSimpleParameter.cxx

@@ -2238,6 +2238,8 @@ output_instance(ostream &out, bool brief, const string &prename,
       }
       break;
 
+    case ST_blob:
+    case ST_blob32:
     case ST_string:
       if (!_uint_range.is_empty()) {
         out << "(";

+ 0 - 6
direct/src/dcparser/dcbase.h

@@ -80,12 +80,6 @@ using namespace std;
 #define nassertv(condition) assert(condition)
 #define nassertv_always(condition) assert(condition)
 
-// Panda defines these export symbols for building DLL's.  Outside of Panda,
-// we assume we're not putting this code in a DLL, so we define them to
-// nothing.
-#define EXPCL_DIRECT
-#define EXPTP_DIRECT
-
 // Panda defines a special Filename class.  We'll use an ordinary string
 // instead.
 typedef string Filename;

+ 4 - 0
direct/src/deadrec/config_deadrec.cxx

@@ -15,6 +15,10 @@
 
 #include "dconfig.h"
 
+#if !defined(CPPPARSER) && !defined(BUILDING_DIRECT_DEADREC)
+  #error Buildsystem error: BUILDING_DIRECT_DEADREC not defined
+#endif
+
 Configure(config_deadrec);
 NotifyCategoryDef(deadrec, "");
 

+ 2 - 2
direct/src/deadrec/config_deadrec.h

@@ -18,10 +18,10 @@
 #include "notifyCategoryProxy.h"
 #include "configVariableBool.h"
 
-NotifyCategoryDecl(deadrec, EXPCL_DIRECT, EXPTP_DIRECT);
+NotifyCategoryDecl(deadrec, EXPCL_DIRECT_DEADREC, EXPTP_DIRECT_DEADREC);
 
 extern ConfigVariableBool accept_clock_skew;
 
-extern EXPCL_DIRECT void init_libdeadrec();
+extern EXPCL_DIRECT_DEADREC void init_libdeadrec();
 
 #endif

+ 1 - 1
direct/src/deadrec/smoothMover.h

@@ -38,7 +38,7 @@ static const int max_timestamp_delays = 10;
  * update.  The assumption is that all SmoothMovers in the world will be
  * operating in the same mode together.
  */
-class EXPCL_DIRECT SmoothMover {
+class EXPCL_DIRECT_DEADREC SmoothMover {
 PUBLISHED:
   SmoothMover();
   ~SmoothMover();

+ 54 - 4
direct/src/directbase/directsymbols.h

@@ -16,12 +16,62 @@
 
 /* See dtoolsymbols.h for a rant on the purpose of this file.  */
 
+/* BUILDING_DIRECT is just a buildsystem shortcut for all of these: */
 #ifdef BUILDING_DIRECT
-  #define EXPCL_DIRECT EXPORT_CLASS
-  #define EXPTP_DIRECT EXPORT_TEMPL
+  #define BUILDING_DIRECT_DEADREC
+  #define BUILDING_DIRECT_DIRECTD
+  #define BUILDING_DIRECT_INTERVAL
+  #define BUILDING_DIRECT_MOTIONTRAIL
+  #define BUILDING_DIRECT_SHOWBASE
+  #define BUILDING_DIRECT_DISTRIBUTED
+#endif
+
+#ifdef BUILDING_DIRECT_DEADREC
+  #define EXPCL_DIRECT_DEADREC EXPORT_CLASS
+  #define EXPTP_DIRECT_DEADREC EXPORT_TEMPL
+#else
+  #define EXPCL_DIRECT_DEADREC IMPORT_CLASS
+  #define EXPTP_DIRECT_DEADREC IMPORT_TEMPL
+#endif
+
+#ifdef BUILDING_DIRECT_DIRECTD
+  #define EXPCL_DIRECT_DIRECTD EXPORT_CLASS
+  #define EXPTP_DIRECT_DIRECTD EXPORT_TEMPL
+#else
+  #define EXPCL_DIRECT_DIRECTD IMPORT_CLASS
+  #define EXPTP_DIRECT_DIRECTD IMPORT_TEMPL
+#endif
+
+#ifdef BUILDING_DIRECT_INTERVAL
+  #define EXPCL_DIRECT_INTERVAL EXPORT_CLASS
+  #define EXPTP_DIRECT_INTERVAL EXPORT_TEMPL
+#else
+  #define EXPCL_DIRECT_INTERVAL IMPORT_CLASS
+  #define EXPTP_DIRECT_INTERVAL IMPORT_TEMPL
+#endif
+
+#ifdef BUILDING_DIRECT_MOTIONTRAIL
+  #define EXPCL_DIRECT_MOTIONTRAIL EXPORT_CLASS
+  #define EXPTP_DIRECT_MOTIONTRAIL EXPORT_TEMPL
+#else
+  #define EXPCL_DIRECT_MOTIONTRAIL IMPORT_CLASS
+  #define EXPTP_DIRECT_MOTIONTRAIL IMPORT_TEMPL
+#endif
+
+#ifdef BUILDING_DIRECT_SHOWBASE
+  #define EXPCL_DIRECT_SHOWBASE EXPORT_CLASS
+  #define EXPTP_DIRECT_SHOWBASE EXPORT_TEMPL
+#else
+  #define EXPCL_DIRECT_SHOWBASE IMPORT_CLASS
+  #define EXPTP_DIRECT_SHOWBASE IMPORT_TEMPL
+#endif
+
+#ifdef BUILDING_DIRECT_DISTRIBUTED
+  #define EXPCL_DIRECT_DISTRIBUTED EXPORT_CLASS
+  #define EXPTP_DIRECT_DISTRIBUTED EXPORT_TEMPL
 #else
-  #define EXPCL_DIRECT IMPORT_CLASS
-  #define EXPTP_DIRECT IMPORT_TEMPL
+  #define EXPCL_DIRECT_DISTRIBUTED IMPORT_CLASS
+  #define EXPTP_DIRECT_DISTRIBUTED IMPORT_TEMPL
 #endif
 
 #endif

+ 4 - 0
direct/src/directd/directd.cxx

@@ -30,6 +30,10 @@
 
 #include "pset.h"
 
+#if !defined(CPPPARSER) && !defined(BUILDING_DIRECT_DIRECTD)
+  #error Buildsystem error: BUILDING_DIRECT_DIRECTD not defined
+#endif
+
 namespace {
   // ...This section is part of the old stuff from the original
   // implementation.  The new stuff that uses job objects doesn't need this

+ 1 - 1
direct/src/directd/directd.h

@@ -52,7 +52,7 @@ typedef int HANDLE;
  * presented in order chronologically by their intended usage.  The first
  * group will probably provide everthing needed for DirectD.
  */
-class EXPCL_DIRECT DirectD {
+class EXPCL_DIRECT_DIRECTD DirectD {
 PUBLISHED:
   DirectD();
   ~DirectD();

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

@@ -333,7 +333,7 @@ class ConnectionRepository(
                         continue
                     classDef = getattr(classDef, className)
 
-                if inspect.isclass(classDef):
+                if not inspect.isclass(classDef):
                     self.notify.error("Symbol %s is not a class name." % (className))
                 else:
                     dclass.setClassDef(classDef)

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

@@ -280,7 +280,7 @@ class ServerRepository:
                         self.notify.error("Module %s does not define class %s." % (className, className))
                     classDef = getattr(classDef, className)
 
-                if inspect.isclass(classDef):
+                if not inspect.isclass(classDef):
                     self.notify.error("Symbol %s is not a class name." % (className))
                 else:
                     dclass.setClassDef(classDef)

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

@@ -803,8 +803,9 @@ handle_update_field_owner() {
       Py_DECREF(dclass_this);
 
       // check if we should forward this update to the owner view
+      vector_uchar data = _di.get_remaining_bytes();
       DCPacker packer;
-      packer.set_unpack_data(_di.get_remaining_bytes());
+      packer.set_unpack_data((const char *)data.data(), data.size(), false);
       int field_id = packer.raw_unpack_uint16();
       DCField *field = dclass->get_field_by_index(field_id);
       if (field->is_ownrecv()) {
@@ -845,8 +846,9 @@ handle_update_field_owner() {
       Py_DECREF(dclass_this);
 
       // check if we should forward this update to the owner view
+      vector_uchar data = _di.get_remaining_bytes();
       DCPacker packer;
-      packer.set_unpack_data(_di.get_remaining_bytes());
+      packer.set_unpack_data((const char *)data.data(), data.size(), false);
       int field_id = packer.raw_unpack_uint16();
       DCField *field = dclass->get_field_by_index(field_id);
       if (true) {//field->is_broadcast()) {

+ 1 - 1
direct/src/distributed/cConnectionRepository.h

@@ -53,7 +53,7 @@ class SocketStream;
  * the C++ layer, while server messages that are not understood by the C++
  * layer are returned up to the Python layer for processing.
  */
-class EXPCL_DIRECT CConnectionRepository {
+class EXPCL_DIRECT_DISTRIBUTED CConnectionRepository {
 PUBLISHED:
   explicit CConnectionRepository(bool has_owner_view = false,
                                  bool threaded_net = false);

+ 1 - 1
direct/src/distributed/cDistributedSmoothNodeBase.h

@@ -28,7 +28,7 @@ class CConnectionRepository;
  * This class defines some basic methods of DistributedSmoothNodeBase which
  * have been moved into C++ as a performance optimization.
  */
-class EXPCL_DIRECT CDistributedSmoothNodeBase {
+class EXPCL_DIRECT_DISTRIBUTED CDistributedSmoothNodeBase {
 PUBLISHED:
   CDistributedSmoothNodeBase();
   ~CDistributedSmoothNodeBase();

+ 4 - 0
direct/src/distributed/config_distributed.cxx

@@ -14,6 +14,10 @@
 #include "config_distributed.h"
 #include "dconfig.h"
 
+#if !defined(CPPPARSER) && !defined(BUILDING_DIRECT_DISTRIBUTED)
+  #error Buildsystem error: BUILDING_DIRECT_DISTRIBUTED not defined
+#endif
+
 Configure(config_distributed);
 NotifyCategoryDef(distributed, "");
 

+ 2 - 2
direct/src/distributed/config_distributed.h

@@ -21,13 +21,13 @@
 #include "configVariableDouble.h"
 #include "configVariableBool.h"
 
-NotifyCategoryDecl(distributed, EXPCL_DIRECT, EXPTP_DIRECT);
+NotifyCategoryDecl(distributed, EXPCL_DIRECT_DISTRIBUTED, EXPTP_DIRECT_DISTRIBUTED);
 
 extern ConfigVariableInt game_server_timeout_ms;
 extern ConfigVariableDouble min_lag;
 extern ConfigVariableDouble max_lag;
 extern ConfigVariableBool handle_datagrams_internally;
 
-extern EXPCL_DIRECT void init_libdistributed();
+extern EXPCL_DIRECT_DISTRIBUTED void init_libdistributed();
 
 #endif

+ 6 - 0
direct/src/gui/DirectEntry.py

@@ -302,12 +302,18 @@ class DirectEntry(DirectFrame):
             else:
                 return self.guiItem.getText()
 
+    def getCursorPosition(self):
+        return self.guiItem.getCursorPosition()
+
     def setCursorPosition(self, pos):
         if (pos < 0):
             self.guiItem.setCursorPosition(self.guiItem.getNumCharacters() + pos)
         else:
             self.guiItem.setCursorPosition(pos)
 
+    def getNumCharacters(self):
+        return self.guiItem.getNumCharacters()
+
     def enterText(self, text):
         """ sets the entry's text, and moves the cursor to the end """
         self.set(text)

+ 1 - 1
direct/src/interval/cConstrainHprInterval.h

@@ -24,7 +24,7 @@
  * A constraint interval that will constrain the orientation of one node to
  * the orientation of another.
  */
-class EXPCL_DIRECT CConstrainHprInterval : public CConstraintInterval {
+class EXPCL_DIRECT_INTERVAL CConstrainHprInterval : public CConstraintInterval {
 PUBLISHED:
   explicit CConstrainHprInterval(const string &name, double duration,
                                  const NodePath &node, const NodePath &target,

+ 1 - 1
direct/src/interval/cConstrainPosHprInterval.h

@@ -24,7 +24,7 @@
  * A constraint interval that will constrain the position and orientation of
  * one node to the position and orientation of another.
  */
-class EXPCL_DIRECT CConstrainPosHprInterval : public CConstraintInterval {
+class EXPCL_DIRECT_INTERVAL CConstrainPosHprInterval : public CConstraintInterval {
 PUBLISHED:
   explicit CConstrainPosHprInterval(const string &name, double duration,
                                     const NodePath &node, const NodePath &target,

+ 1 - 1
direct/src/interval/cConstrainPosInterval.h

@@ -23,7 +23,7 @@
  * A constraint interval that will constrain the position of one node to the
  * position of another.
  */
-class EXPCL_DIRECT CConstrainPosInterval : public CConstraintInterval {
+class EXPCL_DIRECT_INTERVAL CConstrainPosInterval : public CConstraintInterval {
 PUBLISHED:
   explicit CConstrainPosInterval(const string &name, double duration,
                                  const NodePath &node, const NodePath &target,

+ 1 - 1
direct/src/interval/cConstrainTransformInterval.h

@@ -22,7 +22,7 @@
  * A constraint interval that will constrain the transform of one node to the
  * transform of another.
  */
-class EXPCL_DIRECT CConstrainTransformInterval : public CConstraintInterval {
+class EXPCL_DIRECT_INTERVAL CConstrainTransformInterval : public CConstraintInterval {
 PUBLISHED:
   explicit CConstrainTransformInterval(const string &name, double duration,
                                        const NodePath &node,

+ 1 - 1
direct/src/interval/cConstraintInterval.h

@@ -21,7 +21,7 @@
  * The base class for a family of intervals that constrain some property to a
  * value over time.
  */
-class EXPCL_DIRECT CConstraintInterval : public CInterval {
+class EXPCL_DIRECT_INTERVAL CConstraintInterval : public CInterval {
 PUBLISHED:
  bool bogus_variable;
 

+ 2 - 2
direct/src/interval/cInterval.h

@@ -32,7 +32,7 @@ class CIntervalManager;
  * C++ will inherit from this class; Intervals that must be implemented in
  * Python will inherit from the similar Python class.
  */
-class EXPCL_DIRECT CInterval : public TypedReferenceCount {
+class EXPCL_DIRECT_INTERVAL CInterval : public TypedReferenceCount {
 public:
   CInterval(const string &name, double duration, bool open_ended);
   virtual ~CInterval();
@@ -202,7 +202,7 @@ private:
 };
 
 INLINE ostream &operator << (ostream &out, const CInterval &ival);
-EXPCL_DIRECT ostream &operator << (ostream &out, CInterval::State state);
+EXPCL_DIRECT_INTERVAL ostream &operator << (ostream &out, CInterval::State state);
 
 #include "cInterval.I"
 

+ 1 - 1
direct/src/interval/cIntervalManager.h

@@ -36,7 +36,7 @@ class EventQueue;
  * It is also possible to create multiple IntervalManager objects for special
  * needs.
  */
-class EXPCL_DIRECT CIntervalManager {
+class EXPCL_DIRECT_INTERVAL CIntervalManager {
 PUBLISHED:
   CIntervalManager();
   ~CIntervalManager();

+ 1 - 1
direct/src/interval/cLerpAnimEffectInterval.h

@@ -29,7 +29,7 @@
  * CLerpAnimEffectInterval to adjust the degree to which each animation
  * affects the actor.
  */
-class EXPCL_DIRECT CLerpAnimEffectInterval : public CLerpInterval {
+class EXPCL_DIRECT_INTERVAL CLerpAnimEffectInterval : public CLerpInterval {
 PUBLISHED:
   INLINE explicit CLerpAnimEffectInterval(const string &name, double duration,
                                           BlendType blend_type);

+ 1 - 1
direct/src/interval/cLerpInterval.h

@@ -21,7 +21,7 @@
  * The base class for a family of intervals that linearly interpolate one or
  * more numeric values over time.
  */
-class EXPCL_DIRECT CLerpInterval : public CInterval {
+class EXPCL_DIRECT_INTERVAL CLerpInterval : public CInterval {
 PUBLISHED:
   enum BlendType {
     BT_no_blend,

+ 1 - 1
direct/src/interval/cLerpNodePathInterval.h

@@ -23,7 +23,7 @@
  * An interval that lerps one or more properties (like pos, hpr, etc.) on a
  * NodePath over time.
  */
-class EXPCL_DIRECT CLerpNodePathInterval : public CLerpInterval {
+class EXPCL_DIRECT_INTERVAL CLerpNodePathInterval : public CLerpInterval {
 PUBLISHED:
   explicit CLerpNodePathInterval(const string &name, double duration,
                                  BlendType blend_type, bool bake_in_start,

+ 1 - 1
direct/src/interval/cMetaInterval.h

@@ -29,7 +29,7 @@
  * own begin and end times.  Some of them may overlap and some of them may
  * not.
  */
-class EXPCL_DIRECT CMetaInterval : public CInterval {
+class EXPCL_DIRECT_INTERVAL CMetaInterval : public CInterval {
 PUBLISHED:
   explicit CMetaInterval(const string &name);
   virtual ~CMetaInterval();

+ 4 - 0
direct/src/interval/config_interval.cxx

@@ -29,6 +29,10 @@
 
 #include "dconfig.h"
 
+#if !defined(CPPPARSER) && !defined(BUILDING_DIRECT_INTERVAL)
+  #error Buildsystem error: BUILDING_DIRECT_INTERVAL not defined
+#endif
+
 Configure(config_interval);
 NotifyCategoryDef(interval, "");
 

+ 3 - 3
direct/src/interval/config_interval.h

@@ -20,11 +20,11 @@
 #include "configVariableDouble.h"
 #include "configVariableBool.h"
 
-NotifyCategoryDecl(interval, EXPCL_DIRECT, EXPTP_DIRECT);
+NotifyCategoryDecl(interval, EXPCL_DIRECT_INTERVAL, EXPTP_DIRECT_INTERVAL);
 
 extern ConfigVariableDouble interval_precision;
-extern EXPCL_DIRECT ConfigVariableBool verify_intervals;
+extern EXPCL_DIRECT_INTERVAL ConfigVariableBool verify_intervals;
 
-extern EXPCL_DIRECT void init_libinterval();
+extern EXPCL_DIRECT_INTERVAL void init_libinterval();
 
 #endif

+ 1 - 1
direct/src/interval/hideInterval.h

@@ -21,7 +21,7 @@
 /**
  * An interval that calls NodePath::hide().
  */
-class EXPCL_DIRECT HideInterval : public CInterval {
+class EXPCL_DIRECT_INTERVAL HideInterval : public CInterval {
 PUBLISHED:
   explicit HideInterval(const NodePath &node, const string &name = string());
 

+ 5 - 5
direct/src/interval/lerpblend.h

@@ -17,7 +17,7 @@
 #include "directbase.h"
 #include "typedReferenceCount.h"
 
-class EXPCL_DIRECT LerpBlendType : public TypedReferenceCount {
+class EXPCL_DIRECT_INTERVAL LerpBlendType : public TypedReferenceCount {
 PUBLISHED:
   LerpBlendType() {}
   virtual ~LerpBlendType();
@@ -47,7 +47,7 @@ private:
   static TypeHandle _type_handle;
 };
 
-class EXPCL_DIRECT EaseInBlendType : public LerpBlendType {
+class EXPCL_DIRECT_INTERVAL EaseInBlendType : public LerpBlendType {
 PUBLISHED:
   EaseInBlendType() {}
   virtual ~EaseInBlendType();
@@ -77,7 +77,7 @@ private:
   static TypeHandle _type_handle;
 };
 
-class EXPCL_DIRECT EaseOutBlendType : public LerpBlendType {
+class EXPCL_DIRECT_INTERVAL EaseOutBlendType : public LerpBlendType {
 PUBLISHED:
   EaseOutBlendType() {}
   virtual ~EaseOutBlendType();
@@ -107,7 +107,7 @@ private:
   static TypeHandle _type_handle;
 };
 
-class EXPCL_DIRECT EaseInOutBlendType : public LerpBlendType {
+class EXPCL_DIRECT_INTERVAL EaseInOutBlendType : public LerpBlendType {
 PUBLISHED:
   EaseInOutBlendType() {}
   virtual ~EaseInOutBlendType();
@@ -136,7 +136,7 @@ private:
   static TypeHandle _type_handle;
 };
 
-class EXPCL_DIRECT NoBlendType : public LerpBlendType {
+class EXPCL_DIRECT_INTERVAL NoBlendType : public LerpBlendType {
 PUBLISHED:
   NoBlendType() {}
   virtual ~NoBlendType();

+ 1 - 1
direct/src/interval/showInterval.h

@@ -21,7 +21,7 @@
 /**
  * An interval that calls NodePath::show().
  */
-class EXPCL_DIRECT ShowInterval : public CInterval {
+class EXPCL_DIRECT_INTERVAL ShowInterval : public CInterval {
 PUBLISHED:
   explicit ShowInterval(const NodePath &node, const string &name = string());
 

+ 1 - 1
direct/src/interval/waitInterval.h

@@ -21,7 +21,7 @@
  * This interval does absolutely nothing, and is mainly useful for marking
  * time between other intervals within a sequence.
  */
-class EXPCL_DIRECT WaitInterval : public CInterval {
+class EXPCL_DIRECT_INTERVAL WaitInterval : public CInterval {
 PUBLISHED:
   INLINE explicit WaitInterval(double duration);
 

+ 1 - 1
direct/src/motiontrail/cMotionTrail.h

@@ -69,7 +69,7 @@ public:
  * coordinate of the texture corresponds to time and the v coordinate
  * corresponds to the "shape" of the motion trail.
  */
-class EXPCL_DIRECT CMotionTrail : public TypedReferenceCount {
+class EXPCL_DIRECT_MOTIONTRAIL CMotionTrail : public TypedReferenceCount {
 PUBLISHED:
   CMotionTrail();
   ~CMotionTrail();

+ 5 - 1
direct/src/motiontrail/config_motiontrail.cxx

@@ -14,7 +14,11 @@
 #include "config_motiontrail.h"
 #include "dconfig.h"
 
-extern EXPCL_DIRECT void init_libmotiontrail();
+#if !defined(CPPPARSER) && !defined(BUILDING_DIRECT_MOTIONTRAIL)
+  #error Buildsystem error: BUILDING_DIRECT_MOTIONTRAIL not defined
+#endif
+
+extern EXPCL_DIRECT_MOTIONTRAIL void init_libmotiontrail();
 
 Configure(config_motiontrail);
 NotifyCategoryDef(motiontrail, "");

+ 2 - 2
direct/src/motiontrail/config_motiontrail.h

@@ -20,8 +20,8 @@
 
 #include "cMotionTrail.h"
 
-NotifyCategoryDecl(motiontrail, EXPCL_DIRECT, EXPTP_DIRECT);
+NotifyCategoryDecl(motiontrail, EXPCL_DIRECT_MOTIONTRAIL, EXPTP_DIRECT_MOTIONTRAIL);
 
-extern EXPCL_DIRECT void init_libmotiontrail();
+extern EXPCL_DIRECT_MOTIONTRAIL void init_libmotiontrail();
 
 #endif

+ 4 - 0
direct/src/showbase/showBase.cxx

@@ -34,6 +34,10 @@ TOGGLEKEYS g_StartupToggleKeys = {sizeof(TOGGLEKEYS), 0};
 FILTERKEYS g_StartupFilterKeys = {sizeof(FILTERKEYS), 0};
 #endif
 
+#if !defined(CPPPARSER) && !defined(BUILDING_DIRECT_SHOWBASE)
+  #error Buildsystem error: BUILDING_DIRECT_SHOWBASE not defined
+#endif
+
 ConfigureDef(config_showbase);
 ConfigureFn(config_showbase) {
 }

+ 11 - 11
direct/src/showbase/showBase.h

@@ -26,7 +26,7 @@
 #include "configVariableSearchPath.h"
 #include "nodePath.h"
 
-ConfigureDecl(config_showbase, EXPCL_DIRECT, EXPTP_DIRECT);
+ConfigureDecl(config_showbase, EXPCL_DIRECT_SHOWBASE, EXPTP_DIRECT_SHOWBASE);
 
 class CollisionTraverser;
 class Camera;
@@ -34,24 +34,24 @@ class GraphicsEngine;
 
 BEGIN_PUBLISH
 
-EXPCL_DIRECT ConfigVariableSearchPath &get_particle_path();
+EXPCL_DIRECT_SHOWBASE ConfigVariableSearchPath &get_particle_path();
 
-EXPCL_DIRECT void throw_new_frame();
+EXPCL_DIRECT_SHOWBASE void throw_new_frame();
 
-EXPCL_DIRECT DConfig &get_config_showbase();
-EXPCL_DIRECT void init_app_for_gui();
+EXPCL_DIRECT_SHOWBASE DConfig &get_config_showbase();
+EXPCL_DIRECT_SHOWBASE void init_app_for_gui();
 
 // klunky interface since we cant pass array from python->C++
-EXPCL_DIRECT void add_fullscreen_testsize(int xsize, int ysize);
-EXPCL_DIRECT void runtest_fullscreen_sizes(GraphicsWindow *win);
-EXPCL_DIRECT bool query_fullscreen_testresult(int xsize, int ysize);
+EXPCL_DIRECT_SHOWBASE void add_fullscreen_testsize(int xsize, int ysize);
+EXPCL_DIRECT_SHOWBASE void runtest_fullscreen_sizes(GraphicsWindow *win);
+EXPCL_DIRECT_SHOWBASE bool query_fullscreen_testresult(int xsize, int ysize);
 
 // to handle windows stickykeys
-EXPCL_DIRECT void store_accessibility_shortcut_keys();
-EXPCL_DIRECT void allow_accessibility_shortcut_keys(bool allowKeys);
+EXPCL_DIRECT_SHOWBASE void store_accessibility_shortcut_keys();
+EXPCL_DIRECT_SHOWBASE void allow_accessibility_shortcut_keys(bool allowKeys);
 
 #ifdef IS_OSX
-EXPCL_DIRECT void activate_osx_application();
+EXPCL_DIRECT_SHOWBASE void activate_osx_application();
 #endif
 
 END_PUBLISH

+ 4 - 0
dtool/src/dconfig/config_dconfig.cxx

@@ -13,5 +13,9 @@
 
 #include "config_dconfig.h"
 
+#if !defined(CPPPARSER) && !defined(BUILDING_DTOOL_DCONFIG)
+  #error Buildsystem error: BUILDING_DTOOL_DCONFIG not defined
+#endif
+
 NotifyCategoryDef(dconfig, "");
 NotifyCategoryDef(microconfig, "dconfig");

+ 2 - 2
dtool/src/dconfig/config_dconfig.h

@@ -23,7 +23,7 @@
 #include "dtoolbase.h"
 #include "notifyCategoryProxy.h"
 
-NotifyCategoryDecl(dconfig, EXPCL_DTOOLCONFIG, EXPTP_DTOOLCONFIG);
-NotifyCategoryDecl(microconfig, EXPCL_DTOOLCONFIG, EXPTP_DTOOLCONFIG);
+NotifyCategoryDecl(dconfig, EXPCL_DTOOL_DCONFIG, EXPTP_DTOOL_DCONFIG);
+NotifyCategoryDecl(microconfig, EXPCL_DTOOL_DCONFIG, EXPTP_DTOOL_DCONFIG);
 
 #endif

+ 1 - 1
dtool/src/dconfig/dconfig.h

@@ -30,7 +30,7 @@
  * used primarily by Python code.  For modern code, use the new
  * ConfigVariable* interface instead of this deprecated interface.
  */
-class EXPCL_DTOOLCONFIG DConfig {
+class EXPCL_DTOOL_DCONFIG DConfig {
 PUBLISHED:
   static INLINE bool GetBool(const string &sym, bool def = false);
   static INLINE int GetInt(const string &sym, int def = 0);

+ 1 - 1
dtool/src/dtoolbase/addHash.h

@@ -23,7 +23,7 @@
  * of static functions, which are used to wrap calls to Bob Jenkins' public-
  * domain hash generation function (defined in lookup3.c).
  */
-class EXPCL_DTOOL AddHash {
+class EXPCL_DTOOL_DTOOLBASE AddHash {
 public:
   INLINE static size_t add_hash(size_t start, const uint32_t *words, size_t num_words);
   static size_t add_hash(size_t start, const uint8_t *bytes, size_t num_bytes);

+ 1 - 1
dtool/src/dtoolbase/atomicAdjustDummyImpl.h

@@ -24,7 +24,7 @@
  * require multiprogramming, and therefore don't require special atomic
  * operations.
  */
-class EXPCL_DTOOL AtomicAdjustDummyImpl {
+class EXPCL_DTOOL_DTOOLBASE AtomicAdjustDummyImpl {
 public:
   typedef long Integer;
   typedef void *Pointer;

+ 1 - 1
dtool/src/dtoolbase/atomicAdjustGccImpl.h

@@ -22,7 +22,7 @@
 /**
  * Uses GCC built-ins to implement atomic adjustments.
  */
-class EXPCL_DTOOL AtomicAdjustGccImpl {
+class EXPCL_DTOOL_DTOOLBASE AtomicAdjustGccImpl {
 public:
 #if __GCC_ATOMIC_LONG_LOCK_FREE >= __GCC_ATOMIC_INT_LOCK_FREE
   // If the long can be more lock-free than int, use it instead.

+ 1 - 1
dtool/src/dtoolbase/atomicAdjustI386Impl.h

@@ -26,7 +26,7 @@
  * Although this class is named i386, it actually uses instructions that are
  * specific to 486 and higher.
  */
-class EXPCL_DTOOL AtomicAdjustI386Impl {
+class EXPCL_DTOOL_DTOOLBASE AtomicAdjustI386Impl {
 public:
   typedef ALIGN_4BYTE int32_t Integer;
   typedef void *UnalignedPointer;

+ 1 - 1
dtool/src/dtoolbase/atomicAdjustPosixImpl.h

@@ -26,7 +26,7 @@
 /**
  * Uses POSIX to implement atomic adjustments.
  */
-class EXPCL_DTOOL AtomicAdjustPosixImpl {
+class EXPCL_DTOOL_DTOOLBASE AtomicAdjustPosixImpl {
 public:
   // In Posix, "long" is generally the native word size (32- or 64-bit), which
   // is what we'd prefer.

+ 1 - 1
dtool/src/dtoolbase/atomicAdjustWin32Impl.h

@@ -29,7 +29,7 @@
 /**
  * Uses Windows native calls to implement atomic adjustments.
  */
-class EXPCL_DTOOL AtomicAdjustWin32Impl {
+class EXPCL_DTOOL_DTOOLBASE AtomicAdjustWin32Impl {
 public:
 #ifdef _WIN64
   // For 64-bit builds, we'd prefer to use a 64-bit integer.

+ 1 - 1
dtool/src/dtoolbase/deletedBufferChain.h

@@ -55,7 +55,7 @@ enum DeletedChainFlag {
  *
  * Use MemoryHook to get a new DeletedBufferChain of a particular size.
  */
-class EXPCL_DTOOL DeletedBufferChain {
+class EXPCL_DTOOL_DTOOLBASE DeletedBufferChain {
 protected:
   DeletedBufferChain(size_t buffer_size);
 

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

@@ -14,6 +14,10 @@
 #include "dtoolbase.h"
 #include "memoryHook.h"
 
+#if !defined(CPPPARSER) && !defined(BUILDING_DTOOL_DTOOLBASE)
+  #error Buildsystem error: BUILDING_DTOOL_DTOOLBASE not defined
+#endif
+
 #if defined(USE_TAU) && defined(WIN32)
 // Hack around tau's lack of DLL export declarations for Profiler class.
 bool __tau_shutdown = false;

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

@@ -257,7 +257,7 @@ template<class T> typename remove_reference<T>::type &&move(T &&t) {
 #endif
 
 
-#if !defined(LINK_ALL_STATIC) && defined(EXPORT_TEMPLATES)
+#ifndef LINK_ALL_STATIC
 // This macro must be used to export an instantiated template class from a
 // DLL.  If the template class name itself contains commas, it may be
 // necessary to first define a macro for the class name, to allow proper macro
@@ -282,8 +282,8 @@ class ReferenceCount;
 // We need a pointer to a global MemoryHook object, to manage all malloc and
 // free requests from Panda.  See the comments in MemoryHook itself.
 class MemoryHook;
-EXPCL_DTOOL extern MemoryHook *memory_hook;
-EXPCL_DTOOL void init_memory_hook();
+EXPCL_DTOOL_DTOOLBASE extern MemoryHook *memory_hook;
+EXPCL_DTOOL_DTOOLBASE void init_memory_hook();
 
 // Now redefine some handy macros to hook into the above MemoryHook object.
 #ifndef USE_MEMORY_NOWRAPPERS
@@ -303,8 +303,8 @@ EXPCL_DTOOL void init_memory_hook();
 #if defined(HAVE_THREADS) && defined(SIMPLE_THREADS)
 // We need another forward-reference function to allow low-level code to
 // cooperatively yield the timeslice, in SIMPLE_THREADS mode.
-extern EXPCL_DTOOL void (*global_thread_yield)();
-extern EXPCL_DTOOL void (*global_thread_consider_yield)();
+extern EXPCL_DTOOL_DTOOLBASE void (*global_thread_yield)();
+extern EXPCL_DTOOL_DTOOLBASE void (*global_thread_consider_yield)();
 
 INLINE void thread_yield() {
   (*global_thread_yield)();
@@ -324,8 +324,8 @@ INLINE void thread_consider_yield() {
 
 #if defined(USE_TAU) && defined(WIN32)
 // Hack around tau's lack of DLL export declarations for Profiler class.
-extern EXPCL_DTOOL bool __tau_shutdown;
-class EXPCL_DTOOL TauProfile {
+extern EXPCL_DTOOL_DTOOLBASE bool __tau_shutdown;
+class EXPCL_DTOOL_DTOOLBASE TauProfile {
 public:
   TauProfile(void *&tautimer, char *name, char *type, int group, char *group_name) {
     Tau_profile_c_timer(&tautimer, name, type, group, group_name);

+ 36 - 9
dtool/src/dtoolbase/dtoolsymbols.h

@@ -68,19 +68,45 @@
   */
 
 #ifdef BUILDING_DTOOL
-  #define EXPCL_DTOOL EXPORT_CLASS
-  #define EXPTP_DTOOL EXPORT_TEMPL
-#else
-  #define EXPCL_DTOOL IMPORT_CLASS
-  #define EXPTP_DTOOL IMPORT_TEMPL
+  #define BUILDING_DTOOL_DTOOLBASE
+  #define BUILDING_DTOOL_DTOOLUTIL
 #endif
 
 #ifdef BUILDING_DTOOLCONFIG
-  #define EXPCL_DTOOLCONFIG EXPORT_CLASS
-  #define EXPTP_DTOOLCONFIG EXPORT_TEMPL
+  #define BUILDING_DTOOL_PRC
+  #define BUILDING_DTOOL_DCONFIG
+#endif
+
+#ifdef BUILDING_DTOOL_DTOOLBASE
+  #define EXPCL_DTOOL_DTOOLBASE EXPORT_CLASS
+  #define EXPTP_DTOOL_DTOOLBASE EXPORT_TEMPL
 #else
-  #define EXPCL_DTOOLCONFIG IMPORT_CLASS
-  #define EXPTP_DTOOLCONFIG IMPORT_TEMPL
+  #define EXPCL_DTOOL_DTOOLBASE IMPORT_CLASS
+  #define EXPTP_DTOOL_DTOOLBASE IMPORT_TEMPL
+#endif
+
+#ifdef BUILDING_DTOOL_DTOOLUTIL
+  #define EXPCL_DTOOL_DTOOLUTIL EXPORT_CLASS
+  #define EXPTP_DTOOL_DTOOLUTIL EXPORT_TEMPL
+#else
+  #define EXPCL_DTOOL_DTOOLUTIL IMPORT_CLASS
+  #define EXPTP_DTOOL_DTOOLUTIL IMPORT_TEMPL
+#endif
+
+#ifdef BUILDING_DTOOL_PRC
+  #define EXPCL_DTOOL_PRC EXPORT_CLASS
+  #define EXPTP_DTOOL_PRC EXPORT_TEMPL
+#else
+  #define EXPCL_DTOOL_PRC IMPORT_CLASS
+  #define EXPTP_DTOOL_PRC IMPORT_TEMPL
+#endif
+
+#ifdef BUILDING_DTOOL_DCONFIG
+  #define EXPCL_DTOOL_DCONFIG EXPORT_CLASS
+  #define EXPTP_DTOOL_DCONFIG EXPORT_TEMPL
+#else
+  #define EXPCL_DTOOL_DCONFIG IMPORT_CLASS
+  #define EXPTP_DTOOL_DCONFIG IMPORT_TEMPL
 #endif
 
 #ifdef BUILDING_INTERROGATEDB
@@ -99,6 +125,7 @@
   #define EXPTP_MISC IMPORT_TEMPL
 #endif /* BUILDING_MISC */
 
+
 /* These two are always defined empty, because pystub is statically
    built.  But we leave the symbol around in case we change our minds
    to make pystub once again be a dynamic library. */

+ 1 - 1
dtool/src/dtoolbase/indent.h

@@ -22,7 +22,7 @@
  * stream itself.  Useful for indenting a series of lines of text by a given
  * amount.
  */
-EXPCL_DTOOL ostream &
+EXPCL_DTOOL_DTOOLBASE ostream &
 indent(ostream &out, int indent_level);
 
 /**

+ 1 - 1
dtool/src/dtoolbase/lookup3.h

@@ -21,7 +21,7 @@
 extern "C" {
 #endif
 
-EXPCL_DTOOL uint32_t hashword(const uint32_t *k,                   /* the key, an array of uint32_t values */
+EXPCL_DTOOL_DTOOLBASE uint32_t hashword(const uint32_t *k,                   /* the key, an array of uint32_t values */
                                size_t          length,               /* the length of the key, in uint32_ts */
                                uint32_t        initval);
 

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

@@ -66,7 +66,7 @@
  * that seems to cause problems when including header files for C++-based
  * system libraries (such as are found on OSX).
  */
-class EXPCL_DTOOL MemoryBase {
+class EXPCL_DTOOL_DTOOLBASE MemoryBase {
 public:
   ALLOC_MEMORY_BASE;
 };

+ 1 - 1
dtool/src/dtoolbase/memoryHook.h

@@ -34,7 +34,7 @@ class DeletedBufferChain;
  * employed for classes which inherit from MemoryBase; otherwise, use the
  * PANDA_MALLOC macros.)
  */
-class EXPCL_DTOOL MemoryHook {
+class EXPCL_DTOOL_DTOOLBASE MemoryHook {
 public:
   MemoryHook();
   MemoryHook(const MemoryHook &copy);

+ 1 - 1
dtool/src/dtoolbase/mutexDummyImpl.h

@@ -21,7 +21,7 @@
  * A fake mutex implementation for single-threaded applications that don't
  * need any synchronization control.  This does nothing at all.
  */
-class EXPCL_DTOOL MutexDummyImpl {
+class EXPCL_DTOOL_DTOOLBASE MutexDummyImpl {
 public:
   CONSTEXPR MutexDummyImpl() DEFAULT_CTOR;
 

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

@@ -26,7 +26,7 @@
 /**
  * Uses Posix threads to implement a mutex.
  */
-class EXPCL_DTOOL MutexPosixImpl {
+class EXPCL_DTOOL_DTOOLBASE MutexPosixImpl {
 public:
   CONSTEXPR MutexPosixImpl() NOEXCEPT;
   INLINE ~MutexPosixImpl();
@@ -50,7 +50,7 @@ private:
 /**
  * Uses Posix threads to implement a reentrant mutex.
  */
-class EXPCL_DTOOL ReMutexPosixImpl {
+class EXPCL_DTOOL_DTOOLBASE ReMutexPosixImpl {
 public:
 #ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
   CONSTEXPR ReMutexPosixImpl() NOEXCEPT;

+ 1 - 1
dtool/src/dtoolbase/mutexSpinlockImpl.h

@@ -27,7 +27,7 @@
  * specific application on a specific SMP machine, and you are confident that
  * you have at least as many CPU's as you have threads.
  */
-class EXPCL_DTOOL MutexSpinlockImpl {
+class EXPCL_DTOOL_DTOOLBASE MutexSpinlockImpl {
 public:
   CONSTEXPR MutexSpinlockImpl();
 

+ 1 - 1
dtool/src/dtoolbase/mutexWin32Impl.h

@@ -26,7 +26,7 @@
 /**
  * Uses Windows native calls to implement a mutex.
  */
-class EXPCL_DTOOL MutexWin32Impl {
+class EXPCL_DTOOL_DTOOLBASE MutexWin32Impl {
 public:
   MutexWin32Impl();
   INLINE ~MutexWin32Impl();

+ 1 - 1
dtool/src/dtoolbase/neverFreeMemory.h

@@ -29,7 +29,7 @@
  * since this will help reduce fragmentation problems in the dynamic heap.
  * Also, memory allocated from here will exhibit less wasted space.
  */
-class EXPCL_DTOOL NeverFreeMemory {
+class EXPCL_DTOOL_DTOOLBASE NeverFreeMemory {
 private:
   NeverFreeMemory();
 

+ 1 - 1
dtool/src/dtoolbase/pdtoa.h

@@ -15,7 +15,7 @@
 extern "C" {
 #endif
 
-EXPCL_DTOOL void pdtoa(double value, char *buffer);
+EXPCL_DTOOL_DTOOLBASE void pdtoa(double value, char *buffer);
 
 #ifdef __cplusplus
 };  /* end of extern "C" */

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

@@ -20,10 +20,10 @@
 extern "C" {
 #endif
 
-EXPCL_DTOOL double
+EXPCL_DTOOL_DTOOLBASE double
 pstrtod(const char *nptr, char **endptr);
 
-EXPCL_DTOOL double
+EXPCL_DTOOL_DTOOLBASE double
 patof(const char *str);
 
 #ifdef __cplusplus

+ 15 - 0
dtool/src/dtoolbase/pvector.h

@@ -46,9 +46,24 @@ public:
   typedef TYPENAME base_class::size_type size_type;
 
   explicit pvector(TypeHandle type_handle = pvector_type_handle) : base_class(allocator(type_handle)) { }
+  pvector(const pvector<Type> &copy) : base_class(copy) { }
   explicit pvector(size_type n, TypeHandle type_handle = pvector_type_handle) : base_class(n, Type(), allocator(type_handle)) { }
   explicit pvector(size_type n, const Type &value, TypeHandle type_handle = pvector_type_handle) : base_class(n, value, allocator(type_handle)) { }
   pvector(const Type *begin, const Type *end, TypeHandle type_handle = pvector_type_handle) : base_class(begin, end, allocator(type_handle)) { }
+
+#ifdef USE_MOVE_SEMANTICS
+  pvector(pvector<Type> &&from) NOEXCEPT : base_class(move(from)) {};
+
+  pvector<Type> &operator =(pvector<Type> &&from) NOEXCEPT {
+    base_class::operator =(move(from));
+    return *this;
+  }
+#endif
+
+  pvector<Type> &operator =(const pvector<Type> &copy) {
+    base_class::operator =(copy);
+    return *this;
+  }
 };
 
 #endif  // USE_STL_ALLOCATOR

+ 19 - 19
dtool/src/dtoolbase/register_type.h

@@ -76,18 +76,18 @@ register_dynamic_type(const string &name,
 
 
 // A few system-wide TypeHandles are defined for some basic types.
-extern TypeHandle EXPCL_DTOOL long_type_handle;
-extern TypeHandle EXPCL_DTOOL int_type_handle;
-extern TypeHandle EXPCL_DTOOL uint_type_handle;
-extern TypeHandle EXPCL_DTOOL short_type_handle;
-extern TypeHandle EXPCL_DTOOL ushort_type_handle;
-extern TypeHandle EXPCL_DTOOL char_type_handle;
-extern TypeHandle EXPCL_DTOOL uchar_type_handle;
-extern TypeHandle EXPCL_DTOOL bool_type_handle;
-extern TypeHandle EXPCL_DTOOL double_type_handle;
-extern TypeHandle EXPCL_DTOOL float_type_handle;
-extern TypeHandle EXPCL_DTOOL string_type_handle;
-extern TypeHandle EXPCL_DTOOL wstring_type_handle;
+extern TypeHandle EXPCL_DTOOL_DTOOLBASE long_type_handle;
+extern TypeHandle EXPCL_DTOOL_DTOOLBASE int_type_handle;
+extern TypeHandle EXPCL_DTOOL_DTOOLBASE uint_type_handle;
+extern TypeHandle EXPCL_DTOOL_DTOOLBASE short_type_handle;
+extern TypeHandle EXPCL_DTOOL_DTOOLBASE ushort_type_handle;
+extern TypeHandle EXPCL_DTOOL_DTOOLBASE char_type_handle;
+extern TypeHandle EXPCL_DTOOL_DTOOLBASE uchar_type_handle;
+extern TypeHandle EXPCL_DTOOL_DTOOLBASE bool_type_handle;
+extern TypeHandle EXPCL_DTOOL_DTOOLBASE double_type_handle;
+extern TypeHandle EXPCL_DTOOL_DTOOLBASE float_type_handle;
+extern TypeHandle EXPCL_DTOOL_DTOOLBASE string_type_handle;
+extern TypeHandle EXPCL_DTOOL_DTOOLBASE wstring_type_handle;
 
 extern TypeHandle long_p_type_handle;
 extern TypeHandle int_p_type_handle;
@@ -98,14 +98,14 @@ extern TypeHandle double_p_type_handle;
 extern TypeHandle float_p_type_handle;
 extern TypeHandle void_p_type_handle;
 
-extern TypeHandle EXPCL_DTOOL pvector_type_handle;
-extern TypeHandle EXPCL_DTOOL ov_set_type_handle;
-extern TypeHandle EXPCL_DTOOL pdeque_type_handle;
-extern TypeHandle EXPCL_DTOOL plist_type_handle;
-extern TypeHandle EXPCL_DTOOL pmap_type_handle;
-extern TypeHandle EXPCL_DTOOL pset_type_handle;
+extern TypeHandle EXPCL_DTOOL_DTOOLBASE pvector_type_handle;
+extern TypeHandle EXPCL_DTOOL_DTOOLBASE ov_set_type_handle;
+extern TypeHandle EXPCL_DTOOL_DTOOLBASE pdeque_type_handle;
+extern TypeHandle EXPCL_DTOOL_DTOOLBASE plist_type_handle;
+extern TypeHandle EXPCL_DTOOL_DTOOLBASE pmap_type_handle;
+extern TypeHandle EXPCL_DTOOL_DTOOLBASE pset_type_handle;
 
-void EXPCL_DTOOL init_system_type_handles();
+void EXPCL_DTOOL_DTOOLBASE init_system_type_handles();
 
 // The following template function and its specializations will return a
 // TypeHandle for any type in the world, from a pointer to that type.

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

@@ -78,7 +78,7 @@ class TypedObject;
  * that ancestry of a particular type may be queried, and the type name may be
  * retrieved for run-time display.
  */
-class EXPCL_DTOOL TypeHandle FINAL {
+class EXPCL_DTOOL_DTOOLBASE TypeHandle FINAL {
 PUBLISHED:
   TypeHandle() NOEXCEPT DEFAULT_CTOR;
 
@@ -162,7 +162,7 @@ INLINE ostream &operator << (ostream &out, TypeHandle type) {
   return out;
 }
 
-EXPCL_DTOOL ostream &operator << (ostream &out, TypeHandle::MemoryClass mem_class);
+EXPCL_DTOOL_DTOOLBASE ostream &operator << (ostream &out, TypeHandle::MemoryClass mem_class);
 
 // We must include typeRegistry at this point so we can call it from our
 // inline functions.  This is a circular include that is strategically placed

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

@@ -33,7 +33,7 @@ class TypedObject;
  * should be migrated to shared memory as soon as shared memory becomes
  * available.
  */
-class EXPCL_DTOOL TypeRegistry : public MemoryBase {
+class EXPCL_DTOOL_DTOOLBASE TypeRegistry : public MemoryBase {
 public:
   // User code shouldn't generally need to call TypeRegistry::register_type()
   // or record_derivation() directly; instead, use the register_type
@@ -118,7 +118,7 @@ private:
 };
 
 // Helper function to allow for "C" interaction into the type system
-extern "C" EXPCL_DTOOL  int get_best_parent_from_Set(int id, const std::set<int> &this_set);
+extern "C" EXPCL_DTOOL_DTOOLBASE  int get_best_parent_from_Set(int id, const std::set<int> &this_set);
 
 #include "typeHandle.h"
 

+ 1 - 1
dtool/src/dtoolbase/typeRegistryNode.h

@@ -27,7 +27,7 @@
  * directly access this class; this class is hidden within the TypeRegistry
  * accessors.
  */
-class EXPCL_DTOOL TypeRegistryNode {
+class EXPCL_DTOOL_DTOOLBASE TypeRegistryNode {
 public:
   TypeRegistryNode(TypeHandle handle, const string &name, TypeHandle &ref);
 

+ 1 - 1
dtool/src/dtoolbase/typedObject.h

@@ -85,7 +85,7 @@
  * }
  * @endcode
  */
-class EXPCL_DTOOL TypedObject : public MemoryBase {
+class EXPCL_DTOOL_DTOOLBASE TypedObject : public MemoryBase {
 public:
   INLINE TypedObject() DEFAULT_CTOR;
   INLINE TypedObject(const TypedObject &copy) DEFAULT_CTOR;

+ 4 - 0
dtool/src/dtoolutil/config_dtoolutil.cxx

@@ -16,6 +16,10 @@
 #include "filename.h"
 #include "pandaSystem.h"
 
+#if !defined(CPPPARSER) && !defined(BUILDING_DTOOL_DTOOLUTIL)
+  #error Buildsystem error: BUILDING_DTOOL_DCTOOLUTIL not defined
+#endif
+
 /**
  * Initializes the library.  This must be called at least once before any of
  * the functions or classes in this library can be used.  Normally it will be

+ 2 - 2
dtool/src/dtoolutil/dSearchPath.h

@@ -25,9 +25,9 @@
  * traditional searchpath-style string, e.g.  a list of directory names
  * delimited by spaces or colons, but it can also be built up explicitly.
  */
-class EXPCL_DTOOL DSearchPath {
+class EXPCL_DTOOL_DTOOLUTIL DSearchPath {
 PUBLISHED:
-  class EXPCL_DTOOL Results {
+  class EXPCL_DTOOL_DTOOLUTIL Results {
   PUBLISHED:
     Results();
     Results(const Results &copy);

+ 1 - 1
dtool/src/dtoolutil/executionEnvironment.h

@@ -26,7 +26,7 @@
  * at the time of execution.  This is encapsulated to support accessing these
  * things during static init time, which seems to be risky at best.
  */
-class EXPCL_DTOOL ExecutionEnvironment {
+class EXPCL_DTOOL_DTOOLUTIL ExecutionEnvironment {
 private:
   ExecutionEnvironment();
 

+ 1 - 1
dtool/src/dtoolutil/filename.h

@@ -36,7 +36,7 @@ class DSearchPath;
  * for file existence and searching a searchpath, as well as the best way to
  * open an fstream for reading or writing.
  */
-class EXPCL_DTOOL Filename {
+class EXPCL_DTOOL_DTOOLUTIL Filename {
 PUBLISHED:
   enum Type {
     // These type values must fit within the bits allocated for F_type, below.

+ 1 - 1
dtool/src/dtoolutil/globPattern.h

@@ -29,7 +29,7 @@
  * the pattern or not.  It can be used, for example, to scan a directory for
  * all files matching a particular pattern.
  */
-class EXPCL_DTOOL GlobPattern {
+class EXPCL_DTOOL_DTOOLUTIL GlobPattern {
 PUBLISHED:
   INLINE GlobPattern(const string &pattern = string());
   INLINE GlobPattern(const GlobPattern &copy);

+ 1 - 1
dtool/src/dtoolutil/lineStream.h

@@ -28,7 +28,7 @@
  * otherwise affected when a line of text is extracted.  More text can still
  * be written to it and continuously extracted.
  */
-class EXPCL_DTOOL LineStream : public ostream {
+class EXPCL_DTOOL_DTOOLUTIL LineStream : public ostream {
 PUBLISHED:
   INLINE LineStream();
 

+ 1 - 1
dtool/src/dtoolutil/lineStreamBuf.h

@@ -23,7 +23,7 @@
  * whose contents can be continuously extracted as a sequence of lines of
  * text.
  */
-class EXPCL_DTOOL LineStreamBuf : public streambuf {
+class EXPCL_DTOOL_DTOOLUTIL LineStreamBuf : public streambuf {
 public:
   LineStreamBuf();
   virtual ~LineStreamBuf();

+ 4 - 4
dtool/src/dtoolutil/load_dso.h

@@ -22,20 +22,20 @@
 // otherwise on success.  If the filename is not absolute, searches the path.
 // If the path is empty, searches the dtool directory.
 
-EXPCL_DTOOL void *
+EXPCL_DTOOL_DTOOLUTIL void *
 load_dso(const DSearchPath &path, const Filename &filename);
 
 // true indicates success
-EXPCL_DTOOL bool
+EXPCL_DTOOL_DTOOLUTIL bool
 unload_dso(void *dso_handle);
 
 // Returns the error message from the last failed load_dso() call.
 
-EXPCL_DTOOL string
+EXPCL_DTOOL_DTOOLUTIL string
 load_dso_error();
 
 // Returns a function pointer or other symbol from a loaded library.
-EXPCL_DTOOL void *
+EXPCL_DTOOL_DTOOLUTIL void *
 get_dso_symbol(void *handle, const string &name);
 
 #endif

+ 3 - 3
dtool/src/dtoolutil/pandaFileStream.h

@@ -26,7 +26,7 @@
  * simple-threading implementation (using this interface will block only the
  * current thread, rather than the entire process, on I/O waits).
  */
-class EXPCL_DTOOL IFileStream : public istream {
+class EXPCL_DTOOL_DTOOLUTIL IFileStream : public istream {
 PUBLISHED:
   INLINE IFileStream();
   INLINE explicit IFileStream(const char *filename, ios::openmode mode = ios::in);
@@ -54,7 +54,7 @@ private:
  * simple-threading implementation (using this interface will block only the
  * current thread, rather than the entire process, on I/O waits).
  */
-class EXPCL_DTOOL OFileStream : public ostream {
+class EXPCL_DTOOL_DTOOLUTIL OFileStream : public ostream {
 PUBLISHED:
   INLINE OFileStream();
   INLINE explicit OFileStream(const char *filename, ios::openmode mode = ios::out);
@@ -83,7 +83,7 @@ private:
  * will block only the current thread, rather than the entire process, on I/O
  * waits).
  */
-class EXPCL_DTOOL FileStream : public iostream {
+class EXPCL_DTOOL_DTOOLUTIL FileStream : public iostream {
 PUBLISHED:
   INLINE FileStream();
   INLINE explicit FileStream(const char *filename, ios::openmode mode = ios::in);

+ 3 - 3
dtool/src/dtoolutil/pandaFileStreamBuf.h

@@ -28,7 +28,7 @@
 /**
  * The streambuf object that implements pifstream and pofstream.
  */
-class EXPCL_DTOOL PandaFileStreamBuf : public streambuf {
+class EXPCL_DTOOL_DTOOLUTIL PandaFileStreamBuf : public streambuf {
 public:
   PandaFileStreamBuf();
   virtual ~PandaFileStreamBuf();
@@ -95,10 +95,10 @@ private:
   streampos _gpos;
 };
 
-EXPCL_DTOOL ostream &
+EXPCL_DTOOL_DTOOLUTIL ostream &
 operator << (ostream &out, PandaFileStreamBuf::NewlineMode newline_mode);
 
-EXPCL_DTOOL istream &
+EXPCL_DTOOL_DTOOLUTIL istream &
 operator >> (istream &in, PandaFileStreamBuf::NewlineMode &newline_mode);
 
 #endif  // USE_PANDAFILESTREAM

+ 1 - 1
dtool/src/dtoolutil/pandaSystem.h

@@ -23,7 +23,7 @@
  * Panda.  Application developers can use this class to query the runtime
  * version or capabilities of the current Panda environment.
  */
-class EXPCL_DTOOL PandaSystem {
+class EXPCL_DTOOL_DTOOLUTIL PandaSystem {
 protected:
   PandaSystem();
   ~PandaSystem();

+ 5 - 5
dtool/src/dtoolutil/panda_getopt_impl.h

@@ -40,8 +40,8 @@
 extern "C" {
 #endif
 
-extern EXPCL_DTOOL char *optarg;
-extern EXPCL_DTOOL int optind, opterr, optopt;
+extern EXPCL_DTOOL_DTOOLUTIL char *optarg;
+extern EXPCL_DTOOL_DTOOLUTIL int optind, opterr, optopt;
 
 struct option {
   const char *name;
@@ -54,12 +54,12 @@ struct option {
 #define required_argument 1
 #define optional_argument 2
 
-extern EXPCL_DTOOL int
+extern EXPCL_DTOOL_DTOOLUTIL int
 getopt(int argc, char *const argv[], const char *optstring);
-extern EXPCL_DTOOL int
+extern EXPCL_DTOOL_DTOOLUTIL int
 getopt_long(int argc, char *const argv[], const char *optstring,
             const struct option *longopts, int *longindex);
-extern EXPCL_DTOOL int
+extern EXPCL_DTOOL_DTOOLUTIL int
 getopt_long_only(int argc, char *const argv[], const char *optstring,
                  const struct option *longopts, int *longindex);
 

+ 2 - 2
dtool/src/dtoolutil/pfstream.h

@@ -16,7 +16,7 @@
 
 #include "pfstreamBuf.h"
 
-class EXPCL_DTOOL IPipeStream : public istream {
+class EXPCL_DTOOL_DTOOLUTIL IPipeStream : public istream {
 public:
   INLINE IPipeStream(const std::string);
 
@@ -32,7 +32,7 @@ private:
   INLINE IPipeStream();
 };
 
-class EXPCL_DTOOL OPipeStream : public ostream {
+class EXPCL_DTOOL_DTOOLUTIL OPipeStream : public ostream {
 public:
   INLINE OPipeStream(const std::string);
 

+ 1 - 1
dtool/src/dtoolutil/pfstreamBuf.h

@@ -41,7 +41,7 @@
 
 #endif // WIN_PIPE_CALLS
 
-class EXPCL_DTOOL PipeStreamBuf : public streambuf {
+class EXPCL_DTOOL_DTOOLUTIL PipeStreamBuf : public streambuf {
 public:
   enum Direction { Input, Output };
 

+ 1 - 1
dtool/src/dtoolutil/preprocess_argv.h

@@ -16,7 +16,7 @@
 
 #include "dtoolbase.h"
 
-extern EXPCL_DTOOL void
+extern EXPCL_DTOOL_DTOOLUTIL void
 preprocess_argv(int &argc, char **&argv);
 
 #endif

+ 1 - 1
dtool/src/dtoolutil/stringDecoder.h

@@ -21,7 +21,7 @@
  * byte streams.  Give it a string, then ask it to pull the characters out one
  * at a time.  This also serves as the plain old byte-at-a-time decoder.
  */
-class EXPCL_DTOOL StringDecoder {
+class EXPCL_DTOOL_DTOOLUTIL StringDecoder {
 public:
   INLINE StringDecoder(const string &input);
   virtual ~StringDecoder();

+ 20 - 20
dtool/src/dtoolutil/string_utils.h

@@ -22,44 +22,44 @@
 
 // Case-insensitive string comparison, from Stroustrup's C++ third edition.
 // Works like strcmp().
-EXPCL_DTOOL int cmp_nocase(const string &s, const string &s2);
+EXPCL_DTOOL_DTOOLUTIL int cmp_nocase(const string &s, const string &s2);
 
 // Similar, except it also accepts hyphen and underscore as equivalent.
-EXPCL_DTOOL int cmp_nocase_uh(const string &s, const string &s2);
+EXPCL_DTOOL_DTOOLUTIL int cmp_nocase_uh(const string &s, const string &s2);
 
 // Returns the string converted to lowercase.
-EXPCL_DTOOL string downcase(const string &s);
+EXPCL_DTOOL_DTOOLUTIL string downcase(const string &s);
 
 // Returns the string converted to uppercase.
-EXPCL_DTOOL string upcase(const string &s);
+EXPCL_DTOOL_DTOOLUTIL string upcase(const string &s);
 
 // Separates the string into words according to whitespace.
-EXPCL_DTOOL int extract_words(const string &str, vector_string &words);
-EXPCL_DTOOL int extract_words(const wstring &str, pvector<wstring> &words);
+EXPCL_DTOOL_DTOOLUTIL int extract_words(const string &str, vector_string &words);
+EXPCL_DTOOL_DTOOLUTIL int extract_words(const wstring &str, pvector<wstring> &words);
 
 // Separates the string into words according to the indicated delimiters.
-EXPCL_DTOOL void tokenize(const string &str, vector_string &words,
+EXPCL_DTOOL_DTOOLUTIL void tokenize(const string &str, vector_string &words,
                           const string &delimiters,
                           bool discard_repeated_delimiters = false);
-EXPCL_DTOOL void tokenize(const wstring &str, pvector<wstring> &words,
+EXPCL_DTOOL_DTOOLUTIL void tokenize(const wstring &str, pvector<wstring> &words,
                           const wstring &delimiters,
                           bool discard_repeated_delimiters = false);
 
 // Trims leading andor trailing whitespace from the string.
-EXPCL_DTOOL string trim_left(const string &str);
-EXPCL_DTOOL wstring trim_left(const wstring &str);
-EXPCL_DTOOL string trim_right(const string &str);
-EXPCL_DTOOL wstring trim_right(const wstring &str);
-EXPCL_DTOOL string trim(const string &str);
-EXPCL_DTOOL wstring trim(const wstring &str);
+EXPCL_DTOOL_DTOOLUTIL string trim_left(const string &str);
+EXPCL_DTOOL_DTOOLUTIL wstring trim_left(const wstring &str);
+EXPCL_DTOOL_DTOOLUTIL string trim_right(const string &str);
+EXPCL_DTOOL_DTOOLUTIL wstring trim_right(const wstring &str);
+EXPCL_DTOOL_DTOOLUTIL string trim(const string &str);
+EXPCL_DTOOL_DTOOLUTIL wstring trim(const wstring &str);
 
 // Functions to parse numeric values out of a string.
-EXPCL_DTOOL int string_to_int(const string &str, string &tail);
-EXPCL_DTOOL bool string_to_int(const string &str, int &result);
-EXPCL_DTOOL double string_to_double(const string &str, string &tail);
-EXPCL_DTOOL bool string_to_double(const string &str, double &result);
-EXPCL_DTOOL bool string_to_float(const string &str, float &result);
-EXPCL_DTOOL bool string_to_stdfloat(const string &str, PN_stdfloat &result);
+EXPCL_DTOOL_DTOOLUTIL int string_to_int(const string &str, string &tail);
+EXPCL_DTOOL_DTOOLUTIL bool string_to_int(const string &str, int &result);
+EXPCL_DTOOL_DTOOLUTIL double string_to_double(const string &str, string &tail);
+EXPCL_DTOOL_DTOOLUTIL bool string_to_double(const string &str, double &result);
+EXPCL_DTOOL_DTOOLUTIL bool string_to_float(const string &str, float &result);
+EXPCL_DTOOL_DTOOLUTIL bool string_to_stdfloat(const string &str, PN_stdfloat &result);
 
 // Convenience function to make a string from anything that has an ostream
 // operator.

+ 4 - 4
dtool/src/dtoolutil/textEncoder.h

@@ -30,7 +30,7 @@ class StringDecoder;
  * This class is also a base class of TextNode, which inherits this
  * functionality.
  */
-class EXPCL_DTOOL TextEncoder {
+class EXPCL_DTOOL_DTOOLUTIL TextEncoder {
 PUBLISHED:
   enum Encoding {
     E_iso8859,
@@ -112,9 +112,9 @@ private:
   static Encoding _default_encoding;
 };
 
-EXPCL_DTOOL ostream &
+EXPCL_DTOOL_DTOOLUTIL ostream &
 operator << (ostream &out, TextEncoder::Encoding encoding);
-EXPCL_DTOOL istream &
+EXPCL_DTOOL_DTOOLUTIL istream &
 operator >> (istream &in, TextEncoder::Encoding &encoding);
 
 // We'll define the output operator for wstring here, too.  Presumably this
@@ -122,7 +122,7 @@ operator >> (istream &in, TextEncoder::Encoding &encoding);
 
 // This function is declared inline to minimize the risk of link conflicts
 // should another third-party module also define the same output operator.
-INLINE EXPCL_DTOOL ostream &
+INLINE EXPCL_DTOOL_DTOOLUTIL ostream &
 operator << (ostream &out, const wstring &str);
 
 #include "textEncoder.I"

+ 1 - 1
dtool/src/dtoolutil/unicodeLatinMap.h

@@ -25,7 +25,7 @@
  * equivalent without the accent mark; as well as how to switch case from
  * upper to lower while retaining the Unicode accent marks.
  */
-class EXPCL_DTOOL UnicodeLatinMap {
+class EXPCL_DTOOL_DTOOLUTIL UnicodeLatinMap {
 public:
   enum AccentType {
     AT_none,

+ 2 - 7
dtool/src/dtoolutil/vector_double.cxx

@@ -13,14 +13,9 @@
 
 #include "vector_double.h"
 
-#define EXPCL EXPCL_DTOOL
-#define EXPTP EXPTP_DTOOL
+#define EXPCL EXPCL_DTOOL_DTOOLUTIL
+#define EXPTP EXPTP_DTOOL_DTOOLUTIL
 #define TYPE double
 #define NAME vector_double
 
 #include "vector_src.cxx"
-
-// Tell GCC that we'll take care of the instantiation explicitly here.
-#ifdef __GNUC__
-#pragma implementation
-#endif

+ 2 - 7
dtool/src/dtoolutil/vector_double.h

@@ -23,16 +23,11 @@
  * defining the vector again.
  */
 
-#define EXPCL EXPCL_DTOOL
-#define EXPTP EXPTP_DTOOL
+#define EXPCL EXPCL_DTOOL_DTOOLUTIL
+#define EXPTP EXPTP_DTOOL_DTOOLUTIL
 #define TYPE double
 #define NAME vector_double
 
 #include "vector_src.h"
 
-// Tell GCC that we'll take care of the instantiation explicitly here.
-#ifdef __GNUC__
-#pragma interface
-#endif
-
 #endif

+ 2 - 7
dtool/src/dtoolutil/vector_float.cxx

@@ -13,14 +13,9 @@
 
 #include "vector_float.h"
 
-#define EXPCL EXPCL_DTOOL
-#define EXPTP EXPTP_DTOOL
+#define EXPCL EXPCL_DTOOL_DTOOLUTIL
+#define EXPTP EXPTP_DTOOL_DTOOLUTIL
 #define TYPE float
 #define NAME vector_float
 
 #include "vector_src.cxx"
-
-// Tell GCC that we'll take care of the instantiation explicitly here.
-#ifdef __GNUC__
-#pragma implementation
-#endif

+ 2 - 7
dtool/src/dtoolutil/vector_float.h

@@ -23,16 +23,11 @@
  * defining the vector again.
  */
 
-#define EXPCL EXPCL_DTOOL
-#define EXPTP EXPTP_DTOOL
+#define EXPCL EXPCL_DTOOL_DTOOLUTIL
+#define EXPTP EXPTP_DTOOL_DTOOLUTIL
 #define TYPE float
 #define NAME vector_float
 
 #include "vector_src.h"
 
-// Tell GCC that we'll take care of the instantiation explicitly here.
-#ifdef __GNUC__
-#pragma interface
-#endif
-
 #endif

+ 2 - 7
dtool/src/dtoolutil/vector_int.cxx

@@ -13,14 +13,9 @@
 
 #include "vector_int.h"
 
-#define EXPCL EXPCL_DTOOL
-#define EXPTP EXPTP_DTOOL
+#define EXPCL EXPCL_DTOOL_DTOOLUTIL
+#define EXPTP EXPTP_DTOOL_DTOOLUTIL
 #define TYPE int
 #define NAME vector_int
 
 #include "vector_src.cxx"
-
-// Tell GCC that we'll take care of the instantiation explicitly here.
-#ifdef __GNUC__
-#pragma implementation
-#endif

+ 2 - 7
dtool/src/dtoolutil/vector_int.h

@@ -23,16 +23,11 @@
  * rather than defining the vector again.
  */
 
-#define EXPCL EXPCL_DTOOL
-#define EXPTP EXPTP_DTOOL
+#define EXPCL EXPCL_DTOOL_DTOOLUTIL
+#define EXPTP EXPTP_DTOOL_DTOOLUTIL
 #define TYPE int
 #define NAME vector_int
 
 #include "vector_src.h"
 
-// Tell GCC that we'll take care of the instantiation explicitly here.
-#ifdef __GNUC__
-#pragma interface
-#endif
-
 #endif

+ 2 - 7
dtool/src/dtoolutil/vector_string.cxx

@@ -13,14 +13,9 @@
 
 #include "vector_string.h"
 
-#define EXPCL EXPCL_DTOOL
-#define EXPTP EXPTP_DTOOL
+#define EXPCL EXPCL_DTOOL_DTOOLUTIL
+#define EXPTP EXPTP_DTOOL_DTOOLUTIL
 #define TYPE std::string
 #define NAME vector_string
 
 #include "vector_src.cxx"
-
-// Tell GCC that we'll take care of the instantiation explicitly here.
-#ifdef __GNUC__
-#pragma implementation
-#endif

+ 2 - 7
dtool/src/dtoolutil/vector_string.h

@@ -23,16 +23,11 @@
  * defining the vector again.
  */
 
-#define EXPCL EXPCL_DTOOL
-#define EXPTP EXPTP_DTOOL
+#define EXPCL EXPCL_DTOOL_DTOOLUTIL
+#define EXPTP EXPTP_DTOOL_DTOOLUTIL
 #define TYPE std::string
 #define NAME vector_string
 
 #include "vector_src.h"
 
-// Tell GCC that we'll take care of the instantiation explicitly here.
-#ifdef __GNUC__
-#pragma interface
-#endif
-
 #endif

+ 2 - 7
dtool/src/dtoolutil/vector_uchar.cxx

@@ -13,14 +13,9 @@
 
 #include "vector_uchar.h"
 
-#define EXPCL EXPCL_DTOOL
-#define EXPTP EXPTP_DTOOL
+#define EXPCL EXPCL_DTOOL_DTOOLUTIL
+#define EXPTP EXPTP_DTOOL_DTOOLUTIL
 #define TYPE unsigned char
 #define NAME vector_uchar
 
 #include "vector_src.cxx"
-
-// Tell GCC that we'll take care of the instantiation explicitly here.
-#ifdef __GNUC__
-#pragma implementation
-#endif

+ 2 - 7
dtool/src/dtoolutil/vector_uchar.h

@@ -23,16 +23,11 @@
  * rather than defining the vector again.
  */
 
-#define EXPCL EXPCL_DTOOL
-#define EXPTP EXPTP_DTOOL
+#define EXPCL EXPCL_DTOOL_DTOOLUTIL
+#define EXPTP EXPTP_DTOOL_DTOOLUTIL
 #define TYPE unsigned char
 #define NAME vector_uchar
 
 #include "vector_src.h"
 
-// Tell GCC that we'll take care of the instantiation explicitly here.
-#ifdef __GNUC__
-#pragma interface
-#endif
-
 #endif

+ 1 - 1
dtool/src/dtoolutil/win32ArgParser.h

@@ -30,7 +30,7 @@
  * but it is also supports automatic expansion of glob filenames, e.g.  *.egg
  * is turned into an explicit list of egg files in the directory.
  */
-class EXPCL_DTOOL Win32ArgParser {
+class EXPCL_DTOOL_DTOOLUTIL Win32ArgParser {
 public:
   Win32ArgParser();
   ~Win32ArgParser();

+ 56 - 8
dtool/src/interrogate/interfaceMakerPythonNative.cxx

@@ -5414,6 +5414,18 @@ write_function_instance(ostream &out, FunctionRemap *remap,
         parameter_list += ", &" + param_name;
       }
 
+      // If the default value is NULL, we also accept a None value.
+      bool maybe_none = false;
+      if (default_value != nullptr && (return_flags & RF_coerced) == 0) {
+        CPPExpression::Result res = param->get_default_value()->evaluate();
+        if (res._type == CPPExpression::RT_integer ||
+            res._type == CPPExpression::RT_pointer) {
+          if (res.as_integer() == 0) {
+            maybe_none = true;
+          }
+        }
+      }
+
       string class_name = obj_type->get_local_name(&parser);
 
       // need to a forward scope for this class..
@@ -5464,17 +5476,27 @@ write_function_instance(ostream &out, FunctionRemap *remap,
 
           type->output_instance(extra_convert, param_name + "_this", &parser);
 
-          if (is_optional) {
+          if (is_optional && maybe_none) {
+            extra_convert
+              << default_expr << ";\n"
+              << "if (" << param_name << " != NULL && " << param_name << " != Py_None) {\n"
+              << "  " << param_name << "_this";
+          } else if (is_optional) {
             extra_convert
               << default_expr << ";\n"
               << "if (" << param_name << " != NULL) {\n"
               << "  " << param_name << "_this";
+          } else if (maybe_none) {
+            extra_convert
+              << " = NULL;\n"
+              << "if (" << param_name << " != Py_None) {\n"
+              << "  " << param_name << "_this";
           }
 
           extra_convert << " = Dtool_Coerce_" + make_safe_name(class_name) +
             "(" + param_name + ", " + param_name + "_local);\n";
 
-          if (is_optional) {
+          if (is_optional || maybe_none) {
             extra_convert << "}\n";
           }
 
@@ -5485,8 +5507,12 @@ write_function_instance(ostream &out, FunctionRemap *remap,
 
         if (report_errors) {
           // We were asked to report any errors.  Let's do it.
-          if (is_optional) {
+          if (is_optional && maybe_none) {
+            extra_convert << "if (" << param_name << " != NULL && " << param_name << " != Py_None && !" << coerce_call << ") {\n";
+          } else if (is_optional) {
             extra_convert << "if (" << param_name << " != NULL && !" << coerce_call << ") {\n";
+          } else if (maybe_none) {
+            extra_convert << "if (" << param_name << " != Py_None && !" << coerce_call << ") {\n";
           } else {
             extra_convert << "if (!" << coerce_call << ") {\n";
           }
@@ -5509,19 +5535,35 @@ write_function_instance(ostream &out, FunctionRemap *remap,
           }
           extra_convert << "}\n";
 
+        } else if (is_optional && maybe_none) {
+          extra_param_check << " && (" << param_name << " == NULL || " << param_name << " == Py_None || " << coerce_call << ")";
+
         } else if (is_optional) {
           extra_param_check << " && (" << param_name << " == NULL || " << coerce_call << ")";
 
+        } else if (maybe_none) {
+          extra_param_check << " && (" << param_name << " == Py_None || " << coerce_call << ")";
+
         } else {
           extra_param_check << " && " << coerce_call;
         }
 
-      } else {
+      } else { // The regular, non-coercion case.
         type->output_instance(extra_convert, param_name + "_this", &parser);
-        if (is_optional) {
+        if (is_optional && maybe_none) {
+          extra_convert
+            << default_expr << ";\n"
+            << "if (" << param_name << " != NULL && " << param_name << " != Py_None) {\n"
+            << "  " << param_name << "_this";
+        } else if (is_optional) {
           extra_convert
             << default_expr << ";\n"
-            << "if (" << param_name << " != (PyObject *)NULL) {\n"
+            << "if (" << param_name << " != NULL) {\n"
+            << "  " << param_name << "_this";
+        } else if (maybe_none) {
+          extra_convert
+            << " = NULL;\n"
+            << "if (" << param_name << " != Py_None) {\n"
             << "  " << param_name << "_this";
         }
         if (const_ok && !report_errors) {
@@ -5529,7 +5571,7 @@ write_function_instance(ostream &out, FunctionRemap *remap,
           // simpler.  But maybe we should just reorganize these functions
           // entirely?
           extra_convert << " = NULL;\n";
-          int indent_level = is_optional ? 2 : 0;
+          int indent_level = (is_optional || maybe_none) ? 2 : 0;
           indent(extra_convert, indent_level)
             << "DtoolInstance_GetPointer(" << param_name
             << ", " << param_name << "_this"
@@ -5545,9 +5587,15 @@ write_function_instance(ostream &out, FunctionRemap *remap,
             << "\", " << const_ok << ", " << report_errors << ");\n";
         }
 
-        if (is_optional) {
+        if (is_optional && maybe_none) {
+          extra_convert << "}\n";
+          extra_param_check << " && (" << param_name << " == NULL || " << param_name << " == Py_None || " << param_name << "_this != NULL)";
+        } else if (is_optional) {
           extra_convert << "}\n";
           extra_param_check << " && (" << param_name << " == NULL || " << param_name << "_this != NULL)";
+        } else if (maybe_none) {
+          extra_convert << "}\n";
+          extra_param_check << " && (" << param_name << " == Py_None || " << param_name << "_this != NULL)";
         } else {
           extra_param_check << " && " << param_name << "_this != NULL";
         }

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