Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
c4f1842505
|
|
@ -2,6 +2,7 @@
|
|||
name: Bug report
|
||||
about: Report a defect
|
||||
title:
|
||||
type: bug
|
||||
labels:
|
||||
assignees:
|
||||
---
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
name: Enhancement request
|
||||
about: Request new functionality or improvement to existing functionality
|
||||
title:
|
||||
type: feature
|
||||
labels: enhancement
|
||||
assignees:
|
||||
---
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
open-pull-requests-limit: 5
|
||||
|
|
@ -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
|
||||
double: NO
|
||||
|
||||
- profile: macos-eigen-coverage-unity-xcode
|
||||
os: macOS-12
|
||||
config: Coverage
|
||||
unity: YES
|
||||
generator: Xcode
|
||||
compiler: Default
|
||||
metalibs: YES
|
||||
python: YES
|
||||
eigen: YES
|
||||
#- 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 Python 3.12
|
||||
uses: actions/setup-python@v4
|
||||
- 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.12'
|
||||
- name: Build Python 3.12
|
||||
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
|
||||
- name: Test Python 3.12
|
||||
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@v5
|
||||
with:
|
||||
python-version: '3.12'
|
||||
- name: Build Python 3.12 (double)
|
||||
shell: bash
|
||||
run: |
|
||||
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_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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ This is a list of all the people who are contributing financially to Panda3D. I
|
|||
* GameDev JONI
|
||||
* Max Rodriguez
|
||||
* Jethro Schoppenhorst
|
||||
* dabe
|
||||
|
||||
## Backers
|
||||
|
||||
|
|
|
|||
10
README.md
10
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:
|
||||
|
|
|
|||
|
|
@ -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}")
|
||||
|
|
|
|||
|
|
@ -547,31 +547,35 @@ client_format_generate_CMU(PyObject *distobj, DOID_TYPE do_id,
|
|||
}
|
||||
|
||||
// Also specify the optional fields.
|
||||
int num_optional_fields = 0;
|
||||
if (PyObject_IsTrue(optional_fields)) {
|
||||
num_optional_fields = PySequence_Size(optional_fields);
|
||||
}
|
||||
packer.raw_pack_uint16(num_optional_fields);
|
||||
optional_fields = PySequence_Tuple(optional_fields);
|
||||
Py_ssize_t num_optional_fields = PyTuple_GET_SIZE(optional_fields);
|
||||
packer.raw_pack_uint16(num_optional_fields);
|
||||
|
||||
for (int i = 0; i < num_optional_fields; i++) {
|
||||
PyObject *py_field_name = PySequence_GetItem(optional_fields, i);
|
||||
std::string field_name = PyUnicode_AsUTF8(py_field_name);
|
||||
Py_XDECREF(py_field_name);
|
||||
for (Py_ssize_t i = 0; i < num_optional_fields; i++) {
|
||||
PyObject *py_field_name = PyTuple_GET_ITEM(optional_fields, i);
|
||||
std::string field_name = PyUnicode_AsUTF8(py_field_name);
|
||||
|
||||
DCField *field = _this->get_field_by_name(field_name);
|
||||
if (field == nullptr) {
|
||||
std::ostringstream strm;
|
||||
strm << "No field named " << field_name << " in class " << _this->get_name()
|
||||
<< "\n";
|
||||
nassert_raise(strm.str());
|
||||
return Datagram();
|
||||
DCField *field = _this->get_field_by_name(field_name);
|
||||
if (field == nullptr) {
|
||||
std::ostringstream strm;
|
||||
strm << "No field named " << field_name << " in class " << _this->get_name()
|
||||
<< "\n";
|
||||
nassert_raise(strm.str());
|
||||
Py_DECREF(optional_fields);
|
||||
return Datagram();
|
||||
}
|
||||
packer.raw_pack_uint16(field->get_number());
|
||||
packer.begin_pack(field);
|
||||
if (!pack_required_field(packer, distobj, field)) {
|
||||
Py_DECREF(optional_fields);
|
||||
return Datagram();
|
||||
}
|
||||
packer.end_pack();
|
||||
}
|
||||
packer.raw_pack_uint16(field->get_number());
|
||||
packer.begin_pack(field);
|
||||
if (!pack_required_field(packer, distobj, field)) {
|
||||
return Datagram();
|
||||
}
|
||||
packer.end_pack();
|
||||
Py_DECREF(optional_fields);
|
||||
} else {
|
||||
packer.raw_pack_uint16(0);
|
||||
}
|
||||
|
||||
return Datagram(packer.get_data(), packer.get_length());
|
||||
|
|
@ -646,13 +650,13 @@ ai_format_generate(PyObject *distobj, DOID_TYPE do_id,
|
|||
|
||||
// Also specify the optional fields.
|
||||
if (has_optional_fields) {
|
||||
int num_optional_fields = PySequence_Size(optional_fields);
|
||||
optional_fields = PySequence_Tuple(optional_fields);
|
||||
Py_ssize_t num_optional_fields = PyTuple_GET_SIZE(optional_fields);
|
||||
packer.raw_pack_uint16(num_optional_fields);
|
||||
|
||||
for (int i = 0; i < num_optional_fields; ++i) {
|
||||
PyObject *py_field_name = PySequence_GetItem(optional_fields, i);
|
||||
for (Py_ssize_t i = 0; i < num_optional_fields; ++i) {
|
||||
PyObject *py_field_name = PyTuple_GET_ITEM(optional_fields, i);
|
||||
std::string field_name = PyUnicode_AsUTF8(py_field_name);
|
||||
Py_XDECREF(py_field_name);
|
||||
|
||||
DCField *field = _this->get_field_by_name(field_name);
|
||||
if (field == nullptr) {
|
||||
|
|
@ -660,6 +664,7 @@ ai_format_generate(PyObject *distobj, DOID_TYPE do_id,
|
|||
strm << "No field named " << field_name << " in class "
|
||||
<< _this->get_name() << "\n";
|
||||
nassert_raise(strm.str());
|
||||
Py_DECREF(optional_fields);
|
||||
return Datagram();
|
||||
}
|
||||
|
||||
|
|
@ -667,10 +672,13 @@ ai_format_generate(PyObject *distobj, DOID_TYPE do_id,
|
|||
|
||||
packer.begin_pack(field);
|
||||
if (!pack_required_field(packer, distobj, field)) {
|
||||
Py_DECREF(optional_fields);
|
||||
return Datagram();
|
||||
}
|
||||
packer.end_pack();
|
||||
}
|
||||
|
||||
Py_DECREF(optional_fields);
|
||||
}
|
||||
|
||||
return Datagram(packer.get_data(), packer.get_length());
|
||||
|
|
|
|||
|
|
@ -286,8 +286,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);
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ pack_object(PyObject *object) {
|
|||
// The supplied object is not an instance of the expected class object,
|
||||
// but it is a sequence. This is case (2).
|
||||
_this->push();
|
||||
Py_BEGIN_CRITICAL_SECTION(object);
|
||||
int size = PySequence_Size(object);
|
||||
for (int i = 0; i < size; ++i) {
|
||||
PyObject *element = PySequence_GetItem(object, i);
|
||||
|
|
@ -146,6 +147,7 @@ pack_object(PyObject *object) {
|
|||
std::cerr << "Unable to extract item " << i << " from sequence.\n";
|
||||
}
|
||||
}
|
||||
Py_END_CRITICAL_SECTION();
|
||||
_this->pop();
|
||||
} else {
|
||||
// The supplied object is not a sequence, and we weren't expecting a
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -174,35 +174,6 @@ class ConnectionRepository(
|
|||
return retVal
|
||||
|
||||
def generateGlobalObject(self, doId, dcname, values=None):
|
||||
def applyFieldValues(distObj, dclass, values):
|
||||
for i in range(dclass.getNumInheritedFields()):
|
||||
field = dclass.getInheritedField(i)
|
||||
if field.asMolecularField() is None:
|
||||
value = values.get(field.getName(), None)
|
||||
if value is None and field.isRequired():
|
||||
# Gee, this could be better. What would really be
|
||||
# nicer is to get value from field.getDefaultValue
|
||||
# or similar, but that returns a binary string, not
|
||||
# a python tuple, like the following does. If you
|
||||
# want to change something better, please go ahead.
|
||||
packer = DCPacker()
|
||||
packer.beginPack(field)
|
||||
packer.packDefaultValue()
|
||||
packer.endPack()
|
||||
|
||||
unpacker = DCPacker()
|
||||
unpacker.setUnpackData(packer.getString())
|
||||
unpacker.beginUnpack(field)
|
||||
value = unpacker.unpackObject()
|
||||
unpacker.endUnpack()
|
||||
if value is not None:
|
||||
function = getattr(distObj, field.getName())
|
||||
if function is not None:
|
||||
function(*value)
|
||||
else:
|
||||
self.notify.error("\n\n\nNot able to find %s.%s"%(
|
||||
distObj.__class__.__name__, field.getName()))
|
||||
|
||||
# Look up the dclass
|
||||
dclass = self.dclassesByName.get(dcname+self.dcSuffix)
|
||||
if dclass is None:
|
||||
|
|
@ -229,7 +200,37 @@ class ConnectionRepository(
|
|||
distObj.generateInit() # Only called when constructed
|
||||
distObj.generate()
|
||||
if values is not None:
|
||||
applyFieldValues(distObj, dclass, values)
|
||||
for i in range(dclass.getNumInheritedFields()):
|
||||
field = dclass.getInheritedField(i)
|
||||
if field.asMolecularField() is None:
|
||||
value = values.get(field.getName(), None)
|
||||
if value is None and field.isRequired():
|
||||
# Gee, this could be better. What would really be
|
||||
# nicer is to get value from field.getDefaultValue
|
||||
# or similar, but that returns a binary string, not
|
||||
# a python tuple, like the following does. If you
|
||||
# want to change something better, please go ahead.
|
||||
packer = DCPacker()
|
||||
packer.beginPack(field)
|
||||
packer.packDefaultValue()
|
||||
packer.endPack()
|
||||
|
||||
unpacker = DCPacker()
|
||||
unpacker.setUnpackData(packer.getString())
|
||||
unpacker.beginUnpack(field)
|
||||
value = unpacker.unpackObject()
|
||||
unpacker.endUnpack()
|
||||
if value is not None:
|
||||
function = getattr(distObj, field.getName())
|
||||
if function is not None:
|
||||
function(*value)
|
||||
else:
|
||||
self.notify.error(
|
||||
"\n\n\nNot able to find %s.%s" % (
|
||||
distObj.__class__.__name__,
|
||||
field.getName()
|
||||
)
|
||||
)
|
||||
distObj.announceGenerate()
|
||||
distObj.parentId = 0
|
||||
distObj.zoneId = 0
|
||||
|
|
|
|||
|
|
@ -713,11 +713,12 @@ handle_update_field() {
|
|||
nassertr(doId2do != nullptr, false);
|
||||
|
||||
PyObject *doId = PyLong_FromUnsignedLong(do_id);
|
||||
PyObject *distobj = PyDict_GetItem(doId2do, doId);
|
||||
PyObject *distobj;
|
||||
int result = PyDict_GetItemRef(doId2do, doId, &distobj);
|
||||
Py_DECREF(doId);
|
||||
Py_DECREF(doId2do);
|
||||
|
||||
if (distobj != nullptr) {
|
||||
if (result > 0) {
|
||||
PyObject *dclass_obj = PyObject_GetAttrString(distobj, "dclass");
|
||||
nassertr(dclass_obj != nullptr, false);
|
||||
|
||||
|
|
@ -736,9 +737,11 @@ handle_update_field() {
|
|||
nassertr(neverDisable != nullptr, false);
|
||||
|
||||
unsigned int cNeverDisable = PyLong_AsLong(neverDisable);
|
||||
Py_DECREF(neverDisable);
|
||||
if (!cNeverDisable) {
|
||||
// in quiet zone and distobj is disable-able drop update on the
|
||||
// floor
|
||||
Py_DECREF(distobj);
|
||||
#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
|
||||
PyGILState_Release(gstate);
|
||||
#endif
|
||||
|
|
@ -746,13 +749,8 @@ handle_update_field() {
|
|||
}
|
||||
}
|
||||
|
||||
// It's a good idea to ensure the reference count to distobj is raised
|
||||
// while we call the update method--otherwise, the update method might
|
||||
// get into trouble if it tried to delete the object from the doId2do
|
||||
// map.
|
||||
PyObject *distobj_ref = Py_NewRef(distobj);
|
||||
invoke_extension(dclass).receive_update(distobj_ref, _di);
|
||||
Py_DECREF(distobj_ref);
|
||||
invoke_extension(dclass).receive_update(distobj, _di);
|
||||
Py_DECREF(distobj);
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
|
||||
|
|
@ -802,10 +800,11 @@ handle_update_field_owner() {
|
|||
PyObject *doId = PyLong_FromUnsignedLong(do_id);
|
||||
|
||||
// pass the update to the owner view first
|
||||
PyObject *distobjOV = PyDict_GetItem(doId2ownerView, doId);
|
||||
PyObject *distobjOV;
|
||||
int result = PyDict_GetItemRef(doId2ownerView, doId, &distobjOV);
|
||||
Py_DECREF(doId2ownerView);
|
||||
|
||||
if (distobjOV != nullptr) {
|
||||
if (result > 0) {
|
||||
PyObject *dclass_obj = PyObject_GetAttrString(distobjOV, "dclass");
|
||||
nassertr(dclass_obj != nullptr, false);
|
||||
|
||||
|
|
@ -823,32 +822,29 @@ handle_update_field_owner() {
|
|||
int field_id = packer.raw_unpack_uint16();
|
||||
DCField *field = dclass->get_field_by_index(field_id);
|
||||
if (field->is_ownrecv()) {
|
||||
// It's a good idea to ensure the reference count to distobjOV is
|
||||
// raised while we call the update method--otherwise, the update
|
||||
// method might get into trouble if it tried to delete the object from
|
||||
// the doId2do map.
|
||||
PyObject *distobjOV_ref = Py_NewRef(distobjOV);
|
||||
// make a copy of the datagram iterator so that we can use the main
|
||||
// iterator for the non-owner update
|
||||
DatagramIterator _odi(_di);
|
||||
invoke_extension(dclass).receive_update(distobjOV_ref, _odi);
|
||||
Py_DECREF(distobjOV_ref);
|
||||
invoke_extension(dclass).receive_update(distobjOV, _odi);
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
Py_DECREF(distobjOV);
|
||||
#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
|
||||
PyGILState_Release(gstate);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Py_DECREF(distobjOV);
|
||||
}
|
||||
|
||||
// now pass the update to the visible view
|
||||
PyObject *distobj = PyDict_GetItem(doId2do, doId);
|
||||
PyObject *distobj;
|
||||
result = PyDict_GetItemRef(doId2do, doId, &distobj);
|
||||
Py_DECREF(doId);
|
||||
Py_DECREF(doId2do);
|
||||
|
||||
if (distobj != nullptr) {
|
||||
if (result > 0) {
|
||||
PyObject *dclass_obj = PyObject_GetAttrString(distobj, "dclass");
|
||||
nassertr(dclass_obj != nullptr, false);
|
||||
|
||||
|
|
@ -867,21 +863,17 @@ handle_update_field_owner() {
|
|||
//int field_id = packer.raw_unpack_uint16();
|
||||
//DCField *field = dclass->get_field_by_index(field_id);
|
||||
if (true) {//field->is_broadcast()) {
|
||||
// It's a good idea to ensure the reference count to distobj is raised
|
||||
// while we call the update method--otherwise, the update method might
|
||||
// get into trouble if it tried to delete the object from the doId2do
|
||||
// map.
|
||||
PyObject *distobj_ref = Py_NewRef(distobj);
|
||||
invoke_extension(dclass).receive_update(distobj_ref, _di);
|
||||
Py_DECREF(distobj_ref);
|
||||
invoke_extension(dclass).receive_update(distobj, _di);
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
Py_DECREF(distobj);
|
||||
#if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS)
|
||||
PyGILState_Release(gstate);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Py_DECREF(distobj);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -995,12 +987,14 @@ describe_message(std::ostream &out, const string &prefix,
|
|||
nassertv(doId2do != nullptr);
|
||||
|
||||
PyObject *doId = PyLong_FromUnsignedLong(do_id);
|
||||
PyObject *distobj = PyDict_GetItem(doId2do, doId);
|
||||
PyObject *distobj;
|
||||
int result = PyDict_GetItemRef(doId2do, doId, &distobj);
|
||||
Py_DECREF(doId);
|
||||
Py_DECREF(doId2do);
|
||||
|
||||
if (distobj != nullptr) {
|
||||
if (result > 0) {
|
||||
PyObject *dclass_obj = PyObject_GetAttrString(distobj, "dclass");
|
||||
Py_DECREF(distobj);
|
||||
nassertv(dclass_obj != nullptr);
|
||||
|
||||
PyObject *dclass_this = PyObject_GetAttrString(dclass_obj, "this");
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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()`.
|
||||
|
|
|
|||
|
|
@ -327,8 +327,6 @@ class Transitions:
|
|||
else:
|
||||
self.transitionIval = self.getIrisInIval(t, finishIval, blendType)
|
||||
self.__transitionFuture = AsyncFuture()
|
||||
if finishIval:
|
||||
self.transitionIval.append(finishIval)
|
||||
self.transitionIval.start()
|
||||
return self.__transitionFuture
|
||||
|
||||
|
|
@ -349,8 +347,6 @@ class Transitions:
|
|||
else:
|
||||
self.transitionIval = self.getIrisOutIval(t, finishIval, blendType)
|
||||
self.__transitionFuture = AsyncFuture()
|
||||
if finishIval:
|
||||
self.transitionIval.append(finishIval)
|
||||
self.transitionIval.start()
|
||||
return self.__transitionFuture
|
||||
|
||||
|
|
|
|||
|
|
@ -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] != '.':
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -265,7 +265,7 @@ if(BUILD_INTERROGATE)
|
|||
panda3d-interrogate
|
||||
|
||||
GIT_REPOSITORY https://github.com/panda3d/interrogate.git
|
||||
GIT_TAG e297384b30f1eae8ab839ec096fc3bb6bdb3edeb
|
||||
GIT_TAG 03418d6d7ddda7fb99abf27230aa42d1d8bd607e
|
||||
|
||||
PREFIX ${_interrogate_dir}
|
||||
CMAKE_ARGS
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -133,7 +134,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")
|
||||
|
|
@ -200,6 +201,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")
|
||||
|
|
@ -319,6 +341,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)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -49,19 +49,26 @@ __reduce__() const {
|
|||
PyTypeObject *py_type = _this->get_python_type();
|
||||
if (py_type != nullptr && py_type->tp_dict != nullptr) {
|
||||
// Look for a get_class_type method, if it returns this handle.
|
||||
PyObject *func = PyDict_GetItemString(py_type->tp_dict, "get_class_type");
|
||||
if (func != nullptr && PyCallable_Check(func)) {
|
||||
PyObject *result = PyObject_CallNoArgs(func);
|
||||
TypeHandle *result_handle = nullptr;
|
||||
if (result == nullptr) {
|
||||
// Never mind.
|
||||
PyErr_Clear();
|
||||
}
|
||||
else if (DtoolInstance_GetPointer(result, result_handle, Dtool_TypeHandle) &&
|
||||
*result_handle == *_this) {
|
||||
// It returned the correct result, so we can use this.
|
||||
return Py_BuildValue("O()", func);
|
||||
PyObject *func;
|
||||
int result = PyDict_GetItemStringRef(py_type->tp_dict, "get_class_type", &func);
|
||||
if (result > 0) {
|
||||
if (PyCallable_Check(func)) {
|
||||
PyObject *result = PyObject_CallNoArgs(func);
|
||||
TypeHandle *result_handle = nullptr;
|
||||
if (result == nullptr) {
|
||||
// Never mind.
|
||||
PyErr_Clear();
|
||||
}
|
||||
else if (DtoolInstance_GetPointer(result, result_handle, Dtool_TypeHandle) &&
|
||||
*result_handle == *_this) {
|
||||
// It returned the correct result, so we can use this.
|
||||
return Py_BuildValue("N()", func);
|
||||
}
|
||||
}
|
||||
Py_DECREF(func);
|
||||
}
|
||||
else if (result < 0) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ is_open() const {
|
|||
*/
|
||||
bool PipeStreamBuf::
|
||||
eof_pipe() const {
|
||||
return (_pipe == nullptr) && feof(_pipe);
|
||||
return (_pipe == nullptr) || feof(_pipe);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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.");
|
||||
|
|
@ -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
|
||||
|
|
@ -1,161 +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();
|
||||
auto it = type_map->find("DTOOL_SUPER_BASE");
|
||||
if (it != type_map->end()) {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
static PyMethodDef methods[] = {
|
||||
{ "DtoolGetSuperBase", (PyCFunction)&GetSuperBase, METH_NOARGS, "Will Return SUPERbase Class"},
|
||||
{ nullptr, nullptr, 0, nullptr }
|
||||
};
|
||||
|
||||
static Dtool_PyTypedObject super_base_type = {
|
||||
{
|
||||
PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
"dtoolconfig.DTOOL_SUPER_BASE",
|
||||
sizeof(Dtool_PyInstDef),
|
||||
0, // tp_itemsize
|
||||
&Dtool_FreeInstance_DTOOL_SUPER_BASE,
|
||||
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)");
|
||||
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;
|
||||
return &super_base_type;
|
||||
}
|
||||
|
||||
#endif // HAVE_PYTHON
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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 ©) :
|
||||
_def(copy._def),
|
||||
_name(copy._name)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
INLINE void InterrogateComponent::
|
||||
operator = (const InterrogateComponent ©) {
|
||||
_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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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 ©);
|
||||
INLINE void operator = (const InterrogateComponent ©);
|
||||
|
||||
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
|
||||
|
|
@ -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);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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
|
||||
|
|
@ -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 ©) {
|
||||
(*this) = copy;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
INLINE void InterrogateElement::
|
||||
operator = (const InterrogateElement ©) {
|
||||
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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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 ©);
|
||||
INLINE void operator = (const InterrogateElement ©);
|
||||
|
||||
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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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 ©) {
|
||||
(*this) = copy;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void InterrogateFunction::
|
||||
operator = (const InterrogateFunction ©) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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 ©);
|
||||
void operator = (const InterrogateFunction ©);
|
||||
|
||||
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
|
||||
|
|
@ -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 ©) {
|
||||
(*this) = copy;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
INLINE void InterrogateFunctionWrapper::
|
||||
operator = (const InterrogateFunctionWrapper ©) {
|
||||
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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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 ©);
|
||||
INLINE void operator = (const InterrogateFunctionWrapper ©);
|
||||
|
||||
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 ¶meter_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
|
||||
|
|
@ -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 ©) {
|
||||
(*this) = copy;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
INLINE void InterrogateMakeSeq::
|
||||
operator = (const InterrogateMakeSeq ©) {
|
||||
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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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 ©);
|
||||
INLINE void operator = (const InterrogateMakeSeq ©);
|
||||
|
||||
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
|
||||
|
|
@ -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 ©) {
|
||||
(*this) = copy;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
INLINE void InterrogateManifest::
|
||||
operator = (const InterrogateManifest ©) {
|
||||
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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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 ©);
|
||||
INLINE void operator = (const InterrogateManifest ©);
|
||||
|
||||
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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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 ©) {
|
||||
(*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 ©) {
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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 ©);
|
||||
void operator = (const InterrogateType ©);
|
||||
|
||||
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
|
||||
|
|
@ -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--;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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"
|
||||
|
|
@ -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"
|
||||
|
|
@ -1,46 +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 (res < 0) {
|
||||
return (size_t)res;
|
||||
} else {
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // HAVE_PYTHON
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -189,6 +189,20 @@ INLINE PyObject *_PyObject_FastCall(PyObject *func, PyObject **args, Py_ssize_t
|
|||
} while (0)
|
||||
#endif
|
||||
|
||||
#if PY_VERSION_HEX < 0x03070000
|
||||
INLINE PyObject *PyImport_GetModule(PyObject *name) {
|
||||
PyObject *modules = PyImport_GetModuleDict();
|
||||
if (modules != nullptr) {
|
||||
PyObject *module = PyDict_GetItem(modules, name);
|
||||
if (module != nullptr) {
|
||||
Py_INCREF(module);
|
||||
return module;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Python 3.8 */
|
||||
#if PY_VERSION_HEX < 0x03080000
|
||||
INLINE PyObject *_PyLong_Rshift(PyObject *a, size_t shiftby) {
|
||||
|
|
@ -207,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
|
||||
|
|
@ -279,6 +297,77 @@ INLINE bool PyLong_IsNonNegative(PyObject *value) {
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Python 3.13 */
|
||||
|
||||
#if PY_VERSION_HEX < 0x030D00A1
|
||||
# define PyLong_AsInt(x) (_PyLong_AsInt(x))
|
||||
#endif
|
||||
|
||||
#if PY_VERSION_HEX < 0x030D00A1
|
||||
ALWAYS_INLINE int
|
||||
PyModule_Add(PyObject *mod, const char *name, PyObject *value) {
|
||||
int res = PyModule_AddObjectRef(mod, name, value);
|
||||
Py_XDECREF(value);
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if PY_VERSION_HEX < 0x030D00A1
|
||||
INLINE int
|
||||
PyDict_GetItemRef(PyObject *mp, PyObject *key, PyObject **result) {
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
PyObject *item = PyDict_GetItemWithError(mp, key);
|
||||
#else
|
||||
PyObject *item = _PyDict_GetItemWithError(mp, key);
|
||||
#endif
|
||||
if (item != nullptr) {
|
||||
*result = Py_NewRef(item);
|
||||
return 1;
|
||||
}
|
||||
*result = nullptr;
|
||||
return PyErr_Occurred() ? -1 : 0;
|
||||
}
|
||||
|
||||
INLINE int
|
||||
PyDict_GetItemStringRef(PyObject *mp, const char *key, PyObject **result) {
|
||||
PyObject *item = nullptr;
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
PyObject *key_obj = PyUnicode_FromString(key);
|
||||
item = key_obj ? PyDict_GetItemWithError(mp, key_obj) : nullptr;
|
||||
#else
|
||||
PyObject *key_obj = PyString_FromString(key);
|
||||
item = key_obj ? _PyDict_GetItemWithError(mp, key_obj) : nullptr;
|
||||
#endif
|
||||
Py_DECREF(key_obj);
|
||||
if (item != nullptr) {
|
||||
*result = Py_NewRef(item);
|
||||
return 1;
|
||||
}
|
||||
*result = nullptr;
|
||||
return PyErr_Occurred() ? -1 : 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if PY_VERSION_HEX >= 0x03050200 && PY_VERSION_HEX < 0x030D00A1
|
||||
# define PyThreadState_GetUnchecked() (_PyThreadState_UncheckedGet())
|
||||
#endif
|
||||
|
||||
#if PY_VERSION_HEX < 0x030D00A2
|
||||
# define PyList_Extend(list, iterable) (PyList_SetSlice((list), PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, (iterable)))
|
||||
# define PyList_Clear(list) (PyList_SetSlice((list), 0, PY_SSIZE_T_MAX, nullptr))
|
||||
#endif
|
||||
|
||||
#if PY_VERSION_HEX < 0x030D00A4
|
||||
# define PyList_GetItemRef(op, index) (Py_XNewRef(PyList_GetItem((op), (index))))
|
||||
#endif
|
||||
|
||||
#if PY_VERSION_HEX < 0x030D00B3
|
||||
# define Py_BEGIN_CRITICAL_SECTION(op) {
|
||||
# define Py_END_CRITICAL_SECTION() }
|
||||
# define Py_BEGIN_CRITICAL_SECTION2(a, b) {
|
||||
# define Py_END_CRITICAL_SECTION2() }
|
||||
#endif
|
||||
|
||||
/* Other Python implementations */
|
||||
|
||||
#endif // HAVE_PYTHON
|
||||
|
|
|
|||
|
|
@ -1,918 +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 = PyDict_GetItem(value2member, arg);
|
||||
if (member != nullptr) {
|
||||
return Py_NewRef(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) {
|
||||
static PyObject *enum_class = nullptr;
|
||||
#if PY_VERSION_HEX >= 0x03040000
|
||||
static PyObject *enum_meta = nullptr;
|
||||
static PyObject *enum_create = nullptr;
|
||||
if (enum_meta == nullptr) {
|
||||
PyObject *enum_module = PyImport_ImportModule("enum");
|
||||
nassertr_always(enum_module != nullptr, nullptr);
|
||||
|
||||
enum_class = PyObject_GetAttrString(enum_module, "Enum");
|
||||
enum_meta = PyObject_GetAttrString(enum_module, "EnumMeta");
|
||||
enum_create = PyObject_GetAttrString(enum_meta, "_create_");
|
||||
nassertr(enum_meta != nullptr, nullptr);
|
||||
}
|
||||
|
||||
PyObject *result = PyObject_CallFunction(enum_create, (char *)"OsN", enum_class, name, names);
|
||||
nassertr(result != nullptr, nullptr);
|
||||
#else
|
||||
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() {
|
||||
PyObject *capsule = PySys_GetObject((char *)"_interrogate_types");
|
||||
if (capsule != nullptr) {
|
||||
return (Dtool_TypeMap *)PyCapsule_GetPointer(capsule, nullptr);
|
||||
} else {
|
||||
Dtool_TypeMap *type_map = new Dtool_TypeMap;
|
||||
capsule = PyCapsule_New((void *)type_map, nullptr, nullptr);
|
||||
PySys_SetObject((char *)"_interrogate_types", capsule);
|
||||
Py_DECREF(capsule);
|
||||
return type_map;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
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();
|
||||
|
||||
// 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 {
|
||||
return PyErr_Format(PyExc_NameError, "name '%s' is not defined", types->name);
|
||||
}
|
||||
++types;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 >= 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
|
||||
|
|
@ -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)
|
||||
|
||||
|
|
@ -181,7 +182,14 @@ static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\
|
|||
// forward declared of typed object. We rely on the fact that typed objects
|
||||
// are uniquly defined by an integer.
|
||||
|
||||
#if PY_VERSION_HEX >= 0x030d0000
|
||||
class Dtool_TypeMap : public std::map<std::string, Dtool_PyTypedObject *> {
|
||||
public:
|
||||
PyMutex _lock { 0 };
|
||||
};
|
||||
#else
|
||||
typedef std::map<std::string, Dtool_PyTypedObject *> Dtool_TypeMap;
|
||||
#endif
|
||||
|
||||
EXPCL_PYPANDA Dtool_TypeMap *Dtool_GetGlobalTypeMap();
|
||||
|
||||
|
|
@ -338,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
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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}"
|
||||
|
|
@ -383,6 +382,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
|
||||
|
|
@ -393,6 +393,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
|
||||
|
||||
|
|
@ -504,6 +505,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
|
||||
|
|
@ -516,6 +518,7 @@ Function .onInit
|
|||
!insertmacro MaybeEnablePyBindingSection 3.11
|
||||
!insertmacro MaybeEnablePyBindingSection 3.12
|
||||
!insertmacro MaybeEnablePyBindingSection 3.13
|
||||
!insertmacro MaybeEnablePyBindingSection 3.14
|
||||
${EndIf}
|
||||
!endif
|
||||
|
||||
|
|
@ -541,6 +544,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
|
||||
|
||||
|
|
@ -845,6 +852,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
|
||||
|
|
@ -855,6 +863,7 @@ Section Uninstall
|
|||
!insertmacro RemovePythonPath 3.11
|
||||
!insertmacro RemovePythonPath 3.12
|
||||
!insertmacro RemovePythonPath 3.13
|
||||
!insertmacro RemovePythonPath 3.14
|
||||
!endif
|
||||
|
||||
SetDetailsPrint both
|
||||
|
|
@ -926,6 +935,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)
|
||||
|
|
@ -936,6 +946,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)
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
@ -404,7 +406,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.
|
||||
|
|
@ -470,7 +472,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)
|
||||
|
|
@ -795,7 +797,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])
|
||||
|
||||
|
|
|
|||
|
|
@ -158,7 +158,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:")
|
||||
|
|
@ -269,11 +269,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-")):
|
||||
|
|
@ -311,8 +311,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]
|
||||
|
|
@ -321,12 +321,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)
|
||||
|
|
@ -425,6 +423,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
|
||||
|
||||
|
|
@ -565,6 +565,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)
|
||||
|
||||
########################################################################
|
||||
|
|
@ -1023,12 +1028,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")
|
||||
|
|
@ -1318,7 +1325,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:
|
||||
|
|
@ -1730,7 +1737,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)
|
||||
|
||||
|
|
@ -1877,6 +1884,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"
|
||||
|
||||
|
|
@ -1902,7 +1911,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:
|
||||
|
|
@ -2514,7 +2522,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'
|
||||
|
|
@ -2780,7 +2789,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)
|
||||
|
|
@ -3517,27 +3527,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/
|
||||
#
|
||||
|
|
@ -4254,7 +4243,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'])
|
||||
|
||||
|
|
@ -4294,7 +4282,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)
|
||||
|
||||
#
|
||||
|
|
@ -4326,7 +4313,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)
|
||||
|
||||
#
|
||||
|
|
@ -4363,7 +4349,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)
|
||||
|
||||
#
|
||||
|
|
@ -4389,7 +4374,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)
|
||||
|
||||
#
|
||||
|
|
@ -4608,7 +4592,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)
|
||||
|
||||
#
|
||||
|
|
@ -4808,7 +4791,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'])
|
||||
|
||||
|
|
@ -4844,7 +4826,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'])
|
||||
|
||||
|
|
@ -4910,7 +4891,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)
|
||||
|
||||
#
|
||||
|
|
@ -5225,7 +5205,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'])
|
||||
|
||||
|
|
@ -6098,7 +6077,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)
|
||||
|
||||
#
|
||||
|
|
@ -6119,7 +6097,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)
|
||||
|
||||
#
|
||||
|
|
@ -6170,6 +6147,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
|
||||
#
|
||||
|
|
@ -6331,8 +6344,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)
|
||||
|
|
|
|||
|
|
@ -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.1.0.dist-info")):
|
||||
oscmd("\"%s\" -m pip install --force-reinstall -t \"%s\" panda3d-interrogate==0.1.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
|
||||
|
||||
|
|
@ -2126,6 +2126,14 @@ def SdkLocatePython(prefer_thirdparty_python=False):
|
|||
SDK["PYTHON"] = sdkdir
|
||||
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:
|
||||
|
|
@ -2136,11 +2144,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"]))
|
||||
|
|
@ -2151,37 +2159,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'
|
||||
|
||||
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:
|
||||
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")
|
||||
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
|
||||
|
||||
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))
|
||||
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
|
||||
|
|
@ -2189,11 +2222,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):
|
||||
# Use Brew Python.
|
||||
|
|
@ -2839,6 +2876,13 @@ def FindLibDirectory(opt):
|
|||
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
|
||||
|
|
@ -3041,6 +3085,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.
|
||||
|
|
@ -3052,6 +3099,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':
|
||||
|
|
@ -3368,12 +3416,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:
|
||||
|
|
@ -3386,7 +3438,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"):
|
||||
|
|
@ -3508,7 +3567,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,
|
||||
|
|
@ -3663,7 +3722,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):
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#else
|
||||
#include <AL/al.h>
|
||||
#include <AL/alc.h>
|
||||
#include <AL/alext.h>
|
||||
#endif
|
||||
|
||||
class OpenALAudioSound;
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ load_display_information() {
|
|||
|
||||
// Get processor information
|
||||
const NXArchInfo *ainfo = NXGetLocalArchInfo();
|
||||
_display_information->_cpu_brand_string = strdup(ainfo->description);
|
||||
_display_information->_cpu_brand_string.assign(ainfo->description);
|
||||
|
||||
// Get version of Mac OS X
|
||||
SInt32 major, minor, bugfix;
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@
|
|||
#import "cocoaPandaAppDelegate.h"
|
||||
|
||||
#import <ApplicationServices/ApplicationServices.h>
|
||||
#import <Foundation/NSAutoreleasePool.h>
|
||||
#import <AppKit/NSApplication.h>
|
||||
#import <AppKit/NSCursor.h>
|
||||
#import <AppKit/NSEvent.h>
|
||||
|
|
@ -47,6 +46,12 @@ TypeHandle CocoaGraphicsWindow::_type_handle;
|
|||
#define NSAppKitVersionNumber10_14 1671
|
||||
#endif
|
||||
|
||||
#if __MAC_OS_X_VERSION_MAX_ALLOWED < 1070
|
||||
enum {
|
||||
NSFullScreenWindowMask = 1 << 14
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
|
@ -177,7 +182,6 @@ void CocoaGraphicsWindow::
|
|||
process_events() {
|
||||
GraphicsWindow::process_events();
|
||||
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
NSEvent *event = nil;
|
||||
|
||||
while (true) {
|
||||
|
|
@ -212,8 +216,6 @@ process_events() {
|
|||
[_window update];
|
||||
}
|
||||
|
||||
[pool release];
|
||||
|
||||
if (_context_needs_update && _gsg != nullptr) {
|
||||
update_context();
|
||||
}
|
||||
|
|
@ -728,13 +730,12 @@ set_properties_now(WindowProperties &properties) {
|
|||
// here.
|
||||
if (!properties.has_undecorated() && !_properties.get_undecorated() &&
|
||||
[_window respondsToSelector:@selector(setStyleMask:)]) {
|
||||
if (properties.get_fixed_size()) {
|
||||
[_window setStyleMask:NSTitledWindowMask | NSClosableWindowMask |
|
||||
NSMiniaturizableWindowMask ];
|
||||
} else {
|
||||
[_window setStyleMask:NSTitledWindowMask | NSClosableWindowMask |
|
||||
NSMiniaturizableWindowMask | NSResizableWindowMask ];
|
||||
NSUInteger style = ([_window styleMask] & NSFullScreenWindowMask);
|
||||
style |= NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask;
|
||||
if (!properties.get_fixed_size()) {
|
||||
style |= NSResizableWindowMask;
|
||||
}
|
||||
[_window setStyleMask:style];
|
||||
[_window makeFirstResponder:_view];
|
||||
// Resize event fired by makeFirstResponder has an invalid backing scale factor
|
||||
// The actual size must be reset afterward
|
||||
|
|
@ -749,16 +750,14 @@ set_properties_now(WindowProperties &properties) {
|
|||
_properties.set_undecorated(properties.get_undecorated());
|
||||
|
||||
if (!_properties.get_fullscreen()) {
|
||||
if (properties.get_undecorated()) {
|
||||
[_window setStyleMask: NSBorderlessWindowMask];
|
||||
} else if (_properties.get_fixed_size()) {
|
||||
// Fixed size windows should not show the resize button.
|
||||
[_window setStyleMask: NSTitledWindowMask | NSClosableWindowMask |
|
||||
NSMiniaturizableWindowMask ];
|
||||
} else {
|
||||
[_window setStyleMask: NSTitledWindowMask | NSClosableWindowMask |
|
||||
NSMiniaturizableWindowMask | NSResizableWindowMask ];
|
||||
NSUInteger style = ([_window styleMask] & NSFullScreenWindowMask);
|
||||
if (!properties.get_undecorated()) {
|
||||
style |= NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask;
|
||||
if (!properties.get_fixed_size()) {
|
||||
style |= NSResizableWindowMask;
|
||||
}
|
||||
}
|
||||
[_window setStyleMask:style];
|
||||
[_window makeFirstResponder:_view];
|
||||
// Resize event fired by makeFirstResponder has an invalid backing scale factor
|
||||
// The actual size must be reset afterward
|
||||
|
|
@ -1176,10 +1175,16 @@ do_switch_fullscreen(CGDisplayModeRef mode) {
|
|||
}
|
||||
|
||||
if (_window != nil) {
|
||||
// Exit macOS' own fullscreen mode, since our own fullscreen mode
|
||||
// doesn't work properly with it.
|
||||
if ([_window styleMask] & NSFullScreenWindowMask) {
|
||||
[_window toggleFullScreen:nil];
|
||||
}
|
||||
|
||||
// For some reason, setting the style mask makes it give up its
|
||||
// first-responder status.
|
||||
if ([_window respondsToSelector:@selector(setStyleMask:)]) {
|
||||
[_window setStyleMask:NSBorderlessWindowMask];
|
||||
[_window setStyleMask:([_window styleMask] & NSFullScreenWindowMask)];
|
||||
}
|
||||
[_window makeFirstResponder:_view];
|
||||
[_window setLevel:CGShieldingWindowLevel()];
|
||||
|
|
|
|||
|
|
@ -16,11 +16,11 @@
|
|||
|
||||
@implementation CocoaPandaApp
|
||||
- (void) sendEvent: (NSEvent *) event {
|
||||
// This is a hack that allows us to receive cmd-key-up events correctly.
|
||||
// Also prevent it from eating the inserthelp key.
|
||||
if (([event type] == NSKeyUp && ([event modifierFlags] & NSCommandKeyMask))
|
||||
||([event type] == NSKeyDown && [event keyCode] == 0x72)) {
|
||||
|
||||
// This is a hack that allows us to receive cmd-key-up events correctly, as
|
||||
// well as key-up events during a full-screen transition.
|
||||
// Also prevent it from eating the insert/help key.
|
||||
if ([event type] == NSKeyUp ||
|
||||
([event type] == NSKeyDown && [event keyCode] == 0x72)) {
|
||||
[[self keyWindow] sendEvent: event];
|
||||
} else {
|
||||
[super sendEvent: event];
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue