Ver código fonte

Merge branch 'master' into input-overhaul

rdb 7 anos atrás
pai
commit
70bfe21a63
91 arquivos alterados com 1614 adições e 1981 exclusões
  1. 4 2
      .travis.yml
  2. 0 9
      direct/src/configfiles/direct.init
  3. 1 2
      direct/src/distributed/DistributedSmoothNode.py
  4. 25 0
      direct/src/showbase/DConfig.py
  5. 4 3
      direct/src/showbase/ShowBase.py
  6. 1 2
      direct/src/showbase/ShowBaseGlobal.py
  7. 0 8
      direct/src/showbase/showBase.cxx
  8. 0 1
      direct/src/showbase/showBase.h
  9. 0 21
      dtool/src/dconfig/config_dconfig.cxx
  10. 0 29
      dtool/src/dconfig/config_dconfig.h
  11. 0 42
      dtool/src/dconfig/dconfig.I
  12. 0 14
      dtool/src/dconfig/dconfig.cxx
  13. 1 26
      dtool/src/dconfig/dconfig.h
  14. 0 3
      dtool/src/dconfig/p3dconfig_composite1.cxx
  15. 0 35
      dtool/src/dconfig/test_config.cxx
  16. 0 87
      dtool/src/dconfig/test_expand.cxx
  17. 0 32
      dtool/src/dconfig/test_pfstream.cxx
  18. 0 48
      dtool/src/dconfig/test_searchpath.cxx
  19. 0 2
      dtool/src/dtoolbase/dtoolbase.h
  20. 15 0
      dtool/src/dtoolbase/typeHandle.cxx
  21. 4 0
      dtool/src/dtoolbase/typeHandle.h
  22. 2 1
      dtool/src/dtoolbase/typeHandle_ext.cxx
  23. 18 0
      dtool/src/dtoolbase/typeRegistry.cxx
  24. 3 0
      dtool/src/dtoolbase/typeRegistry.h
  25. 13 0
      dtool/src/dtoolbase/typeRegistryNode.I
  26. 23 0
      dtool/src/dtoolbase/typeRegistryNode.cxx
  27. 5 0
      dtool/src/dtoolbase/typeRegistryNode.h
  28. 75 41
      dtool/src/interrogate/interfaceMakerPythonNative.cxx
  29. 0 3
      dtool/src/interrogate/interrogate.cxx
  30. 9 14
      dtool/src/interrogate/interrogate_module.cxx
  31. 0 3
      dtool/src/interrogate/parse_file.cxx
  32. 103 91
      dtool/src/interrogatedb/dtool_super_base.cxx
  33. 0 1
      dtool/src/interrogatedb/p3interrogatedb_composite1.cxx
  34. 0 3
      dtool/src/interrogatedb/p3interrogatedb_composite2.cxx
  35. 0 7
      dtool/src/interrogatedb/py_compat.cxx
  36. 1 8
      dtool/src/interrogatedb/py_compat.h
  37. 17 12
      dtool/src/interrogatedb/py_panda.I
  38. 48 174
      dtool/src/interrogatedb/py_panda.cxx
  39. 42 53
      dtool/src/interrogatedb/py_panda.h
  40. 299 674
      dtool/src/interrogatedb/py_wrappers.cxx
  41. 6 23
      dtool/src/interrogatedb/py_wrappers.h
  42. 4 0
      dtool/src/parser-inc/vrpn_Analog.h
  43. 4 0
      dtool/src/parser-inc/vrpn_Button.h
  44. 3 0
      dtool/src/parser-inc/vrpn_Configure.h
  45. 3 0
      dtool/src/parser-inc/vrpn_Connection.h
  46. 4 0
      dtool/src/parser-inc/vrpn_Dial.h
  47. 6 0
      dtool/src/parser-inc/vrpn_Tracker.h
  48. 8 0
      dtool/src/pystub/pystub.cxx
  49. 0 3
      dtool/src/test_interrogate/test_interrogate.cxx
  50. 16 7
      makepanda/installer.nsi
  51. 6 1
      makepanda/installpanda.py
  52. 222 262
      makepanda/makepanda.py
  53. 128 9
      makepanda/makepandacore.py
  54. 1 1
      makepanda/makewheel.py
  55. 1 1
      panda/src/audiotraits/fmodAudioSound.cxx
  56. 1 1
      panda/src/audiotraits/fmodAudioSound.h
  57. 9 4
      panda/src/collide/collisionHandlerQueue.cxx
  58. 0 10
      panda/src/configfiles/panda.init
  59. 0 1
      panda/src/dxgsg9/dxgsg9base.h
  60. 8 26
      panda/src/dxgsg9/wdxGraphicsPipe9.cxx
  61. 0 1
      panda/src/dxgsg9/wdxGraphicsPipe9.h
  62. 1 2
      panda/src/dxgsg9/wdxGraphicsWindow9.cxx
  63. 1 8
      panda/src/event/asyncFuture_ext.cxx
  64. 1 1
      panda/src/event/asyncFuture_ext.h
  65. 0 8
      panda/src/express/config_express.cxx
  66. 0 5
      panda/src/express/config_express.h
  67. 2 0
      panda/src/express/virtualFileSystem.cxx
  68. 72 0
      panda/src/glstuff/glShaderContext_src.cxx
  69. 1 5
      panda/src/gobj/internalName.h
  70. 12 2
      panda/src/gobj/internalName_ext.cxx
  71. 1 5
      panda/src/gobj/internalName_ext.h
  72. 285 94
      panda/src/gobj/shader.cxx
  73. 10 3
      panda/src/gobj/shader.h
  74. 1 3
      panda/src/ode/odeBody.I
  75. 4 23
      panda/src/ode/odeBody.cxx
  76. 8 7
      panda/src/ode/odeBody.h
  77. 13 0
      panda/src/ode/odeBody_ext.I
  78. 37 0
      panda/src/ode/odeBody_ext.cxx
  79. 3 0
      panda/src/ode/odeBody_ext.h
  80. 1 0
      panda/src/ode/p3ode_ext_composite.cxx
  81. 1 0
      panda/src/pgraph/config_pgraph.h
  82. 1 0
      panda/src/physx/config_physx.h
  83. 1 1
      panda/src/pipeline/cycleData.h
  84. 2 0
      panda/src/putil/config_putil.h
  85. 6 1
      panda/src/vision/webcamVideoCursorOpenCV.cxx
  86. 1 0
      panda/src/vision/webcamVideoCursorOpenCV.h
  87. 5 0
      panda/src/vision/webcamVideoCursorV4L.cxx
  88. 0 10
      panda/src/vrpn/vrpn_interface.h
  89. 1 0
      panda/src/windisplay/winDetectDx9.cxx
  90. 0 1
      pandatool/src/configfiles/pandatool.init
  91. 0 1
      pandatool/src/progbase/programBase.cxx

+ 4 - 2
.travis.yml

@@ -11,6 +11,8 @@ matrix:
       before_install:
         - export CC=gcc-4.7
         - export CXX=g++-4.7
+    - compiler: clang
+      env: PYTHONV=python3 FLAGS=--no-python SKIP_TESTS=1
 addons:
   apt:
     sources:
@@ -42,8 +44,8 @@ install:
     - $PYTHONV -m pip install pytest
 script:
     - $PYTHONV makepanda/makepanda.py --everything --git-commit $TRAVIS_COMMIT $FLAGS --threads 4
-    - LD_LIBRARY_PATH=built/lib PYTHONPATH=built $PYTHONV makepanda/test_imports.py
-    - LD_LIBRARY_PATH=built/lib PYTHONPATH=built $PYTHONV -m pytest -v tests
+    - test -n "$SKIP_TESTS" || LD_LIBRARY_PATH=built/lib PYTHONPATH=built $PYTHONV makepanda/test_imports.py
+    - test -n "$SKIP_TESTS" || LD_LIBRARY_PATH=built/lib PYTHONPATH=built $PYTHONV -m pytest -v tests
 notifications:
   irc:
     channels:

+ 0 - 9
direct/src/configfiles/direct.init

@@ -1,9 +0,0 @@
-ATTACH dmodels
-ATTACH panda
-MODREL ETC_PATH etc
-DOCSH set parent=`dirname $DIRECT`
-DOCSH if ( ${?PANDA_ROOT} ) then
-DOCSH   setenv PYTHONPATH "${PYTHONPATH};"`cygpath -w "$parent"`
-DOCSH else
-DOCSH   setenv PYTHONPATH "${PYTHONPATH}:$parent"
-DOCSH endif

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

@@ -6,8 +6,7 @@ from .ClockDelta import *
 from . import DistributedNode
 from . import DistributedSmoothNodeBase
 from direct.task.Task import cont
-
-config = get_config_showbase()
+from direct.showbase import DConfig as config
 
 # This number defines our tolerance for out-of-sync telemetry packets.
 # If a packet appears to have originated from more than MaxFuture

+ 25 - 0
direct/src/showbase/DConfig.py

@@ -0,0 +1,25 @@
+"This module contains a deprecated shim emulating the old DConfig API."
+
+__all__ = []
+
+from panda3d.core import (ConfigFlags, ConfigVariableBool, ConfigVariableInt,
+                          ConfigVariableDouble, ConfigVariableString)
+
+
+def GetBool(sym, default=False):
+    return ConfigVariableBool(sym, default, "DConfig", ConfigFlags.F_dconfig).value
+
+
+def GetInt(sym, default=0):
+    return ConfigVariableInt(sym, default, "DConfig", ConfigFlags.F_dconfig).value
+
+
+def GetDouble(sym, default=0.0):
+    return ConfigVariableDouble(sym, default, "DConfig", ConfigFlags.F_dconfig).value
+
+
+def GetString(sym, default=""):
+    return ConfigVariableString(sym, default, "DConfig", ConfigFlags.F_dconfig).value
+
+
+GetFloat = GetDouble

+ 4 - 3
direct/src/showbase/ShowBase.py

@@ -10,8 +10,9 @@ __all__ = ['ShowBase', 'WindowControls']
 #import VerboseImport
 
 from panda3d.core import *
-from panda3d.direct import get_config_showbase, throw_new_frame, init_app_for_gui
+from panda3d.direct import throw_new_frame, init_app_for_gui
 from panda3d.direct import storeAccessibilityShortcutKeys, allowAccessibilityShortcutKeys
+from . import DConfig
 
 # Register the extension methods for NodePath.
 from direct.extensions_native import NodePath_extensions
@@ -22,7 +23,7 @@ if sys.version_info >= (3, 0):
     import builtins
 else:
     import __builtin__ as builtins
-builtins.config = get_config_showbase()
+builtins.config = DConfig
 
 from direct.directnotify.DirectNotifyGlobal import directNotify, giveNotify
 from .MessengerGlobal import messenger
@@ -57,7 +58,7 @@ def exitfunc():
 # *seem* to cause anyone any problems.
 class ShowBase(DirectObject.DirectObject):
 
-    config = get_config_showbase()
+    config = DConfig
     notify = directNotify.newCategory("ShowBase")
 
     def __init__(self, fStartDirect = True, windowType = None):

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

@@ -12,9 +12,8 @@ from direct.directnotify.DirectNotifyGlobal import directNotify, giveNotify
 from panda3d.core import VirtualFileSystem, Notify, ClockObject, PandaSystem
 from panda3d.core import ConfigPageManager, ConfigVariableManager
 from panda3d.core import NodePath, PGTop
-from panda3d.direct import get_config_showbase
+from . import DConfig as config
 
-config = get_config_showbase()
 __dev__ = config.GetBool('want-dev', __debug__)
 
 vfs = VirtualFileSystem.getGlobalPtr()

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

@@ -61,14 +61,6 @@ throw_new_frame() {
   throw_event("NewFrame");
 }
 
-// Returns the configure object for accessing config variables from a
-// scripting language.
-DConfig &
-get_config_showbase() {
-  static DConfig config_showbase;
-  return config_showbase;
-}
-
 // Initialize the application for making a Gui-based app, such as wx.  At the
 // moment, this is a no-op except on Mac.
 void

+ 0 - 1
direct/src/showbase/showBase.h

@@ -38,7 +38,6 @@ EXPCL_DIRECT_SHOWBASE ConfigVariableSearchPath &get_particle_path();
 
 EXPCL_DIRECT_SHOWBASE void throw_new_frame();
 
-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++

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

@@ -1,21 +0,0 @@
-/**
- * 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 config_dconfig.cxx
- * @author drose
- * @date 2000-05-15
- */
-
-#include "config_dconfig.h"
-
-#if !defined(CPPPARSER) && !defined(LINK_ALL_STATIC) && !defined(BUILDING_DTOOL_DCONFIG)
-  #error Buildsystem error: BUILDING_DTOOL_DCONFIG not defined
-#endif
-
-NotifyCategoryDef(dconfig, "");
-NotifyCategoryDef(microconfig, "dconfig");

+ 0 - 29
dtool/src/dconfig/config_dconfig.h

@@ -1,29 +0,0 @@
-/**
- * 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 config_dconfig.h
- * @author drose
- * @date 2000-05-15
- */
-
-#ifndef CONFIG_DCONFIG_H
-#define CONFIG_DCONFIG_H
-
-#ifdef WIN32_VC
-/* C4231: extern before template instantiation */
-/* MPG - For some reason, this one only works if it's here */
-#pragma warning (disable : 4231)
-#endif
-
-#include "dtoolbase.h"
-#include "notifyCategoryProxy.h"
-
-NotifyCategoryDecl(dconfig, EXPCL_DTOOL_DCONFIG, EXPTP_DTOOL_DCONFIG);
-NotifyCategoryDecl(microconfig, EXPCL_DTOOL_DCONFIG, EXPTP_DTOOL_DCONFIG);
-
-#endif

+ 0 - 42
dtool/src/dconfig/dconfig.I

@@ -1,42 +0,0 @@
-/**
- * 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 dconfig.I
- * @author cary
- * @date 2000-03-20
- */
-
-bool DConfig::
-GetBool(const std::string &sym, bool def) {
-  ConfigVariableBool var(sym, def, "DConfig", ConfigFlags::F_dconfig);
-  return var.get_value();
-}
-
-int DConfig::
-GetInt(const std::string &sym, int def) {
-  ConfigVariableInt var(sym, def, "DConfig", ConfigFlags::F_dconfig);
-  return var.get_value();
-}
-
-float DConfig::
-GetFloat(const std::string &sym, float def) {
-  ConfigVariableDouble var(sym, (double)def, "DConfig", ConfigFlags::F_dconfig);
-  return (float)var.get_value();
-}
-
-double DConfig::
-GetDouble(const std::string &sym, double def) {
-  ConfigVariableDouble var(sym, def, "DConfig", ConfigFlags::F_dconfig);
-  return var.get_value();
-}
-
-std::string DConfig::
-GetString(const std::string &sym, const std::string &def) {
-  ConfigVariableString var(sym, def, "DConfig", ConfigFlags::F_dconfig);
-  return var.get_value();
-}

+ 0 - 14
dtool/src/dconfig/dconfig.cxx

@@ -1,14 +0,0 @@
-/**
- * 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 dconfig.cxx
- * @author drose
- * @date 1999-02-08
- */
-
-#include "dconfig.h"

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

@@ -15,32 +15,7 @@
 #define DCONFIG_H
 
 #include "dtoolbase.h"
-
-#include "config_dconfig.h"
-#include "configVariableString.h"
-#include "configVariableBool.h"
-#include "configVariableInt.h"
-#include "configVariableDouble.h"
-#include "configVariableList.h"
-#include "configFlags.h"
-
-/**
- * This class emulates the old dconfig-style interface to our Panda config
- * system.  It exists only to provide backward-compatible support, and it is
- * used primarily by Python code.  For modern code, use the new
- * ConfigVariable* interface instead of this deprecated interface.
- */
-class EXPCL_DTOOL_DCONFIG DConfig {
-PUBLISHED:
-  static INLINE bool GetBool(const std::string &sym, bool def = false);
-  static INLINE int GetInt(const std::string &sym, int def = 0);
-  static INLINE float GetFloat(const std::string &sym, float def = 0.);
-  static INLINE double GetDouble(const std::string &sym, double def = 0.);
-  static INLINE std::string GetString(const std::string &sym, const std::string &def = "");
-};
-
-#include "dconfig.I"
-
+#include "notifyCategoryProxy.h"
 
 // These macros are used in each directory to call an initialization function
 // at static-init time.  These macros may eventually be phased out in favor of

+ 0 - 3
dtool/src/dconfig/p3dconfig_composite1.cxx

@@ -1,3 +0,0 @@
-
-#include "config_dconfig.cxx"
-#include "dconfig.cxx"

+ 0 - 35
dtool/src/dconfig/test_config.cxx

@@ -1,35 +0,0 @@
-/**
- * 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 test_config.cxx
- * @author cary
- * @date 1998-09-10
- */
-
-#include "dconfig.h"
-
-using std::cout;
-using std::endl;
-
-#define SNARF
-Configure(test);
-
-std::string foo = test.GetString("user");
-std::string path = test.GetString("LD_LIBRARY_PATH");
-
-ConfigureFn(test)
-{
-   cout << "AIEE!  Doing work before main()!  The sky is falling!" << endl;
-}
-
-main()
-{
-   cout << "Testing Configuration functionality:" << endl;
-   cout << "foo = " << foo << endl;
-   cout << "path = " << path << endl;
-}

+ 0 - 87
dtool/src/dconfig/test_expand.cxx

@@ -1,87 +0,0 @@
-/**
- * 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 test_expand.cxx
- * @author cary
- * @date 1998-08-31
- */
-
-#include "expand.h"
-#include <string>
-
-using std::cout;
-using std::endl;
-
-void TestExpandFunction()
-{
-   std::string line;
-
-   line = "foo";
-   cout << "input: '" << line << "'" << endl;
-   cout << "output: '" << Expand::Expand(line) << "'" << endl;
-   line = "'foo'";
-   cout << "input: '" << line << "'" << endl;
-   cout << "output: '" << Expand::Expand(line) << "'" << endl;
-   line = "'$USER'";
-   cout << "input: '" << line << "'" << endl;
-   cout << "output: '" << Expand::Expand(line) << "'" << endl;
-   line = "$USER";
-   cout << "input: '" << line << "'" << endl;
-   cout << "output: '" << Expand::Expand(line) << "'" << endl;
-   line = "\"$USER\"";
-   cout << "input: '" << line << "'" << endl;
-   cout << "output: '" << Expand::Expand(line) << "'" << endl;
-   line = "`ls -l`";
-   cout << "input: '" << line << "'" << endl;
-   cout << "output: '" << Expand::Expand(line) << "'" << endl;
-   line = "~";
-   cout << "input: '" << line << "'" << endl;
-   cout << "output: '" << Expand::Expand(line) << "'" << endl;
-   line = "~cary";
-   cout << "input: '" << line << "'" << endl;
-   cout << "output: '" << Expand::Expand(line) << "'" << endl;
-}
-
-void TestExpandClass()
-{
-   std::string line;
-
-   line = "foo";
-   Expand::Expander ex(line);
-   cout << "input: '" << line << "'" << endl;
-   cout << "output: '" << ex() << "'" << endl;
-   line = "'foo'";
-   cout << "input: '" << line << "'" << endl;
-   cout << "output: '" << ex(line) << "'" << endl;
-   line = "'$USER'";
-   cout << "input: '" << line << "'" << endl;
-   cout << "output: '" << ex(line) << "'" << endl;
-   line = "$USER";
-   cout << "input: '" << line << "'" << endl;
-   cout << "output: '" << ex(line) << "'" << endl;
-   line = "\"$USER\"";
-   cout << "input: '" << line << "'" << endl;
-   cout << "output: '" << ex(line) << "'" << endl;
-   line = "`ls -l`";
-   cout << "input: '" << line << "'" << endl;
-   cout << "output: '" << ex(line) << "'" << endl;
-   line = "~";
-   cout << "input: '" << line << "'" << endl;
-   cout << "output: '" << ex(line) << "'" << endl;
-   line = "~cary";
-   cout << "input: '" << line << "'" << endl;
-   cout << "output: '" << ex(line) << "'" << endl;
-}
-
-main()
-{
-   cout << endl << "Testing shell expansion (function version):" << endl;
-   TestExpandFunction();
-   cout << endl << "Testing shell expansion (class version):" << endl;
-   TestExpandClass();
-}

+ 0 - 32
dtool/src/dconfig/test_pfstream.cxx

@@ -1,32 +0,0 @@
-/**
- * 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 test_pfstream.cxx
- * @author cary
- * @date 1998-08-31
- */
-
-#include "pfstream.h"
-#include <string>
-
-void ReadIt(std::istream& ifs) {
-   std::string line;
-
-   while (!ifs.eof()) {
-      std::getline(ifs, line);
-      if (line.length() != 0)
-         std::cout << line << std::endl;
-   }
-}
-
-main()
-{
-   IPipeStream ipfs("ls -l");
-
-   ReadIt(ipfs);
-}

+ 0 - 48
dtool/src/dconfig/test_searchpath.cxx

@@ -1,48 +0,0 @@
-/**
- * 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 test_searchpath.cxx
- * @author cary
- * @date 1998-09-01
- */
-
-#include "dSearchPath.h"
-// #include "expand.h"
-#include <string>
-
-using std::cout;
-using std::endl;
-
-void TestSearch()
-{
-   std::string line, path;
-
-// path = ".:~ etc";
-   path = ". /etc";
-// path = Expand::Expand(path);
-   line = "searchpath.h";
-   cout << "looking for file '" << line << "' in path '" << path << "': '";
-   line = DSearchPath::search_path(line, path);
-   cout << line << "'" << endl;
-
-   line = ".cshrc";
-   cout << "looking for file '" << line << "' in path '" << path << "': '";
-   line = DSearchPath::search_path(line, path);
-   cout << line << "'" << endl;
-
-   line = "passwd";
-   cout << "looking for file '" << line << "' in path '" << path << "': '";
-   line = DSearchPath::search_path(line, path);
-   cout << line << "'" << endl;
-}
-
-main()
-{
-   cout << "Testing search path:" << endl;
-   TestSearch();
-}

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

@@ -138,12 +138,10 @@
 #endif
 #endif
 
-#ifdef HAVE_PYTHON
 // Instead of including the Python headers, which will implicitly add a linker
 // flag to link in Python, we'll just excerpt the forward declaration of
 // PyObject.
 typedef struct _object PyObject;
-#endif
 
 #ifndef HAVE_EIGEN
 // If we don't have the Eigen library, don't define LINMATH_ALIGN.

+ 15 - 0
dtool/src/dtoolbase/typeHandle.cxx

@@ -153,6 +153,21 @@ deallocate_array(void *ptr) {
   PANDA_FREE_ARRAY(ptr);
 }
 
+#ifdef HAVE_PYTHON
+/**
+ * Returns the internal void pointer that is stored for interrogate's benefit.
+ */
+PyObject *TypeHandle::
+get_python_type() const {
+  TypeRegistryNode *rnode = TypeRegistry::ptr()->look_up(*this, nullptr);
+  if (rnode != nullptr) {
+    return rnode->get_python_type();
+  } else {
+    return nullptr;
+  }
+}
+#endif
+
 /**
  * Return the Index of the BEst fit Classs from a set
  */

+ 4 - 0
dtool/src/dtoolbase/typeHandle.h

@@ -138,6 +138,10 @@ PUBLISHED:
   MAKE_SEQ_PROPERTY(child_classes, get_num_child_classes, get_child_class);
 
 public:
+#ifdef HAVE_PYTHON
+  PyObject *get_python_type() const;
+#endif
+
   void *allocate_array(size_t size) RETURNS_ALIGNED(MEMORY_HOOK_ALIGNMENT);
   void *reallocate_array(void *ptr, size_t size) RETURNS_ALIGNED(MEMORY_HOOK_ALIGNMENT);
   void deallocate_array(void *ptr);

+ 2 - 1
dtool/src/dtoolbase/typeHandle_ext.cxx

@@ -22,7 +22,8 @@
  */
 TypeHandle Extension<TypeHandle>::
 make(PyTypeObject *tp) {
-  if (!PyType_IsSubtype(tp, &Dtool_DTOOL_SUPER_BASE._PyType)) {
+  Dtool_PyTypedObject *super_base = Dtool_GetSuperBase();
+  if (!PyType_IsSubtype(tp, (PyTypeObject *)super_base)) {
     PyErr_SetString(PyExc_TypeError, "a Panda type is required");
     return TypeHandle::none();
   }

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

@@ -207,6 +207,24 @@ record_alternate_name(TypeHandle type, const string &name) {
   _lock->unlock();
 }
 
+#ifdef HAVE_PYTHON
+/**
+ * Records the given Python type pointer in the type registry for the benefit
+ * of interrogate.
+ */
+void TypeRegistry::
+record_python_type(TypeHandle type, PyObject *python_type) {
+  _lock->lock();
+
+  TypeRegistryNode *rnode = look_up(type, nullptr);
+  if (rnode != nullptr) {
+    rnode->_python_type = python_type;
+  }
+
+  _lock->unlock();
+}
+#endif
+
 /**
  * Looks for a previously-registered type of the given name.  Returns its
  * TypeHandle if it exists, or TypeHandle::none() if there is no such type.

+ 3 - 0
dtool/src/dtoolbase/typeRegistry.h

@@ -45,6 +45,9 @@ PUBLISHED:
 
   void record_derivation(TypeHandle child, TypeHandle parent);
   void record_alternate_name(TypeHandle type, const std::string &name);
+#ifdef HAVE_PYTHON
+  void record_python_type(TypeHandle type, PyObject *python_type);
+#endif
 
   TypeHandle find_type(const std::string &name) const;
   TypeHandle find_type_by_id(int id) const;

+ 13 - 0
dtool/src/dtoolbase/typeRegistryNode.I

@@ -11,6 +11,19 @@
  * @date 2001-08-06
  */
 
+/**
+ * Returns the Python type object associated with this node.
+ */
+INLINE PyObject *TypeRegistryNode::
+get_python_type() const {
+  if (_python_type != nullptr || _parent_classes.empty()) {
+    return _python_type;
+  } else {
+    // Recurse through parent classes.
+    return r_get_python_type();
+  }
+}
+
 /**
  *
  */

+ 23 - 0
dtool/src/dtoolbase/typeRegistryNode.cxx

@@ -308,6 +308,29 @@ r_build_subtrees(TypeRegistryNode *top, int bit_count,
   }
 }
 
+/**
+ * Recurses through the parent nodes to find the best Python type object to
+ * represent objects of this type.
+ */
+PyObject *TypeRegistryNode::
+r_get_python_type() const {
+  Classes::const_iterator ni;
+  for (ni = _parent_classes.begin(); ni != _parent_classes.end(); ++ni) {
+    const TypeRegistryNode *parent = *ni;
+    if (parent->_python_type != nullptr) {
+      return parent->_python_type;
+
+    } else if (!parent->_parent_classes.empty()) {
+      PyObject *py_type = parent->r_get_python_type();
+      if (py_type != nullptr) {
+        return py_type;
+      }
+    }
+  }
+
+  return nullptr;
+}
+
 /**
  * A recursive function to double-check the result of is_derived_from().  This
  * is the slow, examine-the-whole-graph approach, as opposed to the clever and

+ 5 - 0
dtool/src/dtoolbase/typeRegistryNode.h

@@ -37,6 +37,8 @@ public:
   static TypeHandle get_parent_towards(const TypeRegistryNode *child,
                                        const TypeRegistryNode *base);
 
+  INLINE PyObject *get_python_type() const;
+
   void clear_subtree();
   void define_subtree();
 
@@ -46,6 +48,7 @@ public:
   typedef std::vector<TypeRegistryNode *> Classes;
   Classes _parent_classes;
   Classes _child_classes;
+  PyObject *_python_type = nullptr;
 
   AtomicAdjust::Integer _memory_usage[TypeHandle::MC_limit];
 
@@ -77,6 +80,8 @@ private:
   void r_build_subtrees(TypeRegistryNode *top,
                         int bit_count, SubtreeMaskType bits);
 
+  PyObject *r_get_python_type() const;
+
   static bool check_derived_from(const TypeRegistryNode *child,
                                  const TypeRegistryNode *base);
 

+ 75 - 41
dtool/src/interrogate/interfaceMakerPythonNative.cxx

@@ -821,10 +821,54 @@ write_prototypes(ostream &out_code, ostream *out_h) {
     }
   }
 
+  out_code << "/**\n";
+  out_code << " * Declarations for exported classes\n";
+  out_code << " */\n";
+
+  out_code << "static const Dtool_TypeDef exports[] = {\n";
+
+  for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
+    Object *object = (*oi).second;
+
+    if (object->_itype.is_class() || object->_itype.is_struct()) {
+      CPPType *type = object->_itype._cpptype;
+
+      if (isExportThisRun(type) && is_cpp_type_legal(type)) {
+        string class_name = type->get_local_name(&parser);
+        string safe_name = make_safe_name(class_name);
+
+        out_code << "  {\"" << class_name << "\", &Dtool_" << safe_name << "},\n";
+      }
+    }
+  }
+
+  out_code << "  {nullptr, nullptr},\n";
+  out_code << "};\n\n";
+
   out_code << "/**\n";
   out_code << " * Extern declarations for imported classes\n";
   out_code << " */\n";
 
