Browse Source

Merge branch 'master' into shaderpipeline

rdb 1 year ago
parent
commit
75c2eff999
100 changed files with 1251 additions and 14000 deletions
  1. 1 0
      .github/ISSUE_TEMPLATE/bug.md
  2. 12 0
      .github/ISSUE_TEMPLATE/config.yml
  3. 1 0
      .github/ISSUE_TEMPLATE/enhancement.md
  4. 7 0
      .github/dependabot.yml
  5. 125 55
      .github/workflows/ci.yml
  6. 2 2
      .github/workflows/mypy.yml
  7. 5 5
      README.md
  8. 1 0
      cmake/macros/Python.cmake
  9. 3 2
      direct/src/dcparser/dcField_ext.cxx
  10. 3 0
      direct/src/directbase/TestStart.py
  11. 3 0
      direct/src/directbase/ThreeUpStart.py
  12. 41 5
      direct/src/dist/commands.py
  13. 48 17
      direct/src/filter/CommonFilters.py
  14. 2 3
      direct/src/fsm/FSM.py
  15. 2 2
      direct/src/interval/cMetaInterval.cxx
  16. 2 1
      direct/src/showbase/DistancePhasedNode.py
  17. 82 74
      direct/src/showbase/ShowBase.py
  18. 1 1
      direct/src/stdpy/glob.py
  19. 2 2
      doc/CODING_STYLE.md
  20. 61 0
      doc/ReleaseNotes
  21. 4 4
      dtool/CompilerFlags.cmake
  22. 1 1
      dtool/Config.cmake
  23. 175 55
      dtool/Package.cmake
  24. 0 3112
      dtool/metalibs/dtoolconfig/pydtool.cxx
  25. 1 0
      dtool/src/dtoolbase/CMakeLists.txt
  26. 3 3
      dtool/src/dtoolbase/dtoolbase_cc.h
  27. 0 0
      dtool/src/dtoolbase/extension.h
  28. 6 0
      dtool/src/dtoolbase/pdtoa.cxx
  29. 20 3
      dtool/src/dtoolutil/executionEnvironment.cxx
  30. 11 0
      dtool/src/dtoolutil/executionEnvironment.h
  31. 23 9
      dtool/src/dtoolutil/filename_ext.cxx
  32. 4 72
      dtool/src/interrogatedb/CMakeLists.txt
  33. 0 66
      dtool/src/interrogatedb/config_interrogatedb.cxx
  34. 0 25
      dtool/src/interrogatedb/config_interrogatedb.h
  35. 0 177
      dtool/src/interrogatedb/dtool_super_base.cxx
  36. 0 68
      dtool/src/interrogatedb/indexRemapper.cxx
  37. 0 44
      dtool/src/interrogatedb/indexRemapper.h
  38. 0 123
      dtool/src/interrogatedb/interrogateComponent.I
  39. 0 50
      dtool/src/interrogatedb/interrogateComponent.cxx
  40. 0 67
      dtool/src/interrogatedb/interrogateComponent.h
  41. 0 89
      dtool/src/interrogatedb/interrogateDatabase.I
  42. 0 1330
      dtool/src/interrogatedb/interrogateDatabase.cxx
  43. 0 205
      dtool/src/interrogatedb/interrogateDatabase.h
  44. 0 259
      dtool/src/interrogatedb/interrogateElement.I
  45. 0 74
      dtool/src/interrogatedb/interrogateElement.cxx
  46. 0 103
      dtool/src/interrogatedb/interrogateElement.h
  47. 0 178
      dtool/src/interrogatedb/interrogateFunction.I
  48. 0 100
      dtool/src/interrogatedb/interrogateFunction.cxx
  49. 0 117
      dtool/src/interrogatedb/interrogateFunction.h
  50. 0 240
      dtool/src/interrogatedb/interrogateFunctionWrapper.I
  51. 0 84
      dtool/src/interrogatedb/interrogateFunctionWrapper.cxx
  52. 0 118
      dtool/src/interrogatedb/interrogateFunctionWrapper.h
  53. 0 103
      dtool/src/interrogatedb/interrogateMakeSeq.I
  54. 0 50
      dtool/src/interrogatedb/interrogateMakeSeq.cxx
  55. 0 60
      dtool/src/interrogatedb/interrogateMakeSeq.h
  56. 0 116
      dtool/src/interrogatedb/interrogateManifest.I
  57. 0 49
      dtool/src/interrogatedb/interrogateManifest.cxx
  58. 0 66
      dtool/src/interrogatedb/interrogateManifest.h
  59. 0 594
      dtool/src/interrogatedb/interrogateType.I
  60. 0 247
      dtool/src/interrogatedb/interrogateType.cxx
  61. 0 239
      dtool/src/interrogatedb/interrogateType.h
  62. 0 51
      dtool/src/interrogatedb/interrogate_datafile.I
  63. 0 98
      dtool/src/interrogatedb/interrogate_datafile.cxx
  64. 0 37
      dtool/src/interrogatedb/interrogate_datafile.h
  65. 0 1043
      dtool/src/interrogatedb/interrogate_interface.cxx
  66. 0 581
      dtool/src/interrogatedb/interrogate_interface.h
  67. 0 37
      dtool/src/interrogatedb/interrogate_request.cxx
  68. 0 7
      dtool/src/interrogatedb/p3interrogatedb_composite1.cxx
  69. 0 6
      dtool/src/interrogatedb/p3interrogatedb_composite2.cxx
  70. 0 50
      dtool/src/interrogatedb/py_compat.cxx
  71. 6 2
      dtool/src/interrogatedb/py_compat.h
  72. 0 957
      dtool/src/interrogatedb/py_panda.cxx
  73. 2 0
      dtool/src/interrogatedb/py_panda.h
  74. 0 1791
      dtool/src/interrogatedb/py_wrappers.cxx
  75. 5 1
      dtool/src/parser-inc/algorithm
  76. 9 0
      dtool/src/parser-inc/emscripten/heap.h
  77. 12 1
      makepanda/installer.nsi
  78. 4 1
      makepanda/installpanda.py
  79. 5 3
      makepanda/makepackage.py
  80. 75 54
      makepanda/makepanda.py
  81. 126 32
      makepanda/makepandacore.py
  82. 29 10
      makepanda/makewheel.py
  83. 6 2
      makepanda/test_wheel.py
  84. 7 0
      panda/src/audio/config_audio.cxx
  85. 1 0
      panda/src/audio/config_audio.h
  86. 16 1
      panda/src/audiotraits/openalAudioManager.cxx
  87. 1 0
      panda/src/audiotraits/openalAudioManager.h
  88. 1 0
      panda/src/audiotraits/openalAudioSound.h
  89. 2 10
      panda/src/bullet/bulletDebugNode.cxx
  90. 10 104
      panda/src/collide/collisionBox.I
  91. 236 536
      panda/src/collide/collisionBox.cxx
  92. 3 45
      panda/src/collide/collisionBox.h
  93. 36 32
      panda/src/collide/collisionSphere.cxx
  94. 4 10
      panda/src/collide/collisionVisualizer.cxx
  95. 2 2
      panda/src/cull/binCullHandler.cxx
  96. 1 1
      panda/src/cull/binCullHandler.h
  97. 0 12
      panda/src/cull/cullBinBackToFront.cxx
  98. 0 1
      panda/src/cull/cullBinBackToFront.h
  99. 0 12
      panda/src/cull/cullBinFixed.cxx
  100. 0 1
      panda/src/cull/cullBinFixed.h

+ 1 - 0
.github/ISSUE_TEMPLATE/bug.md

@@ -2,6 +2,7 @@
 name: Bug report
 about: Report a defect
 title:
+type: bug
 labels:
 assignees:
 ---

+ 12 - 0
.github/ISSUE_TEMPLATE/config.yml

@@ -0,0 +1,12 @@
+contact_links:
+  - name: Community forums
+    url: https://discourse.panda3d.org/
+    about: Please visit the community forums for technical support and other questions.
+
+  - name: Documentation bugs
+    url: https://github.com/panda3d/panda3d-docs/issues
+    about: Problems with the online documentation should be reported on the panda3d-docs issue tracker, not here.
+
+  - name: Discord server
+    url: https://discord.gg/UyepRMm
+    about: Get real-time help with questions about Panda3D or discuss ideas with the developers on our Discord server.

+ 1 - 0
.github/ISSUE_TEMPLATE/enhancement.md

@@ -2,6 +2,7 @@
 name: Enhancement request
 about: Request new functionality or improvement to existing functionality
 title:
+type: feature
 labels: enhancement
 assignees:
 ---

+ 7 - 0
.github/dependabot.yml

@@ -0,0 +1,7 @@
+version: 2
+updates:
+- package-ecosystem: "github-actions"
+  directory: "/"
+  schedule:
+    interval: "weekly"
+  open-pull-requests-limit: 5

+ 125 - 55
.github/workflows/ci.yml

@@ -11,15 +11,15 @@ jobs:
 
       matrix:
         profile:
-        - ubuntu-bionic-standard-unity-makefile
+        - ubuntu-bionic-double-standard-unity-makefile
         - ubuntu-bionic-coverage-ninja
-        - macos-eigen-coverage-unity-xcode
+        #- macos-coverage-unity-xcode
         - macos-nometa-standard-makefile
         - windows-standard-unity-msvc
         - windows-nopython-nometa-standard-msvc
 
         include:
-        - profile: ubuntu-bionic-standard-unity-makefile
+        - profile: ubuntu-bionic-double-standard-unity-makefile
           os: ubuntu-20.04
           config: Standard
           unity: YES
@@ -28,6 +28,7 @@ jobs:
           metalibs: YES
           python: YES
           eigen: NO
+          double: YES
 
         - profile: ubuntu-bionic-coverage-ninja
           os: ubuntu-20.04
@@ -38,19 +39,21 @@ jobs:
           metalibs: YES
           python: YES
           eigen: NO
-
-        - profile: macos-eigen-coverage-unity-xcode
-          os: macOS-12
-          config: Coverage
-          unity: YES
-          generator: Xcode
-          compiler: Default
-          metalibs: YES
-          python: YES
-          eigen: YES
+          double: NO
+
+        #- profile: macos-coverage-unity-xcode
+        #  os: macOS-13
+        #  config: Coverage
+        #  unity: YES
+        #  generator: Xcode
+        #  compiler: Default
+        #  metalibs: YES
+        #  python: YES
+        #  eigen: NO
+        #  double: NO
 
         - profile: macos-nometa-standard-makefile
-          os: macOS-12
+          os: macOS-13
           config: Standard
           unity: NO
           generator: Unix Makefiles
@@ -58,6 +61,7 @@ jobs:
           metalibs: NO
           python: YES
           eigen: NO
+          double: NO
 
         - profile: windows-standard-unity-msvc
           os: windows-2022
@@ -68,6 +72,7 @@ jobs:
           metalibs: YES
           python: YES
           eigen: NO
+          double: NO
 
         - profile: windows-nopython-nometa-standard-msvc
           os: windows-2022
@@ -78,11 +83,12 @@ jobs:
           metalibs: NO
           python: NO
           eigen: NO
+          double: NO
 
     runs-on: ${{ matrix.os }}
 
     steps:
-    - uses: actions/checkout@v1
+    - uses: actions/checkout@v4
       with:
         fetch-depth: 10
 
@@ -92,16 +98,20 @@ jobs:
     - name: Install dependencies (macOS)
       if: runner.os == 'macOS'
       run: |
-        curl -O https://www.panda3d.org/download/panda3d-1.10.14/panda3d-1.10.14-tools-mac.tar.gz
-        tar -xf panda3d-1.10.14-tools-mac.tar.gz
-        mv panda3d-1.10.14/thirdparty thirdparty
-        rmdir panda3d-1.10.14
+        curl -O https://www.panda3d.org/download/panda3d-1.10.15/panda3d-1.10.15-tools-mac.tar.gz
+        tar -xf panda3d-1.10.15-tools-mac.tar.gz
+        mv panda3d-1.10.15/thirdparty thirdparty
+        rmdir panda3d-1.10.15
 
         # Temporary hack so that pzip can run, since we are about to remove Cg anyway.
         install_name_tool -id "$(pwd)/thirdparty/darwin-libs-a/nvidiacg/lib/libCg.dylib" thirdparty/darwin-libs-a/nvidiacg/lib/libCg.dylib
 
         brew install ccache
 
+    - name: Set up XCode (macOS)
+      if: runner.os == 'macOS'
+      run: sudo xcode-select -s /Applications/Xcode_14.3.1.app/Contents/Developer
+
     - name: Install dependencies (Ubuntu)
       if: startsWith(matrix.os, 'ubuntu')
       run: >
@@ -117,24 +127,24 @@ jobs:
 
     - name: Cache dependencies (Windows)
       if: runner.os == 'Windows'
-      uses: actions/cache@v1
+      uses: actions/cache@v4
       with:
         path: thirdparty
-        key: ci-cmake-${{ runner.OS }}-thirdparty-v1.10.14-r1
+        key: ci-cmake-${{ runner.OS }}-thirdparty-v1.10.15-r1
     - name: Install dependencies (Windows)
       if: runner.os == 'Windows'
       shell: powershell
       run: |
         if (!(Test-Path thirdparty/win-libs-vc14-x64)) {
           $wc = New-Object System.Net.WebClient
-          $wc.DownloadFile("https://www.panda3d.org/download/panda3d-1.10.14/panda3d-1.10.14-tools-win64.zip", "thirdparty-tools.zip")
+          $wc.DownloadFile("https://www.panda3d.org/download/panda3d-1.10.15/panda3d-1.10.15-tools-win64.zip", "thirdparty-tools.zip")
           Expand-Archive -Path thirdparty-tools.zip
-          Move-Item -Path thirdparty-tools/panda3d-1.10.14/thirdparty -Destination .
+          Move-Item -Path thirdparty-tools/panda3d-1.10.15/thirdparty -Destination .
         }
 
     - name: ccache (non-Windows)
       if: runner.os != 'Windows'
-      uses: actions/cache@v1
+      uses: actions/cache@v4
       with:
         path: ccache
         key: ci-cmake-ccache-${{ matrix.profile }}
@@ -171,6 +181,7 @@ jobs:
         -D BUILD_METALIBS=${{ matrix.metalibs }}
         -D HAVE_PYTHON=${{ runner.os != 'Windows' && matrix.python || 'NO' }}
         -D HAVE_EIGEN=${{ matrix.eigen }}
+        -D STDFLOAT_DOUBLE=${{ matrix.double }}
         ..
 
     - name: Build (no Python)
@@ -182,7 +193,7 @@ jobs:
 
     - name: Setup Python (Python 3.8)
       if: contains(matrix.python, 'YES')
-      uses: actions/setup-python@v4
+      uses: actions/setup-python@v5
       with:
         python-version: '3.8'
     - name: Configure (Python 3.8)
@@ -214,7 +225,7 @@ jobs:
 
     - name: Setup Python (Python 3.9)
       if: contains(matrix.python, 'YES')
-      uses: actions/setup-python@v4
+      uses: actions/setup-python@v5
       with:
         python-version: '3.9'
     - name: Configure (Python 3.9)
@@ -246,7 +257,7 @@ jobs:
 
     - name: Setup Python (Python 3.10)
       if: contains(matrix.python, 'YES')
-      uses: actions/setup-python@v4
+      uses: actions/setup-python@v5
       with:
         python-version: '3.10'
     - name: Configure (Python 3.10)
@@ -278,7 +289,7 @@ jobs:
 
     - name: Setup Python (Python 3.11)
       if: contains(matrix.python, 'YES')
-      uses: actions/setup-python@v4
+      uses: actions/setup-python@v5
       with:
         python-version: '3.11'
     - name: Configure (Python 3.11)
@@ -310,7 +321,7 @@ jobs:
 
     - name: Setup Python (Python 3.12)
       if: contains(matrix.python, 'YES')
-      uses: actions/setup-python@v4
+      uses: actions/setup-python@v5
       with:
         python-version: '3.12'
     - name: Configure (Python 3.12)
@@ -361,10 +372,10 @@ jobs:
     if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '[ci skip]')"
     strategy:
       matrix:
-        os: [ubuntu-20.04, windows-2019, macOS-12]
+        os: [ubuntu-20.04, windows-2019, macOS-13]
     runs-on: ${{ matrix.os }}
     steps:
-    - uses: actions/checkout@v1
+    - uses: actions/checkout@v4
     - name: Install dependencies (Ubuntu)
       if: matrix.os == 'ubuntu-20.04'
       run: |
@@ -375,40 +386,62 @@ jobs:
       shell: powershell
       run: |
         $wc = New-Object System.Net.WebClient
-        $wc.DownloadFile("https://www.panda3d.org/download/panda3d-1.10.14/panda3d-1.10.14-tools-win64.zip", "thirdparty-tools.zip")
+        $wc.DownloadFile("https://www.panda3d.org/download/panda3d-1.10.15/panda3d-1.10.15-tools-win64.zip", "thirdparty-tools.zip")
         Expand-Archive -Path thirdparty-tools.zip
-        Move-Item -Path thirdparty-tools/panda3d-1.10.14/thirdparty -Destination .
+        Move-Item -Path thirdparty-tools/panda3d-1.10.15/thirdparty -Destination .
     - name: Get thirdparty packages (macOS)
       if: runner.os == 'macOS'
       run: |
-        curl -O https://www.panda3d.org/download/panda3d-1.10.14/panda3d-1.10.14-tools-mac.tar.gz
-        tar -xf panda3d-1.10.14-tools-mac.tar.gz
-        mv panda3d-1.10.14/thirdparty thirdparty
-        rmdir panda3d-1.10.14
+        curl -O https://www.panda3d.org/download/panda3d-1.10.15/panda3d-1.10.15-tools-mac.tar.gz
+        tar -xf panda3d-1.10.15-tools-mac.tar.gz
+        mv panda3d-1.10.15/thirdparty thirdparty
+        rmdir panda3d-1.10.15
         (cd thirdparty/darwin-libs-a && rm -rf rocket)
 
+    - name: Set up XCode (macOS)
+      if: runner.os == 'macOS'
+      run: sudo xcode-select -s /Applications/Xcode_14.3.1.app/Contents/Developer
+
+    - name: Set up Python 3.13
+      uses: actions/setup-python@v5
+      with:
+        python-version: '3.13'
+    - name: Build Python 3.13
+      shell: bash
+      run: |
+        python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10 --msvc-version=14.2
+    - name: Test Python 3.13
+      shell: bash
+      run: |
+        python -m pip install -r requirements-test.txt
+        PYTHONPATH=built LD_LIBRARY_PATH=built/lib:$pythonLocation/lib DYLD_LIBRARY_PATH=built/lib python -m pytest
+
     - name: Set up Python 3.12
-      uses: actions/setup-python@v4
+      uses: actions/setup-python@v5
       with:
         python-version: '3.12'
-    - name: Build Python 3.12
+    - name: Build Python 3.12 (double)
       shell: bash
       run: |
-        python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10
-    - name: Test Python 3.12
+        python makepanda/makepanda.py --override STDFLOAT_DOUBLE=1 --git-commit=${{github.sha}} --outputdir=built_dbl --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10 --msvc-version=14.2
+    - name: Test Python 3.12 (double)
       shell: bash
       run: |
         python -m pip install -r requirements-test.txt
-        PYTHONPATH=built LD_LIBRARY_PATH=built/lib:$pythonLocation/lib DYLD_LIBRARY_PATH=built/lib python -m pytest
+        PYTHONPATH=built_dbl LD_LIBRARY_PATH=built_dbl/lib:$pythonLocation/lib DYLD_LIBRARY_PATH=built_dbl/lib python -m pytest
+
+    - name: Make installer
+      run: |
+        python makepanda/makepackage.py --verbose --lzma --outputdir=built_dbl
 
     - name: Set up Python 3.11
-      uses: actions/setup-python@v4
+      uses: actions/setup-python@v5
       with:
         python-version: '3.11'
     - name: Build Python 3.11
       shell: bash
       run: |
-        python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10
+        python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10 --msvc-version=14.2
     - name: Test Python 3.11
       shell: bash
       run: |
@@ -416,13 +449,13 @@ jobs:
         PYTHONPATH=built LD_LIBRARY_PATH=built/lib:$pythonLocation/lib DYLD_LIBRARY_PATH=built/lib python -m pytest
 
     - name: Set up Python 3.10
-      uses: actions/setup-python@v4
+      uses: actions/setup-python@v5
       with:
         python-version: '3.10'
     - name: Build Python 3.10
       shell: bash
       run: |
-        python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10
+        python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10 --msvc-version=14.2
     - name: Test Python 3.10
       shell: bash
       run: |
@@ -430,13 +463,13 @@ jobs:
         PYTHONPATH=built LD_LIBRARY_PATH=built/lib:$pythonLocation/lib DYLD_LIBRARY_PATH=built/lib python -m pytest
 
     - name: Set up Python 3.9
-      uses: actions/setup-python@v4
+      uses: actions/setup-python@v5
       with:
         python-version: '3.9'
     - name: Build Python 3.9
       shell: bash
       run: |
-        python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10
+        python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10 --msvc-version=14.2
     - name: Test Python 3.9
       shell: bash
       run: |
@@ -444,13 +477,13 @@ jobs:
         PYTHONPATH=built LD_LIBRARY_PATH=built/lib:$pythonLocation/lib DYLD_LIBRARY_PATH=built/lib python -m pytest
 
     - name: Set up Python 3.8
-      uses: actions/setup-python@v4
+      uses: actions/setup-python@v5
       with:
         python-version: '3.8'
     - name: Build Python 3.8
       shell: bash
       run: |
-        python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10
+        python makepanda/makepanda.py --git-commit=${{github.sha}} --outputdir=built --everything --no-eigen --python-incdir="$pythonLocation/include" --python-libdir="$pythonLocation/lib" --verbose --threads=4 --windows-sdk=10 --msvc-version=14.2
     - name: Test Python 3.8
       shell: bash
       run: |
@@ -463,22 +496,59 @@ jobs:
 
   emscripten:
     if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '[ci skip]')"
-    runs-on: ubuntu-22.04
+    runs-on: ubuntu-24.04
     steps:
-    - uses: actions/checkout@v1
+    - uses: actions/checkout@v4
 
     - name: Install dependencies
       run: |
         sudo apt-get update
-        sudo apt-get install build-essential ninja-build bison flex
+        sudo apt-get install build-essential ninja-build bison flex nodejs python3-pip
 
     - name: Setup emsdk
       uses: mymindstorm/setup-emsdk@v14
       with:
-        version: 3.1.51
+        version: 3.1.70
         actions-cache-folder: 'emsdk-cache'
 
+    - name: Restore Python build cache
+      id: cache-emscripten-python-restore
+      uses: actions/cache/restore@v4
+      with:
+        path: ~/python
+        key: cache-emscripten-python-3.12.7
+
+    - name: Build Python 3.12
+      if: steps.cache-emscripten-python-restore.outputs.cache-hit != 'true'
+      run: |
+        wget https://www.python.org/ftp/python/3.12.7/Python-3.12.7.tar.xz
+        tar -xJf Python-3.12.7.tar.xz
+        (cd Python-3.12.7 && EM_CONFIG=$EMSDK/.emscripten python3 Tools/wasm/wasm_build.py emscripten-browser)
+        (cd Python-3.12.7/builddir/emscripten-browser && make install DESTDIR=~/python)
+        cp Python-3.12.7/builddir/emscripten-browser/Modules/_hacl/libHacl_Hash_SHA2.a ~/python/usr/local/lib
+        cp Python-3.12.7/builddir/emscripten-browser/Modules/_decimal/libmpdec/libmpdec.a ~/python/usr/local/lib
+        cp Python-3.12.7/builddir/emscripten-browser/Modules/expat/libexpat.a ~/python/usr/local/lib
+        rm -rf Python-3.12.7
+
+    - name: Save Python build cache
+      id: cache-emscripten-python-save
+      if: steps.cache-emscripten-python-restore.outputs.cache-hit != 'true'
+      uses: actions/cache/save@v4
+      with:
+        path: ~/python
+        key: ${{ steps.cache-emscripten-python-restore.outputs.cache-primary-key }}
+
     - name: Build for Emscripten
       shell: bash
       run: |
-        python3 makepanda/makepanda.py --git-commit=${{github.sha}} --target emscripten --outputdir=built --everything --no-python --verbose --threads=4
+        python3 makepanda/makepanda.py --git-commit=${{github.sha}} --target emscripten --python-incdir=~/python/usr/local/include --python-libdir=~/python/usr/local/lib --static --everything --no-pandatool --no-deploytools --verbose --threads=4
+
+    - name: Install test dependencies
+      shell: bash
+      run: |
+        python3 -m pip install -t ~/python/usr/local/lib/python3.12/site-packages -r requirements-test.txt
+
+    - name: Test in node.js
+      shell: bash
+      run: |
+        PYTHONHOME=~/python/usr/local PYTHONPATH=built node built/bin/run_tests.js tests

+ 2 - 2
.github/workflows/mypy.yml

@@ -10,9 +10,9 @@ jobs:
         python-version: ['3.8', '3.11']
       fail-fast: false
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
       - name: Set up Python ${{ matrix.python-version }}
-        uses: actions/setup-python@v4
+        uses: actions/setup-python@v5
         with:
           python-version: ${{ matrix.python-version }}
       - name: Install dependencies

+ 5 - 5
README.md

@@ -24,7 +24,7 @@ Installing Panda3D
 ==================
 
 The latest Panda3D SDK can be downloaded from
-[this page](https://www.panda3d.org/download/sdk-1-10-14/).
+[this page](https://www.panda3d.org/download/sdk-1-10-15/).
 If you are familiar with installing Python packages, you can use
 the following command:
 
@@ -52,7 +52,7 @@ Building Panda3D
 Windows
 -------
 
-You can build Panda3D with the Microsoft Visual C++ 2015, 2017, 2019 or 2022
+You can build Panda3D with the Microsoft Visual C++ 2017, 2019 or 2022
 compiler, which can be downloaded for free from the [Visual Studio site](https://visualstudio.microsoft.com/downloads/).
 You will also need to install the [Windows SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-sdk),
 and if you intend to target Windows Vista, you will also need the
@@ -64,8 +64,8 @@ depending on whether you are on a 32-bit or 64-bit system, or you can
 [click here](https://github.com/rdb/panda3d-thirdparty) for instructions on
 building them from source.
 
-- https://www.panda3d.org/download/panda3d-1.10.14/panda3d-1.10.14-tools-win64.zip
-- https://www.panda3d.org/download/panda3d-1.10.14/panda3d-1.10.14-tools-win32.zip
+- https://www.panda3d.org/download/panda3d-1.10.15/panda3d-1.10.15-tools-win64.zip
+- https://www.panda3d.org/download/panda3d-1.10.15/panda3d-1.10.15-tools-win32.zip
 
 After acquiring these dependencies, you can build Panda3D from the command
 prompt using the following command.  Change the `--msvc-version` option based
@@ -136,7 +136,7 @@ macOS
 -----
 
 On macOS, you will need to download a set of precompiled thirdparty packages in order to
-compile Panda3D, which can be acquired from [here](https://www.panda3d.org/download/panda3d-1.10.14/panda3d-1.10.14-tools-mac.tar.gz).
+compile Panda3D, which can be acquired from [here](https://www.panda3d.org/download/panda3d-1.10.15/panda3d-1.10.15-tools-mac.tar.gz).
 
 After placing the thirdparty directory inside the panda3d source directory,
 you may build Panda3D using a command like the following:

+ 1 - 0
cmake/macros/Python.cmake

@@ -49,6 +49,7 @@ function(add_python_target target)
 
   add_library(${target} ${MODULE_TYPE} ${sources})
   target_link_libraries(${target} PKG::PYTHON)
+  target_include_directories(${target} PRIVATE "${PROJECT_SOURCE_DIR}/dtool/src/interrogatedb")
 
   if(BUILD_SHARED_LIBS)
     set(_outdir "${PANDA_OUTPUT_DIR}/${slash_namespace}")

+ 3 - 2
direct/src/dcparser/dcField_ext.cxx

@@ -278,8 +278,9 @@ get_pystr(PyObject *value) {
     return result;
   }
 
-  if (value->ob_type != nullptr) {
-    PyObject *typestr = PyObject_Str((PyObject *)(value->ob_type));
+  PyTypeObject *type = Py_TYPE(value);
+  if (type != nullptr) {
+    PyObject *typestr = PyObject_Str((PyObject *)type);
     if (typestr != nullptr) {
       std::string result = PyUnicode_AsUTF8(typestr);
       Py_DECREF(typestr);

+ 3 - 0
direct/src/directbase/TestStart.py

@@ -8,6 +8,9 @@ base = ShowBase.ShowBase()
 # Put an axis in the world:
 base.loader.loadModel("models/misc/xyzAxis").reparentTo(base.render)
 
+assert base.camera is not None
+assert base.camLens is not None
+
 base.camera.setPosHpr(0, -10.0, 0, 0, 0, 0)
 base.camLens.setFov(52.0)
 base.camLens.setNearFar(1.0, 10000.0)

+ 3 - 0
direct/src/directbase/ThreeUpStart.py

@@ -10,6 +10,9 @@ base = ThreeUpShow.ThreeUpShow()
 # Put an axis in the world:
 base.loader.loadModel("models/misc/xyzAxis").reparentTo(base.render)
 
+assert base.camera is not None
+assert base.camLens is not None
+
 base.camera.setPosHpr(0, -10.0, 0, 0, 0, 0)
 base.camLens.setFov(52.0)
 base.camLens.setNearFar(1.0, 10000.0)

+ 41 - 5
direct/src/dist/commands.py

@@ -75,6 +75,7 @@ def _model_to_bam(_build_cmd, srcpath, dstpath):
 
     src_fn = p3d.Filename.from_os_specific(srcpath)
     dst_fn = p3d.Filename.from_os_specific(dstpath)
+    dst_fn.set_binary()
 
     _register_python_loaders()
 
@@ -85,8 +86,30 @@ def _model_to_bam(_build_cmd, srcpath, dstpath):
     if not node:
         raise IOError('Failed to load model: %s' % (srcpath))
 
-    if not p3d.NodePath(node).write_bam_file(dst_fn):
-        raise IOError('Failed to write .bam file: %s' % (dstpath))
+    stream = p3d.OFileStream()
+    if not dst_fn.open_write(stream):
+        raise IOError('Failed to open .bam file for writing: %s' % (dstpath))
+
+    # We pass it the source filename here so that texture files are made
+    # relative to the original pathname and don't point from the destination
+    # back into the source directory.
+    dout = p3d.DatagramOutputFile()
+    if not dout.open(stream, src_fn) or not dout.write_header("pbj\0\n\r"):
+        raise IOError('Failed to write to .bam file: %s' % (dstpath))
+
+    writer = p3d.BamWriter(dout)
+    writer.root_node = node
+    writer.init()
+    if _build_cmd.bam_embed_textures:
+        writer.set_file_texture_mode(p3d.BamEnums.BTM_rawdata)
+    else:
+        writer.set_file_texture_mode(p3d.BamEnums.BTM_relative)
+    writer.write_object(node)
+    writer.flush()
+    writer = None
+    dout.close()
+    dout = None
+    stream.close()
 
 
 macosx_binary_magics = (
@@ -289,6 +312,11 @@ class build_apps(setuptools.Command):
             'macosx_10_9_x86_64',
             'win_amd64',
         ]
+
+        if sys.version_info >= (3, 13):
+            # This version of Python is only available for 10.13+.
+            self.platforms[1] = 'macosx_10_13_x86_64'
+
         self.plugins = []
         self.embed_prc_data = True
         self.extra_prc_files = []
@@ -307,6 +335,7 @@ class build_apps(setuptools.Command):
         ]
         self.file_handlers = {}
         self.bam_model_extensions = ['.egg', '.gltf', '.glb']
+        self.bam_embed_textures = False
         self.exclude_dependencies = [
             # Windows
             'kernel32.dll', 'user32.dll', 'wsock32.dll', 'ws2_32.dll',
@@ -321,7 +350,8 @@ class build_apps(setuptools.Command):
 
             # manylinux1/linux
             'libdl.so.*', 'libstdc++.so.*', 'libm.so.*', 'libgcc_s.so.*',
-            'libpthread.so.*', 'libc.so.*', 'ld-linux-x86-64.so.*',
+            'libpthread.so.*', 'libc.so.*',
+            'ld-linux-x86-64.so.*', 'ld-linux-aarch64.so.*',
             'libgl.so.*', 'libx11.so.*', 'libncursesw.so.*', 'libz.so.*',
             'librt.so.*', 'libutil.so.*', 'libnsl.so.1', 'libXext.so.6',
             'libXrender.so.1', 'libICE.so.6', 'libSM.so.6', 'libEGL.so.1',
@@ -646,14 +676,20 @@ class build_apps(setuptools.Command):
             subprocess.check_call([sys.executable, '-m', 'pip'] + pip_args)
         except:
             # Display a more helpful message for these common issues.
-            if platform.startswith('manylinux2010_') and sys.version_info >= (3, 11):
+            if platform.startswith('macosx_10_9_') and sys.version_info >= (3, 13):
+                new_platform = platform.replace('macosx_10_9_', 'macosx_10_13_')
+                self.announce('This error likely occurs because {} is not a supported target as of Python 3.13.\nChange the target platform to {} instead.'.format(platform, new_platform), distutils.log.ERROR)
+            elif platform.startswith('manylinux2010_') and sys.version_info >= (3, 11):
                 new_platform = platform.replace('manylinux2010_', 'manylinux2014_')
                 self.announce('This error likely occurs because {} is not a supported target as of Python 3.11.\nChange the target platform to {} instead.'.format(platform, new_platform), distutils.log.ERROR)
             elif platform.startswith('manylinux1_') and sys.version_info >= (3, 10):
                 new_platform = platform.replace('manylinux1_', 'manylinux2014_')
                 self.announce('This error likely occurs because {} is not a supported target as of Python 3.10.\nChange the target platform to {} instead.'.format(platform, new_platform), distutils.log.ERROR)
             elif platform.startswith('macosx_10_6_') and sys.version_info >= (3, 8):
-                new_platform = platform.replace('macosx_10_6_', 'macosx_10_9_')
+                if sys.version_info >= (3, 13):
+                    new_platform = platform.replace('macosx_10_6_', 'macosx_10_13_')
+                else:
+                    new_platform = platform.replace('macosx_10_6_', 'macosx_10_9_')
                 self.announce('This error likely occurs because {} is not a supported target as of Python 3.8.\nChange the target platform to {} instead.'.format(platform, new_platform), distutils.log.ERROR)
             raise
 

+ 48 - 17
direct/src/filter/CommonFilters.py

@@ -100,6 +100,11 @@ void fshader(out float4 o_color : COLOR,
 """
 
 
+class ToneMap:
+    ACES = object()
+    PBR_NEUTRAL = object()
+
+
 class FilterConfig:
     pass
 
@@ -279,16 +284,19 @@ class CommonFilters:
 
             text = "//Cg\n"
             if "HighDynamicRange" in configuration:
-                text += "static const float3x3 aces_input_mat = {\n"
-                text += "  {0.59719, 0.35458, 0.04823},\n"
-                text += "  {0.07600, 0.90834, 0.01566},\n"
-                text += "  {0.02840, 0.13383, 0.83777},\n"
-                text += "};\n"
-                text += "static const float3x3 aces_output_mat = {\n"
-                text += "  { 1.60475, -0.53108, -0.07367},\n"
-                text += "  {-0.10208,  1.10813, -0.00605},\n"
-                text += "  {-0.00327, -0.07276,  1.07602},\n"
-                text += "};\n"
+                tonemap = configuration["HighDynamicRange"]
+                if tonemap is ToneMap.ACES:
+                    text += "static const float3x3 aces_input_mat = {\n"
+                    text += "  {0.59719, 0.35458, 0.04823},\n"
+                    text += "  {0.07600, 0.90834, 0.01566},\n"
+                    text += "  {0.02840, 0.13383, 0.83777},\n"
+                    text += "};\n"
+                    text += "static const float3x3 aces_output_mat = {\n"
+                    text += "  { 1.60475, -0.53108, -0.07367},\n"
+                    text += "  {-0.10208,  1.10813, -0.00605},\n"
+                    text += "  {-0.00327, -0.07276,  1.07602},\n"
+                    text += "};\n"
+
             text += "void vshader(float4 vtx_position : POSITION,\n"
             text += "  out float4 l_position : POSITION,\n"
 
@@ -381,10 +389,30 @@ class CommonFilters:
             if "ExposureAdjust" in configuration:
                 text += "  o_color.rgb *= k_exposure;\n"
 
-            # With thanks to Stephen Hill!
             if "HighDynamicRange" in configuration:
-                text += "  float3 aces_color = mul(aces_input_mat, o_color.rgb);\n"
-                text += "  o_color.rgb = saturate(mul(aces_output_mat, (aces_color * (aces_color + 0.0245786f) - 0.000090537f) / (aces_color * (0.983729f * aces_color + 0.4329510f) + 0.238081f)));\n"
+                tonemap = configuration["HighDynamicRange"]
+                if tonemap is ToneMap.ACES:
+                    # With thanks to Stephen Hill!
+                    text += "  float3 aces_color = mul(aces_input_mat, o_color.rgb);\n"
+                    text += "  o_color.rgb = saturate(mul(aces_output_mat, (aces_color * (aces_color + 0.0245786f) - 0.000090537f) / (aces_color * (0.983729f * aces_color + 0.4329510f) + 0.238081f)));\n"
+                elif tonemap is ToneMap.PBR_NEUTRAL:
+                    text += "  const float start_compression = 0.8 - 0.04;\n"
+                    text += "  const float desaturation = 0.15;\n"
+
+                    text += "  float x = min(o_color.r, min(o_color.g, o_color.b));\n"
+                    text += "  float offset = x < 0.08 ? x - 6.25 * x * x : 0.04;\n"
+                    text += "  o_color.rgb -= offset;\n"
+
+                    text += "  float peak = max(o_color.r, max(o_color.g, o_color.b));\n"
+
+                    text += "  if (peak >= start_compression) {\n"
+                    text += "    const float d = 1.0 - start_compression;\n"
+                    text += "    float new_peak = 1.0 - d * d / (peak + d - start_compression);\n"
+                    text += "    o_color.rgb *= new_peak / peak;\n"
+                    text += "    float g = 1.0 - 1.0 / (desaturation * (peak - new_peak) + 1.0);\n"
+
+                    text += "    o_color.rgb = lerp(o_color.rgb, new_peak * float3(1, 1, 1), g);\n"
+                    text += "}\n"
 
             if "GammaAdjust" in configuration:
                 gamma = configuration["GammaAdjust"]
@@ -668,10 +696,10 @@ class CommonFilters:
             return self.reconfigure(old_enable, "SrgbEncode")
         return True
 
-    def setHighDynamicRange(self):
+    def setHighDynamicRange(self, tonemap=ToneMap.ACES):
         """ Enables HDR rendering by using a floating-point framebuffer,
         disabling color clamping on the main scene, and applying a tone map
-        operator (ACES).
+        operator (ACES or Khronos PBR Neutral).
 
         It may also be necessary to use setExposureAdjust to perform exposure
         compensation on the scene, depending on the lighting intensity.
@@ -679,8 +707,11 @@ class CommonFilters:
         .. versionadded:: 1.10.7
         """
 
-        fullrebuild = (("HighDynamicRange" in self.configuration) is False)
-        self.configuration["HighDynamicRange"] = 1
+        fullrebuild = "HighDynamicRange" not in self.configuration or \
+                      self.configuration["HighDynamicRange"] is not tonemap
+        if tonemap is not ToneMap.ACES and tonemap is not ToneMap.PBR_NEUTRAL:
+            raise ValueError("Invalid value for tonemap")
+        self.configuration["HighDynamicRange"] = tonemap
         return self.reconfigure(fullrebuild, "HighDynamicRange")
 
     def delHighDynamicRange(self):

+ 2 - 3
direct/src/fsm/FSM.py

@@ -485,9 +485,8 @@ class FSM(DirectObject):
                     new_index = (cur_index + 1) % len(self.stateArray)
                     return self.request(self.stateArray[new_index], args)
             else:
-                assert self.notifier.debug(
+                assert self.notify.debug(
                                     "stateArray empty. Can't switch to next.")
-
         finally:
             self.fsmLock.release()
 
@@ -503,7 +502,7 @@ class FSM(DirectObject):
                     new_index = (cur_index - 1) % len(self.stateArray)
                     return self.request(self.stateArray[new_index], args)
             else:
-                assert self.notifier.debug(
+                assert self.notify.debug(
                                     "stateArray empty. Can't switch to next.")
         finally:
             self.fsmLock.release()

+ 2 - 2
direct/src/interval/cMetaInterval.cxx

@@ -679,7 +679,7 @@ write(std::ostream &out, int indent_level) const {
   int total_digits = num_decimals + 4;
   static const int max_digits = 32;  // totally arbitrary
   nassertv(total_digits <= max_digits);
-  char format_str[16];
+  char format_str[26];
   sprintf(format_str, "%%%d.%df", total_digits, num_decimals);
 
   indent(out, indent_level) << get_name() << ":\n";
@@ -708,7 +708,7 @@ timeline(std::ostream &out) const {
   int total_digits = num_decimals + 4;
   static const int max_digits = 32;  // totally arbitrary
   nassertv(total_digits <= max_digits);
-  char format_str[16];
+  char format_str[26];
   sprintf(format_str, "%%%d.%df", total_digits, num_decimals);
 
   int extra_indent_level = 0;

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

@@ -87,7 +87,8 @@ class DistancePhasedNode(PhasedObject, DirectObject, NodePath):
         """
         Reuse abandoned ids.
         """
-        DistancePhasedNode.__InstanceDeque.append(id)
+        if DistancePhasedNode is not None:
+            DistancePhasedNode.__InstanceDeque.append(id)
 
     def __init__(self, name, phaseParamMap = {},
                  autoCleanup = True,

+ 82 - 74
direct/src/showbase/ShowBase.py

@@ -32,6 +32,8 @@ built-in scope.
 
 """
 
+from __future__ import annotations
+
 __all__ = ['ShowBase', 'WindowControls']
 
 # This module redefines the builtin import function with one
@@ -71,9 +73,11 @@ from panda3d.core import (
     GraphicsPipe,
     GraphicsPipeSelection,
     GraphicsWindow,
+    InputDevice,
     InputDeviceManager,
     InputDeviceNode,
     KeyboardButton,
+    Lens,
     LensNode,
     Mat4,
     ModelNode,
@@ -118,9 +122,11 @@ from . import DConfig
 from direct.extensions_native import NodePath_extensions # pylint: disable=unused-import
 
 # This needs to be available early for DirectGUI imports
+from typing import Any
+builtins: Any  # Tell mypy not to worry about us setting attributes on builtins
 import sys
 import builtins
-builtins.config = DConfig  # type: ignore[attr-defined]
+builtins.config = DConfig
 
 from direct.directnotify.DirectNotifyGlobal import directNotify, giveNotify
 from direct.directnotify.Notifier import Notifier
@@ -141,7 +147,7 @@ import importlib
 from direct.showbase import ExceptionVarDump
 from . import DirectObject
 from . import SfxPlayer
-from typing import ClassVar, Optional
+from typing import Callable, ClassVar, Literal, NoReturn
 if __debug__:
     from direct.showbase import GarbageReport
     from direct.directutil import DeltaProfiler
@@ -150,9 +156,10 @@ if __debug__:
 
 
 @atexit.register
-def exitfunc():
-    if getattr(builtins, 'base', None) is not None:
-        builtins.base.destroy()
+def exitfunc() -> None:
+    base = getattr(builtins, 'base', None)
+    if base is not None:
+        base.destroy()
 
 # Now ShowBase is a DirectObject.  We need this so ShowBase can hang
 # hooks on messages, particularly on window-event.  This doesn't
@@ -170,7 +177,7 @@ class ShowBase(DirectObject.DirectObject):
     aspect2d: NodePath
     pixel2d: NodePath
 
-    def __init__(self, fStartDirect=True, windowType=None):
+    def __init__(self, fStartDirect: bool = True, windowType: str | None = None) -> None:
         """Opens a window, sets up a 3-D and several 2-D scene graphs, and
         everything else needed to render the scene graph to the window.
 
@@ -233,10 +240,10 @@ class ShowBase(DirectObject.DirectObject):
         self.wantRender2dp = ConfigVariableBool('want-render2dp', True).value
 
         self.screenshotExtension = ConfigVariableString('screenshot-extension', 'jpg').value
-        self.musicManager = None
-        self.musicManagerIsValid = None
-        self.sfxManagerList = []
-        self.sfxManagerIsValidList = []
+        self.musicManager: AudioManager | None = None
+        self.musicManagerIsValid: bool | None = None
+        self.sfxManagerList: list[AudioManager] = []
+        self.sfxManagerIsValidList: list[bool] = []
 
         self.wantStats = ConfigVariableBool('want-pstats', False).value
         self.wantTk = False
@@ -245,12 +252,12 @@ class ShowBase(DirectObject.DirectObject):
 
         #: Fill this in with a function to invoke when the user "exits"
         #: the program by closing the main window.
-        self.exitFunc = None
+        self.exitFunc: Callable[[], object] | None = None
 
         #: Add final-exit callbacks to this list.  These will be called
         #: when sys.exit() is called, after Panda has unloaded, and
         #: just before Python is about to shut down.
-        self.finalExitCallbacks = []
+        self.finalExitCallbacks: list[Callable[[], object]] = []
 
         # Set up the TaskManager to reset the PStats clock back
         # whenever we resume from a pause.  This callback function is
@@ -268,7 +275,7 @@ class ShowBase(DirectObject.DirectObject):
         self.__configAspectRatio = ConfigVariableDouble('aspect-ratio', 0).value
         # This variable is used to see if the aspect ratio has changed when
         # we get a window-event.
-        self.__oldAspectRatio = None
+        self.__oldAspectRatio: float | None = None
 
         #: This is set to the value of the window-type config variable, but may
         #: optionally be overridden in the Showbase constructor.  Should either
@@ -279,68 +286,68 @@ class ShowBase(DirectObject.DirectObject):
         self.requireWindow = ConfigVariableBool('require-window', True).value
 
         #: This is the main, or only window; see `winList` for a list of *all* windows.
-        self.win = None
-        self.frameRateMeter = None
-        self.sceneGraphAnalyzerMeter = None
+        self.win: GraphicsOutput | None = None
+        self.frameRateMeter: FrameRateMeter | None = None
+        self.sceneGraphAnalyzerMeter: SceneGraphAnalyzerMeter | None = None
         #: A list of all windows opened via `openWindow()`.
-        self.winList = []
-        self.winControls = []
-        self.mainWinMinimized = 0
-        self.mainWinForeground = 0
+        self.winList: list[GraphicsEngine] = []
+        self.winControls: list[WindowControls] = []
+        self.mainWinMinimized = False
+        self.mainWinForeground = False
         #: Contains the :class:`~panda3d.core.GraphicsPipe` object created by
         #: `makeDefaultPipe()`.
-        self.pipe = None
+        self.pipe: GraphicsPipe | None = None
         #: The full list of :class:`~panda3d.core.GraphicsPipe` objects,
         #: including any auxiliary pipes.  Filled by `makeAllPipes()`.
-        self.pipeList = []
-        self.mouse2cam = None
-        self.buttonThrowers = None
-        self.mouseWatcher = None
+        self.pipeList: list[GraphicsPipe] = []
+        self.mouse2cam: NodePath | None = None
+        self.buttonThrowers: list[ButtonThrower] | None = None
+        self.mouseWatcher: NodePath | None = None
         #: The :class:`~panda3d.core.MouseWatcher` object, created by
         #: `setupMouse()`.
-        self.mouseWatcherNode = None
-        self.pointerWatcherNodes = None
-        self.mouseInterface = None
-        self.drive = None
-        self.trackball = None
-        self.texmem = None
-        self.showVertices = None
-        self.deviceButtonThrowers = []
+        self.mouseWatcherNode: MouseWatcher | None = None
+        self.pointerWatcherNodes: list[MouseWatcher] | None = None
+        self.mouseInterface: NodePath | None = None
+        self.drive: NodePath | None = None
+        self.trackball: NodePath | None = None
+        self.texmem: Any | None = None
+        self.showVertices: NodePath | None = None
+        self.deviceButtonThrowers: list[NodePath] = []
 
         #: This is a :class:`~panda3d.core.NodePath` pointing to the
         #: :class:`~panda3d.core.Camera` object set up for the 3D scene.
         #: Usually a child of `camera`.
-        self.cam = None
+        self.cam: NodePath | None = None
         #: Same as `cam`, but for the 2D scene graph.
-        self.cam2d = None
+        self.cam2d: NodePath | None = None
         #: Same as `cam2d`, but for the 2D overlay scene graph.
-        self.cam2dp = None
+        self.cam2dp: NodePath | None = None
 
         #: This is the :class:`~panda3d.core.NodePath` that should be used to
         #: manipulate the camera.  It points at the node to which the default
         #: camera (`cam`, `camNode`) is attached.
-        self.camera = None
+        self.camera: NodePath | None = None
         #: Same as `camera`, but for the 2D scene graph.  Parent of `cam2d`.
-        self.camera2d = None
+        self.camera2d: NodePath | None = None
         #: Same as `camera2d`, but for the 2D overlay scene graph.  Parent of
         #: `cam2dp`.
-        self.camera2dp = None
+        self.camera2dp: NodePath | None = None
 
         #: A list of all cameras created with `makeCamera()`, including `cam`.
-        self.camList = []
+        self.camList: list[NodePath] = []
         #: Convenience accessor for base.cam.node(), containing a
         #: :class:`~panda3d.core.Camera` object.
-        self.camNode = None
+        self.camNode: Camera | None = None
         #: Convenience accessor for base.camNode.get_lens(), containing a
         #: :class:`~panda3d.core.Lens` object.
-        self.camLens = None
-        self.camFrustumVis = None
+        self.camLens: Lens | None = None
+        self.camFrustumVis: NodePath | None = None
         self.direct = None
         #: This is used to store the wx.Application object used when want-wx is
         #: set or `startWx()` is called.
-        self.wxApp = None
+        self.wxApp: Any | None = None
         self.wxAppCreated = False
-        self.tkRoot = None
+        self.tkRoot: Any | None = None
         self.tkRootCreated = False
 
         # This is used for syncing multiple PCs in a distributed cluster
@@ -371,11 +378,11 @@ class ShowBase(DirectObject.DirectObject):
         #: traverse it automatically in the collisionLoop task, so you won't
         #: need to call :meth:`~panda3d.core.CollisionTraverser.traverse()`
         #: yourself every frame.
-        self.cTrav = 0
-        self.shadowTrav = 0
+        self.cTrav: CollisionTraverser | Literal[0] = 0
+        self.shadowTrav: CollisionTraverser | Literal[0] = 0
         self.cTravStack = Stack()
         # Ditto for an AppTraverser.
-        self.appTrav = 0
+        self.appTrav: Any | Literal[0] = 0
 
         # This is the DataGraph traverser, which we might as well
         # create now.
@@ -383,7 +390,7 @@ class ShowBase(DirectObject.DirectObject):
 
         # Maybe create a RecorderController to record and/or play back
         # the user session.
-        self.recorder = None
+        self.recorder: RecorderController | None = None
         playbackSession = ConfigVariableFilename('playback-session', '')
         recordSession = ConfigVariableFilename('record-session', '')
         if not playbackSession.empty():
@@ -448,22 +455,22 @@ class ShowBase(DirectObject.DirectObject):
         #: If `enableParticles()` has been called, this is the particle manager
         #: as imported from :mod:`direct.particles.ParticleManagerGlobal`.
         self.particleMgr = None
-        self.particleMgrEnabled = 0
+        self.particleMgrEnabled = False
 
         #: If `enableParticles()` has been called, this is the physics manager
         #: as imported from :mod:`direct.showbase.PhysicsManagerGlobal`.
         self.physicsMgr = None
-        self.physicsMgrEnabled = 0
-        self.physicsMgrAngular = 0
+        self.physicsMgrEnabled = False
+        self.physicsMgrAngular = False
 
         #: This is the global :class:`~panda3d.core.InputDeviceManager`, which
         #: keeps track of connected input devices.
         self.devices = InputDeviceManager.getGlobalPtr()
-        self.__inputDeviceNodes = {}
+        self.__inputDeviceNodes: dict[InputDevice, NodePath] = {}
 
         self.createStats()
 
-        self.AppHasAudioFocus = 1
+        self.AppHasAudioFocus = True
 
         # Get a pointer to Panda's global ClockObject, used for
         # synchronizing events between Python and C.
@@ -502,7 +509,7 @@ class ShowBase(DirectObject.DirectObject):
                 affinity = ConfigVariableInt('client-cpu-affinity', -1).value
             if (affinity in (None, -1)) and autoAffinity:
                 affinity = 0
-            if affinity not in (None, -1):
+            if affinity is not None and affinity != -1:
                 # Windows XP supports a 32-bit affinity mask
                 TrueClock.getGlobalPtr().setCpuAffinity(1 << (affinity % 32))
 
@@ -575,7 +582,7 @@ class ShowBase(DirectObject.DirectObject):
         # Now hang a hook on the window-event from Panda.  This allows
         # us to detect when the user resizes, minimizes, or closes the
         # main window.
-        self.__prevWindowProperties = None
+        self.__prevWindowProperties: WindowProperties | None = None
         self.__directObject.accept('window-event', self.windowEvent)
 
         # Transition effects (fade, iris, etc)
@@ -658,7 +665,7 @@ class ShowBase(DirectObject.DirectObject):
             #print getDnaPath()
             print("}")
 
-    def destroy(self):
+    def destroy(self) -> None:
         """ Call this function to destroy the ShowBase and stop all
         its tasks, freeing all of the Panda resources.  Normally, you
         should not need to call it explicitly, as it is bound to the
@@ -704,6 +711,7 @@ class ShowBase(DirectObject.DirectObject):
         self.shutdown()
 
         if getattr(self, 'musicManager', None):
+            assert self.musicManager is not None
             self.musicManager.shutdown()
             self.musicManager = None
             for sfxManager in self.sfxManagerList:
@@ -711,12 +719,12 @@ class ShowBase(DirectObject.DirectObject):
             self.sfxManagerList = []
         if getattr(self, 'loader', None):
             self.loader.destroy()
-            self.loader = None
+            del self.loader
         if getattr(self, 'graphicsEngine', None):
             self.graphicsEngine.removeAllWindows()
 
         try:
-            self.direct.panel.destroy()
+            self.direct.panel.destroy()  # type: ignore[attr-defined]
         except Exception:
             pass
 
@@ -1185,7 +1193,7 @@ class ShowBase(DirectObject.DirectObject):
             self.setSceneGraphAnalyzerMeter(flag.value)
         return success
 
-    def setSleep(self, amount):
+    def setSleep(self, amount: float) -> None:
         """
         Sets up a task that calls python 'sleep' every frame.  This is a simple
         way to reduce the CPU usage (and frame rate) of a panda program.
@@ -1205,7 +1213,7 @@ class ShowBase(DirectObject.DirectObject):
         #time.sleep(self.clientSleep)
         return Task.cont
 
-    def setFrameRateMeter(self, flag):
+    def setFrameRateMeter(self, flag: bool) -> None:
         """
         Turns on or off (according to flag) a standard frame rate
         meter in the upper-right corner of the main window.
@@ -1219,7 +1227,7 @@ class ShowBase(DirectObject.DirectObject):
                 self.frameRateMeter.clearWindow()
                 self.frameRateMeter = None
 
-    def setSceneGraphAnalyzerMeter(self, flag):
+    def setSceneGraphAnalyzerMeter(self, flag: bool) -> None:
         """
         Turns on or off (according to flag) a standard frame rate
         meter in the upper-right corner of the main window.
@@ -1242,7 +1250,7 @@ class ShowBase(DirectObject.DirectObject):
                 mouseKeyboard = self.dataRoot.find("**/*"))
         self.winControls.append(winCtrl)
 
-    def setupRender(self):
+    def setupRender(self) -> None:
         """
         Creates the render scene graph, the primary scene graph for
         rendering 3-d geometry.
@@ -1252,11 +1260,11 @@ class ShowBase(DirectObject.DirectObject):
         self.render.setAttrib(RescaleNormalAttrib.makeDefault())
 
         self.render.setTwoSided(0)
-        self.backfaceCullingEnabled = 1
-        self.textureEnabled = 1
-        self.wireframeEnabled = 0
+        self.backfaceCullingEnabled = True
+        self.textureEnabled = True
+        self.wireframeEnabled = False
 
-    def setupRender2d(self):
+    def setupRender2d(self) -> None:
         """
         Creates the render2d scene graph, the primary scene graph for
         2-d objects and gui elements that are superimposed over the
@@ -1355,7 +1363,7 @@ class ShowBase(DirectObject.DirectObject):
         if xsize > 0 and ysize > 0:
             self.pixel2d.setScale(2.0 / xsize, 1.0, 2.0 / ysize)
 
-    def setupRender2dp(self):
+    def setupRender2dp(self) -> None:
         """
         Creates a render2d scene graph, the secondary scene graph for
         2-d objects and gui elements that are superimposed over the
@@ -1677,7 +1685,7 @@ class ShowBase(DirectObject.DirectObject):
 
         return camera2dp
 
-    def setupDataGraph(self):
+    def setupDataGraph(self) -> None:
         """
         Creates the data graph and populates it with the basic input
         devices.
@@ -2006,7 +2014,7 @@ class ShowBase(DirectObject.DirectObject):
             self.physicsMgr.doPhysics(dt)
         return Task.cont
 
-    def createStats(self, hostname=None, port=None):
+    def createStats(self, hostname: str | None = None, port: int | None = None) -> bool:
         """
         If want-pstats is set in Config.prc, or the `wantStats` member is
         otherwise set to True, connects to the PStats server.
@@ -2323,7 +2331,7 @@ class ShowBase(DirectObject.DirectObject):
         throw_new_frame()
         return Task.cont
 
-    def restart(self, clusterSync=False, cluster=None):
+    def restart(self, clusterSync: bool = False, cluster=None) -> None:
         self.shutdown()
         # __resetPrevTransform goes at the very beginning of the frame.
         self.taskMgr.add(
@@ -2354,7 +2362,7 @@ class ShowBase(DirectObject.DirectObject):
         self.taskMgr.add(self.__audioLoop, 'audioLoop', sort = 60)
         self.eventMgr.restart()
 
-    def shutdown(self):
+    def shutdown(self) -> None:
         self.taskMgr.remove('audioLoop')
         self.taskMgr.remove('igLoop')
         self.taskMgr.remove('shadowCollisionLoop')
@@ -3195,14 +3203,14 @@ class ShowBase(DirectObject.DirectObject):
             # If anybody needs to update their GUI, put a callback on this event
             messenger.send("aspectRatioChanged")
 
-    def userExit(self):
+    def userExit(self) -> NoReturn:
         # The user has requested we exit the program.  Deal with this.
         if self.exitFunc:
             self.exitFunc()
         self.notify.info("Exiting ShowBase.")
         self.finalizeExit()
 
-    def finalizeExit(self):
+    def finalizeExit(self) -> NoReturn:
         """
         Called by `userExit()` to quit the application.  The default
         implementation just calls `sys.exit()`.

+ 1 - 1
direct/src/stdpy/glob.py

@@ -52,7 +52,7 @@ def glob1(dirname, pattern):
     if not dirname:
         dirname = os.curdir
     try:
-        names = os.listdir(dirname)
+        names = file.listdir(dirname)
     except os.error:
         return []
     if pattern[0] != '.':

+ 2 - 2
doc/CODING_STYLE.md

@@ -184,7 +184,7 @@ Try to group logically-similar lines, separating them with a single blank line.
 Modern language features
 ------------------------
 
-Panda3D is a C++11 project.  The use of the following modern language features
+Panda3D is a C++14 project.  The use of the following modern language features
 is greatly encouraged:
 
 1. `nullptr` over `NULL`
@@ -197,4 +197,4 @@ creating a typedef for the container type instead.
 Avoid using `std::function` in cases where a lambda can be accepted directly
 (using a template function), since it has extra overhead over lambdas.
 
-C++14 and C++17 features should be avoided for now.
+C++17 features should be avoided for now.

+ 61 - 0
doc/ReleaseNotes

@@ -1,3 +1,64 @@
+-----------------------  RELEASE 1.10.15  -----------------------
+
+This release adds support for Python 3.13, and fixes some significant bugs.
+Upgrading is highly recommended.
+
+Windowing
+* Fix regression related to fullscreen switching on Windows (#1594)
+* Fix issues related to fullscreen switching corner cases on macOS
+* Fix keyUp event being eaten when switching fullscreen modes on macOS
+* Support UTF-8 window titles on X11
+* Fix wrong error message on X11 if xf86dga extension is not found
+
+Rendering
+* Add "Khronos PBR Neutral" tone mapping operator to HDR filter (#1659)
+* OpenGL: Fix offscreen buffer clearing if back buffers are requested
+* DirectX 9: Fix crash on window event after window close
+* DirectX 9: Fix support for r32f and rgba32f textures
+* DirectX 9: Fix crash when copying inverted framebuffer to texture RAM
+* DirectX 9: Fix buffer crash if main window has no depth buffer
+
+Text
+* Fix handling of surrogate pairs in text on Windows (#1629)
+* Fix disabling text-native-antialias setting not working properly
+* Fix small-caps not working with text-use-harfbuzz enabled (#1666)
+* Show error instead of crash if glyph does not fit in page (#1626)
+* Update docstring for set_text_color() (#1621)
+
+GUI
+* Fix crash when PGEntry removes itself with background focus (#1650)
+* Fix `PGEntry::get_cursor_Y()`, which always returned 0.0 (#1633)
+* Now makes copies of mutable default values in DirectGUI constructor (#1587)
+
+Deployment
+* Fix wrong relative paths with bam_model_extensions (#1642)
+* Add bam_embed_textures option to embed textures in .bam files
+* Don't warn about missing ld-linux library on aarch64 Linux
+* build_apps dist hooks no longer import Panda3D (#1624)
+
+Miscellaneous
+* Fix major memory leak on M1/M2/M3 Macs
+* Fix seeking in OpenAL sounds not working on macOS in some cases (#1607)
+* Fix direct.stdpy.glob not finding files in VFS (#1675)
+* Improve printing of floating-point linmath objects (#1671)
+* Fix VFS mount points not being listed as directories (#1244)
+* Fix splits occurring in RopeNode geometry (#1325)
+* Fix DistancePhasedNode exception at module clean-up time
+* Fix magfilter on KW_mipmap in egg-palettize (#1631)
+* Fix creating LerpFunctionInterval from functools.partial (#1623)
+* Fix "no attribute notifier" in FSM.requestNext/Prev (#1644)
+* Fix file_texture_mode property on BamWriter being read-only
+* TransformState getters no longer return references to temporary (#1625)
+
+Build
+* Assorted build fixes for Python 3.13 and 3.13t
+* Fix assorted compiler warnings
+* Build fix for newer FFmpeg versions
+* Add --ignore option to test_wheel.py to allow ignoring tests
+* Update Eigen to 3.2.10 (fixes binder2nd error when building with C++17)
+* Fix non-determinism in Python bindings (#1651)
+* Fix preprocessor issues in interrogate (#1635)
+
 -----------------------  RELEASE 1.10.14  -----------------------
 
 This release adds support for Python 3.12 and furthermore contains significant

+ 4 - 4
dtool/CompilerFlags.cmake

@@ -51,8 +51,8 @@ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GCC")
 
 endif()
 
-# Panda3D is now a C++11 project.
-set(CMAKE_CXX_STANDARD 11)
+# Panda3D is now a C++14 project.
+set(CMAKE_CXX_STANDARD 14)
 set(CMAKE_CXX_STANDARD_REQUIRED ON)
 
 # Set certain CMake flags we expect
@@ -190,8 +190,8 @@ else()
 
   check_cxx_compiler_flag("-fno-rtti" COMPILER_SUPPORTS_FRTTI)
   if(COMPILER_SUPPORTS_FRTTI)
-    set(cxx_rtti_on "-frtti")
-    set(cxx_rtti_off "-fno-rtti")
+    set(cxx_rtti_on "$<$<OR:$<COMPILE_LANGUAGE:CXX>,$<COMPILE_LANGUAGE:OBJCXX>>:-frtti>")
+    set(cxx_rtti_off "$<$<OR:$<COMPILE_LANGUAGE:CXX>,$<COMPILE_LANGUAGE:OBJCXX>>:-fno-rtti>")
 
   else()
     set(cxx_rtti_on)

+ 1 - 1
dtool/Config.cmake

@@ -265,7 +265,7 @@ if(BUILD_INTERROGATE)
     panda3d-interrogate
 
     GIT_REPOSITORY https://github.com/panda3d/interrogate.git
-    GIT_TAG c343350a6e210029cfe3fd8468e530e1ea6bcead
+    GIT_TAG 03418d6d7ddda7fb99abf27230aa42d1d8bd607e
 
     PREFIX ${_interrogate_dir}
     CMAKE_ARGS

+ 175 - 55
dtool/Package.cmake

@@ -1,9 +1,54 @@
-set(_thirdparty_dir_default "${PROJECT_SOURCE_DIR}/thirdparty")
-if(NOT IS_DIRECTORY "${_thirdparty_dir_default}")
-  set(_thirdparty_dir_default "")
+set(_thirdparty_platform)
+
+if(APPLE)
+  set(_thirdparty_platform "darwin-libs-a")
+
+elseif(WIN32)
+  if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+    set(_thirdparty_platform "win-libs-vc14-x64")
+  else()
+    set(_thirdparty_platform "win-libs-vc14")
+  endif()
+
+elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+  if(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")
+    set(_thirdparty_platform "linux-libs-arm64")
+  elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
+    set(_thirdparty_platform "linux-libs-x64")
+  else()
+    set(_thirdparty_platform "linux-libs-a")
+  endif()
+
+elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
+  if(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")
+    set(_thirdparty_platform "freebsd-libs-arm64")
+  elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
+    set(_thirdparty_platform "freebsd-libs-x64")
+  else()
+    set(_thirdparty_platform "freebsd-libs-a")
+  endif()
+
+elseif(CMAKE_SYSTEM_NAME STREQUAL "Android")
+  set(_thirdparty_platform "android-libs-${CMAKE_ANDROID_ARCH}")
+
+elseif(CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
+  set(_thirdparty_platform "emscripten-libs")
+
+elseif(CMAKE_SYSTEM_NAME STREQUAL "WASI")
+  set(_thirdparty_platform "wasi-libs-${CMAKE_SYSTEM_PROCESSOR}")
+
 endif()
-if(CMAKE_SYSTEM_NAME STREQUAL "WASI")
-  set(_thirdparty_dir_default "")
+
+set(_thirdparty_dir_default "")
+if(_thirdparty_platform)
+  if(IS_DIRECTORY "${PROJECT_SOURCE_DIR}/thirdparty/${_thirdparty_platform}")
+    set(_thirdparty_dir_default "${PROJECT_SOURCE_DIR}/thirdparty")
+
+  else()
+    message(WARNING
+      "Ignoring thirdparty directory without ${_thirdparty_platform} subdirectory.")
+
+  endif()
 endif()
 
 set(THIRDPARTY_DIRECTORY "${_thirdparty_dir_default}" CACHE PATH
@@ -14,6 +59,11 @@ set(THIRDPARTY_DIRECTORY "${_thirdparty_dir_default}" CACHE PATH
 set(THIRDPARTY_DLLS)
 
 if(THIRDPARTY_DIRECTORY)
+  if(NOT _thirdparty_platform)
+    message(FATAL_ERROR
+      "You can't use THIRDPARTY_DIRECTORY on this platform. Unset it to continue.")
+  endif()
+
   # This policy is necessary for PackageName_ROOT variables to be respected
   if(POLICY CMP0074)
     cmake_policy(GET CMP0074 _policy_cmp0074)
@@ -24,63 +74,14 @@ if(THIRDPARTY_DIRECTORY)
       "Your version of CMake is too old; please upgrade or unset THIRDPARTY_DIRECTORY to continue.")
   endif()
 
-  # Dig up the actual "libs" directory
   if(APPLE)
-    set(_package_dir "${THIRDPARTY_DIRECTORY}/darwin-libs-a")
-
     # Make sure thirdparty has the first shot, not system frameworks
     set(CMAKE_FIND_FRAMEWORK LAST)
 
   elseif(WIN32)
-    if(CMAKE_SIZEOF_VOID_P EQUAL 8)
-      set(_package_dir "${THIRDPARTY_DIRECTORY}/win-libs-vc14-x64")
-
-      file(GLOB _python_dirs "${THIRDPARTY_DIRECTORY}/win-python*-x64")
-    else()
-      set(_package_dir "${THIRDPARTY_DIRECTORY}/win-libs-vc14")
-
-      file(GLOB _python_dirs "${THIRDPARTY_DIRECTORY}/win-python*")
-    endif()
-
-    list(REVERSE _python_dirs) # Descending order of version
-    if(NOT DEFINED Python_ROOT)
-      set(Python_ROOT "${_python_dirs}")
-    endif()
-
     set(BISON_ROOT "${THIRDPARTY_DIRECTORY}/win-util")
     set(FLEX_ROOT "${THIRDPARTY_DIRECTORY}/win-util")
 
-  elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
-    if(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")
-      set(_package_dir ${THIRDPARTY_DIRECTORY}/linux-libs-arm64)
-    elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
-      set(_package_dir ${THIRDPARTY_DIRECTORY}/linux-libs-x64)
-    else()
-      set(_package_dir ${THIRDPARTY_DIRECTORY}/linux-libs-a)
-    endif()
-
-  elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
-    if(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")
-      set(_package_dir ${THIRDPARTY_DIRECTORY}/freebsd-libs-arm64)
-    elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
-      set(_package_dir ${THIRDPARTY_DIRECTORY}/freebsd-libs-x64)
-    else()
-      set(_package_dir ${THIRDPARTY_DIRECTORY}/freebsd-libs-a)
-    endif()
-
-  elseif(CMAKE_SYSTEM_NAME STREQUAL "Android")
-    set(_package_dir ${THIRDPARTY_DIRECTORY}/android-libs-${CMAKE_ANDROID_ARCH})
-
-  else()
-    message(FATAL_ERROR
-      "You can't use THIRDPARTY_DIRECTORY on this platform. Unset it to continue.")
-
-  endif()
-
-  if(NOT EXISTS "${_package_dir}")
-    message(FATAL_ERROR
-      "Either your THIRDPARTY_DIRECTORY path does not exist, or it is for the wrong platform.")
-
   endif()
 
   foreach(_Package
@@ -130,7 +131,7 @@ if(THIRDPARTY_DIRECTORY)
     endif()
 
     # Set search path
-    set(${_Package}_ROOT "${_package_dir}/${_package}")
+    set(${_Package}_ROOT "${THIRDPARTY_DIRECTORY}/${_thirdparty_platform}/${_package}")
 
     # Set up copying DLLs, if necessary
     file(GLOB _dlls "${${_Package}_ROOT}/bin/*.dll")
@@ -197,6 +198,27 @@ if(DEFINED _PREV_WANT_PYTHON_VERSION
 
 endif()
 
+# Look for Python in the thirdparty directory on Windows.
+if(WIN32 AND THIRDPARTY_DIRECTORY)
+  set(_python_dir_suffix "")
+  if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+    set(_python_dir_suffix "-x64")
+  endif()
+
+  if(WANT_PYTHON_VERSION)
+    set(Python_ROOT_DIR "${THIRDPARTY_DIRECTORY}/win-python${WANT_PYTHON_VERSION}${_python_dir_suffix}")
+  else()
+    # CMake doesn't support NATURAL sorting until 3.18, so we sort the 3.1x
+    # versions separately from the prior versions.
+    file(GLOB _python_dirs "${THIRDPARTY_DIRECTORY}/win-python3.[0-9][0-9]${_python_dir_suffix}")
+    file(GLOB _python_dirs2 "${THIRDPARTY_DIRECTORY}/win-python3.[0-9]${_python_dir_suffix}")
+    list(SORT _python_dirs COMPARE FILE_BASENAME CASE INSENSITIVE ORDER DESCENDING)
+    list(SORT _python_dirs2 COMPARE FILE_BASENAME CASE INSENSITIVE ORDER DESCENDING)
+    list(APPEND _python_dirs ${_python_dirs2})
+    set(Python_ROOT_DIR "${_python_dirs}")
+  endif()
+endif()
+
 if(WANT_PYTHON_VERSION)
   # A specific version is requested; ensure we get that specific version
   list(APPEND WANT_PYTHON_VERSION "EXACT")
@@ -316,6 +338,104 @@ if(HAVE_PYTHON)
   set(PYTHON_EXTENSION_SUFFIX "${_EXT_SUFFIX}" CACHE STRING
     "Suffix for Python binary extension modules.")
 
+  # Determine the platform to use for .whl files.
+  if(WIN32)
+    if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+      set(_platform "win-amd64")
+    else()
+      set(_platform "win32")
+    endif()
+
+  elseif(APPLE)
+    if(NOT CMAKE_OSX_ARCHITECTURES)
+      set(_arch_tag ${CMAKE_SYSTEM_PROCESSOR})
+
+    elseif("x86_64" IN_LIST CMAKE_OSX_ARCHITECTURES)
+      if("arm64" IN_LIST CMAKE_OSX_ARCHITECTURES)
+        set(_arch_tag "universal2")
+
+      elseif("i386" IN_LIST CMAKE_OSX_ARCHITECTURES AND
+             "ppc64" IN_LIST CMAKE_OSX_ARCHITECTURES AND
+             "ppc" IN_LIST CMAKE_OSX_ARCHITECTURES)
+        set(_arch_tag "universal")
+
+      elseif("i386" IN_LIST CMAKE_OSX_ARCHITECTURES AND
+             "ppc" IN_LIST CMAKE_OSX_ARCHITECTURES)
+        set(_arch_tag "fat32")
+
+      elseif("ppc64" IN_LIST CMAKE_OSX_ARCHITECTURES)
+        set(_arch_tag "fat64")
+
+      elseif("i386" IN_LIST CMAKE_OSX_ARCHITECTURES)
+        set(_arch_tag "intel")
+
+      else()
+        set(_arch_tag "x86_64")
+
+      endif()
+
+    elseif("i386" IN_LIST CMAKE_OSX_ARCHITECTURES AND
+           "ppc" IN_LIST CMAKE_OSX_ARCHITECTURES)
+      set(_arch_tag "fat")
+
+    else()
+      list(GET CMAKE_OSX_ARCHITECTURES 0 _arch_tag)
+
+    endif()
+
+    set(_target "${CMAKE_OSX_DEPLOYMENT_TARGET}")
+
+    if(_arch_tag STREQUAL "arm64" AND _target VERSION_LESS "11.0")
+      set(_target "11.0")
+
+    elseif(PYTHON_VERSION_STRING VERSION_GREATER_EQUAL "3.13" AND _target VERSION_LESS "10.13")
+      set(_target "10.13")
+
+    elseif(PYTHON_VERSION_STRING VERSION_GREATER_EQUAL "3.8" AND _target VERSION_LESS "10.9")
+      set(_target "10.9")
+
+    endif()
+
+    set(_platform "macosx-${_target}-${_arch_tag}")
+
+  elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+    set(_platform "linux-${CMAKE_SYSTEM_PROCESSOR}")
+
+    if(IS_DIRECTORY "/opt/python")
+      # Sloppy detection for manylinux.
+      if(EXISTS "/lib64/libc-2.5.so" OR EXISTS "/lib/libc-2.5.so")
+        set(_platform "manylinux1-${CMAKE_SYSTEM_PROCESSOR}")
+
+      elseif(EXISTS "/lib64/libc-2.12.so" OR EXISTS "/lib/libc-2.12.so")
+        set(_platform "manylinux2010-${CMAKE_SYSTEM_PROCESSOR}")
+
+      elseif(EXISTS "/lib64/libc-2.17.so" OR EXISTS "/lib/libc-2.17.so")
+        set(_platform "manylinux2014-${CMAKE_SYSTEM_PROCESSOR}")
+
+      elseif(EXISTS "/lib/x86_64-linux-gnu/libc-2.24.so" OR EXISTS "/lib/i386-linux-gnu/libc-2.24.so")
+        set(_platform "manylinux_2_24-${CMAKE_SYSTEM_PROCESSOR}")
+
+      elseif(EXISTS "/etc/almalinux-release" AND EXISTS "/lib64/libc-2.28.so")
+        set(_platform "manylinux_2_28-${CMAKE_SYSTEM_PROCESSOR}")
+
+      endif()
+    endif()
+
+  elseif(CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
+    set(_platform "emscripten-${CMAKE_SYSTEM_PROCESSOR}")
+
+  else()
+    set(_platform "")
+
+  endif()
+
+  # This is being read out of the CMake cache by makewheel.py.
+  if(_platform)
+    set(PYTHON_PLATFORM_TAG "${_platform}" CACHE STRING "" FORCE)
+  else()
+    unset(PYTHON_PLATFORM_TAG CACHE)
+  endif()
+
 endif()
 
 if(NOT DEFINED _PREV_PYTHON_VALUES)

+ 0 - 3112
dtool/metalibs/dtoolconfig/pydtool.cxx

@@ -1,3112 +0,0 @@
-/*
- * This file was generated by:
- * interrogate -D EXPCL_DTOOLCONFIG= -nodb -python -promiscuous -I../../../built/include -module panda3d.interrogatedb -library interrogatedb -string -true-names -do-module -oc pydtool.cxx ../../src/interrogatedb/interrogate_interface.h ../../src/interrogatedb/interrogate_request.h
- *
- */
-
-#include <sstream>
-
-#include "../../src/interrogatedb/interrogate_interface.h"
-#include "../../src/interrogatedb/interrogate_request.h"
-#include "dtoolbase.h"
-
-#undef _POSIX_C_SOURCE
-#undef _XOPEN_SOURCE
-#define PY_SSIZE_T_CLEAN 1
-
-#if PYTHON_FRAMEWORK
-  #include <Python/Python.h>
-#else
-  #include "Python.h"
-#endif
-
-static PyObject *_inP07yttbRf(PyObject *self, PyObject *args);
-static PyObject *_inP07ytda_g(PyObject *self, PyObject *args);
-static PyObject *_inP07yt4RgX(PyObject *self, PyObject *args);
-static PyObject *_inP07yt3Gip(PyObject *self, PyObject *args);
-static PyObject *_inP07ytRKDz(PyObject *self, PyObject *args);
-static PyObject *_inP07ytgZ9N(PyObject *self, PyObject *args);
-static PyObject *_inP07ytFnRZ(PyObject *self, PyObject *args);
-static PyObject *_inP07ytg0Qv(PyObject *self, PyObject *args);
-static PyObject *_inP07yttrqw(PyObject *self, PyObject *args);
-static PyObject *_inP07ytdmpW(PyObject *self, PyObject *args);
-static PyObject *_inP07ytUYgQ(PyObject *self, PyObject *args);
-static PyObject *_inP07yt0k7F(PyObject *self, PyObject *args);
-static PyObject *_inP07ytfIsr(PyObject *self, PyObject *args);
-static PyObject *_inP07ytvysR(PyObject *self, PyObject *args);
-static PyObject *_inP07ytYQ_2(PyObject *self, PyObject *args);
-static PyObject *_inP07yt3kdv(PyObject *self, PyObject *args);
-static PyObject *_inP07ytew01(PyObject *self, PyObject *args);
-static PyObject *_inP07ytQna7(PyObject *self, PyObject *args);
-static PyObject *_inP07ytkg95(PyObject *self, PyObject *args);
-static PyObject *_inP07ytluRc(PyObject *self, PyObject *args);
-static PyObject *_inP07yttHdM(PyObject *self, PyObject *args);
-static PyObject *_inP07ytDId0(PyObject *self, PyObject *args);
-static PyObject *_inP07ytHuAm(PyObject *self, PyObject *args);
-static PyObject *_inP07yt_xr0(PyObject *self, PyObject *args);
-static PyObject *_inP07ytH5qp(PyObject *self, PyObject *args);
-static PyObject *_inP07ytLfJw(PyObject *self, PyObject *args);
-static PyObject *_inP07yt_Atg(PyObject *self, PyObject *args);
-static PyObject *_inP07ytlBqc(PyObject *self, PyObject *args);
-static PyObject *_inP07ytNdUp(PyObject *self, PyObject *args);
-static PyObject *_inP07ytlS0p(PyObject *self, PyObject *args);
-static PyObject *_inP07ytZZe7(PyObject *self, PyObject *args);
-static PyObject *_inP07ytV5S_(PyObject *self, PyObject *args);
-static PyObject *_inP07yto9vD(PyObject *self, PyObject *args);
-static PyObject *_inP07ytv7tF(PyObject *self, PyObject *args);
-static PyObject *_inP07ythOg6(PyObject *self, PyObject *args);
-static PyObject *_inP07ytoZUn(PyObject *self, PyObject *args);
-static PyObject *_inP07ytq45U(PyObject *self, PyObject *args);
-static PyObject *_inP07yt6IPa(PyObject *self, PyObject *args);
-static PyObject *_inP07ytU2_B(PyObject *self, PyObject *args);
-static PyObject *_inP07ytHFO2(PyObject *self, PyObject *args);
-static PyObject *_inP07ytcfjm(PyObject *self, PyObject *args);
-static PyObject *_inP07yt3Sjw(PyObject *self, PyObject *args);
-static PyObject *_inP07ytgJcX(PyObject *self, PyObject *args);
-static PyObject *_inP07ytYlw6(PyObject *self, PyObject *args);
-static PyObject *_inP07ytsmnz(PyObject *self, PyObject *args);
-static PyObject *_inP07ytxQ10(PyObject *self, PyObject *args);
-static PyObject *_inP07yt6gPB(PyObject *self, PyObject *args);
-static PyObject *_inP07ytISgV(PyObject *self, PyObject *args);
-static PyObject *_inP07ytH3bx(PyObject *self, PyObject *args);
-static PyObject *_inP07ytzeUk(PyObject *self, PyObject *args);
-static PyObject *_inP07ytUeI5(PyObject *self, PyObject *args);
-static PyObject *_inP07ytbmxJ(PyObject *self, PyObject *args);
-static PyObject *_inP07ytY8Lc(PyObject *self, PyObject *args);
-static PyObject *_inP07ytJAAI(PyObject *self, PyObject *args);
-static PyObject *_inP07yt0UXw(PyObject *self, PyObject *args);
-static PyObject *_inP07ytuSvx(PyObject *self, PyObject *args);
-static PyObject *_inP07ytwpYd(PyObject *self, PyObject *args);
-static PyObject *_inP07ytOfNh(PyObject *self, PyObject *args);
-static PyObject *_inP07ytf5_U(PyObject *self, PyObject *args);
-static PyObject *_inP07ytL3ZB(PyObject *self, PyObject *args);
-static PyObject *_inP07ytXw0I(PyObject *self, PyObject *args);
-static PyObject *_inP07yt3zru(PyObject *self, PyObject *args);
-static PyObject *_inP07ytRrg2(PyObject *self, PyObject *args);
-static PyObject *_inP07ytEJCx(PyObject *self, PyObject *args);
-static PyObject *_inP07ytWAZr(PyObject *self, PyObject *args);
-static PyObject *_inP07ytHQi6(PyObject *self, PyObject *args);
-static PyObject *_inP07ytrD_M(PyObject *self, PyObject *args);
-static PyObject *_inP07ytYaah(PyObject *self, PyObject *args);
-static PyObject *_inP07yt2otr(PyObject *self, PyObject *args);
-static PyObject *_inP07ytNP_b(PyObject *self, PyObject *args);
-static PyObject *_inP07ytrrrN(PyObject *self, PyObject *args);
-static PyObject *_inP07ytjolz(PyObject *self, PyObject *args);
-static PyObject *_inP07ytt_JD(PyObject *self, PyObject *args);
-static PyObject *_inP07ytwEts(PyObject *self, PyObject *args);
-static PyObject *_inP07ytrJWs(PyObject *self, PyObject *args);
-static PyObject *_inP07ytpmFD(PyObject *self, PyObject *args);
-static PyObject *_inP07ytyYUX(PyObject *self, PyObject *args);
-static PyObject *_inP07yt54dn(PyObject *self, PyObject *args);
-static PyObject *_inP07ytGMpW(PyObject *self, PyObject *args);
-static PyObject *_inP07ytNuBV(PyObject *self, PyObject *args);
-static PyObject *_inP07yt9UwA(PyObject *self, PyObject *args);
-static PyObject *_inP07yt3FDt(PyObject *self, PyObject *args);
-static PyObject *_inP07ytDgOY(PyObject *self, PyObject *args);
-static PyObject *_inP07ytf513(PyObject *self, PyObject *args);
-static PyObject *_inP07ytsqGH(PyObject *self, PyObject *args);
-static PyObject *_inP07yt7shV(PyObject *self, PyObject *args);
-static PyObject *_inP07ytA1eF(PyObject *self, PyObject *args);
-static PyObject *_inP07yt776V(PyObject *self, PyObject *args);
-static PyObject *_inP07ytryup(PyObject *self, PyObject *args);
-static PyObject *_inP07ytiytI(PyObject *self, PyObject *args);
-static PyObject *_inP07ytZc07(PyObject *self, PyObject *args);
-static PyObject *_inP07ytfaH0(PyObject *self, PyObject *args);
-static PyObject *_inP07ytGB9D(PyObject *self, PyObject *args);
-static PyObject *_inP07ytrppS(PyObject *self, PyObject *args);
-static PyObject *_inP07ytO50x(PyObject *self, PyObject *args);
-static PyObject *_inP07ytsxxs(PyObject *self, PyObject *args);
-static PyObject *_inP07ytMT0z(PyObject *self, PyObject *args);
-static PyObject *_inP07ytiW3v(PyObject *self, PyObject *args);
-static PyObject *_inP07yt4Px8(PyObject *self, PyObject *args);
-static PyObject *_inP07ytNHcs(PyObject *self, PyObject *args);
-static PyObject *_inP07ytqHrb(PyObject *self, PyObject *args);
-static PyObject *_inP07ytaOqq(PyObject *self, PyObject *args);
-static PyObject *_inP07ytpTBb(PyObject *self, PyObject *args);
-static PyObject *_inP07ytZUkn(PyObject *self, PyObject *args);
-static PyObject *_inP07ytqWOw(PyObject *self, PyObject *args);
-static PyObject *_inP07ytHu7x(PyObject *self, PyObject *args);
-static PyObject *_inP07ytwGnA(PyObject *self, PyObject *args);
-static PyObject *_inP07ytXGxx(PyObject *self, PyObject *args);
-static PyObject *_inP07ytj04Z(PyObject *self, PyObject *args);
-static PyObject *_inP07ytEOv4(PyObject *self, PyObject *args);
-static PyObject *_inP07ytpCqJ(PyObject *self, PyObject *args);
-static PyObject *_inP07yt_Pz3(PyObject *self, PyObject *args);
-static PyObject *_inP07ytt_06(PyObject *self, PyObject *args);
-static PyObject *_inP07ytmuPs(PyObject *self, PyObject *args);
-static PyObject *_inP07ytvM8B(PyObject *self, PyObject *args);
-static PyObject *_inP07ytap97(PyObject *self, PyObject *args);
-static PyObject *_inP07yt0o8D(PyObject *self, PyObject *args);
-static PyObject *_inP07ytOoQ2(PyObject *self, PyObject *args);
-static PyObject *_inP07ytKuFh(PyObject *self, PyObject *args);
-static PyObject *_inP07yto5L6(PyObject *self, PyObject *args);
-static PyObject *_inP07ytzgKK(PyObject *self, PyObject *args);
-static PyObject *_inP07yt0FIF(PyObject *self, PyObject *args);
-static PyObject *_inP07ytZqvD(PyObject *self, PyObject *args);
-static PyObject *_inP07ytDyRd(PyObject *self, PyObject *args);
-static PyObject *_inP07ytMnKa(PyObject *self, PyObject *args);
-static PyObject *_inP07ytRtji(PyObject *self, PyObject *args);
-static PyObject *_inP07ytCnbQ(PyObject *self, PyObject *args);
-static PyObject *_inP07ytoxqc(PyObject *self, PyObject *args);
-static PyObject *_inP07ytZQIS(PyObject *self, PyObject *args);
-static PyObject *_inP07ytdUVN(PyObject *self, PyObject *args);
-static PyObject *_inP07ytZtNk(PyObject *self, PyObject *args);
-static PyObject *_inP07ytihbt(PyObject *self, PyObject *args);
-static PyObject *_inP07ytbyPY(PyObject *self, PyObject *args);
-static PyObject *_inP07ytAaT6(PyObject *self, PyObject *args);
-static PyObject *_inP07ytgL9q(PyObject *self, PyObject *args);
-static PyObject *_inP07ytWB97(PyObject *self, PyObject *args);
-static PyObject *_inP07ytDUAl(PyObject *self, PyObject *args);
-static PyObject *_inP07yt1_Kf(PyObject *self, PyObject *args);
-static PyObject *_inP07yt98lD(PyObject *self, PyObject *args);
-static PyObject *_inP07yt9SHr(PyObject *self, PyObject *args);
-static PyObject *_inP07ytdiZP(PyObject *self, PyObject *args);
-static PyObject *_inP07ytTdER(PyObject *self, PyObject *args);
-static PyObject *_inP07ytYO56(PyObject *self, PyObject *args);
-static PyObject *_inP07ytxtCG(PyObject *self, PyObject *args);
-static PyObject *_inP07yt_EB2(PyObject *self, PyObject *args);
-static PyObject *_inP07ytEG1l(PyObject *self, PyObject *args);
-static PyObject *_inP07yt7tUq(PyObject *self, PyObject *args);
-static PyObject *_inP07ytyStU(PyObject *self, PyObject *args);
-static PyObject *_inP07ytdM85(PyObject *self, PyObject *args);
-static PyObject *_inP07ytk_GN(PyObject *self, PyObject *args);
-static PyObject *_inP07yt8QjG(PyObject *self, PyObject *args);
-static PyObject *_inP07ytyMtj(PyObject *self, PyObject *args);
-static PyObject *_inP07ytHDtN(PyObject *self, PyObject *args);
-static PyObject *_inP07ytHFjA(PyObject *self, PyObject *args);
-static PyObject *_inP07yt_NPR(PyObject *self, PyObject *args);
-static PyObject *_inP07ytcTOH(PyObject *self, PyObject *args);
-static PyObject *_inP07ytC5Uk(PyObject *self, PyObject *args);
-static PyObject *_inP07ythdU7(PyObject *self, PyObject *args);
-static PyObject *_inP07ytQPxU(PyObject *self, PyObject *args);
-static PyObject *_inP07ytO7Pz(PyObject *self, PyObject *args);
-static PyObject *_inP07ytvu_E(PyObject *self, PyObject *args);
-static PyObject *_inP07ytxGUt(PyObject *self, PyObject *args);
-static PyObject *_inP07ytzM1P(PyObject *self, PyObject *args);
-static PyObject *_inP07ytoY5L(PyObject *self, PyObject *args);
-static PyObject *_inP07yte_7S(PyObject *self, PyObject *args);
-static PyObject *_inP07ytw_15(PyObject *self, PyObject *args);
-
-
-/*
- * Python simple wrapper for
- * void interrogate_add_search_directory(char const *dirname)
- */
-static PyObject *
-_inP07yttbRf(PyObject *, PyObject *args) {
-  char *param0;
-  if (PyArg_ParseTuple(args, "s", &param0)) {
-    (::interrogate_add_search_directory)((char const *)param0);
-    return Py_BuildValue("");
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * void interrogate_add_search_path(char const *pathstring)
- */
-static PyObject *
-_inP07ytda_g(PyObject *, PyObject *args) {
-  char *param0;
-  if (PyArg_ParseTuple(args, "s", &param0)) {
-    (::interrogate_add_search_path)((char const *)param0);
-    return Py_BuildValue("");
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_error_flag(void)
- */
-static PyObject *
-_inP07yt4RgX(PyObject *, PyObject *args) {
-  if (PyArg_ParseTuple(args, "")) {
-    bool return_value = (::interrogate_error_flag)();
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * int interrogate_number_of_manifests(void)
- */
-static PyObject *
-_inP07yt3Gip(PyObject *, PyObject *args) {
-  if (PyArg_ParseTuple(args, "")) {
-    int return_value = (::interrogate_number_of_manifests)();
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * ManifestIndex interrogate_get_manifest(int n)
- */
-static PyObject *
-_inP07ytRKDz(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    ManifestIndex return_value = (::interrogate_get_manifest)((int)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * ManifestIndex interrogate_get_manifest_by_name(char const *manifest_name)
- */
-static PyObject *
-_inP07ytgZ9N(PyObject *, PyObject *args) {
-  char *param0;
-  if (PyArg_ParseTuple(args, "s", &param0)) {
-    ManifestIndex return_value = (::interrogate_get_manifest_by_name)((char const *)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * char const *interrogate_manifest_name(ManifestIndex manifest)
- */
-static PyObject *
-_inP07ytFnRZ(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    char const *return_value = (::interrogate_manifest_name)((ManifestIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyUnicode_FromString(return_value);
-#else
-    return PyString_FromString(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * char const *interrogate_manifest_definition(ManifestIndex manifest)
- */
-static PyObject *
-_inP07ytg0Qv(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    char const *return_value = (::interrogate_manifest_definition)((ManifestIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyUnicode_FromString(return_value);
-#else
-    return PyString_FromString(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_manifest_has_type(ManifestIndex manifest)
- */
-static PyObject *
-_inP07yttrqw(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_manifest_has_type)((ManifestIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * TypeIndex interrogate_manifest_get_type(ManifestIndex manifest)
- */
-static PyObject *
-_inP07ytdmpW(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    TypeIndex return_value = (::interrogate_manifest_get_type)((ManifestIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_manifest_has_getter(ManifestIndex manifest)
- */
-static PyObject *
-_inP07ytUYgQ(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_manifest_has_getter)((ManifestIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * FunctionIndex interrogate_manifest_getter(ManifestIndex manifest)
- */
-static PyObject *
-_inP07yt0k7F(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    FunctionIndex return_value = (::interrogate_manifest_getter)((ManifestIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_manifest_has_int_value(ManifestIndex manifest)
- */
-static PyObject *
-_inP07ytfIsr(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_manifest_has_int_value)((ManifestIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * int interrogate_manifest_get_int_value(ManifestIndex manifest)
- */
-static PyObject *
-_inP07ytvysR(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    int return_value = (::interrogate_manifest_get_int_value)((ManifestIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * char const *interrogate_element_name(ElementIndex element)
- */
-static PyObject *
-_inP07ytYQ_2(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    char const *return_value = (::interrogate_element_name)((ElementIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyUnicode_FromString(return_value);
-#else
-    return PyString_FromString(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * char const *interrogate_element_scoped_name(ElementIndex element)
- */
-static PyObject *
-_inP07yt3kdv(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    char const *return_value = (::interrogate_element_scoped_name)((ElementIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyUnicode_FromString(return_value);
-#else
-    return PyString_FromString(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_element_has_comment(ElementIndex element)
- */
-static PyObject *
-_inP07ytew01(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_element_has_comment)((ElementIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * char const *interrogate_element_comment(ElementIndex element)
- */
-static PyObject *
-_inP07ytQna7(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    char const *return_value = (::interrogate_element_comment)((ElementIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyUnicode_FromString(return_value);
-#else
-    return PyString_FromString(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * ElementIndex interrogate_get_element_by_name(char const *element_name)
- */
-static PyObject *
-_inP07ytkg95(PyObject *, PyObject *args) {
-  char *param0;
-  if (PyArg_ParseTuple(args, "s", &param0)) {
-    ElementIndex return_value = (::interrogate_get_element_by_name)((char const *)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * ElementIndex interrogate_get_element_by_scoped_name(char const *element_name)
- */
-static PyObject *
-_inP07ytluRc(PyObject *, PyObject *args) {
-  char *param0;
-  if (PyArg_ParseTuple(args, "s", &param0)) {
-    ElementIndex return_value = (::interrogate_get_element_by_scoped_name)((char const *)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * TypeIndex interrogate_element_type(ElementIndex element)
- */
-static PyObject *
-_inP07yttHdM(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    TypeIndex return_value = (::interrogate_element_type)((ElementIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_element_has_getter(ElementIndex element)
- */
-static PyObject *
-_inP07ytDId0(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_element_has_getter)((ElementIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * FunctionIndex interrogate_element_getter(ElementIndex element)
- */
-static PyObject *
-_inP07ytHuAm(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    FunctionIndex return_value = (::interrogate_element_getter)((ElementIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_element_has_setter(ElementIndex element)
- */
-static PyObject *
-_inP07yt_xr0(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_element_has_setter)((ElementIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * FunctionIndex interrogate_element_setter(ElementIndex element)
- */
-static PyObject *
-_inP07ytH5qp(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    FunctionIndex return_value = (::interrogate_element_setter)((ElementIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_element_has_has_function(ElementIndex element)
- */
-static PyObject *
-_inP07ytLfJw(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_element_has_has_function)((ElementIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * FunctionIndex interrogate_element_has_function(ElementIndex element)
- */
-static PyObject *
-_inP07yt_Atg(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    FunctionIndex return_value = (::interrogate_element_has_function)((ElementIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_element_has_clear_function(ElementIndex element)
- */
-static PyObject *
-_inP07ytlBqc(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_element_has_clear_function)((ElementIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * FunctionIndex interrogate_element_clear_function(ElementIndex element)
- */
-static PyObject *
-_inP07ytNdUp(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    FunctionIndex return_value = (::interrogate_element_clear_function)((ElementIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_element_has_del_function(ElementIndex element)
- */
-static PyObject *
-_inP07ytlS0p(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_element_has_del_function)((ElementIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * FunctionIndex interrogate_element_del_function(ElementIndex element)
- */
-static PyObject *
-_inP07ytZZe7(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    FunctionIndex return_value = (::interrogate_element_del_function)((ElementIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_element_has_insert_function(ElementIndex element)
- */
-static PyObject *
-_inP07ytV5S_(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_element_has_insert_function)((ElementIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * FunctionIndex interrogate_element_insert_function(ElementIndex element)
- */
-static PyObject *
-_inP07yto9vD(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    FunctionIndex return_value = (::interrogate_element_insert_function)((ElementIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_element_has_getkey_function(ElementIndex element)
- */
-static PyObject *
-_inP07ytv7tF(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_element_has_getkey_function)((ElementIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * FunctionIndex interrogate_element_getkey_function(ElementIndex element)
- */
-static PyObject *
-_inP07ythOg6(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    FunctionIndex return_value = (::interrogate_element_getkey_function)((ElementIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * FunctionIndex interrogate_element_length_function(ElementIndex element)
- */
-static PyObject *
-_inP07ytoZUn(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    FunctionIndex return_value = (::interrogate_element_length_function)((ElementIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_element_is_sequence(ElementIndex element)
- */
-static PyObject *
-_inP07ytq45U(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_element_is_sequence)((ElementIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_element_is_mapping(ElementIndex element)
- */
-static PyObject *
-_inP07yt6IPa(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_element_is_mapping)((ElementIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * int interrogate_number_of_globals(void)
- */
-static PyObject *
-_inP07ytU2_B(PyObject *, PyObject *args) {
-  if (PyArg_ParseTuple(args, "")) {
-    int return_value = (::interrogate_number_of_globals)();
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * ElementIndex interrogate_get_global(int n)
- */
-static PyObject *
-_inP07ytHFO2(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    ElementIndex return_value = (::interrogate_get_global)((int)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * int interrogate_number_of_global_functions(void)
- */
-static PyObject *
-_inP07ytcfjm(PyObject *, PyObject *args) {
-  if (PyArg_ParseTuple(args, "")) {
-    int return_value = (::interrogate_number_of_global_functions)();
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * FunctionIndex interrogate_get_global_function(int n)
- */
-static PyObject *
-_inP07yt3Sjw(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    FunctionIndex return_value = (::interrogate_get_global_function)((int)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * int interrogate_number_of_functions(void)
- */
-static PyObject *
-_inP07ytgJcX(PyObject *, PyObject *args) {
-  if (PyArg_ParseTuple(args, "")) {
-    int return_value = (::interrogate_number_of_functions)();
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * FunctionIndex interrogate_get_function(int n)
- */
-static PyObject *
-_inP07ytYlw6(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    FunctionIndex return_value = (::interrogate_get_function)((int)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * char const *interrogate_function_name(FunctionIndex function)
- */
-static PyObject *
-_inP07ytsmnz(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    char const *return_value = (::interrogate_function_name)((FunctionIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyUnicode_FromString(return_value);
-#else
-    return PyString_FromString(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * char const *interrogate_function_scoped_name(FunctionIndex function)
- */
-static PyObject *
-_inP07ytxQ10(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    char const *return_value = (::interrogate_function_scoped_name)((FunctionIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyUnicode_FromString(return_value);
-#else
-    return PyString_FromString(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_function_has_comment(FunctionIndex function)
- */
-static PyObject *
-_inP07yt6gPB(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_function_has_comment)((FunctionIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * char const *interrogate_function_comment(FunctionIndex function)
- */
-static PyObject *
-_inP07ytISgV(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    char const *return_value = (::interrogate_function_comment)((FunctionIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyUnicode_FromString(return_value);
-#else
-    return PyString_FromString(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * char const *interrogate_function_prototype(FunctionIndex function)
- */
-static PyObject *
-_inP07ytH3bx(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    char const *return_value = (::interrogate_function_prototype)((FunctionIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyUnicode_FromString(return_value);
-#else
-    return PyString_FromString(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_function_is_method(FunctionIndex function)
- */
-static PyObject *
-_inP07ytzeUk(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_function_is_method)((FunctionIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * TypeIndex interrogate_function_class(FunctionIndex function)
- */
-static PyObject *
-_inP07ytUeI5(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    TypeIndex return_value = (::interrogate_function_class)((FunctionIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_function_is_unary_op(FunctionIndex function)
- */
-static PyObject *
-_inP07ytbmxJ(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_function_is_unary_op)((FunctionIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_function_is_operator_typecast(FunctionIndex function)
- */
-static PyObject *
-_inP07ytY8Lc(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_function_is_operator_typecast)((FunctionIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_function_is_constructor(FunctionIndex function)
- */
-static PyObject *
-_inP07ytJAAI(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_function_is_constructor)((FunctionIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_function_is_destructor(FunctionIndex function)
- */
-static PyObject *
-_inP07yt0UXw(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_function_is_destructor)((FunctionIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_function_has_module_name(FunctionIndex function)
- */
-static PyObject *
-_inP07ytuSvx(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_function_has_module_name)((FunctionIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * char const *interrogate_function_module_name(FunctionIndex function)
- */
-static PyObject *
-_inP07ytwpYd(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    char const *return_value = (::interrogate_function_module_name)((FunctionIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyUnicode_FromString(return_value);
-#else
-    return PyString_FromString(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_function_has_library_name(FunctionIndex function)
- */
-static PyObject *
-_inP07ytOfNh(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_function_has_library_name)((FunctionIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * char const *interrogate_function_library_name(FunctionIndex function)
- */
-static PyObject *
-_inP07ytf5_U(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    char const *return_value = (::interrogate_function_library_name)((FunctionIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyUnicode_FromString(return_value);
-#else
-    return PyString_FromString(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_function_is_virtual(FunctionIndex function)
- */
-static PyObject *
-_inP07ytL3ZB(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_function_is_virtual)((FunctionIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * int interrogate_function_number_of_c_wrappers(FunctionIndex function)
- */
-static PyObject *
-_inP07ytXw0I(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    int return_value = (::interrogate_function_number_of_c_wrappers)((FunctionIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * FunctionWrapperIndex interrogate_function_c_wrapper(FunctionIndex function, int n)
- */
-static PyObject *
-_inP07yt3zru(PyObject *, PyObject *args) {
-  int param0;
-  int param1;
-  if (PyArg_ParseTuple(args, "ii", &param0, &param1)) {
-    FunctionWrapperIndex return_value = (::interrogate_function_c_wrapper)((FunctionIndex)param0, (int)param1);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * int interrogate_function_number_of_python_wrappers(FunctionIndex function)
- */
-static PyObject *
-_inP07ytRrg2(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    int return_value = (::interrogate_function_number_of_python_wrappers)((FunctionIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * FunctionWrapperIndex interrogate_function_python_wrapper(FunctionIndex function, int n)
- */
-static PyObject *
-_inP07ytEJCx(PyObject *, PyObject *args) {
-  int param0;
-  int param1;
-  if (PyArg_ParseTuple(args, "ii", &param0, &param1)) {
-    FunctionWrapperIndex return_value = (::interrogate_function_python_wrapper)((FunctionIndex)param0, (int)param1);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * char const *interrogate_wrapper_name(FunctionWrapperIndex wrapper)
- */
-static PyObject *
-_inP07ytWAZr(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    char const *return_value = (::interrogate_wrapper_name)((FunctionWrapperIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyUnicode_FromString(return_value);
-#else
-    return PyString_FromString(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * FunctionIndex interrogate_wrapper_function(FunctionWrapperIndex wrapper)
- */
-static PyObject *
-_inP07ytHQi6(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    FunctionIndex return_value = (::interrogate_wrapper_function)((FunctionWrapperIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_wrapper_is_callable_by_name(FunctionWrapperIndex wrapper)
- */
-static PyObject *
-_inP07ytrD_M(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_wrapper_is_callable_by_name)((FunctionWrapperIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_wrapper_is_copy_constructor(FunctionWrapperIndex wrapper)
- */
-static PyObject *
-_inP07ytYaah(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_wrapper_is_copy_constructor)((FunctionWrapperIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_wrapper_is_coerce_constructor(FunctionWrapperIndex wrapper)
- */
-static PyObject *
-_inP07yt2otr(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_wrapper_is_coerce_constructor)((FunctionWrapperIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_wrapper_is_extension(FunctionWrapperIndex wrapper)
- */
-static PyObject *
-_inP07ytNP_b(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_wrapper_is_extension)((FunctionWrapperIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_wrapper_is_deprecated(FunctionWrapperIndex wrapper)
- */
-static PyObject *
-_inP07ytrrrN(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_wrapper_is_deprecated)((FunctionWrapperIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_wrapper_has_comment(FunctionWrapperIndex wrapper)
- */
-static PyObject *
-_inP07ytjolz(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_wrapper_has_comment)((FunctionWrapperIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * char const *interrogate_wrapper_comment(FunctionWrapperIndex wrapper)
- */
-static PyObject *
-_inP07ytt_JD(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    char const *return_value = (::interrogate_wrapper_comment)((FunctionWrapperIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyUnicode_FromString(return_value);
-#else
-    return PyString_FromString(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_wrapper_has_return_value(FunctionWrapperIndex wrapper)
- */
-static PyObject *
-_inP07ytwEts(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_wrapper_has_return_value)((FunctionWrapperIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * TypeIndex interrogate_wrapper_return_type(FunctionWrapperIndex wrapper)
- */
-static PyObject *
-_inP07ytrJWs(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    TypeIndex return_value = (::interrogate_wrapper_return_type)((FunctionWrapperIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_wrapper_caller_manages_return_value(FunctionWrapperIndex wrapper)
- */
-static PyObject *
-_inP07ytpmFD(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_wrapper_caller_manages_return_value)((FunctionWrapperIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * FunctionIndex interrogate_wrapper_return_value_destructor(FunctionWrapperIndex wrapper)
- */
-static PyObject *
-_inP07ytyYUX(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    FunctionIndex return_value = (::interrogate_wrapper_return_value_destructor)((FunctionWrapperIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * int interrogate_wrapper_number_of_parameters(FunctionWrapperIndex wrapper)
- */
-static PyObject *
-_inP07yt54dn(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    int return_value = (::interrogate_wrapper_number_of_parameters)((FunctionWrapperIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * TypeIndex interrogate_wrapper_parameter_type(FunctionWrapperIndex wrapper, int n)
- */
-static PyObject *
-_inP07ytGMpW(PyObject *, PyObject *args) {
-  int param0;
-  int param1;
-  if (PyArg_ParseTuple(args, "ii", &param0, &param1)) {
-    TypeIndex return_value = (::interrogate_wrapper_parameter_type)((FunctionWrapperIndex)param0, (int)param1);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_wrapper_parameter_has_name(FunctionWrapperIndex wrapper, int n)
- */
-static PyObject *
-_inP07ytNuBV(PyObject *, PyObject *args) {
-  int param0;
-  int param1;
-  if (PyArg_ParseTuple(args, "ii", &param0, &param1)) {
-    bool return_value = (::interrogate_wrapper_parameter_has_name)((FunctionWrapperIndex)param0, (int)param1);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * char const *interrogate_wrapper_parameter_name(FunctionWrapperIndex wrapper, int n)
- */
-static PyObject *
-_inP07yt9UwA(PyObject *, PyObject *args) {
-  int param0;
-  int param1;
-  if (PyArg_ParseTuple(args, "ii", &param0, &param1)) {
-    char const *return_value = (::interrogate_wrapper_parameter_name)((FunctionWrapperIndex)param0, (int)param1);
-#if PY_MAJOR_VERSION >= 3
-    return PyUnicode_FromString(return_value);
-#else
-    return PyString_FromString(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_wrapper_parameter_is_this(FunctionWrapperIndex wrapper, int n)
- */
-static PyObject *
-_inP07yt3FDt(PyObject *, PyObject *args) {
-  int param0;
-  int param1;
-  if (PyArg_ParseTuple(args, "ii", &param0, &param1)) {
-    bool return_value = (::interrogate_wrapper_parameter_is_this)((FunctionWrapperIndex)param0, (int)param1);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_wrapper_parameter_is_optional(FunctionWrapperIndex wrapper, int n)
- */
-static PyObject *
-_inP07ytDgOY(PyObject *, PyObject *args) {
-  int param0;
-  int param1;
-  if (PyArg_ParseTuple(args, "ii", &param0, &param1)) {
-    bool return_value = (::interrogate_wrapper_parameter_is_optional)((FunctionWrapperIndex)param0, (int)param1);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_wrapper_has_pointer(FunctionWrapperIndex wrapper)
- */
-static PyObject *
-_inP07ytf513(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_wrapper_has_pointer)((FunctionWrapperIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * void *interrogate_wrapper_pointer(FunctionWrapperIndex wrapper)
- */
-static PyObject *
-_inP07ytsqGH(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    (::interrogate_wrapper_pointer)((FunctionWrapperIndex)param0);
-    return Py_BuildValue("");
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * char const *interrogate_wrapper_unique_name(FunctionWrapperIndex wrapper)
- */
-static PyObject *
-_inP07yt7shV(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    char const *return_value = (::interrogate_wrapper_unique_name)((FunctionWrapperIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyUnicode_FromString(return_value);
-#else
-    return PyString_FromString(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * FunctionWrapperIndex interrogate_get_wrapper_by_unique_name(char const *unique_name)
- */
-static PyObject *
-_inP07ytA1eF(PyObject *, PyObject *args) {
-  char *param0;
-  if (PyArg_ParseTuple(args, "s", &param0)) {
-    FunctionWrapperIndex return_value = (::interrogate_get_wrapper_by_unique_name)((char const *)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * char const *interrogate_make_seq_seq_name(MakeSeqIndex make_seq)
- */
-static PyObject *
-_inP07yt776V(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    char const *return_value = (::interrogate_make_seq_seq_name)((MakeSeqIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyUnicode_FromString(return_value);
-#else
-    return PyString_FromString(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * char const *interrogate_make_seq_scoped_name(MakeSeqIndex make_seq)
- */
-static PyObject *
-_inP07ytryup(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    char const *return_value = (::interrogate_make_seq_scoped_name)((MakeSeqIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyUnicode_FromString(return_value);
-#else
-    return PyString_FromString(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_make_seq_has_comment(ElementIndex element)
- */
-static PyObject *
-_inP07ytiytI(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_make_seq_has_comment)((ElementIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * char const *interrogate_make_seq_comment(ElementIndex element)
- */
-static PyObject *
-_inP07ytZc07(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    char const *return_value = (::interrogate_make_seq_comment)((ElementIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyUnicode_FromString(return_value);
-#else
-    return PyString_FromString(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * char const *interrogate_make_seq_num_name(MakeSeqIndex make_seq)
- */
-static PyObject *
-_inP07ytfaH0(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    char const *return_value = (::interrogate_make_seq_num_name)((MakeSeqIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyUnicode_FromString(return_value);
-#else
-    return PyString_FromString(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * char const *interrogate_make_seq_element_name(MakeSeqIndex make_seq)
- */
-static PyObject *
-_inP07ytGB9D(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    char const *return_value = (::interrogate_make_seq_element_name)((MakeSeqIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyUnicode_FromString(return_value);
-#else
-    return PyString_FromString(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * FunctionIndex interrogate_make_seq_num_getter(MakeSeqIndex make_seq)
- */
-static PyObject *
-_inP07ytrppS(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    FunctionIndex return_value = (::interrogate_make_seq_num_getter)((MakeSeqIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * FunctionIndex interrogate_make_seq_element_getter(MakeSeqIndex make_seq)
- */
-static PyObject *
-_inP07ytO50x(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    FunctionIndex return_value = (::interrogate_make_seq_element_getter)((MakeSeqIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * int interrogate_number_of_global_types(void)
- */
-static PyObject *
-_inP07ytsxxs(PyObject *, PyObject *args) {
-  if (PyArg_ParseTuple(args, "")) {
-    int return_value = (::interrogate_number_of_global_types)();
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * TypeIndex interrogate_get_global_type(int n)
- */
-static PyObject *
-_inP07ytMT0z(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    TypeIndex return_value = (::interrogate_get_global_type)((int)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * int interrogate_number_of_types(void)
- */
-static PyObject *
-_inP07ytiW3v(PyObject *, PyObject *args) {
-  if (PyArg_ParseTuple(args, "")) {
-    int return_value = (::interrogate_number_of_types)();
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * TypeIndex interrogate_get_type(int n)
- */
-static PyObject *
-_inP07yt4Px8(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    TypeIndex return_value = (::interrogate_get_type)((int)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * TypeIndex interrogate_get_type_by_name(char const *type_name)
- */
-static PyObject *
-_inP07ytNHcs(PyObject *, PyObject *args) {
-  char *param0;
-  if (PyArg_ParseTuple(args, "s", &param0)) {
-    TypeIndex return_value = (::interrogate_get_type_by_name)((char const *)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * TypeIndex interrogate_get_type_by_scoped_name(char const *type_name)
- */
-static PyObject *
-_inP07ytqHrb(PyObject *, PyObject *args) {
-  char *param0;
-  if (PyArg_ParseTuple(args, "s", &param0)) {
-    TypeIndex return_value = (::interrogate_get_type_by_scoped_name)((char const *)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * TypeIndex interrogate_get_type_by_true_name(char const *type_name)
- */
-static PyObject *
-_inP07ytaOqq(PyObject *, PyObject *args) {
-  char *param0;
-  if (PyArg_ParseTuple(args, "s", &param0)) {
-    TypeIndex return_value = (::interrogate_get_type_by_true_name)((char const *)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_type_is_global(TypeIndex type)
- */
-static PyObject *
-_inP07ytpTBb(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_type_is_global)((TypeIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_type_is_deprecated(TypeIndex type)
- */
-static PyObject *
-_inP07ytZUkn(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_type_is_deprecated)((TypeIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * char const *interrogate_type_name(TypeIndex type)
- */
-static PyObject *
-_inP07ytqWOw(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    char const *return_value = (::interrogate_type_name)((TypeIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyUnicode_FromString(return_value);
-#else
-    return PyString_FromString(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * char const *interrogate_type_scoped_name(TypeIndex type)
- */
-static PyObject *
-_inP07ytHu7x(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    char const *return_value = (::interrogate_type_scoped_name)((TypeIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyUnicode_FromString(return_value);
-#else
-    return PyString_FromString(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * char const *interrogate_type_true_name(TypeIndex type)
- */
-static PyObject *
-_inP07ytwGnA(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    char const *return_value = (::interrogate_type_true_name)((TypeIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyUnicode_FromString(return_value);
-#else
-    return PyString_FromString(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_type_is_nested(TypeIndex type)
- */
-static PyObject *
-_inP07ytXGxx(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_type_is_nested)((TypeIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * TypeIndex interrogate_type_outer_class(TypeIndex type)
- */
-static PyObject *
-_inP07ytj04Z(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    TypeIndex return_value = (::interrogate_type_outer_class)((TypeIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_type_has_comment(TypeIndex type)
- */
-static PyObject *
-_inP07ytEOv4(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_type_has_comment)((TypeIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * char const *interrogate_type_comment(TypeIndex type)
- */
-static PyObject *
-_inP07ytpCqJ(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    char const *return_value = (::interrogate_type_comment)((TypeIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyUnicode_FromString(return_value);
-#else
-    return PyString_FromString(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_type_has_module_name(TypeIndex type)
- */
-static PyObject *
-_inP07yt_Pz3(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_type_has_module_name)((TypeIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * char const *interrogate_type_module_name(TypeIndex type)
- */
-static PyObject *
-_inP07ytt_06(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    char const *return_value = (::interrogate_type_module_name)((TypeIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyUnicode_FromString(return_value);
-#else
-    return PyString_FromString(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_type_has_library_name(TypeIndex type)
- */
-static PyObject *
-_inP07ytmuPs(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_type_has_library_name)((TypeIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * char const *interrogate_type_library_name(TypeIndex type)
- */
-static PyObject *
-_inP07ytvM8B(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    char const *return_value = (::interrogate_type_library_name)((TypeIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyUnicode_FromString(return_value);
-#else
-    return PyString_FromString(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_type_is_atomic(TypeIndex type)
- */
-static PyObject *
-_inP07ytap97(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_type_is_atomic)((TypeIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * AtomicToken interrogate_type_atomic_token(TypeIndex type)
- */
-static PyObject *
-_inP07yt0o8D(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    AtomicToken return_value = (::interrogate_type_atomic_token)((TypeIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_type_is_unsigned(TypeIndex type)
- */
-static PyObject *
-_inP07ytOoQ2(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_type_is_unsigned)((TypeIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_type_is_signed(TypeIndex type)
- */
-static PyObject *
-_inP07ytKuFh(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_type_is_signed)((TypeIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_type_is_long(TypeIndex type)
- */
-static PyObject *
-_inP07yto5L6(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_type_is_long)((TypeIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_type_is_longlong(TypeIndex type)
- */
-static PyObject *
-_inP07ytzgKK(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_type_is_longlong)((TypeIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_type_is_short(TypeIndex type)
- */
-static PyObject *
-_inP07yt0FIF(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_type_is_short)((TypeIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_type_is_wrapped(TypeIndex type)
- */
-static PyObject *
-_inP07ytZqvD(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_type_is_wrapped)((TypeIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_type_is_pointer(TypeIndex type)
- */
-static PyObject *
-_inP07ytDyRd(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_type_is_pointer)((TypeIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_type_is_const(TypeIndex type)
- */
-static PyObject *
-_inP07ytMnKa(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_type_is_const)((TypeIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_type_is_typedef(TypeIndex type)
- */
-static PyObject *
-_inP07ytRtji(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_type_is_typedef)((TypeIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * TypeIndex interrogate_type_wrapped_type(TypeIndex type)
- */
-static PyObject *
-_inP07ytCnbQ(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    TypeIndex return_value = (::interrogate_type_wrapped_type)((TypeIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_type_is_array(TypeIndex type)
- */
-static PyObject *
-_inP07ytoxqc(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_type_is_array)((TypeIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * int interrogate_type_array_size(TypeIndex type)
- */
-static PyObject *
-_inP07ytZQIS(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    int return_value = (::interrogate_type_array_size)((TypeIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_type_is_enum(TypeIndex type)
- */
-static PyObject *
-_inP07ytdUVN(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_type_is_enum)((TypeIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_type_is_scoped_enum(TypeIndex type)
- */
-static PyObject *
-_inP07ytZtNk(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_type_is_scoped_enum)((TypeIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * int interrogate_type_number_of_enum_values(TypeIndex type)
- */
-static PyObject *
-_inP07ytihbt(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    int return_value = (::interrogate_type_number_of_enum_values)((TypeIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * char const *interrogate_type_enum_value_name(TypeIndex type, int n)
- */
-static PyObject *
-_inP07ytbyPY(PyObject *, PyObject *args) {
-  int param0;
-  int param1;
-  if (PyArg_ParseTuple(args, "ii", &param0, &param1)) {
-    char const *return_value = (::interrogate_type_enum_value_name)((TypeIndex)param0, (int)param1);
-#if PY_MAJOR_VERSION >= 3
-    return PyUnicode_FromString(return_value);
-#else
-    return PyString_FromString(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * char const *interrogate_type_enum_value_scoped_name(TypeIndex type, int n)
- */
-static PyObject *
-_inP07ytAaT6(PyObject *, PyObject *args) {
-  int param0;
-  int param1;
-  if (PyArg_ParseTuple(args, "ii", &param0, &param1)) {
-    char const *return_value = (::interrogate_type_enum_value_scoped_name)((TypeIndex)param0, (int)param1);
-#if PY_MAJOR_VERSION >= 3
-    return PyUnicode_FromString(return_value);
-#else
-    return PyString_FromString(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * char const *interrogate_type_enum_value_comment(TypeIndex type, int n)
- */
-static PyObject *
-_inP07ytgL9q(PyObject *, PyObject *args) {
-  int param0;
-  int param1;
-  if (PyArg_ParseTuple(args, "ii", &param0, &param1)) {
-    char const *return_value = (::interrogate_type_enum_value_comment)((TypeIndex)param0, (int)param1);
-#if PY_MAJOR_VERSION >= 3
-    return PyUnicode_FromString(return_value);
-#else
-    return PyString_FromString(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * int interrogate_type_enum_value(TypeIndex type, int n)
- */
-static PyObject *
-_inP07ytWB97(PyObject *, PyObject *args) {
-  int param0;
-  int param1;
-  if (PyArg_ParseTuple(args, "ii", &param0, &param1)) {
-    int return_value = (::interrogate_type_enum_value)((TypeIndex)param0, (int)param1);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_type_is_struct(TypeIndex type)
- */
-static PyObject *
-_inP07ytDUAl(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_type_is_struct)((TypeIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_type_is_class(TypeIndex type)
- */
-static PyObject *
-_inP07yt1_Kf(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_type_is_class)((TypeIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_type_is_union(TypeIndex type)
- */
-static PyObject *
-_inP07yt98lD(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_type_is_union)((TypeIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_type_is_fully_defined(TypeIndex type)
- */
-static PyObject *
-_inP07yt9SHr(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_type_is_fully_defined)((TypeIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_type_is_unpublished(TypeIndex type)
- */
-static PyObject *
-_inP07ytdiZP(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_type_is_unpublished)((TypeIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * int interrogate_type_number_of_constructors(TypeIndex type)
- */
-static PyObject *
-_inP07ytTdER(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    int return_value = (::interrogate_type_number_of_constructors)((TypeIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * FunctionIndex interrogate_type_get_constructor(TypeIndex type, int n)
- */
-static PyObject *
-_inP07ytYO56(PyObject *, PyObject *args) {
-  int param0;
-  int param1;
-  if (PyArg_ParseTuple(args, "ii", &param0, &param1)) {
-    FunctionIndex return_value = (::interrogate_type_get_constructor)((TypeIndex)param0, (int)param1);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_type_has_destructor(TypeIndex type)
- */
-static PyObject *
-_inP07ytxtCG(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_type_has_destructor)((TypeIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_type_destructor_is_inherited(TypeIndex type)
- */
-static PyObject *
-_inP07yt_EB2(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_type_destructor_is_inherited)((TypeIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * FunctionIndex interrogate_type_get_destructor(TypeIndex type)
- */
-static PyObject *
-_inP07ytEG1l(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    FunctionIndex return_value = (::interrogate_type_get_destructor)((TypeIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * int interrogate_type_number_of_elements(TypeIndex type)
- */
-static PyObject *
-_inP07yt7tUq(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    int return_value = (::interrogate_type_number_of_elements)((TypeIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * ElementIndex interrogate_type_get_element(TypeIndex type, int n)
- */
-static PyObject *
-_inP07ytyStU(PyObject *, PyObject *args) {
-  int param0;
-  int param1;
-  if (PyArg_ParseTuple(args, "ii", &param0, &param1)) {
-    ElementIndex return_value = (::interrogate_type_get_element)((TypeIndex)param0, (int)param1);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * int interrogate_type_number_of_methods(TypeIndex type)
- */
-static PyObject *
-_inP07ytdM85(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    int return_value = (::interrogate_type_number_of_methods)((TypeIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * FunctionIndex interrogate_type_get_method(TypeIndex type, int n)
- */
-static PyObject *
-_inP07ytk_GN(PyObject *, PyObject *args) {
-  int param0;
-  int param1;
-  if (PyArg_ParseTuple(args, "ii", &param0, &param1)) {
-    FunctionIndex return_value = (::interrogate_type_get_method)((TypeIndex)param0, (int)param1);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * int interrogate_type_number_of_make_seqs(TypeIndex type)
- */
-static PyObject *
-_inP07yt8QjG(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    int return_value = (::interrogate_type_number_of_make_seqs)((TypeIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * MakeSeqIndex interrogate_type_get_make_seq(TypeIndex type, int n)
- */
-static PyObject *
-_inP07ytyMtj(PyObject *, PyObject *args) {
-  int param0;
-  int param1;
-  if (PyArg_ParseTuple(args, "ii", &param0, &param1)) {
-    MakeSeqIndex return_value = (::interrogate_type_get_make_seq)((TypeIndex)param0, (int)param1);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * int interrogate_type_number_of_casts(TypeIndex type)
- */
-static PyObject *
-_inP07ytHDtN(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    int return_value = (::interrogate_type_number_of_casts)((TypeIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * FunctionIndex interrogate_type_get_cast(TypeIndex type, int n)
- */
-static PyObject *
-_inP07ytHFjA(PyObject *, PyObject *args) {
-  int param0;
-  int param1;
-  if (PyArg_ParseTuple(args, "ii", &param0, &param1)) {
-    FunctionIndex return_value = (::interrogate_type_get_cast)((TypeIndex)param0, (int)param1);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * int interrogate_type_number_of_derivations(TypeIndex type)
- */
-static PyObject *
-_inP07yt_NPR(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    int return_value = (::interrogate_type_number_of_derivations)((TypeIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * TypeIndex interrogate_type_get_derivation(TypeIndex type, int n)
- */
-static PyObject *
-_inP07ytcTOH(PyObject *, PyObject *args) {
-  int param0;
-  int param1;
-  if (PyArg_ParseTuple(args, "ii", &param0, &param1)) {
-    TypeIndex return_value = (::interrogate_type_get_derivation)((TypeIndex)param0, (int)param1);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_type_is_final(TypeIndex type)
- */
-static PyObject *
-_inP07ytC5Uk(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    bool return_value = (::interrogate_type_is_final)((TypeIndex)param0);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_type_derivation_has_upcast(TypeIndex type, int n)
- */
-static PyObject *
-_inP07ythdU7(PyObject *, PyObject *args) {
-  int param0;
-  int param1;
-  if (PyArg_ParseTuple(args, "ii", &param0, &param1)) {
-    bool return_value = (::interrogate_type_derivation_has_upcast)((TypeIndex)param0, (int)param1);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * FunctionIndex interrogate_type_get_upcast(TypeIndex type, int n)
- */
-static PyObject *
-_inP07ytQPxU(PyObject *, PyObject *args) {
-  int param0;
-  int param1;
-  if (PyArg_ParseTuple(args, "ii", &param0, &param1)) {
-    FunctionIndex return_value = (::interrogate_type_get_upcast)((TypeIndex)param0, (int)param1);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_type_derivation_downcast_is_impossible(TypeIndex type, int n)
- */
-static PyObject *
-_inP07ytO7Pz(PyObject *, PyObject *args) {
-  int param0;
-  int param1;
-  if (PyArg_ParseTuple(args, "ii", &param0, &param1)) {
-    bool return_value = (::interrogate_type_derivation_downcast_is_impossible)((TypeIndex)param0, (int)param1);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * bool interrogate_type_derivation_has_downcast(TypeIndex type, int n)
- */
-static PyObject *
-_inP07ytvu_E(PyObject *, PyObject *args) {
-  int param0;
-  int param1;
-  if (PyArg_ParseTuple(args, "ii", &param0, &param1)) {
-    bool return_value = (::interrogate_type_derivation_has_downcast)((TypeIndex)param0, (int)param1);
-    return PyBool_FromLong(return_value);
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * FunctionIndex interrogate_type_get_downcast(TypeIndex type, int n)
- */
-static PyObject *
-_inP07ytxGUt(PyObject *, PyObject *args) {
-  int param0;
-  int param1;
-  if (PyArg_ParseTuple(args, "ii", &param0, &param1)) {
-    FunctionIndex return_value = (::interrogate_type_get_downcast)((TypeIndex)param0, (int)param1);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * int interrogate_type_number_of_nested_types(TypeIndex type)
- */
-static PyObject *
-_inP07ytzM1P(PyObject *, PyObject *args) {
-  int param0;
-  if (PyArg_ParseTuple(args, "i", &param0)) {
-    int return_value = (::interrogate_type_number_of_nested_types)((TypeIndex)param0);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * TypeIndex interrogate_type_get_nested_type(TypeIndex type, int n)
- */
-static PyObject *
-_inP07ytoY5L(PyObject *, PyObject *args) {
-  int param0;
-  int param1;
-  if (PyArg_ParseTuple(args, "ii", &param0, &param1)) {
-    TypeIndex return_value = (::interrogate_type_get_nested_type)((TypeIndex)param0, (int)param1);
-#if PY_MAJOR_VERSION >= 3
-    return PyLong_FromLong(return_value);
-#else
-    return PyInt_FromLong(return_value);
-#endif
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * void interrogate_request_database(char const *database_filename)
- */
-static PyObject *
-_inP07yte_7S(PyObject *, PyObject *args) {
-  char *param0;
-  if (PyArg_ParseTuple(args, "s", &param0)) {
-    (::interrogate_request_database)((char const *)param0);
-    return Py_BuildValue("");
-  }
-  return nullptr;
-}
-
-/*
- * Python simple wrapper for
- * void interrogate_request_module(InterrogateModuleDef *def)
- */
-static PyObject *
-_inP07ytw_15(PyObject *, PyObject *args) {
-  Py_ssize_t param0;
-  if (PyArg_ParseTuple(args, "n", &param0)) {
-    (::interrogate_request_module)((InterrogateModuleDef *)param0);
-    return Py_BuildValue("");
-  }
-  return nullptr;
-}
-
-
-static PyMethodDef python_simple_funcs[] = {
-  { "interrogate_add_search_directory", &_inP07yttbRf, METH_VARARGS, nullptr },
-  { "interrogate_add_search_path", &_inP07ytda_g, METH_VARARGS, nullptr },
-  { "interrogate_error_flag", &_inP07yt4RgX, METH_VARARGS, nullptr },
-  { "interrogate_number_of_manifests", &_inP07yt3Gip, METH_VARARGS, nullptr },
-  { "interrogate_get_manifest", &_inP07ytRKDz, METH_VARARGS, nullptr },
-  { "interrogate_get_manifest_by_name", &_inP07ytgZ9N, METH_VARARGS, nullptr },
-  { "interrogate_manifest_name", &_inP07ytFnRZ, METH_VARARGS, nullptr },
-  { "interrogate_manifest_definition", &_inP07ytg0Qv, METH_VARARGS, nullptr },
-  { "interrogate_manifest_has_type", &_inP07yttrqw, METH_VARARGS, nullptr },
-  { "interrogate_manifest_get_type", &_inP07ytdmpW, METH_VARARGS, nullptr },
-  { "interrogate_manifest_has_getter", &_inP07ytUYgQ, METH_VARARGS, nullptr },
-  { "interrogate_manifest_getter", &_inP07yt0k7F, METH_VARARGS, nullptr },
-  { "interrogate_manifest_has_int_value", &_inP07ytfIsr, METH_VARARGS, nullptr },
-  { "interrogate_manifest_get_int_value", &_inP07ytvysR, METH_VARARGS, nullptr },
-  { "interrogate_element_name", &_inP07ytYQ_2, METH_VARARGS, nullptr },
-  { "interrogate_element_scoped_name", &_inP07yt3kdv, METH_VARARGS, nullptr },
-  { "interrogate_element_has_comment", &_inP07ytew01, METH_VARARGS, nullptr },
-  { "interrogate_element_comment", &_inP07ytQna7, METH_VARARGS, nullptr },
-  { "interrogate_get_element_by_name", &_inP07ytkg95, METH_VARARGS, nullptr },
-  { "interrogate_get_element_by_scoped_name", &_inP07ytluRc, METH_VARARGS, nullptr },
-  { "interrogate_element_type", &_inP07yttHdM, METH_VARARGS, nullptr },
-  { "interrogate_element_has_getter", &_inP07ytDId0, METH_VARARGS, nullptr },
-  { "interrogate_element_getter", &_inP07ytHuAm, METH_VARARGS, nullptr },
-  { "interrogate_element_has_setter", &_inP07yt_xr0, METH_VARARGS, nullptr },
-  { "interrogate_element_setter", &_inP07ytH5qp, METH_VARARGS, nullptr },
-  { "interrogate_element_has_has_function", &_inP07ytLfJw, METH_VARARGS, nullptr },
-  { "interrogate_element_has_function", &_inP07yt_Atg, METH_VARARGS, nullptr },
-  { "interrogate_element_has_clear_function", &_inP07ytlBqc, METH_VARARGS, nullptr },
-  { "interrogate_element_clear_function", &_inP07ytNdUp, METH_VARARGS, nullptr },
-  { "interrogate_element_has_del_function", &_inP07ytlS0p, METH_VARARGS, nullptr },
-  { "interrogate_element_del_function", &_inP07ytZZe7, METH_VARARGS, nullptr },
-  { "interrogate_element_has_insert_function", &_inP07ytV5S_, METH_VARARGS, nullptr },
-  { "interrogate_element_insert_function", &_inP07yto9vD, METH_VARARGS, nullptr },
-  { "interrogate_element_has_getkey_function", &_inP07ytv7tF, METH_VARARGS, nullptr },
-  { "interrogate_element_getkey_function", &_inP07ythOg6, METH_VARARGS, nullptr },
-  { "interrogate_element_length_function", &_inP07ytoZUn, METH_VARARGS, nullptr },
-  { "interrogate_element_is_sequence", &_inP07ytq45U, METH_VARARGS, nullptr },
-  { "interrogate_element_is_mapping", &_inP07yt6IPa, METH_VARARGS, nullptr },
-  { "interrogate_number_of_globals", &_inP07ytU2_B, METH_VARARGS, nullptr },
-  { "interrogate_get_global", &_inP07ytHFO2, METH_VARARGS, nullptr },
-  { "interrogate_number_of_global_functions", &_inP07ytcfjm, METH_VARARGS, nullptr },
-  { "interrogate_get_global_function", &_inP07yt3Sjw, METH_VARARGS, nullptr },
-  { "interrogate_number_of_functions", &_inP07ytgJcX, METH_VARARGS, nullptr },
-  { "interrogate_get_function", &_inP07ytYlw6, METH_VARARGS, nullptr },
-  { "interrogate_function_name", &_inP07ytsmnz, METH_VARARGS, nullptr },
-  { "interrogate_function_scoped_name", &_inP07ytxQ10, METH_VARARGS, nullptr },
-  { "interrogate_function_has_comment", &_inP07yt6gPB, METH_VARARGS, nullptr },
-  { "interrogate_function_comment", &_inP07ytISgV, METH_VARARGS, nullptr },
-  { "interrogate_function_prototype", &_inP07ytH3bx, METH_VARARGS, nullptr },
-  { "interrogate_function_is_method", &_inP07ytzeUk, METH_VARARGS, nullptr },
-  { "interrogate_function_class", &_inP07ytUeI5, METH_VARARGS, nullptr },
-  { "interrogate_function_is_unary_op", &_inP07ytbmxJ, METH_VARARGS, nullptr },
-  { "interrogate_function_is_operator_typecast", &_inP07ytY8Lc, METH_VARARGS, nullptr },
-  { "interrogate_function_is_constructor", &_inP07ytJAAI, METH_VARARGS, nullptr },
-  { "interrogate_function_is_destructor", &_inP07yt0UXw, METH_VARARGS, nullptr },
-  { "interrogate_function_has_module_name", &_inP07ytuSvx, METH_VARARGS, nullptr },
-  { "interrogate_function_module_name", &_inP07ytwpYd, METH_VARARGS, nullptr },
-  { "interrogate_function_has_library_name", &_inP07ytOfNh, METH_VARARGS, nullptr },
-  { "interrogate_function_library_name", &_inP07ytf5_U, METH_VARARGS, nullptr },
-  { "interrogate_function_is_virtual", &_inP07ytL3ZB, METH_VARARGS, nullptr },
-  { "interrogate_function_number_of_c_wrappers", &_inP07ytXw0I, METH_VARARGS, nullptr },
-  { "interrogate_function_c_wrapper", &_inP07yt3zru, METH_VARARGS, nullptr },
-  { "interrogate_function_number_of_python_wrappers", &_inP07ytRrg2, METH_VARARGS, nullptr },
-  { "interrogate_function_python_wrapper", &_inP07ytEJCx, METH_VARARGS, nullptr },
-  { "interrogate_wrapper_name", &_inP07ytWAZr, METH_VARARGS, nullptr },
-  { "interrogate_wrapper_function", &_inP07ytHQi6, METH_VARARGS, nullptr },
-  { "interrogate_wrapper_is_callable_by_name", &_inP07ytrD_M, METH_VARARGS, nullptr },
-  { "interrogate_wrapper_is_copy_constructor", &_inP07ytYaah, METH_VARARGS, nullptr },
-  { "interrogate_wrapper_is_coerce_constructor", &_inP07yt2otr, METH_VARARGS, nullptr },
-  { "interrogate_wrapper_is_extension", &_inP07ytNP_b, METH_VARARGS, nullptr },
-  { "interrogate_wrapper_is_deprecated", &_inP07ytrrrN, METH_VARARGS, nullptr },
-  { "interrogate_wrapper_has_comment", &_inP07ytjolz, METH_VARARGS, nullptr },
-  { "interrogate_wrapper_comment", &_inP07ytt_JD, METH_VARARGS, nullptr },
-  { "interrogate_wrapper_has_return_value", &_inP07ytwEts, METH_VARARGS, nullptr },
-  { "interrogate_wrapper_return_type", &_inP07ytrJWs, METH_VARARGS, nullptr },
-  { "interrogate_wrapper_caller_manages_return_value", &_inP07ytpmFD, METH_VARARGS, nullptr },
-  { "interrogate_wrapper_return_value_destructor", &_inP07ytyYUX, METH_VARARGS, nullptr },
-  { "interrogate_wrapper_number_of_parameters", &_inP07yt54dn, METH_VARARGS, nullptr },
-  { "interrogate_wrapper_parameter_type", &_inP07ytGMpW, METH_VARARGS, nullptr },
-  { "interrogate_wrapper_parameter_has_name", &_inP07ytNuBV, METH_VARARGS, nullptr },
-  { "interrogate_wrapper_parameter_name", &_inP07yt9UwA, METH_VARARGS, nullptr },
-  { "interrogate_wrapper_parameter_is_this", &_inP07yt3FDt, METH_VARARGS, nullptr },
-  { "interrogate_wrapper_parameter_is_optional", &_inP07ytDgOY, METH_VARARGS, nullptr },
-  { "interrogate_wrapper_has_pointer", &_inP07ytf513, METH_VARARGS, nullptr },
-  { "interrogate_wrapper_pointer", &_inP07ytsqGH, METH_VARARGS, nullptr },
-  { "interrogate_wrapper_unique_name", &_inP07yt7shV, METH_VARARGS, nullptr },
-  { "interrogate_get_wrapper_by_unique_name", &_inP07ytA1eF, METH_VARARGS, nullptr },
-  { "interrogate_make_seq_seq_name", &_inP07yt776V, METH_VARARGS, nullptr },
-  { "interrogate_make_seq_scoped_name", &_inP07ytryup, METH_VARARGS, nullptr },
-  { "interrogate_make_seq_has_comment", &_inP07ytiytI, METH_VARARGS, nullptr },
-  { "interrogate_make_seq_comment", &_inP07ytZc07, METH_VARARGS, nullptr },
-  { "interrogate_make_seq_num_name", &_inP07ytfaH0, METH_VARARGS, nullptr },
-  { "interrogate_make_seq_element_name", &_inP07ytGB9D, METH_VARARGS, nullptr },
-  { "interrogate_make_seq_num_getter", &_inP07ytrppS, METH_VARARGS, nullptr },
-  { "interrogate_make_seq_element_getter", &_inP07ytO50x, METH_VARARGS, nullptr },
-  { "interrogate_number_of_global_types", &_inP07ytsxxs, METH_VARARGS, nullptr },
-  { "interrogate_get_global_type", &_inP07ytMT0z, METH_VARARGS, nullptr },
-  { "interrogate_number_of_types", &_inP07ytiW3v, METH_VARARGS, nullptr },
-  { "interrogate_get_type", &_inP07yt4Px8, METH_VARARGS, nullptr },
-  { "interrogate_get_type_by_name", &_inP07ytNHcs, METH_VARARGS, nullptr },
-  { "interrogate_get_type_by_scoped_name", &_inP07ytqHrb, METH_VARARGS, nullptr },
-  { "interrogate_get_type_by_true_name", &_inP07ytaOqq, METH_VARARGS, nullptr },
-  { "interrogate_type_is_global", &_inP07ytpTBb, METH_VARARGS, nullptr },
-  { "interrogate_type_is_deprecated", &_inP07ytZUkn, METH_VARARGS, nullptr },
-  { "interrogate_type_name", &_inP07ytqWOw, METH_VARARGS, nullptr },
-  { "interrogate_type_scoped_name", &_inP07ytHu7x, METH_VARARGS, nullptr },
-  { "interrogate_type_true_name", &_inP07ytwGnA, METH_VARARGS, nullptr },
-  { "interrogate_type_is_nested", &_inP07ytXGxx, METH_VARARGS, nullptr },
-  { "interrogate_type_outer_class", &_inP07ytj04Z, METH_VARARGS, nullptr },
-  { "interrogate_type_has_comment", &_inP07ytEOv4, METH_VARARGS, nullptr },
-  { "interrogate_type_comment", &_inP07ytpCqJ, METH_VARARGS, nullptr },
-  { "interrogate_type_has_module_name", &_inP07yt_Pz3, METH_VARARGS, nullptr },
-  { "interrogate_type_module_name", &_inP07ytt_06, METH_VARARGS, nullptr },
-  { "interrogate_type_has_library_name", &_inP07ytmuPs, METH_VARARGS, nullptr },
-  { "interrogate_type_library_name", &_inP07ytvM8B, METH_VARARGS, nullptr },
-  { "interrogate_type_is_atomic", &_inP07ytap97, METH_VARARGS, nullptr },
-  { "interrogate_type_atomic_token", &_inP07yt0o8D, METH_VARARGS, nullptr },
-  { "interrogate_type_is_unsigned", &_inP07ytOoQ2, METH_VARARGS, nullptr },
-  { "interrogate_type_is_signed", &_inP07ytKuFh, METH_VARARGS, nullptr },
-  { "interrogate_type_is_long", &_inP07yto5L6, METH_VARARGS, nullptr },
-  { "interrogate_type_is_longlong", &_inP07ytzgKK, METH_VARARGS, nullptr },
-  { "interrogate_type_is_short", &_inP07yt0FIF, METH_VARARGS, nullptr },
-  { "interrogate_type_is_wrapped", &_inP07ytZqvD, METH_VARARGS, nullptr },
-  { "interrogate_type_is_pointer", &_inP07ytDyRd, METH_VARARGS, nullptr },
-  { "interrogate_type_is_const", &_inP07ytMnKa, METH_VARARGS, nullptr },
-  { "interrogate_type_is_typedef", &_inP07ytRtji, METH_VARARGS, nullptr },
-  { "interrogate_type_wrapped_type", &_inP07ytCnbQ, METH_VARARGS, nullptr },
-  { "interrogate_type_is_array", &_inP07ytoxqc, METH_VARARGS, nullptr },
-  { "interrogate_type_array_size", &_inP07ytZQIS, METH_VARARGS, nullptr },
-  { "interrogate_type_is_enum", &_inP07ytdUVN, METH_VARARGS, nullptr },
-  { "interrogate_type_is_scoped_enum", &_inP07ytZtNk, METH_VARARGS, nullptr },
-  { "interrogate_type_number_of_enum_values", &_inP07ytihbt, METH_VARARGS, nullptr },
-  { "interrogate_type_enum_value_name", &_inP07ytbyPY, METH_VARARGS, nullptr },
-  { "interrogate_type_enum_value_scoped_name", &_inP07ytAaT6, METH_VARARGS, nullptr },
-  { "interrogate_type_enum_value_comment", &_inP07ytgL9q, METH_VARARGS, nullptr },
-  { "interrogate_type_enum_value", &_inP07ytWB97, METH_VARARGS, nullptr },
-  { "interrogate_type_is_struct", &_inP07ytDUAl, METH_VARARGS, nullptr },
-  { "interrogate_type_is_class", &_inP07yt1_Kf, METH_VARARGS, nullptr },
-  { "interrogate_type_is_union", &_inP07yt98lD, METH_VARARGS, nullptr },
-  { "interrogate_type_is_fully_defined", &_inP07yt9SHr, METH_VARARGS, nullptr },
-  { "interrogate_type_is_unpublished", &_inP07ytdiZP, METH_VARARGS, nullptr },
-  { "interrogate_type_number_of_constructors", &_inP07ytTdER, METH_VARARGS, nullptr },
-  { "interrogate_type_get_constructor", &_inP07ytYO56, METH_VARARGS, nullptr },
-  { "interrogate_type_has_destructor", &_inP07ytxtCG, METH_VARARGS, nullptr },
-  { "interrogate_type_destructor_is_inherited", &_inP07yt_EB2, METH_VARARGS, nullptr },
-  { "interrogate_type_get_destructor", &_inP07ytEG1l, METH_VARARGS, nullptr },
-  { "interrogate_type_number_of_elements", &_inP07yt7tUq, METH_VARARGS, nullptr },
-  { "interrogate_type_get_element", &_inP07ytyStU, METH_VARARGS, nullptr },
-  { "interrogate_type_number_of_methods", &_inP07ytdM85, METH_VARARGS, nullptr },
-  { "interrogate_type_get_method", &_inP07ytk_GN, METH_VARARGS, nullptr },
-  { "interrogate_type_number_of_make_seqs", &_inP07yt8QjG, METH_VARARGS, nullptr },
-  { "interrogate_type_get_make_seq", &_inP07ytyMtj, METH_VARARGS, nullptr },
-  { "interrogate_type_number_of_casts", &_inP07ytHDtN, METH_VARARGS, nullptr },
-  { "interrogate_type_get_cast", &_inP07ytHFjA, METH_VARARGS, nullptr },
-  { "interrogate_type_number_of_derivations", &_inP07yt_NPR, METH_VARARGS, nullptr },
-  { "interrogate_type_get_derivation", &_inP07ytcTOH, METH_VARARGS, nullptr },
-  { "interrogate_type_is_final", &_inP07ytC5Uk, METH_VARARGS, nullptr },
-  { "interrogate_type_derivation_has_upcast", &_inP07ythdU7, METH_VARARGS, nullptr },
-  { "interrogate_type_get_upcast", &_inP07ytQPxU, METH_VARARGS, nullptr },
-  { "interrogate_type_derivation_downcast_is_impossible", &_inP07ytO7Pz, METH_VARARGS, nullptr },
-  { "interrogate_type_derivation_has_downcast", &_inP07ytvu_E, METH_VARARGS, nullptr },
-  { "interrogate_type_get_downcast", &_inP07ytxGUt, METH_VARARGS, nullptr },
-  { "interrogate_type_number_of_nested_types", &_inP07ytzM1P, METH_VARARGS, nullptr },
-  { "interrogate_type_get_nested_type", &_inP07ytoY5L, METH_VARARGS, nullptr },
-  { "interrogate_request_database", &_inP07yte_7S, METH_VARARGS, nullptr },
-  { "interrogate_request_module", &_inP07ytw_15, METH_VARARGS, nullptr },
-  { nullptr, nullptr, 0, nullptr }
-};
-
-#if PY_MAJOR_VERSION >= 3
-static struct PyModuleDef python_simple_module = {
-  PyModuleDef_HEAD_INIT,
-  "panda3d.interrogatedb",
-  nullptr,
-  -1,
-  python_simple_funcs,
-  nullptr, nullptr, nullptr, nullptr
-};
-
-#define INIT_FUNC PyObject *PyInit_interrogatedb
-#else
-#define INIT_FUNC void initinterrogatedb
-#endif
-
-#ifdef _WIN32
-extern "C" __declspec(dllexport) INIT_FUNC();
-#elif __GNUC__ >= 4
-extern "C" __attribute__((visibility("default"))) INIT_FUNC();
-#else
-extern "C" INIT_FUNC();
-#endif
-
-INIT_FUNC() {
-#if PY_MAJOR_VERSION >= 3
-  return PyModule_Create(&python_simple_module);
-#else
-  Py_InitModule("interrogatedb", python_simple_funcs);
-#endif
-}
-

+ 1 - 0
dtool/src/dtoolbase/CMakeLists.txt

@@ -24,6 +24,7 @@ set(P3DTOOLBASE_HEADERS
   deletedChain.h deletedChain.I
   dtoolbase.h dtoolbase_cc.h dtoolsymbols.h
   dtool_platform.h
+  extension.h
   fakestringstream.h
   indent.I indent.h
   memoryBase.h

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

@@ -110,9 +110,9 @@ typedef std::ios::seekdir ios_seekdir;
 #define INLINE inline
 #endif
 
-// Determine the availability of C++11 features.
-#if defined(_MSC_VER) && _MSC_VER < 1900 // Visual Studio 2015
-#error Microsoft Visual C++ 2015 or later is required to compile Panda3D.
+// Determine the availability of C++14 features.
+#if defined(_MSC_VER) && _MSC_VER < 1910 // Visual Studio 2017
+#error Microsoft Visual C++ 2017 or later is required to compile Panda3D.
 #endif
 
 // This is just to support code generated with older versions of interrogate.

+ 0 - 0
dtool/src/interrogatedb/extension.h → dtool/src/dtoolbase/extension.h


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

@@ -32,6 +32,8 @@ THE SOFTWARE.
 #include <intrin.h>
 #include <float.h>
 #define copysign _copysign
+
+#pragma float_control(precise, on, push)
 #endif
 
 #define UINT64_C2(h, l) ((static_cast<uint64_t>(h) << 32) | static_cast<uint64_t>(l))
@@ -586,3 +588,7 @@ void pftoa(float value, char *buffer) {
     }
   }
 }
+
+#ifdef _MSC_VER
+#pragma float_control(pop)
+#endif

+ 20 - 3
dtool/src/dtoolutil/executionEnvironment.cxx

@@ -72,7 +72,7 @@ extern char **environ;
 // read environment variables at static init time.  In this case, we must read
 // all of the environment variables directly and cache them locally.
 
-#ifndef STATIC_INIT_GETENV
+#if !defined(STATIC_INIT_GETENV) || defined(__EMSCRIPTEN__)
 #define PREREAD_ENVIRONMENT
 #endif
 
@@ -123,6 +123,13 @@ static const char *const libp3dtool_filenames[] = {
 };
 #endif /* !LINK_ALL_STATIC */
 
+#if defined(__EMSCRIPTEN__) && !defined(CPPPARSER)
+extern "C" void EMSCRIPTEN_KEEPALIVE
+_set_env_var(ExecutionEnvironment *ptr, const char *var, const char *value) {
+  ptr->_variables[std::string(var)] = std::string(value);
+}
+#endif
+
 // Linux with GNU libc does have global argvargc variables, but we can't
 // safely access them at stat init time--at least, not in libc5. (It does seem
 // to work with glibc2, however.)
@@ -449,7 +456,7 @@ ns_set_environment_variable(const string &var, const string &value) {
 void ExecutionEnvironment::
 ns_shadow_environment_variable(const string &var, const string &value) {
   _variables[var] = value;
-  string putstr = var + "=" + value;
+  //string putstr = var + "=" + value;
 }
 
 /**
@@ -577,7 +584,17 @@ read_environment_variables() {
     }
   }
 #elif defined(__EMSCRIPTEN__)
-  // Emscripten has no environment vars.  Don't even try.
+  // We only have environment variables if we're running in node.js.
+#ifndef CPPPARSER
+  EM_ASM({
+    if (typeof process === 'object' && typeof process.env === 'object') {
+      for (var variable in process.env) {
+        __set_env_var($0, stringToUTF8OnStack(variable),
+                          stringToUTF8OnStack(process.env[variable]));
+      }
+    }
+  }, this);
+#endif
 
 #elif defined(HAVE_PROC_SELF_ENVIRON)
   // In some cases, we may have a file called procselfenviron that may be read

+ 11 - 0
dtool/src/dtoolutil/executionEnvironment.h

@@ -21,6 +21,13 @@
 
 #include <map>
 
+#if defined(__EMSCRIPTEN__) && !defined(CPPPARSER)
+class ExecutionEnvironment;
+
+extern "C" void EMSCRIPTEN_KEEPALIVE
+_set_env_var(ExecutionEnvironment *ptr, const char *var, const char *value);
+#endif
+
 /**
  * Encapsulates access to the environment variables and command-line arguments
  * at the time of execution.  This is encapsulated to support accessing these
@@ -89,6 +96,10 @@ private:
   std::string _dtool_name;
 
   static ExecutionEnvironment *_global_ptr;
+
+#ifdef __EMSCRIPTEN__
+  friend void ::_set_env_var(ExecutionEnvironment *ptr, const char *var, const char *value);
+#endif
 };
 
 #include "executionEnvironment.I"

+ 23 - 9
dtool/src/dtoolutil/filename_ext.cxx

@@ -33,10 +33,17 @@ __init__(PyObject *path) {
   Py_ssize_t length;
 
   if (PyUnicode_CheckExact(path)) {
-    wchar_t *data;
-    data = PyUnicode_AsWideCharString(path, &length);
-    (*_this) = wstring(data, length);
-    PyMem_Free(data);
+    if (Filename::get_filesystem_encoding() == TextEncoder::E_utf8) {
+      const char *data = PyUnicode_AsUTF8AndSize(path, &length);
+      if (data != nullptr) {
+        (*_this) = string(data, length);
+      }
+    } else {
+      wchar_t *data;
+      data = PyUnicode_AsWideCharString(path, &length);
+      (*_this) = wstring(data, length);
+      PyMem_Free(data);
+    }
     return;
   }
 
@@ -47,7 +54,7 @@ __init__(PyObject *path) {
     return;
   }
 
-  if (Py_TYPE(path) == &Dtool_Filename._PyType) {
+  if (Py_IS_TYPE(path, Dtool_GetPyTypeObject(&Dtool_Filename))) {
     // Copy constructor.
     *_this = *(Filename *)DtoolInstance_VOID_PTR(path);
     return;
@@ -67,10 +74,17 @@ __init__(PyObject *path) {
   }
 
   if (PyUnicode_CheckExact(path_str)) {
-    wchar_t *data;
-    data = PyUnicode_AsWideCharString(path_str, &length);
-    (*_this) = Filename::from_os_specific_w(wstring(data, length));
-    PyMem_Free(data);
+    if (Filename::get_filesystem_encoding() == TextEncoder::E_utf8) {
+      const char *data = PyUnicode_AsUTF8AndSize(path_str, &length);
+      if (data != nullptr) {
+        (*_this) = Filename::from_os_specific(string(data, length));
+      }
+    } else {
+      wchar_t *data;
+      data = PyUnicode_AsWideCharString(path_str, &length);
+      (*_this) = Filename::from_os_specific_w(wstring(data, length));
+      PyMem_Free(data);
+    }
 
   } else if (PyBytes_CheckExact(path_str)) {
     char *data;

+ 4 - 72
dtool/src/interrogatedb/CMakeLists.txt

@@ -1,76 +1,8 @@
-set(P3INTERROGATEDB_HEADERS
-  config_interrogatedb.h indexRemapper.h interrogateComponent.I
-  interrogateComponent.h interrogateDatabase.I
-  interrogateDatabase.h interrogateElement.I
-  interrogateElement.h interrogateFunction.I
-  interrogateFunction.h interrogateFunctionWrapper.I
-  interrogateFunctionWrapper.h
-  interrogateMakeSeq.I interrogateMakeSeq.h
-  interrogateManifest.I interrogateManifest.h
-  interrogateType.I interrogateType.h
-  interrogate_datafile.I interrogate_datafile.h
-  interrogate_interface.h interrogate_request.h
-)
-
-set(P3INTERROGATEDB_SOURCES
-  config_interrogatedb.cxx
-  indexRemapper.cxx
-  interrogateComponent.cxx interrogateDatabase.cxx
-  interrogateElement.cxx interrogateFunction.cxx
-  interrogateFunctionWrapper.cxx
-  interrogateMakeSeq.cxx
-  interrogateManifest.cxx
-  interrogateType.cxx interrogate_datafile.cxx
-  interrogate_interface.cxx interrogate_request.cxx
-)
-
-set(P3INTERROGATEDB_IGATE
-  interrogate_interface.h
-  interrogate_request.h
-)
-
 set(P3IGATERUNTIME_HEADERS
-  extension.h py_compat.h py_panda.h py_panda.I py_wrappers.h
+  interrogate_request.h
+  py_compat.h
+  py_panda.h py_panda.I
+  py_wrappers.h
 )
 
-composite_sources(p3interrogatedb P3INTERROGATEDB_SOURCES)
-add_library(p3interrogatedb
-  ${P3INTERROGATEDB_HEADERS} ${P3INTERROGATEDB_SOURCES})
-set_target_properties(p3interrogatedb PROPERTIES DEFINE_SYMBOL BUILDING_INTERROGATEDB)
-target_link_libraries(p3interrogatedb p3dconfig p3prc)
-
-install(TARGETS p3interrogatedb
-  EXPORT Core COMPONENT Core
-  DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-  INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
-  ARCHIVE COMPONENT CoreDevel)
-install(FILES ${P3INTERROGATEDB_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
 install(FILES ${P3IGATERUNTIME_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
-
-# ALSO: This has an Interrogate binding! Take care of that if we want it.
-# Note we don't use the regular Interrogate macros; this has some custom flags
-# that would make it not worthwhile.
-
-if(NOT INTERROGATE_PYTHON_INTERFACE)
-  return()
-endif()
-
-add_custom_command(
-  OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/interrogatedb_module.cxx"
-  COMMAND interrogate
-    -D EXPCL_INTERROGATEDB=
-    -nodb -python -promiscuous
-    -module panda3d.interrogatedb
-    -library interrogatedb
-    -string -true-names -do-module
-    -srcdir "${CMAKE_CURRENT_SOURCE_DIR}"
-    -oc "${CMAKE_CURRENT_BINARY_DIR}/interrogatedb_module.cxx"
-    ${P3INTERROGATEDB_IGATE}
-
-  DEPENDS interrogate ${P3INTERROGATEDB_IGATE}
-  COMMENT "Interrogating interrogatedb")
-
-add_python_target(panda3d.interrogatedb
-  "${CMAKE_CURRENT_BINARY_DIR}/interrogatedb_module.cxx")
-target_link_libraries(panda3d.interrogatedb p3interrogatedb)

+ 0 - 66
dtool/src/interrogatedb/config_interrogatedb.cxx

@@ -1,66 +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_interrogatedb.cxx
- * @author drose
- * @date 2000-08-01
- */
-
-#include "config_interrogatedb.h"
-#include "interrogate_request.h"
-#include "configVariableBool.h"
-#include "configVariableSearchPath.h"
-#include "dconfig.h"
-
-#if defined(_MSC_VER) && defined(_DEBUG)
-// _DEBUG assumes you are linking to msvcrt70d.dll, not msvcrt70.dll
-#define USE_WIN32_DBGHEAP
-#include <crtdbg.h>
-#endif
-
-Configure(config_interrogatedb);
-NotifyCategoryDef(interrogatedb, "");
-
-ConfigureFn(config_interrogatedb) {
-  // interrogate_request_library("types");
-
-#ifdef USE_WIN32_DBGHEAP
-  ConfigVariableBool use_win32_dbgheap("use-win32-dbgheap", false);
-  ConfigVariableBool win32_report_leaks("win32-report-leaks", false);
-
-  int dbg_flags = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
-
-  if (use_win32_dbgheap.get_string_value() == "full") {
-    // "full" means check the heap after *every* allocdealloc.  Expensive.
-    dbg_flags |= (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF |
-                  _CRTDBG_CHECK_CRT_DF);
-
-  } else {
-    // Otherwise, it's a bool flag.  true means check the heap normally, false
-    // means don't do any debug checking.
-    if (!use_win32_dbgheap) {
-      // deflt disable complete heap verify every 1024 allocations (VC7
-      // deflt). With vc7 stl small-string-optimization causing more allocs,
-      // this can cause order-of-magnitude slowdowns in dbg builds
-      dbg_flags = 0;
-    }
-  }
-
-  if (win32_report_leaks) {
-    // Report memory still allocated at program termination.  Not sure how
-    // useful this is, as many things get allocated once and never freed, but
-    // they aren't really leaks.
-    dbg_flags |= _CRTDBG_LEAK_CHECK_DF;
-  }
-
-  _CrtSetDbgFlag(dbg_flags);
-#endif
-}
-
-ConfigVariableSearchPath interrogatedb_path
-("interrogatedb-path", "The search path for interrogate's *.in files.");

+ 0 - 25
dtool/src/interrogatedb/config_interrogatedb.h

@@ -1,25 +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_interrogatedb.h
- * @author drose
- * @date 2000-08-01
- */
-
-#ifndef CONFIG_INTERROGATEDB_H
-#define CONFIG_INTERROGATEDB_H
-
-#include "dtoolbase.h"
-#include "notifyCategoryProxy.h"
-#include "configVariableSearchPath.h"
-
-NotifyCategoryDecl(interrogatedb, EXPCL_INTERROGATEDB, EXPTP_INTERROGATEDB);
-
-extern ConfigVariableSearchPath interrogatedb_path;
-
-#endif

+ 0 - 177
dtool/src/interrogatedb/dtool_super_base.cxx

@@ -1,177 +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 dtool_super_base.cxx
- * @author drose
- * @date 2005-07-04
- */
-
-#include "py_panda.h"
-
-#ifdef HAVE_PYTHON
-
-static PyMemberDef standard_type_members[] = {
-  {(char *)"this", (sizeof(void*) == sizeof(int)) ? T_UINT : T_ULONGLONG, offsetof(Dtool_PyInstDef, _ptr_to_object), READONLY, (char *)"C++ 'this' pointer, if any"},
-  {(char *)"this_ownership", T_BOOL, offsetof(Dtool_PyInstDef, _memory_rules), READONLY, (char *)"C++ 'this' ownership rules"},
-  {(char *)"this_const", T_BOOL, offsetof(Dtool_PyInstDef, _is_const), READONLY, (char *)"C++ 'this' const flag"},
-// {(char *)"this_signature", T_INT, offsetof(Dtool_PyInstDef, _signature),
-// READONLY, (char *)"A type check signature"},
-  {(char *)"this_metatype", T_OBJECT_EX, offsetof(Dtool_PyInstDef, _My_Type), READONLY, (char *)"The dtool meta object"},
-  {nullptr}  /* Sentinel */
-};
-
-static PyObject *GetSuperBase(PyObject *self) {
-  Dtool_PyTypedObject *super_base = Dtool_GetSuperBase();
-  return Py_XNewRef((PyObject *)&super_base->_PyType);
-};
-
-static void Dtool_PyModuleClassInit_DTOOL_SUPER_BASE(PyObject *module) {
-  if (module != nullptr) {
-    Dtool_PyTypedObject *super_base = Dtool_GetSuperBase();
-    PyModule_AddObjectRef(module, "DTOOL_SUPER_BASE", (PyObject *)&super_base->_PyType);
-  }
-}
-
-static void *Dtool_UpcastInterface_DTOOL_SUPER_BASE(PyObject *self, Dtool_PyTypedObject *requested_type) {
-  return nullptr;
-}
-
-static PyObject *Dtool_Wrap_DTOOL_SUPER_BASE(void *from_this, PyTypeObject *from_type) {
-  return nullptr;
-}
-
-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;
-}
-
-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();
-
-  // If we don't have the GIL, we have to protect this with a lock to make
-  // sure that there is only one DTOOL_SUPER_BASE instance in the world.
-#ifdef Py_GIL_DISABLED
-  PyMutex_Lock(&type_map->_lock);
-#endif
-
-  auto it = type_map->find("DTOOL_SUPER_BASE");
-  if (it != type_map->end()) {
-#ifdef Py_GIL_DISABLED
-    PyMutex_Unlock(&type_map->_lock);
-#endif
-    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,
-      0, // tp_vectorcall_offset
-      nullptr, // tp_getattr
-      nullptr, // tp_setattr
-#if PY_MAJOR_VERSION >= 3
-      nullptr, // tp_compare
-#else
-      &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
-#if PY_MAJOR_VERSION >= 3
-      &DtoolInstance_RichComparePointers,
-#else
-      nullptr, // tp_richcompare
-#endif
-      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
-      0, // tp_version_tag,
-#if PY_VERSION_HEX >= 0x03040000
-      nullptr, // tp_finalize
-#endif
-#if PY_VERSION_HEX >= 0x03080000
-      nullptr, // tp_vectorcall
-#endif
-    },
-    TypeHandle::none(),
-    Dtool_PyModuleClassInit_DTOOL_SUPER_BASE,
-    Dtool_UpcastInterface_DTOOL_SUPER_BASE,
-    Dtool_Wrap_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)");
-#ifdef Py_GIL_DISABLED
-    PyMutex_Unlock(&type_map->_lock);
-#endif
-    return nullptr;
-  }
-  Py_INCREF(&super_base_type._PyType);
-
-  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;
-#ifdef Py_GIL_DISABLED
-  PyMutex_Unlock(&type_map->_lock);
-#endif
-  return &super_base_type;
-}
-
-#endif  // HAVE_PYTHON

+ 0 - 68
dtool/src/interrogatedb/indexRemapper.cxx

@@ -1,68 +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 indexRemapper.cxx
- * @author drose
- * @date 2000-08-05
- */
-
-#include "indexRemapper.h"
-
-
-/**
- *
- */
-IndexRemapper::
-IndexRemapper() {
-}
-
-/**
- *
- */
-IndexRemapper::
-~IndexRemapper() {
-}
-
-/**
- * Removes all mappings from the object.
- */
-void IndexRemapper::
-clear() {
-  _map_int.clear();
-}
-
-/**
- * Adds a mapping from the integer 'from' to 'to'.
- */
-void IndexRemapper::
-add_mapping(int from, int to) {
-  _map_int[from] = to;
-}
-
-/**
- * Returns true if the given 'from' integer has been assigned a mapping, false
- * if it has not.
- */
-bool IndexRemapper::
-in_map(int from) const {
-  return _map_int.count(from) != 0;
-}
-
-/**
- * Returns the integer that the given 'from' integer had been set to map to,
- * or the same integer if nothing had been set for it.
- */
-int IndexRemapper::
-map_from(int from) const {
-  std::map<int, int>::const_iterator mi;
-  mi = _map_int.find(from);
-  if (mi == _map_int.end()) {
-    return from;
-  }
-  return (*mi).second;
-}

+ 0 - 44
dtool/src/interrogatedb/indexRemapper.h

@@ -1,44 +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 indexRemapper.h
- * @author drose
- * @date 2000-08-05
- */
-
-#ifndef INDEXREMAPPER_H
-#define INDEXREMAPPER_H
-
-#include "dtoolbase.h"
-
-#include <map>
-
-/**
- * This class manages a mapping of integers to integers.  It's used in this
- * package to resequence some or all of the index numbers in the database to a
- * different sequence.
- *
- * This class is just a wrapper around STL map.  The only reason it exists is
- * because Microsoft can't export STL map outside of the DLL.
- */
-class EXPCL_INTERROGATEDB IndexRemapper {
-public:
-  IndexRemapper();
-  ~IndexRemapper();
-
-  void clear();
-  void add_mapping(int from, int to);
-
-  bool in_map(int from) const;
-  int map_from(int from) const;
-
-private:
-  std::map<int, int> _map_int;
-};
-
-#endif

+ 0 - 123
dtool/src/interrogatedb/interrogateComponent.I

@@ -1,123 +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 interrogateComponent.I
- * @author drose
- * @date 2000-08-08
- */
-
-/**
- *
- */
-INLINE InterrogateComponent::
-InterrogateComponent(InterrogateModuleDef *def) :
-  _def(def)
-{
-}
-
-/**
- *
- */
-INLINE InterrogateComponent::
-InterrogateComponent(const InterrogateComponent &copy) :
-  _def(copy._def),
-  _name(copy._name)
-{
-}
-
-/**
- *
- */
-INLINE void InterrogateComponent::
-operator = (const InterrogateComponent &copy) {
-  _def = copy._def;
-  _name = copy._name;
-}
-
-/**
- * Returns true if we have a known library name, false if we do not.  See
- * get_library_name().
- */
-INLINE bool InterrogateComponent::
-has_library_name() const {
-  const char *name = get_library_name();
-  return (name != nullptr && name[0] != '\0');
-}
-
-/**
- * Returns the library name, if it is known, or NULL if it is not.  This is
- * the name of the library that this particular component was built into.
- * Typically this will be a one-to-one correspondance with an invocation of
- * the interrogate command.  Typical examples are "libutil" and "liblinmath".
- */
-INLINE const char *InterrogateComponent::
-get_library_name() const {
-  if (_def != nullptr) {
-    return _def->library_name;
-  }
-  return nullptr;
-}
-
-/**
- * Returns true if we have a known module name, false if we do not.  See
- * get_module_name().
- */
-INLINE bool InterrogateComponent::
-has_module_name() const {
-  const char *name = get_module_name();
-  return (name != nullptr && name[0] != '\0');
-}
-
-/**
- * Returns the module name, if it is known, or NULL if it is not.  This is the
- * name of the module that this particular component is associated with.  This
- * is a higher grouping than library.  Typical examples are "panda" and
- * "pandaegg".
- */
-INLINE const char *InterrogateComponent::
-get_module_name() const {
-  if (_def != nullptr) {
-    return _def->module_name;
-  }
-  return nullptr;
-}
-
-/**
- *
- */
-INLINE bool InterrogateComponent::
-has_name() const {
-  return !_name.empty();
-}
-
-/**
- *
- */
-INLINE const std::string &InterrogateComponent::
-get_name() const {
-  return _name;
-}
-
-/**
- *
- */
-INLINE int InterrogateComponent::
-get_num_alt_names() const {
-  return _alt_names.size();
-}
-
-/**
- *
- */
-INLINE const std::string &InterrogateComponent::
-get_alt_name(int n) const {
-  if (n >= 0 && n < (int)_alt_names.size()) {
-    return _alt_names[n];
-  }
-  return _empty_string;
-}

+ 0 - 50
dtool/src/interrogatedb/interrogateComponent.cxx

@@ -1,50 +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 interrogateComponent.cxx
- * @author drose
- * @date 2000-08-08
- */
-
-#include "interrogateComponent.h"
-#include "interrogate_datafile.h"
-
-// This static string is just kept around as a handy bogus return value for
-// functions that must return a const string reference.
-std::string InterrogateComponent::_empty_string;
-
-/**
- * Formats the component for output to a data file.
- */
-void InterrogateComponent::
-output(std::ostream &out) const {
-  idf_output_string(out, _name);
-  out << _alt_names.size() << " ";
-
-  Strings::const_iterator vi;
-  for (vi = _alt_names.begin(); vi != _alt_names.end(); ++vi) {
-    idf_output_string(out, *vi);
-  }
-}
-
-/**
- * Reads the data file as previously formatted by output().
- */
-void InterrogateComponent::
-input(std::istream &in) {
-  idf_input_string(in, _name);
-
-  int num_alt_names;
-  in >> num_alt_names;
-  _alt_names.reserve(num_alt_names);
-  for (int i = 0; i < num_alt_names; ++i) {
-    std::string alt_name;
-    idf_input_string(in, alt_name);
-    _alt_names.push_back(alt_name);
-  }
-}

+ 0 - 67
dtool/src/interrogatedb/interrogateComponent.h

@@ -1,67 +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 interrogateComponent.h
- * @author drose
- * @date 2000-08-08
- */
-
-#ifndef INTERROGATECOMPONENT_H
-#define INTERROGATECOMPONENT_H
-
-#include "dtoolbase.h"
-
-#include "interrogate_interface.h"
-#include "interrogate_request.h"
-
-#include <vector>
-
-class IndexRemapper;
-
-/**
- * The base class for things that are part of the interrogate database.  This
- * includes types, functions, and function wrappers.
- */
-class EXPCL_INTERROGATEDB InterrogateComponent {
-public:
-  INLINE InterrogateComponent(InterrogateModuleDef *def = nullptr);
-  INLINE InterrogateComponent(const InterrogateComponent &copy);
-  INLINE void operator = (const InterrogateComponent &copy);
-
-  INLINE bool has_library_name() const;
-  INLINE const char *get_library_name() const;
-
-  INLINE bool has_module_name() const;
-  INLINE const char *get_module_name() const;
-
-  INLINE bool has_name() const;
-  INLINE const std::string &get_name() const;
-
-  INLINE int get_num_alt_names() const;
-  INLINE const std::string &get_alt_name(int n) const;
-
-  void output(std::ostream &out) const;
-  void input(std::istream &in);
-
-protected:
-  static std::string _empty_string;
-
-private:
-  InterrogateModuleDef *_def;
-  std::string _name;
-
-  typedef std::vector<std::string> Strings;
-  Strings _alt_names;
-
-  friend class InterrogateBuilder;
-  friend class FunctionRemap;
-};
-
-#include "interrogateComponent.I"
-
-#endif

+ 0 - 89
dtool/src/interrogatedb/interrogateDatabase.I

@@ -1,89 +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 interrogateDatabase.I
- * @author drose
- * @date 2000-08-01
- */
-
-/**
- * Checks that all the latest data for all the libraries have been loaded.
- * Loads them if not.
- */
-INLINE void InterrogateDatabase::
-check_latest() {
-  if (!_requests.empty()) {
-    load_latest();
-  }
-}
-
-/**
- * Returns the TypeIndex associated with the first type found with the given
- * name, or 0 if no type has this name.
- */
-INLINE TypeIndex InterrogateDatabase::
-lookup_type_by_name(const std::string &name) {
-  check_latest();
-  return lookup(name, _types_by_name, LT_type_name,
-                &InterrogateDatabase::freshen_types_by_name);
-}
-
-/**
- * Returns the TypeIndex associated with the first type found with the given
- * scoped name, or 0 if no type has this name.
- */
-INLINE TypeIndex InterrogateDatabase::
-lookup_type_by_scoped_name(const std::string &name) {
-  check_latest();
-  return lookup(name, _types_by_scoped_name, LT_type_scoped_name,
-                &InterrogateDatabase::freshen_types_by_scoped_name);
-}
-
-/**
- * Returns the TypeIndex associated with the first type found with the given
- * true name, or 0 if no type has this name.
- */
-INLINE TypeIndex InterrogateDatabase::
-lookup_type_by_true_name(const std::string &name) {
-  check_latest();
-  return lookup(name, _types_by_true_name, LT_type_true_name,
-                &InterrogateDatabase::freshen_types_by_true_name);
-}
-
-/**
- * Returns the ManifestIndex associated with the first manifest found with the
- * given name, or 0 if no manifest has this name.
- */
-INLINE ManifestIndex InterrogateDatabase::
-lookup_manifest_by_name(const std::string &name) {
-  check_latest();
-  return lookup(name, _manifests_by_name, LT_manifest_name,
-                &InterrogateDatabase::freshen_manifests_by_name);
-}
-
-/**
- * Returns the ElementIndex associated with the first element found with the
- * given name, or 0 if no element has this name.
- */
-INLINE ElementIndex InterrogateDatabase::
-lookup_element_by_name(const std::string &name) {
-  check_latest();
-  return lookup(name, _elements_by_name, LT_element_name,
-                &InterrogateDatabase::freshen_elements_by_name);
-}
-
-/**
- * Returns the ElementIndex associated with the first element found with the
- * given scoped name, or 0 if no element has this name.
- */
-INLINE ElementIndex InterrogateDatabase::
-lookup_element_by_scoped_name(const std::string &name) {
-  check_latest();
-  return lookup(name, _elements_by_scoped_name, LT_element_scoped_name,
-                &InterrogateDatabase::freshen_elements_by_scoped_name);
-}

+ 0 - 1330
dtool/src/interrogatedb/interrogateDatabase.cxx

@@ -1,1330 +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 interrogateDatabase.cxx
- * @author drose
- * @date 2000-08-01
- */
-
-#include "interrogateDatabase.h"
-#include "config_interrogatedb.h"
-#include "indexRemapper.h"
-#include "interrogate_datafile.h"
-
-using std::map;
-using std::string;
-
-InterrogateDatabase *InterrogateDatabase::_global_ptr = nullptr;
-int InterrogateDatabase::_file_major_version = 0;
-int InterrogateDatabase::_file_minor_version = 0;
-int InterrogateDatabase::_current_major_version = 3;
-int InterrogateDatabase::_current_minor_version = 3;
-
-/**
- *
- */
-InterrogateDatabase::
-InterrogateDatabase() {
-  _error_flag = false;
-  _next_index = 1;
-  _lookups_fresh = 0;
-}
-
-/**
- * Returns the global pointer to the one InterrogateDatabase.
- */
-InterrogateDatabase *InterrogateDatabase::
-get_ptr() {
-  if (_global_ptr == nullptr) {
-    if (interrogatedb_cat->is_debug()) {
-      interrogatedb_cat->debug()
-        << "Creating interrogate database\n";
-    }
-    _global_ptr = new InterrogateDatabase;
-  }
-  return _global_ptr;
-}
-
-/**
- * Requests that the interrogate data for the given module be made available.
- * The function pointers will be made available immediately, while the
- * database file will be read later, the next time someone asks for
- * interrogate data that requires it.
- */
-void InterrogateDatabase::
-request_module(InterrogateModuleDef *def) {
-  if (interrogatedb_cat->is_debug()) {
-    if (def->library_name == nullptr) {
-      interrogatedb_cat->debug()
-        << "Got interrogate data for anonymous module\n";
-    } else {
-      interrogatedb_cat->debug()
-        << "Got interrogate data for module " << def->library_name << "\n";
-    }
-  }
-
-  int num_indices = def->next_index - def->first_index;
-  if (num_indices > 0) {
-    // If the module def has any definitions--any index numbers used--assign
-    // it to its own unique range of index numbers.
-    def->first_index = _next_index;
-    _next_index += num_indices;
-    def->next_index = _next_index;
-
-    // Assign a reference to the module def by index number.  When we need to
-    // look up a function by its index number, we'll be able to use this.
-    _modules.push_back(def);
-  }
-
-  if (def->num_unique_names > 0 && def->library_name != nullptr) {
-    // Define a lookup by hash for this module, mainly so we can look up
-    // functions by their unique names.
-    _modules_by_hash[def->library_hash_name] = def;
-  }
-
-  if (def->database_filename != nullptr) {
-    _requests.push_back(def);
-  }
-}
-
-/**
- * Returns the global error flag.  This will be set true if there was some
- * problem importing the database (e.g.  cannot find an .in file), or false if
- * everything is ok.
- */
-bool InterrogateDatabase::
-get_error_flag() {
-  return _error_flag;
-}
-
-/**
- * Returns the total number of "global" types known to the interrogate
- * database.  These are types defined at the global level that should be
- * considered for exporting, but not the incidental types (like pointers,
- * etc.) that must be defined to support these.
- */
-int InterrogateDatabase::
-get_num_global_types() {
-  check_latest();
-  return _global_types.size();
-}
-
-/**
- * Returns the index of the nth global type known to the interrogate database.
- */
-TypeIndex InterrogateDatabase::
-get_global_type(int n) {
-  check_latest();
-  if (n >= 0 && n < (int)_global_types.size()) {
-    return _global_types[n];
-  }
-  return 0;
-}
-
-/**
- * Returns the total number of types known to the interrogate database.  This
- * includes all known types, global as well as incidental.  See also
- * get_num_global_types().
- */
-int InterrogateDatabase::
-get_num_all_types() {
-  check_latest();
-  return _all_types.size();
-}
-
-/**
- * Returns the index of the nth type known to the interrogate database.
- */
-TypeIndex InterrogateDatabase::
-get_all_type(int n) {
-  check_latest();
-  if (n >= 0 && n < (int)_all_types.size()) {
-    return _all_types[n];
-  }
-  return 0;
-}
-
-/**
- * Returns the total number of global functions known to the interrogate
- * database.  These are functions defined at the global level, e.g.  non-
- * member functions.
- */
-int InterrogateDatabase::
-get_num_global_functions() {
-  check_latest();
-  return _global_functions.size();
-}
-
-/**
- * Returns the index of the nth global function known to the interrogate
- * database.
- */
-FunctionIndex InterrogateDatabase::
-get_global_function(int n) {
-  check_latest();
-  if (n >= 0 && n < (int)_global_functions.size()) {
-    return _global_functions[n];
-  }
-  return 0;
-}
-
-/**
- * Returns the total number of functions known to the interrogate database.
- * This includes all known functions, global, method, or synthesized.  See
- * also get_num_global_functions().
- */
-int InterrogateDatabase::
-get_num_all_functions() {
-  check_latest();
-  return _all_functions.size();
-}
-
-/**
- * Returns the index of the nth function known to the interrogate database.
- */
-FunctionIndex InterrogateDatabase::
-get_all_function(int n) {
-  check_latest();
-  if (n >= 0 && n < (int)_all_functions.size()) {
-    return _all_functions[n];
-  }
-  return 0;
-}
-
-/**
- * Returns the total number of global manifest constants known to the
- * interrogate database.
- */
-int InterrogateDatabase::
-get_num_global_manifests() {
-  check_latest();
-  return _global_manifests.size();
-}
-
-/**
- * Returns the index of the nth global manifest constant known to the
- * interrogate database.
- */
-ManifestIndex InterrogateDatabase::
-get_global_manifest(int n) {
-  check_latest();
-  if (n >= 0 && n < (int)_global_manifests.size()) {
-    return _global_manifests[n];
-  }
-  return 0;
-}
-
-/**
- * Returns the total number of global data elements known to the interrogate
- * database.
- */
-int InterrogateDatabase::
-get_num_global_elements() {
-  check_latest();
-  return _global_elements.size();
-}
-
-/**
- * Returns the index of the nth global data element known to the interrogate
- * database.
- */
-ElementIndex InterrogateDatabase::
-get_global_element(int n) {
-  check_latest();
-  if (n >= 0 && n < (int)_global_elements.size()) {
-    return _global_elements[n];
-  }
-  return 0;
-}
-
-/**
- * Returns the type associated with the given TypeIndex, if there is one.
- */
-const InterrogateType &InterrogateDatabase::
-get_type(TypeIndex type) {
-  static InterrogateType bogus_type;
-
-  check_latest();
-  TypeMap::const_iterator ti;
-  ti = _type_map.find(type);
-  if (ti == _type_map.end()) {
-    return bogus_type;
-  }
-  return (*ti).second;
-}
-
-/**
- * Returns the function associated with the given FunctionIndex, if there is
- * one.
- */
-const InterrogateFunction &InterrogateDatabase::
-get_function(FunctionIndex function) {
-  static InterrogateFunction bogus_function;
-
-  check_latest();
-  FunctionMap::const_iterator fi;
-  fi = _function_map.find(function);
-  if (fi == _function_map.end()) {
-    return bogus_function;
-  }
-  return *(*fi).second;
-}
-
-/**
- * Returns the function wrapper associated with the given
- * FunctionWrapperIndex, if there is one.
- */
-const InterrogateFunctionWrapper &InterrogateDatabase::
-get_wrapper(FunctionWrapperIndex wrapper) {
-  static InterrogateFunctionWrapper bogus_wrapper;
-
-  check_latest();
-  FunctionWrapperMap::const_iterator wi;
-  wi = _wrapper_map.find(wrapper);
-  if (wi == _wrapper_map.end()) {
-    return bogus_wrapper;
-  }
-  return (*wi).second;
-}
-
-/**
- * Returns the manifest constant associated with the given ManifestIndex, if
- * there is one.
- */
-const InterrogateManifest &InterrogateDatabase::
-get_manifest(ManifestIndex manifest) {
-  static InterrogateManifest bogus_manifest;
-
-  check_latest();
-  ManifestMap::const_iterator mi;
-  mi = _manifest_map.find(manifest);
-  if (mi == _manifest_map.end()) {
-    return bogus_manifest;
-  }
-  return (*mi).second;
-}
-
-/**
- * Returns the data element associated with the given ElementIndex, if there
- * is one.
- */
-const InterrogateElement &InterrogateDatabase::
-get_element(ElementIndex element) {
-  static InterrogateElement bogus_element;
-
-  check_latest();
-  ElementMap::const_iterator ei;
-  ei = _element_map.find(element);
-  if (ei == _element_map.end()) {
-    return bogus_element;
-  }
-  return (*ei).second;
-}
-
-/**
- * Returns the make_seq associated with the given MakeSeqIndex, if there is
- * one.
- */
-const InterrogateMakeSeq &InterrogateDatabase::
-get_make_seq(MakeSeqIndex make_seq) {
-  static InterrogateMakeSeq bogus_make_seq;
-
-  check_latest();
-  MakeSeqMap::const_iterator si;
-  si = _make_seq_map.find(make_seq);
-  if (si == _make_seq_map.end()) {
-    return bogus_make_seq;
-  }
-  return (*si).second;
-}
-
-/**
- * Erases the type from the database.
- */
-void InterrogateDatabase::
-remove_type(TypeIndex type) {
-  _type_map.erase(type);
-}
-
-/**
- * Returns the function pointer associated with the given function wrapper, if
- * it has a pointer available.  Returns NULL if the pointer is not available.
- */
-void *InterrogateDatabase::
-get_fptr(FunctionWrapperIndex wrapper) {
-  InterrogateModuleDef *def;
-  int module_index;
-  if (find_module(wrapper, def, module_index)) {
-    if (module_index >= 0 && module_index < def->num_fptrs) {
-      return def->fptrs[module_index];
-    }
-  }
-  return nullptr;
-}
-
-/**
- * Looks up the function wrapper corresponding to the given unique name, if
- * available.  Returns the corresponding wrapper index, or 0 if no such
- * wrapper is found.
- */
-FunctionWrapperIndex InterrogateDatabase::
-get_wrapper_by_unique_name(const string &unique_name) {
-  // First, split the unique_name into a library_hash_name and a
-  // wrapper_hash_name.
-
-  // The first four characters are always the library_name.
-  string library_hash_name = unique_name.substr(0, 4);
-  string wrapper_hash_name = unique_name.substr(4);
-
-  // Is the library_name defined?
-  ModulesByHash::const_iterator mi;
-  mi = _modules_by_hash.find(library_hash_name);
-  if (mi == _modules_by_hash.end()) {
-    return 0;
-  }
-
-  InterrogateModuleDef *def = (*mi).second;
-  int index_offset =
-    binary_search_wrapper_hash(def->unique_names,
-                               def->unique_names + def->num_unique_names,
-                               wrapper_hash_name);
-  if (index_offset >= 0) {
-    return def->first_index + index_offset;
-  }
-
-  return 0;
-}
-
-/**
- * Returns the major version number of the interrogate database file currently
- * being read.
- */
-int InterrogateDatabase::
-get_file_major_version() {
-  return _file_major_version;
-}
-
-/**
- * Returns the minor version number of the interrogate database file currently
- * being read.
- */
-int InterrogateDatabase::
-get_file_minor_version() {
-  return _file_minor_version;
-}
-
-/**
- * Returns the major version number currently expected in interrogate database
- * files generated by this code base.
- */
-int InterrogateDatabase::
-get_current_major_version() {
-  return _current_major_version;
-}
-
-/**
- * Returns the minor version number currently expected in interrogate database
- * files generated by this code base.
- */
-int InterrogateDatabase::
-get_current_minor_version() {
-  return _current_minor_version;
-}
-
-/**
- * Sets the global error flag.  This should be set true if there was some
- * problem importing the database (e.g.  cannot find an .in file).
- */
-void InterrogateDatabase::
-set_error_flag(bool error_flag) {
-  _error_flag = error_flag;
-}
-
-/**
- * Returns a new index number suitable for the next thing, that will not be
- * shared with any other index numbers.
- */
-int InterrogateDatabase::
-get_next_index() {
-  return _next_index++;
-}
-
-/**
- * Adds the indicated type to the database at the given index number.
- */
-void InterrogateDatabase::
-add_type(TypeIndex index, const InterrogateType &type) {
-  assert(index != 0);
-  bool inserted =
-    _type_map.insert(TypeMap::value_type(index, type)).second;
-
-  if (!inserted) {
-    // If there was already a type at that index, maybe it was a forward
-    // reference.  If its _fully_defined bit isn't set, then it's ok.
-    InterrogateType &old_type = _type_map[index];
-    assert(!old_type.is_fully_defined());
-
-    // It was a forward reference.  Merge it with the new one.
-    old_type.merge_with(type);
-  }
-
-  if (type.is_global()) {
-    _global_types.push_back(index);
-  }
-  _all_types.push_back(index);
-}
-
-/**
- * Adds the indicated function to the database at the given index number.
- */
-void InterrogateDatabase::
-add_function(FunctionIndex index, InterrogateFunction *function) {
-  bool inserted =
-    _function_map.insert(FunctionMap::value_type(index, function)).second;
-  assert(inserted);
-
-  if (function->is_global()) {
-    _global_functions.push_back(index);
-  }
-  _all_functions.push_back(index);
-}
-
-/**
- * Adds the indicated function wrapper to the database at the given index
- * number.
- */
-void InterrogateDatabase::
-add_wrapper(FunctionWrapperIndex index,
-            const InterrogateFunctionWrapper &wrapper) {
-  bool inserted =
-    _wrapper_map.insert(FunctionWrapperMap::value_type(index, wrapper)).second;
-  assert(inserted);
-}
-
-/**
- * Adds the indicated manifest constant to the database at the given index
- * number.
- */
-void InterrogateDatabase::
-add_manifest(ManifestIndex index, const InterrogateManifest &manifest) {
-  bool inserted =
-    _manifest_map.insert(ManifestMap::value_type(index, manifest)).second;
-  assert(inserted);
-
-  _global_manifests.push_back(index);
-}
-
-/**
- * Adds the indicated data element to the database at the given index number.
- */
-void InterrogateDatabase::
-add_element(ElementIndex index, const InterrogateElement &element) {
-  bool inserted =
-    _element_map.insert(ElementMap::value_type(index, element)).second;
-  assert(inserted);
-
-  if (element.is_global()) {
-    _global_elements.push_back(index);
-  }
-}
-
-/**
- * Adds the indicated make_seq to the database at the given index number.
- */
-void InterrogateDatabase::
-add_make_seq(MakeSeqIndex index, const InterrogateMakeSeq &make_seq) {
-  bool inserted =
-    _make_seq_map.insert(MakeSeqMap::value_type(index, make_seq)).second;
-  assert(inserted);
-}
-
-/**
- * Returns a non-const reference to the indicated type, allowing the user to
- * update it.
- */
-InterrogateType &InterrogateDatabase::
-update_type(TypeIndex type) {
-  assert(type != 0);
-  check_latest();
-  return _type_map[type];
-}
-
-/**
- * Returns a non-const reference to the indicated function, allowing the user
- * to update it.
- */
-InterrogateFunction &InterrogateDatabase::
-update_function(FunctionIndex function) {
-  check_latest();
-  return *_function_map[function];
-}
-
-/**
- * Returns a non-const reference to the indicated function wrapper, allowing
- * the user to update it.
- */
-InterrogateFunctionWrapper &InterrogateDatabase::
-update_wrapper(FunctionWrapperIndex wrapper) {
-  check_latest();
-  return _wrapper_map[wrapper];
-}
-
-/**
- * Returns a non-const reference to the indicated manifest constant, allowing
- * the user to update it.
- */
-InterrogateManifest &InterrogateDatabase::
-update_manifest(ManifestIndex manifest) {
-  check_latest();
-  return _manifest_map[manifest];
-}
-
-/**
- * Returns a non-const reference to the indicated data element, allowing the
- * user to update it.
- */
-InterrogateElement &InterrogateDatabase::
-update_element(ElementIndex element) {
-  check_latest();
-  return _element_map[element];
-}
-
-/**
- * Returns a non-const reference to the indicated make_seq, allowing the user
- * to update it.
- */
-InterrogateMakeSeq &InterrogateDatabase::
-update_make_seq(MakeSeqIndex make_seq) {
-  check_latest();
-  return _make_seq_map[make_seq];
-}
-
-/**
- * Resequences all of the various index numbers so that all of the functions
- * start at first_index and increment consecutively from there, and then all
- * of the types follow.  Returns the next available index number.
- */
-int InterrogateDatabase::
-remap_indices(int first_index) {
-  IndexRemapper remap;
-  return remap_indices(first_index, remap);
-}
-
-/**
- * This flavor of remap_indices() accepts a map that should be empty on
- * initial call, and will be filled with the mapping of old index number to
- * new index number.  This allows the caller to update its own data structures
- * to match the new index numbers.
- */
-int InterrogateDatabase::
-remap_indices(int first_index, IndexRemapper &remap) {
-  remap.clear();
-
-  // First, build up the complete map.
-
-  // Get the wrapper indices first.  This is important, because the
-  // InterrogateBuilder wants these to be first, and consecutive.
-  FunctionWrapperMap new_wrapper_map;
-  FunctionWrapperMap::iterator wi;
-  for (wi = _wrapper_map.begin(); wi != _wrapper_map.end(); ++wi) {
-    remap.add_mapping((*wi).first, first_index);
-    new_wrapper_map[first_index] = (*wi).second;
-    first_index++;
-  }
-
-  // Everything else can follow; it doesn't matter so much.
-  FunctionMap new_function_map;
-  FunctionMap::iterator fi;
-  for (fi = _function_map.begin(); fi != _function_map.end(); ++fi) {
-    remap.add_mapping((*fi).first, first_index);
-    new_function_map[first_index] = (*fi).second;
-    first_index++;
-  }
-
-  TypeMap new_type_map;
-  TypeMap::iterator ti;
-  for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
-    assert((*ti).first != 0);
-    remap.add_mapping((*ti).first, first_index);
-    new_type_map[first_index] = (*ti).second;
-    first_index++;
-  }
-
-  ManifestMap new_manifest_map;
-  ManifestMap::iterator mi;
-  for (mi = _manifest_map.begin(); mi != _manifest_map.end(); ++mi) {
-    remap.add_mapping((*mi).first, first_index);
-    new_manifest_map[first_index] = (*mi).second;
-    first_index++;
-  }
-
-  ElementMap new_element_map;
-  ElementMap::iterator ei;
-  for (ei = _element_map.begin(); ei != _element_map.end(); ++ei) {
-    remap.add_mapping((*ei).first, first_index);
-    new_element_map[first_index] = (*ei).second;
-    first_index++;
-  }
-
-  MakeSeqMap new_make_seq_map;
-  MakeSeqMap::iterator si;
-  for (si = _make_seq_map.begin(); si != _make_seq_map.end(); ++si) {
-    remap.add_mapping((*si).first, first_index);
-    new_make_seq_map[first_index] = (*si).second;
-    first_index++;
-  }
-
-  _next_index = first_index;
-
-  _wrapper_map.swap(new_wrapper_map);
-  _function_map.swap(new_function_map);
-  _type_map.swap(new_type_map);
-  _manifest_map.swap(new_manifest_map);
-  _element_map.swap(new_element_map);
-  _make_seq_map.swap(new_make_seq_map);
-
-  // Then, go back through and update all of the internal references.
-  for (wi = _wrapper_map.begin(); wi != _wrapper_map.end(); ++wi) {
-    (*wi).second.remap_indices(remap);
-  }
-  for (fi = _function_map.begin(); fi != _function_map.end(); ++fi) {
-    (*fi).second->remap_indices(remap);
-  }
-  for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
-    (*ti).second.remap_indices(remap);
-  }
-  for (mi = _manifest_map.begin(); mi != _manifest_map.end(); ++mi) {
-    (*mi).second.remap_indices(remap);
-  }
-  for (ei = _element_map.begin(); ei != _element_map.end(); ++ei) {
-    (*ei).second.remap_indices(remap);
-  }
-  for (si = _make_seq_map.begin(); si != _make_seq_map.end(); ++si) {
-    (*si).second.remap_indices(remap);
-  }
-  GlobalFunctions::iterator gfi;
-  for (gfi = _global_functions.begin(); gfi != _global_functions.end(); ++gfi) {
-    (*gfi) = remap.map_from(*gfi);
-  }
-  for (gfi = _all_functions.begin(); gfi != _all_functions.end(); ++gfi) {
-    (*gfi) = remap.map_from(*gfi);
-  }
-  GlobalTypes::iterator gti;
-  for (gti = _global_types.begin(); gti != _global_types.end(); ++gti) {
-    (*gti) = remap.map_from(*gti);
-  }
-  for (gti = _all_types.begin(); gti != _all_types.end(); ++gti) {
-    (*gti) = remap.map_from(*gti);
-  }
-  GlobalManifests::iterator gmi;
-  for (gmi = _global_manifests.begin(); gmi != _global_manifests.end(); ++gmi) {
-    (*gmi) = remap.map_from(*gmi);
-  }
-  GlobalElements::iterator gei;
-  for (gei = _global_elements.begin(); gei != _global_elements.end(); ++gei) {
-    (*gei) = remap.map_from(*gei);
-  }
-
-  return _next_index;
-}
-
-/**
- * Writes the database to the indicated stream for later reading.
- */
-void InterrogateDatabase::
-write(std::ostream &out, InterrogateModuleDef *def) const {
-  // Write out the file header.
-  out << def->file_identifier << "\n"
-      << _current_major_version << " " << _current_minor_version << "\n";
-
-  // Write out the module definition.
-  idf_output_string(out, def->library_name);
-  idf_output_string(out, def->library_hash_name);
-  idf_output_string(out, def->module_name);
-  out << "\n";
-
-  // Now write out the components.
-
-  out << _function_map.size() << "\n";
-  FunctionMap::const_iterator fi;
-  for (fi = _function_map.begin(); fi != _function_map.end(); ++fi) {
-    out << (*fi).first << " " << *(*fi).second << "\n";
-  }
-
-  out << _wrapper_map.size() << "\n";
-  FunctionWrapperMap::const_iterator wi;
-  for (wi = _wrapper_map.begin(); wi != _wrapper_map.end(); ++wi) {
-    out << (*wi).first << " " << (*wi).second << "\n";
-  }
-
-  out << _type_map.size() << "\n";
-  TypeMap::const_iterator ti;
-  for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
-    out << (*ti).first << " " << (*ti).second << "\n";
-  }
-
-  out << _manifest_map.size() << "\n";
-  ManifestMap::const_iterator mi;
-  for (mi = _manifest_map.begin(); mi != _manifest_map.end(); ++mi) {
-    out << (*mi).first << " " << (*mi).second << "\n";
-  }
-
-  out << _element_map.size() << "\n";
-  ElementMap::const_iterator ei;
-  for (ei = _element_map.begin(); ei != _element_map.end(); ++ei) {
-    out << (*ei).first << " " << (*ei).second << "\n";
-  }
-
-  out << _make_seq_map.size() << "\n";
-  MakeSeqMap::const_iterator si;
-  for (si = _make_seq_map.begin(); si != _make_seq_map.end(); ++si) {
-    out << (*si).first << " " << (*si).second << "\n";
-  }
-}
-
-/**
- * Reads a database from the indicated stream, associated with the indicated
- * module definition and merges it with any existing data in the database,
- * according to the expected index numbers specified in the module def.  The
- * header information has already been read.
- *
- * Returns true if the file is read successfully, false if there is an error.
- */
-bool InterrogateDatabase::
-read(std::istream &in, InterrogateModuleDef *def) {
-  InterrogateDatabase temp;
-  if (!temp.read_new(in, def)) {
-    return false;
-  }
-
-  if (def->first_index == 0 && def->next_index == 0) {
-    _next_index = temp.remap_indices(_next_index);
-
-  } else {
-    int next = temp.remap_indices(def->first_index);
-    if (next != def->next_index) {
-      interrogatedb_cat->error()
-        << "Module database file " << def->database_filename
-        << " is out of date.\n";
-      return false;
-    }
-  }
-
-  merge_from(temp);
-  return true;
-}
-
-/**
- * Reads in the latest interrogate data.
- */
-void InterrogateDatabase::
-load_latest() {
-  const DSearchPath &searchpath = interrogatedb_path;
-
-  Requests copy_requests;
-  copy_requests.swap(_requests);
-
-  Requests::const_iterator ri;
-  for (ri = copy_requests.begin(); ri != copy_requests.end(); ++ri) {
-    InterrogateModuleDef *def = (*ri);
-
-    if (def->database_filename != nullptr) {
-      Filename filename = def->database_filename;
-      Filename pathname = filename;
-      if (!pathname.empty() && pathname[0] != '/') {
-        pathname = searchpath.find_file(pathname);
-      }
-
-      if (pathname.empty()) {
-        interrogatedb_cat->error()
-          << "Unable to find " << filename << " on " << searchpath << "\n";
-        set_error_flag(true);
-
-      } else {
-
-        pifstream input;
-        pathname.set_text();
-        if (!pathname.open_read(input)) {
-          interrogatedb_cat->error() << "Unable to read " << pathname << ".\n";
-          set_error_flag(true);
-
-        } else {
-          int file_identifier;
-          input >> file_identifier
-                >> _file_major_version >> _file_minor_version;
-
-          if (def->file_identifier != 0 &&
-              file_identifier != def->file_identifier) {
-            interrogatedb_cat->warning()
-              << "Interrogate data in " << pathname
-              << " is out of sync with the compiled-in data"
-              << " (" << file_identifier << " != " << def->file_identifier << ").\n";
-            set_error_flag(true);
-          }
-
-          if (_file_major_version != _current_major_version ||
-              _file_minor_version > _current_minor_version) {
-            interrogatedb_cat->error()
-              << "Cannot read interrogate data in " << pathname
-              << "; database is version " << _file_major_version << "."
-              << _file_minor_version << " while we are expecting "
-              << _current_major_version << "." << _current_minor_version
-              << ".\n";
-            set_error_flag(true);
-
-          } else {
-            if (interrogatedb_cat->is_debug()) {
-              interrogatedb_cat->debug()
-                << "Reading " << filename << "\n";
-            }
-            if (!read(input, def)) {
-              interrogatedb_cat->error()
-                << "Error reading " << pathname << ".\n";
-              set_error_flag(true);
-            }
-          }
-        }
-      }
-    }
-  }
-
-  _requests.clear();
-}
-
-/**
- * Reads from the indicated stream (the header information has already been
- * read) into the newly-created database.  It is an error if the database
- * already has some data in it.
- */
-bool InterrogateDatabase::
-read_new(std::istream &in, InterrogateModuleDef *def) {
-  // We've already read the header.  Read the module definition.
-  idf_input_string(in, def->library_name);
-  idf_input_string(in, def->library_hash_name);
-  idf_input_string(in, def->module_name);
-
-  // Now read all of the components.
-
-  { // Functions.
-    int num_functions;
-    in >> num_functions;
-    if (in.fail()) {
-      return false;
-    }
-
-    while (num_functions > 0) {
-      FunctionIndex index;
-      InterrogateFunction *function = new InterrogateFunction(def);
-      in >> index >> *function;
-      if (in.fail()) {
-        delete function;
-        return false;
-      }
-
-      add_function(index, function);
-      num_functions--;
-    }
-  }
-
-  { // Wrappers.
-    int num_wrappers;
-    in >> num_wrappers;
-    if (in.fail()) {
-      return false;
-    }
-
-    while (num_wrappers > 0) {
-      FunctionWrapperIndex index;
-      InterrogateFunctionWrapper wrapper(def);
-      in >> index >> wrapper;
-      if (in.fail()) {
-        return false;
-      }
-
-      add_wrapper(index, wrapper);
-      num_wrappers--;
-    }
-  }
-
-  { // Types.
-    int num_types;
-    in >> num_types;
-    if (in.fail()) {
-      return false;
-    }
-
-    while (num_types > 0) {
-      TypeIndex index;
-      InterrogateType type(def);
-      in >> index >> type;
-      if (in.fail()) {
-        return false;
-      }
-
-      add_type(index, type);
-      num_types--;
-
-      // Older versions of interrogate were not setting these flags.
-      const InterrogateType &itype = get_type(index);
-      FunctionIndex dtor = itype.get_destructor();
-      if (dtor != 0) {
-        update_function(dtor)._flags |= InterrogateFunction::F_destructor;
-      }
-      for (int i = 0; i < itype.number_of_constructors(); ++i) {
-        FunctionIndex ctor = itype.get_constructor(i);
-        update_function(ctor)._flags |= InterrogateFunction::F_constructor;
-      }
-    }
-  }
-
-  { // Manifests.
-    int num_manifests;
-    in >> num_manifests;
-    if (in.fail()) {
-      return false;
-    }
-
-    while (num_manifests > 0) {
-      ManifestIndex index;
-      InterrogateManifest manifest(def);
-      in >> index >> manifest;
-      if (in.fail()) {
-        return false;
-      }
-
-      add_manifest(index, manifest);
-      num_manifests--;
-    }
-  }
-
-  { // Elements.
-    int num_elements;
-    in >> num_elements;
-    if (in.fail()) {
-      return false;
-    }
-
-    while (num_elements > 0) {
-      ElementIndex index;
-      InterrogateElement element(def);
-      in >> index >> element;
-      if (in.fail()) {
-        return false;
-      }
-
-      add_element(index, element);
-      num_elements--;
-    }
-  }
-
-  { // MakeSeqs.
-    int num_make_seqs;
-    in >> num_make_seqs;
-    if (in.fail()) {
-      return false;
-    }
-
-    while (num_make_seqs > 0) {
-      MakeSeqIndex index;
-      InterrogateMakeSeq make_seq(def);
-      in >> index >> make_seq;
-      if (in.fail()) {
-        return false;
-      }
-
-      add_make_seq(index, make_seq);
-      num_make_seqs--;
-    }
-  }
-
-  return true;
-}
-
-/**
- * Copies all the data from the indicated database into this one.  It is an
- * error if any index numbers are shared between the two databases.
- */
-void InterrogateDatabase::
-merge_from(const InterrogateDatabase &other) {
-  // We want to collapse shared types together.
-  IndexRemapper remap;
-
-  // First, we need to build a set of types by name, so we know what types we
-  // already have.
-  map<string, TypeIndex> types_by_name;
-
-  TypeMap::const_iterator ti;
-  for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
-    const InterrogateType &type = (*ti).second;
-    if (type.has_true_name()) {
-      types_by_name[type.get_true_name()] = (*ti).first;
-    }
-  }
-
-  // Now go through the other set of types and determine the mapping into this
-  // set.
-  for (ti = other._type_map.begin(); ti != other._type_map.end(); ++ti) {
-    TypeIndex other_type_index = (*ti).first;
-    const InterrogateType &other_type = (*ti).second;
-
-    if (other_type.has_name()) {
-      map<string, TypeIndex>::iterator ni;
-      ni = types_by_name.find(other_type.get_true_name());
-      if (ni != types_by_name.end()) {
-        // Here's a type that we seem to have in common!  We'll have to merge
-        // them.
-        TypeIndex this_type_index = (*ni).second;
-        remap.add_mapping(other_type_index, this_type_index);
-      }
-    }
-  }
-
-  // Now that we know the full type-to-type mapping, we can copy the new
-  // types, one at a time.
-  for (ti = other._type_map.begin(); ti != other._type_map.end(); ++ti) {
-    TypeIndex other_type_index = (*ti).first;
-    const InterrogateType &other_type = (*ti).second;
-
-    if (!remap.in_map(other_type_index)) {
-      // Here's a new type.
-      add_type(other_type_index, other_type);
-      update_type(other_type_index).remap_indices(remap);
-
-    } else {
-      // Here's a type to merge.
-      TypeIndex this_type_index = remap.map_from(other_type_index);
-
-      InterrogateType &this_type = update_type(this_type_index);
-      if (!this_type.is_global() && other_type.is_global()) {
-        // If the type is about to become global, we need to add it to our
-        // global_types list.
-        _global_types.push_back(this_type_index);
-      }
-
-      InterrogateType merge_type = other_type;
-      merge_type.remap_indices(remap);
-      this_type.merge_with(merge_type);
-    }
-  }
-
-  // And copy all of the functions, wrappers, manifests, and elements.
-  FunctionMap::const_iterator fi;
-  for (fi = other._function_map.begin();
-       fi != other._function_map.end();
-       ++fi) {
-    FunctionIndex other_function_index = (*fi).first;
-    InterrogateFunction *other_function = (*fi).second;
-    add_function(other_function_index, other_function);
-    update_function(other_function_index).remap_indices(remap);
-  }
-
-  FunctionWrapperMap::const_iterator wi;
-  for (wi = other._wrapper_map.begin();
-       wi != other._wrapper_map.end();
-       ++wi) {
-    FunctionWrapperIndex other_wrapper_index = (*wi).first;
-    const InterrogateFunctionWrapper &other_wrapper = (*wi).second;
-    add_wrapper(other_wrapper_index, other_wrapper);
-    update_wrapper(other_wrapper_index).remap_indices(remap);
-  }
-
-  ManifestMap::const_iterator mi;
-  for (mi = other._manifest_map.begin();
-       mi != other._manifest_map.end();
-       ++mi) {
-    ManifestIndex other_manifest_index = (*mi).first;
-    const InterrogateManifest &other_manifest = (*mi).second;
-    add_manifest(other_manifest_index, other_manifest);
-    update_manifest(other_manifest_index).remap_indices(remap);
-  }
-
-  ElementMap::const_iterator ei;
-  for (ei = other._element_map.begin();
-       ei != other._element_map.end();
-       ++ei) {
-    ElementIndex other_element_index = (*ei).first;
-    const InterrogateElement &other_element = (*ei).second;
-    add_element(other_element_index, other_element);
-    update_element(other_element_index).remap_indices(remap);
-  }
-
-  MakeSeqMap::const_iterator si;
-  for (si = other._make_seq_map.begin();
-       si != other._make_seq_map.end();
-       ++si) {
-    MakeSeqIndex other_make_seq_index = (*si).first;
-    const InterrogateMakeSeq &other_make_seq = (*si).second;
-    add_make_seq(other_make_seq_index, other_make_seq);
-    update_make_seq(other_make_seq_index).remap_indices(remap);
-  }
-
-  _lookups_fresh = 0;
-}
-
-/**
- * Looks up the wrapper definition in the set of module defs that are loaded
- * in at runtime and represent the part of the interrogate database that's
- * compiled in.
- *
- * If the wrapper definition is not found, returns false.  If it is found,
- * returns true and sets def and module_index to the particular module and the
- * index within the module where the wrapper is defined.
- */
-bool InterrogateDatabase::
-find_module(FunctionWrapperIndex wrapper, InterrogateModuleDef *&def,
-            int &module_index) {
-  if (_modules.empty()) {
-    return false;
-  }
-
-  int mi = binary_search_module(0, _modules.size(), wrapper);
-  assert(mi >= 0 && mi < (int)_modules.size());
-  def = _modules[mi];
-  module_index = wrapper - def->first_index;
-
-  return (wrapper < def->next_index);
-}
-
-/**
- * Searches for the function module that includes the given function index by
- * binary search.
- */
-int InterrogateDatabase::
-binary_search_module(int begin, int end, FunctionIndex function) {
-  int mid = begin + (end - begin) / 2;
-  if (mid == begin) {
-    return mid;
-  }
-
-  int index = _modules[mid]->first_index;
-  if (index <= function) {
-    return binary_search_module(mid, end, function);
-
-  } else {
-    return binary_search_module(begin, mid, function);
-  }
-}
-
-/**
- * Searches for the particular function wrapper's hash name within a given
- * module.  Returns the index number local to the module, or -1 if it is not
- * found.
- */
-int InterrogateDatabase::
-binary_search_wrapper_hash(InterrogateUniqueNameDef *begin,
-                           InterrogateUniqueNameDef *end,
-                           const string &wrapper_hash_name) {
-  if (end <= begin) {
-    return -1;
-  }
-
-  InterrogateUniqueNameDef *mid = begin + (end - begin) / 2;
-  string name = mid->name;
-  if (name < wrapper_hash_name) {
-    return binary_search_wrapper_hash(mid, end, wrapper_hash_name);
-
-  } else if (wrapper_hash_name < name) {
-    return binary_search_wrapper_hash(begin, mid, wrapper_hash_name);
-
-  } else {
-    return mid->index_offset;
-  }
-}
-
-/**
- * Builds up the lookup of types by name.
- */
-void InterrogateDatabase::
-freshen_types_by_name() {
-  _types_by_name.clear();
-  TypeMap::const_iterator ti;
-  for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
-    _types_by_name[(*ti).second.get_name()] = (*ti).first;
-  }
-}
-
-/**
- * Builds up the lookup of types by scoped name.
- */
-void InterrogateDatabase::
-freshen_types_by_scoped_name() {
-  _types_by_scoped_name.clear();
-  TypeMap::const_iterator ti;
-  for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
-    _types_by_scoped_name[(*ti).second.get_scoped_name()] = (*ti).first;
-  }
-}
-
-/**
- * Builds up the lookup of types by true name.
- */
-void InterrogateDatabase::
-freshen_types_by_true_name() {
-  _types_by_true_name.clear();
-  TypeMap::const_iterator ti;
-  for (ti = _type_map.begin(); ti != _type_map.end(); ++ti) {
-    _types_by_true_name[(*ti).second.get_true_name()] = (*ti).first;
-  }
-}
-
-/**
- * Builds up the lookup of manifests by name.
- */
-void InterrogateDatabase::
-freshen_manifests_by_name() {
-  _manifests_by_name.clear();
-  ManifestMap::const_iterator ti;
-  for (ti = _manifest_map.begin(); ti != _manifest_map.end(); ++ti) {
-    _manifests_by_name[(*ti).second.get_name()] = (*ti).first;
-  }
-}
-
-/**
- * Builds up the lookup of elements by name.
- */
-void InterrogateDatabase::
-freshen_elements_by_name() {
-  _elements_by_name.clear();
-  ElementMap::const_iterator ti;
-  for (ti = _element_map.begin(); ti != _element_map.end(); ++ti) {
-    _elements_by_name[(*ti).second.get_name()] = (*ti).first;
-  }
-}
-
-/**
- * Builds up the lookup of elements by scoped name.
- */
-void InterrogateDatabase::
-freshen_elements_by_scoped_name() {
-  _elements_by_scoped_name.clear();
-  ElementMap::const_iterator ti;
-  for (ti = _element_map.begin(); ti != _element_map.end(); ++ti) {
-    _elements_by_scoped_name[(*ti).second.get_scoped_name()] = (*ti).first;
-  }
-}
-
-/**
- * Looks up a type, manifest, or element in the indicated lookup table by
- * name.  This is an internal support function.
- */
-int InterrogateDatabase::
-lookup(const string &name, Lookup &lookup, LookupType type,
-       void (InterrogateDatabase::*freshen)()) {
-  if ((_lookups_fresh & (int)type) == 0) {
-    // The lookup table isn't fresh; we need to freshen it.
-    (this->*freshen)();
-    _lookups_fresh |= (int)type;
-  }
-
-  Lookup::const_iterator li;
-  li = lookup.find(name);
-  if (li != lookup.end()) {
-    return (*li).second;
-  }
-  return 0;
-}

+ 0 - 205
dtool/src/interrogatedb/interrogateDatabase.h

@@ -1,205 +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 interrogateDatabase.h
- * @author drose
- * @date 2000-08-01
- */
-
-#ifndef INTERROGATEDATABASE_H
-#define INTERROGATEDATABASE_H
-
-#include "dtoolbase.h"
-
-#include "interrogate_interface.h"
-#include "interrogateType.h"
-#include "interrogateFunction.h"
-#include "interrogateFunctionWrapper.h"
-#include "interrogateManifest.h"
-#include "interrogateElement.h"
-#include "interrogateMakeSeq.h"
-#include "interrogate_request.h"
-
-#include <map>
-
-class IndexRemapper;
-
-/**
- * This stores all of the interrogate data and handles reading the data from a
- * disk file when necessary.
- */
-class EXPCL_INTERROGATEDB InterrogateDatabase {
-private:
-  InterrogateDatabase();
-
-public:
-  static InterrogateDatabase *get_ptr();
-  void request_module(InterrogateModuleDef *def);
-
-public:
-  // Functions to read the database.
-  bool get_error_flag();
-
-  int get_num_global_types();
-  TypeIndex get_global_type(int n);
-  int get_num_all_types();
-  TypeIndex get_all_type(int n);
-  int get_num_global_functions();
-  FunctionIndex get_global_function(int n);
-  int get_num_all_functions();
-  FunctionIndex get_all_function(int n);
-  int get_num_global_manifests();
-  ManifestIndex get_global_manifest(int n);
-  int get_num_global_elements();
-  ElementIndex get_global_element(int n);
-
-  const InterrogateType &get_type(TypeIndex type);
-  const InterrogateFunction &get_function(FunctionIndex function);
-  const InterrogateFunctionWrapper &get_wrapper(FunctionWrapperIndex wrapper);
-  const InterrogateManifest &get_manifest(ManifestIndex manifest);
-  const InterrogateElement &get_element(ElementIndex element);
-  const InterrogateMakeSeq &get_make_seq(MakeSeqIndex element);
-
-  INLINE TypeIndex lookup_type_by_name(const std::string &name);
-  INLINE TypeIndex lookup_type_by_scoped_name(const std::string &name);
-  INLINE TypeIndex lookup_type_by_true_name(const std::string &name);
-  INLINE ManifestIndex lookup_manifest_by_name(const std::string &name);
-  INLINE ElementIndex lookup_element_by_name(const std::string &name);
-  INLINE ElementIndex lookup_element_by_scoped_name(const std::string &name);
-
-  void remove_type(TypeIndex type);
-
-  void *get_fptr(FunctionWrapperIndex wrapper);
-
-  FunctionWrapperIndex get_wrapper_by_unique_name(const std::string &unique_name);
-
-  static int get_file_major_version();
-  static int get_file_minor_version();
-  static int get_current_major_version();
-  static int get_current_minor_version();
-
-public:
-  // Functions to build the database.
-  void set_error_flag(bool error_flag);
-
-  int get_next_index();
-  void add_type(TypeIndex index, const InterrogateType &type);
-  void add_function(FunctionIndex index, InterrogateFunction *function);
-  void add_wrapper(FunctionWrapperIndex index,
-                   const InterrogateFunctionWrapper &wrapper);
-  void add_manifest(ManifestIndex index, const InterrogateManifest &manifest);
-  void add_element(ElementIndex index, const InterrogateElement &element);
-  void add_make_seq(MakeSeqIndex index, const InterrogateMakeSeq &make_seq);
-
-  InterrogateType &update_type(TypeIndex type);
-  InterrogateFunction &update_function(FunctionIndex function);
-  InterrogateFunctionWrapper &update_wrapper(FunctionWrapperIndex wrapper);
-  InterrogateManifest &update_manifest(ManifestIndex manifest);
-  InterrogateElement &update_element(ElementIndex element);
-  InterrogateMakeSeq &update_make_seq(MakeSeqIndex make_seq);
-
-  int remap_indices(int first_index);
-  int remap_indices(int first_index, IndexRemapper &remap);
-
-  void write(std::ostream &out, InterrogateModuleDef *def) const;
-  bool read(std::istream &in, InterrogateModuleDef *def);
-
-private:
-  INLINE void check_latest();
-  void load_latest();
-
-  bool read_new(std::istream &in, InterrogateModuleDef *def);
-  void merge_from(const InterrogateDatabase &other);
-
-  bool find_module(FunctionWrapperIndex wrapper,
-                   InterrogateModuleDef *&def, int &module_index);
-  int binary_search_module(int begin, int end, FunctionIndex function);
-  int binary_search_wrapper_hash(InterrogateUniqueNameDef *begin,
-                                 InterrogateUniqueNameDef *end,
-                                 const std::string &wrapper_hash_name);
-
-  // This data is loaded from the various database files.
-  typedef std::map<TypeIndex, InterrogateType> TypeMap;
-  TypeMap _type_map;
-  typedef std::map<FunctionIndex, InterrogateFunction *> FunctionMap;
-  FunctionMap _function_map;
-  typedef std::map<FunctionWrapperIndex, InterrogateFunctionWrapper> FunctionWrapperMap;
-  FunctionWrapperMap _wrapper_map;
-
-  typedef std::map<ManifestIndex, InterrogateManifest> ManifestMap;
-  ManifestMap _manifest_map;
-  typedef std::map<ElementIndex, InterrogateElement> ElementMap;
-  ElementMap _element_map;
-
-  typedef std::map<MakeSeqIndex, InterrogateMakeSeq> MakeSeqMap;
-  MakeSeqMap _make_seq_map;
-
-  typedef std::vector<TypeIndex> GlobalTypes;
-  GlobalTypes _global_types;
-  GlobalTypes _all_types;
-  typedef std::vector<FunctionIndex> GlobalFunctions;
-  GlobalFunctions _global_functions;
-  GlobalFunctions _all_functions;
-  typedef std::vector<ManifestIndex> GlobalManifests;
-  GlobalManifests _global_manifests;
-  typedef std::vector<ElementIndex> GlobalElements;
-  GlobalElements _global_elements;
-
-  // This data is compiled in directly to the shared libraries that we link
-  // with.
-  typedef std::vector<InterrogateModuleDef *> Modules;
-  Modules _modules;
-  typedef std::map<std::string, InterrogateModuleDef *> ModulesByHash;
-  ModulesByHash _modules_by_hash;
-
-  // This records the set of database files that are still to be loaded.
-  typedef std::vector<InterrogateModuleDef *> Requests;
-  Requests _requests;
-
-  bool _error_flag;
-  int _next_index;
-
-  enum LookupType {
-    LT_type_name           = 0x001,
-    LT_type_scoped_name    = 0x002,
-    LT_type_true_name      = 0x004,
-    LT_manifest_name       = 0x008,
-    LT_element_name        = 0x010,
-    LT_element_scoped_name = 0x020,
-  };
-
-  int _lookups_fresh;
-  typedef std::map<std::string, int> Lookup;
-  Lookup _types_by_name;
-  Lookup _types_by_scoped_name;
-  Lookup _types_by_true_name;
-  Lookup _manifests_by_name;
-  Lookup _elements_by_name;
-  Lookup _elements_by_scoped_name;
-
-  void freshen_types_by_name();
-  void freshen_types_by_scoped_name();
-  void freshen_types_by_true_name();
-  void freshen_manifests_by_name();
-  void freshen_elements_by_name();
-  void freshen_elements_by_scoped_name();
-
-  int lookup(const std::string &name,
-             Lookup &lookup, LookupType type,
-             void (InterrogateDatabase::*freshen)());
-
-  static InterrogateDatabase *_global_ptr;
-  static int _file_major_version;
-  static int _file_minor_version;
-  static int _current_major_version;
-  static int _current_minor_version;
-};
-
-#include "interrogateDatabase.I"
-
-#endif

+ 0 - 259
dtool/src/interrogatedb/interrogateElement.I

@@ -1,259 +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 interrogateElement.I
- * @author drose
- * @date 2000-08-11
- */
-
-/**
- *
- */
-INLINE InterrogateElement::
-InterrogateElement(InterrogateModuleDef *def) :
-  InterrogateComponent(def)
-{
-  _flags = 0;
-  _type = 0;
-  _getter = 0;
-  _setter = 0;
-  _has_function = 0;
-  _clear_function = 0;
-  _del_function = 0;
-  _insert_function = 0;
-  _getkey_function = 0;
-  _length_function = 0;
-  _make_property = nullptr;
-}
-
-/**
- *
- */
-INLINE InterrogateElement::
-InterrogateElement(const InterrogateElement &copy) {
-  (*this) = copy;
-}
-
-/**
- *
- */
-INLINE void InterrogateElement::
-operator = (const InterrogateElement &copy) {
-  InterrogateComponent::operator = (copy);
-  _flags = copy._flags;
-  _scoped_name = copy._scoped_name;
-  _comment = copy._comment;
-  _type = copy._type;
-  _getter = copy._getter;
-  _setter = copy._setter;
-  _has_function = copy._has_function;
-  _clear_function = copy._clear_function;
-  _del_function = copy._del_function;
-  _insert_function = copy._insert_function;
-  _getkey_function = copy._getkey_function;
-  _length_function = copy._length_function;
-  _make_property = copy._make_property;
-}
-
-/**
- * Returns true if the element is marked as 'global'. This means only that it
- * should appear in the global element list.
- */
-INLINE bool InterrogateElement::
-is_global() const {
-  return (_flags & F_global) != 0;
-}
-
-/**
- *
- */
-INLINE bool InterrogateElement::
-has_scoped_name() const {
-  return !_scoped_name.empty();
-}
-
-/**
- *
- */
-INLINE const std::string &InterrogateElement::
-get_scoped_name() const {
-  return _scoped_name;
-}
-
-/**
- *
- */
-INLINE bool InterrogateElement::
-has_comment() const {
-  return !_comment.empty();
-}
-
-/**
- *
- */
-INLINE const std::string &InterrogateElement::
-get_comment() const {
-  return _comment;
-}
-
-/**
- *
- */
-INLINE TypeIndex InterrogateElement::
-get_type() const {
-  return _type;
-}
-
-/**
- *
- */
-INLINE bool InterrogateElement::
-has_getter() const {
-  return (_flags & F_has_getter) != 0;
-}
-
-/**
- *
- */
-INLINE FunctionIndex InterrogateElement::
-get_getter() const {
-  return _getter;
-}
-
-/**
- *
- */
-INLINE bool InterrogateElement::
-has_setter() const {
-  return (_flags & F_has_setter) != 0;
-}
-
-/**
- *
- */
-INLINE FunctionIndex InterrogateElement::
-get_setter() const {
-  return _setter;
-}
-
-/**
- *
- */
-INLINE bool InterrogateElement::
-has_has_function() const {
-  return (_flags & F_has_has_function) != 0;
-}
-
-/**
- *
- */
-INLINE FunctionIndex InterrogateElement::
-get_has_function() const {
-  return _has_function;
-}
-
-/**
- *
- */
-INLINE bool InterrogateElement::
-has_clear_function() const {
-  return (_flags & F_has_clear_function) != 0;
-}
-
-/**
- *
- */
-INLINE FunctionIndex InterrogateElement::
-get_clear_function() const {
-  return _clear_function;
-}
-
-/**
- *
- */
-INLINE bool InterrogateElement::
-has_del_function() const {
-  return (_flags & F_has_del_function) != 0;
-}
-
-/**
- *
- */
-INLINE FunctionIndex InterrogateElement::
-get_del_function() const {
-  return _del_function;
-}
-
-/**
- *
- */
-INLINE bool InterrogateElement::
-has_insert_function() const {
-  return (_flags & F_has_insert_function) != 0;
-}
-
-/**
- *
- */
-INLINE FunctionIndex InterrogateElement::
-get_insert_function() const {
-  return _insert_function;
-}
-
-/**
- *
- */
-INLINE bool InterrogateElement::
-has_getkey_function() const {
-  return (_flags & F_has_getkey_function) != 0;
-}
-
-/**
- *
- */
-INLINE FunctionIndex InterrogateElement::
-get_getkey_function() const {
-  return _getkey_function;
-}
-
-/**
- *
- */
-INLINE bool InterrogateElement::
-is_sequence() const {
-  return (_flags & F_sequence) != 0;
-}
-
-/**
- *
- */
-INLINE FunctionIndex InterrogateElement::
-get_length_function() const {
-  return _length_function;
-}
-
-/**
- *
- */
-INLINE bool InterrogateElement::
-is_mapping() const {
-  return (_flags & F_mapping) != 0;
-}
-
-
-INLINE std::ostream &
-operator << (std::ostream &out, const InterrogateElement &element) {
-  element.output(out);
-  return out;
-}
-
-INLINE std::istream &
-operator >> (std::istream &in, InterrogateElement &element) {
-  element.input(in);
-  return in;
-}

+ 0 - 74
dtool/src/interrogatedb/interrogateElement.cxx

@@ -1,74 +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 interrogateElement.cxx
- * @author drose
- * @date 2000-08-11
- */
-
-#include "interrogateElement.h"
-#include "interrogateDatabase.h"
-#include "indexRemapper.h"
-#include "interrogate_datafile.h"
-
-/**
- * Formats the InterrogateElement data for output to a data file.
- */
-void InterrogateElement::
-output(std::ostream &out) const {
-  InterrogateComponent::output(out);
-  out << _flags << " "
-      << _type << " "
-      << _getter << " "
-      << _setter << " "
-      << _has_function << " "
-      << _clear_function << " "
-      << _del_function << " "
-      << _length_function << " "
-      << _insert_function << " "
-      << _getkey_function << " ";
-  idf_output_string(out, _scoped_name);
-  idf_output_string(out, _comment, '\n');
-}
-
-/**
- * Reads the data file as previously formatted by output().
- */
-void InterrogateElement::
-input(std::istream &in) {
-  InterrogateComponent::input(in);
-  in >> _flags >> _type >> _getter >> _setter;
-  if (InterrogateDatabase::get_file_minor_version() >= 1) {
-    in >> _has_function >> _clear_function;
-    if (InterrogateDatabase::get_file_minor_version() >= 2) {
-      in >> _del_function >> _length_function;
-      if (InterrogateDatabase::get_file_minor_version() >= 3) {
-        in >> _insert_function >> _getkey_function;
-      }
-    }
-  }
-  idf_input_string(in, _scoped_name);
-  idf_input_string(in, _comment);
-}
-
-/**
- * Remaps all internal index numbers according to the indicated map.  This
- * called from InterrogateDatabase::remap_indices().
- */
-void InterrogateElement::
-remap_indices(const IndexRemapper &remap) {
-  _type = remap.map_from(_type);
-  _getter = remap.map_from(_getter);
-  _setter = remap.map_from(_setter);
-  _has_function = remap.map_from(_has_function);
-  _clear_function = remap.map_from(_clear_function);
-  _del_function = remap.map_from(_del_function);
-  _insert_function = remap.map_from(_insert_function);
-  _getkey_function = remap.map_from(_getkey_function);
-  _length_function = remap.map_from(_length_function);
-}

+ 0 - 103
dtool/src/interrogatedb/interrogateElement.h

@@ -1,103 +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 interrogateElement.h
- * @author drose
- * @date 2000-08-11
- */
-
-#ifndef INTERROGATEELEMENT_H
-#define INTERROGATEELEMENT_H
-
-#include "dtoolbase.h"
-
-#include "interrogateComponent.h"
-
-class IndexRemapper;
-class CPPMakeProperty;
-
-/**
- * An internal representation of a data element, like a data member or a
- * global variable.
- */
-class EXPCL_INTERROGATEDB InterrogateElement : public InterrogateComponent {
-public:
-  INLINE InterrogateElement(InterrogateModuleDef *def = nullptr);
-  INLINE InterrogateElement(const InterrogateElement &copy);
-  INLINE void operator = (const InterrogateElement &copy);
-
-  INLINE bool is_global() const;
-
-  INLINE bool has_scoped_name() const;
-  INLINE const std::string &get_scoped_name() const;
-
-  INLINE bool has_comment() const;
-  INLINE const std::string &get_comment() const;
-
-  INLINE TypeIndex get_type() const;
-  INLINE bool has_getter() const;
-  INLINE FunctionIndex get_getter() const;
-  INLINE bool has_setter() const;
-  INLINE FunctionIndex get_setter() const;
-  INLINE bool has_has_function() const;
-  INLINE FunctionIndex get_has_function() const;
-  INLINE bool has_clear_function() const;
-  INLINE FunctionIndex get_clear_function() const;
-  INLINE bool has_del_function() const;
-  INLINE FunctionIndex get_del_function() const;
-  INLINE bool has_insert_function() const;
-  INLINE FunctionIndex get_insert_function() const;
-  INLINE bool has_getkey_function() const;
-  INLINE FunctionIndex get_getkey_function() const;
-  INLINE bool is_sequence() const;
-  INLINE FunctionIndex get_length_function() const;
-  INLINE bool is_mapping() const;
-
-  void output(std::ostream &out) const;
-  void input(std::istream &in);
-
-  void remap_indices(const IndexRemapper &remap);
-
-private:
-  enum Flags {
-    F_global          = 0x0001,
-    F_has_getter      = 0x0002,
-    F_has_setter      = 0x0004,
-    F_has_has_function= 0x0008,
-    F_has_clear_function= 0x0010,
-    F_has_del_function= 0x0020,
-    F_sequence        = 0x0040,
-    F_mapping         = 0x0080,
-    F_has_insert_function= 0x0100,
-    F_has_getkey_function= 0x0200,
-  };
-
-  int _flags;
-  std::string _scoped_name;
-  std::string _comment;
-  TypeIndex _type;
-  FunctionIndex _length_function;
-  FunctionIndex _getter;
-  FunctionIndex _setter;
-  FunctionIndex _has_function;
-  FunctionIndex _clear_function;
-  FunctionIndex _del_function;
-  FunctionIndex _insert_function;
-  FunctionIndex _getkey_function;
-
-  CPPMakeProperty *_make_property;
-
-  friend class InterrogateBuilder;
-};
-
-INLINE std::ostream &operator << (std::ostream &out, const InterrogateElement &element);
-INLINE std::istream &operator >> (std::istream &in, InterrogateElement &element);
-
-#include "interrogateElement.I"
-
-#endif

+ 0 - 178
dtool/src/interrogatedb/interrogateFunction.I

@@ -1,178 +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 interrogateFunction.I
- * @author drose
- * @date 2000-08-01
- */
-
-/**
- * Returns true if the function is marked as 'global'. This means only that it
- * should appear in the global function list.
- */
-INLINE bool InterrogateFunction::
-is_global() const {
-  return (_flags & F_global) != 0;
-}
-
-/**
- * Returns true if the function is virtual, for whatever that's worth.
- */
-INLINE bool InterrogateFunction::
-is_virtual() const {
-  return (_flags & F_virtual) != 0;
-}
-
-/**
- * Returns true if the function is a class method.
- */
-INLINE bool InterrogateFunction::
-is_method() const {
-  return (_flags & F_method) != 0;
-}
-
-/**
- * Returns true if the function is flagged as a special unary operator, like
- * operator -() with no parameters.
- */
-INLINE bool InterrogateFunction::
-is_unary_op() const {
-  return (_flags & F_unary_op) != 0;
-}
-
-/**
- * Returns true if the function is a special typecast operator, like operator
- * bool().
- */
-INLINE bool InterrogateFunction::
-is_operator_typecast() const {
-  return (_flags & F_operator_typecast) != 0;
-}
-
-/**
- * Returns true if the function is a constructor.
- */
-INLINE bool InterrogateFunction::
-is_constructor() const {
-  return (_flags & F_constructor) != 0;
-}
-
-/**
- * Returns true if the function is a destructor.
- */
-INLINE bool InterrogateFunction::
-is_destructor() const {
-  return (_flags & F_destructor) != 0;
-}
-
-/**
- * Return the class that owns the method, if is_method() returns true.
- */
-INLINE TypeIndex InterrogateFunction::
-get_class() const {
-  return _class;
-}
-
-/**
- *
- */
-INLINE bool InterrogateFunction::
-has_scoped_name() const {
-  return !_scoped_name.empty();
-}
-
-/**
- *
- */
-INLINE const std::string &InterrogateFunction::
-get_scoped_name() const {
-  return _scoped_name;
-}
-
-/**
- *
- */
-INLINE bool InterrogateFunction::
-has_comment() const {
-  return !_comment.empty();
-}
-
-/**
- *
- */
-INLINE const std::string &InterrogateFunction::
-get_comment() const {
-  return _comment;
-}
-
-/**
- *
- */
-INLINE bool InterrogateFunction::
-has_prototype() const {
-  return !_prototype.empty();
-}
-
-/**
- *
- */
-INLINE const std::string &InterrogateFunction::
-get_prototype() const {
-  return _prototype;
-}
-
-/**
- *
- */
-INLINE int InterrogateFunction::
-number_of_c_wrappers() const {
-  return _c_wrappers.size();
-}
-
-/**
- *
- */
-INLINE FunctionWrapperIndex InterrogateFunction::
-get_c_wrapper(int n) const {
-  if (n >= 0 && n < (int)_c_wrappers.size()) {
-    return _c_wrappers[n];
-  }
-  return 0;
-}
-
-/**
- *
- */
-INLINE int InterrogateFunction::
-number_of_python_wrappers() const {
-  return _python_wrappers.size();
-}
-
-/**
- *
- */
-INLINE FunctionWrapperIndex InterrogateFunction::
-get_python_wrapper(int n) const {
-  if (n >= 0 && n < (int)_python_wrappers.size()) {
-    return _python_wrappers[n];
-  }
-  return 0;
-}
-
-
-INLINE std::ostream &
-operator << (std::ostream &out, const InterrogateFunction &function) {
-  function.output(out);
-  return out;
-}
-
-INLINE std::istream &
-operator >> (std::istream &in, InterrogateFunction &function) {
-  function.input(in);
-  return in;
-}

+ 0 - 100
dtool/src/interrogatedb/interrogateFunction.cxx

@@ -1,100 +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 interrogateFunction.cxx
- * @author drose
- * @date 2000-08-01
- */
-
-#include "interrogateFunction.h"
-#include "indexRemapper.h"
-#include "interrogate_datafile.h"
-#include "interrogateDatabase.h"
-
-/**
- *
- */
-InterrogateFunction::
-InterrogateFunction(InterrogateModuleDef *def) :
-  InterrogateComponent(def)
-{
-  _flags = 0;
-  _class = 0;
-  _instances = nullptr;
-}
-
-/**
- *
- */
-InterrogateFunction::
-InterrogateFunction(const InterrogateFunction &copy) {
-  (*this) = copy;
-}
-
-/**
- *
- */
-void InterrogateFunction::
-operator = (const InterrogateFunction &copy) {
-  InterrogateComponent::operator = (copy);
-  _flags = copy._flags;
-  _scoped_name = copy._scoped_name;
-  _comment = copy._comment;
-  _prototype = copy._prototype;
-  _class = copy._class;
-  _c_wrappers = copy._c_wrappers;
-  _python_wrappers = copy._python_wrappers;
-
-  _instances = copy._instances;
-  _expression = copy._expression;
-}
-
-/**
- * Formats the InterrogateFunction data for output to a data file.
- */
-void InterrogateFunction::
-output(std::ostream &out) const {
-  InterrogateComponent::output(out);
-  out << _flags << " "
-      << _class << " ";
-  idf_output_string(out, _scoped_name);
-  idf_output_vector(out, _c_wrappers);
-  idf_output_vector(out, _python_wrappers);
-  idf_output_string(out, _comment, '\n');
-  idf_output_string(out, _prototype, '\n');
-}
-
-/**
- * Reads the data file as previously formatted by output().
- */
-void InterrogateFunction::
-input(std::istream &in) {
-  InterrogateComponent::input(in);
-  in >> _flags >> _class;
-  idf_input_string(in, _scoped_name);
-  idf_input_vector(in, _c_wrappers);
-  idf_input_vector(in, _python_wrappers);
-  idf_input_string(in, _comment);
-  idf_input_string(in, _prototype);
-}
-
-/**
- * Remaps all internal index numbers according to the indicated map.  This
- * called from InterrogateDatabase::remap_indices().
- */
-void InterrogateFunction::
-remap_indices(const IndexRemapper &remap) {
-  _class = remap.map_from(_class);
-  Wrappers::iterator wi;
-  for (wi = _c_wrappers.begin(); wi != _c_wrappers.end(); ++wi) {
-    (*wi) = remap.map_from(*wi);
-  }
-  for (wi = _python_wrappers.begin(); wi != _python_wrappers.end(); ++wi) {
-    (*wi) = remap.map_from(*wi);
-  }
-}

+ 0 - 117
dtool/src/interrogatedb/interrogateFunction.h

@@ -1,117 +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 interrogateFunction.h
- * @author drose
- * @date 2000-08-01
- */
-
-#ifndef INTERROGATEFUNCTION_H
-#define INTERROGATEFUNCTION_H
-
-#include "dtoolbase.h"
-
-#include "interrogateComponent.h"
-
-#include <vector>
-#include <map>
-
-class IndexRemapper;
-class CPPInstance;
-
-/**
- * An internal representation of a function.
- */
-class EXPCL_INTERROGATEDB InterrogateFunction : public InterrogateComponent {
-public:
-  InterrogateFunction(InterrogateModuleDef *def = nullptr);
-  InterrogateFunction(const InterrogateFunction &copy);
-  void operator = (const InterrogateFunction &copy);
-
-  INLINE bool is_global() const;
-  INLINE bool is_virtual() const;
-  INLINE bool is_method() const;
-  INLINE bool is_unary_op() const;
-  INLINE bool is_operator_typecast() const;
-  INLINE bool is_constructor() const;
-  INLINE bool is_destructor() const;
-  INLINE TypeIndex get_class() const;
-
-  INLINE bool has_scoped_name() const;
-  INLINE const std::string &get_scoped_name() const;
-
-  INLINE bool has_comment() const;
-  INLINE const std::string &get_comment() const;
-
-  INLINE bool has_prototype() const;
-  INLINE const std::string &get_prototype() const;
-
-  INLINE int number_of_c_wrappers() const;
-  INLINE FunctionWrapperIndex get_c_wrapper(int n) const;
-
-  INLINE int number_of_python_wrappers() const;
-  INLINE FunctionWrapperIndex get_python_wrapper(int n) const;
-
-  void output(std::ostream &out) const;
-  void input(std::istream &in);
-
-  void remap_indices(const IndexRemapper &remap);
-
-private:
-  enum Flags {
-    F_global          = 0x0001,
-    F_virtual         = 0x0002,
-    F_method          = 0x0004,
-    F_typecast        = 0x0008,
-    F_getter          = 0x0010,
-    F_setter          = 0x0020,
-    F_unary_op        = 0x0040,
-    F_operator_typecast = 0x0080,
-    F_constructor     = 0x0100,
-    F_destructor      = 0x0200,
-    F_item_assignment = 0x0400,
-  };
-
-  int _flags;
-  std::string _scoped_name;
-  std::string _comment;
-  std::string _prototype;
-  TypeIndex _class;
-
-  typedef std::vector<FunctionWrapperIndex> Wrappers;
-  Wrappers _c_wrappers;
-  Wrappers _python_wrappers;
-
-public:
-  // The rest of the members in this class aren't part of the public interface
-  // to interrogate, but are used internally as the interrogate database is
-  // built.  They are valid only during the session of interrogate that
-  // generates the database, and will not be filled in when the database is
-  // reloaded from disk.
-
-  // This must be a pointer, rather than a concrete map, so we don't risk
-  // trying to create a map in one DLL and access it in another.  Silly
-  // Windows.
-  typedef std::map<std::string, CPPInstance *> Instances;
-  Instances *_instances;
-  std::string _expression;
-
-  friend class InterrogateBuilder;
-  friend class InterrogateDatabase;
-  friend class InterfaceMakerC;
-  friend class InterfaceMakerPythonSimple;
-  friend class InterfaceMakerPythonNative;
-  friend class FunctionRemap;
-};
-
-INLINE std::ostream &operator << (std::ostream &out, const InterrogateFunction &function);
-INLINE std::istream &operator >> (std::istream &in, InterrogateFunction &function);
-
-#include "interrogateFunction.I"
-
-#endif

+ 0 - 240
dtool/src/interrogatedb/interrogateFunctionWrapper.I

@@ -1,240 +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 interrogateFunctionWrapper.I
- * @author drose
- * @date 2000-08-06
- */
-
-/**
- *
- */
-INLINE InterrogateFunctionWrapper::
-InterrogateFunctionWrapper(InterrogateModuleDef *def) :
-  InterrogateComponent(def)
-{
-  _flags = 0;
-  _function = 0;
-  _return_type = 0;
-  _return_value_destructor = 0;
-}
-
-/**
- *
- */
-INLINE InterrogateFunctionWrapper::
-InterrogateFunctionWrapper(const InterrogateFunctionWrapper &copy) {
-  (*this) = copy;
-}
-
-/**
- *
- */
-INLINE void InterrogateFunctionWrapper::
-operator = (const InterrogateFunctionWrapper &copy) {
-  InterrogateComponent::operator = (copy);
-  _flags = copy._flags;
-  _function = copy._function;
-  _return_type = copy._return_type;
-  _return_value_destructor = copy._return_value_destructor;
-  _unique_name = copy._unique_name;
-  _comment = copy._comment;
-  _parameters = copy._parameters;
-}
-
-/**
- * Returns the FunctionIndex of the function that this wrapper corresponds to.
- */
-INLINE FunctionIndex InterrogateFunctionWrapper::
-get_function() const {
-  return _function;
-}
-
-/**
- *
- */
-INLINE bool InterrogateFunctionWrapper::
-is_callable_by_name() const {
-  return (_flags & F_callable_by_name) != 0;
-}
-
-/**
- * @since 1.10.13
- */
-INLINE bool InterrogateFunctionWrapper::
-is_copy_constructor() const {
-  return (_flags & F_copy_constructor) != 0;
-}
-
-/**
- * @since 1.10.13
- */
-INLINE bool InterrogateFunctionWrapper::
-is_coerce_constructor() const {
-  return (_flags & F_coerce_constructor) != 0;
-}
-
-/**
- * @since 1.10.13
- */
-INLINE bool InterrogateFunctionWrapper::
-is_extension() const {
-  return (_flags & F_extension) != 0;
-}
-
-/**
- * @since 1.11.0
- */
-INLINE bool InterrogateFunctionWrapper::
-is_deprecated() const {
-  return (_flags & F_deprecated) != 0;
-}
-
-/**
- *
- */
-INLINE bool InterrogateFunctionWrapper::
-has_return_value() const {
-  return (_flags & F_has_return) != 0;
-}
-
-/**
- *
- */
-INLINE TypeIndex InterrogateFunctionWrapper::
-get_return_type() const {
-  return _return_type;
-}
-
-/**
- *
- */
-INLINE bool InterrogateFunctionWrapper::
-caller_manages_return_value() const {
-  return (_flags & F_caller_manages) != 0;
-}
-
-/**
- *
- */
-INLINE FunctionIndex InterrogateFunctionWrapper::
-get_return_value_destructor() const {
-  return _return_value_destructor;
-}
-
-/**
- *
- */
-INLINE int InterrogateFunctionWrapper::
-number_of_parameters() const {
-  return _parameters.size();
-}
-
-/**
- *
- */
-INLINE TypeIndex InterrogateFunctionWrapper::
-parameter_get_type(int n) const {
-  if (n >= 0 && n < (int)_parameters.size()) {
-    return _parameters[n]._type;
-  }
-  return 0;
-}
-
-/**
- *
- */
-INLINE bool InterrogateFunctionWrapper::
-parameter_has_name(int n) const {
-  if (n >= 0 && n < (int)_parameters.size()) {
-    return (_parameters[n]._parameter_flags & PF_has_name) != 0;
-  }
-  return false;
-}
-
-/**
- *
- */
-INLINE const std::string &InterrogateFunctionWrapper::
-parameter_get_name(int n) const {
-  static std::string bogus_string;
-  if (n >= 0 && n < (int)_parameters.size()) {
-    return _parameters[n]._name;
-  }
-  return bogus_string;
-}
-
-/**
- *
- */
-INLINE bool InterrogateFunctionWrapper::
-parameter_is_this(int n) const {
-  if (n >= 0 && n < (int)_parameters.size()) {
-    return (_parameters[n]._parameter_flags & PF_is_this) != 0;
-  }
-  return false;
-}
-
-/**
- *
- */
-INLINE bool InterrogateFunctionWrapper::
-parameter_is_optional(int n) const {
-  if (n >= 0 && n < (int)_parameters.size()) {
-    return (_parameters[n]._parameter_flags & PF_is_optional) != 0;
-  }
-  return false;
-}
-
-/**
- *
- */
-INLINE const std::string &InterrogateFunctionWrapper::
-get_unique_name() const {
-  return _unique_name;
-}
-
-/**
- *
- */
-INLINE bool InterrogateFunctionWrapper::
-has_comment() const {
-  return !_comment.empty();
-}
-
-/**
- *
- */
-INLINE const std::string &InterrogateFunctionWrapper::
-get_comment() const {
-  return _comment;
-}
-
-INLINE std::ostream &
-operator << (std::ostream &out, const InterrogateFunctionWrapper &wrapper) {
-  wrapper.output(out);
-  return out;
-}
-
-INLINE std::istream &
-operator >> (std::istream &in, InterrogateFunctionWrapper &wrapper) {
-  wrapper.input(in);
-  return in;
-}
-
-INLINE std::ostream &
-operator << (std::ostream &out, const InterrogateFunctionWrapper::Parameter &p) {
-  p.output(out);
-  return out;
-}
-
-INLINE std::istream &
-operator >> (std::istream &in, InterrogateFunctionWrapper::Parameter &p) {
-  p.input(in);
-  return in;
-}

+ 0 - 84
dtool/src/interrogatedb/interrogateFunctionWrapper.cxx

@@ -1,84 +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 interrogateFunctionWrapper.cxx
- * @author drose
- * @date 2000-08-06
- */
-
-#include "interrogateFunctionWrapper.h"
-#include "indexRemapper.h"
-#include "interrogate_datafile.h"
-
-#include <algorithm>
-
-using std::istream;
-using std::ostream;
-
-/**
- *
- */
-void InterrogateFunctionWrapper::Parameter::
-output(ostream &out) const {
-  idf_output_string(out, _name);
-  out << _parameter_flags << " " << _type << " ";
-}
-
-/**
- *
- */
-void InterrogateFunctionWrapper::Parameter::
-input(istream &in) {
-  idf_input_string(in, _name);
-  in >> _parameter_flags >> _type;
-}
-
-/**
- * Formats the InterrogateFunctionWrapper data for output to a data file.
- */
-void InterrogateFunctionWrapper::
-output(ostream &out) const {
-  InterrogateComponent::output(out);
-  out << _flags << " "
-      << _function << " "
-      << _return_type << " "
-      << _return_value_destructor << " ";
-  idf_output_string(out, _unique_name);
-  idf_output_string(out, _comment);
-  idf_output_vector(out, _parameters);
-}
-
-/**
- * Reads the data file as previously formatted by output().
- */
-void InterrogateFunctionWrapper::
-input(istream &in) {
-  InterrogateComponent::input(in);
-  in >> _flags
-     >> _function
-     >> _return_type
-     >> _return_value_destructor;
-  idf_input_string(in, _unique_name);
-  idf_input_string(in, _comment);
-  idf_input_vector(in, _parameters);
-}
-
-/**
- * Remaps all internal index numbers according to the indicated map.  This
- * called from InterrogateDatabase::remap_indices().
- */
-void InterrogateFunctionWrapper::
-remap_indices(const IndexRemapper &remap) {
-  _return_value_destructor = remap.map_from(_return_value_destructor);
-  _return_type = remap.map_from(_return_type);
-
-  Parameters::iterator pi;
-  for (pi = _parameters.begin(); pi != _parameters.end(); ++pi) {
-    (*pi)._type = remap.map_from((*pi)._type);
-  }
-}

+ 0 - 118
dtool/src/interrogatedb/interrogateFunctionWrapper.h

@@ -1,118 +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 interrogateFunctionWrapper.h
- * @author drose
- * @date 2000-08-06
- */
-
-#ifndef INTERROGATEFUNCTIONWRAPPER_H
-#define INTERROGATEFUNCTIONWRAPPER_H
-
-#include "dtoolbase.h"
-
-#include "interrogateComponent.h"
-
-#include <vector>
-
-class IndexRemapper;
-
-/**
- * An internal representation of a callable function.
- */
-class EXPCL_INTERROGATEDB InterrogateFunctionWrapper : public InterrogateComponent {
-public:
-  INLINE InterrogateFunctionWrapper(InterrogateModuleDef *def = nullptr);
-  INLINE InterrogateFunctionWrapper(const InterrogateFunctionWrapper &copy);
-  INLINE void operator = (const InterrogateFunctionWrapper &copy);
-
-  INLINE FunctionIndex get_function() const;
-
-  INLINE bool is_callable_by_name() const;
-  INLINE bool is_copy_constructor() const;
-  INLINE bool is_coerce_constructor() const;
-  INLINE bool is_extension() const;
-  INLINE bool is_deprecated() const;
-
-  INLINE bool has_return_value() const;
-  INLINE TypeIndex get_return_type() const;
-  INLINE bool caller_manages_return_value() const;
-  INLINE FunctionIndex get_return_value_destructor() const;
-
-  INLINE int number_of_parameters() const;
-  INLINE TypeIndex parameter_get_type(int n) const;
-  INLINE bool parameter_has_name(int n) const;
-  INLINE const std::string &parameter_get_name(int n) const;
-  INLINE bool parameter_is_this(int n) const;
-  INLINE bool parameter_is_optional(int n) const;
-
-  INLINE const std::string &get_unique_name() const;
-
-  INLINE bool has_comment() const;
-  INLINE const std::string &get_comment() const;
-
-  void output(std::ostream &out) const;
-  void input(std::istream &in);
-
-  void remap_indices(const IndexRemapper &remap);
-
-private:
-  enum Flags {
-    F_caller_manages   = 0x0001,
-    F_has_return       = 0x0002,
-    F_callable_by_name = 0x0004,
-    F_copy_constructor = 0x0008,
-    F_coerce_constructor = 0x0010,
-    F_extension        = 0x0020,
-    F_deprecated       = 0x0040,
-  };
-
-  enum ParameterFlags {
-    PF_has_name       = 0x0001,
-    PF_is_this        = 0x0002,
-    PF_is_optional    = 0x0004,
-  };
-
-  int _flags;
-  FunctionIndex _function;
-  TypeIndex _return_type;
-  FunctionIndex _return_value_destructor;
-  std::string _unique_name;
-  std::string _comment;
-
-public:
-  // This nested class must be declared public just so we can declare the
-  // external ostream and istream IO operator functions, on the SGI compiler.
-  // Arguably a compiler bug, but what can you do.
-  class Parameter {
-  public:
-    void output(std::ostream &out) const;
-    void input(std::istream &in);
-
-    int _parameter_flags;
-    TypeIndex _type;
-    std::string _name;
-  };
-
-private:
-  typedef std::vector<Parameter> Parameters;
-  Parameters _parameters;
-
-  friend class InterrogateBuilder;
-  friend class FunctionRemap;
-};
-
-INLINE std::ostream &operator << (std::ostream &out, const InterrogateFunctionWrapper &wrapper);
-INLINE std::istream &operator >> (std::istream &in, InterrogateFunctionWrapper &wrapper);
-
-INLINE std::ostream &operator << (std::ostream &out, const InterrogateFunctionWrapper::Parameter &p);
-INLINE std::istream &operator >> (std::istream &in, InterrogateFunctionWrapper::Parameter &p);
-
-#include "interrogateFunctionWrapper.I"
-
-#endif

+ 0 - 103
dtool/src/interrogatedb/interrogateMakeSeq.I

@@ -1,103 +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 interrogateMakeSeq.I
- * @author drose
- * @date 2009-09-15
- */
-
-/**
- *
- */
-INLINE InterrogateMakeSeq::
-InterrogateMakeSeq(InterrogateModuleDef *def) :
-  InterrogateComponent(def)
-{
-  _length_getter = 0;
-  _element_getter = 0;
-}
-
-/**
- *
- */
-INLINE InterrogateMakeSeq::
-InterrogateMakeSeq(const InterrogateMakeSeq &copy) {
-  (*this) = copy;
-}
-
-/**
- *
- */
-INLINE void InterrogateMakeSeq::
-operator = (const InterrogateMakeSeq &copy) {
-  InterrogateComponent::operator = (copy);
-  _scoped_name = copy._scoped_name;
-  _comment = copy._comment;
-  _length_getter = copy._length_getter;
-  _element_getter = copy._element_getter;
-}
-
-/**
- *
- */
-INLINE bool InterrogateMakeSeq::
-has_scoped_name() const {
-  return !_scoped_name.empty();
-}
-
-/**
- *
- */
-INLINE const std::string &InterrogateMakeSeq::
-get_scoped_name() const {
-  return _scoped_name;
-}
-
-/**
- *
- */
-INLINE bool InterrogateMakeSeq::
-has_comment() const {
-  return !_comment.empty();
-}
-
-/**
- *
- */
-INLINE const std::string &InterrogateMakeSeq::
-get_comment() const {
-  return _comment;
-}
-
-/**
- *
- */
-INLINE FunctionIndex InterrogateMakeSeq::
-get_length_getter() const {
-  return _length_getter;
-}
-
-/**
- *
- */
-INLINE FunctionIndex InterrogateMakeSeq::
-get_element_getter() const {
-  return _element_getter;
-}
-
-INLINE std::ostream &
-operator << (std::ostream &out, const InterrogateMakeSeq &make_seq) {
-  make_seq.output(out);
-  return out;
-}
-
-INLINE std::istream &
-operator >> (std::istream &in, InterrogateMakeSeq &make_seq) {
-  make_seq.input(in);
-  return in;
-}

+ 0 - 50
dtool/src/interrogatedb/interrogateMakeSeq.cxx

@@ -1,50 +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 interrogateMakeSeq.cxx
- * @author drose
- * @date 2009-09-15
- */
-
-#include "interrogateMakeSeq.h"
-#include "indexRemapper.h"
-#include "interrogate_datafile.h"
-
-/**
- * Formats the InterrogateMakeSeq data for output to a data file.
- */
-void InterrogateMakeSeq::
-output(std::ostream &out) const {
-  InterrogateComponent::output(out);
-  out << _length_getter << " "
-      << _element_getter << " ";
-  idf_output_string(out, _scoped_name);
-  idf_output_string(out, _comment, '\n');
-}
-
-/**
- * Reads the data file as previously formatted by output().
- */
-void InterrogateMakeSeq::
-input(std::istream &in) {
-  InterrogateComponent::input(in);
-
-  in >> _length_getter >> _element_getter;
-  idf_input_string(in, _scoped_name);
-  idf_input_string(in, _comment);
-}
-
-/**
- * Remaps all internal index numbers according to the indicated map.  This
- * called from InterrogateDatabase::remap_indices().
- */
-void InterrogateMakeSeq::
-remap_indices(const IndexRemapper &remap) {
-  _length_getter = remap.map_from(_length_getter);
-  _element_getter = remap.map_from(_element_getter);
-}

+ 0 - 60
dtool/src/interrogatedb/interrogateMakeSeq.h

@@ -1,60 +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 interrogateMakeSeq.h
- * @author drose
- * @date 2009-09-15
- */
-
-#ifndef INTERROGATEMAKESEQ_H
-#define INTERROGATEMAKESEQ_H
-
-#include "dtoolbase.h"
-
-#include "interrogateComponent.h"
-
-class IndexRemapper;
-
-/**
- * Represents a synthetic method created via the MAKE_SEQ() macro.
- */
-class EXPCL_INTERROGATEDB InterrogateMakeSeq : public InterrogateComponent {
-public:
-  INLINE InterrogateMakeSeq(InterrogateModuleDef *def = nullptr);
-  INLINE InterrogateMakeSeq(const InterrogateMakeSeq &copy);
-  INLINE void operator = (const InterrogateMakeSeq &copy);
-
-  INLINE bool has_scoped_name() const;
-  INLINE const std::string &get_scoped_name() const;
-
-  INLINE bool has_comment() const;
-  INLINE const std::string &get_comment() const;
-
-  INLINE FunctionIndex get_length_getter() const;
-  INLINE FunctionIndex get_element_getter() const;
-
-  void output(std::ostream &out) const;
-  void input(std::istream &in);
-
-  void remap_indices(const IndexRemapper &remap);
-
-private:
-  std::string _scoped_name;
-  std::string _comment;
-  FunctionIndex _length_getter;
-  FunctionIndex _element_getter;
-
-  friend class InterrogateBuilder;
-};
-
-INLINE std::ostream &operator << (std::ostream &out, const InterrogateMakeSeq &make_seq);
-INLINE std::istream &operator >> (std::istream &in, InterrogateMakeSeq &make_seq);
-
-#include "interrogateMakeSeq.I"
-
-#endif

+ 0 - 116
dtool/src/interrogatedb/interrogateManifest.I

@@ -1,116 +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 interrogateManifest.I
- * @author drose
- * @date 2000-08-11
- */
-
-/**
- *
- */
-INLINE InterrogateManifest::
-InterrogateManifest(InterrogateModuleDef *def) :
-  InterrogateComponent(def)
-{
-  _flags = 0;
-  _int_value = 0;
-  _type = 0;
-  _getter = 0;
-}
-
-/**
- *
- */
-INLINE InterrogateManifest::
-InterrogateManifest(const InterrogateManifest &copy) {
-  (*this) = copy;
-}
-
-/**
- *
- */
-INLINE void InterrogateManifest::
-operator = (const InterrogateManifest &copy) {
-  InterrogateComponent::operator = (copy);
-  _flags = copy._flags;
-  _definition = copy._definition;
-  _int_value = copy._int_value;
-  _type = copy._type;
-  _getter = copy._getter;
-}
-
-
-/**
- *
- */
-INLINE const std::string &InterrogateManifest::
-get_definition() const {
-  return _definition;
-}
-
-/**
- *
- */
-INLINE bool InterrogateManifest::
-has_type() const {
-  return (_flags & F_has_type) != 0;
-}
-
-/**
- *
- */
-INLINE TypeIndex InterrogateManifest::
-get_type() const {
-  return _type;
-}
-
-/**
- *
- */
-INLINE bool InterrogateManifest::
-has_getter() const {
-  return (_flags & F_has_getter) != 0;
-}
-
-/**
- *
- */
-INLINE FunctionIndex InterrogateManifest::
-get_getter() const {
-  return _getter;
-}
-
-/**
- *
- */
-INLINE bool InterrogateManifest::
-has_int_value() const {
-  return (_flags & F_has_int_value) != 0;
-}
-
-/**
- *
- */
-INLINE int InterrogateManifest::
-get_int_value() const {
-  return _int_value;
-}
-
-
-INLINE std::ostream &
-operator << (std::ostream &out, const InterrogateManifest &manifest) {
-  manifest.output(out);
-  return out;
-}
-
-INLINE std::istream &
-operator >> (std::istream &in, InterrogateManifest &manifest) {
-  manifest.input(in);
-  return in;
-}

+ 0 - 49
dtool/src/interrogatedb/interrogateManifest.cxx

@@ -1,49 +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 interrogateManifest.cxx
- * @author drose
- * @date 2000-08-11
- */
-
-#include "interrogateManifest.h"
-#include "indexRemapper.h"
-#include "interrogate_datafile.h"
-
-/**
- * Formats the InterrogateManifest data for output to a data file.
- */
-void InterrogateManifest::
-output(std::ostream &out) const {
-  InterrogateComponent::output(out);
-  out << _flags << " "
-      << _int_value << " "
-      << _type << " "
-      << _getter << " ";
-  idf_output_string(out, _definition);
-}
-
-/**
- * Reads the data file as previously formatted by output().
- */
-void InterrogateManifest::
-input(std::istream &in) {
-  InterrogateComponent::input(in);
-  in >> _flags >> _int_value >> _type >> _getter;
-  idf_input_string(in, _definition);
-}
-
-/**
- * Remaps all internal index numbers according to the indicated map.  This
- * called from InterrogateDatabase::remap_indices().
- */
-void InterrogateManifest::
-remap_indices(const IndexRemapper &remap) {
-  _type = remap.map_from(_type);
-  _getter = remap.map_from(_getter);
-}

+ 0 - 66
dtool/src/interrogatedb/interrogateManifest.h

@@ -1,66 +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 interrogateManifest.h
- * @author drose
- * @date 2000-08-11
- */
-
-#ifndef INTERROGATEMANIFEST_H
-#define INTERROGATEMANIFEST_H
-
-#include "dtoolbase.h"
-
-#include "interrogateComponent.h"
-
-class IndexRemapper;
-
-/**
- * An internal representation of a manifest constant.
- */
-class EXPCL_INTERROGATEDB InterrogateManifest : public InterrogateComponent {
-public:
-  INLINE InterrogateManifest(InterrogateModuleDef *def = nullptr);
-  INLINE InterrogateManifest(const InterrogateManifest &copy);
-  INLINE void operator = (const InterrogateManifest &copy);
-
-  INLINE const std::string &get_definition() const;
-  INLINE bool has_type() const;
-  INLINE TypeIndex get_type() const;
-  INLINE bool has_getter() const;
-  INLINE FunctionIndex get_getter() const;
-  INLINE bool has_int_value() const;
-  INLINE int get_int_value() const;
-
-  void output(std::ostream &out) const;
-  void input(std::istream &in);
-
-  void remap_indices(const IndexRemapper &remap);
-
-private:
-  enum Flags {
-    F_has_type        = 0x0001,
-    F_has_getter      = 0x0002,
-    F_has_int_value   = 0x0004
-  };
-
-  int _flags;
-  std::string _definition;
-  int _int_value;
-  TypeIndex _type;
-  FunctionIndex _getter;
-
-  friend class InterrogateBuilder;
-};
-
-INLINE std::ostream &operator << (std::ostream &out, const InterrogateManifest &manifest);
-INLINE std::istream &operator >> (std::istream &in, InterrogateManifest &manifest);
-
-#include "interrogateManifest.I"
-
-#endif

+ 0 - 594
dtool/src/interrogatedb/interrogateType.I

@@ -1,594 +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 interrogateType.I
- * @author drose
- * @date 2000-07-31
- */
-
-/**
- * Returns true if the type is marked as 'global'.  This means only that it
- * should appear in the global type list.
- */
-INLINE bool InterrogateType::
-is_global() const {
-  return (_flags & F_global) != 0;
-}
-
-/**
- * Returns true if the type is marked as 'deprecated'.
- *
- * @since 1.11.0
- */
-INLINE bool InterrogateType::
-is_deprecated() const {
-  return (_flags & F_deprecated) != 0;
-}
-
-/**
- *
- */
-INLINE bool InterrogateType::
-has_scoped_name() const {
-  return !_scoped_name.empty();
-}
-
-/**
- *
- */
-INLINE const std::string &InterrogateType::
-get_scoped_name() const {
-  return _scoped_name;
-}
-
-/**
- *
- */
-INLINE bool InterrogateType::
-has_true_name() const {
-  return !_true_name.empty();
-}
-
-/**
- *
- */
-INLINE const std::string &InterrogateType::
-get_true_name() const {
-  return _true_name;
-}
-
-/**
- *
- */
-INLINE bool InterrogateType::
-has_comment() const {
-  return !_comment.empty();
-}
-
-/**
- *
- */
-INLINE const std::string &InterrogateType::
-get_comment() const {
-  return _comment;
-}
-
-/**
- * Returns true if this type is nested within some class definition.
- */
-INLINE bool InterrogateType::
-is_nested() const {
-  return (_flags & F_nested) != 0;
-}
-
-/**
- * If is_nested() returns true, this is the class within which this type is
- * defined.
- */
-INLINE TypeIndex InterrogateType::
-get_outer_class() const {
-  return _outer_class;
-}
-
-/**
- *
- */
-INLINE bool InterrogateType::
-is_atomic() const {
-  return (_flags & F_atomic) != 0;
-}
-
-/**
- *
- */
-INLINE AtomicToken InterrogateType::
-get_atomic_token() const {
-  return _atomic_token;
-}
-
-/**
- *
- */
-INLINE bool InterrogateType::
-is_unsigned() const {
-  return (_flags & F_unsigned) != 0;
-}
-
-/**
- *
- */
-INLINE bool InterrogateType::
-is_signed() const {
-  return (_flags & F_signed) != 0;
-}
-
-/**
- *
- */
-INLINE bool InterrogateType::
-is_long() const {
-  return (_flags & F_long) != 0;
-}
-
-/**
- *
- */
-INLINE bool InterrogateType::
-is_longlong() const {
-  return (_flags & F_longlong) != 0;
-}
-
-/**
- *
- */
-INLINE bool InterrogateType::
-is_short() const {
-  return (_flags & F_short) != 0;
-}
-
-/**
- *
- */
-INLINE bool InterrogateType::
-is_wrapped() const {
-  return (_flags & F_wrapped) != 0;
-}
-
-/**
- *
- */
-INLINE bool InterrogateType::
-is_pointer() const {
-  return (_flags & F_pointer) != 0;
-}
-
-/**
- *
- */
-INLINE bool InterrogateType::
-is_const() const {
-  return (_flags & F_const) != 0;
-}
-
-/**
- *
- */
-INLINE bool InterrogateType::
-is_typedef() const {
-  return (_flags & F_typedef) != 0;
-}
-
-/**
- *
- */
-INLINE TypeIndex InterrogateType::
-get_wrapped_type() const {
-  return _wrapped_type;
-}
-
-/**
- *
- */
-INLINE bool InterrogateType::
-is_array() const {
-  return (_flags & F_array) != 0;
-}
-
-/**
- *
- */
-INLINE int InterrogateType::
-get_array_size() const {
-  return _array_size;
-}
-
-/**
- *
- */
-INLINE bool InterrogateType::
-is_enum() const {
-  return (_flags & F_enum) != 0;
-}
-
-/**
- * Returns true if enum values are only available under a scope.
- */
-INLINE bool InterrogateType::
-is_scoped_enum() const {
-  return (_flags & F_scoped_enum) != 0;
-}
-
-/**
- *
- */
-INLINE int InterrogateType::
-number_of_enum_values() const {
-  return _enum_values.size();
-}
-
-/**
- *
- */
-INLINE const std::string &InterrogateType::
-get_enum_value_name(int n) const {
-  if (n >= 0 && n < (int)_enum_values.size()) {
-    return _enum_values[n]._name;
-  }
-  return _empty_string;
-}
-
-/**
- *
- */
-INLINE const std::string &InterrogateType::
-get_enum_value_scoped_name(int n) const {
-  if (n >= 0 && n < (int)_enum_values.size()) {
-    return _enum_values[n]._scoped_name;
-  }
-  return _empty_string;
-}
-
-/**
- *
- */
-INLINE const std::string &InterrogateType::
-get_enum_value_comment(int n) const {
-  if (n >= 0 && n < (int)_enum_values.size()) {
-    return _enum_values[n]._comment;
-  }
-  return _empty_string;
-}
-
-/**
- *
- */
-INLINE int InterrogateType::
-get_enum_value(int n) const {
-  if (n >= 0 && n < (int)_enum_values.size()) {
-    return _enum_values[n]._value;
-  }
-  return 0;
-}
-
-/**
- *
- */
-INLINE bool InterrogateType::
-is_struct() const {
-  return (_flags & F_struct) != 0;
-}
-
-/**
- *
- */
-INLINE bool InterrogateType::
-is_class() const {
-  return (_flags & F_class) != 0;
-}
-
-/**
- *
- */
-INLINE bool InterrogateType::
-is_union() const {
-  return (_flags & F_union) != 0;
-}
-
-/**
- *
- */
-INLINE bool InterrogateType::
-is_final() const {
-  return (_flags & F_final) != 0;
-}
-
-/**
- *
- */
-INLINE bool InterrogateType::
-is_fully_defined() const {
-  return (_flags & F_fully_defined) != 0;
-}
-
-/**
- * Returns true if the type is an unpublished type.  This either means the
- * type is a nested type, and it is protected or private within its scope, or
- * that its definition is simply not marked as 'published'.
- */
-INLINE bool InterrogateType::
-is_unpublished() const {
-  return (_flags & F_unpublished) != 0;
-}
-
-/**
- *
- */
-INLINE int InterrogateType::
-number_of_constructors() const {
-  return _constructors.size();
-}
-
-/**
- *
- */
-INLINE FunctionIndex InterrogateType::
-get_constructor(int n) const {
-  if (n >= 0 && n < (int)_constructors.size()) {
-    return _constructors[n];
-  } else {
-    return 0;
-  }
-}
-
-/**
- *
- */
-INLINE bool InterrogateType::
-has_destructor() const {
-  return (_destructor != 0);
-}
-
-/**
- *
- */
-INLINE bool InterrogateType::
-destructor_is_inherited() const {
-  return (_flags & F_inherited_destructor) != 0;
-}
-
-/**
- *
- */
-INLINE bool InterrogateType::
-destructor_is_implicit() const {
-  return (_flags & F_implicit_destructor) != 0;
-}
-
-/**
- *
- */
-INLINE FunctionIndex InterrogateType::
-get_destructor() const {
-  return _destructor;
-}
-
-/**
- *
- */
-INLINE int InterrogateType::
-number_of_elements() const {
-  return _elements.size();
-}
-
-/**
- *
- */
-INLINE ElementIndex InterrogateType::
-get_element(int n) const {
-  if (n >= 0 && n < (int)_elements.size()) {
-    return _elements[n];
-  } else {
-    return 0;
-  }
-}
-
-/**
- *
- */
-INLINE int InterrogateType::
-number_of_methods() const {
-  return _methods.size();
-}
-
-/**
- *
- */
-INLINE FunctionIndex InterrogateType::
-get_method(int n) const {
-  if (n >= 0 && n < (int)_methods.size()) {
-    return _methods[n];
-  } else {
-    return 0;
-  }
-}
-
-/**
- *
- */
-INLINE int InterrogateType::
-number_of_make_seqs() const {
-  return _make_seqs.size();
-}
-
-/**
- *
- */
-INLINE MakeSeqIndex InterrogateType::
-get_make_seq(int n) const {
-  if (n >= 0 && n < (int)_make_seqs.size()) {
-    return _make_seqs[n];
-  } else {
-    return 0;
-  }
-}
-
-/**
- *
- */
-INLINE int InterrogateType::
-number_of_casts() const {
-  return _casts.size();
-}
-
-/**
- *
- */
-INLINE FunctionIndex InterrogateType::
-get_cast(int n) const {
-  if (n >= 0 && n < (int)_casts.size()) {
-    return _casts[n];
-  } else {
-    return 0;
-  }
-}
-
-/**
- *
- */
-INLINE int InterrogateType::
-number_of_derivations() const {
-  return _derivations.size();
-}
-
-/**
- *
- */
-INLINE TypeIndex InterrogateType::
-get_derivation(int n) const {
-  if (n >= 0 && n < (int)_derivations.size()) {
-    return _derivations[n]._base;
-  } else {
-    return 0;
-  }
-}
-
-/**
- *
- */
-INLINE bool InterrogateType::
-derivation_has_upcast(int n) const {
-  if (n >= 0 && n < (int)_derivations.size()) {
-    return (_derivations[n]._flags & DF_upcast) != 0;
-  } else {
-    return false;
-  }
-}
-
-/**
- *
- */
-INLINE TypeIndex InterrogateType::
-derivation_get_upcast(int n) const {
-  if (n >= 0 && n < (int)_derivations.size()) {
-    return _derivations[n]._upcast;
-  } else {
-    return 0;
-  }
-}
-
-/**
- *
- */
-INLINE bool InterrogateType::
-derivation_downcast_is_impossible(int n) const {
-  if (n >= 0 && n < (int)_derivations.size()) {
-    return (_derivations[n]._flags & DF_downcast_impossible) != 0;
-  } else {
-    return false;
-  }
-}
-
-/**
- *
- */
-INLINE bool InterrogateType::
-derivation_has_downcast(int n) const {
-  if (n >= 0 && n < (int)_derivations.size()) {
-    return (_derivations[n]._flags & DF_downcast) != 0;
-  } else {
-    return false;
-  }
-}
-
-/**
- *
- */
-INLINE TypeIndex InterrogateType::
-derivation_get_downcast(int n) const {
-  if (n >= 0 && n < (int)_derivations.size()) {
-    return _derivations[n]._downcast;
-  } else {
-    return 0;
-  }
-}
-
-/**
- *
- */
-INLINE int InterrogateType::
-number_of_nested_types() const {
-  return _nested_types.size();
-}
-
-/**
- *
- */
-INLINE TypeIndex InterrogateType::
-get_nested_type(int n) const {
-  if (n >= 0 && n < (int)_nested_types.size()) {
-    return _nested_types[n];
-  } else {
-    return 0;
-  }
-}
-
-INLINE std::ostream &
-operator << (std::ostream &out, const InterrogateType &type) {
-  type.output(out);
-  return out;
-}
-
-INLINE std::istream &
-operator >> (std::istream &in, InterrogateType &type) {
-  type.input(in);
-  return in;
-}
-
-INLINE std::ostream &
-operator << (std::ostream &out, const InterrogateType::Derivation &d) {
-  d.output(out);
-  return out;
-}
-
-INLINE std::istream &
-operator >> (std::istream &in, InterrogateType::Derivation &d) {
-  d.input(in);
-  return in;
-}
-
-INLINE std::ostream &
-operator << (std::ostream &out, const InterrogateType::EnumValue &ev) {
-  ev.output(out);
-  return out;
-}
-
-INLINE std::istream &
-operator >> (std::istream &in, InterrogateType::EnumValue &ev) {
-  ev.input(in);
-  return in;
-}

+ 0 - 247
dtool/src/interrogatedb/interrogateType.cxx

@@ -1,247 +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 interrogateType.cxx
- * @author drose
- * @date 2000-07-31
- */
-
-#include "interrogateType.h"
-#include "indexRemapper.h"
-#include "interrogate_datafile.h"
-#include "interrogateDatabase.h"
-
-#include <algorithm>
-
-using std::istream;
-using std::ostream;
-
-/**
- *
- */
-InterrogateType::
-InterrogateType(InterrogateModuleDef *def) :
-  InterrogateComponent(def)
-{
-  _flags = 0;
-  _outer_class = 0;
-  _atomic_token = AT_not_atomic;
-  _wrapped_type = 0;
-  _array_size = 1;
-  _destructor = 0;
-
-  _cpptype = nullptr;
-  _cppscope = nullptr;
-}
-
-/**
- *
- */
-InterrogateType::
-InterrogateType(const InterrogateType &copy) {
-  (*this) = copy;
-}
-
-/**
- *
- */
-void InterrogateType::Derivation::
-output(ostream &out) const {
-  out << _flags << " " << _base << " " << _upcast << " " << _downcast;
-}
-
-/**
- *
- */
-void InterrogateType::Derivation::
-input(istream &in) {
-  in >> _flags >> _base >> _upcast >> _downcast;
-}
-
-/**
- *
- */
-void InterrogateType::EnumValue::
-output(ostream &out) const {
-  idf_output_string(out, _name);
-  idf_output_string(out, _scoped_name);
-  idf_output_string(out, _comment, '\n');
-  out << _value;
-}
-
-/**
- *
- */
-void InterrogateType::EnumValue::
-input(istream &in) {
-  idf_input_string(in, _name);
-  idf_input_string(in, _scoped_name);
-  idf_input_string(in, _comment);
-  in >> _value;
-}
-
-/**
- *
- */
-void InterrogateType::
-operator = (const InterrogateType &copy) {
-  InterrogateComponent::operator = (copy);
-  _flags = copy._flags;
-  _scoped_name = copy._scoped_name;
-  _true_name = copy._true_name;
-  _comment = copy._comment;
-  _outer_class = copy._outer_class;
-  _atomic_token = copy._atomic_token;
-  _wrapped_type = copy._wrapped_type;
-  _array_size = copy._array_size;
-  _constructors = copy._constructors;
-  _destructor = copy._destructor;
-  _elements = copy._elements;
-  _methods = copy._methods;
-  _make_seqs = copy._make_seqs;
-  _casts = copy._casts;
-  _derivations = copy._derivations;
-  _enum_values = copy._enum_values;
-  _nested_types = copy._nested_types;
-
-  _cpptype = copy._cpptype;
-  _cppscope = copy._cppscope;
-}
-
-/**
- * Combines type with the other similar definition.  If one type is "fully
- * defined" and the other one isn't, the fully-defined type wins.  If both
- * types are fully defined, whichever type is marked "global" wins.
- */
-void InterrogateType::
-merge_with(const InterrogateType &other) {
-  // The only thing we care about copying from the non-fully-defined type
-  // right now is the global flag.
-
-  if (is_fully_defined() &&
-      (!other.is_fully_defined() || (other._flags & F_global) == 0)) {
-    // We win.
-    _flags |= (other._flags & F_global);
-
-  } else {
-    // They win.
-    int old_flags = (_flags & F_global);
-    (*this) = other;
-    _flags |= old_flags;
-  }
-}
-
-/**
- * Formats the InterrogateType data for output to a data file.
- */
-void InterrogateType::
-output(ostream &out) const {
-  InterrogateComponent::output(out);
-
-  out << _flags << " ";
-  idf_output_string(out, _scoped_name);
-  idf_output_string(out, _true_name);
-  out << _outer_class << " "
-      << (int)_atomic_token << " "
-      << _wrapped_type << " ";
-
-  if (is_array()) {
-    out << _array_size << " ";
-  }
-
-  idf_output_vector(out, _constructors);
-  out << _destructor << " ";
-  idf_output_vector(out, _elements);
-  idf_output_vector(out, _methods);
-  idf_output_vector(out, _make_seqs);
-  idf_output_vector(out, _casts);
-  idf_output_vector(out, _derivations);
-  idf_output_vector(out, _enum_values);
-  idf_output_vector(out, _nested_types);
-  idf_output_string(out, _comment, '\n');
-}
-
-/**
- * Reads the data file as previously formatted by output().
- */
-void InterrogateType::
-input(istream &in) {
-  InterrogateComponent::input(in);
-
-  in >> _flags;
-  idf_input_string(in, _scoped_name);
-  idf_input_string(in, _true_name);
-
-  in >> _outer_class;
-  int token;
-  in >> token;
-  _atomic_token = (AtomicToken)token;
-  in >> _wrapped_type;
-
-  if (is_array()) {
-    in >> _array_size;
-  }
-
-  idf_input_vector(in, _constructors);
-  in >> _destructor;
-
-  idf_input_vector(in, _elements);
-  idf_input_vector(in, _methods);
-  idf_input_vector(in, _make_seqs);
-  idf_input_vector(in, _casts);
-  idf_input_vector(in, _derivations);
-  idf_input_vector(in, _enum_values);
-  idf_input_vector(in, _nested_types);
-  idf_input_string(in, _comment);
-}
-
-/**
- * Remaps all internal index numbers according to the indicated map.  This
- * called from InterrogateDatabase::remap_indices().
- */
-void InterrogateType::
-remap_indices(const IndexRemapper &remap) {
-  _outer_class = remap.map_from(_outer_class);
-  _wrapped_type = remap.map_from(_wrapped_type);
-
-  Functions::iterator fi;
-  for (fi = _constructors.begin(); fi != _constructors.end(); ++fi) {
-    (*fi) = remap.map_from(*fi);
-  }
-  _destructor = remap.map_from(_destructor);
-
-  Elements::iterator ei;
-  for (ei = _elements.begin(); ei != _elements.end(); ++ei) {
-    (*ei) = remap.map_from(*ei);
-  }
-
-  for (fi = _methods.begin(); fi != _methods.end(); ++fi) {
-    (*fi) = remap.map_from(*fi);
-  }
-  for (fi = _casts.begin(); fi != _casts.end(); ++fi) {
-    (*fi) = remap.map_from(*fi);
-  }
-
-  MakeSeqs::iterator si;
-  for (si = _make_seqs.begin(); si != _make_seqs.end(); ++si) {
-    (*si) = remap.map_from(*si);
-  }
-
-  Derivations::iterator di;
-  for (di = _derivations.begin(); di != _derivations.end(); ++di) {
-    (*di)._base = remap.map_from((*di)._base);
-    (*di)._upcast = remap.map_from((*di)._upcast);
-    (*di)._downcast = remap.map_from((*di)._downcast);
-  }
-
-  Types::iterator ti;
-  for (ti = _nested_types.begin(); ti != _nested_types.end(); ++ti) {
-    (*ti) = remap.map_from(*ti);
-  }
-
-}

+ 0 - 239
dtool/src/interrogatedb/interrogateType.h

@@ -1,239 +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 interrogateType.h
- * @author drose
- * @date 2000-07-31
- */
-
-#ifndef INTERROGATETYPE_H
-#define INTERROGATETYPE_H
-
-#include "dtoolbase.h"
-
-#include "interrogateComponent.h"
-
-#include <vector>
-
-class IndexRemapper;
-class CPPType;
-class CPPScope;
-
-/**
- * An internal representation of a type.
- */
-class EXPCL_INTERROGATEDB InterrogateType : public InterrogateComponent {
-public:
-  InterrogateType(InterrogateModuleDef *def = nullptr);
-  InterrogateType(const InterrogateType &copy);
-  void operator = (const InterrogateType &copy);
-
-  INLINE bool is_global() const;
-  INLINE bool is_deprecated() const;
-
-  INLINE bool has_scoped_name() const;
-  INLINE const std::string &get_scoped_name() const;
-
-  INLINE bool has_true_name() const;
-  INLINE const std::string &get_true_name() const;
-
-  INLINE bool has_comment() const;
-  INLINE const std::string &get_comment() const;
-
-  INLINE bool is_nested() const;
-  INLINE TypeIndex get_outer_class() const;
-
-  INLINE bool is_atomic() const;
-  INLINE AtomicToken get_atomic_token() const;
-  INLINE bool is_unsigned() const;
-  INLINE bool is_signed() const;
-  INLINE bool is_long() const;
-  INLINE bool is_longlong() const;
-  INLINE bool is_short() const;
-
-  INLINE bool is_wrapped() const;
-  INLINE bool is_pointer() const;
-  INLINE bool is_const() const;
-  INLINE bool is_typedef() const;
-  INLINE TypeIndex get_wrapped_type() const;
-
-  INLINE bool is_array() const;
-  INLINE int get_array_size() const;
-
-  INLINE bool is_enum() const;
-  INLINE bool is_scoped_enum() const;
-  INLINE int number_of_enum_values() const;
-  INLINE const std::string &get_enum_value_name(int n) const;
-  INLINE const std::string &get_enum_value_scoped_name(int n) const;
-  INLINE const std::string &get_enum_value_comment(int n) const;
-  INLINE int get_enum_value(int n) const;
-
-  INLINE bool is_struct() const;
-  INLINE bool is_class() const;
-  INLINE bool is_union() const;
-  INLINE bool is_final() const;
-
-  INLINE bool is_fully_defined() const;
-  INLINE bool is_unpublished() const;
-  INLINE int number_of_constructors() const;
-  INLINE FunctionIndex get_constructor(int n) const;
-  INLINE bool has_destructor() const;
-  INLINE bool destructor_is_inherited() const;
-  INLINE bool destructor_is_implicit() const;
-  INLINE FunctionIndex get_destructor() const;
-  INLINE int number_of_elements() const;
-  INLINE ElementIndex get_element(int n) const;
-  INLINE int number_of_methods() const;
-  INLINE FunctionIndex get_method(int n) const;
-  INLINE int number_of_make_seqs() const;
-  INLINE MakeSeqIndex get_make_seq(int n) const;
-
-  INLINE int number_of_casts() const;
-  INLINE FunctionIndex get_cast(int n) const;
-
-  INLINE int number_of_derivations() const;
-  INLINE TypeIndex get_derivation(int n) const;
-
-  INLINE bool derivation_has_upcast(int n) const;
-  INLINE FunctionIndex derivation_get_upcast(int n) const;
-
-  INLINE bool derivation_downcast_is_impossible(int n) const;
-  INLINE bool derivation_has_downcast(int n) const;
-  INLINE FunctionIndex derivation_get_downcast(int n) const;
-
-  INLINE int number_of_nested_types() const;
-  INLINE TypeIndex get_nested_type(int n) const;
-
-  void merge_with(const InterrogateType &other);
-  void output(std::ostream &out) const;
-  void input(std::istream &in);
-
-  void remap_indices(const IndexRemapper &remap);
-
-private:
-  enum Flags {
-    F_global               = 0x000001,
-    F_atomic               = 0x000002,
-    F_unsigned             = 0x000004,
-    F_signed               = 0x000008,
-    F_long                 = 0x000010,
-    F_longlong             = 0x000020,
-    F_short                = 0x000040,
-    F_wrapped              = 0x000080,
-    F_pointer              = 0x000100,
-    F_const                = 0x000200,
-    F_struct               = 0x000400,
-    F_class                = 0x000800,
-    F_union                = 0x001000,
-    F_fully_defined        = 0x002000,
-    F_true_destructor      = 0x004000,
-    F_private_destructor   = 0x008000,
-    F_inherited_destructor = 0x010000,
-    F_implicit_destructor  = 0x020000,
-    F_nested               = 0x040000,
-    F_enum                 = 0x080000,
-    F_unpublished          = 0x100000,
-    F_typedef              = 0x200000,
-    F_array                = 0x400000,
-    F_scoped_enum          = 0x800000,
-    F_final                =0x1000000,
-    F_deprecated           =0x2000000,
-  };
-
-public:
-  int _flags;
-
-  std::string _scoped_name;
-  std::string _true_name;
-  std::string _comment;
-  TypeIndex _outer_class;
-  AtomicToken _atomic_token;
-  TypeIndex _wrapped_type;
-  int _array_size;
-
-  typedef std::vector<FunctionIndex> Functions;
-  Functions _constructors;
-  FunctionIndex _destructor;
-
-  typedef std::vector<ElementIndex> Elements;
-  Elements _elements;
-  Functions _methods;
-  Functions _casts;
-
-  typedef std::vector<MakeSeqIndex> MakeSeqs;
-  MakeSeqs _make_seqs;
-
-  enum DerivationFlags {
-    DF_upcast               = 0x01,
-    DF_downcast             = 0x02,
-    DF_downcast_impossible  = 0x04
-  };
-
-public:
-  // This nested class must be declared public just so we can declare the
-  // external ostream and istream IO operator functions, on the SGI compiler.
-  // Arguably a compiler bug, but what can you do.
-  class Derivation {
-  public:
-    void output(std::ostream &out) const;
-    void input(std::istream &in);
-
-    int _flags;
-    TypeIndex _base;
-    FunctionIndex _upcast;
-    FunctionIndex _downcast;
-  };
-
-private:
-  typedef std::vector<Derivation> Derivations;
-  Derivations _derivations;
-
-public:
-  // This nested class must also be public, for the same reason.
-  class EnumValue {
-  public:
-    void output(std::ostream &out) const;
-    void input(std::istream &in);
-
-    std::string _name;
-    std::string _scoped_name;
-    std::string _comment;
-    int _value;
-  };
-
-private:
-  typedef std::vector<EnumValue> EnumValues;
-  EnumValues _enum_values;
-
-  typedef std::vector<TypeIndex> Types;
-  Types _nested_types;
-
-public:
-  // The rest of the members in this class aren't part of the public interface
-  // to interrogate, but are used internally as the interrogate database is
-  // built.  They are valid only during the session of interrogate that
-  // generates the database, and will not be filled in when the database is
-  // reloaded from disk.
-  CPPType *_cpptype;
-  CPPScope *_cppscope;
-
-  friend class InterrogateBuilder;
-};
-
-INLINE std::ostream &operator << (std::ostream &out, const InterrogateType &type);
-INLINE std::istream &operator >> (std::istream &in, InterrogateType &type);
-
-INLINE std::ostream &operator << (std::ostream &out, const InterrogateType::Derivation &d);
-INLINE std::istream &operator >> (std::istream &in, InterrogateType::Derivation &d);
-
-INLINE std::ostream &operator << (std::ostream &out, const InterrogateType::EnumValue &d);
-INLINE std::istream &operator >> (std::istream &in, InterrogateType::EnumValue &d);
-
-#include "interrogateType.I"
-
-#endif

+ 0 - 51
dtool/src/interrogatedb/interrogate_datafile.I

@@ -1,51 +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 interrogate_datafile.I
- * @author drose
- * @date 2000-08-09
- */
-
-/**
- * Writes the indicated vector to the output file.  Each component is written
- * using its normal ostream output operator.
- */
-template<class Element>
-void
-idf_output_vector(std::ostream &out, const std::vector<Element> &vec) {
-  out << vec.size() << " ";
-  typename std::vector<Element>::const_iterator vi;
-  for (vi = vec.begin(); vi != vec.end(); ++vi) {
-    out << (*vi) << " ";
-  }
-}
-
-
-/**
- * Reads the given vector from the input file, as previously written by
- * output_string().  Each component is read using its normal istream input
- * operator.
- */
-template<class Element>
-void
-idf_input_vector(std::istream &in, std::vector<Element> &vec) {
-  int length;
-  in >> length;
-  if (in.fail()) {
-    return;
-  }
-
-  vec.clear();
-  vec.reserve(length);
-  while (length > 0) {
-    Element elem;
-    in >> elem;
-    vec.push_back(elem);
-    length--;
-  }
-}

+ 0 - 98
dtool/src/interrogatedb/interrogate_datafile.cxx

@@ -1,98 +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 interrogate_datafile.cxx
- * @author drose
- * @date 2000-08-09
- */
-
-#include "interrogate_datafile.h"
-
-using std::istream;
-using std::ostream;
-using std::string;
-
-
-/**
- * Writes the indicated string to the output file.  Uses the given whitespace
- * character to separate the string's length and its contents.
- */
-void
-idf_output_string(ostream &out, const string &str, char whitespace) {
-  out << str.length() << whitespace;
-  if (!str.empty()) {
-    out << str << whitespace;
-  }
-}
-
-/**
- * Reads the given string from the input file, as previously written by
- * output_string().
- */
-void
-idf_input_string(istream &in, string &str) {
-  int length;
-  in >> length;
-  if (in.fail()) {
-    return;
-  }
-
-  // Skip one character of whitespace, and then read the string.
-  in.get();
-  str = "";
-  while (length > 0) {
-    str += in.get();
-    length--;
-  }
-}
-
-/**
- * Writes the indicated string to the output file.  Uses the given whitespace
- * character to separate the string's length and its contents.
- */
-void
-idf_output_string(ostream &out, const char *str, char whitespace) {
-  if (str == nullptr) {
-    out << "0 ";
-  } else {
-    out << strlen(str) << whitespace;
-    if (str[0] != '\0') {
-      out << str << whitespace;
-    }
-  }
-}
-
-/**
- * Reads the given string from the input file, as previously written by
- * output_string().
- */
-void
-idf_input_string(istream &in, const char *&str) {
-  int length;
-  in >> length;
-  if (in.fail()) {
-    return;
-  }
-
-  if (length == 0) {
-    // Don't change the string if the input length is zero.
-    return;
-  }
-
-  // Skip one character of whitespace, and then read the string.
-  in.get();
-  char *readstr = new char[length + 1];
-  int p = 0;
-  while (p < length) {
-    readstr[p] = in.get();
-    p++;
-  }
-  readstr[p] = '\0';
-
-  str = readstr;
-}

+ 0 - 37
dtool/src/interrogatedb/interrogate_datafile.h

@@ -1,37 +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 interrogate_datafile.h
- * @author drose
- * @date 2000-08-09
- */
-
-#ifndef INTERROGATE_DATAFILE_H
-#define INTERROGATE_DATAFILE_H
-
-// This file defines some convenience functions for reading and writing the
-// interrogate database files.
-
-#include "dtoolbase.h"
-#include <vector>
-
-void idf_output_string(std::ostream &out, const std::string &str, char whitespace = ' ');
-void idf_input_string(std::istream &in, std::string &str);
-
-void idf_output_string(std::ostream &out, const char *str, char whitespace = ' ');
-void idf_input_string(std::istream &in, const char *&str);
-
-template<class Element>
-void idf_output_vector(std::ostream &out, const std::vector<Element> &vec);
-
-template<class Element>
-void idf_input_vector(std::istream &in, std::vector<Element> &vec);
-
-#include "interrogate_datafile.I"
-
-#endif

+ 0 - 1043
dtool/src/interrogatedb/interrogate_interface.cxx

@@ -1,1043 +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 interrogate_interface.cxx
- * @author drose
- * @date 2000-07-31
- */
-
-#include "interrogate_interface.h"
-#include "interrogateDatabase.h"
-#include "interrogateType.h"
-#include "interrogateFunction.h"
-#include "config_interrogatedb.h"
-
-using std::string;
-
-// This function adds one more directory to the list of directories search for
-// interrogate (*.in) files.  In the past, this list has been defined the
-// environment variable ETC_PATH, but now it is passed in by the code
-// generator.
-void
-interrogate_add_search_directory(const char *dirname) {
-  // cerr << "interrogate_add_search_directory(" << dirname << ")\n";
-  interrogatedb_path.append_directory(Filename::from_os_specific(dirname));
-}
-
-// This function works similar to the above, but adds a complete path string--
-// a list of multiple directories, separated by the standard delimiter--to the
-// search path.
-void
-interrogate_add_search_path(const char *pathstring) {
-  // cerr << "interrogate_add_search_path(" << pathstring << ")\n";
-  interrogatedb_path.append_path(pathstring);
-}
-
-bool interrogate_error_flag() {
-  // cerr << "interrogate_error_flag\n";
-  return InterrogateDatabase::get_ptr()->get_error_flag();
-}
-
-int
-interrogate_number_of_manifests() {
-  // cerr << "interrogate_number_of_manifests\n";
-  return InterrogateDatabase::get_ptr()->get_num_global_manifests();
-}
-
-ManifestIndex
-interrogate_get_manifest(int n) {
-  // cerr << "interrogate_get_manifest(" << n << ")\n";
-  return InterrogateDatabase::get_ptr()->get_global_manifest(n);
-}
-
-ManifestIndex
-interrogate_get_manifest_by_name(const char *manifest_name) {
-  // cerr << "interrogate_get_manifest_by_name(" << manifest_name << ")\n";
-  return InterrogateDatabase::get_ptr()->lookup_manifest_by_name(manifest_name);
-}
-
-const char *
-interrogate_manifest_name(ManifestIndex manifest) {
-  // cerr << "interrogate_manifest_name(" << manifest << ")\n";
-  return InterrogateDatabase::get_ptr()->get_manifest(manifest).get_name().c_str();
-}
-
-const char *
-interrogate_manifest_definition(ManifestIndex manifest) {
-  // cerr << "interrogate_manifest_definition(" << manifest << ")\n";
-  return InterrogateDatabase::get_ptr()->get_manifest(manifest).get_definition().c_str();
-}
-
-bool
-interrogate_manifest_has_type(ManifestIndex manifest) {
-  // cerr << "interrogate_manifest_has_type(" << manifest << ")\n";
-  return InterrogateDatabase::get_ptr()->get_manifest(manifest).has_type();
-}
-
-TypeIndex
-interrogate_manifest_get_type(ManifestIndex manifest) {
-  // cerr << "interrogate_manifest_get_type(" << manifest << ")\n";
-  return InterrogateDatabase::get_ptr()->get_manifest(manifest).get_type();
-}
-
-bool
-interrogate_manifest_has_getter(ManifestIndex manifest) {
-  // cerr << "interrogate_manifest_has_getter(" << manifest << ")\n";
-  return InterrogateDatabase::get_ptr()->get_manifest(manifest).has_getter();
-}
-
-FunctionIndex
-interrogate_manifest_getter(ManifestIndex manifest) {
-  // cerr << "interrogate_manifest_getter(" << manifest << ")\n";
-  return InterrogateDatabase::get_ptr()->get_manifest(manifest).get_getter();
-}
-
-bool
-interrogate_manifest_has_int_value(ManifestIndex manifest) {
-  // cerr << "interrogate_manifest_has_int_value(" << manifest << ")\n";
-  return InterrogateDatabase::get_ptr()->get_manifest(manifest).has_int_value();
-}
-
-int
-interrogate_manifest_get_int_value(ManifestIndex manifest) {
-  // cerr << "interrogate_manifest_get_int_value(" << manifest << ")\n";
-  return InterrogateDatabase::get_ptr()->get_manifest(manifest).get_int_value();
-}
-
-const char *
-interrogate_element_name(ElementIndex element) {
-  // cerr << "interrogate_element_name(" << element << ")\n";
-  return InterrogateDatabase::get_ptr()->get_element(element).get_name().c_str();
-}
-
-const char *
-interrogate_element_scoped_name(ElementIndex element) {
-  // cerr << "interrogate_element_scoped_name(" << element << ")\n";
-  return InterrogateDatabase::get_ptr()->get_element(element).get_scoped_name().c_str();
-}
-
-bool
-interrogate_element_has_comment(ElementIndex element) {
-  // cerr << "interrogate_element_has_comment(" << element << ")\n";
-  return InterrogateDatabase::get_ptr()->get_element(element).has_comment();
-}
-
-const char *
-interrogate_element_comment(ElementIndex element) {
-  // cerr << "interrogate_element_comment(" << element << ")\n";
-  return InterrogateDatabase::get_ptr()->get_element(element).get_comment().c_str();
-}
-
-ElementIndex
-interrogate_get_element_by_name(const char *element_name) {
-  // cerr << "interrogate_get_element_by_name(" << element_name << ")\n";
-  return InterrogateDatabase::get_ptr()->lookup_element_by_name(element_name);
-}
-
-ElementIndex
-interrogate_get_element_by_scoped_name(const char *element_name) {
-  // cerr << "interrogate_get_element_by_scoped_name(" << element_name <<
-  // ")\n";
-  return InterrogateDatabase::get_ptr()->lookup_element_by_scoped_name(element_name);
-}
-
-TypeIndex
-interrogate_element_type(ElementIndex element) {
-  // cerr << "interrogate_element_type(" << element << ")\n";
-  return InterrogateDatabase::get_ptr()->get_element(element).get_type();
-}
-
-bool
-interrogate_element_has_getter(ElementIndex element) {
-  // cerr << "interrogate_element_has_getter(" << element << ")\n";
-  return InterrogateDatabase::get_ptr()->get_element(element).has_getter();
-}
-
-FunctionIndex
-interrogate_element_getter(ElementIndex element) {
-  // cerr << "interrogate_element_getter(" << element << ")\n";
-  return InterrogateDatabase::get_ptr()->get_element(element).get_getter();
-}
-
-bool
-interrogate_element_has_setter(ElementIndex element) {
-  // cerr << "interrogate_element_has_setter(" << element << ")\n";
-  return InterrogateDatabase::get_ptr()->get_element(element).has_setter();
-}
-
-FunctionIndex
-interrogate_element_setter(ElementIndex element) {
-  // cerr << "interrogate_element_setter(" << element << ")\n";
-  return InterrogateDatabase::get_ptr()->get_element(element).get_setter();
-}
-
-bool
-interrogate_element_has_has_function(ElementIndex element) {
-  // cerr << "interrogate_element_has_has_function(" << element << ")\n";
-  return InterrogateDatabase::get_ptr()->get_element(element).has_has_function();
-}
-
-FunctionIndex
-interrogate_element_has_function(ElementIndex element) {
-  // cerr << "interrogate_element_has_function(" << element << ")\n";
-  return InterrogateDatabase::get_ptr()->get_element(element).get_has_function();
-}
-
-bool
-interrogate_element_has_clear_function(ElementIndex element) {
-  // cerr << "interrogate_element_has_clear_function(" << element << ")\n";
-  return InterrogateDatabase::get_ptr()->get_element(element).has_clear_function();
-}
-
-FunctionIndex
-interrogate_element_clear_function(ElementIndex element) {
-  // cerr << "interrogate_element_clear_function(" << element << ")\n";
-  return InterrogateDatabase::get_ptr()->get_element(element).get_clear_function();
-}
-
-bool
-interrogate_element_has_del_function(ElementIndex element) {
-  // cerr << "interrogate_element_has_del_function(" << element << ")\n";
-  return InterrogateDatabase::get_ptr()->get_element(element).has_del_function();
-}
-
-FunctionIndex
-interrogate_element_del_function(ElementIndex element) {
-  // cerr << "interrogate_element_del_function(" << element << ")\n";
-  return InterrogateDatabase::get_ptr()->get_element(element).get_del_function();
-}
-
-bool
-interrogate_element_has_insert_function(ElementIndex element) {
-  // cerr << "interrogate_element_has_insert_function(" << element << ")\n";
-  return InterrogateDatabase::get_ptr()->get_element(element).has_insert_function();
-}
-
-FunctionIndex
-interrogate_element_insert_function(ElementIndex element) {
-  // cerr << "interrogate_element_insert_function(" << element << ")\n";
-  return InterrogateDatabase::get_ptr()->get_element(element).get_insert_function();
-}
-
-bool
-interrogate_element_has_getkey_function(ElementIndex element) {
-  // cerr << "interrogate_element_has_getkey_function(" << element << ")\n";
-  return InterrogateDatabase::get_ptr()->get_element(element).has_getkey_function();
-}
-
-FunctionIndex
-interrogate_element_getkey_function(ElementIndex element) {
-  // cerr << "interrogate_element_getkey_function(" << element << ")\n";
-  return InterrogateDatabase::get_ptr()->get_element(element).get_getkey_function();
-}
-
-FunctionIndex
-interrogate_element_length_function(ElementIndex element) {
-  // cerr << "interrogate_element_length_function(" << element << ")\n";
-  return InterrogateDatabase::get_ptr()->get_element(element).get_length_function();
-}
-
-bool
-interrogate_element_is_sequence(ElementIndex element) {
-  // cerr << "interrogate_element_is_sequence(" << element << ")\n";
-  return InterrogateDatabase::get_ptr()->get_element(element).is_sequence();
-}
-
-bool
-interrogate_element_is_mapping(ElementIndex element) {
-  // cerr << "interrogate_element_is_mapping(" << element << ")\n";
-  return InterrogateDatabase::get_ptr()->get_element(element).is_mapping();
-}
-
-int
-interrogate_number_of_globals() {
-  // cerr << "interrogate_number_of_globals()\n";
-  return InterrogateDatabase::get_ptr()->get_num_global_elements();
-}
-
-ElementIndex
-interrogate_get_global(int n) {
-  // cerr << "interrogate_get_global(" << n << ")\n";
-  return InterrogateDatabase::get_ptr()->get_global_element(n);
-}
-
-int
-interrogate_number_of_global_functions() {
-  // cerr << "interrogate_number_of_global_functions()\n";
-  return InterrogateDatabase::get_ptr()->get_num_global_functions();
-}
-
-FunctionIndex
-interrogate_get_global_function(int n) {
-  // cerr << "interrogate_get_global_function(" << n << ")\n";
-  return InterrogateDatabase::get_ptr()->get_global_function(n);
-}
-
-int
-interrogate_number_of_functions() {
-  // cerr << "interrogate_number_of_functions()\n";
-  return InterrogateDatabase::get_ptr()->get_num_all_functions();
-}
-
-FunctionIndex
-interrogate_get_function(int n) {
-  // cerr << "interrogate_get_function(" << n << ")\n";
-  return InterrogateDatabase::get_ptr()->get_all_function(n);
-}
-
-const char *
-interrogate_function_name(FunctionIndex function) {
-  // cerr << "interrogate_function_name(" << function << ")\n";
-  return InterrogateDatabase::get_ptr()->get_function(function).get_name().c_str();
-}
-
-const char *
-interrogate_function_scoped_name(FunctionIndex function) {
-  // cerr << "interrogate_function_scoped_name(" << function << ")\n";
-  return InterrogateDatabase::get_ptr()->get_function(function).get_scoped_name().c_str();
-}
-
-bool
-interrogate_function_has_comment(FunctionIndex function) {
-  // cerr << "interrogate_function_has_comment(" << function << ")\n";
-  return InterrogateDatabase::get_ptr()->get_function(function).has_comment();
-}
-
-const char *
-interrogate_function_comment(FunctionIndex function) {
-  // cerr << "interrogate_function_comment(" << function << ")\n";
-  return InterrogateDatabase::get_ptr()->get_function(function).get_comment().c_str();
-}
-
-const char *
-interrogate_function_prototype(FunctionIndex function) {
-  // cerr << "interrogate_function_prototype(" << function << ")\n";
-  return InterrogateDatabase::get_ptr()->get_function(function).get_prototype().c_str();
-}
-
-bool
-interrogate_function_is_method(FunctionIndex function) {
-  // cerr << "interrogate_function_is_method(" << function << ")\n";
-  return InterrogateDatabase::get_ptr()->get_function(function).is_method();
-}
-
-TypeIndex
-interrogate_function_class(FunctionIndex function) {
-  // cerr << "interrogate_function_class(" << function << ")\n";
-  return InterrogateDatabase::get_ptr()->get_function(function).get_class();
-}
-
-bool
-interrogate_function_is_unary_op(FunctionIndex function) {
-  // cerr << "interrogate_function_is_unary_op(" << function << ")\n";
-  return InterrogateDatabase::get_ptr()->get_function(function).is_unary_op();
-}
-
-bool
-interrogate_function_is_operator_typecast(FunctionIndex function) {
-  // cerr << "interrogate_function_is_operator_typecast(" << function <<
-  // ")\n";
-  return InterrogateDatabase::get_ptr()->get_function(function).is_operator_typecast();
-}
-
-bool
-interrogate_function_is_constructor(FunctionIndex function) {
-  // cerr << "interrogate_function_is_constructor(" << function << ")\n";
-  return InterrogateDatabase::get_ptr()->get_function(function).is_constructor();
-}
-
-bool
-interrogate_function_is_destructor(FunctionIndex function) {
-  // cerr << "interrogate_function_is_destructor(" << function << ")\n";
-  return InterrogateDatabase::get_ptr()->get_function(function).is_destructor();
-}
-
-bool
-interrogate_function_has_module_name(FunctionIndex function) {
-  // cerr << "interrogate_function_has_module_name(" << function << ")\n";
-  return InterrogateDatabase::get_ptr()->get_function(function).has_module_name();
-}
-
-const char *
-interrogate_function_module_name(FunctionIndex function) {
-  // cerr << "interrogate_function_module_name(" << function << ")\n";
-  return InterrogateDatabase::get_ptr()->get_function(function).get_module_name();
-}
-
-bool
-interrogate_function_has_library_name(FunctionIndex function) {
-  // cerr << "interrogate_function_has_library_name(" << function << ")\n";
-  return InterrogateDatabase::get_ptr()->get_function(function).has_library_name();
-}
-
-const char *
-interrogate_function_library_name(FunctionIndex function) {
-  // cerr << "interrogate_function_library_name(" << function << ")\n";
-  return InterrogateDatabase::get_ptr()->get_function(function).get_library_name();
-}
-
-
-
-bool
-interrogate_function_is_virtual(FunctionIndex function) {
-  // cerr << "interrogate_function_is_virtual(" << function << ")\n";
-  return InterrogateDatabase::get_ptr()->get_function(function).is_virtual();
-}
-
-int
-interrogate_function_number_of_c_wrappers(FunctionIndex function) {
-  // cerr << "interrogate_function_number_of_c_wrappers(" << function <<
-  // ")\n";
-  return InterrogateDatabase::get_ptr()->get_function(function).number_of_c_wrappers();
-}
-
-FunctionWrapperIndex
-interrogate_function_c_wrapper(FunctionIndex function, int n) {
-  // cerr << "interrogate_function_c_wrapper(" << function << ", " << n <<
-  // ")\n";
-  return InterrogateDatabase::get_ptr()->get_function(function).get_c_wrapper(n);
-}
-
-int
-interrogate_function_number_of_python_wrappers(FunctionIndex function) {
-  // cerr << "interrogate_function_number_of_python_wrappers(" << function <<
-  // ")\n";
-  return InterrogateDatabase::get_ptr()->get_function(function).number_of_python_wrappers();
-}
-
-FunctionWrapperIndex
-interrogate_function_python_wrapper(FunctionIndex function, int n) {
-  // cerr << "interrogate_function_python_wrapper(" << function << ", " << n
-  // << ")\n";
-  return InterrogateDatabase::get_ptr()->get_function(function).get_python_wrapper(n);
-}
-
-const char *
-interrogate_wrapper_name(FunctionWrapperIndex wrapper) {
-  // cerr << "interrogate_wrapper_name(" << wrapper << ")\n";
-  static string result;
-  result = InterrogateDatabase::get_ptr()->get_wrapper(wrapper).get_name();
-  return result.c_str();
-}
-
-FunctionIndex
-interrogate_wrapper_function(FunctionWrapperIndex wrapper) {
-  // cerr << "interrogate_wrapper_function(" << wrapper << ")\n";
-  return InterrogateDatabase::get_ptr()->get_wrapper(wrapper).get_function();
-}
-
-bool
-interrogate_wrapper_is_callable_by_name(FunctionWrapperIndex wrapper) {
-  // cerr << "interrogate_wrapper_is_callable_by_name(" << wrapper << ")\n";
-  return InterrogateDatabase::get_ptr()->get_wrapper(wrapper).is_callable_by_name();
-}
-
-bool
-interrogate_wrapper_is_copy_constructor(FunctionWrapperIndex wrapper) {
-  // cerr << "interrogate_wrapper_is_copy_constructor(" << wrapper << ")\n";
-  return InterrogateDatabase::get_ptr()->get_wrapper(wrapper).is_copy_constructor();
-}
-
-bool
-interrogate_wrapper_is_coerce_constructor(FunctionWrapperIndex wrapper) {
-  // cerr << "interrogate_wrapper_is_coerce_constructor(" << wrapper << ")\n";
-  return InterrogateDatabase::get_ptr()->get_wrapper(wrapper).is_coerce_constructor();
-}
-
-bool
-interrogate_wrapper_is_extension(FunctionWrapperIndex wrapper) {
-  // cerr << "interrogate_wrapper_is_extension(" << wrapper << ")\n";
-  return InterrogateDatabase::get_ptr()->get_wrapper(wrapper).is_extension();
-}
-
-bool
-interrogate_wrapper_is_deprecated(FunctionWrapperIndex wrapper) {
-  // cerr << "interrogate_wrapper_is_deprecated(" << wrapper << ")\n";
-  return InterrogateDatabase::get_ptr()->get_wrapper(wrapper).is_deprecated();
-}
-
-bool
-interrogate_wrapper_has_comment(FunctionWrapperIndex wrapper) {
-  // cerr << "interrogate_wrapper_has_comment(" << wrapper << ")\n";
-  return InterrogateDatabase::get_ptr()->get_wrapper(wrapper).has_comment();
-}
-
-const char *
-interrogate_wrapper_comment(FunctionWrapperIndex wrapper) {
-  // cerr << "interrogate_wrapper_comment(" << wrapper << ")\n";
-  return InterrogateDatabase::get_ptr()->get_wrapper(wrapper).get_comment().c_str();
-}
-
-bool
-interrogate_wrapper_has_return_value(FunctionWrapperIndex wrapper) {
-  // cerr << "interrogate_wrapper_has_return_value(" << wrapper << ")\n";
-  return InterrogateDatabase::get_ptr()->get_wrapper(wrapper).has_return_value();
-}
-
-TypeIndex
-interrogate_wrapper_return_type(FunctionWrapperIndex wrapper) {
-  // cerr << "interrogate_wrapper_return_type(" << wrapper << ")\n";
-  return InterrogateDatabase::get_ptr()->get_wrapper(wrapper).get_return_type();
-}
-
-bool
-interrogate_wrapper_caller_manages_return_value(FunctionWrapperIndex wrapper) {
-  // cerr << "interrogate_wrapper_caller_manages_return_value(" << wrapper <<
-  // ")\n";
-  return InterrogateDatabase::get_ptr()->get_wrapper(wrapper).caller_manages_return_value();
-}
-
-FunctionIndex
-interrogate_wrapper_return_value_destructor(FunctionWrapperIndex wrapper) {
-  // cerr << "interrogate_wrapper_return_value_destructor(" << wrapper <<
-  // ")\n";
-  return InterrogateDatabase::get_ptr()->get_wrapper(wrapper).get_return_value_destructor();
-}
-
-int
-interrogate_wrapper_number_of_parameters(FunctionWrapperIndex wrapper) {
-  // cerr << "interrogate_wrapper_number_of_parameters(" << wrapper << ")\n";
-  return InterrogateDatabase::get_ptr()->get_wrapper(wrapper).number_of_parameters();
-}
-
-TypeIndex
-interrogate_wrapper_parameter_type(FunctionWrapperIndex wrapper, int n) {
-  // cerr << "interrogate_wrapper_parameter_type(" << wrapper << ", " << n <<
-  // ")\n";
-  return InterrogateDatabase::get_ptr()->get_wrapper(wrapper).parameter_get_type(n);
-}
-
-bool
-interrogate_wrapper_parameter_has_name(FunctionWrapperIndex wrapper, int n) {
-  // cerr << "interrogate_wrapper_parameter_has_name(" << wrapper << ", " << n
-  // << ")\n";
-  return InterrogateDatabase::get_ptr()->get_wrapper(wrapper).parameter_has_name(n);
-}
-
-const char *
-interrogate_wrapper_parameter_name(FunctionWrapperIndex wrapper, int n) {
-  // cerr << "interrogate_wrapper_parameter_name(" << wrapper << ", " << n <<
-  // ")\n";
-  return InterrogateDatabase::get_ptr()->get_wrapper(wrapper).parameter_get_name(n).c_str();
-}
-
-bool
-interrogate_wrapper_parameter_is_this(FunctionWrapperIndex wrapper, int n) {
-  // cerr << "interrogate_wrapper_is_this(" << wrapper << ", " << n << ")\n";
-  return InterrogateDatabase::get_ptr()->get_wrapper(wrapper).parameter_is_this(n);
-}
-
-bool
-interrogate_wrapper_parameter_is_optional(FunctionWrapperIndex wrapper, int n) {
-  // cerr << "interrogate_wrapper_is_optional(" << wrapper << ", " << n << ")\n";
-  return InterrogateDatabase::get_ptr()->get_wrapper(wrapper).parameter_is_optional(n);
-}
-
-bool
-interrogate_wrapper_has_pointer(FunctionWrapperIndex wrapper) {
-  // cerr << "interrogate_wrapper_has_pointer(" << wrapper << ")\n";
-  return (InterrogateDatabase::get_ptr()->get_fptr(wrapper) != nullptr);
-}
-
-void *
-interrogate_wrapper_pointer(FunctionWrapperIndex wrapper) {
-  // cerr << "interrogate_wrapper_pointer(" << wrapper << ")\n";
-  return InterrogateDatabase::get_ptr()->get_fptr(wrapper);
-}
-
-const char *
-interrogate_wrapper_unique_name(FunctionWrapperIndex wrapper) {
-  // cerr << "interrogate_wrapper_unique_name(" << wrapper << ")\n";
-  static string result;
-  result = InterrogateDatabase::get_ptr()->get_wrapper(wrapper).get_unique_name();
-  return result.c_str();
-}
-
-FunctionWrapperIndex
-interrogate_get_wrapper_by_unique_name(const char *unique_name) {
-  // cerr << "interrogate_get_wrapper_by_unique_name(" << unique_name <<
-  // ")\n";
-  return InterrogateDatabase::get_ptr()->get_wrapper_by_unique_name(unique_name);
-}
-
-const char *
-interrogate_make_seq_seq_name(MakeSeqIndex make_seq) {
-  // cerr << "interrogate_make_seq_seq_name(" << make_seq << ")\n";
-  static string result;
-  result = InterrogateDatabase::get_ptr()->get_make_seq(make_seq).get_name();
-  return result.c_str();
-}
-
-const char *
-interrogate_make_seq_scoped_name(MakeSeqIndex make_seq) {
-  // cerr << "interrogate_make_seq_seq_name(" << make_seq << ")\n";
-  static string result;
-  result = InterrogateDatabase::get_ptr()->get_make_seq(make_seq).get_scoped_name();
-  return result.c_str();
-}
-
-bool
-interrogate_make_seq_has_comment(MakeSeqIndex make_seq) {
-  // cerr << "interrogate_make_seq_has_comment(" << make_seq << ")\n";
-  return InterrogateDatabase::get_ptr()->get_make_seq(make_seq).has_comment();
-}
-
-const char *
-interrogate_make_seq_comment(MakeSeqIndex make_seq) {
-  // cerr << "interrogate_make_seq_comment(" << make_seq << ")\n";
-  return InterrogateDatabase::get_ptr()->get_make_seq(make_seq).get_comment().c_str();
-}
-
-const char *
-interrogate_make_seq_num_name(MakeSeqIndex make_seq) {
-  // cerr << "interrogate_make_seq_num_name(" << make_seq << ")\n";
-  FunctionIndex function = InterrogateDatabase::get_ptr()->get_make_seq(make_seq).get_length_getter();
-  return interrogate_function_name(function);
-}
-
-const char *
-interrogate_make_seq_element_name(MakeSeqIndex make_seq) {
-  // cerr << "interrogate_make_seq_element_name(" << make_seq << ")\n";
-  FunctionIndex function = InterrogateDatabase::get_ptr()->get_make_seq(make_seq).get_element_getter();
-  return interrogate_function_name(function);
-}
-
-FunctionIndex
-interrogate_make_seq_num_getter(MakeSeqIndex make_seq) {
-  // cerr << "interrogate_make_seq_num_getter(" << make_seq << ")\n";
-  return InterrogateDatabase::get_ptr()->get_make_seq(make_seq).get_length_getter();
-}
-
-FunctionIndex
-interrogate_make_seq_element_getter(MakeSeqIndex make_seq) {
-  // cerr << "interrogate_make_seq_element_getter(" << make_seq << ")\n";
-  return InterrogateDatabase::get_ptr()->get_make_seq(make_seq).get_element_getter();
-}
-
-int
-interrogate_number_of_global_types() {
-  // cerr << "interrogate_number_of_global_types()\n";
-  return InterrogateDatabase::get_ptr()->get_num_global_types();
-}
-
-TypeIndex
-interrogate_get_global_type(int n) {
-  // cerr << "interrogate_get_global_type(" << n << ")\n";
-  return InterrogateDatabase::get_ptr()->get_global_type(n);
-}
-
-int
-interrogate_number_of_types() {
-  // cerr << "interrogate_number_of_types()\n";
-  return InterrogateDatabase::get_ptr()->get_num_all_types();
-}
-
-TypeIndex
-interrogate_get_type(int n) {
-  // cerr << "interrogate_get_type(" << n << ")\n";
-  return InterrogateDatabase::get_ptr()->get_all_type(n);
-}
-
-TypeIndex
-interrogate_get_type_by_name(const char *type_name) {
-  // cerr << "interrogate_get_type_by_name(" << type_name << ")\n";
-  return InterrogateDatabase::get_ptr()->lookup_type_by_name(type_name);
-}
-
-TypeIndex
-interrogate_get_type_by_scoped_name(const char *type_name) {
-  // cerr << "interrogate_get_type_by_scoped_name(" << type_name << ")\n";
-  return InterrogateDatabase::get_ptr()->lookup_type_by_scoped_name(type_name);
-}
-
-TypeIndex
-interrogate_get_type_by_true_name(const char *type_name) {
-  // cerr << "interrogate_get_type_by_true_name(" << type_name << ")\n";
-  return InterrogateDatabase::get_ptr()->lookup_type_by_true_name(type_name);
-}
-
-bool
-interrogate_type_is_global(TypeIndex type) {
-  // cerr << "interrogate_type_is_global(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).is_global();
-}
-
-bool
-interrogate_type_is_deprecated(TypeIndex type) {
-  // cerr << "interrogate_type_is_deprecated(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).is_deprecated();
-}
-
-const char *
-interrogate_type_name(TypeIndex type) {
-  // cerr << "interrogate_type_name(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).get_name().c_str();
-}
-
-const char *
-interrogate_type_scoped_name(TypeIndex type) {
-  // cerr << "interrogate_type_scoped_name(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).get_scoped_name().c_str();
-}
-
-const char *
-interrogate_type_true_name(TypeIndex type) {
-  // cerr << "interrogate_type_true_name(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).get_true_name().c_str();
-}
-
-bool
-interrogate_type_is_nested(TypeIndex type) {
-  // cerr << "interrogate_type_is_nested(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).is_nested();
-}
-
-TypeIndex
-interrogate_type_outer_class(TypeIndex type) {
-  // cerr << "interrogate_type_outer_class(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).get_outer_class();
-}
-
-bool
-interrogate_type_has_comment(TypeIndex type) {
-  // cerr << "interrogate_type_has_comment(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).has_comment();
-}
-
-const char *
-interrogate_type_comment(TypeIndex type) {
-  // cerr << "interrogate_type_comment(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).get_comment().c_str();
-}
-
-bool
-interrogate_type_has_module_name(TypeIndex type) {
-  // cerr << "interrogate_type_has_module_name(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).has_module_name();
-}
-
-const char *
-interrogate_type_module_name(TypeIndex type) {
-  // cerr << "interrogate_type_module_name(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).get_module_name();
-}
-
-bool
-interrogate_type_has_library_name(TypeIndex type) {
-  // cerr << "interrogate_type_has_library_name(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).has_library_name();
-}
-
-const char *
-interrogate_type_library_name(TypeIndex type) {
-  // cerr << "interrogate_type_library_name(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).get_library_name();
-}
-
-
-bool
-interrogate_type_is_atomic(TypeIndex type) {
-  // cerr << "interrogate_type_is_atomic(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).is_atomic();
-}
-
-AtomicToken
-interrogate_type_atomic_token(TypeIndex type) {
-  // cerr << "interrogate_type_atomic_token(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).get_atomic_token();
-}
-
-bool
-interrogate_type_is_unsigned(TypeIndex type) {
-  // cerr << "interrogate_type_is_unsigned(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).is_unsigned();
-}
-
-bool
-interrogate_type_is_signed(TypeIndex type) {
-  // cerr << "interrogate_type_is_signed(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).is_signed();
-}
-
-bool
-interrogate_type_is_long(TypeIndex type) {
-  // cerr << "interrogate_type_is_long(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).is_long();
-}
-
-bool
-interrogate_type_is_longlong(TypeIndex type) {
-  // cerr << "interrogate_type_is_longlong(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).is_longlong();
-}
-
-bool
-interrogate_type_is_short(TypeIndex type) {
-  // cerr << "interrogate_type_is_short(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).is_short();
-}
-
-bool
-interrogate_type_is_wrapped(TypeIndex type) {
-  // cerr << "interrogate_type_is_wrapped(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).is_wrapped();
-}
-
-bool
-interrogate_type_is_pointer(TypeIndex type) {
-  // cerr << "interrogate_type_is_pointer(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).is_pointer();
-}
-
-bool
-interrogate_type_is_const(TypeIndex type) {
-  // cerr << "interrogate_type_is_const(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).is_const();
-}
-
-bool
-interrogate_type_is_typedef(TypeIndex type) {
-  // cerr << "interrogate_type_is_typedef(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).is_typedef();
-}
-
-TypeIndex
-interrogate_type_wrapped_type(TypeIndex type) {
-  // cerr << "interrogate_type_wrapped_type(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).get_wrapped_type();
-}
-
-bool
-interrogate_type_is_array(TypeIndex type) {
-  // cerr << "interrogate_type_is_array(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).is_array();
-}
-
-int
-interrogate_type_array_size(TypeIndex type) {
-  // cerr << "interrogate_type_array_size(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).get_array_size();
-}
-
-bool
-interrogate_type_is_enum(TypeIndex type) {
-  // cerr << "interrogate_type_is_enum(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).is_enum();
-}
-
-bool
-interrogate_type_is_scoped_enum(TypeIndex type) {
-  // cerr << "interrogate_type_is_scoped_enum(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).is_scoped_enum();
-}
-
-int
-interrogate_type_number_of_enum_values(TypeIndex type) {
-  // cerr << "interrogate_type_number_of_enum_values(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).number_of_enum_values();
-}
-
-const char *
-interrogate_type_enum_value_name(TypeIndex type, int n) {
-  // cerr << "interrogate_type_enum_value_name(" << type << ", " << n <<
-  // ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).get_enum_value_name(n).c_str();
-}
-
-const char *
-interrogate_type_enum_value_scoped_name(TypeIndex type, int n) {
-  // cerr << "interrogate_type_enum_value_scoped_name(" << type << ", " << n
-  // << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).get_enum_value_scoped_name(n).c_str();
-}
-
-const char *
-interrogate_type_enum_value_comment(TypeIndex type, int n) {
-  // cerr << "interrogate_type_enum_value_comment(" << type << ", " << n <<
-  // ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).get_enum_value_comment(n).c_str();
-}
-
-int
-interrogate_type_enum_value(TypeIndex type, int n) {
-  // cerr << "interrogate_type_enum_value(" << type << ", " << n << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).get_enum_value(n);
-}
-
-bool
-interrogate_type_is_struct(TypeIndex type) {
-  // cerr << "interrogate_type_is_struct(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).is_struct();
-}
-
-bool
-interrogate_type_is_class(TypeIndex type) {
-  // cerr << "interrogate_type_is_class(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).is_class();
-}
-
-bool
-interrogate_type_is_union(TypeIndex type) {
-  // cerr << "interrogate_type_is_union(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).is_union();
-}
-
-bool
-interrogate_type_is_fully_defined(TypeIndex type) {
-  // cerr << "interrogate_type_is_fully_defined(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).is_fully_defined();
-}
-
-bool
-interrogate_type_is_unpublished(TypeIndex type) {
-  // cerr << "interrogate_type_is_unpublished(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).is_unpublished();
-}
-
-int
-interrogate_type_number_of_constructors(TypeIndex type) {
-  // cerr << "interrogate_type_number_of_constructors(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).number_of_constructors();
-}
-
-FunctionIndex
-interrogate_type_get_constructor(TypeIndex type, int n) {
-  // cerr << "interrogate_type_get_constructor(" << type << ", " << n <<
-  // ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).get_constructor(n);
-}
-
-bool
-interrogate_type_has_destructor(TypeIndex type) {
-  // cerr << "interrogate_type_has_destructor(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).has_destructor();
-}
-
-bool
-interrogate_type_destructor_is_inherited(TypeIndex type) {
-  // cerr << "interrogate_type_destructor_is_inherited(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).destructor_is_inherited();
-}
-
-FunctionIndex
-interrogate_type_get_destructor(TypeIndex type) {
-  // cerr << "interrogate_type_get_destructor(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).get_destructor();
-}
-
-int
-interrogate_type_number_of_elements(TypeIndex type) {
-  // cerr << "interrogate_type_number_of_elements(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).number_of_elements();
-}
-
-ElementIndex
-interrogate_type_get_element(TypeIndex type, int n) {
-  // cerr << "interrogate_type_get_element(" << type << ", " << n << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).get_element(n);
-}
-
-int
-interrogate_type_number_of_methods(TypeIndex type) {
-  // cerr << "interrogate_type_number_of_methods(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).number_of_methods();
-}
-
-FunctionIndex
-interrogate_type_get_method(TypeIndex type, int n) {
-  // cerr << "interrogate_type_get_method(" << type << ", " << n << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).get_method(n);
-}
-
-int
-interrogate_type_number_of_make_seqs(TypeIndex type) {
-  // cerr << "interrogate_type_number_of_make_seqs(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).number_of_make_seqs();
-}
-
-MakeSeqIndex
-interrogate_type_get_make_seq(TypeIndex type, int n) {
-  // cerr << "interrogate_type_get_make_seq(" << type << ", " << n << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).get_make_seq(n);
-}
-
-int
-interrogate_type_number_of_casts(TypeIndex type) {
-  // cerr << "interrogate_type_number_of_casts(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).number_of_casts();
-}
-
-FunctionIndex
-interrogate_type_get_cast(TypeIndex type, int n) {
-  // cerr << "interrogate_type_get_cast(" << type << ", " << n << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).get_cast(n);
-}
-
-int
-interrogate_type_number_of_derivations(TypeIndex type) {
-  // cerr << "interrogate_type_number_of_derivations(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).number_of_derivations();
-}
-
-TypeIndex
-interrogate_type_get_derivation(TypeIndex type, int n) {
-  // cerr << "interrogate_type_get_derivation(" << type << ", " << n << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).get_derivation(n);
-}
-
-bool
-interrogate_type_is_final(TypeIndex type) {
-  // cerr << "interrogate_type_is_final(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).is_final();
-}
-
-bool
-interrogate_type_derivation_has_upcast(TypeIndex type, int n) {
-  // cerr << "interrogate_type_derivation_has_upcast(" << type << ", " << n <<
-  // ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).derivation_has_upcast(n);
-}
-
-FunctionIndex
-interrogate_type_get_upcast(TypeIndex type, int n) {
-  // cerr << "interrogate_type_get_upcast(" << type << ", " << n << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).derivation_get_upcast(n);
-}
-
-bool
-interrogate_type_derivation_downcast_is_impossible(TypeIndex type, int n) {
-  // cerr << "interrogate_type_derivation_downcast_is_impossible(" << type <<
-  // ", " << n << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).derivation_downcast_is_impossible(n);
-}
-
-bool
-interrogate_type_derivation_has_downcast(TypeIndex type, int n) {
-  // cerr << "interrogate_type_derivation_has_downcast(" << type << ", " << n
-  // << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).derivation_has_downcast(n);
-}
-
-FunctionIndex
-interrogate_type_get_downcast(TypeIndex type, int n) {
-  // cerr << "interrogate_type_get_downcast(" << type << ", " << n << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).derivation_get_downcast(n);
-}
-
-int
-interrogate_type_number_of_nested_types(TypeIndex type) {
-  // cerr << "interrogate_type_number_of_nested_types(" << type << ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).number_of_nested_types();
-}
-
-TypeIndex
-interrogate_type_get_nested_type(TypeIndex type, int n) {
-  // cerr << "interrogate_type_get_nested_type(" << type << ", " << n <<
-  // ")\n";
-  return InterrogateDatabase::get_ptr()->get_type(type).get_nested_type(n);
-}

+ 0 - 581
dtool/src/interrogatedb/interrogate_interface.h

@@ -1,581 +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 interrogate_interface.h
- * @author frang
- * @date 1999-11-09
- */
-
-#ifndef INTERROGATE_INTERFACE_H
-#define INTERROGATE_INTERFACE_H
-
-#include "dtoolbase.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// This file defines the interface to the interrogate database.  This database
-// is generated by running interrogate on a package's source code; interrogate
-// parses the C++ syntax, determines the public interface, generates C-style
-// wrapper functions where necessary, and builds up a table of functions and
-// classes and their relationships.
-
-/*
- * Some of this data (in particular, the wrapper functions, and the table of
- * unique names for these functions) is linked in along with the codebase,
- * permanently a part of the library file, and is always available; the rest
- * of it is stored in external files (named *.in) and read in when needed.
- * For this reason, most of the interface functions defined here will force a
- * load of the complete interrogate database the first time any of them are
- * called.  The three exceptions are noted below; they are
- * interrogate_wrapper_has_pointer(), interrogate_wrapper_pointer(), and
- * interrogate_get_wrapper_by_unique_name().
- */
-
-
-// The interface here is intentionally made to be as simple as possible, to
-// maximize portability.  All that is required of a scripting language is a
-// foreign function interface capable of calling C functions.
-
-
-// In general, the interrogate database consists of a number of query
-// functions that allow the caller to walk through the list of available
-// types, functions, manifests, etc.  For each of these, a unique index number
-// is returned; this index number may then be used to query details about the
-// type, function, etc.  The index numbers are only guaranteed to remain
-// unchanged during a particular session; from one session to another they may
-// differ.
-
-// All index numbers are ordinary integers.  Each has a unique typedef here
-// for clarity of meaning, but they may be treated as ordinary integers by the
-// caller.
-typedef int ManifestIndex;
-typedef int ElementIndex;
-typedef int TypeIndex;
-typedef int FunctionIndex;
-typedef int FunctionWrapperIndex;
-typedef int MakeSeqIndex;
-
-// Atomic types are those that are built in to C.  This enumerated value is
-// returned by interrogate_type_atomic_token() when a type is known to be one
-// of the atomic types.
-enum AtomicToken {
-  AT_not_atomic = 0,
-  AT_int = 1,
-  AT_float = 2,
-  AT_double = 3,
-  AT_bool = 4,
-  AT_char = 5,
-  AT_void = 6,
-
-  // There isn't an atomic string type in C, but there is one in almost all
-  // other languages.  If -string is supplied to the interrogate command line,
-  // functions may be reported as returning and accepting objects of type
-  // atomic string.  For the C calling convention wrappers, atomic string
-  // means (const char *); for other calling convention wrappers, atomic
-  // string means whatever the native string representation is.
-  AT_string = 7,
-
-  AT_longlong = 8,
-
-  // This is not a type that C has, but C++ and many scripting languages do;
-  // it indicates a null value, or the absence of any value.
-  AT_null = 9,
-};
-
-EXPCL_INTERROGATEDB void interrogate_add_search_directory(const char *dirname);
-EXPCL_INTERROGATEDB void interrogate_add_search_path(const char *pathstring);
-EXPCL_INTERROGATEDB bool interrogate_error_flag();
-
-// Manifest Symbols
-
-/*
- * These correspond to #define constants that appear in the C code.  (These
- * are only the manifest constants--those #define's that take no parameters.
- * Manifest functions, #define's that take one or more parameters, are not
- * exported.)  They cannot be set, of course, but they often have a meaningful
- * value that may be get.  The scripting language may choose to get the value
- * as a literal string via interrogate_manifest_definition(), or as a value of
- * a particular type (whatever type interrogate thinks it is), as returned by
- * the getter function given by interrogate_manifest_getter().
- */
-
-EXPCL_INTERROGATEDB int interrogate_number_of_manifests();
-EXPCL_INTERROGATEDB ManifestIndex interrogate_get_manifest(int n);
-EXPCL_INTERROGATEDB ManifestIndex interrogate_get_manifest_by_name(const char *manifest_name);
-EXPCL_INTERROGATEDB const char *interrogate_manifest_name(ManifestIndex manifest);
-EXPCL_INTERROGATEDB const char *interrogate_manifest_definition(ManifestIndex manifest);
-EXPCL_INTERROGATEDB bool interrogate_manifest_has_type(ManifestIndex manifest);
-EXPCL_INTERROGATEDB TypeIndex interrogate_manifest_get_type(ManifestIndex manifest);
-EXPCL_INTERROGATEDB bool interrogate_manifest_has_getter(ManifestIndex manifest);
-EXPCL_INTERROGATEDB FunctionIndex interrogate_manifest_getter(ManifestIndex manifest);
-
-// An exception is made for manifest constants that have an integer type
-// value, since these are so common.  The scripting language can query these
-// values directly, which saves having to generate a wrapper function for each
-// stupid little manifest.  In this case, there will be no getter function
-// available.
-EXPCL_INTERROGATEDB bool interrogate_manifest_has_int_value(ManifestIndex manifest);
-EXPCL_INTERROGATEDB int interrogate_manifest_get_int_value(ManifestIndex manifest);
-
-
-// Data Elements
-
-// These correspond to data members of a class, or global data elements.
-// Interrogate automatically generates a getter function and, if possible, a
-// setter function.
-
-EXPCL_INTERROGATEDB const char *interrogate_element_name(ElementIndex element);
-EXPCL_INTERROGATEDB const char *interrogate_element_scoped_name(ElementIndex element);
-EXPCL_INTERROGATEDB bool interrogate_element_has_comment(ElementIndex element);
-EXPCL_INTERROGATEDB const char *interrogate_element_comment(ElementIndex element);
-EXPCL_INTERROGATEDB ElementIndex interrogate_get_element_by_name(const char *element_name);
-EXPCL_INTERROGATEDB ElementIndex interrogate_get_element_by_scoped_name(const char *element_name);
-
-// Be careful with this function.  The element's bare type is not likely to be
-// directly useful to the scripting language.  This is a different answer than
-// the return value of the getter.
-
-// The element type might well be something concrete that the scripting
-// language can't handle directly, e.g.  a Node, while the getter will return
-// (and the setter accept) a pointer to a Node, which is what the scripting
-// language actually works with.
-EXPCL_INTERROGATEDB TypeIndex interrogate_element_type(ElementIndex element);
-
-EXPCL_INTERROGATEDB bool interrogate_element_has_getter(ElementIndex element);
-EXPCL_INTERROGATEDB FunctionIndex interrogate_element_getter(ElementIndex element);
-EXPCL_INTERROGATEDB bool interrogate_element_has_setter(ElementIndex element);
-EXPCL_INTERROGATEDB FunctionIndex interrogate_element_setter(ElementIndex element);
-EXPCL_INTERROGATEDB bool interrogate_element_has_has_function(ElementIndex element);
-EXPCL_INTERROGATEDB FunctionIndex interrogate_element_has_function(ElementIndex element);
-EXPCL_INTERROGATEDB bool interrogate_element_has_clear_function(ElementIndex element);
-EXPCL_INTERROGATEDB FunctionIndex interrogate_element_clear_function(ElementIndex element);
-EXPCL_INTERROGATEDB bool interrogate_element_has_del_function(ElementIndex element);
-EXPCL_INTERROGATEDB FunctionIndex interrogate_element_del_function(ElementIndex element);
-EXPCL_INTERROGATEDB bool interrogate_element_has_insert_function(ElementIndex element);
-EXPCL_INTERROGATEDB FunctionIndex interrogate_element_insert_function(ElementIndex element);
-EXPCL_INTERROGATEDB bool interrogate_element_has_getkey_function(ElementIndex element);
-EXPCL_INTERROGATEDB FunctionIndex interrogate_element_getkey_function(ElementIndex element);
-EXPCL_INTERROGATEDB FunctionIndex interrogate_element_length_function(ElementIndex element);
-
-EXPCL_INTERROGATEDB bool interrogate_element_is_sequence(ElementIndex element);
-EXPCL_INTERROGATEDB bool interrogate_element_is_mapping(ElementIndex element);
-
-// Global Data
-
-// This is the list of global data elements.
-
-EXPCL_INTERROGATEDB int interrogate_number_of_globals();
-EXPCL_INTERROGATEDB ElementIndex interrogate_get_global(int n);
-
-// Functions
-
-// There is a unique FunctionIndex associated with each of the functions that
-// interrogate knows about.  This includes member functions, nonmember
-// functions, synthesized getters and setters, and upcastdowncast functions.
-
-
-// These are the global (nonmember) functions that appear outside of any class
-// definition.
-EXPCL_INTERROGATEDB int interrogate_number_of_global_functions();
-EXPCL_INTERROGATEDB FunctionIndex interrogate_get_global_function(int n);
-
-// This can be used to traverse through *all* the functions known to
-// interrogate.  It's usually not what you want, since this includes global
-// functions, class methods, and synthesized functions like upcasts and
-// downcasts.  You probably want to use instead
-// interrogate_number_of_global_functions(), above.
-EXPCL_INTERROGATEDB int interrogate_number_of_functions();
-EXPCL_INTERROGATEDB FunctionIndex interrogate_get_function(int n);
-
-// This is the function's name.  It is not unique; it may be shared between
-// multiple different functions that have the same name but different
-// parameter types (this is C++'s function overloading). Two different classes
-// might also have member functions that have the same name, or the same name
-// as a global function (but also see the scoped_name, below).
-EXPCL_INTERROGATEDB const char *interrogate_function_name(FunctionIndex function);
-
-// The scoped name is the function name prefixed with the name of the class
-// that includes the function, if the function is a class method.  If it is a
-// global function, the scoped name is the same as the name returned above.
-// In the absence of C++ function overloading, this name will be unique to
-// each function.
-EXPCL_INTERROGATEDB const char *interrogate_function_scoped_name(FunctionIndex function);
-
-// This returns the C++ comment written for the function, either in the header
-// file or in the .C file, or both.
-EXPCL_INTERROGATEDB bool interrogate_function_has_comment(FunctionIndex function);
-EXPCL_INTERROGATEDB const char *interrogate_function_comment(FunctionIndex function);
-
-// This defines the function prototype as it appears in the C++ source, useful
-// primarily for documentation purposes.
-EXPCL_INTERROGATEDB const char *interrogate_function_prototype(FunctionIndex function);
-
-// This can be used to determine the class that the function is a method for,
-// if the function is a class method.
-EXPCL_INTERROGATEDB bool interrogate_function_is_method(FunctionIndex function);
-EXPCL_INTERROGATEDB TypeIndex interrogate_function_class(FunctionIndex function);
-EXPCL_INTERROGATEDB bool interrogate_function_is_unary_op(FunctionIndex function);
-EXPCL_INTERROGATEDB bool interrogate_function_is_operator_typecast(FunctionIndex function);
-EXPCL_INTERROGATEDB bool interrogate_function_is_constructor(FunctionIndex function);
-EXPCL_INTERROGATEDB bool interrogate_function_is_destructor(FunctionIndex function);
-
-// This returns the module name reported for the function, if available.
-EXPCL_INTERROGATEDB bool interrogate_function_has_module_name(FunctionIndex function);
-EXPCL_INTERROGATEDB const char *interrogate_function_module_name(FunctionIndex function);
-
-// This returns the library name reported for the function, if available.
-EXPCL_INTERROGATEDB bool interrogate_function_has_library_name(FunctionIndex function);
-EXPCL_INTERROGATEDB const char *interrogate_function_library_name(FunctionIndex function);
-
-// This is true for virtual member functions.  It's not likely that this will
-// be important to the scripting language.
-EXPCL_INTERROGATEDB bool interrogate_function_is_virtual(FunctionIndex function);
-
-
-// The actual callable function interface is defined via one or more wrappers
-// for each function.  (There might be multiple wrappers for the same function
-// to allow for default parameter values.)
-
-// At present, interrogate can generate wrappers that use the C calling
-// convention or the Python calling convention.  The set of wrappers that will
-// actually be available depends on the parameters passed to the interrogate
-// command line.
-EXPCL_INTERROGATEDB int interrogate_function_number_of_c_wrappers(FunctionIndex function);
-EXPCL_INTERROGATEDB FunctionWrapperIndex interrogate_function_c_wrapper(FunctionIndex function, int n);
-
-EXPCL_INTERROGATEDB int interrogate_function_number_of_python_wrappers(FunctionIndex function);
-EXPCL_INTERROGATEDB FunctionWrapperIndex interrogate_function_python_wrapper(FunctionIndex function, int n);
-
-// Function wrappers
-
-// These define the way to call a given function.  Depending on the parameters
-// supplied to interrogate, a function wrapper may be able to supply either a
-// void * pointer to the function, or the name of the function in the library,
-// or both.
-
-
-// This returns the actual name of the wrapper function, as opposed to the
-// name of the function it wraps.  It's probably not terribly useful to the
-// scripting language, unless the -fnames option was given to interrogate, in
-// which case this name may be used to call the wrapper function (see
-// is_callable_by_name, below).  It will usually be an ugly hashed name, not
-// intended for human consumption.
-
-// Don't confuse this with the unique_name, below.  The two are related, but
-// not identical.
-EXPCL_INTERROGATEDB const char *interrogate_wrapper_name(FunctionWrapperIndex wrapper);
-
-// Returns the function that this wrapper belongs to.
-EXPCL_INTERROGATEDB FunctionIndex interrogate_wrapper_function(FunctionWrapperIndex wrapper);
-
-// This returns true if -fnames was given to interrogate, making the wrapper
-// function callable directly by its name.
-EXPCL_INTERROGATEDB bool interrogate_wrapper_is_callable_by_name(FunctionWrapperIndex wrapper);
-
-// This returns true if this is a copy constructor.
-EXPCL_INTERROGATEDB bool interrogate_wrapper_is_copy_constructor(FunctionWrapperIndex wrapper);
-
-// This returns true if this is a constructor that is not marked "explicit".
-EXPCL_INTERROGATEDB bool interrogate_wrapper_is_coerce_constructor(FunctionWrapperIndex wrapper);
-
-// This returns true if this is an extension function, rather than a real
-// function defined in the C++ code.
-EXPCL_INTERROGATEDB bool interrogate_wrapper_is_extension(FunctionWrapperIndex wrapper);
-
-// This returns true if function is marked as deprecated.
-EXPCL_INTERROGATEDB bool interrogate_wrapper_is_deprecated(FunctionWrapperIndex wrapper);
-
-// This returns the C++ comment written for the function wrapper, usually from
-// the .cpp file.  There may be a different comment for each overload of a
-// given function.
-EXPCL_INTERROGATEDB bool interrogate_wrapper_has_comment(FunctionWrapperIndex wrapper);
-EXPCL_INTERROGATEDB const char *interrogate_wrapper_comment(FunctionWrapperIndex wrapper);
-
-// Every function wrapper has zero or more parameters and may or may not have
-// a return value.  Each parameter has a type and may or may not have a name.
-// For member functions, the first parameter may be a 'this' parameter, which
-// should receive a pointer to the class object.  (If a member function does
-// not have a 'this' parameter as its first parameter, it is a static member
-// function, also called a class method.)
-
-EXPCL_INTERROGATEDB bool interrogate_wrapper_has_return_value(FunctionWrapperIndex wrapper);
-EXPCL_INTERROGATEDB TypeIndex interrogate_wrapper_return_type(FunctionWrapperIndex wrapper);
-
-/*
- * Sometimes interrogate must synthesize a wrapper that allocates its return
- * value from the free store.  Other times (especially if -refcount is
- * supplied to interrogate), interrogate will automatically increment the
- * count of a reference-counted object that it returns.  In cases like these,
- * interrogate_wrapper_caller_manages_return_value() will return true, and it
- * is the responsibility of the scripting language to eventually call the
- * destructor supplied by interrogate_wrapper_return_value_destructor() on
- * this value when it is no longer needed (which will generally be the same
- * destructor as that for the class).  Otherwise, this function will return
- * false, and the scripting language should *not* call any destructor on this
- * value.
- */
-EXPCL_INTERROGATEDB bool interrogate_wrapper_caller_manages_return_value(FunctionWrapperIndex wrapper);
-EXPCL_INTERROGATEDB FunctionIndex interrogate_wrapper_return_value_destructor(FunctionWrapperIndex wrapper);
-
-// These define the parameters of the function.
-EXPCL_INTERROGATEDB int interrogate_wrapper_number_of_parameters(FunctionWrapperIndex wrapper);
-EXPCL_INTERROGATEDB TypeIndex interrogate_wrapper_parameter_type(FunctionWrapperIndex wrapper, int n);
-EXPCL_INTERROGATEDB bool interrogate_wrapper_parameter_has_name(FunctionWrapperIndex wrapper, int n);
-EXPCL_INTERROGATEDB const char *interrogate_wrapper_parameter_name(FunctionWrapperIndex wrapper, int n);
-EXPCL_INTERROGATEDB bool interrogate_wrapper_parameter_is_this(FunctionWrapperIndex wrapper, int n);
-EXPCL_INTERROGATEDB bool interrogate_wrapper_parameter_is_optional(FunctionWrapperIndex wrapper, int n);
-
-// This returns a pointer to a function that may be called to invoke the
-// function, if the -fptrs option to return function pointers was specified to
-// interrogate.  Be sure to push the required parameters on the stack,
-// according to the calling convention, before calling the function.
-
-// These two functions may be called without forcing a load of the complete
-// interrogate database.
-EXPCL_INTERROGATEDB bool interrogate_wrapper_has_pointer(FunctionWrapperIndex wrapper);
-EXPCL_INTERROGATEDB void *interrogate_wrapper_pointer(FunctionWrapperIndex wrapper);
-
-// This function will return a name that is guaranteed to be unique to this
-// particular function wrapper, and that will (usually) be consistent across
-// multiple runtime sessions.  (It will only change between sessions if the
-// database was regenerated in the interim with some new function that
-// happened to introduce a hash conflict.)
-
-// The unique name is an ugly hashed name, not safe for human consumption.
-// Its sole purpose is to provide some consistent way to identify function
-// wrappers between sessions.
-EXPCL_INTERROGATEDB const char *interrogate_wrapper_unique_name(FunctionWrapperIndex wrapper);
-
-// This function provides a reverse-lookup on the above unique name, returning
-// the wrapper index corresponding to the given name.  It depends on data
-// having been compiled directly into the library, and thus is only available
-// if the option -unique-names was given to interrogate.
-
-// This function may be called without forcing a load of the complete
-// interrogate database.
-EXPCL_INTERROGATEDB FunctionWrapperIndex interrogate_get_wrapper_by_unique_name(const char *unique_name);
-
-// MakeSeqs
-
-// These are special synthesized methods that iterate through a list.  They
-// are generated in C++ code via the MAKE_SEQ macro.  The normal pattern is
-// that a pair of actual C++ methods like get_num_things() and get_thing(n)
-// are used to synthesize a new method called get_things().
-
-EXPCL_INTERROGATEDB const char *interrogate_make_seq_seq_name(MakeSeqIndex make_seq);
-EXPCL_INTERROGATEDB const char *interrogate_make_seq_scoped_name(MakeSeqIndex make_seq);
-EXPCL_INTERROGATEDB bool interrogate_make_seq_has_comment(ElementIndex element);
-EXPCL_INTERROGATEDB const char *interrogate_make_seq_comment(ElementIndex element);
-// The name of the real method that returns the length, e.g.  "get_num_things"
-EXPCL_INTERROGATEDB const char *interrogate_make_seq_num_name(MakeSeqIndex make_seq);
-// The name of the real method that returns the nth element, e.g.  "get_thing"
-EXPCL_INTERROGATEDB const char *interrogate_make_seq_element_name(MakeSeqIndex make_seq);
-EXPCL_INTERROGATEDB FunctionIndex interrogate_make_seq_num_getter(MakeSeqIndex make_seq);
-EXPCL_INTERROGATEDB FunctionIndex interrogate_make_seq_element_getter(MakeSeqIndex make_seq);
-
-// Types
-
-// These are all the types that interrogate knows about.  This includes atomic
-// types like ints and floats, type wrappers like pointers and const pointers,
-// enumerated types, and classes.
-
-/*
- * Two lists of types are maintained: the list of global types, which includes
- * only those types intended to be wrapped in the API (for instance, all of
- * the classes).  The second list is the complete list of all types, which
- * probably does not need to be traversed--this includes *all* types known to
- * the interrogate database, including simple types and pointers and const
- * pointers to classes.  These types are necessary to fully define all of the
- * function parameters, but need not themselves be wrapped.
- */
-
-EXPCL_INTERROGATEDB int interrogate_number_of_global_types();
-EXPCL_INTERROGATEDB TypeIndex interrogate_get_global_type(int n);
-EXPCL_INTERROGATEDB int interrogate_number_of_types();
-EXPCL_INTERROGATEDB TypeIndex interrogate_get_type(int n);
-EXPCL_INTERROGATEDB TypeIndex interrogate_get_type_by_name(const char *type_name);
-EXPCL_INTERROGATEDB TypeIndex interrogate_get_type_by_scoped_name(const char *type_name);
-EXPCL_INTERROGATEDB TypeIndex interrogate_get_type_by_true_name(const char *type_name);
-EXPCL_INTERROGATEDB bool interrogate_type_is_global(TypeIndex type);
-EXPCL_INTERROGATEDB bool interrogate_type_is_deprecated(TypeIndex type);
-EXPCL_INTERROGATEDB const char *interrogate_type_name(TypeIndex type);
-EXPCL_INTERROGATEDB const char *interrogate_type_scoped_name(TypeIndex type);
-EXPCL_INTERROGATEDB const char *interrogate_type_true_name(TypeIndex type);
-
-// A given type might be a nested type, meaning it is entirely defined within
-// (and scoped within) some different C++ class.  In this case, the
-// type_name() will return the local name of the type as seen within the
-// class, while the scoped_name() will return the fully-qualified name of the
-// type, and is_nested() and outer_class() can be used to determine the class
-// it is nested within.
-EXPCL_INTERROGATEDB bool interrogate_type_is_nested(TypeIndex type);
-EXPCL_INTERROGATEDB TypeIndex interrogate_type_outer_class(TypeIndex type);
-
-EXPCL_INTERROGATEDB bool interrogate_type_has_comment(TypeIndex type);
-EXPCL_INTERROGATEDB const char *interrogate_type_comment(TypeIndex type);
-
-// This returns the module name reported for the type, if available.
-EXPCL_INTERROGATEDB bool interrogate_type_has_module_name(TypeIndex type);
-EXPCL_INTERROGATEDB const char *interrogate_type_module_name(TypeIndex type);
-
-// This returns the library name reported for the type, if available.
-EXPCL_INTERROGATEDB bool interrogate_type_has_library_name(TypeIndex type);
-EXPCL_INTERROGATEDB const char *interrogate_type_library_name(TypeIndex type);
-
-
-// If interrogate_type_is_atomic() returns true, the type is one of the basic
-// C types enumerated in AtomicToken, above.  The type may then be further
-// modified by one or more of unsigned, signed, long, longlong, or short.
-// However, it will not be a pointer.
-EXPCL_INTERROGATEDB bool interrogate_type_is_atomic(TypeIndex type);
-EXPCL_INTERROGATEDB AtomicToken interrogate_type_atomic_token(TypeIndex type);
-EXPCL_INTERROGATEDB bool interrogate_type_is_unsigned(TypeIndex type);
-EXPCL_INTERROGATEDB bool interrogate_type_is_signed(TypeIndex type);
-EXPCL_INTERROGATEDB bool interrogate_type_is_long(TypeIndex type);
-EXPCL_INTERROGATEDB bool interrogate_type_is_longlong(TypeIndex type);
-EXPCL_INTERROGATEDB bool interrogate_type_is_short(TypeIndex type);
-
-// If interrogate_type_is_wrapped() returns true, this is a composite type
-// "wrapped" around some simpler type, for instance a pointer to a class.  The
-// type will be either a pointer or a const wrapper--it cannot be a
-// combination of these.  (When combinations are required, they use multiple
-// wrappers.  A const char pointer, for example, is represented as a pointer
-// wrapper around a const wrapper around an atomic char.)
-EXPCL_INTERROGATEDB bool interrogate_type_is_wrapped(TypeIndex type);
-EXPCL_INTERROGATEDB bool interrogate_type_is_pointer(TypeIndex type);
-EXPCL_INTERROGATEDB bool interrogate_type_is_const(TypeIndex type);
-EXPCL_INTERROGATEDB bool interrogate_type_is_typedef(TypeIndex type);
-EXPCL_INTERROGATEDB TypeIndex interrogate_type_wrapped_type(TypeIndex type);
-
-// If interrogate_type_is_array() returns true, this is an array type.
-EXPCL_INTERROGATEDB bool interrogate_type_is_array(TypeIndex type);
-EXPCL_INTERROGATEDB int interrogate_type_array_size(TypeIndex type);
-
-// If interrogate_type_is_enum() returns true, this is an enumerated type,
-// which means it may take any one of a number of named integer values.
-EXPCL_INTERROGATEDB bool interrogate_type_is_enum(TypeIndex type);
-EXPCL_INTERROGATEDB bool interrogate_type_is_scoped_enum(TypeIndex type);
-EXPCL_INTERROGATEDB int interrogate_type_number_of_enum_values(TypeIndex type);
-EXPCL_INTERROGATEDB const char *interrogate_type_enum_value_name(TypeIndex type, int n);
-EXPCL_INTERROGATEDB const char *interrogate_type_enum_value_scoped_name(TypeIndex type, int n);
-EXPCL_INTERROGATEDB const char *interrogate_type_enum_value_comment(TypeIndex type, int n);
-EXPCL_INTERROGATEDB int interrogate_type_enum_value(TypeIndex type, int n);
-
-// If none of the above is true, the type is some extension type.  It may be a
-// struct, class, or union (and the distinction between these three is not
-// likely to be important to the scripting language).  In any case, it may
-// contain zero or more constructors, zero or one destructor, zero or more
-// member functions, and zero or more data members; all of the remaining type
-// functions may apply.
-EXPCL_INTERROGATEDB bool interrogate_type_is_struct(TypeIndex type);
-EXPCL_INTERROGATEDB bool interrogate_type_is_class(TypeIndex type);
-EXPCL_INTERROGATEDB bool interrogate_type_is_union(TypeIndex type);
-
-// If is_fully_defined() returns false, this classstruct was a forward
-// reference, and we really don't know anything about it.  (In this case, it
-// will appear to have no methods or members.)
-EXPCL_INTERROGATEDB bool interrogate_type_is_fully_defined(TypeIndex type);
-
-// If is_unpublished() returns false, the classstruct is unknown because it
-// was not marked to be published (or, in promiscuous mode, it is a protected
-// or private nested class).
-EXPCL_INTERROGATEDB bool interrogate_type_is_unpublished(TypeIndex type);
-
-/*
- * Otherwise, especially if the type is a struct or class, we may have a
- * number of member functions, including zero or more constructors and zero or
- * one destructor.  A constructor function may be called to allocate a new
- * instance of the type; its return value will be a pointer to the new
- * instance.  The destructor may be called to destroy the instance; however,
- * it usually should not be explicitly called by the user, since the proper
- * support of the interrogate_caller_manages_return_value() interface, above,
- * will ensure that the appropriate destructors are called when they should
- * be.
- */
-
-/*
- * In certain circumstances, the destructor might be inherited from a parent
- * or ancestor class.  This happens when the destructor wrapper from the
- * ancestor class is an acceptable substitute for this destructor; this is
- * only possible in the case of a virtual C++ destructor.  In this case, the
- * destructor returned here will be the same function index as the one
- * returned by the ancestor class, and
- * interrogate_type_destructor_is_inherited() will return true for this class.
- */
-EXPCL_INTERROGATEDB int interrogate_type_number_of_constructors(TypeIndex type);
-EXPCL_INTERROGATEDB FunctionIndex interrogate_type_get_constructor(TypeIndex type, int n);
-EXPCL_INTERROGATEDB bool interrogate_type_has_destructor(TypeIndex type);
-EXPCL_INTERROGATEDB bool interrogate_type_destructor_is_inherited(TypeIndex type);
-EXPCL_INTERROGATEDB FunctionIndex interrogate_type_get_destructor(TypeIndex type);
-
-// This is the set of exposed data elements in the struct or class.
-EXPCL_INTERROGATEDB int interrogate_type_number_of_elements(TypeIndex type);
-EXPCL_INTERROGATEDB ElementIndex interrogate_type_get_element(TypeIndex type, int n);
-
-// This is the set of exposed member functions in the struct or class.
-EXPCL_INTERROGATEDB int interrogate_type_number_of_methods(TypeIndex type);
-EXPCL_INTERROGATEDB FunctionIndex interrogate_type_get_method(TypeIndex type, int n);
-
-// This is the set of MAKE_SEQ wrappers in the struct or class.
-EXPCL_INTERROGATEDB int interrogate_type_number_of_make_seqs(TypeIndex type);
-EXPCL_INTERROGATEDB MakeSeqIndex interrogate_type_get_make_seq(TypeIndex type, int n);
-
-// A C++ class may also define a number of explicit cast operators, which
-// define how to convert an object of this type to an object of some other
-// type (the type can be inferred by the return type of the cast function).
-// This is not related to upcast and downcast, defined below.
-EXPCL_INTERROGATEDB int interrogate_type_number_of_casts(TypeIndex type);
-EXPCL_INTERROGATEDB FunctionIndex interrogate_type_get_cast(TypeIndex type, int n);
-
-// A C++ class may inherit from zero or more base classes.  This defines the
-// list of base classes for this particular type.
-EXPCL_INTERROGATEDB int interrogate_type_number_of_derivations(TypeIndex type);
-EXPCL_INTERROGATEDB TypeIndex interrogate_type_get_derivation(TypeIndex type, int n);
-EXPCL_INTERROGATEDB bool interrogate_type_is_final(TypeIndex type);
-
-// For each base class, we might need to define an explicit upcast or downcast
-// operation to convert the pointer to the derived class to an appropriate
-// pointer to its base class (upcast) or vice-versa (downcast).  This is
-// particularly true in the presence of multiple inheritance or virtual
-// inheritance, in which case you cannot simply use the same pointer as either
-// type.
-
-// If interrogate_type_derivation_has_upcast() returns true for a particular
-// typederivation combination, you must use the indicated upcast function to
-// convert pointers of this type to pointers of the base type before calling
-// any of the inherited methods from the base class.  If this returns false,
-// you may simply use the same pointer as either a derived class pointer or a
-// base class pointer without any extra step.
-EXPCL_INTERROGATEDB bool interrogate_type_derivation_has_upcast(TypeIndex type, int n);
-EXPCL_INTERROGATEDB FunctionIndex interrogate_type_get_upcast(TypeIndex type, int n);
-
-/*
- * Although it is always possible to upcast a pointer to a base class, it is
- * not always possible to downcast from a base class to the derived class
- * (particularly in the presence of virtual inheritance).  If
- * interrogate_type_derivation_downcast_is_impossible() returns true, forget
- * it.  Otherwise, downcasting works the same way as upcasting.  (Of course,
- * it is the caller's responsibility to guarantee that the pointer actually
- * represents an object of the type being downcast to.)
- */
-EXPCL_INTERROGATEDB bool interrogate_type_derivation_downcast_is_impossible(TypeIndex type, int n);
-EXPCL_INTERROGATEDB bool interrogate_type_derivation_has_downcast(TypeIndex type, int n);
-EXPCL_INTERROGATEDB FunctionIndex interrogate_type_get_downcast(TypeIndex type, int n);
-
-// A C++ class may also define any number of nested types--classes or enums
-// defined within the scope of this class.
-EXPCL_INTERROGATEDB int interrogate_type_number_of_nested_types(TypeIndex type);
-EXPCL_INTERROGATEDB TypeIndex interrogate_type_get_nested_type(TypeIndex type, int n);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif

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

@@ -1,37 +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 interrogate_request.cxx
- * @author drose
- * @date 2000-08-01
- */
-
-#include "interrogate_request.h"
-#include "interrogateDatabase.h"
-
-#include <string.h>  // for strdup
-
-void
-interrogate_request_database(const char *database_filename) {
-  InterrogateModuleDef *def = new InterrogateModuleDef;
-  memset(def, 0, sizeof(InterrogateModuleDef));
-#ifdef _WIN32
-  def->database_filename = _strdup(database_filename);
-#else
-  def->database_filename = strdup(database_filename);
-#endif
-
-  // Don't think of this as a leak; think of it as a one-time database
-  // allocation.
-  InterrogateDatabase::get_ptr()->request_module(def);
-}
-
-void
-interrogate_request_module(InterrogateModuleDef *def) {
-  InterrogateDatabase::get_ptr()->request_module(def);
-}

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

@@ -1,7 +0,0 @@
-#include "config_interrogatedb.cxx"
-#include "indexRemapper.cxx"
-#include "interrogateComponent.cxx"
-#include "interrogateDatabase.cxx"
-#include "interrogateElement.cxx"
-#include "interrogateFunction.cxx"
-#include "interrogateFunctionWrapper.cxx"

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

@@ -1,6 +0,0 @@
-#include "interrogateMakeSeq.cxx"
-#include "interrogateManifest.cxx"
-#include "interrogateType.cxx"
-#include "interrogate_datafile.cxx"
-#include "interrogate_interface.cxx"
-#include "interrogate_request.cxx"

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

@@ -1,50 +0,0 @@
-/**
- * @file py_compat.cxx
- * @author rdb
- * @date 2017-12-03
- */
-
-#include "py_compat.h"
-#include "py_panda.h"
-
-#ifdef HAVE_PYTHON
-
-#if PY_MAJOR_VERSION < 3
-/**
- * Given a long or int, returns a size_t, or raises an OverflowError if it is
- * out of range.
- */
-size_t PyLongOrInt_AsSize_t(PyObject *vv) {
-  if (PyInt_Check(vv)) {
-    long value = PyInt_AS_LONG(vv);
-    if (value < 0) {
-      PyErr_SetString(PyExc_OverflowError,
-                      "can't convert negative value to size_t");
-      return (size_t)-1;
-    }
-    return (size_t)value;
-  }
-
-  if (!PyLong_Check(vv)) {
-    Dtool_Raise_TypeError("a long or int was expected");
-    return (size_t)-1;
-  }
-
-  size_t bytes;
-  int one = 1;
-  int res = _PyLong_AsByteArray((PyLongObject *)vv, (unsigned char *)&bytes,
-                                SIZEOF_SIZE_T, (int)*(unsigned char*)&one, 0,
-#if PY_VERSION_HEX >= 0x030d0000
-                                , 1 // with_exceptions
-#endif
-                                );
-
-  if (res < 0) {
-    return (size_t)res;
-  } else {
-    return bytes;
-  }
-}
-#endif
-
-#endif  // HAVE_PYTHON

+ 6 - 2
dtool/src/interrogatedb/py_compat.h

@@ -65,7 +65,7 @@ typedef int Py_ssize_t;
 
 /* Python 2.6 */
 
-#ifndef Py_TYPE
+#if PY_VERSION_HEX < 0x02060000
 #  define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
 #endif
 
@@ -221,8 +221,12 @@ INLINE PyObject *_PyLong_Lshift(PyObject *a, size_t shiftby) {
 
 /* Python 3.9 */
 
+#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_IS_TYPE)
+#  define Py_IS_TYPE(ob, type) (Py_TYPE((PyObject *)ob) == type)
+#endif
+
 #ifndef PyCFunction_CheckExact
-#  define PyCFunction_CheckExact(op) (Py_TYPE(op) == &PyCFunction_Type)
+#  define PyCFunction_CheckExact(op) (Py_IS_TYPE(op, &PyCFunction_Type))
 #endif
 
 #if PY_VERSION_HEX < 0x03090000

+ 0 - 957
dtool/src/interrogatedb/py_panda.cxx

@@ -1,957 +0,0 @@
-/**
- * @file py_panda.cxx
- * @author drose
- * @date 2005-07-04
- */
-
-#include "py_panda.h"
-#include "config_interrogatedb.h"
-#include "executionEnvironment.h"
-
-#ifdef HAVE_PYTHON
-
-#define _STRINGIFY_VERSION(a, b) (#a "." #b)
-#define STRINGIFY_VERSION(a, b) _STRINGIFY_VERSION(a, b)
-
-using std::string;
-
-/**
-
- */
-void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject *classdef, void **answer) {
-  if (DtoolInstance_Check(self)) {
-    *answer = DtoolInstance_UPCAST(self, *classdef);
-  } else {
-    *answer = nullptr;
-  }
-}
-
-/**
- * This is a support function for the Python bindings: it extracts the
- * underlying C++ pointer of the given type for a given Python object.  If it
- * was of the wrong type, raises an AttributeError.
- */
-bool Dtool_Call_ExtractThisPointer(PyObject *self, Dtool_PyTypedObject &classdef, void **answer) {
-  if (self == nullptr || !DtoolInstance_Check(self) || DtoolInstance_VOID_PTR(self) == nullptr) {
-    Dtool_Raise_TypeError("C++ object is not yet constructed, or already destructed.");
-    return false;
-  }
-
-  *answer = DtoolInstance_UPCAST(self, classdef);
-  return true;
-}
-
-/**
- * The same thing as Dtool_Call_ExtractThisPointer, except that it performs
- * the additional check that the pointer is a non-const pointer.  This is
- * called by function wrappers for functions of which all overloads are non-
- * const, and saves a bit of code.
- *
- * The extra method_name argument is used in formatting the error message.
- */
-bool Dtool_Call_ExtractThisPointer_NonConst(PyObject *self, Dtool_PyTypedObject &classdef,
-                                            void **answer, const char *method_name) {
-
-  if (self == nullptr || !DtoolInstance_Check(self) || DtoolInstance_VOID_PTR(self) == nullptr) {
-    Dtool_Raise_TypeError("C++ object is not yet constructed, or already destructed.");
-    return false;
-  }
-
-  if (DtoolInstance_IS_CONST(self)) {
-    // All overloads of this function are non-const.
-    PyErr_Format(PyExc_TypeError,
-                 "Cannot call %s() on a const object.",
-                 method_name);
-    return false;
-  }
-
-  *answer = DtoolInstance_UPCAST(self, classdef);
-  return true;
-}
-
-/**
- * Extracts the C++ pointer for an object, given its Python wrapper object,
- * for passing as the parameter to a C++ function.
- *
- * self is the Python wrapper object in question.
- *
- * classdef is the Python class wrapper for the C++ class in which the this
- * pointer should be returned.  (This may require an upcast operation, if self
- * is not already an instance of classdef.)
- *
- * param and function_name are used for error reporting only, and describe the
- * particular function and parameter index for this parameter.
- *
- * const_ok is true if the function is declared const and can therefore be
- * called with either a const or non-const "this" pointer, or false if the
- * function is declared non-const, and can therefore be called with only a
- * non-const "this" pointer.
- *
- * The return value is the C++ pointer that was extracted, or NULL if there
- * was a problem (in which case the Python exception state will have been
- * set).
- */
-void *
-DTOOL_Call_GetPointerThisClass(PyObject *self, Dtool_PyTypedObject *classdef,
-                               int param, const string &function_name, bool const_ok,
-                               bool report_errors) {
-  // if (PyErr_Occurred()) { return nullptr; }
-  if (self == nullptr) {
-    if (report_errors) {
-      return Dtool_Raise_TypeError("self is nullptr");
-    }
-    return nullptr;
-  }
-
-  if (DtoolInstance_Check(self)) {
-    void *result = DtoolInstance_UPCAST(self, *classdef);
-
-    if (result != nullptr) {
-      if (const_ok || !DtoolInstance_IS_CONST(self)) {
-        return result;
-      }
-
-      if (report_errors) {
-        return PyErr_Format(PyExc_TypeError,
-                            "%s() argument %d may not be const",
-                            function_name.c_str(), param);
-      }
-      return nullptr;
-    }
-  }
-
-  if (report_errors) {
-    return Dtool_Raise_ArgTypeError(self, param, function_name.c_str(), classdef->_PyType.tp_name);
-  }
-
-  return nullptr;
-}
-
-/**
- * This is similar to a PyErr_Occurred() check, except that it also checks
- * Notify to see if an assertion has occurred.  If that is the case, then it
- * raises an AssertionError.
- *
- * Returns true if there is an active exception, false otherwise.
- *
- * In the NDEBUG case, this is simply a #define to PyErr_Occurred().
- */
-bool _Dtool_CheckErrorOccurred() {
-  if (PyErr_Occurred()) {
-    return true;
-  }
-  if (Notify::ptr()->has_assert_failed()) {
-    Dtool_Raise_AssertionError();
-    return true;
-  }
-  return false;
-}
-
-/**
- * Raises an AssertionError containing the last thrown assert message, and
- * clears the assertion flag.  Returns NULL.
- */
-PyObject *Dtool_Raise_AssertionError() {
-  Notify *notify = Notify::ptr();
-#if PY_MAJOR_VERSION >= 3
-  PyObject *message = PyUnicode_FromString(notify->get_assert_error_message().c_str());
-#else
-  PyObject *message = PyString_FromString(notify->get_assert_error_message().c_str());
-#endif
-  PyErr_SetObject(PyExc_AssertionError, message);
-  notify->clear_assert_failed();
-  return nullptr;
-}
-
-/**
- * Raises a TypeError with the given message, and returns NULL.
- */
-PyObject *Dtool_Raise_TypeError(const char *message) {
-  PyErr_SetString(PyExc_TypeError, message);
-  return nullptr;
-}
-
-/**
- * Raises a TypeError of the form: function_name() argument n must be type,
- * not type for a given object passed to a function.
- *
- * Always returns NULL so that it can be conveniently used as a return
- * expression for wrapper functions that return a PyObject pointer.
- */
-PyObject *Dtool_Raise_ArgTypeError(PyObject *obj, int param, const char *function_name, const char *type_name) {
-#if PY_MAJOR_VERSION >= 3
-  PyObject *message = PyUnicode_FromFormat(
-#else
-  PyObject *message = PyString_FromFormat(
-#endif
-    "%s() argument %d must be %s, not %s",
-    function_name, param, type_name,
-    Py_TYPE(obj)->tp_name);
-
-  PyErr_SetObject(PyExc_TypeError, message);
-  return nullptr;
-}
-
-/**
- * Raises an AttributeError of the form: 'type' has no attribute 'attr'
- *
- * Always returns NULL so that it can be conveniently used as a return
- * expression for wrapper functions that return a PyObject pointer.
- */
-PyObject *Dtool_Raise_AttributeError(PyObject *obj, const char *attribute) {
-#if PY_MAJOR_VERSION >= 3
-  PyObject *message = PyUnicode_FromFormat(
-#else
-  PyObject *message = PyString_FromFormat(
-#endif
-    "'%.100s' object has no attribute '%.200s'",
-    Py_TYPE(obj)->tp_name, attribute);
-
-  PyErr_SetObject(PyExc_AttributeError, message);
-  return nullptr;
-}
-
-/**
- * Raises a TypeError of the form: Arguments must match: <list of overloads>
- *
- * However, in release builds, this instead is defined to a function that just
- * prints out a generic message, to help reduce the amount of strings in the
- * compiled library.
- *
- * If there is already an exception set, does nothing.
- *
- * Always returns NULL so that it can be conveniently used as a return
- * expression for wrapper functions that return a PyObject pointer.
- */
-PyObject *_Dtool_Raise_BadArgumentsError(const char *message) {
-  if (!PyErr_Occurred()) {
-    return PyErr_Format(PyExc_TypeError, "Arguments must match:\n%s", message);
-  }
-  return nullptr;
-}
-
-/**
- * Overload that prints a generic message instead.
- */
-PyObject *_Dtool_Raise_BadArgumentsError() {
-  if (!PyErr_Occurred()) {
-    PyErr_SetString(PyExc_TypeError, "arguments do not match any function overload");
-  }
-  return nullptr;
-}
-
-/**
- * Overload that returns -1 instead of nullptr.
- */
-int _Dtool_Raise_BadArgumentsError_Int(const char *message) {
-  if (!PyErr_Occurred()) {
-    PyErr_Format(PyExc_TypeError, "Arguments must match:\n%s", message);
-  }
-  return -1;
-}
-
-/**
- * Overload that returns -1 instead of nullptr and prints a generic message.
- */
-int _Dtool_Raise_BadArgumentsError_Int() {
-  if (!PyErr_Occurred()) {
-    PyErr_SetString(PyExc_TypeError, "arguments do not match any function overload");
-  }
-  return -1;
-}
-
-/**
- * Convenience method that checks for exceptions, and if one occurred, returns
- * NULL, otherwise Py_None.
- */
-PyObject *_Dtool_Return_None() {
-  if (UNLIKELY(PyErr_Occurred())) {
-    return nullptr;
-  }
-#ifndef NDEBUG
-  if (UNLIKELY(Notify::ptr()->has_assert_failed())) {
-    return Dtool_Raise_AssertionError();
-  }
-#endif
-  return Py_NewRef(Py_None);
-}
-
-/**
- * Convenience method that checks for exceptions, and if one occurred, returns
- * NULL, otherwise the given boolean value as a PyObject *.
- */
-PyObject *Dtool_Return_Bool(bool value) {
-  if (UNLIKELY(PyErr_Occurred())) {
-    return nullptr;
-  }
-#ifndef NDEBUG
-  if (UNLIKELY(Notify::ptr()->has_assert_failed())) {
-    return Dtool_Raise_AssertionError();
-  }
-#endif
-  return Py_NewRef(value ? Py_True : Py_False);
-}
-
-/**
- * Convenience method that checks for exceptions, and if one occurred, returns
- * NULL, otherwise the given return value.  Its reference count is not
- * increased.
- */
-PyObject *_Dtool_Return(PyObject *value) {
-  if (UNLIKELY(PyErr_Occurred())) {
-    return nullptr;
-  }
-#ifndef NDEBUG
-  if (UNLIKELY(Notify::ptr()->has_assert_failed())) {
-    return Dtool_Raise_AssertionError();
-  }
-#endif
-  return value;
-}
-
-#if PY_VERSION_HEX < 0x03040000
-/**
- * This function converts an int value to the appropriate enum instance.
- */
-static PyObject *Dtool_EnumType_New(PyTypeObject *subtype, PyObject *args, PyObject *kwds) {
-  PyObject *arg;
-  if (!Dtool_ExtractArg(&arg, args, kwds, "value")) {
-    return PyErr_Format(PyExc_TypeError,
-                        "%s() missing 1 required argument: 'value'",
-                        subtype->tp_name);
-  }
-
-  if (Py_TYPE(arg) == subtype) {
-    return Py_NewRef(arg);
-  }
-
-  PyObject *value2member = PyDict_GetItemString(subtype->tp_dict, "_value2member_map_");
-  nassertr_always(value2member != nullptr, nullptr);
-
-  PyObject *member;
-  if (PyDict_GetItemRef(value2member, arg, &member) > 0) {
-    return member;
-  }
-
-  PyObject *repr = PyObject_Repr(arg);
-  PyErr_Format(PyExc_ValueError, "%s is not a valid %s",
-#if PY_MAJOR_VERSION >= 3
-               PyUnicode_AS_STRING(repr),
-#else
-               PyString_AS_STRING(repr),
-#endif
-               subtype->tp_name);
-  Py_DECREF(repr);
-  return nullptr;
-}
-
-static PyObject *Dtool_EnumType_Str(PyObject *self) {
-  PyObject *name = PyObject_GetAttrString(self, "name");
-#if PY_MAJOR_VERSION >= 3
-  PyObject *repr = PyUnicode_FromFormat("%s.%s", Py_TYPE(self)->tp_name, PyString_AS_STRING(name));
-#else
-  PyObject *repr = PyString_FromFormat("%s.%s", Py_TYPE(self)->tp_name, PyString_AS_STRING(name));
-#endif
-  Py_DECREF(name);
-  return repr;
-}
-
-static PyObject *Dtool_EnumType_Repr(PyObject *self) {
-  PyObject *name = PyObject_GetAttrString(self, "name");
-  PyObject *value = PyObject_GetAttrString(self, "value");
-#if PY_MAJOR_VERSION >= 3
-  PyObject *repr = PyUnicode_FromFormat("<%s.%s: %ld>", Py_TYPE(self)->tp_name, PyString_AS_STRING(name), PyLongOrInt_AS_LONG(value));
-#else
-  PyObject *repr = PyString_FromFormat("<%s.%s: %ld>", Py_TYPE(self)->tp_name, PyString_AS_STRING(name), PyLongOrInt_AS_LONG(value));
-#endif
-  Py_DECREF(name);
-  Py_DECREF(value);
-  return repr;
-}
-#endif
-
-/**
- * Creates a Python 3.4-style enum type.  Steals reference to 'names', which
- * should be a tuple of (name, value) pairs.
- */
-PyTypeObject *Dtool_EnumType_Create(const char *name, PyObject *names, const char *module) {
-#if PY_VERSION_HEX >= 0x03040000
-  PyObject *enum_module = PyImport_ImportModule("enum");
-  nassertr_always(enum_module != nullptr, nullptr);
-
-  PyObject *enum_meta = PyObject_GetAttrString(enum_module, "EnumMeta");
-  nassertr(enum_meta != nullptr, nullptr);
-
-  PyObject *enum_class = PyObject_GetAttrString(enum_module, "Enum");
-  Py_DECREF(enum_module);
-  nassertr(enum_class != nullptr, nullptr);
-
-  PyObject *enum_create = PyObject_GetAttrString(enum_meta, "_create_");
-  Py_DECREF(enum_meta);
-
-  PyObject *result = PyObject_CallFunction(enum_create, (char *)"OsN", enum_class, name, names);
-  Py_DECREF(enum_create);
-  Py_DECREF(enum_class);
-  nassertr(result != nullptr, nullptr);
-#else
-  static PyObject *enum_class = nullptr;
-  static PyObject *name_str;
-  static PyObject *name_sunder_str;
-  static PyObject *value_str;
-  static PyObject *value_sunder_str;
-  static PyObject *value2member_map_sunder_str;
-  // Emulate something vaguely like the enum module.
-  if (enum_class == nullptr) {
-#if PY_MAJOR_VERSION >= 3
-    name_str = PyUnicode_InternFromString("name");
-    value_str = PyUnicode_InternFromString("value");
-    name_sunder_str = PyUnicode_InternFromString("_name_");
-    value_sunder_str = PyUnicode_InternFromString("_value_");
-    value2member_map_sunder_str = PyUnicode_InternFromString("_value2member_map_");
-#else
-    name_str = PyString_InternFromString("name");
-    value_str = PyString_InternFromString("value");
-    name_sunder_str = PyString_InternFromString("_name_");
-    value_sunder_str = PyString_InternFromString("_value_");
-    value2member_map_sunder_str = PyString_InternFromString("_value2member_map_");
-#endif
-    PyObject *name_value_tuple = PyTuple_New(4);
-    PyTuple_SET_ITEM(name_value_tuple, 0, Py_NewRef(name_str));
-    PyTuple_SET_ITEM(name_value_tuple, 1, Py_NewRef(value_str));
-    PyTuple_SET_ITEM(name_value_tuple, 2, name_sunder_str);
-    PyTuple_SET_ITEM(name_value_tuple, 3, value_sunder_str);
-
-    PyObject *slots_dict = PyDict_New();
-    PyDict_SetItemString(slots_dict, "__slots__", name_value_tuple);
-    Py_DECREF(name_value_tuple);
-
-    enum_class = PyObject_CallFunction((PyObject *)&PyType_Type, (char *)"s()N", "Enum", slots_dict);
-    nassertr(enum_class != nullptr, nullptr);
-  }
-
-  // Create a subclass of this generic Enum class we just created.
-  PyObject *value2member = PyDict_New();
-  PyObject *dict = PyDict_New();
-  PyDict_SetItem(dict, value2member_map_sunder_str, value2member);
-  PyObject *result = PyObject_CallFunction((PyObject *)&PyType_Type, (char *)"s(O)N", name, enum_class, dict);
-  nassertr(result != nullptr, nullptr);
-
-  ((PyTypeObject *)result)->tp_new = Dtool_EnumType_New;
-  ((PyTypeObject *)result)->tp_str = Dtool_EnumType_Str;
-  ((PyTypeObject *)result)->tp_repr = Dtool_EnumType_Repr;
-
-  PyObject *empty_tuple = PyTuple_New(0);
-
-  // Copy the names as instances of the above to the class dict, and create a
-  // reverse mapping in the _value2member_map_ dict.
-  Py_ssize_t size = PyTuple_GET_SIZE(names);
-  for (Py_ssize_t i = 0; i < size; ++i) {
-    PyObject *item = PyTuple_GET_ITEM(names, i);
-    PyObject *name = PyTuple_GET_ITEM(item, 0);
-    PyObject *value = PyTuple_GET_ITEM(item, 1);
-    PyObject *member = PyType_GenericNew((PyTypeObject *)result, empty_tuple, nullptr);
-    PyObject_SetAttr(member, name_str, name);
-    PyObject_SetAttr(member, name_sunder_str, name);
-    PyObject_SetAttr(member, value_str, value);
-    PyObject_SetAttr(member, value_sunder_str, value);
-    PyObject_SetAttr(result, name, member);
-    PyDict_SetItem(value2member, value, member);
-    Py_DECREF(member);
-  }
-  Py_DECREF(names);
-  Py_DECREF(value2member);
-  Py_DECREF(empty_tuple);
-#endif
-
-  if (module != nullptr) {
-    PyObject *modstr = PyUnicode_FromString(module);
-    PyObject_SetAttrString(result, "__module__", modstr);
-    Py_DECREF(modstr);
-  }
-  nassertr(PyType_Check(result), nullptr);
-  return (PyTypeObject *)result;
-}
-
-/**
-
- */
-PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject &known_class_type, bool memory_rules, bool is_const, int type_index) {
-  // We can't do the NULL check here like in DTool_CreatePyInstance, since the
-  // caller will have to get the type index to pass to this function to begin
-  // with.  That code probably would have crashed by now if it was really NULL
-  // for whatever reason.
-  nassertr(local_this_in != nullptr, nullptr);
-
-  // IF the class is possibly a run time typed object
-  if (type_index > 0) {
-    // get best fit class...
-    Dtool_PyInstDef *self = (Dtool_PyInstDef *)TypeHandle::from_index(type_index).wrap_python(local_this_in, &known_class_type._PyType);
-    if (self != nullptr) {
-      self->_memory_rules = memory_rules;
-      self->_is_const = is_const;
-      return (PyObject *)self;
-    }
-  }
-
-  // if we get this far .. just wrap the thing in the known type ?? better
-  // than aborting...I guess....
-  Dtool_PyInstDef *self = (Dtool_PyInstDef *)PyType_GenericAlloc(&known_class_type._PyType, 0);
-  if (self != nullptr) {
-    self->_signature = PY_PANDA_SIGNATURE;
-    self->_My_Type = &known_class_type;
-    self->_ptr_to_object = local_this_in;
-    self->_memory_rules = memory_rules;
-    self->_is_const = is_const;
-  }
-  return (PyObject *)self;
-}
-
-// DTool_CreatePyInstance .. wrapper function to finalize the existance of a
-// general dtool py instance..
-PyObject *DTool_CreatePyInstance(void *local_this, Dtool_PyTypedObject &in_classdef, bool memory_rules, bool is_const) {
-  if (local_this == nullptr) {
-    // This is actually a very common case, so let's allow this, but return
-    // Py_None consistently.  This eliminates code in the wrappers.
-    return Py_NewRef(Py_None);
-  }
-
-  Dtool_PyInstDef *self = (Dtool_PyInstDef *)PyType_GenericAlloc(&in_classdef._PyType, 0);
-  if (self != nullptr) {
-    self->_signature = PY_PANDA_SIGNATURE;
-    self->_My_Type = &in_classdef;
-    self->_ptr_to_object = local_this;
-    self->_memory_rules = memory_rules;
-    self->_is_const = is_const;
-    self->_My_Type = &in_classdef;
-  }
-  return (PyObject *)self;
-}
-
-/**
- * Returns a borrowed reference to the global type dictionary.
- */
-Dtool_TypeMap *Dtool_GetGlobalTypeMap() {
-#if PY_VERSION_HEX >= 0x030d0000 // 3.13
-  PyObject *istate_dict = PyInterpreterState_GetDict(PyInterpreterState_Get());
-  PyObject *key = PyUnicode_InternFromString("_interrogate_types");
-  PyObject *capsule = PyDict_GetItem(istate_dict, key);
-  if (capsule != nullptr) {
-    Py_DECREF(key);
-    return (Dtool_TypeMap *)PyCapsule_GetPointer(capsule, nullptr);
-  }
-#else
-  PyObject *capsule = PySys_GetObject((char *)"_interrogate_types");
-  if (capsule != nullptr) {
-    return (Dtool_TypeMap *)PyCapsule_GetPointer(capsule, nullptr);
-  }
-#endif
-
-  Dtool_TypeMap *type_map = new Dtool_TypeMap;
-  capsule = PyCapsule_New((void *)type_map, nullptr, nullptr);
-
-#if PY_VERSION_HEX >= 0x030d0000 // 3.13
-  PyObject *result;
-  if (PyDict_SetDefaultRef(istate_dict, key, capsule, &result) != 0) {
-    // Another thread already beat us to it.
-    Py_DECREF(capsule);
-    delete type_map;
-    capsule = result;
-    type_map = (Dtool_TypeMap *)PyCapsule_GetPointer(capsule, nullptr);
-  }
-  Py_DECREF(key);
-#endif
-
-  PySys_SetObject((char *)"_interrogate_types", capsule);
-  Py_DECREF(capsule);
-  return type_map;
-}
-
-/**
- *
- */
-void DtoolProxy_Init(DtoolProxy *proxy, PyObject *self,
-                     Dtool_PyTypedObject &classdef,
-                     TypeRegistry::PythonWrapFunc *wrap_func) {
-  if (proxy == nullptr) {
-    // Out of memory, the generated code will handle this.
-    return;
-  }
-
-  proxy->_self = Py_NewRef(self);
-  PyTypeObject *cls = Py_TYPE(self);
-  if (cls != &classdef._PyType) {
-    TypeRegistry *registry = TypeRegistry::ptr();
-    TypeHandle handle = registry->register_dynamic_type(cls->tp_name);
-    registry->record_derivation(handle, classdef._type);
-    //TODO unregister type when it is unloaded? weak callback?
-    PyTypeObject *cls_ref = (PyTypeObject *)Py_NewRef((PyObject *)cls);
-    registry->record_python_type(handle, cls_ref, wrap_func);
-    proxy->_type = handle;
-  } else {
-    proxy->_type = classdef._type;
-  }
-}
-
-#define PY_MAJOR_VERSION_STR #PY_MAJOR_VERSION "." #PY_MINOR_VERSION
-
-#if PY_MAJOR_VERSION >= 3
-PyObject *Dtool_PyModuleInitHelper(const LibraryDef *defs[], PyModuleDef *module_def) {
-#else
-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();
-  size_t version_len = version.find('.', 2);
-  if (version_len != string::npos) {
-    version.resize(version_len);
-  }
-
-  if (version != STRINGIFY_VERSION(PY_MAJOR_VERSION, PY_MINOR_VERSION)) {
-    // Raise a helpful error message.  We can safely do this because the
-    // signature and behavior for PyErr_SetString has remained consistent.
-    std::ostringstream errs;
-    errs << "this module was compiled for Python "
-         << PY_MAJOR_VERSION << "." << PY_MINOR_VERSION << ", which is "
-         << "incompatible with Python " << version;
-    string error = errs.str();
-    PyErr_SetString(PyExc_ImportError, error.c_str());
-    return nullptr;
-  }
-
-  Dtool_TypeMap *type_map = Dtool_GetGlobalTypeMap();
-
-#ifdef Py_GIL_DISABLED
-  PyMutex_Lock(&type_map->_lock);
-#endif
-
-  // the module level function inits....
-  MethodDefmap functions;
-  for (size_t i = 0; defs[i] != nullptr; i++) {
-    const LibraryDef &def = *defs[i];
-
-    // 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;
-      }
-    }
-
-    // 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;
-      }
-    }
-  }
-
-  // Resolve external types, in a second pass.
-  for (size_t i = 0; defs[i] != nullptr; i++) {
-    const LibraryDef &def = *defs[i];
-
-    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 {
-          PyErr_Format(PyExc_NameError, "name '%s' is not defined", types->name);
-#ifdef Py_GIL_DISABLED
-          PyMutex_Unlock(&type_map->_lock);
-#endif
-          return nullptr;
-        }
-        ++types;
-      }
-    }
-  }
-#ifdef Py_GIL_DISABLED
-  PyMutex_Unlock(&type_map->_lock);
-#endif
-
-  PyMethodDef *newdef = new PyMethodDef[functions.size() + 1];
-  MethodDefmap::iterator mi;
-  int offset = 0;
-  for (mi = functions.begin(); mi != functions.end(); mi++, offset++) {
-    newdef[offset] = *mi->second;
-  }
-  newdef[offset].ml_doc = nullptr;
-  newdef[offset].ml_name = nullptr;
-  newdef[offset].ml_meth = nullptr;
-  newdef[offset].ml_flags = 0;
-
-#if PY_MAJOR_VERSION >= 3
-  module_def->m_methods = newdef;
-  PyObject *module = PyModule_Create(module_def);
-#else
-  PyObject *module = Py_InitModule((char *)modulename, newdef);
-#endif
-
-  if (module == nullptr) {
-#if PY_MAJOR_VERSION >= 3
-    return Dtool_Raise_TypeError("PyModule_Create returned NULL");
-#else
-    return Dtool_Raise_TypeError("Py_InitModule returned NULL");
-#endif
-  }
-
-  // MAIN_DIR needs to be set very early; this seems like a convenient place
-  // to do that.  Perhaps we'll find a better place for this in the future.
-  static bool initialized_main_dir = false;
-  if (!initialized_main_dir) {
-    if (interrogatedb_cat.is_debug()) {
-      // Good opportunity to print this out once, at startup.
-      interrogatedb_cat.debug()
-        << "Python " << version << "\n";
-    }
-
-    if (!ExecutionEnvironment::has_environment_variable("MAIN_DIR")) {
-      // Grab the __main__ module.
-      PyObject *main_module = PyImport_ImportModule("__main__");
-      if (main_module == NULL) {
-        interrogatedb_cat.warning() << "Unable to import __main__\n";
-      }
-
-      // Extract the __file__ attribute, if present.
-      Filename main_dir;
-      PyObject *file_attr = nullptr;
-      if (main_module != nullptr) {
-        file_attr = PyObject_GetAttrString(main_module, "__file__");
-      }
-      if (file_attr == nullptr) {
-        // Must be running in the interactive interpreter.  Use the CWD.
-        main_dir = ExecutionEnvironment::get_cwd();
-      } else {
-#if PY_MAJOR_VERSION >= 3
-        Py_ssize_t length;
-        wchar_t *buffer = PyUnicode_AsWideCharString(file_attr, &length);
-        if (buffer != nullptr) {
-          main_dir = Filename::from_os_specific_w(std::wstring(buffer, length));
-          main_dir.make_absolute();
-          main_dir = main_dir.get_dirname();
-          PyMem_Free(buffer);
-        }
-#else
-        char *buffer;
-        Py_ssize_t length;
-        if (PyString_AsStringAndSize(file_attr, &buffer, &length) != -1) {
-          main_dir = Filename::from_os_specific(std::string(buffer, length));
-          main_dir.make_absolute();
-          main_dir = main_dir.get_dirname();
-        }
-#endif
-        else {
-          interrogatedb_cat.warning() << "Invalid string for __main__.__file__\n";
-        }
-      }
-      ExecutionEnvironment::shadow_environment_variable("MAIN_DIR", main_dir.to_os_specific());
-      PyErr_Clear();
-    }
-    initialized_main_dir = true;
-
-    // Also, while we are at it, initialize the thread swap hook.
-#if defined(HAVE_THREADS) && defined(SIMPLE_THREADS)
-    global_thread_state_swap = PyThreadState_Swap;
-#endif
-  }
-
-  PyModule_AddIntConstant(module, "Dtool_PyNativeInterface", 1);
-  return module;
-}
-
-// HACK.... Be careful Dtool_BorrowThisReference This function can be used to
-// grab the "THIS" pointer from an object and use it Required to support
-// historical inheritance in the form of "is this instance of"..
-PyObject *Dtool_BorrowThisReference(PyObject *self, PyObject *args) {
-  PyObject *from_in = nullptr;
-  PyObject *to_in = nullptr;
-  if (PyArg_UnpackTuple(args, "Dtool_BorrowThisReference", 2, 2, &to_in, &from_in)) {
-
-    if (DtoolInstance_Check(from_in) && DtoolInstance_Check(to_in)) {
-      Dtool_PyInstDef *from = (Dtool_PyInstDef *) from_in;
-      Dtool_PyInstDef *to = (Dtool_PyInstDef *) to_in;
-
-      // if (PyObject_TypeCheck(to_in, Py_TYPE(from_in))) {
-      if (from->_My_Type == to->_My_Type) {
-        to->_memory_rules = false;
-        to->_is_const = from->_is_const;
-        to->_ptr_to_object = from->_ptr_to_object;
-
-        return Py_NewRef(Py_None);
-      }
-
-      return PyErr_Format(PyExc_TypeError, "types %s and %s do not match",
-                          Py_TYPE(from)->tp_name, Py_TYPE(to)->tp_name);
-    } else {
-      return Dtool_Raise_TypeError("One of these does not appear to be DTOOL Instance ??");
-    }
-  }
-  return nullptr;
-}
-
-// We do expose a dictionay for dtool classes .. this should be removed at
-// some point..
-EXPCL_PYPANDA PyObject *
-Dtool_AddToDictionary(PyObject *self1, PyObject *args) {
-  PyObject *self;
-  PyObject *subject;
-  PyObject *key;
-  if (PyArg_ParseTuple(args, "OSO", &self, &key, &subject)) {
-    PyObject *dict = ((PyTypeObject *)self)->tp_dict;
-    if (dict == nullptr || !PyDict_Check(dict)) {
-      return Dtool_Raise_TypeError("No dictionary On Object");
-    } else {
-      PyDict_SetItem(dict, key, subject);
-    }
-  }
-  if (PyErr_Occurred()) {
-    return nullptr;
-  }
-  return Py_NewRef(Py_None);
-}
-
-/**
- * This is a support function for a synthesized __copy__() method from a C++
- * make_copy() method.
- */
-PyObject *copy_from_make_copy(PyObject *self, PyObject *noargs) {
-  PyObject *callable = PyObject_GetAttrString(self, "make_copy");
-  if (callable == nullptr) {
-    return nullptr;
-  }
-  PyObject *result = PyObject_CallNoArgs(callable);
-  Py_DECREF(callable);
-  return result;
-}
-
-/**
- * This is a support function for a synthesized __copy__() method from a C++
- * copy constructor.
- */
-PyObject *copy_from_copy_constructor(PyObject *self, PyObject *noargs) {
-  PyObject *callable = (PyObject *)Py_TYPE(self);
-  return PyObject_CallOneArg(callable, self);
-}
-
-/**
- * This is a support function for a synthesized __deepcopy__() method for any
- * class that has a __copy__() method.  The sythethic method simply invokes
- * __copy__().
- */
-PyObject *map_deepcopy_to_copy(PyObject *self, PyObject *args) {
-  PyObject *callable = PyObject_GetAttrString(self, "__copy__");
-  if (callable == nullptr) {
-    return nullptr;
-  }
-  PyObject *result = PyObject_CallNoArgs(callable);
-  Py_DECREF(callable);
-  return result;
-}
-
-/**
- * A more efficient version of PyArg_ParseTupleAndKeywords for the special
- * case where there is only a single PyObject argument.
- */
-bool Dtool_ExtractArg(PyObject **result, PyObject *args, PyObject *kwds,
-                      const char *keyword) {
-
-  if (PyTuple_GET_SIZE(args) == 1) {
-    if (kwds == nullptr || PyDict_GET_SIZE(kwds) == 0) {
-      *result = PyTuple_GET_ITEM(args, 0);
-      return true;
-    }
-  }
-  else if (!keyword || !keyword[0]) {
-    return false;
-  }
-  else if (PyTuple_GET_SIZE(args) == 0) {
-    PyObject *key;
-    Py_ssize_t ppos = 0;
-    if (kwds != nullptr && PyDict_GET_SIZE(kwds) == 1 &&
-        PyDict_Next(kwds, &ppos, &key, result)) {
-      // We got the item, we just need to make sure that it had the right key.
-#if PY_MAJOR_VERSION >= 3
-      return PyUnicode_CheckExact(key) && PyUnicode_CompareWithASCIIString(key, keyword) == 0;
-#else
-      return PyString_CheckExact(key) && strcmp(PyString_AS_STRING(key), keyword) == 0;
-#endif
-    }
-  }
-
-  return false;
-}
-
-/**
- * Variant of Dtool_ExtractArg that does not accept a keyword argument.
- */
-bool Dtool_ExtractArg(PyObject **result, PyObject *args, PyObject *kwds) {
-  if (PyTuple_GET_SIZE(args) == 1 &&
-      (kwds == nullptr || PyDict_GET_SIZE(kwds) == 0)) {
-    *result = PyTuple_GET_ITEM(args, 0);
-    return true;
-  }
-  return false;
-}
-
-/**
- * A more efficient version of PyArg_ParseTupleAndKeywords for the special
- * case where there is only a single optional PyObject argument.
- *
- * Returns true if valid (including if there were 0 items), false if there was
- * an error, such as an invalid number of parameters.
- */
-bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args, PyObject *kwds,
-                              const char *keyword) {
-
-  if (PyTuple_GET_SIZE(args) == 1) {
-    if (kwds == nullptr || PyDict_GET_SIZE(kwds) == 0) {
-      *result = PyTuple_GET_ITEM(args, 0);
-      return true;
-    }
-  }
-  else if (!keyword || !keyword[0]) {
-    return (kwds == nullptr || PyDict_GET_SIZE(kwds) == 0);
-  }
-  else if (PyTuple_GET_SIZE(args) == 0) {
-    if (kwds != nullptr && PyDict_GET_SIZE(kwds) == 1) {
-      PyObject *key;
-      Py_ssize_t ppos = 0;
-      if (!PyDict_Next(kwds, &ppos, &key, result)) {
-        return true;
-      }
-
-      // We got the item, we just need to make sure that it had the right key.
-#if PY_VERSION_HEX >= 0x030d0000
-      return PyUnicode_CheckExact(key) && PyUnicode_EqualToUTF8(key, keyword);
-#elif PY_VERSION_HEX >= 0x03060000
-      return PyUnicode_CheckExact(key) && _PyUnicode_EqualToASCIIString(key, keyword);
-#elif PY_MAJOR_VERSION >= 3
-      return PyUnicode_CheckExact(key) && PyUnicode_CompareWithASCIIString(key, keyword) == 0;
-#else
-      return PyString_CheckExact(key) && strcmp(PyString_AS_STRING(key), keyword) == 0;
-#endif
-    } else {
-      return true;
-    }
-  }
-
-  return false;
-}
-
-/**
- * Variant of Dtool_ExtractOptionalArg that does not accept a keyword argument.
- */
-bool Dtool_ExtractOptionalArg(PyObject **result, PyObject *args, PyObject *kwds) {
-  if (kwds != nullptr && PyDict_GET_SIZE(kwds) != 0) {
-    return false;
-  }
-  if (PyTuple_GET_SIZE(args) == 1) {
-    *result = PyTuple_GET_ITEM(args, 0);
-    return true;
-  }
-  return (PyTuple_GET_SIZE(args) == 0);
-}
-
-#endif  // HAVE_PYTHON

+ 2 - 0
dtool/src/interrogatedb/py_panda.h

@@ -16,6 +16,7 @@
 #include "pnotify.h"
 #include "vector_uchar.h"
 #include "register_type.h"
+#include "interrogate_request.h"
 
 #if defined(HAVE_PYTHON) && !defined(CPPPARSER)
 
@@ -345,6 +346,7 @@ struct LibraryDef {
   PyMethodDef *const _methods;
   const Dtool_TypeDef *const _types;
   Dtool_TypeDef *const _external_types;
+  const InterrogateModuleDef *const _module_def;
 };
 
 #if PY_MAJOR_VERSION >= 3

+ 0 - 1791
dtool/src/interrogatedb/py_wrappers.cxx

@@ -1,1791 +0,0 @@
-/**
- * @file py_wrappers.cxx
- * @author rdb
- * @date 2017-11-26
- */
-
-#include "py_wrappers.h"
-
-#ifdef HAVE_PYTHON
-
-#if PY_VERSION_HEX >= 0x03040000
-#define _COLLECTIONS_ABC "_collections_abc"
-#elif PY_VERSION_HEX >= 0x03030000
-#define _COLLECTIONS_ABC "collections.abc"
-#else
-#define _COLLECTIONS_ABC "_abcoll"
-#endif
-
-static void _register_collection(PyTypeObject *type, const char *abc) {
-#if PY_MAJOR_VERSION >= 3
-  PyObject *module_name = PyUnicode_InternFromString(_COLLECTIONS_ABC);
-#else
-  PyObject *module_name = PyString_InternFromString(_COLLECTIONS_ABC);
-#endif
-  PyObject *module = PyImport_GetModule(module_name);
-  Py_DECREF(module_name);
-  if (module != nullptr) {
-    PyObject *dict = PyModule_GetDict(module);
-    if (dict != nullptr) {
-#if PY_MAJOR_VERSION >= 3
-      PyObject *register_str = PyUnicode_InternFromString("register");
-#else
-      PyObject *register_str = PyString_InternFromString("register");
-#endif
-      PyObject *obj = nullptr;
-      if (register_str == nullptr ||
-          PyDict_GetItemStringRef(dict, abc, &obj) <= 0 ||
-          PyObject_CallMethodOneArg(obj, register_str, (PyObject *)type) == nullptr) {
-        PyErr_Print();
-      }
-      Py_XDECREF(obj);
-      Py_XDECREF(register_str);
-    } else {
-      PyErr_Clear();
-    }
-    Py_DECREF(module);
-  }
-}
-
-/**
- * These classes are returned from properties that require a subscript
- * interface, ie. something.children[i] = 3.
- */
-static void Dtool_WrapperBase_dealloc(PyObject *self) {
-  Dtool_WrapperBase *wrap = (Dtool_WrapperBase *)self;
-  nassertv(wrap);
-  Py_XDECREF(wrap->_self);
-  Py_TYPE(self)->tp_free(self);
-}
-
-static PyObject *Dtool_WrapperBase_repr(PyObject *self) {
-  Dtool_WrapperBase *wrap = (Dtool_WrapperBase *)self;
-  nassertr(wrap, nullptr);
-
-  PyObject *repr = PyObject_Repr(wrap->_self);
-  PyObject *result;
-#if PY_MAJOR_VERSION >= 3
-  result = PyUnicode_FromFormat("<%s[] of %s>", wrap->_name, PyUnicode_AsUTF8(repr));
-#else
-  result = PyString_FromFormat("<%s[] of %s>", wrap->_name, PyString_AS_STRING(repr));
-#endif
-  Py_DECREF(repr);
-  return result;
-}
-
-static PyObject *Dtool_SequenceWrapper_repr(PyObject *self) {
-  Dtool_SequenceWrapper *wrap = (Dtool_SequenceWrapper *)self;
-  nassertr(wrap, nullptr);
-
-  Py_ssize_t len = -1;
-  if (wrap->_len_func != nullptr) {
-    len = wrap->_len_func(wrap->_base._self);
-  }
-
-  if (len < 0) {
-    PyErr_Clear();
-    return Dtool_WrapperBase_repr(self);
-  }
-
-  PyObject *repr = PyObject_Repr(wrap->_base._self);
-  PyObject *result;
-#if PY_MAJOR_VERSION >= 3
-  result = PyUnicode_FromFormat("<%s[%zd] of %s>", wrap->_base._name, len, PyUnicode_AsUTF8(repr));
-#else
-  result = PyString_FromFormat("<%s[%zd] of %s>", wrap->_base._name, len, PyString_AS_STRING(repr));
-#endif
-  Py_DECREF(repr);
-  return result;
-}
-
-static Py_ssize_t Dtool_SequenceWrapper_length(PyObject *self) {
-  Dtool_SequenceWrapper *wrap = (Dtool_SequenceWrapper *)self;
-  nassertr(wrap, -1);
-  if (wrap->_len_func != nullptr) {
-    return wrap->_len_func(wrap->_base._self);
-  } else {
-    Dtool_Raise_TypeError("property does not support len()");
-    return -1;
-  }
-}
-
-static PyObject *Dtool_SequenceWrapper_getitem(PyObject *self, Py_ssize_t index) {
-  Dtool_SequenceWrapper *wrap = (Dtool_SequenceWrapper *)self;
-  nassertr(wrap, nullptr);
-  nassertr(wrap->_getitem_func, nullptr);
-  return wrap->_getitem_func(wrap->_base._self, index);
-}
-
-/**
- * Implementation of (x in property)
- */
-static int Dtool_SequenceWrapper_contains(PyObject *self, PyObject *value) {
-  Dtool_SequenceWrapper *wrap = (Dtool_SequenceWrapper *)self;
-  nassertr(wrap, -1);
-  nassertr(wrap->_len_func, -1);
-  nassertr(wrap->_getitem_func, -1);
-
-  Py_ssize_t length = wrap->_len_func(wrap->_base._self);
-
-  // Iterate through the items, invoking the equality function for each, until
-  // we have found the matching one.
-  for (Py_ssize_t index = 0; index < length; ++index) {
-    PyObject *item = wrap->_getitem_func(wrap->_base._self, index);
-    if (item != nullptr) {
-      int cmp = PyObject_RichCompareBool(item, value, Py_EQ);
-      if (cmp > 0) {
-        return 1;
-      }
-      if (cmp < 0) {
-        return -1;
-      }
-    } else {
-      return -1;
-    }
-  }
-  return 0;
-}
-
-/**
- * Implementation of property.index(x) which returns the index of the first
- * occurrence of x in the sequence, or raises a ValueError if it isn't found.
- */
-static PyObject *Dtool_SequenceWrapper_index(PyObject *self, PyObject *value) {
-  Dtool_SequenceWrapper *wrap = (Dtool_SequenceWrapper *)self;
-  nassertr(wrap, nullptr);
-  nassertr(wrap->_len_func, nullptr);
-  nassertr(wrap->_getitem_func, nullptr);
-
-  Py_ssize_t length = wrap->_len_func(wrap->_base._self);
-
-  // Iterate through the items, invoking the equality function for each, until
-  // we have found the right one.
-  for (Py_ssize_t index = 0; index < length; ++index) {
-    PyObject *item = wrap->_getitem_func(wrap->_base._self, index);
-    if (item != nullptr) {
-      int cmp = PyObject_RichCompareBool(item, value, Py_EQ);
-      if (cmp > 0) {
-        return Dtool_WrapValue(index);
-      }
-      if (cmp < 0) {
-        return nullptr;
-      }
-    } else {
-      return nullptr;
-    }
-  }
-  // Not found, raise ValueError.
-  return PyErr_Format(PyExc_ValueError, "%s.index() did not find value", wrap->_base._name);
-}
-
-/**
- * Implementation of property.count(x) which returns the number of occurrences
- * of x in the sequence.
- */
-static PyObject *Dtool_SequenceWrapper_count(PyObject *self, PyObject *value) {
-  Dtool_SequenceWrapper *wrap = (Dtool_SequenceWrapper *)self;
-  nassertr(wrap, nullptr);
-  Py_ssize_t index = 0;
-  if (wrap->_len_func != nullptr) {
-    index = wrap->_len_func(wrap->_base._self);
-  } else {
-    return Dtool_Raise_TypeError("property does not support count()");
-  }
-  // Iterate through the items, invoking the == operator for each.
-  long count = 0;
-  nassertr(wrap->_getitem_func, nullptr);
-  while (index > 0) {
-    --index;
-    PyObject *item = wrap->_getitem_func(wrap->_base._self, index);
-    if (item == nullptr) {
-      return nullptr;
-    }
-    int cmp = PyObject_RichCompareBool(item, value, Py_EQ);
-    if (cmp > 0) {
-      ++count;
-    }
-    if (cmp < 0) {
-      return nullptr;
-    }
-  }
-#if PY_MAJOR_VERSION >= 3
-  return PyLong_FromLong(count);
-#else
-  return PyInt_FromLong(count);
-#endif
-}
-
-/**
- * Implementation of `property[i] = x`
- */
-static int Dtool_MutableSequenceWrapper_setitem(PyObject *self, Py_ssize_t index, PyObject *value) {
-  Dtool_MutableSequenceWrapper *wrap = (Dtool_MutableSequenceWrapper *)self;
-  nassertr(wrap, -1);
-  if (wrap->_setitem_func != nullptr) {
-    return wrap->_setitem_func(wrap->_base._self, index, value);
-  } else {
-    Dtool_Raise_TypeError("property does not support item assignment");
-    return -1;
-  }
-}
-
-/**
- * Implementation of property.clear() which removes all elements in the
- * sequence, starting with the last.
- */
-static PyObject *Dtool_MutableSequenceWrapper_clear(PyObject *self, PyObject *) {
-  Dtool_MutableSequenceWrapper *wrap = (Dtool_MutableSequenceWrapper *)self;
-  nassertr(wrap, nullptr);
-  Py_ssize_t index = 0;
-  if (wrap->_len_func != nullptr && wrap->_setitem_func != nullptr) {
-    index = wrap->_len_func(wrap->_base._self);
-  } else {
-    return Dtool_Raise_TypeError("property does not support clear()");
-  }
-
-  // Iterate through the items, invoking the delete function for each.  We do
-  // this in reverse order, which may be more efficient.
-  while (index > 0) {
-    --index;
-    if (wrap->_setitem_func(wrap->_base._self, index, nullptr) != 0) {
-      return nullptr;
-    }
-  }
-  return Py_NewRef(Py_None);
-}
-
-/**
- * Implementation of property.remove(x) which removes the first occurrence of
- * x in the sequence, or raises a ValueError if it isn't found.
- */
-static PyObject *Dtool_MutableSequenceWrapper_remove(PyObject *self, PyObject *value) {
-  Dtool_MutableSequenceWrapper *wrap = (Dtool_MutableSequenceWrapper *)self;
-  nassertr(wrap, nullptr);
-  Py_ssize_t length = 0;
-  if (wrap->_len_func != nullptr && wrap->_setitem_func != nullptr) {
-    length = wrap->_len_func(wrap->_base._self);
-  } else {
-    return Dtool_Raise_TypeError("property does not support remove()");
-  }
-
-  // Iterate through the items, invoking the equality function for each, until
-  // we have found the right one.
-  nassertr(wrap->_getitem_func, nullptr);
-  for (Py_ssize_t index = 0; index < length; ++index) {
-    PyObject *item = wrap->_getitem_func(wrap->_base._self, index);
-    if (item != nullptr) {
-      int cmp = PyObject_RichCompareBool(item, value, Py_EQ);
-      if (cmp > 0) {
-        if (wrap->_setitem_func(wrap->_base._self, index, nullptr) == 0) {
-          return Py_NewRef(Py_None);
-        } else {
-          return nullptr;
-        }
-      }
-      if (cmp < 0) {
-        return nullptr;
-      }
-    } else {
-      return nullptr;
-    }
-  }
-  // Not found, raise ValueError.
-  return PyErr_Format(PyExc_ValueError, "%s.remove() did not find value", wrap->_base._name);
-}
-
-/**
- * Implementation of property.pop([i=-1]) which returns and removes the
- * element at the indicated index in the sequence.  If no index is provided,
- * it removes from the end of the list.
- */
-static PyObject *Dtool_MutableSequenceWrapper_pop(PyObject *self, PyObject *args) {
-  Dtool_MutableSequenceWrapper *wrap = (Dtool_MutableSequenceWrapper *)self;
-  nassertr(wrap, nullptr);
-  if (wrap->_getitem_func == nullptr || wrap->_setitem_func == nullptr ||
-      wrap->_len_func == nullptr) {
-    return Dtool_Raise_TypeError("property does not support pop()");
-  }
-
-  Py_ssize_t length = wrap->_len_func(wrap->_base._self);
-  Py_ssize_t index;
-  switch (PyTuple_GET_SIZE(args)) {
-  case 0:
-    index = length - 1;
-    break;
-  case 1:
-    index = PyNumber_AsSsize_t(PyTuple_GET_ITEM(args, 0), PyExc_IndexError);
-    if (index == -1 && PyErr_Occurred()) {
-      return nullptr;
-    }
-    if (index < 0) {
-      index += length;
-    }
-    break;
-  default:
-    return Dtool_Raise_TypeError("pop([i=-1]) takes 0 or 1 arguments");
-  }
-
-  if (length <= 0) {
-    return PyErr_Format(PyExc_IndexError, "%s.pop() from empty sequence", wrap->_base._name);
-  }
-
-  // Index error will be caught by getitem_func.
-  PyObject *value = wrap->_getitem_func(wrap->_base._self, index);
-  if (value != nullptr) {
-    if (wrap->_setitem_func(wrap->_base._self, index, nullptr) != 0) {
-      return nullptr;
-    }
-    return value;
-  }
-  return nullptr;
-}
-
-/**
- * Implementation of property.append(x) which is an alias for
- * property.insert(len(property), x).
- */
-static PyObject *Dtool_MutableSequenceWrapper_append(PyObject *self, PyObject *arg) {
-  Dtool_MutableSequenceWrapper *wrap = (Dtool_MutableSequenceWrapper *)self;
-  nassertr(wrap, nullptr);
-  if (wrap->_insert_func == nullptr) {
-    return Dtool_Raise_TypeError("property does not support append()");
-  }
-  return wrap->_insert_func(wrap->_base._self, (size_t)-1, arg);
-}
-
-/**
- * Implementation of property.insert(i, x) which inserts the given item at the
- * given position.
- */
-static PyObject *Dtool_MutableSequenceWrapper_insert(PyObject *self, PyObject *args) {
-  Dtool_MutableSequenceWrapper *wrap = (Dtool_MutableSequenceWrapper *)self;
-  nassertr(wrap, nullptr);
-  if (wrap->_insert_func == nullptr) {
-    return Dtool_Raise_TypeError("property does not support insert()");
-  }
-  if (PyTuple_GET_SIZE(args) != 2) {
-    return Dtool_Raise_TypeError("insert() takes exactly 2 arguments");
-  }
-  Py_ssize_t index = PyNumber_AsSsize_t(PyTuple_GET_ITEM(args, 0), PyExc_IndexError);
-  if (index == -1 && PyErr_Occurred()) {
-    return nullptr;
-  }
-  if (index < 0) {
-    if (wrap->_len_func != nullptr) {
-      index += wrap->_len_func(wrap->_base._self);
-    } else {
-      return PyErr_Format(PyExc_TypeError, "%s.insert() does not support negative indices", wrap->_base._name);
-    }
-  }
-  return wrap->_insert_func(wrap->_base._self, (size_t)std::max(index, (Py_ssize_t)0), PyTuple_GET_ITEM(args, 1));
-}
-
-/**
- * Implementation of property.extend(seq) which is equivalent to:
- * @code
- * for x in seq:
- *   property.append(seq)
- * @endcode
- */
-static PyObject *Dtool_MutableSequenceWrapper_extend(PyObject *self, PyObject *arg) {
-  Dtool_MutableSequenceWrapper *wrap = (Dtool_MutableSequenceWrapper *)self;
-  nassertr(wrap, nullptr);
-  if (wrap->_insert_func == nullptr) {
-    return Dtool_Raise_TypeError("property does not support extend()");
-  }
-  PyObject *iter = PyObject_GetIter(arg);
-  if (iter == nullptr) {
-    return nullptr;
-  }
-  PyObject *next = PyIter_Next(iter);
-  PyObject *retval = nullptr;
-  while (next != nullptr) {
-    retval = wrap->_insert_func(wrap->_base._self, (size_t)-1, next);
-    Py_DECREF(next);
-    if (retval == nullptr) {
-      Py_DECREF(iter);
-      return nullptr;
-    }
-    Py_DECREF(retval);
-    next = PyIter_Next(iter);
-  }
-
-  Py_DECREF(iter);
-  return Py_NewRef(Py_None);
-}
-
-/**
- * Implementation of `x in mapping`.
- */
-static int Dtool_MappingWrapper_contains(PyObject *self, PyObject *key) {
-  Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)self;
-  nassertr(wrap, -1);
-  nassertr(wrap->_getitem_func, -1);
-  PyObject *value = wrap->_getitem_func(wrap->_base._self, key);
-  if (value != nullptr) {
-    Py_DECREF(value);
-    return 1;
-  } else if (PyErr_ExceptionMatches(PyExc_KeyError) ||
-             PyErr_ExceptionMatches(PyExc_TypeError)) {
-    PyErr_Clear();
-    return 0;
-  } else {
-    return -1;
-  }
-}
-
-static PyObject *Dtool_MappingWrapper_getitem(PyObject *self, PyObject *key) {
-  Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)self;
-  nassertr(wrap, nullptr);
-  nassertr(wrap->_getitem_func, nullptr);
-  return wrap->_getitem_func(wrap->_base._self, key);
-}
-
-/**
- * Implementation of iter(property) that returns an iterable over all the
- * keys.
- */
-static PyObject *Dtool_MappingWrapper_iter(PyObject *self) {
-  Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)self;
-  nassertr(wrap, nullptr);
-
-  if (wrap->_keys._len_func == nullptr || wrap->_keys._getitem_func == nullptr) {
-    return PyErr_Format(PyExc_TypeError, "%s is not iterable", wrap->_base._name);
-  }
-
-  Dtool_SequenceWrapper *keys = Dtool_NewSequenceWrapper(wrap->_base._self, wrap->_base._name);
-  if (keys != nullptr) {
-    keys->_len_func = wrap->_keys._len_func;
-    keys->_getitem_func = wrap->_keys._getitem_func;
-    return PySeqIter_New((PyObject *)keys);
-  } else {
-    return nullptr;
-  }
-}
-
-/**
- * Implementation of property.get(key[,def=None]) which returns the value with
- * the given key in the mapping, or the given default value (which defaults to
- * None) if the key isn't found in the mapping.
- */
-static PyObject *Dtool_MappingWrapper_get(PyObject *self, PyObject *args) {
-  Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)self;
-  nassertr(wrap, nullptr);
-  nassertr(wrap->_getitem_func, nullptr);
-  Py_ssize_t size = PyTuple_GET_SIZE(args);
-  if (size != 1 && size != 2) {
-    return PyErr_Format(PyExc_TypeError, "%s.get() takes 1 or 2 arguments", wrap->_base._name);
-  }
-  PyObject *defvalue = Py_None;
-  if (size >= 2) {
-    defvalue = PyTuple_GET_ITEM(args, 1);
-  }
-  PyObject *key = PyTuple_GET_ITEM(args, 0);
-  PyObject *value = wrap->_getitem_func(wrap->_base._self, key);
-  if (value != nullptr) {
-    return value;
-  } else if (PyErr_ExceptionMatches(PyExc_KeyError)) {
-    PyErr_Clear();
-    return Py_NewRef(defvalue);
-  } else {
-    return nullptr;
-  }
-}
-
-/**
- * This is returned by mapping.keys().
- */
-static PyObject *Dtool_MappingWrapper_Keys_repr(PyObject *self) {
-  Dtool_WrapperBase *wrap = (Dtool_WrapperBase *)self;
-  nassertr(wrap, nullptr);
-
-  PyObject *repr = PyObject_Repr(wrap->_self);
-  PyObject *result;
-#if PY_MAJOR_VERSION >= 3
-  result = PyUnicode_FromFormat("<%s.keys() of %s>", wrap->_name, PyUnicode_AsUTF8(repr));
-#else
-  result = PyString_FromFormat("<%s.keys() of %s>", wrap->_name, PyString_AS_STRING(repr));
-#endif
-  Py_DECREF(repr);
-  return result;
-}
-
-/**
- * Implementation of property.keys(...) that returns a view of all the keys.
- */
-static PyObject *Dtool_MappingWrapper_keys(PyObject *self, PyObject *) {
-  Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)self;
-  nassertr(wrap, nullptr);
-
-  if (wrap->_keys._len_func == nullptr || wrap->_keys._getitem_func == nullptr) {
-    return Dtool_Raise_TypeError("property does not support keys()");
-  }
-
-  Dtool_MappingWrapper *keys = (Dtool_MappingWrapper *)PyObject_MALLOC(sizeof(Dtool_MappingWrapper));
-  if (keys == nullptr) {
-    return PyErr_NoMemory();
-  }
-
-  static PySequenceMethods seq_methods = {
-    Dtool_SequenceWrapper_length,
-    nullptr, // sq_concat
-    nullptr, // sq_repeat
-    Dtool_SequenceWrapper_getitem,
-    nullptr, // sq_slice
-    nullptr, // sq_ass_item
-    nullptr, // sq_ass_slice
-    Dtool_SequenceWrapper_contains,
-    nullptr, // sq_inplace_concat
-    nullptr, // sq_inplace_repeat
-  };
-
-  static PyTypeObject wrapper_type = {
-    PyVarObject_HEAD_INIT(nullptr, 0)
-    "sequence wrapper",
-    sizeof(Dtool_SequenceWrapper),
-    0, // tp_itemsize
-    Dtool_WrapperBase_dealloc,
-    0, // tp_vectorcall_offset
-    nullptr, // tp_getattr
-    nullptr, // tp_setattr
-    nullptr, // tp_compare
-    Dtool_MappingWrapper_Keys_repr,
-    nullptr, // tp_as_number
-    &seq_methods,
-    nullptr, // tp_as_mapping
-    nullptr, // tp_hash
-    nullptr, // tp_call
-    nullptr, // tp_str
-    PyObject_GenericGetAttr,
-    PyObject_GenericSetAttr,
-    nullptr, // tp_as_buffer
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES,
-    nullptr, // tp_doc
-    nullptr, // tp_traverse
-    nullptr, // tp_clear
-    nullptr, // tp_richcompare
-    0, // tp_weaklistoffset
-    PySeqIter_New,
-    nullptr, // tp_iternext
-    nullptr, // tp_methods
-    nullptr, // tp_members
-    nullptr, // tp_getset
-    nullptr, // tp_base
-    nullptr, // tp_dict
-    nullptr, // tp_descr_get
-    nullptr, // tp_descr_set
-    0, // tp_dictoffset
-    nullptr, // tp_init
-    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
-    0, // tp_version_tag,
-#if PY_VERSION_HEX >= 0x03040000
-    nullptr, // tp_finalize
-#endif
-#if PY_VERSION_HEX >= 0x03080000
-    nullptr, // tp_vectorcall
-#endif
-  };
-
-  static bool registered = false;
-  if (!registered) {
-    registered = true;
-
-    if (PyType_Ready(&wrapper_type) < 0) {
-      return nullptr;
-    }
-
-    // If the collections.abc module is loaded, register this as a subclass.
-    _register_collection((PyTypeObject *)&wrapper_type, "MappingView");
-  }
-
-  (void)PyObject_INIT(keys, &wrapper_type);
-  keys->_base._self = Py_XNewRef(wrap->_base._self);
-  keys->_base._name = wrap->_base._name;
-  keys->_keys._len_func = wrap->_keys._len_func;
-  keys->_keys._getitem_func = wrap->_keys._getitem_func;
-  keys->_getitem_func = wrap->_getitem_func;
-  keys->_setitem_func = nullptr;
-  return (PyObject *)keys;
-}
-
-/**
- * This is returned by mapping.values().
- */
-static PyObject *Dtool_MappingWrapper_Values_repr(PyObject *self) {
-  Dtool_WrapperBase *wrap = (Dtool_WrapperBase *)self;
-  nassertr(wrap, nullptr);
-
-  PyObject *repr = PyObject_Repr(wrap->_self);
-  PyObject *result;
-#if PY_MAJOR_VERSION >= 3
-  result = PyUnicode_FromFormat("<%s.values() of %s>", wrap->_name, PyUnicode_AsUTF8(repr));
-#else
-  result = PyString_FromFormat("<%s.values() of %s>", wrap->_name, PyString_AS_STRING(repr));
-#endif
-  Py_DECREF(repr);
-  return result;
-}
-
-static PyObject *Dtool_MappingWrapper_Values_getitem(PyObject *self, Py_ssize_t index) {
-  Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)self;
-  nassertr(wrap, nullptr);
-  nassertr(wrap->_keys._getitem_func, nullptr);
-
-  PyObject *key = wrap->_keys._getitem_func(wrap->_base._self, index);
-  if (key != nullptr) {
-    PyObject *value = wrap->_getitem_func(wrap->_base._self, key);
-    Py_DECREF(key);
-    return value;
-  }
-  return nullptr;
-}
-
-/**
- * Implementation of property.values(...) that returns a view of the values.
- */
-static PyObject *Dtool_MappingWrapper_values(PyObject *self, PyObject *) {
-  Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)self;
-  nassertr(wrap, nullptr);
-  nassertr(wrap->_getitem_func, nullptr);
-
-  if (wrap->_keys._len_func == nullptr || wrap->_keys._getitem_func == nullptr) {
-    return Dtool_Raise_TypeError("property does not support values()");
-  }
-
-  Dtool_MappingWrapper *values = (Dtool_MappingWrapper *)PyObject_MALLOC(sizeof(Dtool_MappingWrapper));
-  if (values == nullptr) {
-    return PyErr_NoMemory();
-  }
-
-  static PySequenceMethods seq_methods = {
-    Dtool_SequenceWrapper_length,
-    nullptr, // sq_concat
-    nullptr, // sq_repeat
-    Dtool_MappingWrapper_Values_getitem,
-    nullptr, // sq_slice
-    nullptr, // sq_ass_item
-    nullptr, // sq_ass_slice
-    Dtool_MappingWrapper_contains,
-    nullptr, // sq_inplace_concat
-    nullptr, // sq_inplace_repeat
-  };
-
-  static PyTypeObject wrapper_type = {
-    PyVarObject_HEAD_INIT(nullptr, 0)
-    "sequence wrapper",
-    sizeof(Dtool_MappingWrapper),
-    0, // tp_itemsize
-    Dtool_WrapperBase_dealloc,
-    0, // tp_vectorcall_offset
-    nullptr, // tp_getattr
-    nullptr, // tp_setattr
-    nullptr, // tp_compare
-    Dtool_MappingWrapper_Values_repr,
-    nullptr, // tp_as_number
-    &seq_methods,
-    nullptr, // tp_as_mapping
-    nullptr, // tp_hash
-    nullptr, // tp_call
-    nullptr, // tp_str
-    PyObject_GenericGetAttr,
-    PyObject_GenericSetAttr,
-    nullptr, // tp_as_buffer
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES,
-    nullptr, // tp_doc
-    nullptr, // tp_traverse
-    nullptr, // tp_clear
-    nullptr, // tp_richcompare
-    0, // tp_weaklistoffset
-    PySeqIter_New,
-    nullptr, // tp_iternext
-    nullptr, // tp_methods
-    nullptr, // tp_members
-    nullptr, // tp_getset
-    nullptr, // tp_base
-    nullptr, // tp_dict
-    nullptr, // tp_descr_get
-    nullptr, // tp_descr_set
-    0, // tp_dictoffset
-    nullptr, // tp_init
-    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
-    0, // tp_version_tag,
-#if PY_VERSION_HEX >= 0x03040000
-    nullptr, // tp_finalize
-#endif
-#if PY_VERSION_HEX >= 0x03080000
-    nullptr, // tp_vectorcall
-#endif
-  };
-
-  static bool registered = false;
-  if (!registered) {
-    registered = true;
-
-    if (PyType_Ready(&wrapper_type) < 0) {
-      return nullptr;
-    }
-
-    // If the collections.abc module is loaded, register this as a subclass.
-    _register_collection((PyTypeObject *)&wrapper_type, "ValuesView");
-  }
-
-  (void)PyObject_INIT(values, &wrapper_type);
-  values->_base._self = Py_XNewRef(wrap->_base._self);
-  values->_base._name = wrap->_base._name;
-  values->_keys._len_func = wrap->_keys._len_func;
-  values->_keys._getitem_func = wrap->_keys._getitem_func;
-  values->_getitem_func = wrap->_getitem_func;
-  values->_setitem_func = nullptr;
-  return (PyObject *)values;
-}
-
-/**
- * This is returned by mapping.items().
- */
-static PyObject *Dtool_MappingWrapper_Items_repr(PyObject *self) {
-  Dtool_WrapperBase *wrap = (Dtool_WrapperBase *)self;
-  nassertr(wrap, nullptr);
-
-  PyObject *repr = PyObject_Repr(wrap->_self);
-  PyObject *result;
-#if PY_MAJOR_VERSION >= 3
-  result = PyUnicode_FromFormat("<%s.items() of %s>", wrap->_name, PyUnicode_AsUTF8(repr));
-#else
-  result = PyString_FromFormat("<%s.items() of %s>", wrap->_name, PyString_AS_STRING(repr));
-#endif
-  Py_DECREF(repr);
-  return result;
-}
-
-static PyObject *Dtool_MappingWrapper_Items_getitem(PyObject *self, Py_ssize_t index) {
-  Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)self;
-  nassertr(wrap, nullptr);
-  nassertr(wrap->_keys._getitem_func, nullptr);
-
-  PyObject *key = wrap->_keys._getitem_func(wrap->_base._self, index);
-  if (key != nullptr) {
-    PyObject *value = wrap->_getitem_func(wrap->_base._self, key);
-    if (value != nullptr) {
-      // PyTuple_SET_ITEM steals the reference.
-      PyObject *item = PyTuple_New(2);
-      PyTuple_SET_ITEM(item, 0, key);
-      PyTuple_SET_ITEM(item, 1, value);
-      return item;
-    } else {
-      Py_DECREF(key);
-    }
-  }
-  return nullptr;
-}
-
-/**
- * Implementation of property.items(...) that returns an iterable yielding a
- * `(key, value)` tuple for every item.
- */
-static PyObject *Dtool_MappingWrapper_items(PyObject *self, PyObject *) {
-  Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)self;
-  nassertr(wrap, nullptr);
-  nassertr(wrap->_getitem_func, nullptr);
-
-  if (wrap->_keys._len_func == nullptr || wrap->_keys._getitem_func == nullptr) {
-    return Dtool_Raise_TypeError("property does not support items()");
-  }
-
-  Dtool_MappingWrapper *items = (Dtool_MappingWrapper *)PyObject_MALLOC(sizeof(Dtool_MappingWrapper));
-  if (items == nullptr) {
-    return PyErr_NoMemory();
-  }
-
-  static PySequenceMethods seq_methods = {
-    Dtool_SequenceWrapper_length,
-    nullptr, // sq_concat
-    nullptr, // sq_repeat
-    Dtool_MappingWrapper_Items_getitem,
-    nullptr, // sq_slice
-    nullptr, // sq_ass_item
-    nullptr, // sq_ass_slice
-    Dtool_MappingWrapper_contains,
-    nullptr, // sq_inplace_concat
-    nullptr, // sq_inplace_repeat
-  };
-
-  static PyTypeObject wrapper_type = {
-    PyVarObject_HEAD_INIT(nullptr, 0)
-    "sequence wrapper",
-    sizeof(Dtool_MappingWrapper),
-    0, // tp_itemsize
-    Dtool_WrapperBase_dealloc,
-    0, // tp_vectorcall_offset
-    nullptr, // tp_getattr
-    nullptr, // tp_setattr
-    nullptr, // tp_compare
-    Dtool_MappingWrapper_Items_repr,
-    nullptr, // tp_as_number
-    &seq_methods,
-    nullptr, // tp_as_mapping
-    nullptr, // tp_hash
-    nullptr, // tp_call
-    nullptr, // tp_str
-    PyObject_GenericGetAttr,
-    PyObject_GenericSetAttr,
-    nullptr, // tp_as_buffer
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES,
-    nullptr, // tp_doc
-    nullptr, // tp_traverse
-    nullptr, // tp_clear
-    nullptr, // tp_richcompare
-    0, // tp_weaklistoffset
-    PySeqIter_New,
-    nullptr, // tp_iternext
-    nullptr, // tp_methods
-    nullptr, // tp_members
-    nullptr, // tp_getset
-    nullptr, // tp_base
-    nullptr, // tp_dict
-    nullptr, // tp_descr_get
-    nullptr, // tp_descr_set
-    0, // tp_dictoffset
-    nullptr, // tp_init
-    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
-    0, // tp_version_tag,
-#if PY_VERSION_HEX >= 0x03040000
-    nullptr, // tp_finalize
-#endif
-#if PY_VERSION_HEX >= 0x03080000
-    nullptr, // tp_vectorcall
-#endif
-  };
-
-  static bool registered = false;
-  if (!registered) {
-    registered = true;
-
-    if (PyType_Ready(&wrapper_type) < 0) {
-      return nullptr;
-    }
-
-    // If the collections.abc module is loaded, register this as a subclass.
-    _register_collection((PyTypeObject *)&wrapper_type, "MappingView");
-  }
-
-  (void)PyObject_INIT(items, &wrapper_type);
-  items->_base._self = Py_XNewRef(wrap->_base._self);
-  items->_base._name = wrap->_base._name;
-  items->_keys._len_func = wrap->_keys._len_func;
-  items->_keys._getitem_func = wrap->_keys._getitem_func;
-  items->_getitem_func = wrap->_getitem_func;
-  items->_setitem_func = nullptr;
-  return (PyObject *)items;
-}
-
-/**
- * Implementation of `property[key] = value`
- */
-static int Dtool_MutableMappingWrapper_setitem(PyObject *self, PyObject *key, PyObject *value) {
-  Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)self;
-  nassertr(wrap->_setitem_func != nullptr, -1);
-  return wrap->_setitem_func(wrap->_base._self, key, value);
-}
-
-/**
- * Implementation of property.pop(key[,def=None]) which is the same as get()
- * except that it also removes the element from the mapping.
- */
-static PyObject *Dtool_MutableMappingWrapper_pop(PyObject *self, PyObject *args) {
-  Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)self;
-  nassertr(wrap, nullptr);
-  if (wrap->_getitem_func == nullptr || wrap->_setitem_func == nullptr) {
-    return Dtool_Raise_TypeError("property does not support pop()");
-  }
-
-  Py_ssize_t size = PyTuple_GET_SIZE(args);
-  if (size != 1 && size != 2) {
-    return PyErr_Format(PyExc_TypeError, "%s.pop() takes 1 or 2 arguments", wrap->_base._name);
-  }
-  PyObject *defvalue = Py_None;
-  if (size >= 2) {
-    defvalue = PyTuple_GET_ITEM(args, 1);
-  }
-
-  PyObject *key = PyTuple_GET_ITEM(args, 0);
-  PyObject *value = wrap->_getitem_func(wrap->_base._self, key);
-  if (value != nullptr) {
-    // OK, now set unset this value.
-    if (wrap->_setitem_func(wrap->_base._self, key, nullptr) == 0) {
-      return value;
-    } else {
-      Py_DECREF(value);
-      return nullptr;
-    }
-  } else if (PyErr_ExceptionMatches(PyExc_KeyError)) {
-    PyErr_Clear();
-    return Py_NewRef(defvalue);
-  } else {
-    return nullptr;
-  }
-}
-
-/**
- * Implementation of property.popitem() which returns and removes an arbitrary
- * (key, value) pair from the mapping.  Useful for destructive iteration.
- */
-static PyObject *Dtool_MutableMappingWrapper_popitem(PyObject *self, PyObject *) {
-  Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)self;
-  nassertr(wrap, nullptr);
-  if (wrap->_getitem_func == nullptr || wrap->_setitem_func == nullptr ||
-      wrap->_keys._len_func == nullptr || wrap->_keys._getitem_func == nullptr) {
-    return Dtool_Raise_TypeError("property does not support popitem()");
-  }
-
-  Py_ssize_t length = wrap->_keys._len_func(wrap->_base._self);
-  if (length < 1) {
-    return PyErr_Format(PyExc_KeyError, "%s is empty", wrap->_base._name);
-  }
-
-  PyObject *key = wrap->_keys._getitem_func(wrap->_base._self, length - 1);
-  if (key != nullptr) {
-    PyObject *value = wrap->_getitem_func(wrap->_base._self, key);
-    if (value != nullptr) {
-      // OK, now set unset this value.
-      if (wrap->_setitem_func(wrap->_base._self, key, nullptr) == 0) {
-        PyObject *item = PyTuple_New(2);
-        PyTuple_SET_ITEM(item, 0, key);
-        PyTuple_SET_ITEM(item, 1, value);
-        return item;
-      }
-      Py_DECREF(value);
-    }
-  }
-  return nullptr;
-}
-
-/*
- * Implementation of property.clear() which removes all elements in the
- * mapping.
- */
-static PyObject *Dtool_MutableMappingWrapper_clear(PyObject *self, PyObject *) {
-  Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)self;
-  nassertr(wrap, nullptr);
-  Py_ssize_t index = 0;
-  if (wrap->_keys._len_func != nullptr && wrap->_keys._getitem_func != nullptr &&
-      wrap->_setitem_func != nullptr) {
-    index = wrap->_keys._len_func(wrap->_base._self);
-  } else {
-    return Dtool_Raise_TypeError("property does not support clear()");
-  }
-
-  // Iterate through the items, invoking the delete function for each.  We do
-  // this in reverse order, which may be more efficient.
-  while (index > 0) {
-    --index;
-    PyObject *key = wrap->_keys._getitem_func(wrap->_base._self, index);
-    if (key != nullptr) {
-      int result = wrap->_setitem_func(wrap->_base._self, key, nullptr);
-      Py_DECREF(key);
-      if (result != 0) {
-        return nullptr;
-      }
-    }
-  }
-  return Py_NewRef(Py_None);
-}
-
-/**
- * Implementation of property.setdefault(key[,def=None]) which is the same as
- * get() except that it also writes the default value back to the mapping if
- * the key was not found is missing.
- */
-static PyObject *Dtool_MutableMappingWrapper_setdefault(PyObject *self, PyObject *args) {
-  Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)self;
-  nassertr(wrap, nullptr);
-
-  if (wrap->_getitem_func == nullptr || wrap->_setitem_func == nullptr) {
-    return Dtool_Raise_TypeError("property does not support setdefault()");
-  }
-
-  Py_ssize_t size = PyTuple_GET_SIZE(args);
-  if (size != 1 && size != 2) {
-    return PyErr_Format(PyExc_TypeError, "%s.setdefault() takes 1 or 2 arguments", wrap->_base._name);
-  }
-  PyObject *defvalue = Py_None;
-  if (size >= 2) {
-    defvalue = PyTuple_GET_ITEM(args, 1);
-  }
-  PyObject *key = PyTuple_GET_ITEM(args, 0);
-  PyObject *value = wrap->_getitem_func(wrap->_base._self, key);
-  if (value != nullptr) {
-    return value;
-  } else if (PyErr_ExceptionMatches(PyExc_KeyError)) {
-    PyErr_Clear();
-    if (wrap->_setitem_func(wrap->_base._self, key, defvalue) == 0) {
-      return Py_NewRef(defvalue);
-    }
-  }
-  return nullptr;
-}
-
-/**
- * Implementation of property.update(...) which sets multiple values in one
- * go.  It accepts either a single dictionary or keyword arguments, not both.
- */
-static PyObject *Dtool_MutableMappingWrapper_update(PyObject *self, PyObject *args, PyObject *kwargs) {
-  Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)self;
-  nassertr(wrap, nullptr);
-
-  if (wrap->_getitem_func == nullptr || wrap->_setitem_func == nullptr) {
-    return Dtool_Raise_TypeError("property does not support update()");
-  }
-
-  // We accept either a dict argument or keyword arguments, but not both.
-  PyObject *dict;
-  switch (PyTuple_GET_SIZE(args)) {
-  case 0:
-    if (kwargs == nullptr) {
-      // This is legal.
-      return Py_NewRef(Py_None);
-    }
-    dict = kwargs;
-    break;
-  case 1:
-    if (PyDict_Check(PyTuple_GET_ITEM(args, 0)) && (kwargs == nullptr || Py_SIZE(kwargs) == 0)) {
-      dict = PyTuple_GET_ITEM(args, 0);
-      break;
-    }
-    // Fall through
-  default:
-    return PyErr_Format(PyExc_TypeError, "%s.update() takes either a dict argument or keyword arguments", wrap->_base._name);
-  }
-
-  PyObject *result = Py_None;
-  PyObject *key, *value;
-  Py_ssize_t pos = 0;
-  Py_BEGIN_CRITICAL_SECTION(dict);
-  while (PyDict_Next(dict, &pos, &key, &value)) {
-    if (wrap->_setitem_func(wrap->_base._self, key, value) != 0) {
-      result = nullptr;
-      break;
-    }
-  }
-  Py_END_CRITICAL_SECTION();
-
-  return Py_XNewRef(result);
-}
-
-/**
- * This variant defines only a generator interface.
- */
-static PyObject *Dtool_GeneratorWrapper_iternext(PyObject *self) {
-  Dtool_GeneratorWrapper *wrap = (Dtool_GeneratorWrapper *)self;
-  nassertr(wrap, nullptr);
-  nassertr(wrap->_iternext_func, nullptr);
-  return wrap->_iternext_func(wrap->_base._self);
-}
-
-/**
- * This is a variant of the Python getset mechanism that permits static
- * properties.
- */
-static void
-Dtool_StaticProperty_dealloc(PyDescrObject *descr) {
-#if PY_VERSION_HEX >= 0x03080000
-  PyObject_GC_UnTrack(descr);
-#else
-  _PyObject_GC_UNTRACK(descr);
-#endif
-  Py_XDECREF(descr->d_type);
-  Py_XDECREF(descr->d_name);
-//#if PY_MAJOR_VERSION >= 3
-//  Py_XDECREF(descr->d_qualname);
-//#endif
-  PyObject_GC_Del(descr);
-}
-
-static PyObject *
-Dtool_StaticProperty_repr(PyDescrObject *descr, const char *format) {
-#if PY_MAJOR_VERSION >= 3
-  return PyUnicode_FromFormat("<attribute '%s' of '%s'>",
-                              PyUnicode_AsUTF8(descr->d_name),
-                              descr->d_type->tp_name);
-#else
-  return PyString_FromFormat("<attribute '%s' of '%s'>",
-                             PyString_AS_STRING(descr->d_name),
-                             descr->d_type->tp_name);
-#endif
-}
-
-static int
-Dtool_StaticProperty_traverse(PyObject *self, visitproc visit, void *arg) {
-  PyDescrObject *descr = (PyDescrObject *)self;
-  Py_VISIT(descr->d_type);
-  return 0;
-}
-
-static PyObject *
-Dtool_StaticProperty_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type) {
-  if (descr->d_getset->get != nullptr) {
-    return descr->d_getset->get(obj, descr->d_getset->closure);
-  } else {
-    return PyErr_Format(PyExc_AttributeError,
-                        "attribute '%s' of type '%.100s' is not readable",
-#if PY_MAJOR_VERSION >= 3
-                        PyUnicode_AsUTF8(((PyDescrObject *)descr)->d_name),
-#else
-                        PyString_AS_STRING(((PyDescrObject *)descr)->d_name),
-#endif
-                        ((PyDescrObject *)descr)->d_type->tp_name);
-  }
-}
-
-static int
-Dtool_StaticProperty_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value) {
-  if (descr->d_getset->set != nullptr) {
-    return descr->d_getset->set(obj, value, descr->d_getset->closure);
-  } else {
-    PyErr_Format(PyExc_AttributeError,
-                 "attribute '%s' of type '%.100s' is not writable",
-#if PY_MAJOR_VERSION >= 3
-                 PyUnicode_AsUTF8(((PyDescrObject *)descr)->d_name),
-#else
-                 PyString_AS_STRING(((PyDescrObject *)descr)->d_name),
-#endif
-                 ((PyDescrObject *)descr)->d_type->tp_name);
-    return -1;
-  }
-}
-
-/**
- * This wraps around a property that exposes a sequence interface.
- */
-Dtool_SequenceWrapper *Dtool_NewSequenceWrapper(PyObject *self, const char *name) {
-  Dtool_SequenceWrapper *wrap = (Dtool_SequenceWrapper *)PyObject_MALLOC(sizeof(Dtool_SequenceWrapper));
-  if (wrap == nullptr) {
-    return (Dtool_SequenceWrapper *)PyErr_NoMemory();
-  }
-
-  static PySequenceMethods seq_methods = {
-    Dtool_SequenceWrapper_length,
-    nullptr, // sq_concat
-    nullptr, // sq_repeat
-    Dtool_SequenceWrapper_getitem,
-    nullptr, // sq_slice
-    nullptr, // sq_ass_item
-    nullptr, // sq_ass_slice
-    Dtool_SequenceWrapper_contains,
-    nullptr, // sq_inplace_concat
-    nullptr, // sq_inplace_repeat
-  };
-
-  static PyMethodDef methods[] = {
-    {"index", &Dtool_SequenceWrapper_index, METH_O, nullptr},
-    {"count", &Dtool_SequenceWrapper_count, METH_O, nullptr},
-    {nullptr, nullptr, 0, nullptr}
-  };
-
-  static PyTypeObject wrapper_type = {
-    PyVarObject_HEAD_INIT(nullptr, 0)
-    "sequence wrapper",
-    sizeof(Dtool_SequenceWrapper),
-    0, // tp_itemsize
-    Dtool_WrapperBase_dealloc,
-    0, // tp_vectorcall_offset
-    nullptr, // tp_getattr
-    nullptr, // tp_setattr
-    nullptr, // tp_compare
-    Dtool_SequenceWrapper_repr,
-    nullptr, // tp_as_number
-    &seq_methods,
-    nullptr, // tp_as_mapping
-    nullptr, // tp_hash
-    nullptr, // tp_call
-    nullptr, // tp_str
-    PyObject_GenericGetAttr,
-    PyObject_GenericSetAttr,
-    nullptr, // tp_as_buffer
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES,
-    nullptr, // tp_doc
-    nullptr, // tp_traverse
-    nullptr, // tp_clear
-    nullptr, // tp_richcompare
-    0, // tp_weaklistoffset
-    PySeqIter_New,
-    nullptr, // tp_iternext
-    methods,
-    nullptr, // tp_members
-    nullptr, // tp_getset
-    nullptr, // tp_base
-    nullptr, // tp_dict
-    nullptr, // tp_descr_get
-    nullptr, // tp_descr_set
-    0, // tp_dictoffset
-    nullptr, // tp_init
-    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
-    0, // tp_version_tag,
-#if PY_VERSION_HEX >= 0x03040000
-    nullptr, // tp_finalize
-#endif
-#if PY_VERSION_HEX >= 0x03080000
-    nullptr, // tp_vectorcall
-#endif
-  };
-
-  static bool registered = false;
-  if (!registered) {
-    registered = true;
-
-    if (PyType_Ready(&wrapper_type) < 0) {
-      return nullptr;
-    }
-
-    // If the collections.abc module is loaded, register this as a subclass.
-    _register_collection((PyTypeObject *)&wrapper_type, "Sequence");
-  }
-
-  (void)PyObject_INIT(wrap, &wrapper_type);
-  wrap->_base._self = Py_XNewRef(self);
-  wrap->_base._name = name;
-  wrap->_len_func = nullptr;
-  wrap->_getitem_func = nullptr;
-  return wrap;
-}
-
-/**
- * This wraps around a property that exposes a mutable sequence interface.
- */
-Dtool_MutableSequenceWrapper *Dtool_NewMutableSequenceWrapper(PyObject *self, const char *name) {
-  Dtool_MutableSequenceWrapper *wrap = (Dtool_MutableSequenceWrapper *)PyObject_MALLOC(sizeof(Dtool_MutableSequenceWrapper));
-  if (wrap == nullptr) {
-    return (Dtool_MutableSequenceWrapper *)PyErr_NoMemory();
-  }
-
-  static PySequenceMethods seq_methods = {
-    Dtool_SequenceWrapper_length,
-    nullptr, // sq_concat
-    nullptr, // sq_repeat
-    Dtool_SequenceWrapper_getitem,
-    nullptr, // sq_slice
-    Dtool_MutableSequenceWrapper_setitem,
-    nullptr, // sq_ass_slice
-    Dtool_SequenceWrapper_contains,
-    Dtool_MutableSequenceWrapper_extend,
-    nullptr, // sq_inplace_repeat
-  };
-
-  static PyMethodDef methods[] = {
-    {"index", &Dtool_SequenceWrapper_index, METH_O, nullptr},
-    {"count", &Dtool_SequenceWrapper_count, METH_O, nullptr},
-    {"clear", &Dtool_MutableSequenceWrapper_clear, METH_NOARGS, nullptr},
-    {"pop", &Dtool_MutableSequenceWrapper_pop, METH_VARARGS, nullptr},
-    {"remove", &Dtool_MutableSequenceWrapper_remove, METH_O, nullptr},
-    {"append", &Dtool_MutableSequenceWrapper_append, METH_O, nullptr},
-    {"insert", &Dtool_MutableSequenceWrapper_insert, METH_VARARGS, nullptr},
-    {"extend", &Dtool_MutableSequenceWrapper_extend, METH_O, nullptr},
-    {nullptr, nullptr, 0, nullptr}
-  };
-
-  static PyTypeObject wrapper_type = {
-    PyVarObject_HEAD_INIT(nullptr, 0)
-    "sequence wrapper",
-    sizeof(Dtool_MutableSequenceWrapper),
-    0, // tp_itemsize
-    Dtool_WrapperBase_dealloc,
-    0, // tp_vectorcall_offset
-    nullptr, // tp_getattr
-    nullptr, // tp_setattr
-    nullptr, // tp_compare
-    Dtool_SequenceWrapper_repr,
-    nullptr, // tp_as_number
-    &seq_methods,
-    nullptr, // tp_as_mapping
-    nullptr, // tp_hash
-    nullptr, // tp_call
-    nullptr, // tp_str
-    PyObject_GenericGetAttr,
-    PyObject_GenericSetAttr,
-    nullptr, // tp_as_buffer
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES,
-    nullptr, // tp_doc
-    nullptr, // tp_traverse
-    nullptr, // tp_clear
-    nullptr, // tp_richcompare
-    0, // tp_weaklistoffset
-    PySeqIter_New,
-    nullptr, // tp_iternext
-    methods,
-    nullptr, // tp_members
-    nullptr, // tp_getset
-    nullptr, // tp_base
-    nullptr, // tp_dict
-    nullptr, // tp_descr_get
-    nullptr, // tp_descr_set
-    0, // tp_dictoffset
-    nullptr, // tp_init
-    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
-    0, // tp_version_tag,
-#if PY_VERSION_HEX >= 0x03040000
-    nullptr, // tp_finalize
-#endif
-#if PY_VERSION_HEX >= 0x03080000
-    nullptr, // tp_vectorcall
-#endif
-  };
-
-  static bool registered = false;
-  if (!registered) {
-    registered = true;
-
-    if (PyType_Ready(&wrapper_type) < 0) {
-      return nullptr;
-    }
-
-    // If the collections.abc module is loaded, register this as a subclass.
-    _register_collection((PyTypeObject *)&wrapper_type, "MutableSequence");
-  }
-
-  (void)PyObject_INIT(wrap, &wrapper_type);
-  wrap->_base._self = Py_XNewRef(self);
-  wrap->_base._name = name;
-  wrap->_len_func = nullptr;
-  wrap->_getitem_func = nullptr;
-  wrap->_setitem_func = nullptr;
-  wrap->_insert_func = nullptr;
-  return wrap;
-}
-
-/**
- * This wraps around a mapping interface, with getitem function.
- */
-Dtool_MappingWrapper *Dtool_NewMappingWrapper(PyObject *self, const char *name) {
-  Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)PyObject_MALLOC(sizeof(Dtool_MappingWrapper));
-  if (wrap == nullptr) {
-    return (Dtool_MappingWrapper *)PyErr_NoMemory();
-  }
-
-  static PySequenceMethods seq_methods = {
-    Dtool_SequenceWrapper_length,
-    nullptr, // sq_concat
-    nullptr, // sq_repeat
-    nullptr, // sq_item
-    nullptr, // sq_slice
-    nullptr, // sq_ass_item
-    nullptr, // sq_ass_slice
-    Dtool_MappingWrapper_contains,
-    nullptr, // sq_inplace_concat
-    nullptr, // sq_inplace_repeat
-  };
-
-  static PyMappingMethods map_methods = {
-    Dtool_SequenceWrapper_length,
-    Dtool_MappingWrapper_getitem,
-    nullptr, // mp_ass_subscript
-  };
-
-  static PyMethodDef methods[] = {
-    {"get", &Dtool_MappingWrapper_get, METH_VARARGS, nullptr},
-    {"keys", &Dtool_MappingWrapper_keys, METH_NOARGS, nullptr},
-    {"values", &Dtool_MappingWrapper_values, METH_NOARGS, nullptr},
-    {"items", &Dtool_MappingWrapper_items, METH_NOARGS, nullptr},
-    {nullptr, nullptr, 0, nullptr}
-  };
-
-  static PyTypeObject wrapper_type = {
-    PyVarObject_HEAD_INIT(nullptr, 0)
-    "mapping wrapper",
-    sizeof(Dtool_MappingWrapper),
-    0, // tp_itemsize
-    Dtool_WrapperBase_dealloc,
-    0, // tp_vectorcall_offset
-    nullptr, // tp_getattr
-    nullptr, // tp_setattr
-    nullptr, // tp_compare
-    Dtool_WrapperBase_repr,
-    nullptr, // tp_as_number
-    &seq_methods,
-    &map_methods,
-    nullptr, // tp_hash
-    nullptr, // tp_call
-    nullptr, // tp_str
-    PyObject_GenericGetAttr,
-    PyObject_GenericSetAttr,
-    nullptr, // tp_as_buffer
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES,
-    nullptr, // tp_doc
-    nullptr, // tp_traverse
-    nullptr, // tp_clear
-    nullptr, // tp_richcompare
-    0, // tp_weaklistoffset
-    Dtool_MappingWrapper_iter,
-    nullptr, // tp_iternext
-    methods,
-    nullptr, // tp_members
-    nullptr, // tp_getset
-    nullptr, // tp_base
-    nullptr, // tp_dict
-    nullptr, // tp_descr_get
-    nullptr, // tp_descr_set
-    0, // tp_dictoffset
-    nullptr, // tp_init
-    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
-    0, // tp_version_tag,
-#if PY_VERSION_HEX >= 0x03040000
-    nullptr, // tp_finalize
-#endif
-#if PY_VERSION_HEX >= 0x03080000
-    nullptr, // tp_vectorcall
-#endif
-  };
-
-  static bool registered = false;
-  if (!registered) {
-    registered = true;
-
-    if (PyType_Ready(&wrapper_type) < 0) {
-      return nullptr;
-    }
-
-    // If the collections.abc module is loaded, register this as a subclass.
-    _register_collection((PyTypeObject *)&wrapper_type, "Mapping");
-  }
-
-  (void)PyObject_INIT(wrap, &wrapper_type);
-  wrap->_base._self = Py_XNewRef(self);
-  wrap->_base._name = name;
-  wrap->_keys._len_func = nullptr;
-  wrap->_keys._getitem_func = nullptr;
-  wrap->_getitem_func = nullptr;
-  wrap->_setitem_func = nullptr;
-  return wrap;
-}
-
-/**
- * This wraps around a mapping interface, with getitem/setitem functions.
- */
-Dtool_MappingWrapper *Dtool_NewMutableMappingWrapper(PyObject *self, const char *name) {
-  Dtool_MappingWrapper *wrap = (Dtool_MappingWrapper *)PyObject_MALLOC(sizeof(Dtool_MappingWrapper));
-  if (wrap == nullptr) {
-    return (Dtool_MappingWrapper *)PyErr_NoMemory();
-  }
-
-  static PySequenceMethods seq_methods = {
-    Dtool_SequenceWrapper_length,
-    nullptr, // sq_concat
-    nullptr, // sq_repeat
-    nullptr, // sq_item
-    nullptr, // sq_slice
-    nullptr, // sq_ass_item
-    nullptr, // sq_ass_slice
-    Dtool_MappingWrapper_contains,
-    nullptr, // sq_inplace_concat
-    nullptr, // sq_inplace_repeat
-  };
-
-  static PyMappingMethods map_methods = {
-    Dtool_SequenceWrapper_length,
-    Dtool_MappingWrapper_getitem,
-    Dtool_MutableMappingWrapper_setitem,
-  };
-
-  static PyMethodDef methods[] = {
-    {"get", &Dtool_MappingWrapper_get, METH_VARARGS, nullptr},
-    {"pop", &Dtool_MutableMappingWrapper_pop, METH_VARARGS, nullptr},
-    {"popitem", &Dtool_MutableMappingWrapper_popitem, METH_NOARGS, nullptr},
-    {"clear", &Dtool_MutableMappingWrapper_clear, METH_VARARGS, nullptr},
-    {"setdefault", &Dtool_MutableMappingWrapper_setdefault, METH_VARARGS, nullptr},
-    {"update", (PyCFunction) &Dtool_MutableMappingWrapper_update, METH_VARARGS | METH_KEYWORDS, nullptr},
-    {"keys", &Dtool_MappingWrapper_keys, METH_NOARGS, nullptr},
-    {"values", &Dtool_MappingWrapper_values, METH_NOARGS, nullptr},
-    {"items", &Dtool_MappingWrapper_items, METH_NOARGS, nullptr},
-    {nullptr, nullptr, 0, nullptr}
-  };
-
-  static PyTypeObject wrapper_type = {
-    PyVarObject_HEAD_INIT(nullptr, 0)
-    "mapping wrapper",
-    sizeof(Dtool_MappingWrapper),
-    0, // tp_itemsize
-    Dtool_WrapperBase_dealloc,
-    0, // tp_vectorcall_offset
-    nullptr, // tp_getattr
-    nullptr, // tp_setattr
-    nullptr, // tp_compare
-    Dtool_WrapperBase_repr,
-    nullptr, // tp_as_number
-    &seq_methods,
-    &map_methods,
-    nullptr, // tp_hash
-    nullptr, // tp_call
-    nullptr, // tp_str
-    PyObject_GenericGetAttr,
-    PyObject_GenericSetAttr,
-    nullptr, // tp_as_buffer
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES,
-    nullptr, // tp_doc
-    nullptr, // tp_traverse
-    nullptr, // tp_clear
-    nullptr, // tp_richcompare
-    0, // tp_weaklistoffset
-    Dtool_MappingWrapper_iter,
-    nullptr, // tp_iternext
-    methods,
-    nullptr, // tp_members
-    nullptr, // tp_getset
-    nullptr, // tp_base
-    nullptr, // tp_dict
-    nullptr, // tp_descr_get
-    nullptr, // tp_descr_set
-    0, // tp_dictoffset
-    nullptr, // tp_init
-    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
-    0, // tp_version_tag,
-#if PY_VERSION_HEX >= 0x03040000
-    nullptr, // tp_finalize
-#endif
-#if PY_VERSION_HEX >= 0x03080000
-    nullptr, // tp_vectorcall
-#endif
-  };
-
-  static bool registered = false;
-  if (!registered) {
-    registered = true;
-
-    if (PyType_Ready(&wrapper_type) < 0) {
-      return nullptr;
-    }
-
-    // If the collections.abc module is loaded, register this as a subclass.
-    _register_collection((PyTypeObject *)&wrapper_type, "MutableMapping");
-  }
-
-  (void)PyObject_INIT(wrap, &wrapper_type);
-  wrap->_base._self = Py_XNewRef(self);
-  wrap->_base._name = name;
-  wrap->_keys._len_func = nullptr;
-  wrap->_keys._getitem_func = nullptr;
-  wrap->_getitem_func = nullptr;
-  wrap->_setitem_func = nullptr;
-  return wrap;
-}
-
-/**
- * Creates a generator that invokes a given function with the given self arg.
- */
-PyObject *
-Dtool_NewGenerator(PyObject *self, iternextfunc gen_next) {
-  static PyTypeObject wrapper_type = {
-    PyVarObject_HEAD_INIT(nullptr, 0)
-    "generator wrapper",
-    sizeof(Dtool_GeneratorWrapper),
-    0, // tp_itemsize
-    Dtool_WrapperBase_dealloc,
-    0, // tp_vectorcall_offset
-    nullptr, // tp_getattr
-    nullptr, // tp_setattr
-    nullptr, // tp_compare
-    nullptr, // tp_repr
-    nullptr, // tp_as_number
-    nullptr, // tp_as_sequence
-    nullptr, // tp_as_mapping
-    nullptr, // tp_hash
-    nullptr, // tp_call
-    nullptr, // tp_str
-    PyObject_GenericGetAttr,
-    PyObject_GenericSetAttr,
-    nullptr, // tp_as_buffer
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES,
-    nullptr, // tp_doc
-    nullptr, // tp_traverse
-    nullptr, // tp_clear
-    nullptr, // tp_richcompare
-    0, // tp_weaklistoffset
-    PyObject_SelfIter,
-    Dtool_GeneratorWrapper_iternext,
-    nullptr, // tp_methods
-    nullptr, // tp_members
-    nullptr, // tp_getset
-    nullptr, // tp_base
-    nullptr, // tp_dict
-    nullptr, // tp_descr_get
-    nullptr, // tp_descr_set
-    0, // tp_dictoffset
-    nullptr, // tp_init
-    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
-    0, // tp_version_tag,
-#if PY_VERSION_HEX >= 0x03040000
-    nullptr, // tp_finalize
-#endif
-#if PY_VERSION_HEX >= 0x03080000
-    nullptr, // tp_vectorcall
-#endif
-  };
-
-  if (PyType_Ready(&wrapper_type) < 0) {
-    return nullptr;
-  }
-
-  Dtool_GeneratorWrapper *gen;
-  gen = (Dtool_GeneratorWrapper *)PyType_GenericAlloc(&wrapper_type, 0);
-  if (gen != nullptr) {
-    gen->_base._self = Py_NewRef(self);
-    gen->_iternext_func = gen_next;
-  }
-  return (PyObject *)gen;
-}
-
-/**
- * This is a variant of the Python getset mechanism that permits static
- * properties.
- */
-PyObject *
-Dtool_NewStaticProperty(PyTypeObject *type, const PyGetSetDef *getset) {
-  static PyTypeObject wrapper_type = {
-    PyVarObject_HEAD_INIT(&PyType_Type, 0)
-    "getset_descriptor",
-    sizeof(PyGetSetDescrObject),
-    0, // tp_itemsize
-    (destructor)Dtool_StaticProperty_dealloc,
-    0, // tp_vectorcall_offset
-    nullptr, // tp_getattr
-    nullptr, // tp_setattr
-    nullptr, // tp_reserved
-    (reprfunc)Dtool_StaticProperty_repr,
-    nullptr, // tp_as_number
-    nullptr, // tp_as_sequence
-    nullptr, // tp_as_mapping
-    nullptr, // tp_hash
-    nullptr, // tp_call
-    nullptr, // tp_str
-    PyObject_GenericGetAttr,
-    nullptr, // tp_setattro
-    nullptr, // tp_as_buffer
-    Py_TPFLAGS_DEFAULT,
-    nullptr, // tp_doc
-    Dtool_StaticProperty_traverse,
-    nullptr, // tp_clear
-    nullptr, // tp_richcompare
-    0, // tp_weaklistoffset
-    nullptr, // tp_iter
-    nullptr, // tp_iternext
-    nullptr, // tp_methods
-    nullptr, // tp_members
-    nullptr, // tp_getset
-    nullptr, // tp_base
-    nullptr, // tp_dict
-    (descrgetfunc)Dtool_StaticProperty_get,
-    (descrsetfunc)Dtool_StaticProperty_set,
-    0, // tp_dictoffset
-    nullptr, // tp_init
-    nullptr, // tp_alloc
-    nullptr, // tp_new
-    nullptr, // tp_free
-    nullptr, // tp_is_gc
-    nullptr, // tp_bases
-    nullptr, // tp_mro
-    nullptr, // tp_cache
-    nullptr, // tp_subclasses
-    nullptr, // tp_weaklist
-    nullptr, // tp_del
-    0, // tp_version_tag,
-#if PY_VERSION_HEX >= 0x03040000
-    nullptr, // tp_finalize
-#endif
-#if PY_VERSION_HEX >= 0x03080000
-    nullptr, // tp_vectorcall
-#endif
-  };
-
-  if (PyType_Ready(&wrapper_type) < 0) {
-    return nullptr;
-  }
-
-  PyGetSetDescrObject *descr;
-  descr = (PyGetSetDescrObject *)PyType_GenericAlloc(&wrapper_type, 0);
-  if (descr != nullptr) {
-    Py_XINCREF(type);
-    descr->d_getset = (PyGetSetDef *)getset;
-#if PY_MAJOR_VERSION >= 3
-    descr->d_common.d_type = type;
-    descr->d_common.d_name = PyUnicode_InternFromString(getset->name);
-#if PY_VERSION_HEX >= 0x03030000
-    descr->d_common.d_qualname = nullptr;
-#endif
-#else
-    descr->d_type = type;
-    descr->d_name = PyString_InternFromString(getset->name);
-#endif
-  }
-  return (PyObject *)descr;
-}
-
-#endif  // HAVE_PYTHON

+ 5 - 1
dtool/src/parser-inc/algorithm

@@ -25,7 +25,11 @@ namespace std {
   constexpr const T &min(const T &a, const T &b);
   template<class T>
   constexpr const T &max(const T &a, const T &b);
+
+  template<class RandomIt>
+  void sort(RandomIt first, RandomIt last);
+  template<class RandomIt, class Compare>
+  void sort(RandomIt first, RandomIt last, Compare comp);
 }
 
 #endif
-

+ 9 - 0
dtool/src/parser-inc/emscripten/heap.h

@@ -0,0 +1,9 @@
+
+#pragma once
+
+#include <stddef.h>
+#include <stdint.h>
+#include <emscripten/emscripten.h>
+
+#define WASM_PAGE_SIZE 65536
+#define EMSCRIPTEN_PAGE_SIZE WASM_PAGE_SIZE

+ 12 - 1
makepanda/installer.nsi

@@ -145,7 +145,6 @@ var READABLE
         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}"
@@ -381,6 +380,7 @@ SectionGroup "Python modules" SecGroupPython
         !insertmacro PyBindingSection 3.11-32 .cp311-win32.pyd
         !insertmacro PyBindingSection 3.12-32 .cp312-win32.pyd
         !insertmacro PyBindingSection 3.13-32 .cp313-win32.pyd
+        !insertmacro PyBindingSection 3.14-32 .cp314-win32.pyd
     !else
         !insertmacro PyBindingSection 3.5 .cp35-win_amd64.pyd
         !insertmacro PyBindingSection 3.6 .cp36-win_amd64.pyd
@@ -391,6 +391,7 @@ SectionGroup "Python modules" SecGroupPython
         !insertmacro PyBindingSection 3.11 .cp311-win_amd64.pyd
         !insertmacro PyBindingSection 3.12 .cp312-win_amd64.pyd
         !insertmacro PyBindingSection 3.13 .cp313-win_amd64.pyd
+        !insertmacro PyBindingSection 3.14 .cp314-win_amd64.pyd
     !endif
 SectionGroupEnd
 
@@ -502,6 +503,7 @@ Function .onInit
         !insertmacro MaybeEnablePyBindingSection 3.11-32
         !insertmacro MaybeEnablePyBindingSection 3.12-32
         !insertmacro MaybeEnablePyBindingSection 3.13-32
+        !insertmacro MaybeEnablePyBindingSection 3.14-32
         ${EndIf}
     !else
         !insertmacro MaybeEnablePyBindingSection 3.5
@@ -514,6 +516,7 @@ Function .onInit
         !insertmacro MaybeEnablePyBindingSection 3.11
         !insertmacro MaybeEnablePyBindingSection 3.12
         !insertmacro MaybeEnablePyBindingSection 3.13
+        !insertmacro MaybeEnablePyBindingSection 3.14
         ${EndIf}
     !endif
 
@@ -539,6 +542,10 @@ Function .onInit
         SectionSetFlags ${SecPyBindings3.13} ${SF_RO}
         SectionSetInstTypes ${SecPyBindings3.13} 0
     !endif
+    !ifdef SecPyBindings3.14
+        SectionSetFlags ${SecPyBindings3.14} ${SF_RO}
+        SectionSetInstTypes ${SecPyBindings3.14} 0
+    !endif
     ${EndUnless}
 FunctionEnd
 
@@ -843,6 +850,7 @@ Section Uninstall
         !insertmacro RemovePythonPath 3.11-32
         !insertmacro RemovePythonPath 3.12-32
         !insertmacro RemovePythonPath 3.13-32
+        !insertmacro RemovePythonPath 3.14-32
     !else
         !insertmacro RemovePythonPath 3.5
         !insertmacro RemovePythonPath 3.6
@@ -853,6 +861,7 @@ Section Uninstall
         !insertmacro RemovePythonPath 3.11
         !insertmacro RemovePythonPath 3.12
         !insertmacro RemovePythonPath 3.13
+        !insertmacro RemovePythonPath 3.14
     !endif
 
     SetDetailsPrint both
@@ -924,6 +933,7 @@ SectionEnd
     !insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings3.11-32} $(DESC_SecPyBindings3.11-32)
     !insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings3.12-32} $(DESC_SecPyBindings3.12-32)
     !insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings3.13-32} $(DESC_SecPyBindings3.13-32)
+    !insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings3.14-32} $(DESC_SecPyBindings3.14-32)
   !else
     !insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings3.5} $(DESC_SecPyBindings3.5)
     !insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings3.6} $(DESC_SecPyBindings3.6)
@@ -934,6 +944,7 @@ SectionEnd
     !insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings3.11} $(DESC_SecPyBindings3.11)
     !insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings3.12} $(DESC_SecPyBindings3.12)
     !insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings3.13} $(DESC_SecPyBindings3.13)
+    !insertmacro MUI_DESCRIPTION_TEXT ${SecPyBindings3.14} $(DESC_SecPyBindings3.14)
   !endif
   !ifdef INCLUDE_PYVER
     !insertmacro MUI_DESCRIPTION_TEXT ${SecPython} $(DESC_SecPython)

+ 4 - 1
makepanda/installpanda.py

@@ -29,6 +29,9 @@ APP_INFO = (
   ("pstats", "Panda3D Profiling Tool", ("pstats",), False),
 )
 
+EXCLUDE_BINARIES = ["deploy-stub", "deploy-stubw", "run_tests"]
+
+
 def WriteApplicationsFile(fname, appinfo, mimeinfo, bindir):
     fhandle = open(fname, "w")
     for app, desc, exts, multiple in appinfo:
@@ -265,7 +268,7 @@ def InstallPanda(destdir="", prefix="/usr", outputdir="built", libdir=GetLibDir(
             oscmd(f"cp -R -P {outputdir}/lib/{base} {dest_libdir}/panda3d/{base}")
 
     for base in os.listdir(outputdir + "/bin"):
-        if not base.startswith("deploy-stub"):
+        if base not in EXCLUDE_BINARIES:
             oscmd(f"cp -R -P {outputdir}/bin/{base} {dest_prefix}/bin/{base}")
 
     DeleteVCS(dest_prefix + "/share/panda3d")

+ 5 - 3
makepanda/makepackage.py

@@ -125,6 +125,8 @@ MACOS_SCRIPT_POSTFIX = """\
 fi
 """
 
+EXCLUDE_BINARIES = ["deploy-stub", "deploy-stubw", "run_tests"]
+
 
 def MakeInstallerNSIS(version, file, title, installdir, compressor="lzma", **kwargs):
     outputdir = GetOutputDir()
@@ -401,7 +403,7 @@ def MakeInstallerLinux(version, debversion=None, rpmversion=None, rpmrelease=1,
 
         # Add the binaries in /usr/bin explicitly to the spec file
         for base in os.listdir(outputdir + "/bin"):
-            if not base.startswith("deploy-stub"):
+            if base not in EXCLUDE_BINARIES:
                 txt += "/usr/bin/%s\n" % (base)
 
         # Write out the spec file.
@@ -467,7 +469,7 @@ def MakeInstallerOSX(version, python_versions=[], installdir=None, **kwargs):
     oscmd("install -m 0644 doc/man/*.1 dstroot/tools/usr/local/share/man/man1/")
 
     for base in os.listdir(outputdir + "/bin"):
-        if not base.startswith("deploy-stub"):
+        if base not in EXCLUDE_BINARIES:
             binname = ("dstroot/tools/%s/bin/" % installdir) + base
             # OSX needs the -R argument to copy symbolic links correctly, it doesn't have -d. How weird.
             oscmd("cp -R " + outputdir + "/bin/" + base + " " + binname)
@@ -792,7 +794,7 @@ def MakeInstallerFreeBSD(version, python_versions=[], **kwargs):
         oscmd("rm -f %s/tmp/python_dep" % outputdir)
 
         if "PYTHONVERSION" in SDK:
-            pyver_nodot = SDK["PYTHONVERSION"][6:].rstrip('dmu').replace('.', '')
+            pyver_nodot = SDK["PYTHONVERSION"][6:].rstrip('dmut').replace('.', '')
         else:
             pyver_nodot = "%d%d" % (sys.version_info[:2])
 

+ 75 - 54
makepanda/makepanda.py

@@ -156,7 +156,7 @@ def usage(problem):
     print("  --everything      (enable every third-party lib)")
     print("  --directx-sdk=X   (specify version of DirectX SDK to use: jun2010, aug2009)")
     print("  --windows-sdk=X   (specify Windows SDK version, eg. 7.1, 8.1, 10 or 11.  Default is 8.1)")
-    print("  --msvc-version=X  (specify Visual C++ version, eg. 10, 11, 12, 14, 14.1, 14.2, 14.3.  Default is 14)")
+    print("  --msvc-version=X  (specify Visual C++ version, eg. 14.1, 14.2, 14.3.  Default is 14.1)")
     print("  --use-icl         (experimental setting to use an intel compiler instead of MSVC on Windows)")
     print("")
     print("The simplest way to compile panda is to just type:")
@@ -280,11 +280,11 @@ def parseopts(args):
                         break
                     elif option == "--" + pkg.lower() + "-incdir":
                         PkgSetCustomLocation(pkg)
-                        IncDirectory(pkg, value)
+                        IncDirectory(pkg, os.path.expanduser(value))
                         break
                     elif option == "--" + pkg.lower() + "-libdir":
                         PkgSetCustomLocation(pkg)
-                        LibDirectory(pkg, value)
+                        LibDirectory(pkg, os.path.expanduser(value))
                         break
             if (option == "--everything" or option.startswith("--use-")
                 or option == "--nothing" or option.startswith("--no-")):
@@ -322,8 +322,8 @@ def parseopts(args):
 
     if GetTarget() == 'windows':
         if not MSVC_VERSION:
-            print("No MSVC version specified. Defaulting to 14 (Visual Studio 2015).")
-            MSVC_VERSION = (14, 0)
+            print("No MSVC version specified. Defaulting to 14.1 (Visual Studio 2017).")
+            MSVC_VERSION = (14, 1)
         else:
             try:
                 MSVC_VERSION = tuple(int(d) for d in MSVC_VERSION.split('.'))[:2]
@@ -332,12 +332,10 @@ def parseopts(args):
             except:
                 usage("Invalid setting for --msvc-version")
 
-        if MSVC_VERSION < (14, 0):
+        if MSVC_VERSION < (14, 1):
             warn_prefix = "%sERROR:%s " % (GetColor("red"), GetColor())
             print("=========================================================================")
-            print(warn_prefix + "Support for MSVC versions before 2015 has been discontinued.")
-            print(warn_prefix + "For more information, or any questions, please visit:")
-            print(warn_prefix + "  https://github.com/panda3d/panda3d/issues/288")
+            print(warn_prefix + "Support for MSVC versions before 2017 has been discontinued.")
             print("=========================================================================")
             sys.stdout.flush()
             time.sleep(1.0)
@@ -436,6 +434,8 @@ elif target == 'darwin':
 
     if arch_tag == 'arm64':
         PLATFORM = 'macosx-11.0-' + arch_tag
+    elif sys.version_info >= (3, 13):
+        PLATFORM = 'macosx-10.13-' + arch_tag
     else:
         PLATFORM = 'macosx-10.9-' + arch_tag
 
@@ -573,6 +573,11 @@ if GetHost() == 'windows' and GetTarget() == 'windows':
 else:
     COMPILER = "GCC"
 
+# Ensure we've pip-installed interrogate if we need it before setting
+# PYTHONHOME, etc.
+if not PkgSkip("PYTHON"):
+    GetInterrogate()
+
 SetupBuildEnvironment(COMPILER)
 
 ########################################################################
@@ -1070,12 +1075,14 @@ if (COMPILER=="GCC"):
             # Python may have been compiled with these requirements.
             # Is there a cleaner way to check this?
             LinkFlag("PYTHON", "-s USE_BZIP2=1 -s USE_SQLITE3=1")
-            if not PkgHasCustomLocation("PYTHON"):
+            if PkgHasCustomLocation("PYTHON"):
+                python_libdir = FindLibDirectory("PYTHON")
+            else:
                 python_libdir = GetThirdpartyDir() + "python/lib"
-                if os.path.isfile(python_libdir + "/libmpdec.a"):
-                    LibName("PYTHON", python_libdir + "/libmpdec.a")
-                if os.path.isfile(python_libdir + "/libexpat.a"):
-                    LibName("PYTHON", python_libdir + "/libexpat.a")
+
+            for lib in "libmpdec.a", "libexpat.a", "libHacl_Hash_SHA2.a":
+                if os.path.isfile(python_libdir + "/" + lib):
+                    LibName("PYTHON", python_libdir + "/" + lib)
 
         if GetTarget() == "linux":
             LibName("PYTHON", "-lutil")
@@ -1362,7 +1369,7 @@ def CompileCxx(obj,src,opts):
 
     if (COMPILER=="GCC"):
         if (src.endswith(".c")): cmd = GetCC() +' -fPIC -c -o ' + obj
-        else:                    cmd = GetCXX()+' -std=gnu++11 -ftemplate-depth-70 -fPIC -c -o ' + obj
+        else:                    cmd = GetCXX()+' -std=gnu++14 -ftemplate-depth-70 -fPIC -c -o ' + obj
         for (opt, dir) in INCDIRECTORIES:
             if (opt=="ALWAYS") or (opt in opts): cmd += ' -I' + BracketNameWithQuotes(dir)
         for (opt, dir) in FRAMEWORKDIRECTORIES:
@@ -1774,7 +1781,7 @@ def CompileLink(dll, obj, opts):
                 if "PYTHON" not in opts:
                     pythonv = SDK["PYTHONVERSION"].replace('.', '')
                     if optlevel <= 2:
-                        cmd += ' /NOD:{}d.lib'.format(pythonv)
+                        cmd += ' /NOD:{}_d.lib'.format(pythonv)
                     else:
                         cmd += ' /NOD:{}.lib'.format(pythonv)
 
@@ -1921,6 +1928,8 @@ def CompileLink(dll, obj, opts):
 
             if tuple(OSX_ARCHS) == ('arm64',):
                 cmd += " -mmacosx-version-min=11.0"
+            elif sys.version_info >= (3, 13) and 'PYTHON' in opts:
+                cmd += " -mmacosx-version-min=10.13"
             else:
                 cmd += " -mmacosx-version-min=10.9"
 
@@ -1946,7 +1955,6 @@ def CompileLink(dll, obj, opts):
         elif GetTarget() == 'emscripten':
             cmd += " -s WARN_ON_UNDEFINED_SYMBOLS=1"
             if GetOrigExt(dll) == ".exe":
-                cmd += " --memory-init-file 0"
                 cmd += " -s EXIT_RUNTIME=1"
 
         else:
@@ -2550,7 +2558,8 @@ def WriteConfigSettings():
         dtool_config["PYTHON_FRAMEWORK"] = 'Python'
         dtool_config["PHAVE_MALLOC_H"] = 'UNDEF'
         dtool_config["PHAVE_SYS_MALLOC_H"] = '1'
-        dtool_config["HAVE_OPENAL_FRAMEWORK"] = '1'
+        if not os.path.isdir(GetThirdpartyDir() + "openal"):
+            dtool_config["HAVE_OPENAL_FRAMEWORK"] = '1'
         dtool_config["HAVE_X11"] = 'UNDEF'  # We might have X11, but we don't need it.
         dtool_config["IS_LINUX"] = 'UNDEF'
         dtool_config["HAVE_VIDEO4LINUX"] = 'UNDEF'
@@ -2809,7 +2818,8 @@ del_files = ['core.py', 'core.pyc', 'core.pyo',
              'direct.py', 'direct.pyc', 'direct.pyo',
              '_direct.pyd', '_direct.so',
              'dtoolconfig.pyd', 'dtoolconfig.so',
-             'net.pyd', 'net.so']
+             'net.pyd', 'net.so',
+             'interrogatedb.pyd', 'interrogatedb.so']
 
 for basename in del_files:
     path = os.path.join(GetOutputDir(), 'panda3d', basename)
@@ -3523,27 +3533,6 @@ TargetAdd('libp3dtoolconfig.dll', input='p3prc_composite2.obj')
 TargetAdd('libp3dtoolconfig.dll', input='libp3dtool.dll')
 TargetAdd('libp3dtoolconfig.dll', opts=['ADVAPI', 'OPENSSL', 'WINGDI', 'WINUSER'])
 
-#
-# DIRECTORY: dtool/src/interrogatedb/
-#
-
-OPTS=['DIR:dtool/src/interrogatedb', 'BUILDING:INTERROGATEDB']
-TargetAdd('p3interrogatedb_composite1.obj', opts=OPTS, input='p3interrogatedb_composite1.cxx')
-TargetAdd('p3interrogatedb_composite2.obj', opts=OPTS, input='p3interrogatedb_composite2.cxx')
-TargetAdd('libp3interrogatedb.dll', input='p3interrogatedb_composite1.obj')
-TargetAdd('libp3interrogatedb.dll', input='p3interrogatedb_composite2.obj')
-TargetAdd('libp3interrogatedb.dll', input='libp3dtool.dll')
-TargetAdd('libp3interrogatedb.dll', input='libp3dtoolconfig.dll')
-
-# This used to be called dtoolconfig.pyd, but it just contains the interrogatedb
-# stuff, so it has been renamed appropriately.
-OPTS=['DIR:dtool/metalibs/dtoolconfig']
-PyTargetAdd('interrogatedb_pydtool.obj', opts=OPTS, input="pydtool.cxx")
-PyTargetAdd('interrogatedb.pyd', input='interrogatedb_pydtool.obj')
-PyTargetAdd('interrogatedb.pyd', input='libp3dtool.dll')
-PyTargetAdd('interrogatedb.pyd', input='libp3dtoolconfig.dll')
-PyTargetAdd('interrogatedb.pyd', input='libp3interrogatedb.dll')
-
 #
 # DIRECTORY: dtool/src/prckeys/
 #
@@ -4283,7 +4272,6 @@ PyTargetAdd('core.pyd', input='p3display_ext_composite.obj')
 PyTargetAdd('core.pyd', input='p3collide_ext_composite.obj')
 
 PyTargetAdd('core.pyd', input='core_module.obj')
-PyTargetAdd('core.pyd', input='libp3interrogatedb.dll')
 PyTargetAdd('core.pyd', input=COMMON_PANDA_LIBS)
 PyTargetAdd('core.pyd', opts=['WINSOCK2'])
 
@@ -4323,7 +4311,6 @@ if not PkgSkip("VISION"):
     PyTargetAdd('vision.pyd', input='vision_module.obj')
     PyTargetAdd('vision.pyd', input='libp3vision_igate.obj')
     PyTargetAdd('vision.pyd', input='libp3vision.dll')
-    PyTargetAdd('vision.pyd', input='libp3interrogatedb.dll')
     PyTargetAdd('vision.pyd', input=COMMON_PANDA_LIBS)
 
 #
@@ -4355,7 +4342,6 @@ if not PkgSkip('SKEL'):
     PyTargetAdd('skel.pyd', input='skel_module.obj')
     PyTargetAdd('skel.pyd', input='libp3skel_igate.obj')
     PyTargetAdd('skel.pyd', input='libpandaskel.dll')
-    PyTargetAdd('skel.pyd', input='libp3interrogatedb.dll')
     PyTargetAdd('skel.pyd', input=COMMON_PANDA_LIBS)
 
 #
@@ -4392,7 +4378,6 @@ if not PkgSkip('PANDAFX'):
     PyTargetAdd('fx.pyd', input='fx_module.obj')
     PyTargetAdd('fx.pyd', input='libp3distort_igate.obj')
     PyTargetAdd('fx.pyd', input='libpandafx.dll')
-    PyTargetAdd('fx.pyd', input='libp3interrogatedb.dll')
     PyTargetAdd('fx.pyd', input=COMMON_PANDA_LIBS)
 
 #
@@ -4418,7 +4403,6 @@ if not PkgSkip("VRPN"):
     PyTargetAdd('vrpn.pyd', input='vrpn_module.obj')
     PyTargetAdd('vrpn.pyd', input='libp3vrpn_igate.obj')
     PyTargetAdd('vrpn.pyd', input='libp3vrpn.dll')
-    PyTargetAdd('vrpn.pyd', input='libp3interrogatedb.dll')
     PyTargetAdd('vrpn.pyd', input=COMMON_PANDA_LIBS)
 
 #
@@ -4637,7 +4621,6 @@ if not PkgSkip("EGG"):
     PyTargetAdd('egg.pyd', input='libp3egg_igate.obj')
     PyTargetAdd('egg.pyd', input='libp3egg2pg_igate.obj')
     PyTargetAdd('egg.pyd', input='libpandaegg.dll')
-    PyTargetAdd('egg.pyd', input='libp3interrogatedb.dll')
     PyTargetAdd('egg.pyd', input=COMMON_PANDA_LIBS)
 
 #
@@ -4837,7 +4820,6 @@ if not PkgSkip("ODE"):
     PyTargetAdd('ode.pyd', input='libpandaode_igate.obj')
     PyTargetAdd('ode.pyd', input='p3ode_ext_composite.obj')
     PyTargetAdd('ode.pyd', input='libpandaode.dll')
-    PyTargetAdd('ode.pyd', input='libp3interrogatedb.dll')
     PyTargetAdd('ode.pyd', input=COMMON_PANDA_LIBS)
     PyTargetAdd('ode.pyd', opts=['WINUSER', 'ODE'])
 
@@ -4873,7 +4855,6 @@ if not PkgSkip("BULLET"):
     PyTargetAdd('bullet.pyd', input='bullet_module.obj')
     PyTargetAdd('bullet.pyd', input='libpandabullet_igate.obj')
     PyTargetAdd('bullet.pyd', input='libpandabullet.dll')
-    PyTargetAdd('bullet.pyd', input='libp3interrogatedb.dll')
     PyTargetAdd('bullet.pyd', input=COMMON_PANDA_LIBS)
     PyTargetAdd('bullet.pyd', opts=['WINUSER', 'BULLET'])
 
@@ -4939,7 +4920,6 @@ if not PkgSkip("PANDAPHYSICS"):
     if not PkgSkip("PANDAPARTICLESYSTEM"):
         PyTargetAdd('physics.pyd', input='libp3particlesystem_igate.obj')
     PyTargetAdd('physics.pyd', input='libpandaphysics.dll')
-    PyTargetAdd('physics.pyd', input='libp3interrogatedb.dll')
     PyTargetAdd('physics.pyd', input=COMMON_PANDA_LIBS)
 
 #
@@ -5254,7 +5234,6 @@ if not PkgSkip("DIRECT"):
 
     PyTargetAdd('direct.pyd', input='direct_module.obj')
     PyTargetAdd('direct.pyd', input='libp3direct.dll')
-    PyTargetAdd('direct.pyd', input='libp3interrogatedb.dll')
     PyTargetAdd('direct.pyd', input=COMMON_PANDA_LIBS)
     PyTargetAdd('direct.pyd', opts=['WINUSER', 'WINGDI', 'WINSOCK2'])
 
@@ -5953,7 +5932,6 @@ if not PkgSkip("CONTRIB"):
     PyTargetAdd('ai.pyd', input='ai_module.obj')
     PyTargetAdd('ai.pyd', input='libpandaai_igate.obj')
     PyTargetAdd('ai.pyd', input='libpandaai.dll')
-    PyTargetAdd('ai.pyd', input='libp3interrogatedb.dll')
     PyTargetAdd('ai.pyd', input=COMMON_PANDA_LIBS)
 
 #
@@ -5974,7 +5952,6 @@ if not PkgSkip("CONTRIB") and not PkgSkip("PYTHON"):
     PyTargetAdd('_rplight.pyd', input='rplight_module.obj')
     PyTargetAdd('_rplight.pyd', input='libp3rplight_igate.obj')
     PyTargetAdd('_rplight.pyd', input='p3rplight_composite1.obj')
-    PyTargetAdd('_rplight.pyd', input='libp3interrogatedb.dll')
     PyTargetAdd('_rplight.pyd', input=COMMON_PANDA_LIBS)
 
 #
@@ -6025,6 +6002,42 @@ if PkgSkip("PYTHON") == 0:
         PyTargetAdd('libdeploy-stubw.dll', input='libp3android.dll')
         PyTargetAdd('libdeploy-stubw.dll', opts=['DEPLOYSTUB', 'ANDROID'])
 
+#
+# Build the test runner for static builds
+#
+if GetLinkAllStatic():
+    if GetTarget() == 'emscripten':
+        LinkFlag('RUN_TESTS_FLAGS', '-s NODERAWFS')
+        LinkFlag('RUN_TESTS_FLAGS', '-s ASSERTIONS=2')
+        LinkFlag('RUN_TESTS_FLAGS', '-s ALLOW_MEMORY_GROWTH')
+        LinkFlag('RUN_TESTS_FLAGS', '-s INITIAL_HEAP=585302016')
+        LinkFlag('RUN_TESTS_FLAGS', '-s STACK_SIZE=1048576')
+        LinkFlag('RUN_TESTS_FLAGS', '--minify 0')
+
+    if not PkgSkip('DIRECT'):
+        DefSymbol('RUN_TESTS_FLAGS', 'HAVE_DIRECT')
+    if not PkgSkip('PANDAPHYSICS'):
+        DefSymbol('RUN_TESTS_FLAGS', 'HAVE_PHYSICS')
+    if not PkgSkip('EGG'):
+        DefSymbol('RUN_TESTS_FLAGS', 'HAVE_EGG')
+    if not PkgSkip('BULLET'):
+        DefSymbol('RUN_TESTS_FLAGS', 'HAVE_BULLET')
+
+    OPTS=['DIR:tests', 'PYTHON', 'RUN_TESTS_FLAGS']
+    PyTargetAdd('run_tests-main.obj', opts=OPTS, input='main.c')
+    PyTargetAdd('run_tests.exe', input='run_tests-main.obj')
+    PyTargetAdd('run_tests.exe', input='core.pyd')
+    if not PkgSkip('DIRECT'):
+        PyTargetAdd('run_tests.exe', input='direct.pyd')
+    if not PkgSkip('PANDAPHYSICS'):
+        PyTargetAdd('run_tests.exe', input='physics.pyd')
+    if not PkgSkip('EGG'):
+        PyTargetAdd('run_tests.exe', input='egg.pyd')
+    if not PkgSkip('BULLET'):
+        PyTargetAdd('run_tests.exe', input='bullet.pyd')
+    PyTargetAdd('run_tests.exe', input=COMMON_PANDA_LIBS)
+    PyTargetAdd('run_tests.exe', opts=['PYTHON', 'BULLET', 'RUN_TESTS_FLAGS'])
+
 #
 # Generate the models directory and samples directory
 #
@@ -6186,8 +6199,16 @@ finally:
 
 # Run the test suite.
 if RUNTESTS:
-    cmdstr = BracketNameWithQuotes(SDK["PYTHONEXEC"].replace('\\', '/'))
-    cmdstr += " -B -m pytest tests"
+    if GetLinkAllStatic():
+        runner = FindLocation("run_tests.exe", [])
+        if runner.endswith(".js"):
+            cmdstr = "node " + BracketNameWithQuotes(runner)
+        else:
+            cmdstr = BracketNameWithQuotes(runner)
+    else:
+        cmdstr = BracketNameWithQuotes(SDK["PYTHONEXEC"].replace('\\', '/'))
+        cmdstr += " -B -m pytest"
+    cmdstr += " tests"
     if GetVerbose():
         cmdstr += " --verbose"
     oscmd(cmdstr)

+ 126 - 32
makepanda/makepandacore.py

@@ -592,8 +592,8 @@ def GetInterrogateDir():
             return INTERROGATE_DIR
 
         dir = os.path.join(GetOutputDir(), "tmp", "interrogate")
-        if not os.path.isdir(os.path.join(dir, "panda3d_interrogate-0.2.0.dist-info")):
-            oscmd("\"%s\" -m pip install --force-reinstall -t \"%s\" panda3d-interrogate==0.2.0" % (sys.executable, dir))
+        if not os.path.isdir(os.path.join(dir, "panda3d_interrogate-0.4.0.dist-info")):
+            oscmd("\"%s\" -m pip install --force-reinstall --upgrade -t \"%s\" panda3d-interrogate==0.4.0" % (sys.executable, dir))
 
         INTERROGATE_DIR = dir
 
@@ -2148,7 +2148,16 @@ def SdkLocatePython(prefer_thirdparty_python=False):
             sdkdir += "-x64"
 
         SDK["PYTHON"] = sdkdir
-        SDK["PYTHONEXEC"] = SDK["PYTHON"].replace('\\', '/') + "/python"
+        SDK["PYTHONEXEC"] = SDK["PYTHON"] + "/python"
+
+        gil_disabled = locations.get_config_var("Py_GIL_DISABLED")
+        if gil_disabled and int(gil_disabled):
+            SDK["PYTHONEXEC"] += "%d.%dt" % sys.version_info[:2]
+            abiflags = "t"
+            DefSymbol("PYTHON", "Py_GIL_DISABLED", "1")
+        else:
+            abiflags = ""
+
         if (GetOptimize() <= 2):
             SDK["PYTHONEXEC"] += "_d.exe"
         else:
@@ -2159,11 +2168,11 @@ def SdkLocatePython(prefer_thirdparty_python=False):
 
         # Determine which version it is by checking which dll is in the directory.
         if (GetOptimize() <= 2):
-            py_dlls = glob.glob(SDK["PYTHON"] + "/python[0-9][0-9]_d.dll") + \
-                      glob.glob(SDK["PYTHON"] + "/python[0-9][0-9][0-9]_d.dll")
+            py_dlls = glob.glob(SDK["PYTHON"] + "/python[0-9][0-9]" + abiflags + "_d.dll") + \
+                      glob.glob(SDK["PYTHON"] + "/python[0-9][0-9][0-9]" + abiflags + "_d.dll")
         else:
-            py_dlls = glob.glob(SDK["PYTHON"] + "/python[0-9][0-9].dll") + \
-                      glob.glob(SDK["PYTHON"] + "/python[0-9][0-9][0-9].dll")
+            py_dlls = glob.glob(SDK["PYTHON"] + "/python[0-9][0-9]" + abiflags + ".dll") + \
+                      glob.glob(SDK["PYTHON"] + "/python[0-9][0-9][0-9]" + abiflags + ".dll")
 
         if len(py_dlls) == 0:
             exit("Could not find the Python dll in %s." % (SDK["PYTHON"]))
@@ -2174,37 +2183,62 @@ def SdkLocatePython(prefer_thirdparty_python=False):
         py_dllver = py_dll.strip(".DHLNOPTY_dhlnopty")
         ver = py_dllver[0] + '.' + py_dllver[1:]
 
-        SDK["PYTHONVERSION"] = "python" + ver
-        os.environ["PYTHONHOME"] = SDK["PYTHON"]
+        SDK["PYTHONVERSION"] = "python" + ver + abiflags
 
         running_ver = '%d.%d' % sys.version_info[:2]
         if ver != running_ver:
             Warn("running makepanda with Python %s, but building Panda3D with Python %s." % (running_ver, ver))
 
     elif CrossCompiling() or (prefer_thirdparty_python and os.path.isdir(os.path.join(GetThirdpartyDir(), "python"))):
-        tp_python = os.path.join(GetThirdpartyDir(), "python")
+        if PkgHasCustomLocation("PYTHON"):
+            incdir = FindIncDirectory("PYTHON")
+            libdirs = FindLibDirectories("PYTHON")
+        else:
+            tp_python = os.path.join(GetThirdpartyDir(), "python")
+            incdir = tp_python + "/include"
+            libdirs = [tp_python + "/lib"]
+            bindir = tp_python + "/bin"
 
         if GetTarget() == 'darwin':
-            py_libs = glob.glob(tp_python + "/lib/libpython[0-9].[0-9].dylib") + \
-                      glob.glob(tp_python + "/lib/libpython[0-9].[0-9][0-9].dylib")
+            suffix = abiflags + '.dylib'
         else:
-            py_libs = glob.glob(tp_python + "/lib/libpython[0-9].[0-9].so") + \
-                      glob.glob(tp_python + "/lib/libpython[0-9].[0-9][0-9].so")
+            suffix = abiflags + '.so'
 
-        if len(py_libs) == 0:
-            py_libs = glob.glob(tp_python + "/lib/libpython[0-9].[0-9].a") + \
-                      glob.glob(tp_python + "/lib/libpython[0-9].[0-9][0-9].a")
+        py_libs = []
+        py_static_libs = []
+        for libdir in libdirs:
+            py_libs += glob.glob(libdir + "/libpython[0-9].[0-9]" + suffix)
+            py_libs += glob.glob(libdir + "/libpython[0-9].[0-9][0-9]" + suffix)
+            py_static_libs += glob.glob(libdir + "/libpython[0-9].[0-9]" + abiflags + ".a")
+            py_static_libs += glob.glob(libdir + "/libpython[0-9].[0-9][0-9]" + abiflags + ".a")
+
+        # Prefer dynamic libs over static libs
+        py_libs += py_static_libs
 
         if len(py_libs) == 0:
-            exit("Could not find the Python library in %s." % (tp_python))
-        elif len(py_libs) > 1:
-            exit("Found multiple Python libraries in %s." % (tp_python))
+            exit("Could not find the Python library in %s." % (libdirs))
+        elif len(py_libs) == 1:
+            py_lib = os.path.basename(py_libs[0])
+            py_libver = py_lib.lstrip('.abdhilnopsty').rstrip('.abdhilnopsy')
+            bindir = os.path.dirname(os.path.dirname(py_libs[0])) + "/bin"
+        else:
+            # Does one match our version?
+            gil_disabled = locations.get_config_var("Py_GIL_DISABLED")
+            abiflags = 't' if gil_disabled and int(gil_disabled) else ''
+            our_libver = locations.get_python_version() + abiflags
+
+            for py_lib_full in py_libs:
+                py_lib = os.path.basename(py_lib_full)
+                py_libver = py_lib.lstrip('.abdhilnopsty').rstrip('.abdhilnopsy')
+                if py_libver == our_libver:
+                    bindir = os.path.dirname(os.path.dirname(py_lib_full)) + "/bin"
+                    break
+            else:
+                exit("Found multiple Python libraries in %s, none matching current version." % (libdirs))
 
-        py_lib = os.path.basename(py_libs[0])
-        py_libver = py_lib.strip('.abdhilnopsty')
         SDK["PYTHONVERSION"] = "python" + py_libver
-        SDK["PYTHONEXEC"] = tp_python + "/bin/" + SDK["PYTHONVERSION"]
-        SDK["PYTHON"] = tp_python + "/include/" + SDK["PYTHONVERSION"]
+        SDK["PYTHONEXEC"] = bindir + "/" + SDK["PYTHONVERSION"]
+        SDK["PYTHON"] = incdir + "/" + SDK["PYTHONVERSION"]
 
     elif GetTarget() == 'darwin' and not PkgHasCustomLocation("PYTHON"):
         # On macOS, search for the Python framework directory matching the
@@ -2212,11 +2246,15 @@ def SdkLocatePython(prefer_thirdparty_python=False):
         sysroot = SDK.get("MACOSX", "")
         version = locations.get_python_version()
 
-        py_fwx = "{0}/System/Library/Frameworks/Python.framework/Versions/{1}".format(sysroot, version)
+        framework_name = "Python"
+        if 't' in abiflags:
+            framework_name += "T"
+
+        py_fwx = "{0}/System/Library/Frameworks/{1}.framework/Versions/{2}".format(sysroot, framework_name, version)
 
         if not os.path.exists(py_fwx):
             # Fall back to looking on the system.
-            py_fwx = "/Library/Frameworks/Python.framework/Versions/" + version
+            py_fwx = "/Library/Frameworks/{0}.framework/Versions/{1}".format(framework_name, version)
 
         if not os.path.exists(py_fwx):
             # Newer macOS versions use this scheme.
@@ -2843,6 +2881,47 @@ def LibDirectory(opt, dir):
 def FrameworkDirectory(opt, dir):
     FRAMEWORKDIRECTORIES.append((opt, dir))
 
+def FindIncDirectory(opt):
+    # Find the include directory associated with this module
+    for mod, dir in INCDIRECTORIES:
+        if mod == opt:
+            return os.path.abspath(dir)
+
+def FindLibDirectory(opt):
+    # Find the library directory associated with this module
+    for mod, dir in LIBDIRECTORIES:
+        if mod == opt:
+            return os.path.abspath(dir)
+
+def FindLibDirectories(opt):
+    result = []
+    for mod, dir in LIBDIRECTORIES:
+        if mod == opt:
+            result.append(os.path.abspath(dir))
+    return result
+
+def FindOptDirectory(opt):
+    # Find the common directory associated with this module
+    # using the include and library directories as a guide
+    include_dir = FindIncDirectory(opt)
+    lib_dir = FindLibDirectory(opt)
+
+    if include_dir and lib_dir:
+        # The module's common directory is the common prefix of
+        # its include and library directory
+        common_dir = os.path.commonprefix([include_dir, lib_dir])
+
+        if common_dir:
+            return os.path.abspath(common_dir)
+    elif include_dir:
+        # The module's common directory is the parent of the include
+        # directory
+        return os.path.abspath(os.path.join(include_dir, os.pardir))
+    elif lib_dir:
+        # The module's common directory is the parent of the library
+        # directory
+        return os.path.abspath(os.path.join(lib_dir, os.pardir))
+
 def LibName(opt, name):
     # Check to see if the lib file actually exists for the thirdparty library given
     # Are we a thirdparty library?
@@ -3023,6 +3102,9 @@ def SetupBuildEnvironment(compiler):
 
     # If we're cross-compiling, no point in putting our output dirs on the path.
     if CrossCompiling():
+        if GetTarget() == 'emscripten' and not PkgSkip("PYTHON"):
+            AddToPathEnv("PYTHONPATH", GetOutputDir())
+            os.environ["PYTHONHOME"] = os.path.dirname(os.path.dirname(SDK["PYTHON"]))
         return
 
     # Add our output directories to the environment.
@@ -3034,6 +3116,7 @@ def SetupBuildEnvironment(compiler):
         # extension_native_helpers.py currently expects to find libpandaexpress on sys.path.
         AddToPathEnv("PYTHONPATH", os.path.join(builtdir, "bin"))
         AddToPathEnv("PATH", os.path.join(builtdir, "plugins"))
+        os.environ["PYTHONHOME"] = SDK["PYTHON"]
 
     # Now for the special (DY)LD_LIBRARY_PATH on Unix-esque systems.
     if GetHost() != 'windows':
@@ -3350,12 +3433,16 @@ def GetExtensionSuffix():
         else:
             dllext = ''
 
+        gil_disabled = locations.get_config_var("Py_GIL_DISABLED")
+        suffix = 't' if gil_disabled and int(gil_disabled) else ''
         if GetTargetArch() == 'x64':
-            return dllext + '.cp%d%d-win_amd64.pyd' % (sys.version_info[:2])
+            return dllext + '.cp%d%d%s-win_amd64.pyd' % (sys.version_info[0], sys.version_info[1], suffix)
         else:
-            return dllext + '.cp%d%d-win32.pyd' % (sys.version_info[:2])
+            return dllext + '.cp%d%d%s-win32.pyd' % (sys.version_info[0], sys.version_info[1], suffix)
     elif target == 'emscripten':
-        return '.so'
+        abi = GetPythonABI()
+        arch = GetTargetArch()
+        return '.{0}-{1}-emscripten.so'.format(abi, arch)
     elif CrossCompiling():
         return '.{0}.so'.format(GetPythonABI())
     else:
@@ -3368,7 +3455,14 @@ def GetPythonABI():
         if soabi:
             return soabi
 
-    return 'cpython-%d%d' % (sys.version_info[:2])
+    soabi = 'cpython-%d%d' % (sys.version_info[:2])
+
+    if sys.version_info >= (3, 13):
+        gil_disabled = locations.get_config_var("Py_GIL_DISABLED")
+        if gil_disabled and int(gil_disabled):
+            return soabi + 't'
+
+    return soabi
 
 def CalcLocation(fn, ipath):
     if fn.startswith("panda3d/") and fn.endswith(".py"):
@@ -3490,7 +3584,7 @@ def GetCurrentPythonVersionInfo():
         return
 
     return {
-        "version": SDK["PYTHONVERSION"][6:].rstrip('dmu'),
+        "version": SDK["PYTHONVERSION"][6:].rstrip('dmut'),
         "soabi": GetPythonABI(),
         "ext_suffix": GetExtensionSuffix(),
         "executable": sys.executable,
@@ -3645,7 +3739,7 @@ def TargetAdd(target, dummy=0, opts=[], input=[], dep=[], ipath=None, winrc=None
         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.
-        if os.path.splitext(x)[-1] not in SUFFIX_DLL:
+        if os.path.splitext(x)[-1] not in SUFFIX_DLL or (GetLinkAllStatic() and target.endswith(".exe")):
             t.deps[fullinput] = 1
             (base,suffix) = os.path.splitext(x)
             if SUFFIX_INC.count(suffix):

+ 29 - 10
makepanda/makewheel.py

@@ -19,13 +19,15 @@ from sysconfig import get_platform
 
 
 def get_abi_tag():
-    soabi = get_config_var('SOABI')
-    if soabi and soabi.startswith('cpython-'):
-        return 'cp' + soabi.split('-')[1]
-    elif soabi:
-        return soabi.replace('.', '_').replace('-', '_')
+    ver = 'cp%d%d' % sys.version_info[:2]
+    if hasattr(sys, 'abiflags'):
+        return ver + sys.abiflags
 
-    return 'cp%d%d' % (sys.version_info[:2])
+    gil_disabled = get_config_var("Py_GIL_DISABLED")
+    if gil_disabled and int(gil_disabled):
+        return ver + 't'
+
+    return ver
 
 
 def is_exe_file(path):
@@ -102,6 +104,7 @@ EXCLUDE_BINARIES = [
     'interrogate_module',
     'test_interrogate',
     'parse_file',
+    'run_tests',
 ]
 
 WHEEL_DATA = """Wheel-Version: 1.0
@@ -497,7 +500,8 @@ class WheelFile(object):
                         self.consider_add_dependency(target_dep, dep_path)
                         continue
 
-                    elif dep.startswith('/Library/Frameworks/Python.framework/'):
+                    elif dep.startswith('/Library/Frameworks/Python.framework/') or \
+                         dep.startswith('/Library/Frameworks/PythonT.framework/'):
                         # Add this dependency if it's in the Python directory.
                         target_dep = os.path.dirname(target_path) + '/' + os.path.basename(dep)
                         target_dep = self.consider_add_dependency(target_dep, dep, loader_path)
@@ -639,10 +643,20 @@ def makewheel(version, output_dir, platform=None):
     if platform is None:
         # Determine the platform from the build.
         platform_dat = os.path.join(output_dir, 'tmp', 'platform.dat')
+        cmake_cache = os.path.join(output_dir, 'CMakeCache.txt')
         if os.path.isfile(platform_dat):
+            # This is written by makepanda.
             platform = open(platform_dat, 'r').read().strip()
+        elif os.path.isfile(cmake_cache):
+            # This variable is written to the CMake cache by Package.cmake.
+            for line in open(cmake_cache, 'r').readlines():
+                if line.startswith('PYTHON_PLATFORM_TAG:STRING='):
+                    platform = line[27:].strip()
+                    break
+            if not platform:
+                raise Exception("Could not find PYTHON_PLATFORM_TAG in CMakeCache.txt, specify --platform manually.")
         else:
-            print("Could not find platform.dat in build directory")
+            print("Could not find platform.dat or CMakeCache.txt in build directory")
             platform = get_platform()
             if platform.startswith("linux-") and os.path.isdir("/opt/python"):
                 # Is this manylinux?
@@ -722,11 +736,16 @@ def makewheel(version, output_dir, platform=None):
         whl.ignore_deps.update(MANYLINUX_LIBS)
 
     # Add libpython for deployment.
+    suffix = ''
+    gil_disabled = get_config_var("Py_GIL_DISABLED")
+    if gil_disabled and int(gil_disabled):
+        suffix = 't'
+
     if is_windows:
-        pylib_name = 'python{0}{1}.dll'.format(*sys.version_info)
+        pylib_name = 'python{0}{1}{2}.dll'.format(sys.version_info[0], sys.version_info[1], suffix)
         pylib_path = os.path.join(get_config_var('BINDIR'), pylib_name)
     elif is_macosx:
-        pylib_name = 'libpython{0}.{1}.dylib'.format(*sys.version_info)
+        pylib_name = 'libpython{0}.{1}{2}.dylib'.format(sys.version_info[0], sys.version_info[1], suffix)
         pylib_path = os.path.join(get_config_var('LIBDIR'), pylib_name)
     else:
         pylib_name = get_config_var('LDLIBRARY')

+ 6 - 2
makepanda/test_wheel.py

@@ -14,7 +14,7 @@ import tempfile
 from optparse import OptionParser
 
 
-def test_wheel(wheel, verbose=False):
+def test_wheel(wheel, verbose=False, ignores=[]):
     envdir = tempfile.mkdtemp(prefix="venv-")
     print("Setting up virtual environment in {0}".format(envdir))
     sys.stdout.flush()
@@ -61,6 +61,9 @@ def test_wheel(wheel, verbose=False):
     test_cmd = [python, "-m", "pytest", "tests"]
     if verbose:
         test_cmd.append("--verbose")
+    for ignore in ignores:
+        test_cmd.append("--ignore")
+        test_cmd.append(ignore)
 
     # Put the location of the python DLL on the path, for deploy-stub test
     # This is needed because venv does not install a copy of the python DLL
@@ -87,6 +90,7 @@ def test_wheel(wheel, verbose=False):
 if __name__ == "__main__":
     parser = OptionParser(usage="%prog [options] file...")
     parser.add_option('', '--verbose', dest = 'verbose', help = 'Enable verbose output', action = 'store_true', default = False)
+    parser.add_option('', '--ignore', dest = 'ignores', help = 'Ignores given test directory (may be repeated)', action = 'append', default = [])
     (options, args) = parser.parse_args()
 
     if not args:
@@ -94,4 +98,4 @@ if __name__ == "__main__":
         sys.exit(1)
 
     for arg in args:
-        test_wheel(arg, verbose=options.verbose)
+        test_wheel(arg, verbose=options.verbose, ignores=options.ignores)

+ 7 - 0
panda/src/audio/config_audio.cxx

@@ -75,6 +75,13 @@ ConfigVariableInt audio_preload_threshold
           "practical to stream multiple sound-files from disk at the same "
           "time - the hard drive seek time makes it stutter."));
 
+ConfigVariableBool audio_want_hrtf
+("audio-want-hrtf", true,
+ PRC_DESC("This determines whether OpenAL-Soft should activate HRTF in "
+          "certain hardware configurations. Set it to true to cause "
+          "OpenAL to automatically apply HRTF processing to all output "
+          "audio when headphones are used for playback."));
+
 // Unknown
 
 ConfigVariableInt audio_min_hw_channels

+ 1 - 0
panda/src/audio/config_audio.h

@@ -67,6 +67,7 @@ extern EXPCL_PANDA_AUDIO ConfigVariableDouble audio_distance_factor;
 extern EXPCL_PANDA_AUDIO ConfigVariableDouble audio_drop_off_factor;
 extern EXPCL_PANDA_AUDIO ConfigVariableDouble audio_buffering_seconds;
 extern EXPCL_PANDA_AUDIO ConfigVariableInt    audio_preload_threshold;
+extern EXPCL_PANDA_AUDIO ConfigVariableBool   audio_want_hrtf;
 
 #ifdef NOTIFY_DEBUG //[
   // Non-release build:

+ 16 - 1
panda/src/audiotraits/openalAudioManager.cxx

@@ -155,7 +155,22 @@ OpenALAudioManager() {
     if (_device != nullptr) {
       // We managed to get a device open.
       alcGetError(_device); // clear errors
-      _context = alcCreateContext(_device, nullptr);
+
+      ALCboolean is_hrtf_present = alcIsExtensionPresent(_device, "ALC_SOFT_HRTF");
+
+      ALCint attrs[3] = {0};
+
+#ifndef HAVE_OPENAL_FRAMEWORK
+      if (is_hrtf_present) {
+        attrs[0] = ALC_HRTF_SOFT;
+        attrs[1] = audio_want_hrtf.get_value() ? ALC_TRUE : ALC_FALSE;
+        attrs[2] = 0; // end of list
+      } else {
+        attrs[0] = 0; // end of list
+      }
+#endif // HAVE_OPENAL_FRAMEWORK
+
+      _context = alcCreateContext(_device, attrs);
       alc_audio_errcheck("alcCreateContext(_device, NULL)", _device);
       if (_context != nullptr) {
         _openal_active = true;

+ 1 - 0
panda/src/audiotraits/openalAudioManager.h

@@ -29,6 +29,7 @@
 #else
   #include <AL/al.h>
   #include <AL/alc.h>
+  #include <AL/alext.h>
 #endif
 
 class OpenALAudioSound;

+ 1 - 0
panda/src/audiotraits/openalAudioSound.h

@@ -27,6 +27,7 @@
 #else
   #include <AL/al.h>
   #include <AL/alc.h>
+  #include <AL/alext.h>
 #endif
 
 class EXPCL_OPENAL_AUDIO OpenALAudioSound final : public AudioSound {

+ 2 - 10
panda/src/bullet/bulletDebugNode.cxx

@@ -248,16 +248,8 @@ add_for_draw(CullTraverser *trav, CullTraverserData &data) {
 
   // Record them without any state or transform.
   trav->_geoms_pcollector.add_level(2);
-  {
-    CullableObject *object =
-      new CullableObject(std::move(debug_lines), RenderState::make_empty(), trav->get_scene()->get_cs_world_transform());
-    trav->get_cull_handler()->record_object(object, trav);
-  }
-  {
-    CullableObject *object =
-      new CullableObject(std::move(debug_triangles), RenderState::make_empty(), trav->get_scene()->get_cs_world_transform());
-    trav->get_cull_handler()->record_object(object, trav);
-  }
+  trav->get_cull_handler()->record_object(CullableObject(std::move(debug_lines), RenderState::make_empty(), trav->get_scene()->get_cs_world_transform()), trav);
+  trav->get_cull_handler()->record_object(CullableObject(std::move(debug_triangles), RenderState::make_empty(), trav->get_scene()->get_cs_world_transform()), trav);
 }
 
 /**

+ 10 - 104
panda/src/collide/collisionBox.I

@@ -21,11 +21,9 @@ CollisionBox(const LPoint3 &center, PN_stdfloat x, PN_stdfloat y, PN_stdfloat z)
 {
   _min = LPoint3(_center.get_x() - x, _center.get_y() - y, _center.get_z() - z);
   _max = LPoint3(_center.get_x() + x, _center.get_y() + y, _center.get_z() + z);
-  for(int v = 0; v < 8; v++)
-    _vertex[v] = get_point_aabb(v);
-  for(int p = 0; p < 6; p++)
+  for (int p = 0; p < 6; ++p) {
     _planes[p] = set_plane(p);
-  setup_box();
+  }
 }
 
 /**
@@ -33,14 +31,11 @@ CollisionBox(const LPoint3 &center, PN_stdfloat x, PN_stdfloat y, PN_stdfloat z)
  */
 INLINE CollisionBox::
 CollisionBox(const LPoint3 &min, const LPoint3 &max) :
-  _min(min), _max(max)
+  _center((min + max) / 2), _min(min), _max(max)
 {
-  _center = (_min + _max) / 2;
-  for(int v = 0; v < 8; v++)
-    _vertex[v] = get_point_aabb(v);
-  for(int p = 0; p < 6; p++)
+  for (int p = 0; p < 6; ++p) {
     _planes[p] = set_plane(p);
-  setup_box();
+  }
 }
 
 /**
@@ -60,11 +55,9 @@ CollisionBox(const CollisionBox &copy) :
   _min(copy._min),
   _max(copy._max)
 {
-  for(int v = 0; v < 8; v++)
-    _vertex[v] = copy._vertex[v];
-  for(int p = 0; p < 6; p++)
+  for (int p = 0; p < 6; ++p) {
     _planes[p] = copy._planes[p];
-  setup_box();
+  }
 }
 
 /**
@@ -139,8 +132,7 @@ get_num_points() const {
  */
 INLINE LPoint3 CollisionBox::
 get_point(int n) const {
-  nassertr(n >= 0 && n < 8, LPoint3::zero());
-  return _vertex[n];
+  return get_point_aabb(n);
 }
 
 /**
@@ -175,6 +167,8 @@ get_plane(int n) const {
 
 /**
  * Creates the nth face of the rectangular solid.
+ *
+ * @deprecated Same as get_plane().
  */
 INLINE LPlane CollisionBox::
 set_plane(int n) const {
@@ -183,91 +177,3 @@ set_plane(int n) const {
                 get_point(plane_def[n][1]),
                 get_point(plane_def[n][2]));
 }
-
-
-/**
- * Returns true if the 2-d v1 is to the right of v2.
- */
-INLINE bool CollisionBox::
-is_right(const LVector2 &v1, const LVector2 &v2) {
-  return (v1[0] * v2[1] - v1[1] * v2[0]) > 1.0e-6f;
-}
-
-/**
- * Returns the linear distance of p to the line defined by f and f+v, where v
- * is a normalized vector.  The result is negative if p is left of the line,
- * positive if it is right of the line.
- */
-INLINE PN_stdfloat CollisionBox::
-dist_to_line(const LPoint2 &p,
-             const LPoint2 &f, const LVector2 &v) {
-  LVector2 v1 = (p - f);
-  return (v1[0] * v[1] - v1[1] * v[0]);
-}
-
-/**
- * Assuming the indicated point in 3-d space lies within the polygon's plane,
- * returns the corresponding point in the polygon's 2-d definition space.
- */
-INLINE LPoint2 CollisionBox::
-to_2d(const LVecBase3 &point3d, int plane) const {
-  LPoint3 point = LPoint3(point3d) * _to_2d_mat[plane];
-  return LPoint2(point[0], point[2]);
-}
-
-/**
- * Fills the indicated matrix with the appropriate rotation transform to move
- * points from the 2-d plane into the 3-d (X, 0, Z) plane.
- */
-INLINE void CollisionBox::
-calc_to_3d_mat(LMatrix4 &to_3d_mat,int plane) const {
-  // We have to be explicit about the coordinate system--we specifically mean
-  // CS_zup_right, because that points the forward vector down the Y axis and
-  // moves the coords in (X, 0, Z).  We want this effect regardless of the
-  // user's coordinate system of choice.
-
-  // The up vector, on the other hand, is completely arbitrary.
-
-  look_at(to_3d_mat, -get_plane(plane).get_normal(),
-          LVector3(0.0f, 0.0f, 1.0f), CS_zup_right);
-  to_3d_mat.set_row(3, get_plane(plane).get_point());
-}
-
-/**
- * Extrude the indicated point in the polygon's 2-d definition space back into
- * 3-d coordinates.
- */
-INLINE LPoint3 CollisionBox::
-to_3d(const LVecBase2 &point2d, const LMatrix4 &to_3d_mat) {
-  return LPoint3(point2d[0], 0.0f, point2d[1]) * to_3d_mat;
-}
-
-/**
- *
- */
-INLINE CollisionBox::PointDef::
-PointDef(const LPoint2 &p, const LVector2 &v) : _p(p), _v(v) {
-}
-
-/**
- *
- */
-INLINE CollisionBox::PointDef::
-PointDef(PN_stdfloat x, PN_stdfloat y) : _p(x, y), _v(0.0f, 0.0f) {
-}
-
-/**
- *
- */
-INLINE CollisionBox::PointDef::
-PointDef(const CollisionBox::PointDef &copy) : _p(copy._p), _v(copy._v) {
-}
-
-/**
- *
- */
-INLINE void CollisionBox::PointDef::
-operator = (const CollisionBox::PointDef &copy) {
-  _p = copy._p;
-  _v = copy._v;
-}

+ 236 - 536
panda/src/collide/collisionBox.cxx

@@ -55,50 +55,107 @@ const int CollisionBox::plane_def[6][4] = {
 };
 
 /**
- *
+ * Helper function to calculate the intersection between a line segment and a
+ * sphere.  t is filled with the first position along the line segment where
+ * the intersection hits.
  */
-CollisionSolid *CollisionBox::
-make_copy() {
-  return new CollisionBox(*this);
+static bool
+intersect_segment_sphere(double &t,
+                         const LPoint3 &from, const LVector3 &delta,
+                         const LPoint3 &center, double radius_sq) {
+  double A2 = dot(delta, delta) * 2;
+
+  LVector3 fc = from - center;
+  double fc_d2 = dot(fc, fc);
+  double C = fc_d2 - radius_sq;
+
+  if (UNLIKELY(A2 == 0.0)) {
+    // Degenerate case where delta is zero.  This is effectively a test
+    // against a point (or sphere, for nonzero inflate_radius).
+    t = 0.0;
+    return C < 0.0;
+  }
+
+  double B = 2.0f * dot(delta, fc);
+  double radical = B*B - 2.0*A2*C;
+
+  if (radical < 0.0) {
+    // No real roots: no intersection with the line.
+    return false;
+  }
+
+  t = (-B - csqrt(radical)) / A2;
+  return true;
 }
 
 /**
- * Compute parameters for each of the box's sides
+ * Helper function to calculate the intersection between a line segment and a
+ * capsule.  t is filled with the first position along the line segment where
+ * the intersection hits.
+ *
+ * Code derived from a book by Christer Ericson.
  */
-void CollisionBox::
-setup_box() {
-  assert(sizeof(_points) / sizeof(_points[0]) == 6);
-  assert(sizeof(_points[0]) / sizeof(_points[0][0]) == 4);
-  for (int plane = 0; plane < 6; plane++) {
-    setup_points(plane);
+static bool
+intersect_segment_capsule(double &t,
+                          const LPoint3 &from_a, const LVector3 &delta_a,
+                          const LPoint3 &from_b, const LPoint3 &to_b,
+                          double radius_sq) {
+  LVector3 m = from_a - from_b;
+  LVector3 delta_b = to_b - from_b;
+  PN_stdfloat md = m.dot(delta_b);
+  PN_stdfloat nd = delta_a.dot(delta_b);
+  PN_stdfloat dd = delta_b.dot(delta_b);
+  if (md < 0 && md + nd < 0) {
+    return intersect_segment_sphere(t, from_a, delta_a, from_b, radius_sq);
+  }
+  if (md > dd && md + nd > dd) {
+    return intersect_segment_sphere(t, from_a, delta_a, to_b, radius_sq);
+  }
+  PN_stdfloat nn = delta_a.dot(delta_a);
+  PN_stdfloat mn = m.dot(delta_a);
+  PN_stdfloat a = dd * nn - nd * nd;
+  PN_stdfloat k = m.dot(m) - radius_sq;
+  PN_stdfloat c = dd * k - md * md;
+  if (IS_NEARLY_ZERO(a)) {
+    // Segments run parallel
+    if (c > 0.0f) {
+      return false;
+    }
+    if (md < 0.0f) {
+      return intersect_segment_sphere(t, from_a, delta_a, from_b, radius_sq);
+    }
+    else if (md > dd) {
+      return intersect_segment_sphere(t, from_a, delta_a, to_b, radius_sq);
+    }
+    else {
+      t = 0.0;
+    }
+    return true;
+  }
+  PN_stdfloat b = dd * mn - nd * md;
+  PN_stdfloat discr = b * b - a * c;
+  if (discr < 0.0f) {
+    return false;
+  }
+  t = (-b - csqrt(discr)) / a;
+  if (t < 0.0 || t > 1.0) {
+    return false;
+  }
+  if (md + t * nd < 0) {
+    return intersect_segment_sphere(t, from_a, delta_a, from_b, radius_sq);
+  }
+  else if (md + t * nd > dd) {
+    return intersect_segment_sphere(t, from_a, delta_a, to_b, radius_sq);
   }
+  return true;
 }
 
 /**
- * Computes the plane and 2d projection of points that make up this side.
+ *
  */
-void CollisionBox::
-setup_points(int plane) {
-  PointDef *points = _points[plane];
-
-  // Construct a matrix that rotates the points from the (X,0,Z) plane into
-  // the 3-d plane.
-  LMatrix4 to_3d_mat;
-  calc_to_3d_mat(to_3d_mat, plane);
-
-  // And the inverse matrix rotates points from 3-d space into the 2-d plane.
-  _to_2d_mat[plane].invert_from(to_3d_mat);
-
-  // Now project all of the points onto the 2-d plane.
-  for (size_t i = 0; i < 4; ++i) {
-    LPoint3 point = get_point(plane_def[plane][i]) * _to_2d_mat[plane];
-    points[i] = PointDef(point[0], point[2]);
-  }
-
-  for (size_t i = 0; i < 4; i++) {
-    points[i]._v = points[(i + 1) % 4]._p - points[i]._p;
-    points[i]._v.normalize();
-  }
+CollisionSolid *CollisionBox::
+make_copy() {
+  return new CollisionBox(*this);
 }
 
 /**
@@ -117,13 +174,9 @@ xform(const LMatrix4 &mat) {
   _min = _min * mat;
   _max = _max * mat;
   _center = _center * mat;
-  for(int v = 0; v < 8; v++) {
-    _vertex[v] = _vertex[v] * mat;
-  }
   for(int p = 0; p < 6 ; p++) {
     _planes[p] = set_plane(p);
   }
-  setup_box();
   mark_viz_stale();
   mark_internal_bounds_stale();
 }
@@ -169,9 +222,10 @@ output(std::ostream &out) const {
  */
 PT(BoundingVolume) CollisionBox::
 compute_internal_bounds() const {
-  PN_stdfloat x = _vertex[0].get_x() - _center.get_x();
-  PN_stdfloat y = _vertex[0].get_y() - _center.get_y();
-  PN_stdfloat z = _vertex[0].get_z() - _center.get_z();
+  LPoint3 vertex = get_point_aabb(0);
+  PN_stdfloat x = vertex.get_x() - _center.get_x();
+  PN_stdfloat y = vertex.get_y() - _center.get_y();
+  PN_stdfloat z = vertex.get_z() - _center.get_z();
   PN_stdfloat radius = sqrt(x * x + y * y + z * z);
   return new BoundingSphere(_center, radius);
 }
@@ -190,168 +244,45 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
 
   const LMatrix4 &wrt_mat = wrt_space->get_mat();
 
-  LPoint3 orig_center = sphere->get_center() * wrt_mat;
-  LPoint3 from_center = orig_center;
-  bool moved_from_center = false;
-  PN_stdfloat t = 1.0f;
-  LPoint3 contact_point(from_center);
-  PN_stdfloat actual_t = 1.0f;
-
-  LVector3 from_radius_v =
-    LVector3(sphere->get_radius(), 0.0f, 0.0f) * wrt_mat;
-  PN_stdfloat from_radius_2 = from_radius_v.length_squared();
-  PN_stdfloat from_radius = csqrt(from_radius_2);
-
-  int ip;
-  PN_stdfloat max_dist = 0.0;
-  PN_stdfloat dist = 0.0;
-  bool intersect;
-  LPlane plane;
-  LVector3 normal;
-  bool fully_inside = true;
-
-  for(ip = 0, intersect = false; ip < 6 && !intersect; ip++) {
-    plane = get_plane(ip);
-
-    if (wrt_prev_space != wrt_space) {
-      // If we have a delta between the previous position and the current
-      // position, we use that to determine some more properties of the
-      // collision.
-      LPoint3 b = from_center;
-      LPoint3 a = sphere->get_center() * wrt_prev_space->get_mat();
-      LVector3 delta = b - a;
-
-      // First, there is no collision if the "from" object is definitely
-      // moving in the same direction as the plane's normal.
-      PN_stdfloat dot = delta.dot(plane.get_normal());
-      if (dot > 0.1f) {
-        fully_inside = false;
-        continue; // no intersection
-      }
+  LPoint3 center = wrt_mat.xform_point(sphere->get_center());
+  PN_stdfloat radius_sq = wrt_mat.xform_vec(LVector3(0, 0, sphere->get_radius())).length_squared();
 
-      if (IS_NEARLY_ZERO(dot)) {
-        // If we're moving parallel to the plane, the sphere is tested at its
-        // final point.  Leave it as it is.
-
-      } else {
-/*
- * Otherwise, we're moving into the plane; the sphere is tested at the point
- * along its path that is closest to intersecting the plane.  This may be the
- * actual intersection point, or it may be the starting point or the final
- * point.  dot is equal to the (negative) magnitude of 'delta' along the
- * direction of the plane normal t = ratio of (distance from start pos to
- * plane) to (distance from start pos to end pos), along axis of plane normal
- */
-        PN_stdfloat dist_to_p = plane.dist_to_plane(a);
-        t = (dist_to_p / -dot);
-
-        // also compute the actual contact point and time of contact for
-        // handlers that need it
-        actual_t = ((dist_to_p - from_radius) / -dot);
-        actual_t = min((PN_stdfloat)1.0, max((PN_stdfloat)0.0, actual_t));
-        contact_point = a + (actual_t * delta);
-
-        if (t >= 1.0f) {
-          // Leave it where it is.
-
-        } else if (t < 0.0f) {
-          from_center = a;
-          moved_from_center = true;
-        } else {
-          from_center = a + t * delta;
-          moved_from_center = true;
-        }
-      }
-    }
+  bool had_prev = false;
+  LPoint3 prev_center = center;
+  double t = 0;
 
-    normal = (has_effective_normal() && sphere->get_respect_effective_normal()) ? get_effective_normal() : plane.get_normal();
-
-#ifndef NDEBUG
-    /*if (!IS_THRESHOLD_EQUAL(normal.length_squared(), 1.0f, 0.001), NULL) {
-      std::cout
-      << "polygon within " << entry.get_into_node_path()
-      << " has normal " << normal << " of length " << normal.length()
-      << "\n";
-      normal.normalize();
-      }*/
-#endif
-
-    // The nearest point within the plane to our center is the intersection of
-    // the line (center, center - normal) with the plane.
-
-    if (!plane.intersects_line(dist, from_center, -(plane.get_normal()))) {
-      // No intersection with plane?  This means the plane's effective normal
-      // was within the plane itself.  A useless polygon.
-      fully_inside = false;
-      continue;
-    }
+  if (wrt_space != wrt_prev_space) {
+    prev_center = wrt_prev_space->get_mat().xform_point(sphere->get_center());
+  }
+  LPoint3 contact_center = prev_center;
 
-    if (dist > from_radius) {
-      // Fully outside this plane, there can not be an intersection.
+  // First, just test the starting point of the sphere.
+  LVector3 vec = (prev_center - _min).fmin(0) + (prev_center - _max).fmax(0);
+  PN_stdfloat vec_lsq = vec.length_squared();
+  if (vec_lsq > radius_sq) {
+    if (wrt_space == wrt_prev_space) {
       return nullptr;
     }
-    if (dist < -from_radius) {
-      // Fully inside this plane.
-      continue;
-    }
-    fully_inside = false;
-
-    LPoint2 p = to_2d(from_center - dist * plane.get_normal(), ip);
-    PN_stdfloat edge_dist = 0.0f;
-
-    const ClipPlaneAttrib *cpa = entry.get_into_clip_planes();
-    if (cpa != nullptr) {
-      // We have a clip plane; apply it.
-      Points new_points;
-      if (apply_clip_plane(new_points, cpa, entry.get_into_node_path().get_net_transform(),ip)) {
-        // All points are behind the clip plane; just do the default test.
-        edge_dist = dist_to_polygon(p, _points[ip], 4);
-      } else if (new_points.empty()) {
-        // The polygon is completely clipped.
-        continue;
-      } else {
-        // Test against the clipped polygon.
-        edge_dist = dist_to_polygon(p, new_points.data(), new_points.size());
-      }
-    } else {
-      // No clip plane is in effect.  Do the default test.
-      edge_dist = dist_to_polygon(p, _points[ip], 4);
-    }
-
-    max_dist = from_radius;
 
-    // Now we have edge_dist, which is the distance from the sphere center to
-    // the nearest edge of the polygon, within the polygon's plane.
-    // edge_dist<0 means the point is within the polygon.
-    if(edge_dist < 0) {
-      intersect = true;
-      continue;
-    }
-
-    if((edge_dist > 0) &&
-       ((edge_dist * edge_dist + dist * dist) > from_radius_2)) {
-      // No intersection; the circle is outside the polygon.
-      continue;
+    // We must effectively do a capsule-into-box test.
+    LVector3 delta = center - prev_center;
+    if (!intersects_capsule(t, prev_center, delta, radius_sq)) {
+      return nullptr;
     }
+    contact_center = prev_center + delta * t;
 
-    // The sphere appears to intersect the polygon.  If the edge is less than
-    // from_radius away, the sphere may be resting on an edge of the polygon.
-    // Determine how far the center of the sphere must remain from the plane,
-    // based on its distance from the nearest edge.
-
-    if (edge_dist >= 0.0f) {
-      PN_stdfloat max_dist_2 = max(from_radius_2 - edge_dist * edge_dist, (PN_stdfloat)0.0);
-      max_dist = csqrt(max_dist_2);
-    }
+    // This is used to calculate the surface normal, which must always be
+    // opposed to the movement direction!
+    vec = (contact_center - _min).fmin(0) + (contact_center - _max).fmax(0);
+    if ((vec[0] > 0) == (delta[0] > 0)) vec[0] = 0;
+    if ((vec[1] > 0) == (delta[1] > 0)) vec[1] = 0;
+    if ((vec[2] > 0) == (delta[2] > 0)) vec[2] = 0;
 
-    if (dist > max_dist) {
-      // There's no intersection: the sphere is hanging off the edge.
-      continue;
-    }
-    intersect = true;
+    had_prev = true;
   }
-  if (!fully_inside && !intersect) {
-    return nullptr;
+  else if (vec_lsq == 0.0f) {
+    // It's completely inside.
+    vec = prev_center - _center;
   }
 
   if (collide_cat.is_debug()) {
@@ -362,26 +293,44 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
 
   PT(CollisionEntry) new_entry = new CollisionEntry(entry);
 
-  PN_stdfloat into_depth = max_dist - dist;
-  if (moved_from_center) {
-    // We have to base the depth of intersection on the sphere's final resting
-    // point, not the point from which we tested the intersection.
-    PN_stdfloat orig_dist;
-    plane.intersects_line(orig_dist, orig_center, -normal);
-    into_depth = max_dist - orig_dist;
+  int axis;
+  if (abs(vec[0]) > abs(vec[1])) {
+    if (abs(vec[0]) > abs(vec[2])) {
+      axis = 0;
+    } else {
+      axis = 2;
+    }
+  } else {
+    if (abs(vec[1]) > abs(vec[2])) {
+      axis = 1;
+    } else {
+      axis = 2;
+    }
   }
 
-  // Clamp the surface point to the box bounds.
-  LPoint3 surface = from_center - normal * dist;
-  surface = surface.fmax(_min);
-  surface = surface.fmin(_max);
+  LPoint3 surface_point = contact_center.fmax(_min).fmin(_max);
+  surface_point[axis] = vec[axis] > 0 ? _max[axis] : _min[axis];
+
+  LVector3 normal(0, 0, 0);
+  normal[axis] = (vec[axis] > 0) * 2 - 1;
 
-  new_entry->set_surface_normal(normal);
-  new_entry->set_surface_point(surface);
-  new_entry->set_interior_point(surface - normal * into_depth);
-  new_entry->set_contact_pos(contact_point);
-  new_entry->set_contact_normal(plane.get_normal());
-  new_entry->set_t(actual_t);
+  LPoint3 interior_point = surface_point;
+  if (had_prev) {
+    interior_point += (center - contact_center);
+  } else {
+    LVector3 other = surface_point - contact_center;
+    other[axis] = 0.0f;
+    interior_point[axis] = center[axis] - std::copysign(std::max((PN_stdfloat)0, csqrt(radius_sq - other.length_squared())), vec[axis]);
+  }
+
+  new_entry->set_interior_point(interior_point);
+  new_entry->set_surface_point(surface_point);
+  new_entry->set_surface_normal(
+    (has_effective_normal() && sphere->get_respect_effective_normal())
+    ? get_effective_normal() : normal);
+  new_entry->set_contact_pos(contact_center);
+  new_entry->set_contact_normal(normal);
+  new_entry->set_t(t);
 
   return new_entry;
 }
@@ -1088,327 +1037,61 @@ intersects_line(double &t1, double &t2,
 }
 
 /**
- * Clips the polygon by all of the clip planes named in the clip plane
- * attribute and fills new_points up with the resulting points.
- *
- * The return value is true if the set of points is unmodified (all points are
- * behind all the clip planes), or false otherwise.
+ * Determine the first point of intersection of the given capsule with the box.
  */
 bool CollisionBox::
-apply_clip_plane(CollisionBox::Points &new_points,
-                 const ClipPlaneAttrib *cpa,
-                 const TransformState *net_transform, int plane_no) const {
-  bool all_in = true;
-
-  int num_planes = cpa->get_num_on_planes();
-  bool first_plane = true;
-
-  for (int i = 0; i < num_planes; i++) {
-    NodePath plane_path = cpa->get_on_plane(i);
-    PlaneNode *plane_node = DCAST(PlaneNode, plane_path.node());
-    if ((plane_node->get_clip_effect() & PlaneNode::CE_collision) != 0) {
-      CPT(TransformState) new_transform =
-        net_transform->invert_compose(plane_path.get_net_transform());
-
-      LPlane plane = plane_node->get_plane() * new_transform->get_mat();
-      if (first_plane) {
-        first_plane = false;
-        if (!clip_polygon(new_points, _points[plane_no], 4, plane, plane_no)) {
-          all_in = false;
-        }
-      } else {
-        Points last_points;
-        last_points.swap(new_points);
-        if (!clip_polygon(new_points, last_points.data(), last_points.size(), plane, plane_no)) {
-          all_in = false;
-        }
-      }
-    }
-  }
-
-  if (!all_in) {
-    compute_vectors(new_points);
-  }
-
-  return all_in;
-}
-/**
- * Clips the source_points of the polygon by the indicated clipping plane, and
- * modifies new_points to reflect the new set of clipped points (but does not
- * compute the vectors in new_points).
- *
- * The return value is true if the set of points is unmodified (all points are
- * behind the clip plane), or false otherwise.
- */
-bool CollisionBox::
-clip_polygon(CollisionBox::Points &new_points,
-             const PointDef *source_points, size_t num_source_points,
-             const LPlane &plane, int plane_no) const {
-  new_points.clear();
-  if (num_source_points == 0) {
-    return true;
-  }
-
-  LPoint3 from3d;
-  LVector3 delta3d;
-  if (!plane.intersects_plane(from3d, delta3d, get_plane(plane_no))) {
-    // The clipping plane is parallel to the polygon.  The polygon is either
-    // all in or all out.
-    if (plane.dist_to_plane(get_plane(plane_no).get_point()) < 0.0) {
-      // A point within the polygon is behind the clipping plane: the polygon
-      // is all in.
-      new_points.insert(new_points.end(), source_points, source_points + num_source_points);
-      return true;
-    }
+intersects_capsule(double &t, const LPoint3 &from, const LVector3 &delta,
+                   PN_stdfloat radius_sq) const {
+  // First, we check whether the line segment intersects with the box
+  // expanded by the sphere's radius.
+  double t2;
+  if (!intersects_line(t, t2, from, delta, csqrt(radius_sq)) ||
+      t > 1.0 || t2 < 0.0) {
     return false;
   }
 
-  // Project the line of intersection into the 2-d plane.  Now we have a 2-d
-  // clipping line.
-  LPoint2 from2d = to_2d(from3d,plane_no);
-  LVector2 delta2d = to_2d(delta3d,plane_no);
-
-  PN_stdfloat a = -delta2d[1];
-  PN_stdfloat b = delta2d[0];
-  PN_stdfloat c = from2d[0] * delta2d[1] - from2d[1] * delta2d[0];
-
-  // Now walk through the points.  Any point on the left of our line gets
-  // removed, and the line segment clipped at the point of intersection.
-
-  // We might increase the number of vertices by as many as 1, if the plane
-  // clips off exactly one corner.  (We might also decrease the number of
-  // vertices, or keep them the same number.)
-  new_points.reserve(num_source_points + 1);
-
-  LPoint2 last_point = source_points[num_source_points - 1]._p;
-  bool last_is_in = !is_right(last_point - from2d, delta2d);
-  bool all_in = last_is_in;
-  for (size_t pi = 0; pi < num_source_points; ++pi) {
-    const LPoint2 &this_point = source_points[pi]._p;
-    bool this_is_in = !is_right(this_point - from2d, delta2d);
-
-    // There appears to be a compiler bug in gcc 4.0: we need to extract this
-    // comparison outside of the if statement.
-    bool crossed_over = (this_is_in != last_is_in);
-    if (crossed_over) {
-      // We have just crossed over the clipping line.  Find the point of
-      // intersection.
-      LVector2 d = this_point - last_point;
-      PN_stdfloat denom = (a * d[0] + b * d[1]);
-      if (denom != 0.0) {
-        PN_stdfloat t = -(a * last_point[0] + b * last_point[1] + c) / denom;
-        LPoint2 p = last_point + t * d;
-
-        new_points.push_back(PointDef(p[0], p[1]));
-        last_is_in = this_is_in;
-      }
+  LPoint3 intersection = from + delta * t;
+
+  // The following technique is derived from a book by Christer Ericson.
+  int u = 0, v = 0;
+  if (intersection[0] < _min[0]) u |= 4;
+  if (intersection[1] < _min[1]) u |= 2;
+  if (intersection[2] < _min[2]) u |= 1;
+  if (intersection[0] > _max[0]) v |= 4;
+  if (intersection[1] > _max[1]) v |= 2;
+  if (intersection[2] > _max[2]) v |= 1;
+
+  int m = u | v;
+  if (m == 7) {
+    double tmin = DBL_MAX;
+    LPoint3 vertex = get_point_aabb(v);
+    if (intersect_segment_capsule(t, from, delta, vertex,
+                                  get_point_aabb(v ^ 4), radius_sq)) {
+      tmin = std::min(t, tmin);
     }
-
-    if (this_is_in) {
-      // We are behind the clipping line.  Keep the point.
-      new_points.push_back(PointDef(this_point[0], this_point[1]));
-    } else {
-      all_in = false;
+    if (intersect_segment_capsule(t, from, delta, vertex,
+                                  get_point_aabb(v ^ 2), radius_sq)) {
+      tmin = std::min(t, tmin);
     }
-
-    last_point = this_point;
-  }
-
-  return all_in;
-}
-
-/**
- * Returns the linear distance from the 2-d point to the nearest part of the
- * polygon defined by the points vector.  The result is negative if the point
- * is within the polygon.
- */
-PN_stdfloat CollisionBox::
-dist_to_polygon(const LPoint2 &p, const PointDef *points, size_t num_points) const {
-  // We know that that the polygon is convex and is defined with the points in
-  // counterclockwise order.  Therefore, we simply compare the signed distance
-  // to each line segment; we ignore any negative values, and take the minimum
-  // of all the positive values.
-
-  // If all values are negative, the point is within the polygon; we therefore
-  // return an arbitrary negative result.
-
-  bool got_dist = false;
-  PN_stdfloat best_dist = -1.0f;
-
-  for (size_t i = 0; i < num_points - 1; ++i) {
-    PN_stdfloat d = dist_to_line_segment(p, points[i]._p, points[i + 1]._p,
-                                         points[i]._v);
-    if (d >= 0.0f) {
-      if (!got_dist || d < best_dist) {
-        best_dist = d;
-        got_dist = true;
-      }
+    if (intersect_segment_capsule(t, from, delta, vertex,
+                                  get_point_aabb(v ^ 1), radius_sq)) {
+      tmin = std::min(t, tmin);
     }
-  }
-
-  PN_stdfloat d = dist_to_line_segment(p, points[num_points - 1]._p, points[0]._p,
-                                       points[num_points - 1]._v);
-  if (d >= 0.0f) {
-    if (!got_dist || d < best_dist) {
-      best_dist = d;
-      //got_dist = true;
-    }
-  }
-
-  return best_dist;
-}
-
-/**
- * Returns the linear distance of p to the line segment defined by f and t,
- * where v = (t - f).normalize(). The result is negative if p is left of the
- * line, positive if it is right of the line.  If the result is positive, it
- * is constrained by endpoints of the line segment (i.e.  the result might be
- * larger than it would be for a straight distance-to-line test).  If the
- * result is negative, we don't bother.
- */
-PN_stdfloat CollisionBox::
-dist_to_line_segment(const LPoint2 &p,
-                     const LPoint2 &f, const LPoint2 &t,
-                     const LVector2 &v) {
-  LVector2 v1 = (p - f);
-  PN_stdfloat d = (v1[0] * v[1] - v1[1] * v[0]);
-  if (d < 0.0f) {
-    return d;
-  }
-
-  // Compute the nearest point on the line.
-  LPoint2 q = p + LVector2(-v[1], v[0]) * d;
-
-  // Now constrain that point to the line segment.
-  if (v[0] > 0.0f) {
-    // X+
-    if (v[1] > 0.0f) {
-      // Y+
-      if (v[0] > v[1]) {
-        // X-dominant.
-        if (q[0] < f[0]) {
-          return (p - f).length();
-        } if (q[0] > t[0]) {
-          return (p - t).length();
-        } else {
-          return d;
-        }
-      } else {
-        // Y-dominant.
-        if (q[1] < f[1]) {
-          return (p - f).length();
-        } if (q[1] > t[1]) {
-          return (p - t).length();
-        } else {
-          return d;
-        }
-      }
-    } else {
-      // Y-
-      if (v[0] > -v[1]) {
-        // X-dominant.
-        if (q[0] < f[0]) {
-          return (p - f).length();
-        } if (q[0] > t[0]) {
-          return (p - t).length();
-        } else {
-          return d;
-        }
-      } else {
-        // Y-dominant.
-        if (q[1] > f[1]) {
-          return (p - f).length();
-        } if (q[1] < t[1]) {
-          return (p - t).length();
-        } else {
-          return d;
-        }
-      }
-    }
-  } else {
-    // X-
-    if (v[1] > 0.0f) {
-      // Y+
-      if (-v[0] > v[1]) {
-        // X-dominant.
-        if (q[0] > f[0]) {
-          return (p - f).length();
-        } if (q[0] < t[0]) {
-          return (p - t).length();
-        } else {
-          return d;
-        }
-      } else {
-        // Y-dominant.
-        if (q[1] < f[1]) {
-          return (p - f).length();
-        } if (q[1] > t[1]) {
-          return (p - t).length();
-        } else {
-          return d;
-        }
-      }
-    } else {
-      // Y-
-      if (-v[0] > -v[1]) {
-        // X-dominant.
-        if (q[0] > f[0]) {
-          return (p - f).length();
-        } if (q[0] < t[0]) {
-          return (p - t).length();
-        } else {
-          return d;
-        }
-      } else {
-        // Y-dominant.
-        if (q[1] > f[1]) {
-          return (p - f).length();
-        } if (q[1] < t[1]) {
-          return (p - t).length();
-        } else {
-          return d;
-        }
-      }
-    }
-  }
-}
-
-/**
- * Returns true if the indicated point is within the polygon's 2-d space,
- * false otherwise.
- */
-bool CollisionBox::
-point_is_inside(const LPoint2 &p, const CollisionBox::Points &points) const {
-  // We insist that the polygon be convex.  This makes things a bit simpler.
-  // In the case of a convex polygon, defined with points in counterclockwise
-  // order, a point is interior to the polygon iff the point is not right of
-  // each of the edges.
-  for (int i = 0; i < (int)points.size() - 1; i++) {
-    if (is_right(p - points[i]._p, points[i+1]._p - points[i]._p)) {
+    if (tmin == DBL_MAX) {
       return false;
     }
+    t = tmin;
   }
-  if (is_right(p - points[points.size() - 1]._p,
-               points[0]._p - points[points.size() - 1]._p)) {
-    return false;
+  else if ((m & (m - 1)) != 0) {
+    // There's just one edge to test.
+    LPoint3 edge_v1 = get_point_aabb(u ^ 7);
+    LPoint3 edge_v2 = get_point_aabb(v);
+    return intersect_segment_capsule(t, from, delta, edge_v1, edge_v2, radius_sq);
   }
 
   return true;
 }
 
-/**
- * Now that the _p members of the given points array have been computed, go
- * back and compute all of the _v members.
- */
-void CollisionBox::
-compute_vectors(Points &points) {
-  size_t num_points = points.size();
-  for (size_t i = 0; i < num_points; i++) {
-    points[i]._v = points[(i + 1) % num_points]._p - points[i]._p;
-    points[i]._v.normalize();
-  }
-}
-
 /**
  * Factory method to generate a CollisionBox object
  */
@@ -1427,28 +1110,42 @@ write_datagram(BamWriter *manager, Datagram &me) {
   _center.write_datagram(me);
   _min.write_datagram(me);
   _max.write_datagram(me);
-  for(int i=0; i < 8; i++) {
-    _vertex[i].write_datagram(me);
+  for (int i = 0; i < 8; ++i) {
+    get_point_aabb(i).write_datagram(me);
   }
-  PN_stdfloat x = _vertex[0].get_x() - _center.get_x();
-  PN_stdfloat y = _vertex[0].get_y() - _center.get_y();
-  PN_stdfloat z = _vertex[0].get_z() - _center.get_z();
+  LPoint3 vertex = get_point_aabb(0);
+  PN_stdfloat x = vertex.get_x() - _center.get_x();
+  PN_stdfloat y = vertex.get_y() - _center.get_y();
+  PN_stdfloat z = vertex.get_z() - _center.get_z();
   PN_stdfloat radius = sqrt(x * x + y * y + z * z);
   me.add_stdfloat(radius);
   me.add_stdfloat(x);
   me.add_stdfloat(y);
   me.add_stdfloat(z);
-  for(int i=0; i < 6; i++) {
+  for (int i = 0; i < 6; ++i) {
     _planes[i].write_datagram(me);
   }
-  for(int i=0; i < 6; i++) {
-    _to_2d_mat[i].write_datagram(me);
+  LMatrix4 to_2d_mat[6];
+  for (int i = 0; i < 6; ++i) {
+    LMatrix4 to_3d_mat;
+    look_at(to_3d_mat, -get_plane(i).get_normal(),
+            LVector3(0.0f, 0.0f, 1.0f), CS_zup_right);
+    to_3d_mat.set_row(3, get_plane(i).get_point());
+
+    to_2d_mat[i].invert_from(to_3d_mat);
+    to_2d_mat[i].write_datagram(me);
   }
-  for(int i=0; i < 6; i++) {
+  for (int i = 0; i < 6; ++i) {
     me.add_uint16(4);
+    LPoint2 points[4];
+    for (size_t j = 0; j < 4; j++) {
+      points[j] = (get_point(plane_def[i][j]) * to_2d_mat[i]).get_xz();
+    }
     for (size_t j = 0; j < 4; j++) {
-      _points[i][j]._p.write_datagram(me);
-      _points[i][j]._v.write_datagram(me);
+      LPoint2 vec = points[(i + 1) % 4] - points[i];
+      vec.normalize();
+      points[j].write_datagram(me);
+      vec.write_datagram(me);
     }
   }
 }
@@ -1478,25 +1175,28 @@ fillin(DatagramIterator& scan, BamReader* manager) {
   _center.read_datagram(scan);
   _min.read_datagram(scan);
   _max.read_datagram(scan);
-  for(int i=0; i < 8; i++) {
-    _vertex[i].read_datagram(scan);
+  for (int i = 0; i < 8; ++i) {
+    LPoint3 vertex;
+    vertex.read_datagram(scan);
   }
   scan.get_stdfloat();
   scan.get_stdfloat();
   scan.get_stdfloat();
   scan.get_stdfloat();
-  for(int i=0; i < 6; i++) {
+  for (int i = 0; i < 6; ++i) {
     _planes[i].read_datagram(scan);
   }
-  for(int i=0; i < 6; i++) {
-    _to_2d_mat[i].read_datagram(scan);
+  for (int i = 0; i < 6; ++i) {
+    LMatrix4 to_2d_mat;
+    to_2d_mat.read_datagram(scan);
   }
-  for(int i=0; i < 6; i++) {
+  for (int i = 0; i < 6; ++i) {
     size_t size = scan.get_uint16();
-    nassertv(size == 4);
-    for (size_t j = 0; j < size; j++) {
-      _points[i][j]._p.read_datagram(scan);
-      _points[i][j]._v.read_datagram(scan);
+    for (size_t j = 0; j < size; ++j) {
+      LPoint2 p;
+      LVector2 v;
+      p.read_datagram(scan);
+      v.read_datagram(scan);
     }
   }
 }

+ 3 - 45
panda/src/collide/collisionBox.h

@@ -49,7 +49,6 @@ public:
   virtual void output(std::ostream &out) const;
 
   INLINE static void flush_level();
-  void setup_box();
 
 PUBLISHED:
   INLINE int get_num_points() const;
@@ -94,12 +93,14 @@ protected:
   bool intersects_line(double &t1, double &t2,
                        const LPoint3 &from, const LVector3 &delta,
                        PN_stdfloat inflate_size=0) const;
+  bool intersects_capsule(double &t,
+                          const LPoint3 &from, const LVector3 &delta,
+                          PN_stdfloat radius_sq) const;
 
 private:
   LPoint3 _center;
   LPoint3 _min;
   LPoint3 _max;
-  LPoint3 _vertex[8]; // Each of the Eight Vertices of the Box
   LPlane _planes[6]; //Points to each of the six sides of the Box
 
   static const int plane_def[6][4];
@@ -107,49 +108,6 @@ private:
   static PStatCollector _volume_pcollector;
   static PStatCollector _test_pcollector;
 
-private:
-  INLINE static bool is_right(const LVector2 &v1, const LVector2 &v2);
-  INLINE static PN_stdfloat dist_to_line(const LPoint2 &p,
-                                   const LPoint2 &f, const LVector2 &v);
-  static PN_stdfloat dist_to_line_segment(const LPoint2 &p,
-                                    const LPoint2 &f, const LPoint2 &t,
-                                    const LVector2 &v);
-
-public:
-  class PointDef {
-  public:
-    PointDef() = default;
-    INLINE PointDef(const LPoint2 &p, const LVector2 &v);
-    INLINE PointDef(PN_stdfloat x, PN_stdfloat y);
-    INLINE PointDef(const PointDef &copy);
-    INLINE void operator = (const PointDef &copy);
-
-    LPoint2 _p;  // the point in 2-d space
-    LVector2 _v; // the normalized vector to the next point
-  };
-  typedef pvector<PointDef> Points;
-
-  static void compute_vectors(Points &points);
-  void draw_polygon(GeomNode *viz_geom_node, GeomNode *bounds_viz_geom_node,
-                    const Points &points) const;
-
-  bool point_is_inside(const LPoint2 &p, const Points &points) const;
-  PN_stdfloat dist_to_polygon(const LPoint2 &p, const PointDef *points, size_t num_points) const;
-
-  void setup_points(int plane);
-  INLINE LPoint2 to_2d(const LVecBase3 &point3d, int plane) const;
-  INLINE void calc_to_3d_mat(LMatrix4 &to_3d_mat, int plane) const;
-  INLINE static LPoint3 to_3d(const LVecBase2 &point2d, const LMatrix4 &to_3d_mat);
-  bool clip_polygon(Points &new_points, const PointDef *source_points,
-                    size_t num_source_points, const LPlane &plane,
-                    int plane_no) const;
-  bool apply_clip_plane(Points &new_points, const ClipPlaneAttrib *cpa,
-                        const TransformState *net_transform, int plane_no) const;
-
-private:
-  PointDef _points[6][4]; // one set of points for each of the six planes that make up the box
-  LMatrix4 _to_2d_mat[6];
-
 public:
   static void register_with_read_factory();
   virtual void write_datagram(BamWriter *manager, Datagram &me);

+ 36 - 32
panda/src/collide/collisionSphere.cxx

@@ -145,44 +145,48 @@ test_intersection_from_sphere(const CollisionEntry &entry) const {
   LPoint3 contact_point(into_intersection_point);
   PN_stdfloat actual_t = 0.0f;
 
-  LVector3 vec = from_b - into_center;
-  PN_stdfloat dist2 = dot(vec, vec);
-  if (dist2 > (into_radius + from_radius) * (into_radius + from_radius)) {
-    // No intersection with the current position.  Check the delta from the
-    // previous frame.
+  LPoint3 from_a = from_b;
+  if (entry.get_respect_prev_transform()) {
     CPT(TransformState) wrt_prev_space = entry.get_wrt_prev_space();
-    LPoint3 from_a = sphere->get_center() * wrt_prev_space->get_mat();
+    if (wrt_prev_space != wrt_space) {
+      from_a = sphere->get_center() * wrt_prev_space->get_mat();
+    }
+  }
 
-    if (!from_a.almost_equal(from_b)) {
-      LVector3 from_direction = from_b - from_a;
-      if (!intersects_line(t1, t2, from_a, from_direction, from_radius)) {
-        // No intersection.
-        return nullptr;
-      }
+  if (from_a.almost_equal(from_b)) {
+    LVector3 vec = from_b - into_center;
+    PN_stdfloat dist2 = dot(vec, vec);
 
-      if (t2 < 0.0 || t1 > 1.0) {
-        // Both intersection points are before the start of the segment or
-        // after the end of the segment.
-        return nullptr;
-      }
+    if (dist2 > (into_radius + from_radius) * (into_radius + from_radius)) {
+      // No intersection with the current position.
+      return nullptr;
+    }
+  } else {
+    LVector3 from_direction = from_b - from_a;
+    if (!intersects_line(t1, t2, from_a, from_direction, from_radius)) {
+      // No intersection.
+      return nullptr;
+    }
 
-      // doubles, not floats, to satisfy min and max templates.
-      actual_t = min(1.0, max(0.0, t1));
-      contact_point = from_a + actual_t * (from_b - from_a);
-
-      if (t1 < 0.0) {
-        // Point a is within the sphere.  The first intersection point is
-        // point a itself.
-        into_intersection_point = from_a;
-      } else {
-        // Point a is outside the sphere, and point b is either inside the
-        // sphere or beyond it.  The first intersection point is at t1.
-        into_intersection_point = from_a + t1 * from_direction;
-      }
-    } else {
-      // No delta, therefore no intersection.
+    if (t2 < 0.0 || t1 > 1.0) {
+      // Both intersection points are before the start of the segment or
+      // after the end of the segment.
       return nullptr;
     }
+
+    // doubles, not floats, to satisfy min and max templates.
+    actual_t = min(1.0, max(0.0, t1));
+    contact_point = from_a + actual_t * (from_b - from_a);
+
+    if (t1 < 0.0) {
+      // Point a is within the sphere.  The first intersection point is
+      // point a itself.
+      into_intersection_point = from_a;
+    } else {
+      // Point a is outside the sphere, and point b is either inside the
+      // sphere or beyond it.  The first intersection point is at t1.
+      into_intersection_point = from_a + t1 * from_direction;
+    }
   }
 
   if (collide_cat.is_debug()) {

+ 4 - 10
panda/src/collide/collisionVisualizer.cxx

@@ -207,11 +207,8 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) {
           PT(Geom) geom = new Geom(point_vdata);
           geom->add_primitive(points);
 
-          CullableObject *object =
-            new CullableObject(geom, point_state,
-                               xform_data.get_internal_transform(trav));
-
-          trav->get_cull_handler()->record_object(object, trav);
+          trav->get_cull_handler()->record_object(CullableObject(
+            geom, point_state, xform_data.get_internal_transform(trav)), trav);
         }
 
         // Draw the normal vector at the surface point.
@@ -236,11 +233,8 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) {
           PT(Geom) geom = new Geom(line_vdata);
           geom->add_primitive(lines);
 
-          CullableObject *object =
-            new CullableObject(geom, empty_state,
-                               xform_data.get_internal_transform(trav));
-
-          trav->get_cull_handler()->record_object(object, trav);
+          trav->get_cull_handler()->record_object(CullableObject(
+            geom, empty_state, xform_data.get_internal_transform(trav)), trav);
         }
       }
     }

+ 2 - 2
panda/src/cull/binCullHandler.cxx

@@ -19,6 +19,6 @@
  * This is called as each Geom is discovered by the CullTraverser.
  */
 void BinCullHandler::
-record_object(CullableObject *object, const CullTraverser *traverser) {
-  _cull_result->add_object(object, traverser);
+record_object(CullableObject &&object, const CullTraverser *traverser) {
+  _cull_result->add_object(std::move(object), traverser);
 }

+ 1 - 1
panda/src/cull/binCullHandler.h

@@ -28,7 +28,7 @@ class EXPCL_PANDA_CULL BinCullHandler : public CullHandler {
 public:
   INLINE BinCullHandler(CullResult *cull_result);
 
-  virtual void record_object(CullableObject *object,
+  virtual void record_object(CullableObject &&object,
                              const CullTraverser *traverser);
 
 private:

+ 0 - 12
panda/src/cull/cullBinBackToFront.cxx

@@ -23,18 +23,6 @@
 
 TypeHandle CullBinBackToFront::_type_handle;
 
-/**
- *
- */
-CullBinBackToFront::
-~CullBinBackToFront() {
-  Objects::iterator oi;
-  for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
-    CullableObject *object = (*oi)._object;
-    delete object;
-  }
-}
-
 /**
  * Factory constructor for passing to the CullBinManager.
  */

+ 0 - 1
panda/src/cull/cullBinBackToFront.h

@@ -33,7 +33,6 @@ public:
   INLINE CullBinBackToFront(const std::string &name,
                             GraphicsStateGuardianBase *gsg,
                             const PStatCollector &draw_region_pcollector);
-  virtual ~CullBinBackToFront();
 
   static CullBin *make_bin(const std::string &name,
                            GraphicsStateGuardianBase *gsg,

+ 0 - 12
panda/src/cull/cullBinFixed.cxx

@@ -23,18 +23,6 @@
 
 TypeHandle CullBinFixed::_type_handle;
 
-/**
- *
- */
-CullBinFixed::
-~CullBinFixed() {
-  Objects::iterator oi;
-  for (oi = _objects.begin(); oi != _objects.end(); ++oi) {
-    CullableObject *object = (*oi)._object;
-    delete object;
-  }
-}
-
 /**
  * Factory constructor for passing to the CullBinManager.
  */

+ 0 - 1
panda/src/cull/cullBinFixed.h

@@ -35,7 +35,6 @@ public:
   INLINE CullBinFixed(const std::string &name,
                       GraphicsStateGuardianBase *gsg,
                       const PStatCollector &draw_region_pcollector);
-  virtual ~CullBinFixed();
 
   static CullBin *make_bin(const std::string &name,
                            GraphicsStateGuardianBase *gsg,

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