+  // Write out a table of the externally imported types that will be filled in
+  // upon module initialization.
+  if (!_external_imports.empty()) {
+    out_code << "#ifndef LINK_ALL_STATIC\n";
+    out_code << "static Dtool_TypeDef imports[] = {\n";
+
+    int idx = 0;
+    for (CPPType *type : _external_imports) {
+      string class_name = type->get_local_name(&parser);
+      string safe_name = make_safe_name(class_name);
+
+      out_code << "  {\"" << class_name << "\", nullptr},\n";
+      out_code << "#define Dtool_Ptr_" << safe_name << " (imports[" << idx << "].type)\n";
+      ++idx;
+    }
+    out_code << "  {nullptr, nullptr},\n";
+    out_code << "};\n";
+    out_code << "#endif\n\n";
+  }
+
   for (CPPType *type : _external_imports) {
     string class_name = type->get_local_name(&parser);
     string safe_name = make_safe_name(class_name);
@@ -834,7 +878,9 @@ write_prototypes(ostream &out_code, ostream *out_h) {
     out_code << "#ifndef LINK_ALL_STATIC\n";
     // out_code << "IMPORT_THIS struct Dtool_PyTypedObject Dtool_" <<
     // safe_name << ";\n";
-    out_code << "static struct Dtool_PyTypedObject *Dtool_Ptr_" << safe_name << ";\n";
+    //if (has_get_class_type_function(type)) {
+    //  out_code << "static struct Dtool_PyTypedObject *Dtool_Ptr_" << safe_name << ";\n";
+    //}
     // out_code << "#define Dtool_Ptr_" << safe_name << " &Dtool_" <<
     // safe_name << "\n"; out_code << "IMPORT_THIS void
     // Dtool_PyModuleClassInit_" << safe_name << "(PyObject *module);\n";
@@ -1258,36 +1304,36 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
 
   Objects::iterator oi;
 
-  out << "void Dtool_" << def->library_name << "_RegisterTypes() {\n";
+  out << "void Dtool_" << def->library_name << "_RegisterTypes() {\n"
+         "  TypeRegistry *registry = TypeRegistry::ptr();\n"
+         "  nassertv(registry != nullptr);\n";
+
   for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
     Object *object = (*oi).second;
-    if (object->_itype.is_class() ||
-        object->_itype.is_struct()) {
-      if (is_cpp_type_legal(object->_itype._cpptype) &&
-          isExportThisRun(object->_itype._cpptype)) {
-        string class_name = make_safe_name(object->_itype.get_scoped_name());
-        bool is_typed = has_get_class_type_function(object->_itype._cpptype);
+    if (object->_itype.is_class() || object->_itype.is_struct()) {
+      CPPType *type = object->_itype._cpptype;
+      if (is_cpp_type_legal(type) && isExportThisRun(type)) {
+        string class_name = object->_itype.get_scoped_name();
+        string safe_name = make_safe_name(class_name);
+        bool is_typed = has_get_class_type_function(type);
 
         if (is_typed) {
-          if (has_init_type_function(object->_itype._cpptype)) {
+          out << "  {\n";
+          if (has_init_type_function(type)) {
             // 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)
+            out << "    " << type->get_local_name(&parser)
                 << "::init_type();\n";
           }
-          out << "  Dtool_" << class_name << "._type = "
-              << object->_itype._cpptype->get_local_name(&parser)
-              << "::get_class_type();\n"
-              << "  RegisterRuntimeTypedClass(Dtool_" << class_name << ");\n";
-
+          out << "    TypeHandle handle = " << type->get_local_name(&parser)
+              << "::get_class_type();\n";
+          out << "    Dtool_" << safe_name << "._type = handle;\n";
+          out << "    registry->record_python_type(handle, "
+                 "(PyObject *)&Dtool_" << safe_name << ");\n";
+          out << "  }\n";
         } else {
-          out << "#ifndef LINK_ALL_STATIC\n"
-              << "  RegisterNamedClass(\"" << object->_itype.get_scoped_name()
-              << "\", Dtool_" << class_name << ");\n"
-              << "#endif\n";
-
-          if (IsPandaTypedObject(object->_itype._cpptype->as_struct_type())) {
+          if (IsPandaTypedObject(type->as_struct_type())) {
             nout << object->_itype.get_scoped_name() << " derives from TypedObject, "
                  << "but does not define a get_class_type() function.\n";
           }
@@ -1297,23 +1343,6 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
   }
   out << "}\n\n";
 
-  out << "void Dtool_" << def->library_name << "_ResolveExternals() {\n";
-  out << "#ifndef LINK_ALL_STATIC\n";
-  out << "  // Resolve externally imported types.\n";
-
-  for (CPPType *type : _external_imports) {
-    string class_name = type->get_local_name(&parser);
-    string safe_name = make_safe_name(class_name);
-
-    if (has_get_class_type_function(type)) {
-      out << "  Dtool_Ptr_" << safe_name << " = LookupRuntimeTypedClass(" << class_name << "::get_class_type());\n";
-    } else {
-      out << "  Dtool_Ptr_" << safe_name << " = LookupNamedClass(\"" << class_name << "\");\n";
-    }
-  }
-  out << "#endif\n";
-  out << "}\n\n";
-
   out << "void Dtool_" << def->library_name << "_BuildInstants(PyObject *module) {\n";
   out << "  (void) module;\n";
 
@@ -1466,9 +1495,14 @@ write_module_support(ostream &out, ostream *out_h, InterrogateModuleDef *def) {
 
   out << "  {nullptr, nullptr, 0, nullptr}\n" << "};\n\n";
 
-  out << "struct LibraryDef " << def->library_name << "_moddef = {python_simple_funcs};\n";
+  out << "extern const struct LibraryDef " << def->library_name << "_moddef = {python_simple_funcs, exports, ";
+  if (_external_imports.empty()) {
+    out << "nullptr};\n";
+  } else {
+    out << "imports};\n";
+  }
   if (out_h != nullptr) {
-    *out_h << "extern struct LibraryDef " << def->library_name << "_moddef;\n";
+    *out_h << "extern const struct LibraryDef " << def->library_name << "_moddef;\n";
   }
 }
 
@@ -3063,7 +3097,7 @@ write_module_class(ostream &out, Object *obj) {
 
     out << "    Dtool_" << ClassName << "._PyType.tp_bases = PyTuple_Pack(" << bases.size() << baseargs << ");\n";
   } else {
-    out << "    Dtool_" << ClassName << "._PyType.tp_base = (PyTypeObject *)&Dtool_DTOOL_SUPER_BASE;\n";
+    out << "    Dtool_" << ClassName << "._PyType.tp_base = (PyTypeObject *)Dtool_GetSuperBase();\n";
   }
 
   int num_nested = obj->_itype.number_of_nested_types();

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

@@ -19,7 +19,6 @@
 #include "pnotify.h"
 #include "panda_getopt_long.h"
 #include "preprocess_argv.h"
-#include "pystub.h"
 #include <time.h>
 
 using std::cerr;
@@ -309,8 +308,6 @@ predefine_macro(CPPParser& parser, const string& inoption) {
 
 int
 main(int argc, char **argv) {
-  pystub();
-
   preprocess_argv(argc, argv);
   string command_line;
   int i;

+ 9 - 14
dtool/src/interrogate/interrogate_module.cxx

@@ -19,7 +19,6 @@
 #include "interrogate_interface.h"
 #include "interrogate_request.h"
 #include "load_dso.h"
-#include "pystub.h"
 #include "pnotify.h"
 #include "panda_getopt_long.h"
 #include "preprocess_argv.h"
@@ -30,6 +29,9 @@
 using std::cerr;
 using std::string;
 
+// This contains a big source string determined at compile time.
+extern const char interrogate_preamble_python_native[];
+
 Filename output_code_filename;
 string module_name;
 string library_name;
@@ -286,9 +288,8 @@ int write_python_table_native(std::ostream &out) {
   vector_string::const_iterator ii;
   for (ii = libraries.begin(); ii != libraries.end(); ++ii) {
     printf("Referencing Library %s\n", (*ii).c_str());
-    out << "extern LibraryDef " << *ii << "_moddef;\n";
+    out << "extern const struct LibraryDef " << *ii << "_moddef;\n";
     out << "extern void Dtool_" << *ii << "_RegisterTypes();\n";
-    out << "extern void Dtool_" << *ii << "_ResolveExternals();\n";
     out << "extern void Dtool_" << *ii << "_BuildInstants(PyObject *module);\n";
   }
 
@@ -339,12 +340,9 @@ int write_python_table_native(std::ostream &out) {
   for (ii = libraries.begin(); ii != libraries.end(); ii++) {
     out << "  Dtool_" << *ii << "_RegisterTypes();\n";
   }
-  for (ii = libraries.begin(); ii != libraries.end(); ii++) {
-    out << "  Dtool_" << *ii << "_ResolveExternals();\n";
-  }
   out << "\n";
 
-  out << "  LibraryDef *defs[] = {";
+  out << "  const LibraryDef *defs[] = {";
   for(ii = libraries.begin(); ii != libraries.end(); ii++) {
     out << "&" << *ii << "_moddef, ";
   }
@@ -386,12 +384,9 @@ int write_python_table_native(std::ostream &out) {
   for (ii = libraries.begin(); ii != libraries.end(); ii++) {
     out << "  Dtool_" << *ii << "_RegisterTypes();\n";
   }
-  for (ii = libraries.begin(); ii != libraries.end(); ii++) {
-    out << "  Dtool_" << *ii << "_ResolveExternals();\n";
-  }
   out << "\n";
 
-  out << "  LibraryDef *defs[] = {";
+  out << "  const LibraryDef *defs[] = {";
   for(ii = libraries.begin(); ii != libraries.end(); ii++) {
     out << "&" << *ii << "_moddef, ";
   }
@@ -545,8 +540,6 @@ int main(int argc, char *argv[]) {
   extern int optind;
   int flag;
 
-  pystub();
-
   preprocess_argv(argc, argv);
   flag = getopt_long_only(argc, argv, short_options, long_options, nullptr);
   while (flag != EOF) {
@@ -642,8 +635,10 @@ int main(int argc, char *argv[]) {
 
       if (build_python_native_wrappers) {
         write_python_table_native(output_code);
-      }
 
+        // Output the support code.
+        output_code << interrogate_preamble_python_native << "\n";
+      }
     }
   }
 

+ 0 - 3
dtool/src/interrogate/parse_file.cxx

@@ -22,7 +22,6 @@
 #include "cppGlobals.h"
 #include "panda_getopt_long.h"
 #include "preprocess_argv.h"
-#include "pystub.h"
 #include <stdlib.h>
 
 using std::cerr;
@@ -206,8 +205,6 @@ show_nested_types(const string &str) {
 
 int
 main(int argc, char **argv) {
-  pystub();
-
   extern char *optarg;
   extern int optind;
   const char *optstr = "I:S:D:o:l:vp";

+ 103 - 91
dtool/src/interrogatedb/dtool_super_base.cxx

@@ -15,120 +15,132 @@
 
 #ifdef HAVE_PYTHON
 
-class EmptyClass {
-};
-Define_Module_Class_Private(dtoolconfig, DTOOL_SUPER_BASE, EmptyClass, DTOOL_SUPER_BASE111);
-
 static PyObject *GetSuperBase(PyObject *self) {
-  Py_INCREF((PyTypeObject *)&Dtool_DTOOL_SUPER_BASE); // order is important .. this is used for static functions
-  return (PyObject *) &Dtool_DTOOL_SUPER_BASE;
-};
-
-PyMethodDef Dtool_Methods_DTOOL_SUPER_BASE[] = {
-  { "DtoolGetSuperBase", (PyCFunction) &GetSuperBase, METH_NOARGS, "Will Return SUPERbase Class"},
-  { nullptr, nullptr, 0, nullptr }
+  Dtool_PyTypedObject *super_base = Dtool_GetSuperBase();
+  Py_XINCREF((PyTypeObject *)super_base); // order is important .. this is used for static functions
+  return (PyObject *)super_base;
 };
 
-EXPCL_INTERROGATEDB void Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(PyObject *module) {
-  static bool initdone = false;
-  if (!initdone) {
-
-    initdone = true;
-    Dtool_DTOOL_SUPER_BASE._PyType.tp_dict = PyDict_New();
-    PyDict_SetItemString(Dtool_DTOOL_SUPER_BASE._PyType.tp_dict, "DtoolClassDict", Dtool_DTOOL_SUPER_BASE._PyType.tp_dict);
-
-    if (PyType_Ready((PyTypeObject *)&Dtool_DTOOL_SUPER_BASE) < 0) {
-      PyErr_SetString(PyExc_TypeError, "PyType_Ready(Dtool_DTOOL_SUPER_BASE)");
-      return;
-    }
-    Py_INCREF((PyTypeObject *)&Dtool_DTOOL_SUPER_BASE);
-
-    PyDict_SetItemString(Dtool_DTOOL_SUPER_BASE._PyType.tp_dict, "DtoolGetSuperBase", PyCFunction_New(&Dtool_Methods_DTOOL_SUPER_BASE[0], (PyObject *)&Dtool_DTOOL_SUPER_BASE));
-  }
-
+static void Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(PyObject *module) {
   if (module != nullptr) {
-    Py_INCREF((PyTypeObject *)&Dtool_DTOOL_SUPER_BASE);
-    PyModule_AddObject(module, "DTOOL_SUPER_BASE", (PyObject *)&Dtool_DTOOL_SUPER_BASE);
+    Dtool_PyTypedObject *super_base = Dtool_GetSuperBase();
+    Py_INCREF((PyTypeObject *)&super_base);
+    PyModule_AddObject(module, "DTOOL_SUPER_BASE", (PyObject *)&super_base);
   }
 }
 
-inline void *Dtool_DowncastInterface_DTOOL_SUPER_BASE(void *from_this, Dtool_PyTypedObject *from_type) {
+static void *Dtool_DowncastInterface_DTOOL_SUPER_BASE(void *from_this, Dtool_PyTypedObject *from_type) {
   return nullptr;
 }
 
-inline void *Dtool_UpcastInterface_DTOOL_SUPER_BASE(PyObject *self, Dtool_PyTypedObject *requested_type) {
+static void *Dtool_UpcastInterface_DTOOL_SUPER_BASE(PyObject *self, Dtool_PyTypedObject *requested_type) {
   return nullptr;
 }
 
-int Dtool_Init_DTOOL_SUPER_BASE(PyObject *self, PyObject *args, PyObject *kwds) {
+static int Dtool_Init_DTOOL_SUPER_BASE(PyObject *self, PyObject *args, PyObject *kwds) {
   assert(self != nullptr);
   PyErr_Format(PyExc_TypeError, "cannot init constant class %s", Py_TYPE(self)->tp_name);
   return -1;
 }
 
-EXPORT_THIS Dtool_PyTypedObject Dtool_DTOOL_SUPER_BASE = {
-  {
-    PyVarObject_HEAD_INIT(nullptr, 0)
-    "dtoolconfig.DTOOL_SUPER_BASE",
-    sizeof(Dtool_PyInstDef),
-    0, // tp_itemsize
-    &Dtool_FreeInstance_DTOOL_SUPER_BASE,
-    nullptr, // tp_print
-    nullptr, // tp_getattr
-    nullptr, // tp_setattr
+static void Dtool_FreeInstance_DTOOL_SUPER_BASE(PyObject *self) {
+  Py_TYPE(self)->tp_free(self);
+}
+
+/**
+ * Returns a pointer to the DTOOL_SUPER_BASE class that is the base class of
+ * all Panda types.  This pointer is shared by all modules.
+ */
+Dtool_PyTypedObject *Dtool_GetSuperBase() {
+  Dtool_TypeMap *type_map = Dtool_GetGlobalTypeMap();
+  auto it = type_map->find("DTOOL_SUPER_BASE");
+  if (it != type_map->end()) {
+    return it->second;
+  }
+
+  static PyMethodDef methods[] = {
+    { "DtoolGetSuperBase", (PyCFunction)&GetSuperBase, METH_NOARGS, "Will Return SUPERbase Class"},
+    { nullptr, nullptr, 0, nullptr }
+  };
+
+  static Dtool_PyTypedObject super_base_type = {
+    {
+      PyVarObject_HEAD_INIT(nullptr, 0)
+      "dtoolconfig.DTOOL_SUPER_BASE",
+      sizeof(Dtool_PyInstDef),
+      0, // tp_itemsize
+      &Dtool_FreeInstance_DTOOL_SUPER_BASE,
+      nullptr, // tp_print
+      nullptr, // tp_getattr
+      nullptr, // tp_setattr
 #if PY_MAJOR_VERSION >= 3
-    nullptr, // tp_compare
+      nullptr, // tp_compare
 #else
-    &DtoolInstance_ComparePointers,
+      &DtoolInstance_ComparePointers,
 #endif
-    nullptr, // tp_repr
-    nullptr, // tp_as_number
-    nullptr, // tp_as_sequence
-    nullptr, // tp_as_mapping
-    &DtoolInstance_HashPointer,
-    nullptr, // tp_call
-    nullptr, // tp_str
-    PyObject_GenericGetAttr,
-    PyObject_GenericSetAttr,
-    nullptr, // tp_as_buffer
-    (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES),
-    nullptr, // tp_doc
-    nullptr, // tp_traverse
-    nullptr, // tp_clear
+      nullptr, // tp_repr
+      nullptr, // tp_as_number
+      nullptr, // tp_as_sequence
+      nullptr, // tp_as_mapping
+      &DtoolInstance_HashPointer,
+      nullptr, // tp_call
+      nullptr, // tp_str
+      PyObject_GenericGetAttr,
+      PyObject_GenericSetAttr,
+      nullptr, // tp_as_buffer
+      (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES),
+      nullptr, // tp_doc
+      nullptr, // tp_traverse
+      nullptr, // tp_clear
 #if PY_MAJOR_VERSION >= 3
-    &DtoolInstance_RichComparePointers,
+      &DtoolInstance_RichComparePointers,
 #else
-    nullptr, // tp_richcompare
+      nullptr, // tp_richcompare
 #endif
-    0, // tp_weaklistoffset
-    nullptr, // tp_iter
-    nullptr, // tp_iternext
-    Dtool_Methods_DTOOL_SUPER_BASE,
-    standard_type_members,
-    nullptr, // tp_getset
-    nullptr, // tp_base
-    nullptr, // tp_dict
-    nullptr, // tp_descr_get
-    nullptr, // tp_descr_set
-    0, // tp_dictoffset
-    Dtool_Init_DTOOL_SUPER_BASE,
-    PyType_GenericAlloc,
-    Dtool_new_DTOOL_SUPER_BASE,
-    PyObject_Del,
-    nullptr, // tp_is_gc
-    nullptr, // tp_bases
-    nullptr, // tp_mro
-    nullptr, // tp_cache
-    nullptr, // tp_subclasses
-    nullptr, // tp_weaklist
-    nullptr, // tp_del
-  },
-  TypeHandle::none(),
-  Dtool_PyModuleClassInit_DTOOL_SUPER_BASE,
-  Dtool_UpcastInterface_DTOOL_SUPER_BASE,
-  Dtool_DowncastInterface_DTOOL_SUPER_BASE,
-  nullptr,
-  nullptr,
-};
+      0, // tp_weaklistoffset
+      nullptr, // tp_iter
+      nullptr, // tp_iternext
+      methods,
+      standard_type_members,
+      nullptr, // tp_getset
+      nullptr, // tp_base
+      nullptr, // tp_dict
+      nullptr, // tp_descr_get
+      nullptr, // tp_descr_set
+      0, // tp_dictoffset
+      Dtool_Init_DTOOL_SUPER_BASE,
+      PyType_GenericAlloc,
+      nullptr, // tp_new
+      PyObject_Del,
+      nullptr, // tp_is_gc
+      nullptr, // tp_bases
+      nullptr, // tp_mro
+      nullptr, // tp_cache
+      nullptr, // tp_subclasses
+      nullptr, // tp_weaklist
+      nullptr, // tp_del
+    },
+    TypeHandle::none(),
+    Dtool_PyModuleClassInit_DTOOL_SUPER_BASE,
+    Dtool_UpcastInterface_DTOOL_SUPER_BASE,
+    Dtool_DowncastInterface_DTOOL_SUPER_BASE,
+    nullptr,
+    nullptr,
+  };
+
+  super_base_type._PyType.tp_dict = PyDict_New();
+  PyDict_SetItemString(super_base_type._PyType.tp_dict, "DtoolClassDict", super_base_type._PyType.tp_dict);
+
+  if (PyType_Ready((PyTypeObject *)&super_base_type) < 0) {
+    PyErr_SetString(PyExc_TypeError, "PyType_Ready(Dtool_DTOOL_SUPER_BASE)");
+    return nullptr;
+  }
+  Py_INCREF((PyTypeObject *)&super_base_type);
+
+  PyDict_SetItemString(super_base_type._PyType.tp_dict, "DtoolGetSuperBase", PyCFunction_New(&methods[0], (PyObject *)&super_base_type));
+
+  (*type_map)["DTOOL_SUPER_BASE"] = &super_base_type;
+  return &super_base_type;
+}
 
 #endif  // HAVE_PYTHON

+ 0 - 1
dtool/src/interrogatedb/p3interrogatedb_composite1.cxx

@@ -1,5 +1,4 @@
 #include "config_interrogatedb.cxx"
-#include "dtool_super_base.cxx"
 #include "indexRemapper.cxx"
 #include "interrogateComponent.cxx"
 #include "interrogateDatabase.cxx"

+ 0 - 3
dtool/src/interrogatedb/p3interrogatedb_composite2.cxx

@@ -4,6 +4,3 @@
 #include "interrogate_datafile.cxx"
 #include "interrogate_interface.cxx"
 #include "interrogate_request.cxx"
-#include "py_panda.cxx"
-#include "py_compat.cxx"
-#include "py_wrappers.cxx"

+ 0 - 7
dtool/src/interrogatedb/py_compat.cxx

@@ -1,11 +1,4 @@
 /**
- * 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 py_compat.cxx
  * @author rdb
  * @date 2017-12-03

+ 1 - 8
dtool/src/interrogatedb/py_compat.h

@@ -1,11 +1,4 @@
 /**
- * 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 py_compat.h
  * @author rdb
  * @date 2017-12-02
@@ -106,7 +99,7 @@ typedef int Py_ssize_t;
 // PyInt_FromSize_t automatically picks the right type.
 #  define PyLongOrInt_AS_LONG PyInt_AsLong
 
-EXPCL_INTERROGATEDB size_t PyLongOrInt_AsSize_t(PyObject *);
+size_t PyLongOrInt_AsSize_t(PyObject *);
 #endif
 
 // Which character to use in PyArg_ParseTuple et al for a byte string.

+ 17 - 12
dtool/src/interrogatedb/py_panda.I

@@ -1,11 +1,4 @@
 /**
- * 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 py_panda.I
  * @author rdb
  * @date 2016-06-06
@@ -26,7 +19,7 @@
 template<class T> INLINE bool
 DtoolInstance_GetPointer(PyObject *self, T *&into) {
   if (DtoolInstance_Check(self)) {
-    Dtool_PyTypedObject *target_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
+    Dtool_PyTypedObject *target_class = (Dtool_PyTypedObject *)get_type_handle(T).get_python_type();
     if (target_class != nullptr) {
       if (_IS_FINAL(T)) {
         if (DtoolInstance_TYPE(self) == target_class) {
@@ -116,32 +109,44 @@ INLINE long Dtool_EnumValue_AsLong(PyObject *value) {
  */
 template<class T> INLINE PyObject *
 DTool_CreatePyInstance(const T *obj, bool memory_rules) {
-  Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
+  Dtool_PyTypedObject *known_class = (Dtool_PyTypedObject *)get_type_handle(T).get_python_type();
   nassertr(known_class != nullptr, nullptr);
   return DTool_CreatePyInstance((void*) obj, *known_class, memory_rules, true);
 }
 
 template<class T> INLINE PyObject *
 DTool_CreatePyInstance(T *obj, bool memory_rules) {
-  Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
+  Dtool_PyTypedObject *known_class = (Dtool_PyTypedObject *)get_type_handle(T).get_python_type();
   nassertr(known_class != nullptr, nullptr);
   return DTool_CreatePyInstance((void*) obj, *known_class, memory_rules, false);
 }
 
 template<class T> INLINE PyObject *
 DTool_CreatePyInstanceTyped(const T *obj, bool memory_rules) {
-  Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
+  Dtool_PyTypedObject *known_class = (Dtool_PyTypedObject *)get_type_handle(T).get_python_type();
   nassertr(known_class != nullptr, nullptr);
   return DTool_CreatePyInstanceTyped((void*) obj, *known_class, memory_rules, true, obj->get_type().get_index());
 }
 
 template<class T> INLINE PyObject *
 DTool_CreatePyInstanceTyped(T *obj, bool memory_rules) {
-  Dtool_PyTypedObject *known_class = Dtool_RuntimeTypeDtoolType(get_type_handle(T).get_index());
+  Dtool_PyTypedObject *known_class = (Dtool_PyTypedObject *)get_type_handle(T).get_python_type();
   nassertr(known_class != nullptr, nullptr);
   return DTool_CreatePyInstanceTyped((void*) obj, *known_class, memory_rules, false, obj->get_type().get_index());
 }
 
+/**
+ * Finishes initializing the Dtool_PyInstDef.
+ */
+INLINE int
+DTool_PyInit_Finalize(PyObject *self, void *local_this, Dtool_PyTypedObject *type, bool memory_rules, bool is_const) {
+  ((Dtool_PyInstDef *)self)->_My_Type = type;
+  ((Dtool_PyInstDef *)self)->_ptr_to_object = local_this;
+  ((Dtool_PyInstDef *)self)->_memory_rules = memory_rules;
+  ((Dtool_PyInstDef *)self)->_is_const = is_const;
+  return 0;
+}
+
 /**
  * Checks that the tuple is empty.
  */

+ 48 - 174
dtool/src/interrogatedb/py_panda.cxx

@@ -1,11 +1,4 @@
 /**
- * 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 py_panda.cxx
  * @author drose
  * @date 2005-07-04
@@ -29,10 +22,6 @@ PyMemberDef standard_type_members[] = {
   {nullptr}  /* Sentinel */
 };
 
-static RuntimeTypeMap runtime_type_map;
-static RuntimeTypeSet runtime_type_set;
-static NamedTypeMap named_type_map;
-
 /**
 
  */
@@ -431,7 +420,7 @@ PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject &
   // IF the class is possibly a run time typed object
   if (type_index > 0) {
     // get best fit class...
-    Dtool_PyTypedObject *target_class = Dtool_RuntimeTypeDtoolType(type_index);
+    Dtool_PyTypedObject *target_class = (Dtool_PyTypedObject *)TypeHandle::from_index(type_index).get_python_type();
     if (target_class != nullptr) {
       // cast to the type...
       void *new_local_this = target_class->_Dtool_DowncastInterface(local_this_in, &known_class_type);
@@ -484,132 +473,26 @@ PyObject *DTool_CreatePyInstance(void *local_this, Dtool_PyTypedObject &in_class
   return (PyObject *)self;
 }
 
-// Th Finalizer for simple instances..
-int DTool_PyInit_Finalize(PyObject *self, void *local_this, Dtool_PyTypedObject *type, bool memory_rules, bool is_const) {
-  // lets put some code in here that checks to see the memory is properly
-  // configured.. prior to my call ..
-
-  ((Dtool_PyInstDef *)self)->_My_Type = type;
-  ((Dtool_PyInstDef *)self)->_ptr_to_object = local_this;
-  ((Dtool_PyInstDef *)self)->_memory_rules = memory_rules;
-  ((Dtool_PyInstDef *)self)->_is_const = is_const;
-  return 0;
-}
-
-// A helper function to glue method definition together .. that can not be
-// done at code generation time because of multiple generation passes in
-// interrogate..
-void Dtool_Accum_MethDefs(PyMethodDef in[], MethodDefmap &themap) {
-  for (; in->ml_name != nullptr; in++) {
-    if (themap.find(in->ml_name) == themap.end()) {
-      themap[in->ml_name] = in;
-    }
-  }
-}
-
-// ** HACK ** alert.. Need to keep a runtime type dictionary ... that is
-// forward declared of typed object.  We rely on the fact that typed objects
-// are uniquly defined by an integer.
-void
-RegisterNamedClass(const string &name, Dtool_PyTypedObject &otype) {
-  std::pair<NamedTypeMap::iterator, bool> result =
-    named_type_map.insert(NamedTypeMap::value_type(name, &otype));
-
-  if (!result.second) {
-    // There was already a class with this name in the dictionary.
-    interrogatedb_cat.warning()
-      << "Double definition for class " << name << "\n";
-  }
-}
-
-void
-RegisterRuntimeTypedClass(Dtool_PyTypedObject &otype) {
-  int type_index = otype._type.get_index();
-
-  if (type_index == 0) {
-    interrogatedb_cat.warning()
-      << "Class " << otype._PyType.tp_name
-      << " has a zero TypeHandle value; check that init_type() is called.\n";
-
-  } else if (type_index < 0 || type_index >= TypeRegistry::ptr()->get_num_typehandles()) {
-    interrogatedb_cat.warning()
-      << "Class " << otype._PyType.tp_name
-      << " has an illegal TypeHandle value; check that init_type() is called.\n";
-
-  } else {
-    std::pair<RuntimeTypeMap::iterator, bool> result =
-      runtime_type_map.insert(RuntimeTypeMap::value_type(type_index, &otype));
-    if (!result.second) {
-      // There was already an entry in the dictionary for type_index.
-      Dtool_PyTypedObject *other_type = (*result.first).second;
-      interrogatedb_cat.warning()
-        << "Classes " << otype._PyType.tp_name
-        << " and " << other_type->_PyType.tp_name
-        << " share the same TypeHandle value (" << type_index
-        << "); check class definitions.\n";
-
-    } else {
-      runtime_type_set.insert(type_index);
-    }
-  }
-}
-
-Dtool_PyTypedObject *
-LookupNamedClass(const string &name) {
-  NamedTypeMap::const_iterator it;
-  it = named_type_map.find(name);
-
-  if (it == named_type_map.end()) {
-    // Find a type named like this in the type registry.
-    TypeHandle handle = TypeRegistry::ptr()->find_type(name);
-    if (handle.get_index() > 0) {
-      RuntimeTypeMap::const_iterator it2;
-      it2 = runtime_type_map.find(handle.get_index());
-      if (it2 != runtime_type_map.end()) {
-        return it2->second;
-      }
-    }
-
-    interrogatedb_cat.error()
-      << "Attempt to use type " << name << " which has not yet been defined!\n";
-    return nullptr;
-  } else {
-    return it->second;
-  }
-}
-
-Dtool_PyTypedObject *
-LookupRuntimeTypedClass(TypeHandle handle) {
-  RuntimeTypeMap::const_iterator it;
-  it = runtime_type_map.find(handle.get_index());
-
-  if (it == runtime_type_map.end()) {
-    interrogatedb_cat.error()
-      << "Attempt to use type " << handle << " which has not yet been defined!\n";
-    return nullptr;
-  } else {
-    return it->second;
-  }
-}
-
-Dtool_PyTypedObject *Dtool_RuntimeTypeDtoolType(int type) {
-  RuntimeTypeMap::iterator di = runtime_type_map.find(type);
-  if (di != runtime_type_map.end()) {
-    return di->second;
+/**
+ * Returns a borrowed reference to the global type dictionary.
+ */
+Dtool_TypeMap *Dtool_GetGlobalTypeMap() {
+  PyObject *capsule = PySys_GetObject((char *)"_interrogate_types");
+  if (capsule != nullptr) {
+    return (Dtool_TypeMap *)PyCapsule_GetPointer(capsule, nullptr);
   } else {
-    int type2 = get_best_parent_from_Set(type, runtime_type_set);
-    di = runtime_type_map.find(type2);
-    if (di != runtime_type_map.end()) {
-      return di->second;
-    }
+    Dtool_TypeMap *type_map = new Dtool_TypeMap;
+    capsule = PyCapsule_New((void *)type_map, nullptr, nullptr);
+    PySys_SetObject((char *)"_interrogate_types", capsule);
+    Py_DECREF(capsule);
+    return type_map;
   }
-  return nullptr;
 }
 
 #if PY_MAJOR_VERSION >= 3
-PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], PyModuleDef *module_def) {
+PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], PyModuleDef *module_def) {
 #else
-PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename) {
+PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], const char *modulename) {
 #endif
   // Check the version so we can print a helpful error if it doesn't match.
   string version = Py_GetVersion();
@@ -627,55 +510,46 @@ PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename) {
     return nullptr;
   }
 
-  // Initialize the types we define in py_panda.
-  static bool dtool_inited = false;
-  if (!dtool_inited) {
-    dtool_inited = true;
-
-    if (PyType_Ready(&Dtool_SequenceWrapper_Type) < 0) {
-      return Dtool_Raise_TypeError("PyType_Ready(Dtool_SequenceWrapper)");
-    }
-
-    if (PyType_Ready(&Dtool_MutableSequenceWrapper_Type) < 0) {
-      return Dtool_Raise_TypeError("PyType_Ready(Dtool_MutableSequenceWrapper)");
-    }
-
-    if (PyType_Ready(&Dtool_MappingWrapper_Type) < 0) {
-      return Dtool_Raise_TypeError("PyType_Ready(Dtool_MappingWrapper)");
-    }
-
-    if (PyType_Ready(&Dtool_MutableMappingWrapper_Type) < 0) {
-      return Dtool_Raise_TypeError("PyType_Ready(Dtool_MutableMappingWrapper)");
-    }
+  Dtool_TypeMap *type_map = Dtool_GetGlobalTypeMap();
 
-    if (PyType_Ready(&Dtool_MappingWrapper_Keys_Type) < 0) {
-      return Dtool_Raise_TypeError("PyType_Ready(Dtool_MappingWrapper_Keys)");
-    }
+  // the module level function inits....
+  MethodDefmap functions;
+  for (size_t i = 0; defs[i] != nullptr; i++) {
+    const LibraryDef &def = *defs[i];
 
-    if (PyType_Ready(&Dtool_MappingWrapper_Values_Type) < 0) {
-      return Dtool_Raise_TypeError("PyType_Ready(Dtool_MappingWrapper_Values)");
+    // Accumulate method definitions.
+    for (PyMethodDef *meth = def._methods; meth->ml_name != nullptr; meth++) {
+      if (functions.find(meth->ml_name) == functions.end()) {
+        functions[meth->ml_name] = meth;
+      }
     }
 
-    if (PyType_Ready(&Dtool_MappingWrapper_Items_Type) < 0) {
-      return Dtool_Raise_TypeError("PyType_Ready(Dtool_MappingWrapper_Items)");
+    // Define exported types.
+    const Dtool_TypeDef *types = def._types;
+    if (types != nullptr) {
+      while (types->name != nullptr) {
+        (*type_map)[std::string(types->name)] = types->type;
+        ++types;
+      }
     }
+  }
 
-    if (PyType_Ready(&Dtool_GeneratorWrapper_Type) < 0) {
-      return Dtool_Raise_TypeError("PyType_Ready(Dtool_GeneratorWrapper)");
-    }
+  // Resolve external types, in a second pass.
+  for (size_t i = 0; defs[i] != nullptr; i++) {
+    const LibraryDef &def = *defs[i];
 
-    if (PyType_Ready(&Dtool_StaticProperty_Type) < 0) {
-      return Dtool_Raise_TypeError("PyType_Ready(Dtool_StaticProperty_Type)");
+    Dtool_TypeDef *types = def._external_types;
+    if (types != nullptr) {
+      while (types->name != nullptr) {
+        auto it = type_map->find(std::string(types->name));
+        if (it != type_map->end()) {
+          types->type = it->second;
+        } else {
+          return PyErr_Format(PyExc_NameError, "name '%s' is not defined", types->name);
+        }
+        ++types;
+      }
     }
-
-    // Initialize the base class of everything.
-    Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(nullptr);
-  }
-
-  // the module level function inits....
-  MethodDefmap functions;
-  for (int xx = 0; defs[xx] != nullptr; xx++) {
-    Dtool_Accum_MethDefs(defs[xx]->_methods, functions);
   }
 
   PyMethodDef *newdef = new PyMethodDef[functions.size() + 1];
@@ -799,7 +673,7 @@ PyObject *Dtool_BorrowThisReference(PyObject *self, PyObject *args) {
 
 // We do expose a dictionay for dtool classes .. this should be removed at
 // some point..
-EXPCL_INTERROGATEDB PyObject *Dtool_AddToDictionary(PyObject *self1, PyObject *args) {
+PyObject *Dtool_AddToDictionary(PyObject *self1, PyObject *args) {
   PyObject *self;
   PyObject *subject;
   PyObject *key;

+ 42 - 53
dtool/src/interrogatedb/py_panda.h

@@ -1,11 +1,4 @@
 /**
- * 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 py_panda.h
  */
 
@@ -43,9 +36,6 @@ using namespace std;
 #endif
 
 struct Dtool_PyTypedObject;
-typedef std::map<int, Dtool_PyTypedObject *> RuntimeTypeMap;
-typedef std::set<int> RuntimeTypeSet;
-typedef std::map<std::string, Dtool_PyTypedObject *> NamedTypeMap;
 
 // used to stamp dtool instance..
 #define PY_PANDA_SIGNATURE 0xbeaf
@@ -78,7 +68,7 @@ struct Dtool_PyInstDef {
 };
 
 // A Offset Dictionary Defining How to read the Above Object..
-extern EXPCL_INTERROGATEDB PyMemberDef standard_type_members[];
+extern PyMemberDef standard_type_members[];
 
 // The Class Definition Structor For a Dtool python type.
 struct Dtool_PyTypedObject {
@@ -190,25 +180,21 @@ static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\
 // forward declared of typed object.  We rely on the fact that typed objects
 // are uniquly defined by an integer.
 
-EXPCL_INTERROGATEDB void RegisterNamedClass(const std::string &name, Dtool_PyTypedObject &otype);
-EXPCL_INTERROGATEDB void RegisterRuntimeTypedClass(Dtool_PyTypedObject &otype);
+typedef std::map<std::string, Dtool_PyTypedObject *> Dtool_TypeMap;
 
-EXPCL_INTERROGATEDB Dtool_PyTypedObject *LookupNamedClass(const std::string &name);
-EXPCL_INTERROGATEDB Dtool_PyTypedObject *LookupRuntimeTypedClass(TypeHandle handle);
-
-EXPCL_INTERROGATEDB Dtool_PyTypedObject *Dtool_RuntimeTypeDtoolType(int type);
+Dtool_TypeMap *Dtool_GetGlobalTypeMap();
 
 /**
 
  */
-EXPCL_INTERROGATEDB void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject *classdef, void **answer);
+void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject *classdef, void **answer);
 
-EXPCL_INTERROGATEDB void *DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef, int param, const std::string &function_name, bool const_ok, bool report_errors);
+void *DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef, int param, const std::string &function_name, bool const_ok, bool report_errors);
 
-EXPCL_INTERROGATEDB bool Dtool_Call_ExtractThisPointer(PyObject *self, Dtool_PyTypedObject &classdef, void **answer);
+bool Dtool_Call_ExtractThisPointer(PyObject *self, Dtool_PyTypedObject &classdef, void **answer);
 
-EXPCL_INTERROGATEDB bool Dtool_Call_ExtractThisPointer_NonConst(PyObject *self, Dtool_PyTypedObject &classdef,
-                                                              void **answer, const char *method_name);
+bool Dtool_Call_ExtractThisPointer_NonConst(PyObject *self, Dtool_PyTypedObject &classdef,
+                                            void **answer, const char *method_name);
 
 template<class T> INLINE bool DtoolInstance_GetPointer(PyObject *self, T *&into);
 template<class T> INLINE bool DtoolInstance_GetPointer(PyObject *self, T *&into, Dtool_PyTypedObject &classdef);
@@ -218,7 +204,7 @@ INLINE int DtoolInstance_ComparePointers(PyObject *v1, PyObject *v2);
 INLINE PyObject *DtoolInstance_RichComparePointers(PyObject *v1, PyObject *v2, int op);
 
 // Functions related to error reporting.
-EXPCL_INTERROGATEDB bool _Dtool_CheckErrorOccurred();
+bool _Dtool_CheckErrorOccurred();
 
 #ifdef NDEBUG
 #define Dtool_CheckErrorOccurred() (UNLIKELY(_PyErr_OCCURRED() != nullptr))
@@ -226,12 +212,12 @@ EXPCL_INTERROGATEDB bool _Dtool_CheckErrorOccurred();
 #define Dtool_CheckErrorOccurred() (UNLIKELY(_Dtool_CheckErrorOccurred()))
 #endif
 
-EXPCL_INTERROGATEDB PyObject *Dtool_Raise_AssertionError();
-EXPCL_INTERROGATEDB PyObject *Dtool_Raise_TypeError(const char *message);
-EXPCL_INTERROGATEDB PyObject *Dtool_Raise_ArgTypeError(PyObject *obj, int param, const char *function_name, const char *type_name);
-EXPCL_INTERROGATEDB PyObject *Dtool_Raise_AttributeError(PyObject *obj, const char *attribute);
+PyObject *Dtool_Raise_AssertionError();
+PyObject *Dtool_Raise_TypeError(const char *message);
+PyObject *Dtool_Raise_ArgTypeError(PyObject *obj, int param, const char *function_name, const char *type_name);
+PyObject *Dtool_Raise_AttributeError(PyObject *obj, const char *attribute);
 
-EXPCL_INTERROGATEDB PyObject *_Dtool_Raise_BadArgumentsError();
+PyObject *_Dtool_Raise_BadArgumentsError();
 #ifdef NDEBUG
 // Define it to a function that just prints a generic message.
 #define Dtool_Raise_BadArgumentsError(x) _Dtool_Raise_BadArgumentsError()
@@ -243,9 +229,9 @@ EXPCL_INTERROGATEDB PyObject *_Dtool_Raise_BadArgumentsError();
 // These functions are similar to Dtool_WrapValue, except that they also
 // contain code for checking assertions and exceptions when compiling with
 // NDEBUG mode on.
-EXPCL_INTERROGATEDB PyObject *_Dtool_Return_None();
-EXPCL_INTERROGATEDB PyObject *Dtool_Return_Bool(bool value);
-EXPCL_INTERROGATEDB PyObject *_Dtool_Return(PyObject *value);
+PyObject *_Dtool_Return_None();
+PyObject *Dtool_Return_Bool(bool value);
+PyObject *_Dtool_Return(PyObject *value);
 
 #ifdef NDEBUG
 #define Dtool_Return_None() (LIKELY(_PyErr_OCCURRED() == nullptr) ? (Py_INCREF(Py_None), Py_None) : nullptr)
@@ -258,19 +244,19 @@ EXPCL_INTERROGATEDB PyObject *_Dtool_Return(PyObject *value);
 /**
  * Wrapper around Python 3.4's enum library, which does not have a C API.
  */
-EXPCL_INTERROGATEDB PyTypeObject *Dtool_EnumType_Create(const char *name, PyObject *names,
+PyTypeObject *Dtool_EnumType_Create(const char *name, PyObject *names,
                                                         const char *module = nullptr);
-EXPCL_INTERROGATEDB INLINE long Dtool_EnumValue_AsLong(PyObject *value);
+INLINE long Dtool_EnumValue_AsLong(PyObject *value);
 
 
 /**
 
  */
-EXPCL_INTERROGATEDB PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject &known_class_type, bool memory_rules, bool is_const, int RunTimeType);
+PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject &known_class_type, bool memory_rules, bool is_const, int RunTimeType);
 
 // DTool_CreatePyInstance .. wrapper function to finalize the existance of a
 // general dtool py instance..
-EXPCL_INTERROGATEDB PyObject *DTool_CreatePyInstance(void *local_this, Dtool_PyTypedObject &in_classdef, bool memory_rules, bool is_const);
+PyObject *DTool_CreatePyInstance(void *local_this, Dtool_PyTypedObject &in_classdef, bool memory_rules, bool is_const);
 
 // These template methods allow use when the Dtool_PyTypedObject is not known.
 // They require a get_class_type() to be defined for the class.
@@ -314,43 +300,49 @@ Define_Dtool_FreeInstanceRef(CLASS_NAME,CNAME)\
 Define_Dtool_Class(MODULE_NAME,CLASS_NAME,PUBLIC_NAME)
 
 // The finalizer for simple instances.
-EXPCL_INTERROGATEDB int DTool_PyInit_Finalize(PyObject *self, void *This, Dtool_PyTypedObject *type, bool memory_rules, bool is_const);
+INLINE int DTool_PyInit_Finalize(PyObject *self, void *This, Dtool_PyTypedObject *type, bool memory_rules, bool is_const);
 
 // A heler function to glu methed definition together .. that can not be done
 // at code generation time becouse of multiple generation passes in
 // interigate..
 typedef std::map<std::string, PyMethodDef *> MethodDefmap;
 
-EXPCL_INTERROGATEDB void Dtool_Accum_MethDefs(PyMethodDef in[], MethodDefmap &themap);
-
 // We need a way to runtime merge compile units into a python "Module" .. this
 // is done with the fallowing structors and code.. along with the support of
 // interigate_module
+
+struct Dtool_TypeDef {
+  const char *const name;
+  Dtool_PyTypedObject *type;
+};
+
 struct LibraryDef {
-  PyMethodDef *_methods;
+  PyMethodDef *const _methods;
+  const Dtool_TypeDef *const _types;
+  Dtool_TypeDef *const _external_types;
 };
 
 #if PY_MAJOR_VERSION >= 3
-EXPCL_INTERROGATEDB PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], PyModuleDef *module_def);
+PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], PyModuleDef *module_def);
 #else
-EXPCL_INTERROGATEDB PyObject *Dtool_PyModuleInitHelper(LibraryDef *defs[], const char *modulename);
+PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], const char *modulename);
 #endif
 
 // HACK.... Be carefull Dtool_BorrowThisReference This function can be used to
 // grab the "THIS" pointer from an object and use it Required to support fom
 // historical inharatence in the for of "is this instance of"..
-EXPCL_INTERROGATEDB PyObject *Dtool_BorrowThisReference(PyObject *self, PyObject *args);
+PyObject *Dtool_BorrowThisReference(PyObject *self, PyObject *args);
 
 #define DTOOL_PyObject_HashPointer DtoolInstance_HashPointer
 #define DTOOL_PyObject_ComparePointers DtoolInstance_ComparePointers
 
-EXPCL_INTERROGATEDB PyObject *
+PyObject *
 copy_from_make_copy(PyObject *self, PyObject *noargs);
 
-EXPCL_INTERROGATEDB PyObject *
+PyObject *
 copy_from_copy_constructor(PyObject *self, PyObject *noargs);
 
-EXPCL_INTERROGATEDB PyObject *
+PyObject *
 map_deepcopy_to_copy(PyObject *self, PyObject *args);
 
 /**
@@ -359,13 +351,13 @@ map_deepcopy_to_copy(PyObject *self, PyObject *args);
  */
 ALWAYS_INLINE bool Dtool_CheckNoArgs(PyObject *args);
 ALWAYS_INLINE bool Dtool_CheckNoArgs(PyObject *args, PyObject *kwds);
-EXPCL_INTERROGATEDB bool Dtool_ExtractArg(PyObject **result, PyObject *args,
+bool Dtool_ExtractArg(PyObject **result, PyObject *args,
                                           PyObject *kwds, const char *keyword);
-EXPCL_INTERROGATEDB bool Dtool_ExtractArg(PyObject **result, PyObject *args,
+bool Dtool_ExtractArg(PyObject **result, PyObject *args,
                                           PyObject *kwds);
-EXPCL_INTERROGATEDB bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args,
+bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args,
                                                   PyObject *kwds, const char *keyword);
-EXPCL_INTERROGATEDB bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args,
+bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args,
                                                   PyObject *kwds);
 
 /**
@@ -401,10 +393,7 @@ ALWAYS_INLINE PyObject *Dtool_WrapValue(Py_buffer *value);
 template<class T1, class T2>
 ALWAYS_INLINE PyObject *Dtool_WrapValue(const std::pair<T1, T2> &value);
 
-EXPCL_INTERROGATEDB extern struct Dtool_PyTypedObject Dtool_DTOOL_SUPER_BASE;
-EXPCL_INTERROGATEDB extern void Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(PyObject *module);
-
-#define Dtool_Ptr_DTOOL_SUPER_BASE (&Dtool_DTOOL_SUPER_BASE)
+Dtool_PyTypedObject *Dtool_GetSuperBase();
 
 #include "py_panda.I"
 

Diferenças do arquivo suprimidas por serem muito extensas
+ 299 - 674
dtool/src/interrogatedb/py_wrappers.cxx


+ 6 - 23
dtool/src/interrogatedb/py_wrappers.h

@@ -1,11 +1,4 @@
 /**
- * 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 py_wrappers.h
  * @author rdb
  * @date 2017-11-26
@@ -56,22 +49,12 @@ struct Dtool_GeneratorWrapper {
   iternextfunc _iternext_func;
 };
 
-EXPCL_INTERROGATEDB extern PyTypeObject Dtool_SequenceWrapper_Type;
-EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MutableSequenceWrapper_Type;
-EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MappingWrapper_Type;
-EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MutableMappingWrapper_Type;
-EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MappingWrapper_Items_Type;
-EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MappingWrapper_Keys_Type;
-EXPCL_INTERROGATEDB extern PyTypeObject Dtool_MappingWrapper_Values_Type;
-EXPCL_INTERROGATEDB extern PyTypeObject Dtool_GeneratorWrapper_Type;
-EXPCL_INTERROGATEDB extern PyTypeObject Dtool_StaticProperty_Type;
-
-EXPCL_INTERROGATEDB Dtool_SequenceWrapper *Dtool_NewSequenceWrapper(PyObject *self, const char *name);
-EXPCL_INTERROGATEDB Dtool_MutableSequenceWrapper *Dtool_NewMutableSequenceWrapper(PyObject *self, const char *name);
-EXPCL_INTERROGATEDB Dtool_MappingWrapper *Dtool_NewMappingWrapper(PyObject *self, const char *name);
-EXPCL_INTERROGATEDB Dtool_MappingWrapper *Dtool_NewMutableMappingWrapper(PyObject *self, const char *name);
-EXPCL_INTERROGATEDB PyObject *Dtool_NewGenerator(PyObject *self, const char *name, iternextfunc func);
-EXPCL_INTERROGATEDB PyObject *Dtool_NewStaticProperty(PyTypeObject *obj, const PyGetSetDef *getset);
+Dtool_SequenceWrapper *Dtool_NewSequenceWrapper(PyObject *self, const char *name);
+Dtool_MutableSequenceWrapper *Dtool_NewMutableSequenceWrapper(PyObject *self, const char *name);
+Dtool_MappingWrapper *Dtool_NewMappingWrapper(PyObject *self, const char *name);
+Dtool_MappingWrapper *Dtool_NewMutableMappingWrapper(PyObject *self, const char *name);
+PyObject *Dtool_NewGenerator(PyObject *self, iternextfunc func);
+PyObject *Dtool_NewStaticProperty(PyTypeObject *obj, const PyGetSetDef *getset);
 
 #endif  // HAVE_PYTHON
 

+ 4 - 0
dtool/src/parser-inc/vrpn_Analog.h

@@ -0,0 +1,4 @@
+#pragma once
+
+class vrpn_Analog_Remote;
+typedef void vrpn_ANALOGCB;

+ 4 - 0
dtool/src/parser-inc/vrpn_Button.h

@@ -0,0 +1,4 @@
+#pragma once
+
+class vrpn_Button_Remote;
+typedef void vrpn_BUTTONCB;

+ 3 - 0
dtool/src/parser-inc/vrpn_Configure.h

@@ -0,0 +1,3 @@
+#pragma once
+
+#define VRPN_CALLBACK

+ 3 - 0
dtool/src/parser-inc/vrpn_Connection.h

@@ -0,0 +1,3 @@
+#pragma once
+
+class vrpn_Connection;

+ 4 - 0
dtool/src/parser-inc/vrpn_Dial.h

@@ -0,0 +1,4 @@
+#pragma once
+
+class vrpn_Dial_Remote;
+typedef void vrpn_DIALCB;

+ 6 - 0
dtool/src/parser-inc/vrpn_Tracker.h

@@ -0,0 +1,6 @@
+#pragma once
+
+class vrpn_Tracker_Remote;
+typedef void vrpn_TRACKERCB;
+typedef void vrpn_TRACKERACCCB;
+typedef void vrpn_TRACKERVELCB;

+ 8 - 0
dtool/src/pystub/pystub.cxx

@@ -27,6 +27,8 @@ extern "C" {
   EXPCL_PYSTUB int PyCFunction_New(...);
   EXPCL_PYSTUB int PyCFunction_NewEx(...);
   EXPCL_PYSTUB int PyCallable_Check(...);
+  EXPCL_PYSTUB int PyCapsule_GetPointer(...);
+  EXPCL_PYSTUB int PyCapsule_New(...);
   EXPCL_PYSTUB int PyDict_DelItem(...);
   EXPCL_PYSTUB int PyDict_DelItemString(...);
   EXPCL_PYSTUB int PyDict_GetItem(...);
@@ -133,6 +135,7 @@ extern "C" {
   EXPCL_PYSTUB int PyString_InternInPlace(...);
   EXPCL_PYSTUB int PyString_Size(...);
   EXPCL_PYSTUB int PySys_GetObject(...);
+  EXPCL_PYSTUB int PySys_SetObject(...);
   EXPCL_PYSTUB int PyThreadState_Clear(...);
   EXPCL_PYSTUB int PyThreadState_Delete(...);
   EXPCL_PYSTUB int PyThreadState_Get(...);
@@ -216,6 +219,7 @@ extern "C" {
   EXPCL_PYSTUB extern void *PyExc_ImportError;
   EXPCL_PYSTUB extern void *PyExc_IndexError;
   EXPCL_PYSTUB extern void *PyExc_KeyError;
+  EXPCL_PYSTUB extern void *PyExc_NameError;
   EXPCL_PYSTUB extern void *PyExc_OSError;
   EXPCL_PYSTUB extern void *PyExc_OverflowError;
   EXPCL_PYSTUB extern void *PyExc_RuntimeError;
@@ -257,6 +261,8 @@ int PyBytes_Size(...) { return 0; }
 int PyCFunction_New(...) { return 0; };
 int PyCFunction_NewEx(...) { return 0; };
 int PyCallable_Check(...) { return 0; }
+int PyCapsule_GetPointer(...) { return 0; }
+int PyCapsule_New(...) { return 0; }
 int PyDict_DelItem(...) { return 0; }
 int PyDict_DelItemString(...) { return 0; }
 int PyDict_GetItem(...) { return 0; }
@@ -363,6 +369,7 @@ int PyString_FromStringAndSize(...) { return 0; }
 int PyString_InternFromString(...) { return 0; }
 int PyString_InternInPlace(...) { return 0; }
 int PySys_GetObject(...) { return 0; }
+int PySys_SetObject(...) { return 0; }
 int PyThreadState_Clear(...) { return 0; }
 int PyThreadState_Delete(...) { return 0; }
 int PyThreadState_Get(...) { return 0; }
@@ -452,6 +459,7 @@ void *PyExc_FutureWarning = nullptr;
 void *PyExc_ImportError = nullptr;
 void *PyExc_IndexError = nullptr;
 void *PyExc_KeyError = nullptr;
+void *PyExc_NameError = nullptr;
 void *PyExc_OSError = nullptr;
 void *PyExc_OverflowError = nullptr;
 void *PyExc_RuntimeError = nullptr;

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

@@ -17,7 +17,6 @@
 #include "interrogate_request.h"
 #include "load_dso.h"
 #include "filename.h"
-#include "pystub.h"
 #include "panda_getopt.h"
 #include "preprocess_argv.h"
 
@@ -526,8 +525,6 @@ main(int argc, char **argv) {
   extern int optind;
   const char *optstr = "p:ftqh";
 
-  pystub();
-
   bool all_functions = false;
   bool all_types = false;
   bool quick_load = false;

+ 16 - 7
makepanda/installer.nsi

@@ -331,13 +331,24 @@ SectionGroup "Python support"
         SetOutPath $INSTDIR\panda3d
         File /r "${BUILT}\panda3d\*.py"
 
-        File /r /x bullet.pyd /x ode.pyd /x physx.pyd /x rocket.pyd "${BUILT}\panda3d\*.pyd"
+        File /nonfatal /r "${BUILT}\panda3d\core${EXT_SUFFIX}"
+        File /nonfatal /r "${BUILT}\panda3d\ai${EXT_SUFFIX}"
+        File /nonfatal /r "${BUILT}\panda3d\awesomium${EXT_SUFFIX}"
+        File /nonfatal /r "${BUILT}\panda3d\direct${EXT_SUFFIX}"
+        File /nonfatal /r "${BUILT}\panda3d\egg${EXT_SUFFIX}"
+        File /nonfatal /r "${BUILT}\panda3d\fx${EXT_SUFFIX}"
+        File /nonfatal /r "${BUILT}\panda3d\interrogatedb${EXT_SUFFIX}"
+        File /nonfatal /r "${BUILT}\panda3d\physics${EXT_SUFFIX}"
+        File /nonfatal /r "${BUILT}\panda3d\_rplight${EXT_SUFFIX}"
+        File /nonfatal /r "${BUILT}\panda3d\skel${EXT_SUFFIX}"
+        File /nonfatal /r "${BUILT}\panda3d\vision${EXT_SUFFIX}"
+        File /nonfatal /r "${BUILT}\panda3d\vrpn${EXT_SUFFIX}"
 
         !ifdef HAVE_BULLET
             SectionGetFlags ${SecBullet} $R0
             IntOp $R0 $R0 & ${SF_SELECTED}
             StrCmp $R0 ${SF_SELECTED} 0 SkipBulletPyd
-            File /nonfatal /r "${BUILT}\panda3d\bullet.pyd"
+            File /nonfatal /r "${BUILT}\panda3d\bullet${EXT_SUFFIX}"
             SkipBulletPyd:
         !endif
 
@@ -345,7 +356,7 @@ SectionGroup "Python support"
             SectionGetFlags ${SecODE} $R0
             IntOp $R0 $R0 & ${SF_SELECTED}
             StrCmp $R0 ${SF_SELECTED} 0 SkipODEPyd
-            File /nonfatal /r "${BUILT}\panda3d\ode.pyd"
+            File /nonfatal /r "${BUILT}\panda3d\ode${EXT_SUFFIX}"
             SkipODEPyd:
         !endif
 
@@ -353,7 +364,7 @@ SectionGroup "Python support"
             SectionGetFlags ${SecPhysX} $R0
             IntOp $R0 $R0 & ${SF_SELECTED}
             StrCmp $R0 ${SF_SELECTED} 0 SkipPhysXPyd
-            File /nonfatal /r "${BUILT}\panda3d\physx.pyd"
+            File /nonfatal /r "${BUILT}\panda3d\physx${EXT_SUFFIX}"
             SkipPhysXPyd:
         !endif
 
@@ -361,7 +372,7 @@ SectionGroup "Python support"
             SectionGetFlags ${SecRocket} $R0
             IntOp $R0 $R0 & ${SF_SELECTED}
             StrCmp $R0 ${SF_SELECTED} 0 SkipRocketPyd
-            File /nonfatal /r "${BUILT}\panda3d\rocket.pyd"
+            File /nonfatal /r "${BUILT}\panda3d\rocket${EXT_SUFFIX}"
             SkipRocketPyd:
         !endif
 
@@ -589,7 +600,6 @@ Section "3ds Max plug-ins" SecMaxPlugins
     File /nonfatal /r "${BUILT}\plugins\*.dle"
     File /nonfatal /r "${BUILT}\plugins\*.dlo"
     File /nonfatal /r "${BUILT}\plugins\*.ms"
-    File "${SOURCE}\doc\INSTALLING-PLUGINS.TXT"
 SectionEnd
 !endif
 
@@ -604,7 +614,6 @@ Section "Maya plug-ins" SecMayaPlugins
     SetOutPath $INSTDIR\plugins
     File /nonfatal /r "${BUILT}\plugins\*.mll"
     File /nonfatal /r "${BUILT}\plugins\*.mel"
-    File "${SOURCE}\doc\INSTALLING-PLUGINS.TXT"
 SectionEnd
 !endif
 

+ 6 - 1
makepanda/installpanda.py

@@ -175,6 +175,7 @@ def InstallPanda(destdir="", prefix="/usr", outputdir="built", libdir=GetLibDir(
     oscmd("mkdir -m 0755 -p "+destdir+prefix+"/share/applications")
     oscmd("mkdir -m 0755 -p "+destdir+libdir+"/panda3d")
     oscmd("mkdir -m 0755 -p "+destdir+PPATH)
+    oscmd("mkdir -m 0755 -p "+destdir+PPATH+"/panda3d")
 
     if (sys.platform.startswith("freebsd")):
         oscmd("mkdir -m 0755 -p "+destdir+prefix+"/etc")
@@ -194,13 +195,17 @@ def InstallPanda(destdir="", prefix="/usr", outputdir="built", libdir=GetLibDir(
 
     oscmd("cp -R "+outputdir+"/include          "+destdir+prefix+"/include/panda3d")
     oscmd("cp -R "+outputdir+"/pandac           "+destdir+prefix+"/share/panda3d/")
-    oscmd("cp -R "+outputdir+"/panda3d          "+destdir+PPATH+"/")
     oscmd("cp -R "+outputdir+"/models           "+destdir+prefix+"/share/panda3d/")
     if os.path.isdir("samples"):             oscmd("cp -R samples               "+destdir+prefix+"/share/panda3d/")
     if os.path.isdir(outputdir+"/direct"):   oscmd("cp -R "+outputdir+"/direct           "+destdir+prefix+"/share/panda3d/")
     if os.path.isdir(outputdir+"/Pmw"):      oscmd("cp -R "+outputdir+"/Pmw     "+destdir+prefix+"/share/panda3d/")
     if os.path.isdir(outputdir+"/plugins"):  oscmd("cp -R "+outputdir+"/plugins "+destdir+prefix+"/share/panda3d/")
 
+    suffix = GetExtensionSuffix()
+    for base in os.listdir(outputdir + "/panda3d"):
+        if base.endswith(".py") or (base.endswith(suffix) and '.' not in base[:-len(suffix)]):
+            oscmd("cp "+outputdir+"/panda3d/"+base+" "+destdir+PPATH+"/panda3d/"+base)
+
     WriteMimeFile(destdir+prefix+"/share/mime-info/panda3d.mime", MIME_INFO)
     WriteKeysFile(destdir+prefix+"/share/mime-info/panda3d.keys", MIME_INFO)
     WriteMimeXMLFile(destdir+prefix+"/share/mime/packages/panda3d.xml", MIME_INFO)

Diferenças do arquivo suprimidas por serem muito extensas
+ 222 - 262
makepanda/makepanda.py


+ 128 - 9
makepanda/makepandacore.py

@@ -3190,6 +3190,48 @@ def WriteResourceFile(basename, **kwargs):
     ConditionalWriteFile(basename, GenerateResourceFile(**kwargs))
     return basename
 
+
+def WriteEmbeddedStringFile(basename, inputs, string_name=None):
+    if os.path.splitext(basename)[1] not in SUFFIX_INC:
+        basename += '.cxx'
+    target = GetOutputDir() + "/tmp/" + basename
+
+    if string_name is None:
+        string_name = os.path.basename(os.path.splitext(target)[0])
+        string_name = string_name.replace('-', '_')
+
+    data = bytearray()
+    for input in inputs:
+        fp = open(input, 'rb')
+
+        # Insert a #line so that we get meaningful compile/assert errors when
+        # the result is inserted by interrogate_module into generated code.
+        if os.path.splitext(input)[1] in SUFFIX_INC:
+            line = '#line 1 "%s"\n' % (input)
+            data += bytearray(line.encode('ascii', 'replace'))
+
+        data += bytearray(fp.read())
+        fp.close()
+
+    data.append(0)
+
+    output = 'extern const char %s[] = {\n' % (string_name)
+
+    i = 0
+    for byte in data:
+        if i == 0:
+            output += ' '
+
+        output += ' 0x%02x,' % (byte)
+        i += 1
+        if i >= 12:
+            output += '\n'
+            i = 0
+
+    output += '\n};\n'
+    ConditionalWriteFile(target, output)
+    return target
+
 ########################################################################
 ##
 ## FindLocation
@@ -3197,6 +3239,8 @@ def WriteResourceFile(basename, **kwargs):
 ########################################################################
 
 ORIG_EXT = {}
+PYABI_SPECIFIC = set()
+WARNED_FILES = set()
 
 def GetOrigExt(x):
     return ORIG_EXT[x]
@@ -3207,14 +3251,42 @@ def SetOrigExt(x, v):
 def GetExtensionSuffix():
     if sys.version_info >= (3, 0):
         suffix = sysconfig.get_config_var('EXT_SUFFIX')
-        if suffix:
+        if suffix == '.so':
+            # On my FreeBSD system, this is not set correctly, but SOABI is.
+            soabi = sysconfig.get_config_var('SOABI')
+            if soabi:
+                return '.%s.so' % (soabi)
+        elif suffix:
             return suffix
+
     target = GetTarget()
     if target == 'windows':
         return '.pyd'
     else:
         return '.so'
 
+def GetPythonABI():
+    soabi = sysconfig.get_config_var('SOABI')
+    if soabi:
+        return soabi
+
+    soabi = 'cpython-%d%d' % (sys.version_info[:2])
+
+    debug_flag = sysconfig.get_config_var('Py_DEBUG')
+    if (debug_flag is None and hasattr(sys, 'gettotalrefcount')) or debug_flag:
+        soabi += 'd'
+
+    malloc_flag = sysconfig.get_config_var('WITH_PYMALLOC')
+    if malloc_flag is None or malloc_flag:
+        soabi += 'm'
+
+    if sys.version_info < (3, 3):
+        usize = sysconfig.get_config_var('Py_UNICODE_SIZE')
+        if (usize is None and sys.maxunicode == 0x10ffff) or usize == 4:
+            soabi += 'u'
+
+    return soabi
+
 def CalcLocation(fn, ipath):
     if fn.startswith("panda3d/") and fn.endswith(".py"):
         return OUTPUTDIR + "/" + fn
@@ -3285,11 +3357,25 @@ def CalcLocation(fn, ipath):
     return fn
 
 
-def FindLocation(fn, ipath):
+def FindLocation(fn, ipath, pyabi=None):
     if (GetLinkAllStatic() and fn.endswith(".dll")):
         fn = fn[:-4] + ".lib"
     loc = CalcLocation(fn, ipath)
     base, ext = os.path.splitext(fn)
+
+    # If this is a target created with PyTargetAdd, we need to make sure it
+    # it put in a Python-version-specific directory.
+    if loc in PYABI_SPECIFIC:
+        if loc.startswith(OUTPUTDIR + "/tmp"):
+            if pyabi is not None:
+                loc = OUTPUTDIR + "/tmp/" + pyabi + loc[len(OUTPUTDIR) + 4:]
+            else:
+                raise RuntimeError("%s is a Python-specific target, use PyTargetAdd instead of TargetAdd" % (fn))
+
+        elif ext != ".pyd" and loc not in WARNED_FILES:
+            WARNED_FILES.add(loc)
+            print("%sWARNING:%s file depends on Python but is not in an ABI-specific directory: %s%s%s" % (GetColor("red"), GetColor(), GetColor("green"), loc, GetColor()))
+
     ORIG_EXT[loc] = ext
     return loc
 
@@ -3335,6 +3421,11 @@ def FindLocation(fn, ipath):
 ## be inserted: bison generates an OBJ and a secondary header
 ## file, interrogate generates an IN and a secondary IGATE.OBJ.
 ##
+## PyTargetAdd is a special version for targets that depend on Python.
+## It will create a target for each Python version we are building with,
+## ensuring that builds with different Python versions won't conflict
+## when we build for multiple Python ABIs side-by-side.
+##
 ########################################################################
 
 class Target:
@@ -3343,7 +3434,7 @@ class Target:
 TARGET_LIST = []
 TARGET_TABLE = {}
 
-def TargetAdd(target, dummy=0, opts=[], input=[], dep=[], ipath=None, winrc=None):
+def TargetAdd(target, dummy=0, opts=[], input=[], dep=[], ipath=None, winrc=None, pyabi=None):
     if (dummy != 0):
         exit("Syntax error in TargetAdd "+target)
     if ipath is None: ipath = opts
@@ -3351,11 +3442,10 @@ def TargetAdd(target, dummy=0, opts=[], input=[], dep=[], ipath=None, winrc=None
     if (type(input) == str): input = [input]
     if (type(dep) == str): dep = [dep]
 
-    if os.path.splitext(target)[1] == '.pyd' and PkgSkip("PYTHON"):
-        # It makes no sense to build Python modules with python disabled.
-        return
+    if target.endswith(".pyd") and not pyabi:
+        raise RuntimeError("Use PyTargetAdd to build .pyd targets")
 
-    full = FindLocation(target, [OUTPUTDIR + "/include"])
+    full = FindLocation(target, [OUTPUTDIR + "/include"], pyabi=pyabi)
 
     if (full not in TARGET_TABLE):
         t = Target()
@@ -3374,7 +3464,7 @@ def TargetAdd(target, dummy=0, opts=[], input=[], dep=[], ipath=None, winrc=None
 
     ipath = [OUTPUTDIR + "/tmp"] + GetListOption(ipath, "DIR:") + [OUTPUTDIR+"/include"]
     for x in input:
-        fullinput = FindLocation(x, ipath)
+        fullinput = FindLocation(x, ipath, pyabi=pyabi)
         t.inputs.append(fullinput)
         # Don't re-link a library or binary if just its dependency dlls have been altered.
         # This should work out fine in most cases, and often reduces recompilation time.
@@ -3413,7 +3503,7 @@ def TargetAdd(target, dummy=0, opts=[], input=[], dep=[], ipath=None, winrc=None
                 t.deps[fulln] = 1
 
     for x in dep:
-        fulldep = FindLocation(x, ipath)
+        fulldep = FindLocation(x, ipath, pyabi=pyabi)
         t.deps[fulldep] = 1
 
     if winrc and GetTarget() == 'windows':
@@ -3430,3 +3520,32 @@ def TargetAdd(target, dummy=0, opts=[], input=[], dep=[], ipath=None, winrc=None
 
     if target.endswith(".pz") and not CrossCompiling():
         t.deps[FindLocation("pzip.exe", [])] = 1
+
+    if target.endswith(".in"):
+        # Also add a target to compile the _igate.cxx file into an _igate.obj.
+        outbase = os.path.basename(target)[:-3]
+        woutc = OUTPUTDIR + "/tmp/" + outbase + "_igate.cxx"
+        CxxDependencyCache[woutc] = []
+        PyTargetAdd(outbase + "_igate.obj", opts=opts+['PYTHON','BIGOBJ'], input=woutc, dep=target)
+
+
+def PyTargetAdd(target, opts=[], **kwargs):
+    if PkgSkip("PYTHON"):
+        return
+
+    if 'PYTHON' not in opts:
+        opts = opts + ['PYTHON']
+
+    abi = GetPythonABI()
+
+    MakeDirectory(OUTPUTDIR + "/tmp/" + abi)
+
+    # Mark this target as being a Python-specific target.
+    orig = CalcLocation(target, [OUTPUTDIR + "/include"])
+    PYABI_SPECIFIC.add(orig)
+
+    if orig.startswith(OUTPUTDIR + "/tmp/") and os.path.exists(orig):
+        print("Removing file %s" % (orig))
+        os.unlink(orig)
+
+    TargetAdd(target, opts=opts, pyabi=abi, **kwargs)

+ 1 - 1
makepanda/makewheel.py

@@ -498,7 +498,7 @@ __version__ = '{0}'
     for file in os.listdir(panda3d_dir):
         if file == '__init__.py':
             pass
-        elif file.endswith(ext_suffix) or file.endswith('.py'):
+        elif file.endswith('.py') or (file.endswith(ext_suffix) and '.' not in file[:-len(ext_suffix)]):
             source_path = os.path.join(panda3d_dir, file)
 
             if file.endswith('.pyd') and platform.startswith('cygwin'):

+ 1 - 1
panda/src/audiotraits/fmodAudioSound.cxx

@@ -651,7 +651,7 @@ get_3d_max_distance() const {
  * a balance [pan] function what is the point?
  */
 PN_stdfloat FmodAudioSound::
-get_speaker_mix(AudioManager::SpeakerId speaker) {
+get_speaker_mix(int speaker) {
   ReMutexHolder holder(FmodAudioManager::_lock);
   if (_channel == 0) {
     return 0.0;

+ 1 - 1
panda/src/audiotraits/fmodAudioSound.h

@@ -126,7 +126,7 @@ public:
 
   AudioSound::SoundStatus status() const;
 
-  virtual PN_stdfloat get_speaker_mix(AudioManager::SpeakerId speaker);
+  virtual PN_stdfloat get_speaker_mix(int speaker);
   virtual void set_speaker_mix(PN_stdfloat frontleft, PN_stdfloat frontright, PN_stdfloat center, PN_stdfloat sub, PN_stdfloat backleft, PN_stdfloat backright, PN_stdfloat sideleft, PN_stdfloat  sideright);
 
   void set_active(bool active=true);

+ 9 - 4
panda/src/collide/collisionHandlerQueue.cxx

@@ -22,10 +22,15 @@ class CollisionEntrySorter {
 public:
   CollisionEntrySorter(CollisionEntry *entry) {
     _entry = entry;
-    LVector3 vec =
-      entry->get_surface_point(entry->get_from_node_path()) -
-      entry->get_from()->get_collision_origin();
-    _dist2 = vec.length_squared();
+    if (entry->has_surface_point()) {
+      LVector3 vec =
+        entry->get_surface_point(entry->get_from_node_path()) -
+        entry->get_from()->get_collision_origin();
+      _dist2 = vec.length_squared();
+    }
+    else {
+      _dist2 = make_inf((PN_stdfloat)0);
+    }
   }
   bool operator < (const CollisionEntrySorter &other) const {
     return _dist2 < other._dist2;

+ 0 - 10
panda/src/configfiles/panda.init

@@ -1,10 +0,0 @@
-SETABS PANDA_VER 0.8
-MODREL ETC_PATH built/etc
-DOCSH if ( ! $?CFG_PATH ) then
-DOCSH   setenv CFG_PATH ~
-DOCSH   setenv CFG_PATH ". ${CFG_PATH} /usr/local/etc"
-DOCSH endif
-DOSH if [ -z "$CFG_PATH" ]; then
-DOSH   CFG_PATH=". $HOME /usr/local/etc"
-DOSH   export CFG_PATH
-DOSH fi

+ 0 - 1
panda/src/dxgsg9/dxgsg9base.h

@@ -211,7 +211,6 @@ struct DXScreenData {
   bool _is_tnl_device;
   bool _can_use_hw_vertex_shaders;
   bool _can_use_pixel_shaders;
-  bool _is_dx9_1;
   UINT _supported_screen_depths_mask;
   UINT _supported_tex_formats_mask;
   bool _supports_rgba16f_texture_format;

+ 8 - 26
panda/src/dxgsg9/wdxGraphicsPipe9.cxx

@@ -193,30 +193,10 @@ init() {
   }
 
   // Create a Direct3D object.
+  __d3d9 = (*_Direct3DCreate9)(D3D_SDK_VERSION);
 
-  // these were taken from the 8.0 and 8.1 d3d8.h SDK headers
-    __is_dx9_1 = false;
-
-#define D3D_SDK_VERSION_9_0 D3D_SDK_VERSION
-#define D3D_SDK_VERSION_9_1 D3D_SDK_VERSION
-
-  // are we using 9.0 or 9.1?
-  WIN32_FIND_DATA TempFindData;
-  HANDLE hFind;
-  char tmppath[_MAX_PATH + 128];
-  GetSystemDirectory(tmppath, MAX_PATH);
-  strcat(tmppath, "\\dpnhpast.dll");
-  hFind = FindFirstFile (tmppath, &TempFindData);
-  if (hFind != INVALID_HANDLE_VALUE) {
-    FindClose(hFind);
-// ??? This was from DX8 __is_dx9_1 = true;
-    __d3d9 = (*_Direct3DCreate9)(D3D_SDK_VERSION_9_1);
-  } else {
-    __is_dx9_1 = false;
-    __d3d9 = (*_Direct3DCreate9)(D3D_SDK_VERSION_9_0);
-  }
   if (__d3d9 == nullptr) {
-    wdxdisplay9_cat.error() << "Direct3DCreate9(9." << (__is_dx9_1 ? "1" : "0") << ") failed!, error = " << GetLastError() << endl;
+    wdxdisplay9_cat.error() << "Direct3DCreate9 failed!, error = " << GetLastError() << endl;
     // release_gsg();
     goto error;
   }
@@ -361,11 +341,13 @@ find_all_card_memavails() {
       if (!ISPOW2(dwVidMemTotal)) {
         // assume they wont return a proper max value, so round up to next pow
         // of 2
-        UINT count = 0;
-        while ((dwVidMemTotal >> count) != 0x0) {
-          count++;
+        int count = get_next_higher_bit((uint32_t)(dwVidMemTotal - 1u));
+        if (count >= 32u) {
+          // Maximum value that fits in a UINT.
+          dwVidMemTotal = 0xffffffffu;
+        } else {
+          dwVidMemTotal = (1u << count);
         }
-        dwVidMemTotal = (1 << count);
       }
     }
 

+ 0 - 1
panda/src/dxgsg9/wdxGraphicsPipe9.h

@@ -93,7 +93,6 @@ private:
 
   typedef pvector<CardID> CardIDs;
   CardIDs _card_ids;
-  bool __is_dx9_1;
 
 public:
   static TypeHandle get_class_type() {

+ 1 - 2
panda/src/dxgsg9/wdxGraphicsWindow9.cxx

@@ -878,7 +878,7 @@ choose_device() {
     LARGE_INTEGER *DrvVer = &adapter_info.DriverVersion;
 
     wdxdisplay9_cat.info()
-      << "D3D9." << (dxpipe->__is_dx9_1 ?"1":"0") << " Adapter[" << i << "]: " << adapter_info.Description
+      << "D3D9 Adapter[" << i << "]: " << adapter_info.Description
       << ", Driver: " << adapter_info.Driver << ", DriverVersion: ("
       << HIWORD(DrvVer->HighPart) << "." << LOWORD(DrvVer->HighPart) << "."
       << HIWORD(DrvVer->LowPart) << "." << LOWORD(DrvVer->LowPart)
@@ -979,7 +979,6 @@ consider_device(wdxGraphicsPipe9 *dxpipe, DXDeviceInfo *device_info) {
 
   nassertr(_dxgsg != nullptr, false);
   _wcontext._d3d9 = _d3d9;
-  _wcontext._is_dx9_1 = dxpipe->__is_dx9_1;
   _wcontext._card_id = device_info->cardID;  // could this change by end?
 
   bool bWantStencil = (_fb_properties.get_stencil_bits() > 0);

+ 1 - 8
panda/src/event/asyncFuture_ext.cxx

@@ -168,14 +168,7 @@ static PyObject *gen_next(PyObject *self) {
  */
 PyObject *Extension<AsyncFuture>::
 __await__(PyObject *self) {
-  Dtool_GeneratorWrapper *gen;
-  gen = (Dtool_GeneratorWrapper *)PyType_GenericAlloc(&Dtool_GeneratorWrapper_Type, 0);
-  if (gen != nullptr) {
-    Py_INCREF(self);
-    gen->_base._self = self;
-    gen->_iternext_func = &gen_next;
-  }
-  return (PyObject *)gen;
+  return Dtool_NewGenerator(self, &gen_next);
 }
 
 /**

+ 1 - 1
panda/src/event/asyncFuture_ext.h

@@ -16,7 +16,7 @@
 
 #include "extension.h"
 #include "py_panda.h"
-#include "modelLoadRequest.h"
+#include "asyncFuture.h"
 
 #ifdef HAVE_PYTHON
 

+ 0 - 8
panda/src/express/config_express.cxx

@@ -190,11 +190,3 @@ get_verify_dcast() {
 
   return *verify_dcast;
 }
-
-// Returns the configure object for accessing config variables from a
-// scripting language.
-DConfig &
-get_config_express() {
-  static DConfig config_express;
-  return config_express;
-}

+ 0 - 5
panda/src/express/config_express.h

@@ -54,11 +54,6 @@ extern ConfigVariableBool multifile_always_binary;
 extern EXPCL_PANDA_EXPRESS ConfigVariableBool collect_tcp;
 extern EXPCL_PANDA_EXPRESS ConfigVariableDouble collect_tcp_interval;
 
-// Expose the Config variable for Python access.
-BEGIN_PUBLISH
-EXPCL_PANDA_EXPRESS DConfig &get_config_express();
-END_PUBLISH
-
 extern EXPCL_PANDA_EXPRESS void init_libexpress();
 
 #endif /* __CONFIG_UTIL_H__ */

+ 2 - 0
panda/src/express/virtualFileSystem.cxx

@@ -22,6 +22,8 @@
 #include "dSearchPath.h"
 #include "dcast.h"
 #include "config_express.h"
+#include "configVariableList.h"
+#include "configVariableString.h"
 #include "executionEnvironment.h"
 #include "pset.h"
 

+ 72 - 0
panda/src/glstuff/glShaderContext_src.cxx

@@ -1145,6 +1145,78 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
       }
       return;
     }
+    if (size > 4 && noprefix.substr(0, 4) == "Fog.") {
+      Shader::ShaderMatSpec bind;
+      bind._id = arg_id;
+      bind._func = Shader::SMF_first;
+      bind._arg[0] = nullptr;
+      bind._dep[0] = Shader::SSD_general | Shader::SSD_fog;
+      bind._part[1] = Shader::SMO_identity;
+      bind._arg[1] = nullptr;
+      bind._dep[1] = Shader::SSD_NONE;
+
+      if (noprefix == "Fog.color") {
+        bind._part[0] = Shader::SMO_attr_fogcolor;
+
+        if (param_type == GL_FLOAT_VEC3) {
+          bind._piece = Shader::SMP_row3x3;
+        } else if (param_type == GL_FLOAT_VEC4) {
+          bind._piece = Shader::SMP_row3;
+        } else {
+          GLCAT.error()
+            << "p3d_Fog.color should be vec3 or vec4\n";
+          return;
+        }
+
+      } else if (noprefix == "Fog.density") {
+        bind._part[0] = Shader::SMO_attr_fog;
+
+        if (param_type == GL_FLOAT) {
+          bind._piece = Shader::SMP_row3x1;
+        } else {
+          GLCAT.error()
+            << "p3d_Fog.density should be float\n";
+          return;
+        }
+
+      } else if (noprefix == "Fog.start") {
+        bind._part[0] = Shader::SMO_attr_fog;
+
+        if (param_type == GL_FLOAT) {
+          bind._piece = Shader::SMP_cell13;
+        } else {
+          GLCAT.error()
+            << "p3d_Fog.start should be float\n";
+          return;
+        }
+
+      } else if (noprefix == "Fog.end") {
+        bind._part[0] = Shader::SMO_attr_fog;
+
+        if (param_type == GL_FLOAT) {
+          bind._piece = Shader::SMP_cell14;
+        } else {
+          GLCAT.error()
+            << "p3d_Fog.end should be float\n";
+          return;
+        }
+
+      } else if (noprefix == "Fog.scale") {
+        bind._part[0] = Shader::SMO_attr_fog;
+
+        if (param_type == GL_FLOAT) {
+          bind._piece = Shader::SMP_cell15;
+        } else {
+          GLCAT.error()
+            << "p3d_Fog.scale should be float\n";
+          return;
+        }
+      }
+
+      _shader->_mat_spec.push_back(bind);
+      _shader->_mat_deps |= bind._dep[0];
+      return;
+    }
     if (noprefix == "LightModel.ambient") {
       Shader::ShaderMatSpec bind;
       bind._id = arg_id;

+ 1 - 5
panda/src/gobj/internalName.h

@@ -96,11 +96,7 @@ PUBLISHED:
 #ifdef HAVE_PYTHON
   // These versions are exposed to Python, which have additional logic to map
   // from Python interned strings.
-#if PY_MAJOR_VERSION >= 3
-  EXTENSION(static PT(InternalName) make(PyUnicodeObject *str));
-#else
-  EXTENSION(static PT(InternalName) make(PyStringObject *str));
-#endif
+  EXTENSION(static PT(InternalName) make(PyObject *str));
 #endif
 
 public:

+ 12 - 2
panda/src/gobj/internalName_ext.cxx

@@ -24,7 +24,12 @@ using std::string;
  */
 #if PY_MAJOR_VERSION >= 3
 PT(InternalName) Extension<InternalName>::
-make(PyUnicodeObject *str) {
+make(PyObject *str) {
+  if (!PyUnicode_Check(str)) {
+    Dtool_Raise_ArgTypeError(str, 0, "InternalName.make", "str");
+    return nullptr;
+  }
+
   if (!PyUnicode_CHECK_INTERNED(str)) {
     // Not an interned string; don't bother.
     Py_ssize_t len = 0;
@@ -50,7 +55,12 @@ make(PyUnicodeObject *str) {
 
 #else
 PT(InternalName) Extension<InternalName>::
-make(PyStringObject *str) {
+make(PyObject *str) {
+  if (!PyString_Check(str)) {
+    Dtool_Raise_ArgTypeError(str, 0, "InternalName.make", "str");
+    return nullptr;
+  }
+
   if (!PyString_CHECK_INTERNED(str)) {
     // Not an interned string; don't bother.
     string name(PyString_AS_STRING(str), PyString_GET_SIZE(str));

+ 1 - 5
panda/src/gobj/internalName_ext.h

@@ -29,11 +29,7 @@
 template<>
 class Extension<InternalName> : public ExtensionBase<InternalName> {
 public:
-#if PY_MAJOR_VERSION >= 3
-  static PT(InternalName) make(PyUnicodeObject *str);
-#else
-  static PT(InternalName) make(PyStringObject *str);
-#endif
+  static PT(InternalName) make(PyObject *str);
 };
 
 #endif  // HAVE_PYTHON

+ 285 - 94
panda/src/gobj/shader.cxx

@@ -2468,6 +2468,96 @@ read(const ShaderFile &sfile, BamCacheRecord *record) {
   return true;
 }
 
+/**
+ * Loads the shader from the given string(s). Returns a boolean indicating
+ * success or failure.
+ */
+bool Shader::
+load(const ShaderFile &sbody, BamCacheRecord *record) {
+  _filename = ShaderFile("created-shader");
+  _fullpath = Filename();
+  _text._separate = sbody._separate;
+
+  if (sbody._separate) {
+    if (_language == SL_none) {
+      shader_cat.error()
+        << "No shader language was specified!\n";
+      return false;
+    }
+
+    if (!sbody._vertex.empty() &&
+        !do_load_source(_text._vertex, sbody._vertex, record)) {
+      return false;
+    }
+    if (!sbody._fragment.empty() &&
+        !do_load_source(_text._fragment, sbody._fragment, record)) {
+      return false;
+    }
+    if (!sbody._geometry.empty() &&
+        !do_load_source(_text._geometry, sbody._geometry, record)) {
+      return false;
+    }
+    if (!sbody._tess_control.empty() &&
+        !do_load_source(_text._tess_control, sbody._tess_control, record)) {
+      return false;
+    }
+    if (!sbody._tess_evaluation.empty() &&
+        !do_load_source(_text._tess_evaluation, sbody._tess_evaluation, record)) {
+      return false;
+    }
+    if (!sbody._compute.empty() &&
+        !do_load_source(_text._compute, sbody._compute, record)) {
+      return false;
+    }
+
+  } else {
+    if (!do_load_source(_text._shared, sbody._shared, record)) {
+      return false;
+    }
+
+    // Determine which language the shader is written in.
+    if (_language == SL_none) {
+      string header;
+      parse_init();
+      parse_line(header, true, true);
+      if (header == "//Cg") {
+        _language = SL_Cg;
+      } else {
+        shader_cat.error()
+          << "Unable to determine shader language of " << sbody._shared << "\n";
+        return false;
+      }
+    } else if (_language == SL_GLSL) {
+      shader_cat.error()
+        << "GLSL shaders must have separate shader bodies!\n";
+      return false;
+    }
+
+    // Determine which language the shader is written in.
+    if (_language == SL_Cg) {
+#ifdef HAVE_CG
+      cg_get_profile_from_header(_default_caps);
+
+      if (!cg_analyze_shader(_default_caps)) {
+        shader_cat.error()
+          << "Shader encountered an error.\n";
+        return false;
+      }
+#else
+      shader_cat.error()
+        << "Tried to load Cg shader, but no Cg support is enabled.\n";
+#endif
+    } else {
+      shader_cat.error()
+        << "Shader is not in a supported shader-language.\n";
+      return false;
+    }
+  }
+
+  _loaded = true;
+  return true;
+}
+
 /**
  * Reads the shader file from the given path into the given string.
  *
@@ -2476,37 +2566,85 @@ read(const ShaderFile &sfile, BamCacheRecord *record) {
  */
 bool Shader::
 do_read_source(string &into, const Filename &fn, BamCacheRecord *record) {
+  VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
+  PT(VirtualFile) vf = vfs->find_file(fn, get_model_path());
+  if (vf == nullptr) {
+    shader_cat.error()
+      << "Could not find shader file: " << fn << "\n";
+    return false;
+  }
+
   if (_language == SL_GLSL && glsl_preprocess) {
+    istream *source = vf->open_read_file(true);
+    if (source == nullptr) {
+      shader_cat.error()
+        << "Could not open shader file: " << fn << "\n";
+      return false;
+    }
+
     // Preprocess the GLSL file as we read it.
+    shader_cat.info()
+      << "Preprocessing shader file: " << fn << "\n";
+
     std::set<Filename> open_files;
     ostringstream sstr;
-    if (!r_preprocess_source(sstr, fn, Filename(), open_files, record)) {
+    if (!r_preprocess_source(sstr, *source, fn, vf->get_filename(), open_files, record)) {
+      vf->close_read_file(source);
       return false;
     }
+    vf->close_read_file(source);
     into = sstr.str();
 
   } else {
     shader_cat.info() << "Reading shader file: " << fn << "\n";
 
-    VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
-    PT(VirtualFile) vf = vfs->find_file(fn, get_model_path());
-    if (vf == nullptr) {
-      shader_cat.error()
-        << "Could not find shader file: " << fn << "\n";
-      return false;
-    }
-
     if (!vf->read_file(into, true)) {
       shader_cat.error()
         << "Could not read shader file: " << fn << "\n";
       return false;
     }
+  }
+
+  if (record != nullptr) {
+    record->add_dependent_file(vf);
+  }
 
-    if (record != nullptr) {
-      record->add_dependent_file(vf);
+  _last_modified = std::max(_last_modified, vf->get_timestamp());
+  _source_files.push_back(vf->get_filename());
+
+  // Strip trailing whitespace.
+  while (!into.empty() && isspace(into[into.size() - 1])) {
+    into.resize(into.size() - 1);
+  }
+
+  // Except add back a newline at the end, which is needed by Intel drivers.
+  into += "\n";
+
+  return true;
+}
+
+/**
+ * Loads the shader file from the given string into the given string,
+ * performing any pre-processing on it that may be necessary.
+ *
+ * Returns false if there was an error with this shader bad enough to consider
+ * it 'invalid'.
+ */
+bool Shader::
+do_load_source(string &into, const std::string &source, BamCacheRecord *record) {
+  if (_language == SL_GLSL && glsl_preprocess) {
+    // Preprocess the GLSL file as we read it.
+    std::set<Filename> open_files;
+    std::ostringstream sstr;
+    std::istringstream in(source);
+    if (!r_preprocess_source(sstr, in, Filename("created-shader"), Filename(),
+                             open_files, record)) {
+      return false;
     }
-    _last_modified = std::max(_last_modified, vf->get_timestamp());
-    _source_files.push_back(vf->get_filename());
+    into = sstr.str();
+
+  } else {
+    into = source;
   }
 
   // Strip trailing whitespace.
@@ -2528,10 +2666,10 @@ do_read_source(string &into, const Filename &fn, BamCacheRecord *record) {
  * recursive includes.
  */
 bool Shader::
-r_preprocess_source(ostream &out, const Filename &fn,
-                    const Filename &source_dir,
-                    std::set<Filename> &once_files,
-                    BamCacheRecord *record, int depth) {
+r_preprocess_include(ostream &out, const Filename &fn,
+                     const Filename &source_dir,
+                     std::set<Filename> &once_files,
+                     BamCacheRecord *record, int depth) {
 
   if (depth > glsl_include_recursion_limit) {
     shader_cat.error()
@@ -2549,7 +2687,7 @@ r_preprocess_source(ostream &out, const Filename &fn,
   PT(VirtualFile) vf = vfs->find_file(fn, path);
   if (vf == nullptr) {
     shader_cat.error()
-      << "Could not find shader file: " << fn << "\n";
+      << "Could not find shader include: " << fn << "\n";
     return false;
   }
 
@@ -2562,7 +2700,7 @@ r_preprocess_source(ostream &out, const Filename &fn,
   istream *source = vf->open_read_file(true);
   if (source == nullptr) {
     shader_cat.error()
-      << "Could not open shader file: " << fn << "\n";
+      << "Could not open shader include: " << fn << "\n";
     return false;
   }
 
@@ -2578,34 +2716,52 @@ r_preprocess_source(ostream &out, const Filename &fn,
   // than that, unfortunately.  Don't do this for the top-level file, though.
   // We don't want anything to get in before a potential #version directive.
   int fileno = 0;
-  if (depth > 0) {
-    fileno = 2048 + _included_files.size();
-    // Write it into the vector so that we can substitute it later when we are
-    // parsing the GLSL error log.  Don't store the full filename because it
-    // would just be too long to display.
-    _included_files.push_back(fn);
-
-    out << "#line 1 " << fileno << " // " << fn << "\n";
-    if (shader_cat.is_debug()) {
-      shader_cat.debug()
-        << "Preprocessing shader include " << fileno << ": " << fn << "\n";
-    }
-  } else {
-    shader_cat.info()
-      << "Preprocessing shader file: " << fn << "\n";
+  fileno = 2048 + _included_files.size();
+
+  // Write it into the vector so that we can substitute it later when we are
+  // parsing the GLSL error log.  Don't store the full filename because it
+  // would just be too long to display.
+  _included_files.push_back(fn);
+
+  if (shader_cat.is_debug()) {
+    shader_cat.debug()
+      << "Preprocessing shader include " << fileno << ": " << fn << "\n";
   }
 
+  bool result = r_preprocess_source(out, *source, fn, full_fn, once_files, record, fileno, depth);
+  vf->close_read_file(source);
+  return result;
+}
+
+/**
+ * Loads a given GLSL stream line by line, processing any #pragma include and
+ * once statements, as well as removing any comments.
+ *
+ * The set keeps track of which files we have already included, for checking
+ * recursive includes.
+ */
+bool Shader::
+r_preprocess_source(ostream &out, istream &in, const Filename &fn,
+                    const Filename &full_fn, std::set<Filename> &once_files,
+                    BamCacheRecord *record, int fileno, int depth) {
+
   // Iterate over the lines for things we may need to preprocess.
   string line;
   int ext_google_include = 0; // 1 = warn, 2 = enable
   int ext_google_line = 0;
   bool had_include = false;
   int lineno = 0;
-  while (std::getline(*source, line)) {
+  bool write_line_directive = (fileno != 0);
+
+  while (std::getline(in, line)) {
     ++lineno;
 
     if (line.empty()) {
-      out.put('\n');
+      // We still write a newline to make sure the line numbering remains
+      // consistent, unless we are about to write a #line directive anyway.
+      if (!write_line_directive) {
+        out.put('\n');
+      }
       continue;
     }
 
@@ -2615,9 +2771,11 @@ r_preprocess_source(ostream &out, const Filename &fn,
       line.resize(line.size() - 1);
       string line2;
 
-      if (std::getline(*source, line2)) {
+      if (std::getline(in, line2)) {
         line += line2;
-        out.put('\n');
+        if (!write_line_directive) {
+          out.put('\n');
+        }
         ++lineno;
       } else {
         break;
@@ -2644,8 +2802,10 @@ r_preprocess_source(ostream &out, const Filename &fn,
       size_t block_end = line2.find("*/");
       while (block_end == string::npos) {
         // Didn't find it - look in the next line.
-        if (std::getline(*source, line2)) {
-          out.put('\n');
+        if (std::getline(in, line2)) {
+          if (!write_line_directive) {
+            out.put('\n');
+          }
           ++lineno;
           block_end = line2.find("*/");
         } else {
@@ -2663,10 +2823,21 @@ r_preprocess_source(ostream &out, const Filename &fn,
       line.resize(line.size() - 1);
     }
 
+    if (line.empty()) {
+      if (!write_line_directive) {
+        out.put('\n');
+      }
+      continue;
+    }
+
     // Check if this line contains a #directive.
     char directive[64];
     if (line.size() < 8 || sscanf(line.c_str(), " # %63s", directive) != 1) {
       // Nope.  Just pass the line through unmodified.
+      if (write_line_directive) {
+        out << "#line " << lineno << " " << fileno << " // " << fn << "\n";
+        write_line_directive = false;
+      }
       out << line << "\n";
       continue;
     }
@@ -2703,7 +2874,7 @@ r_preprocess_source(ostream &out, const Filename &fn,
         }
 
         // OK, great.  Process the include.
-        if (!r_preprocess_source(out, incfn, source_dir, once_files, record, depth + 1)) {
+        if (!r_preprocess_include(out, incfn, source_dir, once_files, record, depth + 1)) {
           // An error occurred.  Pass on the failure.
           shader_cat.error(false) << "included at line "
             << lineno << " of file " << fn << ":\n  " << line << "\n";
@@ -2711,8 +2882,9 @@ r_preprocess_source(ostream &out, const Filename &fn,
         }
 
         // Restore the line counter.
-        out << "#line " << (lineno + 1) << " " << fileno << " // " << fn << "\n";
+        write_line_directive = true;
         had_include = true;
+        continue;
 
       } else if (strcmp(pragma, "once") == 0) {
         // Do a stricter syntax check, just to be extra safe.
@@ -2724,26 +2896,35 @@ r_preprocess_source(ostream &out, const Filename &fn,
           return false;
         }
 
-        once_files.insert(full_fn);
+        if (fileno == 0) {
+          shader_cat.warning()
+            << "#pragma once in main file at line "
+            << lineno << " of file " << fn
+#ifndef NDEBUG
+            << ":\n  " << line
+#endif
+            << "\n";
+        }
 
-      } else {
-        // Forward it, the driver will ignore it if it doesn't know it.
-        out << line << "\n";
+        if (!full_fn.empty()) {
+          once_files.insert(full_fn);
+        }
+        continue;
       }
+      // Otherwise, just pass it through to the driver.
 
     } else if (strcmp(directive, "endif") == 0) {
       // Check for an #endif after an include.  We have to restore the line
       // number in case the include happened under an #if block.
-      out << line << "\n";
       if (had_include) {
-        out << "#line " << (lineno + 1) << " " << fileno << "\n";
+        write_line_directive = true;
       }
 
     } else if (strcmp(directive, "extension") == 0) {
       // Check for special preprocessing extensions.
       char extension[256];
       char behavior[9];
-      if (sscanf(line.c_str(), " # extension%*[ \t]%255s%*[ \t]:%*[ \t]%8s", extension, behavior) == 2) {
+      if (sscanf(line.c_str(), " # extension%*[ \t]%255[^: \t] : %8s", extension, behavior) == 2) {
         // Parse the behavior string.
         int mode;
         if (strcmp(behavior, "require") == 0 || strcmp(behavior, "enable") == 0) {
@@ -2769,7 +2950,8 @@ r_preprocess_source(ostream &out, const Filename &fn,
           }
           ext_google_include = mode;
           ext_google_line = mode;
-          out << line << "\n";
+          // Still pass it through to the driver, so it can enable other
+          // extensions.
 
         } else if (strcmp(extension, "GL_GOOGLE_include_directive") == 0) {
           // Enable the Google extension support for #include statements.
@@ -2777,14 +2959,12 @@ r_preprocess_source(ostream &out, const Filename &fn,
           // This matches the behavior of Khronos' glslang reference compiler.
           ext_google_include = mode;
           ext_google_line = mode;
+          continue;
 
         } else if (strcmp(extension, "GL_GOOGLE_cpp_style_line_directive") == 0) {
           // Enables strings in #line statements.
           ext_google_line = mode;
-
-        } else {
-          // It's an extension the driver should worry about.
-          out << line << "\n";
+          continue;
         }
       } else {
         shader_cat.error()
@@ -2792,6 +2972,7 @@ r_preprocess_source(ostream &out, const Filename &fn,
           << lineno << " of file " << fn << ":\n  " << line << "\n";
         return false;
       }
+
     } else if (ext_google_include > 0 && strcmp(directive, "include") == 0) {
       // Warn about extension use if requested.
       if (ext_google_include == 1) {
@@ -2821,7 +3002,7 @@ r_preprocess_source(ostream &out, const Filename &fn,
 
       // OK, great.  Process the include.
       Filename source_dir = full_fn.get_dirname();
-      if (!r_preprocess_source(out, incfn, source_dir, once_files, record, depth + 1)) {
+      if (!r_preprocess_include(out, incfn, source_dir, once_files, record, depth + 1)) {
         // An error occurred.  Pass on the failure.
         shader_cat.error(false) << "included at line "
           << lineno << " of file " << fn << ":\n  " << line << "\n";
@@ -2829,8 +3010,9 @@ r_preprocess_source(ostream &out, const Filename &fn,
       }
 
       // Restore the line counter.
-      out << "#line " << (lineno + 1) << " " << fileno << " // " << fn << "\n";
+      write_line_directive = true;
       had_include = true;
+      continue;
 
     } else if (ext_google_line > 0 && strcmp(directive, "line") == 0) {
       // It's a #line directive.  See if it uses a string instead of number.
@@ -2854,18 +3036,17 @@ r_preprocess_source(ostream &out, const Filename &fn,
         _included_files.push_back(Filename(filestr));
 
         out << "#line " << lineno << " " << fileno << " // " << filestr << "\n";
-
-      } else {
-        // We couldn't parse the #line directive.  Pass it through unmodified.
-        out << line << "\n";
+        continue;
       }
-    } else {
-      // Different directive (eg. #version).  Leave it untouched.
-      out << line << "\n";
     }
+
+    if (write_line_directive) {
+      out << "#line " << lineno << " " << fileno << " // " << fn << "\n";
+      write_line_directive = false;
+    }
+    out << line << "\n";
   }
 
-  vf->close_read_file(source);
   return true;
 }
 
@@ -3227,28 +3408,26 @@ make(string body, ShaderLanguage lang) {
   if (cache_generated_shaders) {
     ShaderTable::const_iterator i = _make_table.find(sbody);
     if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) {
-      return i->second;
+      // But check that someone hasn't modified its includes in the meantime.
+      if (!i->second->check_modified()) {
+        return i->second;
+      }
     }
   }
 
   PT(Shader) shader = new Shader(lang);
-  shader->_filename = ShaderFile("created-shader");
-  shader->_text = move(sbody);
-
-#ifdef HAVE_CG
-  if (lang == SL_Cg) {
-    shader->cg_get_profile_from_header(_default_caps);
-
-    if (!shader->cg_analyze_shader(_default_caps)) {
-      shader_cat.error()
-        << "Shader encountered an error.\n";
-      return nullptr;
-    }
+  if (!shader->load(sbody)) {
+    return nullptr;
   }
-#endif
 
   if (cache_generated_shaders) {
-    _make_table[shader->_text] = shader;
+    ShaderTable::const_iterator i = _make_table.find(shader->_text);
+    if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) {
+      shader = i->second;
+    } else {
+      _make_table[shader->_text] = shader;
+    }
+    _make_table[std::move(sbody)] = shader;
   }
 
   if (dump_generated_shaders) {
@@ -3290,26 +3469,27 @@ make(ShaderLanguage lang, string vertex, string fragment, string geometry,
   if (cache_generated_shaders) {
     ShaderTable::const_iterator i = _make_table.find(sbody);
     if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) {
-      return i->second;
+      // But check that someone hasn't modified its includes in the meantime.
+      if (!i->second->check_modified()) {
+        return i->second;
+      }
     }
   }
 
   PT(Shader) shader = new Shader(lang);
   shader->_filename = ShaderFile("created-shader");
-  shader->_text = move(sbody);
-
-#ifdef HAVE_CG
-  if (lang == SL_Cg) {
-    if (!shader->cg_analyze_shader(_default_caps)) {
-      shader_cat.error()
-        << "Shader encountered an error.\n";
-      return nullptr;
-    }
+  if (!shader->load(sbody)) {
+    return nullptr;
   }
-#endif
 
   if (cache_generated_shaders) {
-    _make_table[shader->_text] = shader;
+    ShaderTable::const_iterator i = _make_table.find(shader->_text);
+    if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) {
+      shader = i->second;
+    } else {
+      _make_table[shader->_text] = shader;
+    }
+    _make_table[std::move(sbody)] = shader;
   }
 
   return shader;
@@ -3333,16 +3513,27 @@ make_compute(ShaderLanguage lang, string body) {
   if (cache_generated_shaders) {
     ShaderTable::const_iterator i = _make_table.find(sbody);
     if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) {
-      return i->second;
+      // But check that someone hasn't modified its includes in the meantime.
+      if (!i->second->check_modified()) {
+        return i->second;
+      }
     }
   }
 
   PT(Shader) shader = new Shader(lang);
   shader->_filename = ShaderFile("created-shader");
-  shader->_text = move(sbody);
+  if (!shader->load(sbody)) {
+    return nullptr;
+  }
 
   if (cache_generated_shaders) {
-    _make_table[shader->_text] = shader;
+    ShaderTable::const_iterator i = _make_table.find(shader->_text);
+    if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) {
+      shader = i->second;
+    } else {
+      _make_table[shader->_text] = shader;
+    }
+    _make_table[std::move(sbody)] = shader;
   }
 
   return shader;

+ 10 - 3
panda/src/gobj/shader.h

@@ -616,11 +616,18 @@ private:
   Shader(ShaderLanguage lang);
 
   bool read(const ShaderFile &sfile, BamCacheRecord *record = nullptr);
+  bool load(const ShaderFile &sbody, BamCacheRecord *record = nullptr);
   bool do_read_source(std::string &into, const Filename &fn, BamCacheRecord *record);
-  bool r_preprocess_source(std::ostream &out, const Filename &fn,
-                           const Filename &source_dir,
+  bool do_load_source(std::string &into, const std::string &source, BamCacheRecord *record);
+  bool r_preprocess_include(std::ostream &out, const Filename &fn,
+                            const Filename &source_dir,
+                            std::set<Filename> &open_files,
+                            BamCacheRecord *record, int depth);
+  bool r_preprocess_source(std::ostream &out, std::istream &in,
+                           const Filename &fn, const Filename &full_fn,
                            std::set<Filename> &open_files,
-                           BamCacheRecord *record, int depth = 0);
+                           BamCacheRecord *record,
+                           int fileno = 0, int depth = 0);
 
   bool check_modified() const;
 

+ 1 - 3
panda/src/ode/odeBody.I

@@ -89,12 +89,10 @@ set_data(void *data) {
   dBodySetData(_id, data);
 }
 
-#ifndef HAVE_PYTHON
-INLINE void* OdeBody::
+INLINE void *OdeBody::
 get_data() const {
   return dBodyGetData(_id);
 }
-#endif
 
 INLINE void OdeBody::
 set_position(dReal x, dReal y, dReal z) {

+ 4 - 23
panda/src/ode/odeBody.cxx

@@ -15,10 +15,6 @@
 #include "odeBody.h"
 #include "odeJoint.h"
 
-#ifdef HAVE_PYTHON
-#include "py_panda.h"
-#endif
-
 TypeHandle OdeBody::_type_handle;
 
 OdeBody::
@@ -38,29 +34,14 @@ OdeBody::
 
 void OdeBody::
 destroy() {
-#ifdef HAVE_PYTHON
-  Py_XDECREF((PyObject*) dBodyGetData(_id));
-#endif
+  if (_destroy_callback != nullptr) {
+    _destroy_callback(*this);
+    _destroy_callback = nullptr;
+  }
   nassertv(_id);
   dBodyDestroy(_id);
 }
 
-#ifdef HAVE_PYTHON
-void OdeBody::
-set_data(PyObject *data) {
-  Py_XDECREF((PyObject*) dBodyGetData(_id));
-  Py_XINCREF(data);
-  dBodySetData(_id, data);
-}
-
-PyObject* OdeBody::
-get_data() const {
-  PyObject* data = (PyObject*) dBodyGetData(_id);
-  Py_XINCREF(data);
-  return data;
-}
-#endif
-
 OdeJoint OdeBody::
 get_joint(int index) const {
   nassertr(_id != nullptr, OdeJoint(nullptr));

+ 8 - 7
panda/src/ode/odeBody.h

@@ -51,9 +51,7 @@ PUBLISHED:
   INLINE void set_auto_disable_flag(int do_auto_disable);
   INLINE void set_auto_disable_defaults();
   INLINE void set_data(void *data);
-#ifdef HAVE_PYTHON
-  void set_data(PyObject *data);
-#endif
+  EXTENSION(void set_data(PyObject *data));
 
   INLINE void set_position(dReal x, dReal y, dReal z);
   INLINE void set_position(const LVecBase3f &pos);
@@ -71,11 +69,10 @@ PUBLISHED:
   INLINE int   get_auto_disable_steps() const;
   INLINE dReal get_auto_disable_time() const;
   INLINE int   get_auto_disable_flag() const;
-#ifdef HAVE_PYTHON
-  PyObject* get_data() const;
-#else
-  INLINE void* get_data() const;
+#ifndef CPPPARSER
+  INLINE void *get_data() const;
 #endif
+  EXTENSION(PyObject *get_data() const);
 
   INLINE LVecBase3f  get_position() const;
   INLINE LMatrix3f  get_rotation() const;
@@ -150,6 +147,10 @@ PUBLISHED:
 private:
   dBodyID _id;
 
+public:
+  typedef void (*DestroyCallback)(OdeBody &body);
+  DestroyCallback _destroy_callback = nullptr;
+
 public:
   static TypeHandle get_class_type() {
     return _type_handle;

+ 13 - 0
panda/src/ode/odeBody_ext.I

@@ -13,6 +13,19 @@
 
 #include "odeJoint_ext.h"
 
+/**
+ * Returns the custom data associated with the OdeBody.
+ */
+INLINE PyObject *Extension<OdeBody>::
+get_data() const {
+  PyObject *data = (PyObject *)_this->get_data();
+  if (data == nullptr) {
+    data = Py_None;
+  }
+  Py_INCREF(data);
+  return data;
+}
+
 /**
  * Equivalent to get_joint().convert()
  */

+ 37 - 0
panda/src/ode/odeBody_ext.cxx

@@ -0,0 +1,37 @@
+/**
+ * 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 odeBody_ext.cxx
+ * @author rdb
+ * @date 2018-11-06
+ */
+
+#include "odeBody_ext.h"
+
+static void destroy_callback(OdeBody &body) {
+  Py_XDECREF((PyObject *)body.get_data());
+}
+
+/**
+ * Sets custom data to be associated with the OdeBody.
+ */
+void Extension<OdeBody>::
+set_data(PyObject *data) {
+  void *old_data = _this->get_data();
+
+  if (data != nullptr && data != Py_None) {
+    Py_INCREF(data);
+    _this->set_data((void *)data);
+    _this->_destroy_callback = &destroy_callback;
+  } else {
+    _this->set_data(nullptr);
+    _this->_destroy_callback = nullptr;
+  }
+
+  Py_XDECREF((PyObject *)old_data);
+}

+ 3 - 0
panda/src/ode/odeBody_ext.h

@@ -30,6 +30,9 @@
 template<>
 class Extension<OdeBody> : public ExtensionBase<OdeBody> {
 public:
+  void set_data(PyObject *);
+  INLINE PyObject *get_data() const;
+
   INLINE PyObject *get_converted_joint(int i) const;
 };
 

+ 1 - 0
panda/src/ode/p3ode_ext_composite.cxx

@@ -1,3 +1,4 @@
+#include "odeBody_ext.cxx"
 #include "odeGeom_ext.cxx"
 #include "odeJoint_ext.cxx"
 #include "odeSpace_ext.cxx"

+ 1 - 0
panda/src/pgraph/config_pgraph.h

@@ -21,6 +21,7 @@
 #include "configVariableInt.h"
 #include "configVariableDouble.h"
 #include "configVariableList.h"
+#include "configVariableString.h"
 
 class DSearchPath;
 

+ 1 - 0
panda/src/physx/config_physx.h

@@ -19,6 +19,7 @@
 #include "configVariableBool.h"
 #include "configVariableEnum.h"
 #include "configVariableInt.h"
+#include "configVariableString.h"
 #include "dconfig.h"
 
 #include "physxEnums.h"

+ 1 - 1
panda/src/pipeline/cycleData.h

@@ -44,7 +44,7 @@ class EXPCL_PANDA_PIPELINE CycleData : public NodeReferenceCount
 // If we are *not* compiling in pipelining support, the CycleData object is
 // stored directly within its containing classes, and hence should not be a
 // ReferenceCount object.
-class EXPCL_PANDA_PIPELINE CycleData
+class EXPCL_PANDA_PIPELINE CycleData : public MemoryBase
 
 #endif  // DO_PIPELINING
 {

+ 2 - 0
panda/src/putil/config_putil.h

@@ -16,9 +16,11 @@
 
 #include "pandabase.h"
 #include "notifyCategoryProxy.h"
+#include "configVariableBool.h"
 #include "configVariableSearchPath.h"
 #include "configVariableEnum.h"
 #include "configVariableDouble.h"
+#include "configVariableInt.h"
 #include "bamEnums.h"
 #include "dconfig.h"
 

+ 6 - 1
panda/src/vision/webcamVideoCursorOpenCV.cxx

@@ -11,12 +11,17 @@
  * @date 2010-10-20
  */
 
-#include "webcamVideoOpenCV.h"
+#include "webcamVideoCursorOpenCV.h"
 
 #ifdef HAVE_OPENCV
 
+#include "webcamVideoOpenCV.h"
+#include "movieVideoCursor.h"
+
 #include "pStatTimer.h"
 
+#include <opencv2/highgui/highgui.hpp>
+
 TypeHandle WebcamVideoCursorOpenCV::_type_handle;
 
 /**

+ 1 - 0
panda/src/vision/webcamVideoCursorOpenCV.h

@@ -22,6 +22,7 @@
 #include "movieVideoCursor.h"
 
 class WebcamVideoOpenCV;
+struct CvCapture;
 
 /**
  * The Video4Linux implementation of webcams.

+ 5 - 0
panda/src/vision/webcamVideoCursorV4L.cxx

@@ -11,8 +11,13 @@
  * @date 2010-06-11
  */
 
+#include "webcamVideoCursorV4L.h"
+
+#include "config_vision.h"
 #include "webcamVideoV4L.h"
 
+#include "movieVideoCursor.h"
+
 #if defined(HAVE_VIDEO4LINUX) && !defined(CPPPARSER)
 
 #include <fcntl.h>

+ 0 - 10
panda/src/vrpn/vrpn_interface.h

@@ -16,16 +16,6 @@
 
 #include "pandabase.h"
 
-#ifdef CPPPARSER
-  // For correct interrogate parsing of UNC's vrpn library.
-  #if defined(WIN32_VC) || defined(WIN64_VC)
-    #define SOCKET int
-  #else
-    #define linux
-    typedef struct timeval timeval;
-  #endif
-#endif
-
 // VPRN misses an include to this in vrpn_Shared.h.
 #include <stdint.h>
 

+ 1 - 0
panda/src/windisplay/winDetectDx9.cxx

@@ -18,6 +18,7 @@
 #ifndef WIN32_LEAN_AND_MEAN
 #define WIN32_LEAN_AND_MEAN 1
 #endif
+#undef Configure
 #include <d3d9.h>
 #include "graphicsStateGuardian.h"
 #include "graphicsPipe.h"

+ 0 - 1
pandatool/src/configfiles/pandatool.init

@@ -1 +0,0 @@
-ATTACH panda

+ 0 - 1
pandatool/src/progbase/programBase.cxx

@@ -19,7 +19,6 @@
 #include "dSearchPath.h"
 #include "coordinateSystem.h"
 #include "dconfig.h"
-#include "config_dconfig.h"
 #include "string_utils.h"
 #include "vector_string.h"
 #include "configVariableInt.h"

Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff