mirror of
https://github.com/godotengine/godot-cpp.git
synced 2026-01-01 05:48:37 +03:00
Compare commits
110 Commits
godot-4.3-
...
4.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4bc6e67d51 | ||
|
|
b889fc3ce8 | ||
|
|
ef4c38418e | ||
|
|
9445595df2 | ||
|
|
71b5b84fb1 | ||
|
|
95a29550a7 | ||
|
|
f5fa712138 | ||
|
|
142e5d4302 | ||
|
|
c532b919df | ||
|
|
d42d913edd | ||
|
|
cb41b472f4 | ||
|
|
d8b46e3426 | ||
|
|
397669a3f6 | ||
|
|
17818534d9 | ||
|
|
549f5d6550 | ||
|
|
5f3a66a326 | ||
|
|
810b0ce13e | ||
|
|
a2a336546a | ||
|
|
5e7d2472dd | ||
|
|
6cb5eb9bca | ||
|
|
43c66817ea | ||
|
|
f8c258b3fe | ||
|
|
d06b0283c2 | ||
|
|
463a0feb28 | ||
|
|
4109e14f1b | ||
|
|
5d745add13 | ||
|
|
67e84c04f2 | ||
|
|
5921734784 | ||
|
|
fd31fabcfc | ||
|
|
9d26e3418c | ||
|
|
42d9ac3b08 | ||
|
|
f9095a5552 | ||
|
|
63c67a9977 | ||
|
|
12f6eecf65 | ||
|
|
deaf37120f | ||
|
|
cc70884db3 | ||
|
|
90e0c1515d | ||
|
|
13299e810b | ||
|
|
18321318bb | ||
|
|
806c38e189 | ||
|
|
aeb8be98ed | ||
|
|
1f9a0b7171 | ||
|
|
a0d56336c3 | ||
|
|
d6e5286cc1 | ||
|
|
80aec184df | ||
|
|
18c31e3e31 | ||
|
|
52ea8f9101 | ||
|
|
c35e7545b7 | ||
|
|
1a22e43075 | ||
|
|
121ae8d116 | ||
|
|
3bea67ce6c | ||
|
|
19f56af1be | ||
|
|
7f3e914c6d | ||
|
|
528b7801d2 | ||
|
|
9da6ecd144 | ||
|
|
c5204a2e84 | ||
|
|
a6e5caacf8 | ||
|
|
246fd4718c | ||
|
|
b81b0599f9 | ||
|
|
07b6a03d77 | ||
|
|
7e72c8bf0a | ||
|
|
f88b6a2f00 | ||
|
|
2b6eb6832e | ||
|
|
a246aaaaf6 | ||
|
|
e8e424ade8 | ||
|
|
18354f9b9b | ||
|
|
acee69a3f6 | ||
|
|
ddfcca62a8 | ||
|
|
8aef77a64d | ||
|
|
897280444b | ||
|
|
3d814f6e87 | ||
|
|
8f8ea90088 | ||
|
|
b28098e76b | ||
|
|
9afbdb9cf6 | ||
|
|
98c143a483 | ||
|
|
28d43fb99a | ||
|
|
77f1d228cd | ||
|
|
ab5b9f2ceb | ||
|
|
ef4d771444 | ||
|
|
66ced64c1e | ||
|
|
fc5366c026 | ||
|
|
7e5fa8e7a9 | ||
|
|
f8477fb9f2 | ||
|
|
ef723ca9ec | ||
|
|
7473b984cb | ||
|
|
98ad839827 | ||
|
|
a07b1f6e07 | ||
|
|
f002ca18c7 | ||
|
|
3fe7c2e87b | ||
|
|
7ddd278dea | ||
|
|
cae4bf58ac | ||
|
|
1517a24f72 | ||
|
|
1b8cfaab71 | ||
|
|
dc19986497 | ||
|
|
c2d4ccd592 | ||
|
|
51c752c46b | ||
|
|
45dc04f2cf | ||
|
|
dc76664cea | ||
|
|
97214ecd7a | ||
|
|
300e74364b | ||
|
|
3129672a4f | ||
|
|
c0b2d85ffc | ||
|
|
62eed50524 | ||
|
|
f9b66e3c72 | ||
|
|
81a72ff06b | ||
|
|
0472b6bdd4 | ||
|
|
aaffda23a5 | ||
|
|
78ffea5b13 | ||
|
|
f93a6c5a5b | ||
|
|
b03e56922d |
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -9,7 +9,7 @@ body:
|
||||
- Write a descriptive issue title above.
|
||||
- The golden rule is to **always open *one* issue for *one* bug**. If you notice several bugs and want to report them, make sure to create one new issue for each of them.
|
||||
- Search [open](https://github.com/godotengine/godot-cpp/issues) and [closed](https://github.com/godotengine/godot-cpp/issues?q=is%3Aissue+is%3Aclosed) issues to ensure it has not already been reported. If you don't find a relevant match or if you're unsure, don't hesitate to **open a new issue**. The bugsquad will handle it from there if it's a duplicate.
|
||||
- Verify that you are using a [supported Godot version](https://docs.godotengine.org/en/latest/about/release_policy.html).
|
||||
- Verify that you are using a [supported Godot version](https://docs.godotengine.org/en/stable/about/release_policy.html).
|
||||
|
||||
- type: input
|
||||
attributes:
|
||||
|
||||
25
.github/actions/godot-cache-restore/action.yml
vendored
25
.github/actions/godot-cache-restore/action.yml
vendored
@@ -3,19 +3,22 @@ description: Restore Godot build cache.
|
||||
inputs:
|
||||
cache-name:
|
||||
description: The cache base name (job name by default).
|
||||
default: "${{github.job}}"
|
||||
default: ${{ github.job }}
|
||||
scons-cache:
|
||||
description: The scons cache path.
|
||||
default: "${{github.workspace}}/.scons-cache/"
|
||||
description: The SCons cache path.
|
||||
default: ${{ github.workspace }}/.scons-cache/
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
using: composite
|
||||
steps:
|
||||
- name: Restore .scons_cache directory
|
||||
uses: actions/cache/restore@v3
|
||||
- name: Restore SCons cache directory
|
||||
uses: actions/cache/restore@v4
|
||||
with:
|
||||
path: ${{inputs.scons-cache}}
|
||||
key: ${{inputs.cache-name}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
|
||||
path: ${{ inputs.scons-cache }}
|
||||
key: ${{ inputs.cache-name }}-${{ env.GODOT_BASE_BRANCH }}-${{ github.ref }}-${{ github.sha }}
|
||||
|
||||
restore-keys: |
|
||||
${{inputs.cache-name}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
|
||||
${{inputs.cache-name}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}
|
||||
${{inputs.cache-name}}-${{env.GODOT_BASE_BRANCH}}
|
||||
${{ inputs.cache-name }}-${{ env.GODOT_BASE_BRANCH }}-${{ github.ref }}-${{ github.sha }}
|
||||
${{ inputs.cache-name }}-${{ env.GODOT_BASE_BRANCH }}-${{ github.ref }}
|
||||
${{ inputs.cache-name }}-${{ env.GODOT_BASE_BRANCH }}-refs/heads/${{ env.GODOT_BASE_BRANCH }}
|
||||
${{ inputs.cache-name }}-${{ env.GODOT_BASE_BRANCH }}
|
||||
|
||||
11
.github/actions/godot-cache-save/action.yml
vendored
11
.github/actions/godot-cache-save/action.yml
vendored
@@ -3,15 +3,16 @@ description: Save Godot build cache.
|
||||
inputs:
|
||||
cache-name:
|
||||
description: The cache base name (job name by default).
|
||||
default: "${{github.job}}"
|
||||
default: ${{ github.job }}
|
||||
scons-cache:
|
||||
description: The SCons cache path.
|
||||
default: "${{github.workspace}}/.scons-cache/"
|
||||
default: ${{ github.workspace }}/.scons-cache/
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
using: composite
|
||||
steps:
|
||||
- name: Save SCons cache directory
|
||||
uses: actions/cache/save@v4
|
||||
with:
|
||||
path: ${{inputs.scons-cache}}
|
||||
key: ${{inputs.cache-name}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
|
||||
path: ${{ inputs.scons-cache }}
|
||||
key: ${{ inputs.cache-name }}-${{ env.GODOT_BASE_BRANCH }}-${{ github.ref }}-${{ github.sha }}
|
||||
|
||||
62
.github/actions/setup-godot-cpp/action.yml
vendored
Normal file
62
.github/actions/setup-godot-cpp/action.yml
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
name: Setup godot-cpp
|
||||
description: Setup build dependencies for godot-cpp.
|
||||
|
||||
inputs:
|
||||
platform:
|
||||
required: true
|
||||
description: Target platform.
|
||||
em-version:
|
||||
default: 3.1.62
|
||||
description: Emscripten version.
|
||||
windows-compiler:
|
||||
required: true
|
||||
description: The compiler toolchain to use on Windows ('mingw' or 'msvc').
|
||||
type: choice
|
||||
options:
|
||||
- mingw
|
||||
- msvc
|
||||
default: mingw
|
||||
mingw-version:
|
||||
default: 12.2.0
|
||||
description: MinGW version.
|
||||
ndk-version:
|
||||
default: r23c
|
||||
description: Android NDK version.
|
||||
scons-version:
|
||||
default: 4.4.0
|
||||
description: SCons version.
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Setup Python (for SCons)
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
- name: Setup Android dependencies
|
||||
if: inputs.platform == 'android'
|
||||
uses: nttld/setup-ndk@v1
|
||||
with:
|
||||
ndk-version: ${{ inputs.ndk-version }}
|
||||
link-to-sdk: true
|
||||
|
||||
- name: Setup Web dependencies
|
||||
if: inputs.platform == 'web'
|
||||
uses: mymindstorm/setup-emsdk@v14
|
||||
with:
|
||||
version: ${{ inputs.em-version }}
|
||||
no-cache: true
|
||||
|
||||
- name: Setup MinGW for Windows/MinGW build
|
||||
if: inputs.platform == 'windows' && inputs.windows-compiler == 'mingw'
|
||||
uses: egor-tensin/setup-mingw@v2
|
||||
with:
|
||||
version: ${{ inputs.mingw-version }}
|
||||
|
||||
- name: Setup SCons
|
||||
shell: bash
|
||||
run: |
|
||||
python -c "import sys; print(sys.version)"
|
||||
python -m pip install scons==${{ inputs.scons-version }}
|
||||
scons --version
|
||||
53
.github/workflows/ci.yml
vendored
53
.github/workflows/ci.yml
vendored
@@ -1,14 +1,15 @@
|
||||
name: Continuous integration
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
env:
|
||||
# Only used for the cache key. Increment version to force clean build.
|
||||
GODOT_BASE_BRANCH: master
|
||||
# Used to select the version of Godot to run the tests with.
|
||||
GODOT_TEST_VERSION: master
|
||||
GODOT_TEST_VERSION: 4.2.2-stable
|
||||
|
||||
concurrency:
|
||||
group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}
|
||||
group: ci-${{ github.actor }}-${{ github.head_ref || github.run_number }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
@@ -91,7 +92,6 @@ jobs:
|
||||
env:
|
||||
SCONS_CACHE: ${{ github.workspace }}/.scons-cache/
|
||||
EM_VERSION: 3.1.39
|
||||
EM_CACHE_FOLDER: "emsdk-cache"
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
@@ -105,34 +105,11 @@ jobs:
|
||||
cache-name: ${{ matrix.cache-name }}
|
||||
continue-on-error: true
|
||||
|
||||
- name: Set up Python (for SCons)
|
||||
uses: actions/setup-python@v5
|
||||
- name: Setup godot-cpp
|
||||
uses: ./.github/actions/setup-godot-cpp
|
||||
with:
|
||||
python-version: '3.x'
|
||||
|
||||
- name: Android dependencies
|
||||
if: ${{ matrix.platform == 'android' }}
|
||||
uses: nttld/setup-ndk@v1
|
||||
with:
|
||||
ndk-version: r23c
|
||||
link-to-sdk: true
|
||||
|
||||
- name: Web dependencies
|
||||
if: ${{ matrix.platform == 'web' }}
|
||||
uses: mymindstorm/setup-emsdk@v14
|
||||
with:
|
||||
version: ${{env.EM_VERSION}}
|
||||
actions-cache-folder: ${{env.EM_CACHE_FOLDER}}
|
||||
|
||||
- name: Setup MinGW for Windows/MinGW build
|
||||
if: ${{ matrix.platform == 'windows' && matrix.flags == 'use_mingw=yes' }}
|
||||
uses: egor-tensin/setup-mingw@v2
|
||||
with:
|
||||
version: 12.2.0
|
||||
|
||||
- name: Install scons
|
||||
run: |
|
||||
python -m pip install scons==4.0.0
|
||||
platform: ${{ matrix.platform }}
|
||||
windows-compiler: ${{ contains(matrix.flags, 'use_mingw=yes') && 'mingw' || 'msvc' }}
|
||||
|
||||
- name: Generate godot-cpp sources only
|
||||
run: |
|
||||
@@ -161,7 +138,7 @@ jobs:
|
||||
|
||||
- name: Download latest Godot artifacts
|
||||
uses: dsnopek/action-download-artifact@1322f74e2dac9feed2ee76a32d9ae1ca3b4cf4e9
|
||||
if: ${{ matrix.run-tests && env.GODOT_TEST_VERSION == 'master' }}
|
||||
if: matrix.run-tests && env.GODOT_TEST_VERSION == 'master'
|
||||
with:
|
||||
repo: godotengine/godot
|
||||
branch: master
|
||||
@@ -175,13 +152,13 @@ jobs:
|
||||
path: godot-artifacts
|
||||
|
||||
- name: Prepare Godot artifacts for testing
|
||||
if: ${{ matrix.run-tests && env.GODOT_TEST_VERSION == 'master' }}
|
||||
if: matrix.run-tests && env.GODOT_TEST_VERSION == 'master'
|
||||
run: |
|
||||
chmod +x ./godot-artifacts/godot.linuxbsd.editor.x86_64.mono
|
||||
echo "GODOT=$(pwd)/godot-artifacts/godot.linuxbsd.editor.x86_64.mono" >> $GITHUB_ENV
|
||||
|
||||
- name: Download requested Godot version for testing
|
||||
if: ${{ matrix.run-tests && env.GODOT_TEST_VERSION != 'master' }}
|
||||
if: matrix.run-tests && env.GODOT_TEST_VERSION != 'master'
|
||||
run: |
|
||||
wget "https://github.com/godotengine/godot-builds/releases/download/${GODOT_TEST_VERSION}/Godot_v${GODOT_TEST_VERSION}_linux.x86_64.zip" -O Godot.zip
|
||||
unzip -a Godot.zip
|
||||
@@ -189,12 +166,12 @@ jobs:
|
||||
echo "GODOT=$(pwd)/Godot_v${GODOT_TEST_VERSION}_linux.x86_64" >> $GITHUB_ENV
|
||||
|
||||
- name: Run tests
|
||||
if: ${{ matrix.run-tests }}
|
||||
if: matrix.run-tests
|
||||
run: |
|
||||
$GODOT --headless --version
|
||||
cd test
|
||||
# Need to run the editor so .godot is generated... but it crashes! Ignore that :-)
|
||||
(cd project && (timeout 30 $GODOT --import --headless >/dev/null 2>&1 || true))
|
||||
(cd project && (timeout 30 $GODOT --editor --headless --quit >/dev/null 2>&1 || true))
|
||||
./run-tests.sh
|
||||
|
||||
- name: Upload artifact
|
||||
@@ -264,9 +241,9 @@ jobs:
|
||||
- name: Build godot-cpp
|
||||
run: |
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -G"Visual Studio 16 2019" .
|
||||
cmake --build . --verbose
|
||||
cmake --build . --verbose --config Release
|
||||
|
||||
- name: Build test GDExtension library
|
||||
run: |
|
||||
cd test && cmake -DCMAKE_BUILD_TYPE=Release -DGODOT_HEADERS_PATH="../godot-headers" -DCPP_BINDINGS_PATH=".." -G"Visual Studio 16 2019" .
|
||||
cmake --build . --verbose
|
||||
cmake --build . --verbose --config Release
|
||||
|
||||
21
.github/workflows/runner.yml
vendored
Normal file
21
.github/workflows/runner.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
name: 🔗 GHA
|
||||
on: [push, pull_request, merge_group]
|
||||
|
||||
concurrency:
|
||||
group: ci-${{ github.actor }}-${{ github.head_ref || github.run_number }}-${{ github.ref }}-runner
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
# First stage: Only static checks, fast and prevent expensive builds from running.
|
||||
|
||||
static-checks:
|
||||
if: '!vars.DISABLE_GODOT_CI'
|
||||
name: 📊 Static Checks
|
||||
uses: ./.github/workflows/static_checks.yml
|
||||
|
||||
# Second stage: Run all the builds and some of the tests.
|
||||
|
||||
ci:
|
||||
name: 🛠️ Continuous Integration
|
||||
needs: static-checks
|
||||
uses: ./.github/workflows/ci.yml
|
||||
9
.github/workflows/static_checks.yml
vendored
9
.github/workflows/static_checks.yml
vendored
@@ -1,8 +1,9 @@
|
||||
name: 📊 Static Checks
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
concurrency:
|
||||
group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-static
|
||||
group: ci-${{ github.actor }}-${{ github.head_ref || github.run_number }}-${{ github.ref }}-static
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
@@ -31,3 +32,7 @@ jobs:
|
||||
uses: pre-commit/action@v3.0.1
|
||||
with:
|
||||
extra_args: --verbose --hook-stage manual --files ${{ env.CHANGED_FILES }}
|
||||
|
||||
- name: Check generated files consistency
|
||||
run:
|
||||
python misc/scripts/check_get_file_list.py
|
||||
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -195,3 +195,7 @@ compile_commands.json
|
||||
# Python development
|
||||
.venv
|
||||
venv
|
||||
|
||||
# Clion Configuration
|
||||
.idea/
|
||||
cmake-build-*
|
||||
|
||||
234
CMakeLists.txt
234
CMakeLists.txt
@@ -1,228 +1,24 @@
|
||||
# cmake arguments
|
||||
# CMAKE_BUILD_TYPE: Compilation target (Debug or Release defaults to Debug)
|
||||
#
|
||||
# godot-cpp cmake arguments
|
||||
# GODOT_GDEXTENSION_DIR: Path to the directory containing GDExtension interface header and API JSON file
|
||||
# GODOT_CPP_SYSTEM_HEADERS Mark the header files as SYSTEM. This may be useful to suppress warnings in projects including this one.
|
||||
# GODOT_CPP_WARNING_AS_ERROR Treat any warnings as errors
|
||||
# GODOT_ENABLE_HOT_RELOAD Build with hot reload support. Defaults to YES for Debug-builds and NO for Release-builds.
|
||||
# GODOT_CUSTOM_API_FILE: Path to a custom GDExtension API JSON file (takes precedence over `gdextension_dir`)
|
||||
# FLOAT_PRECISION: Floating-point precision level ("single", "double")
|
||||
#
|
||||
# Android cmake arguments
|
||||
# CMAKE_TOOLCHAIN_FILE: The path to the android cmake toolchain ($ANDROID_NDK/build/cmake/android.toolchain.cmake)
|
||||
# ANDROID_NDK: The path to the android ndk root folder
|
||||
# ANDROID_TOOLCHAIN_NAME: The android toolchain (arm-linux-androideabi-4.9 or aarch64-linux-android-4.9 or x86-4.9 or x86_64-4.9)
|
||||
# ANDROID_PLATFORM: The android platform version (android-23)
|
||||
# More info here: https://godot.readthedocs.io/en/latest/development/compiling/compiling_for_android.html
|
||||
#
|
||||
# Examples
|
||||
#
|
||||
# Builds a debug version:
|
||||
# cmake .
|
||||
# cmake --build .
|
||||
#
|
||||
# Builds a release version with clang
|
||||
# CC=/usr/bin/clang CXX=/usr/bin/clang++ cmake -DCMAKE_BUILD_TYPE=Release -G "Unix Makefiles" .
|
||||
# cmake --build .
|
||||
#
|
||||
# Builds an android armeabi-v7a debug version:
|
||||
# cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake -DANDROID_NDK=$ANDROID_NDK \
|
||||
# -DANDROID_TOOLCHAIN_NAME=arm-linux-androideabi-4.9 -DANDROID_PLATFORM=android-23 -DCMAKE_BUILD_TYPE=Debug .
|
||||
# cmake --build .
|
||||
#
|
||||
# Protip
|
||||
# Generate the buildfiles in a sub directory to not clutter the root directory with build files:
|
||||
# mkdir build && cd build && cmake -G "Unix Makefiles" .. && cmake --build .
|
||||
#
|
||||
# Todo
|
||||
# Test build for Windows, Mac and mingw.
|
||||
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
project(godot-cpp LANGUAGES CXX)
|
||||
|
||||
option(GENERATE_TEMPLATE_GET_NODE "Generate a template version of the Node class's get_node." ON)
|
||||
option(GODOT_CPP_SYSTEM_HEADERS "Expose headers as SYSTEM." ON)
|
||||
option(GODOT_CPP_WARNING_AS_ERROR "Treat warnings as errors" OFF)
|
||||
|
||||
# Add path to modules
|
||||
list( APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/" )
|
||||
|
||||
# Set some helper variables for readability
|
||||
set( compiler_is_clang "$<OR:$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:Clang>>" )
|
||||
set( compiler_is_gnu "$<CXX_COMPILER_ID:GNU>" )
|
||||
set( compiler_is_msvc "$<CXX_COMPILER_ID:MSVC>" )
|
||||
|
||||
# Default build type is Debug in the SConstruct
|
||||
if("${CMAKE_BUILD_TYPE}" STREQUAL "")
|
||||
set(CMAKE_BUILD_TYPE Debug)
|
||||
endif()
|
||||
|
||||
# Hot reload is enabled by default in Debug-builds
|
||||
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
|
||||
option(GODOT_ENABLE_HOT_RELOAD "Build with hot reload support" ON)
|
||||
else()
|
||||
option(GODOT_ENABLE_HOT_RELOAD "Build with hot reload support" OFF)
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED BITS)
|
||||
set(BITS 32)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(BITS 64)
|
||||
endif(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
endif()
|
||||
|
||||
# Input from user for GDExtension interface header and the API JSON file
|
||||
set(GODOT_GDEXTENSION_DIR "gdextension" CACHE STRING "")
|
||||
set(GODOT_CUSTOM_API_FILE "" CACHE STRING "")
|
||||
|
||||
set(GODOT_GDEXTENSION_API_FILE "${GODOT_GDEXTENSION_DIR}/extension_api.json")
|
||||
if (NOT "${GODOT_CUSTOM_API_FILE}" STREQUAL "") # User-defined override.
|
||||
set(GODOT_GDEXTENSION_API_FILE "${GODOT_CUSTOM_API_FILE}")
|
||||
endif()
|
||||
|
||||
set(FLOAT_PRECISION "single" CACHE STRING "")
|
||||
if ("${FLOAT_PRECISION}" STREQUAL "double")
|
||||
add_definitions(-DREAL_T_IS_DOUBLE)
|
||||
endif()
|
||||
|
||||
set(GODOT_COMPILE_FLAGS )
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||
# using Visual Studio C++
|
||||
set(GODOT_COMPILE_FLAGS "/utf-8") # /GF /MP
|
||||
|
||||
if(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /MDd") # /Od /RTC1 /Zi
|
||||
else()
|
||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /MD /O2") # /Oy /GL /Gy
|
||||
STRING(REGEX REPLACE "/RTC(su|[1su])" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
string(REPLACE "/RTC1" "" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
|
||||
endif(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
|
||||
add_definitions(-DNOMINMAX)
|
||||
else() # GCC/Clang
|
||||
if(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -fno-omit-frame-pointer -O0 -g")
|
||||
else()
|
||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -O3")
|
||||
endif(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
endif()
|
||||
|
||||
# Disable exception handling. Godot doesn't use exceptions anywhere, and this
|
||||
# saves around 20% of binary size and very significant build time (GH-80513).
|
||||
option(GODOT_DISABLE_EXCEPTIONS ON "Force disabling exception handling code")
|
||||
if (GODOT_DISABLE_EXCEPTIONS)
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -D_HAS_EXCEPTIONS=0")
|
||||
else()
|
||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -fno-exceptions")
|
||||
endif()
|
||||
else()
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /EHsc")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (GODOT_ENABLE_HOT_RELOAD)
|
||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -D HOT_RELOAD_ENABLED")
|
||||
endif()
|
||||
|
||||
# Generate source from the bindings file
|
||||
find_package(Python3 3.4 REQUIRED) # pathlib should be present
|
||||
if(GENERATE_TEMPLATE_GET_NODE)
|
||||
set(GENERATE_BINDING_PARAMETERS "True")
|
||||
else()
|
||||
set(GENERATE_BINDING_PARAMETERS "False")
|
||||
endif()
|
||||
|
||||
execute_process(COMMAND "${Python3_EXECUTABLE}" "-c" "import binding_generator; binding_generator.print_file_list(\"${GODOT_GDEXTENSION_API_FILE}\", \"${CMAKE_CURRENT_BINARY_DIR}\", headers=True, sources=True)"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE GENERATED_FILES_LIST
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
add_custom_command(OUTPUT ${GENERATED_FILES_LIST}
|
||||
COMMAND "${Python3_EXECUTABLE}" "-c" "import binding_generator; binding_generator.generate_bindings(\"${GODOT_GDEXTENSION_API_FILE}\", \"${GENERATE_BINDING_PARAMETERS}\", \"${BITS}\", \"${FLOAT_PRECISION}\", \"${CMAKE_CURRENT_BINARY_DIR}\")"
|
||||
VERBATIM
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
MAIN_DEPENDENCY ${GODOT_GDEXTENSION_API_FILE}
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/binding_generator.py
|
||||
COMMENT "Generating bindings"
|
||||
)
|
||||
|
||||
# Get Sources
|
||||
file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS src/*.c**)
|
||||
file(GLOB_RECURSE HEADERS CONFIGURE_DEPENDS include/*.h**)
|
||||
|
||||
# Define our godot-cpp library
|
||||
add_library(${PROJECT_NAME} STATIC
|
||||
${SOURCES}
|
||||
${HEADERS}
|
||||
${GENERATED_FILES_LIST}
|
||||
)
|
||||
add_library(godot::cpp ALIAS ${PROJECT_NAME})
|
||||
|
||||
include(GodotCompilerWarnings)
|
||||
|
||||
target_compile_features(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
cxx_std_17
|
||||
)
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME} PUBLIC
|
||||
$<$<CONFIG:Debug>:
|
||||
DEBUG_ENABLED
|
||||
DEBUG_METHODS_ENABLED
|
||||
>
|
||||
$<${compiler_is_msvc}:
|
||||
TYPED_METHOD_BIND
|
||||
>
|
||||
)
|
||||
|
||||
target_link_options(${PROJECT_NAME} PRIVATE
|
||||
$<$<NOT:${compiler_is_msvc}>:
|
||||
-static-libgcc
|
||||
-static-libstdc++
|
||||
-Wl,-R,'$$ORIGIN'
|
||||
>
|
||||
)
|
||||
|
||||
# Optionally mark headers as SYSTEM
|
||||
set(GODOT_CPP_SYSTEM_HEADERS_ATTRIBUTE "")
|
||||
if (GODOT_CPP_SYSTEM_HEADERS)
|
||||
set(GODOT_CPP_SYSTEM_HEADERS_ATTRIBUTE SYSTEM)
|
||||
# Configure CMake
|
||||
# https://discourse.cmake.org/t/how-do-i-remove-compile-options-from-target/5965
|
||||
# https://stackoverflow.com/questions/74426638/how-to-remove-rtc1-from-specific-target-or-file-in-cmake
|
||||
if(${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC)
|
||||
if(NOT CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
STRING(REGEX REPLACE "/RTC(su|[1su])" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
string(REPLACE "/RTC1" "" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
target_include_directories(${PROJECT_NAME} ${GODOT_CPP_SYSTEM_HEADERS_ATTRIBUTE} PUBLIC
|
||||
include
|
||||
${CMAKE_CURRENT_BINARY_DIR}/gen/include
|
||||
${GODOT_GDEXTENSION_DIR}
|
||||
)
|
||||
include( ${PROJECT_SOURCE_DIR}/cmake/godotcpp.cmake )
|
||||
|
||||
# Add the compile flags
|
||||
set_property(TARGET ${PROJECT_NAME} APPEND_STRING PROPERTY COMPILE_FLAGS ${GODOT_COMPILE_FLAGS})
|
||||
# I know this doesn't look like a typical CMakeLists.txt, but as we are
|
||||
# attempting mostly feature parity with SCons, and easy maintenance, the closer
|
||||
# the two build systems look the easier they will be to keep in lockstep.
|
||||
|
||||
# Create the correct name (godot.os.build_type.system_bits)
|
||||
string(TOLOWER "${CMAKE_SYSTEM_NAME}" SYSTEM_NAME)
|
||||
string(TOLOWER "${CMAKE_BUILD_TYPE}" BUILD_TYPE)
|
||||
# The typical target definitions are in ${PROJECT_SOURCE_DIR}/cmake/godotcpp.cmake
|
||||
|
||||
if(ANDROID)
|
||||
# Added the android abi after system name
|
||||
set(SYSTEM_NAME ${SYSTEM_NAME}.${ANDROID_ABI})
|
||||
godotcpp_options()
|
||||
|
||||
# Android does not have the bits at the end if you look at the main godot repo build
|
||||
set(OUTPUT_NAME "godot-cpp.${SYSTEM_NAME}.${BUILD_TYPE}")
|
||||
else()
|
||||
set(OUTPUT_NAME "godot-cpp.${SYSTEM_NAME}.${BUILD_TYPE}.${BITS}")
|
||||
endif()
|
||||
|
||||
set_target_properties(${PROJECT_NAME}
|
||||
PROPERTIES
|
||||
CXX_EXTENSIONS OFF
|
||||
POSITION_INDEPENDENT_CODE ON
|
||||
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin"
|
||||
OUTPUT_NAME "${OUTPUT_NAME}"
|
||||
)
|
||||
godotcpp_generate()
|
||||
|
||||
29
README.md
29
README.md
@@ -1,6 +1,6 @@
|
||||
# godot-cpp
|
||||
|
||||
> [!WARNING]
|
||||
> **Warning**
|
||||
>
|
||||
> This repository's `master` branch is only usable with
|
||||
> [GDExtension](https://godotengine.org/article/introducing-gd-extensions)
|
||||
@@ -22,7 +22,7 @@ This repository contains the *C++ bindings* for the [**Godot Engine**](https://
|
||||
- [**Compatibility**](#compatibility)
|
||||
- [**Contributing**](#contributing)
|
||||
- [**Getting started**](#getting-started)
|
||||
- [**Examples and templates**](#examples-and-templates)
|
||||
- [**Included example**](#included-example)
|
||||
|
||||
## Versioning
|
||||
|
||||
@@ -49,20 +49,18 @@ Godot version.**
|
||||
|
||||
## Compatibility
|
||||
|
||||
> [!WARNING]
|
||||
>
|
||||
> The GDExtension API is brand new in Godot 4.0, and is still
|
||||
**Warning:** The GDExtension API is brand new in Godot 4.0, and is still
|
||||
considered in **beta** stage, despite Godot 4.0 itself being released.
|
||||
>
|
||||
> This applies to both the GDExtension interface header, the API JSON, and this
|
||||
|
||||
This applies to both the GDExtension interface header, the API JSON, and this
|
||||
first-party `godot-cpp` extension.
|
||||
>
|
||||
> Some compatibility breakage is to be expected as GDExtension and `godot-cpp`
|
||||
> get more used, documented, and critical issues get resolved. See the
|
||||
> [Godot issue tracker](https://github.com/godotengine/godot/issues?q=is%3Aissue+is%3Aopen+label%3Atopic%3Agdextension)
|
||||
> and the [godot-cpp issue tracker](https://github.com/godotengine/godot-cpp/issues)
|
||||
> for a list of known issues, and be sure to provide feedback on issues and PRs
|
||||
> which affect your use of this extension.
|
||||
|
||||
Some compatibility breakage is to be expected as GDExtension and `godot-cpp`
|
||||
get more used, documented, and critical issues get resolved. See the
|
||||
[Godot issue tracker](https://github.com/godotengine/godot/issues?q=is%3Aissue+is%3Aopen+label%3Atopic%3Agdextension)
|
||||
and the [godot-cpp issue tracker](https://github.com/godotengine/godot-cpp/issues)
|
||||
for a list of known issues, and be sure to provide feedback on issues and PRs
|
||||
which affect your use of this extension.
|
||||
|
||||
## Contributing
|
||||
|
||||
@@ -71,8 +69,7 @@ wish to help out, ensure you have an account on GitHub and create a "fork" of
|
||||
this repository. See [Pull request workflow](https://docs.godotengine.org/en/stable/community/contributing/pr_workflow.html)
|
||||
for instructions.
|
||||
|
||||
Please install clang-format and copy the files in `misc/hooks` into `.git/hooks`
|
||||
so formatting is done before your changes are submitted.
|
||||
Please install clang-format and the [pre-commit](https://pre-commit.com/) Python framework so formatting is done before your changes are submitted. See the [code style guidelines](https://docs.godotengine.org/en/latest/contributing/development/code_style_guidelines.html#pre-commit-hook) for instructions.
|
||||
|
||||
## Getting started
|
||||
|
||||
|
||||
@@ -70,147 +70,22 @@ def generate_wrappers(target):
|
||||
f.write(txt)
|
||||
|
||||
|
||||
def generate_virtual_version(argcount, const=False, returns=False):
|
||||
s = """#define GDVIRTUAL$VER($RET m_name $ARG)\\
|
||||
::godot::StringName _gdvirtual_##m_name##_sn = #m_name;\\
|
||||
template <bool required>\\
|
||||
_FORCE_INLINE_ bool _gdvirtual_##m_name##_call($CALLARGS) $CONST {\\
|
||||
if (::godot::internal::gdextension_interface_object_has_script_method(_owner, &_gdvirtual_##m_name##_sn)) { \\
|
||||
GDExtensionCallError ce;\\
|
||||
$CALLSIARGS\\
|
||||
::godot::Variant ret;\\
|
||||
::godot::internal::gdextension_interface_object_call_script_method(_owner, &_gdvirtual_##m_name##_sn, $CALLSIARGPASS, &ret, &ce);\\
|
||||
if (ce.error == GDEXTENSION_CALL_OK) {\\
|
||||
$CALLSIRET\\
|
||||
return true;\\
|
||||
}\\
|
||||
}\\
|
||||
if (required) {\\
|
||||
ERR_PRINT_ONCE("Required virtual method " + get_class() + "::" + #m_name + " must be overridden before calling.");\\
|
||||
$RVOID\\
|
||||
}\\
|
||||
return false;\\
|
||||
}\\
|
||||
_FORCE_INLINE_ bool _gdvirtual_##m_name##_overridden() const {\\
|
||||
return ::godot::internal::gdextension_interface_object_has_script_method(_owner, &_gdvirtual_##m_name##_sn); \\
|
||||
}\\
|
||||
_FORCE_INLINE_ static ::godot::MethodInfo _gdvirtual_##m_name##_get_method_info() {\\
|
||||
::godot::MethodInfo method_info;\\
|
||||
method_info.name = #m_name;\\
|
||||
method_info.flags = $METHOD_FLAGS;\\
|
||||
$FILL_METHOD_INFO\\
|
||||
return method_info;\\
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
sproto = str(argcount)
|
||||
method_info = ""
|
||||
if returns:
|
||||
sproto += "R"
|
||||
s = s.replace("$RET", "m_ret,")
|
||||
s = s.replace("$RVOID", "(void)r_ret;") # If required, may lead to uninitialized errors
|
||||
method_info += "method_info.return_val = ::godot::GetTypeInfo<m_ret>::get_class_info();\\\n"
|
||||
method_info += "\t\tmethod_info.return_val_metadata = ::godot::GetTypeInfo<m_ret>::METADATA;"
|
||||
else:
|
||||
s = s.replace("$RET ", "")
|
||||
s = s.replace("\t\t\t$RVOID\\\n", "")
|
||||
|
||||
if const:
|
||||
sproto += "C"
|
||||
s = s.replace("$CONST", "const")
|
||||
s = s.replace("$METHOD_FLAGS", "::godot::METHOD_FLAG_VIRTUAL | ::godot::METHOD_FLAG_CONST")
|
||||
else:
|
||||
s = s.replace("$CONST ", "")
|
||||
s = s.replace("$METHOD_FLAGS", "::godot::METHOD_FLAG_VIRTUAL")
|
||||
|
||||
s = s.replace("$VER", sproto)
|
||||
argtext = ""
|
||||
callargtext = ""
|
||||
callsiargs = ""
|
||||
callsiargptrs = ""
|
||||
if argcount > 0:
|
||||
argtext += ", "
|
||||
callsiargs = f"::godot::Variant vargs[{argcount}] = {{ "
|
||||
callsiargptrs = f"\t\t\tconst ::godot::Variant *vargptrs[{argcount}] = {{ "
|
||||
for i in range(argcount):
|
||||
if i > 0:
|
||||
argtext += ", "
|
||||
callargtext += ", "
|
||||
callsiargs += ", "
|
||||
callsiargptrs += ", "
|
||||
argtext += f"m_type{i + 1}"
|
||||
callargtext += f"m_type{i + 1} arg{i + 1}"
|
||||
callsiargs += f"::godot::Variant(arg{i + 1})"
|
||||
callsiargptrs += f"&vargs[{i}]"
|
||||
if method_info:
|
||||
method_info += "\\\n\t\t"
|
||||
method_info += f"method_info.arguments.push_back(::godot::GetTypeInfo<m_type{i + 1}>::get_class_info());\\\n"
|
||||
method_info += f"\t\tmethod_info.arguments_metadata.push_back(::godot::GetTypeInfo<m_type{i + 1}>::METADATA);"
|
||||
|
||||
if argcount:
|
||||
callsiargs += " };\\\n"
|
||||
callsiargptrs += " };"
|
||||
s = s.replace("$CALLSIARGS", callsiargs + callsiargptrs)
|
||||
s = s.replace("$CALLSIARGPASS", f"(const GDExtensionConstVariantPtr *)vargptrs, {argcount}")
|
||||
else:
|
||||
s = s.replace("\t\t\t$CALLSIARGS\\\n", "")
|
||||
s = s.replace("$CALLSIARGPASS", "nullptr, 0")
|
||||
|
||||
if returns:
|
||||
if argcount > 0:
|
||||
callargtext += ", "
|
||||
callargtext += "m_ret &r_ret"
|
||||
s = s.replace("$CALLSIRET", "r_ret = ::godot::VariantCaster<m_ret>::cast(ret);")
|
||||
else:
|
||||
s = s.replace("\t\t\t\t$CALLSIRET\\\n", "")
|
||||
|
||||
s = s.replace(" $ARG", argtext)
|
||||
s = s.replace("$CALLARGS", callargtext)
|
||||
if method_info:
|
||||
s = s.replace("$FILL_METHOD_INFO", method_info)
|
||||
else:
|
||||
s = s.replace("\t\t$FILL_METHOD_INFO\\\n", method_info)
|
||||
|
||||
return s
|
||||
|
||||
|
||||
def generate_virtuals(target):
|
||||
max_versions = 12
|
||||
|
||||
txt = """/* THIS FILE IS GENERATED DO NOT EDIT */
|
||||
#ifndef GDEXTENSION_GDVIRTUAL_GEN_H
|
||||
#define GDEXTENSION_GDVIRTUAL_GEN_H
|
||||
|
||||
"""
|
||||
|
||||
for i in range(max_versions + 1):
|
||||
txt += f"/* {i} Arguments */\n\n"
|
||||
txt += generate_virtual_version(i, False, False)
|
||||
txt += generate_virtual_version(i, False, True)
|
||||
txt += generate_virtual_version(i, True, False)
|
||||
txt += generate_virtual_version(i, True, True)
|
||||
|
||||
txt += "#endif // GDEXTENSION_GDVIRTUAL_GEN_H\n"
|
||||
|
||||
with open(target, "w", encoding="utf-8") as f:
|
||||
f.write(txt)
|
||||
|
||||
|
||||
def get_file_list(api_filepath, output_dir, headers=False, sources=False, profile_filepath=""):
|
||||
api = {}
|
||||
files = []
|
||||
with open(api_filepath, encoding="utf-8") as api_file:
|
||||
api = json.load(api_file)
|
||||
|
||||
build_profile = parse_build_profile(profile_filepath, api)
|
||||
return _get_file_list(api, output_dir, headers, sources)
|
||||
|
||||
|
||||
def _get_file_list(api, output_dir, headers=False, sources=False):
|
||||
files = []
|
||||
|
||||
core_gen_folder = Path(output_dir) / "gen" / "include" / "godot_cpp" / "core"
|
||||
include_gen_folder = Path(output_dir) / "gen" / "include" / "godot_cpp"
|
||||
source_gen_folder = Path(output_dir) / "gen" / "src"
|
||||
|
||||
files.append(str((core_gen_folder / "ext_wrappers.gen.inc").as_posix()))
|
||||
files.append(str((core_gen_folder / "gdvirtual.gen.inc").as_posix()))
|
||||
|
||||
for builtin_class in api["builtin_classes"]:
|
||||
if is_pod_type(builtin_class["name"]):
|
||||
@@ -235,7 +110,7 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False, profil
|
||||
source_filename = source_gen_folder / "classes" / (camel_to_snake(engine_class["name"]) + ".cpp")
|
||||
if headers:
|
||||
files.append(str(header_filename.as_posix()))
|
||||
if sources and is_class_included(engine_class["name"], build_profile):
|
||||
if sources:
|
||||
files.append(str(source_filename.as_posix()))
|
||||
|
||||
for native_struct in api["native_structures"]:
|
||||
@@ -267,128 +142,19 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False, profil
|
||||
return files
|
||||
|
||||
|
||||
def print_file_list(api_filepath, output_dir, headers=False, sources=False, profile_filepath=""):
|
||||
print(*get_file_list(api_filepath, output_dir, headers, sources, profile_filepath), sep=";", end=None)
|
||||
|
||||
|
||||
def parse_build_profile(profile_filepath, api):
|
||||
if profile_filepath == "":
|
||||
return {}
|
||||
print("Using feature build profile: " + profile_filepath)
|
||||
|
||||
with open(profile_filepath, encoding="utf-8") as profile_file:
|
||||
profile = json.load(profile_file)
|
||||
|
||||
api_dict = {}
|
||||
parents = {}
|
||||
children = {}
|
||||
for engine_class in api["classes"]:
|
||||
api_dict[engine_class["name"]] = engine_class
|
||||
parent = engine_class.get("inherits", "")
|
||||
child = engine_class["name"]
|
||||
parents[child] = parent
|
||||
if parent == "":
|
||||
continue
|
||||
children[parent] = children.get(parent, [])
|
||||
children[parent].append(child)
|
||||
|
||||
# Parse methods dependencies
|
||||
deps = {}
|
||||
reverse_deps = {}
|
||||
for name, engine_class in api_dict.items():
|
||||
ref_cls = set()
|
||||
for method in engine_class.get("methods", []):
|
||||
rtype = method.get("return_value", {}).get("type", "")
|
||||
args = [a["type"] for a in method.get("arguments", [])]
|
||||
if rtype in api_dict:
|
||||
ref_cls.add(rtype)
|
||||
elif is_enum(rtype) and get_enum_class(rtype) in api_dict:
|
||||
ref_cls.add(get_enum_class(rtype))
|
||||
for arg in args:
|
||||
if arg in api_dict:
|
||||
ref_cls.add(arg)
|
||||
elif is_enum(arg) and get_enum_class(arg) in api_dict:
|
||||
ref_cls.add(get_enum_class(arg))
|
||||
deps[engine_class["name"]] = set(filter(lambda x: x != name, ref_cls))
|
||||
for acls in ref_cls:
|
||||
if acls == name:
|
||||
continue
|
||||
reverse_deps[acls] = reverse_deps.get(acls, set())
|
||||
reverse_deps[acls].add(name)
|
||||
|
||||
included = []
|
||||
front = list(profile.get("enabled_classes", []))
|
||||
if front:
|
||||
# These must always be included
|
||||
front.append("WorkerThreadPool")
|
||||
front.append("ClassDB")
|
||||
front.append("ClassDBSingleton")
|
||||
while front:
|
||||
cls = front.pop()
|
||||
if cls in included:
|
||||
continue
|
||||
included.append(cls)
|
||||
parent = parents.get(cls, "")
|
||||
if parent:
|
||||
front.append(parent)
|
||||
for rcls in deps.get(cls, set()):
|
||||
if rcls in included or rcls in front:
|
||||
continue
|
||||
front.append(rcls)
|
||||
|
||||
excluded = []
|
||||
front = list(profile.get("disabled_classes", []))
|
||||
while front:
|
||||
cls = front.pop()
|
||||
if cls in excluded:
|
||||
continue
|
||||
excluded.append(cls)
|
||||
front += children.get(cls, [])
|
||||
for rcls in reverse_deps.get(cls, set()):
|
||||
if rcls in excluded or rcls in front:
|
||||
continue
|
||||
front.append(rcls)
|
||||
|
||||
if included and excluded:
|
||||
print(
|
||||
"WARNING: Cannot specify both 'enabled_classes' and 'disabled_classes' in build profile. 'disabled_classes' will be ignored."
|
||||
)
|
||||
|
||||
return {
|
||||
"enabled_classes": included,
|
||||
"disabled_classes": excluded,
|
||||
}
|
||||
|
||||
|
||||
def scons_emit_files(target, source, env):
|
||||
profile_filepath = env.get("build_profile", "")
|
||||
if profile_filepath and not Path(profile_filepath).is_absolute():
|
||||
profile_filepath = str((Path(env.Dir("#").abspath) / profile_filepath).as_posix())
|
||||
|
||||
files = [env.File(f) for f in get_file_list(str(source[0]), target[0].abspath, True, True, profile_filepath)]
|
||||
env.Clean(target, files)
|
||||
env["godot_cpp_gen_dir"] = target[0].abspath
|
||||
return files, source
|
||||
|
||||
|
||||
def scons_generate_bindings(target, source, env):
|
||||
generate_bindings(
|
||||
str(source[0]),
|
||||
env["generate_template_get_node"],
|
||||
"32" if "32" in env["arch"] else "64",
|
||||
env["precision"],
|
||||
env["godot_cpp_gen_dir"],
|
||||
)
|
||||
return None
|
||||
def print_file_list(api_filepath, output_dir, headers=False, sources=False):
|
||||
print(*get_file_list(api_filepath, output_dir, headers, sources), sep=";", end=None)
|
||||
|
||||
|
||||
def generate_bindings(api_filepath, use_template_get_node, bits="64", precision="single", output_dir="."):
|
||||
api = None
|
||||
|
||||
target_dir = Path(output_dir) / "gen"
|
||||
|
||||
api = {}
|
||||
with open(api_filepath, encoding="utf-8") as api_file:
|
||||
api = json.load(api_file)
|
||||
_generate_bindings(api, use_template_get_node, bits, precision, output_dir)
|
||||
|
||||
|
||||
def _generate_bindings(api, use_template_get_node, bits="64", precision="single", output_dir="."):
|
||||
target_dir = Path(output_dir) / "gen"
|
||||
|
||||
shutil.rmtree(target_dir, ignore_errors=True)
|
||||
target_dir.mkdir(parents=True)
|
||||
@@ -431,7 +197,6 @@ def generate_builtin_bindings(api, output_dir, build_config):
|
||||
source_gen_folder.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
generate_wrappers(core_gen_folder / "ext_wrappers.gen.inc")
|
||||
generate_virtuals(core_gen_folder / "gdvirtual.gen.inc")
|
||||
|
||||
# Store types beforehand.
|
||||
for builtin_api in api["builtin_classes"]:
|
||||
@@ -542,8 +307,14 @@ def generate_builtin_bindings(api, output_dir, build_config):
|
||||
|
||||
builtin_header.append("")
|
||||
|
||||
includes = []
|
||||
for builtin in builtin_classes:
|
||||
builtin_header.append(f"#include <godot_cpp/variant/{camel_to_snake(builtin)}.hpp>")
|
||||
includes.append(f"godot_cpp/variant/{camel_to_snake(builtin)}.hpp")
|
||||
|
||||
includes.sort()
|
||||
|
||||
for include in includes:
|
||||
builtin_header.append(f"#include <{include}>")
|
||||
|
||||
builtin_header.append("")
|
||||
|
||||
@@ -599,11 +370,10 @@ def generate_builtin_class_vararg_method_implements_header(builtin_classes):
|
||||
continue
|
||||
|
||||
result += make_varargs_template(
|
||||
method, "is_static" in method and method["is_static"], class_name, False, False, True
|
||||
method, "is_static" in method and method["is_static"], class_name, False, True
|
||||
)
|
||||
result.append("")
|
||||
|
||||
result.append("")
|
||||
result.append(f"#endif // ! {header_guard}")
|
||||
|
||||
return "\n".join(result)
|
||||
@@ -628,38 +398,50 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
|
||||
|
||||
# Special cases.
|
||||
if class_name == "String":
|
||||
result.append("#include <godot_cpp/classes/global_constants.hpp>")
|
||||
result.append("#include <godot_cpp/variant/char_string.hpp>")
|
||||
result.append("#include <godot_cpp/variant/char_utils.hpp>")
|
||||
result.append("#include <godot_cpp/classes/global_constants.hpp>")
|
||||
result.append("")
|
||||
|
||||
if class_name == "PackedStringArray":
|
||||
result.append("#include <godot_cpp/variant/string.hpp>")
|
||||
result.append("")
|
||||
if class_name == "PackedColorArray":
|
||||
result.append("#include <godot_cpp/variant/color.hpp>")
|
||||
result.append("")
|
||||
if class_name == "PackedVector2Array":
|
||||
result.append("#include <godot_cpp/variant/vector2.hpp>")
|
||||
result.append("")
|
||||
if class_name == "PackedVector3Array":
|
||||
result.append("#include <godot_cpp/variant/vector3.hpp>")
|
||||
if class_name == "PackedVector4Array":
|
||||
result.append("#include <godot_cpp/variant/vector4.hpp>")
|
||||
result.append("")
|
||||
|
||||
if is_packed_array(class_name):
|
||||
result.append("#include <godot_cpp/core/error_macros.hpp>")
|
||||
result.append("#include <initializer_list>")
|
||||
result.append("")
|
||||
|
||||
if class_name == "Array":
|
||||
result.append("#include <godot_cpp/variant/array_helpers.hpp>")
|
||||
result.append("")
|
||||
|
||||
if class_name == "Callable":
|
||||
result.append("#include <godot_cpp/variant/callable_custom.hpp>")
|
||||
|
||||
for include in fully_used_classes:
|
||||
if include == "TypedArray":
|
||||
result.append("#include <godot_cpp/variant/typed_array.hpp>")
|
||||
else:
|
||||
result.append(f"#include <godot_cpp/{get_include_path(include)}>")
|
||||
result.append("")
|
||||
|
||||
if len(fully_used_classes) > 0:
|
||||
includes = []
|
||||
for include in fully_used_classes:
|
||||
if include == "TypedArray":
|
||||
includes.append("godot_cpp/variant/typed_array.hpp")
|
||||
else:
|
||||
includes.append(f"godot_cpp/{get_include_path(include)}")
|
||||
|
||||
includes.sort()
|
||||
|
||||
for include in includes:
|
||||
result.append(f"#include <{include}>")
|
||||
|
||||
result.append("")
|
||||
|
||||
result.append("#include <gdextension_interface.h>")
|
||||
@@ -737,7 +519,7 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
|
||||
result.append("public:")
|
||||
|
||||
result.append(
|
||||
f"\t_FORCE_INLINE_ GDExtensionTypePtr _native_ptr() const {{ return const_cast<uint8_t (*)[{snake_class_name}_SIZE]>(&opaque); }}"
|
||||
f"\t_FORCE_INLINE_ GDExtensionTypePtr _native_ptr() const {{ return const_cast<uint8_t(*)[{snake_class_name}_SIZE]>(&opaque); }}"
|
||||
)
|
||||
|
||||
copy_constructor_index = -1
|
||||
@@ -830,11 +612,9 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
|
||||
# Special cases.
|
||||
if class_name == "String":
|
||||
result.append("\tstatic String utf8(const char *p_from, int64_t p_len = -1);")
|
||||
result.append("\tError parse_utf8(const char *p_from, int64_t p_len = -1);")
|
||||
result.append("\tvoid parse_utf8(const char *p_from, int64_t p_len = -1);")
|
||||
result.append("\tstatic String utf16(const char16_t *p_from, int64_t p_len = -1);")
|
||||
result.append(
|
||||
"\tError parse_utf16(const char16_t *p_from, int64_t p_len = -1, bool p_default_little_endian = true);"
|
||||
)
|
||||
result.append("\tvoid parse_utf16(const char16_t *p_from, int64_t p_len = -1);")
|
||||
result.append("\tCharString utf8() const;")
|
||||
result.append("\tCharString ascii() const;")
|
||||
result.append("\tChar16String utf16() const;")
|
||||
@@ -852,14 +632,14 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
|
||||
|
||||
if "operators" in builtin_api:
|
||||
for operator in builtin_api["operators"]:
|
||||
if operator["name"] not in ["in", "xor"]:
|
||||
if is_valid_cpp_operator(operator["name"]):
|
||||
if "right_type" in operator:
|
||||
result.append(
|
||||
f'\t{correct_type(operator["return_type"])} operator{operator["name"]}({type_for_parameter(operator["right_type"])}p_other) const;'
|
||||
f'\t{correct_type(operator["return_type"])} operator{get_operator_cpp_name(operator["name"])}({type_for_parameter(operator["right_type"])}p_other) const;'
|
||||
)
|
||||
else:
|
||||
result.append(
|
||||
f'\t{correct_type(operator["return_type"])} operator{operator["name"].replace("unary", "")}() const;'
|
||||
f'\t{correct_type(operator["return_type"])} operator{get_operator_cpp_name(operator["name"])}() const;'
|
||||
)
|
||||
|
||||
# Copy assignment.
|
||||
@@ -918,7 +698,7 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
|
||||
result.append(f"\tconst {return_type} *ptr() const;")
|
||||
result.append(f"\t{return_type} *ptrw();")
|
||||
iterators = """
|
||||
struct Iterator {
|
||||
struct Iterator {
|
||||
_FORCE_INLINE_ $TYPE &operator*() const {
|
||||
return *elem_ptr;
|
||||
}
|
||||
@@ -980,19 +760,17 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
|
||||
}
|
||||
_FORCE_INLINE_ ConstIterator end() const {
|
||||
return ConstIterator(ptr() + size());
|
||||
}
|
||||
"""
|
||||
}"""
|
||||
result.append(iterators.replace("$TYPE", return_type))
|
||||
init_list = """
|
||||
_FORCE_INLINE_ $CLASS(std::initializer_list<$TYPE> p_init) {
|
||||
_FORCE_INLINE_ $CLASS(std::initializer_list<$TYPE> p_init) {
|
||||
ERR_FAIL_COND(resize(p_init.size()) != 0);
|
||||
|
||||
size_t i = 0;
|
||||
for (const $TYPE &element : p_init) {
|
||||
set(i++, element);
|
||||
}
|
||||
}
|
||||
"""
|
||||
}"""
|
||||
result.append(init_list.replace("$TYPE", return_type).replace("$CLASS", class_name))
|
||||
|
||||
if class_name == "Array":
|
||||
@@ -1031,7 +809,9 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
|
||||
result.append("")
|
||||
result.append("} // namespace godot")
|
||||
|
||||
result.append("")
|
||||
result.append(f"#endif // ! {header_guard}")
|
||||
result.append("")
|
||||
|
||||
return "\n".join(result)
|
||||
|
||||
@@ -1045,7 +825,6 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
|
||||
|
||||
add_header(f"{snake_class_name}.cpp", result)
|
||||
|
||||
result.append("")
|
||||
result.append(f"#include <godot_cpp/variant/{snake_class_name}.hpp>")
|
||||
result.append("")
|
||||
result.append("#include <godot_cpp/core/binder_common.hpp>")
|
||||
@@ -1054,10 +833,16 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
|
||||
result.append("")
|
||||
|
||||
# Only used since the "fully used" is included in header already.
|
||||
for include in used_classes:
|
||||
result.append(f"#include <godot_cpp/{get_include_path(include)}>")
|
||||
|
||||
if len(used_classes) > 0:
|
||||
includes = []
|
||||
for included in used_classes:
|
||||
includes.append(f"godot_cpp/{get_include_path(included)}")
|
||||
|
||||
includes.sort()
|
||||
|
||||
for included in includes:
|
||||
result.append(f"#include <{included}>")
|
||||
|
||||
result.append("")
|
||||
|
||||
result.append("#include <godot_cpp/core/builtin_ptrcall.hpp>")
|
||||
@@ -1291,10 +1076,10 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
|
||||
|
||||
if "operators" in builtin_api:
|
||||
for operator in builtin_api["operators"]:
|
||||
if operator["name"] not in ["in", "xor"]:
|
||||
if is_valid_cpp_operator(operator["name"]):
|
||||
if "right_type" in operator:
|
||||
result.append(
|
||||
f'{correct_type(operator["return_type"])} {class_name}::operator{operator["name"]}({type_for_parameter(operator["right_type"])}p_other) const {{'
|
||||
f'{correct_type(operator["return_type"])} {class_name}::operator{get_operator_cpp_name(operator["name"])}({type_for_parameter(operator["right_type"])}p_other) const {{'
|
||||
)
|
||||
(encode, arg_name) = get_encoded_arg("other", operator["right_type"], None)
|
||||
result += encode
|
||||
@@ -1304,10 +1089,10 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
|
||||
result.append("}")
|
||||
else:
|
||||
result.append(
|
||||
f'{correct_type(operator["return_type"])} {class_name}::operator{operator["name"].replace("unary", "")}() const {{'
|
||||
f'{correct_type(operator["return_type"])} {class_name}::operator{get_operator_cpp_name(operator["name"])}() const {{'
|
||||
)
|
||||
result.append(
|
||||
f'\treturn internal::_call_builtin_operator_ptr<{get_gdextension_type(correct_type(operator["return_type"]))}>(_method_bindings.operator_{get_operator_id_name(operator["name"])}, (GDExtensionConstTypePtr)&opaque, (GDExtensionConstTypePtr)nullptr);'
|
||||
f'\treturn internal::_call_builtin_operator_ptr<{get_gdextension_type(correct_type(operator["return_type"]))}>(_method_bindings.operator_{get_operator_id_name(operator["name"])}, (GDExtensionConstTypePtr)&opaque, (GDExtensionConstTypePtr) nullptr);'
|
||||
)
|
||||
result.append("}")
|
||||
result.append("")
|
||||
@@ -1343,6 +1128,7 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
|
||||
|
||||
result.append("")
|
||||
result.append("} //namespace godot")
|
||||
result.append("")
|
||||
|
||||
return "\n".join(result)
|
||||
|
||||
@@ -1518,11 +1304,18 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
|
||||
|
||||
result.append("")
|
||||
|
||||
for included in used_classes:
|
||||
result.append(f"#include <godot_cpp/{get_include_path(included)}>")
|
||||
if len(used_classes) > 0:
|
||||
includes = []
|
||||
for included in used_classes:
|
||||
includes.append(f"godot_cpp/{get_include_path(included)}")
|
||||
|
||||
if len(used_classes) == 0:
|
||||
includes.sort()
|
||||
|
||||
for include in includes:
|
||||
result.append(f"#include <{include}>")
|
||||
else:
|
||||
result.append("#include <godot_cpp/core/method_ptrcall.hpp>")
|
||||
|
||||
result.append("")
|
||||
|
||||
result.append("namespace godot {")
|
||||
@@ -1562,16 +1355,23 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
|
||||
|
||||
result.append("")
|
||||
|
||||
for included in fully_used_classes:
|
||||
if included == "TypedArray":
|
||||
result.append("#include <godot_cpp/variant/typed_array.hpp>")
|
||||
else:
|
||||
result.append(f"#include <godot_cpp/{get_include_path(included)}>")
|
||||
if len(fully_used_classes) > 0:
|
||||
includes = []
|
||||
for included in fully_used_classes:
|
||||
if included == "TypedArray":
|
||||
includes.append("godot_cpp/variant/typed_array.hpp")
|
||||
else:
|
||||
includes.append(f"godot_cpp/{get_include_path(included)}")
|
||||
|
||||
includes.sort()
|
||||
|
||||
for include in includes:
|
||||
result.append(f"#include <{include}>")
|
||||
|
||||
result.append("")
|
||||
|
||||
if class_name == "EditorPlugin":
|
||||
result.append("#include <godot_cpp/classes/editor_plugin_registration.hpp>")
|
||||
|
||||
if len(fully_used_classes) > 0:
|
||||
result.append("")
|
||||
|
||||
if class_name != "Object" and class_name != "ClassDBSingleton":
|
||||
@@ -1610,7 +1410,6 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
|
||||
result.append("")
|
||||
|
||||
result.append("public:")
|
||||
result.append("")
|
||||
|
||||
if "enums" in class_api:
|
||||
for enum_api in class_api["enums"]:
|
||||
@@ -1643,6 +1442,10 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
|
||||
|
||||
vararg = "is_vararg" in method and method["is_vararg"]
|
||||
|
||||
if vararg:
|
||||
result.append("")
|
||||
result.append("private:")
|
||||
|
||||
method_signature = "\t"
|
||||
method_signature += make_signature(
|
||||
class_name, method, for_header=True, use_template_get_node=use_template_get_node
|
||||
@@ -1650,6 +1453,8 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
|
||||
result.append(method_signature + ";")
|
||||
|
||||
if vararg:
|
||||
result.append("")
|
||||
result.append("public:")
|
||||
# Add templated version.
|
||||
result += make_varargs_template(method)
|
||||
|
||||
@@ -1664,6 +1469,8 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
|
||||
)
|
||||
result.append(method_signature + ";")
|
||||
|
||||
result.append("")
|
||||
|
||||
result.append("protected:")
|
||||
# T is the custom class we want to register (from which the call initiates, going up the inheritance chain),
|
||||
# B is its base class (can be a custom class too, that's why we pass it).
|
||||
@@ -1680,7 +1487,7 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
|
||||
# If the method is different from the base class, it means T overrides it, so it needs to be bound.
|
||||
# Note that with an `if constexpr`, the code inside the `if` will not even be compiled if the
|
||||
# condition returns false (in such cases it can't compile due to ambiguity).
|
||||
f"\t\tif constexpr (!std::is_same_v<decltype(&B::{method_name}),decltype(&T::{method_name})>) {{"
|
||||
f"\t\tif constexpr (!std::is_same_v<decltype(&B::{method_name}), decltype(&T::{method_name})>) {{"
|
||||
)
|
||||
result.append(f"\t\t\tBIND_VIRTUAL_METHOD(T, {method_name});")
|
||||
result.append("\t\t}")
|
||||
@@ -1698,17 +1505,13 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
|
||||
if class_name == "XMLParser":
|
||||
result.append("\tError _open_buffer(const uint8_t *p_buffer, size_t p_size);")
|
||||
|
||||
if class_name == "Image":
|
||||
result.append("\tuint8_t *ptrw();")
|
||||
result.append("\tconst uint8_t *ptr();")
|
||||
|
||||
if class_name == "FileAccess":
|
||||
result.append("\tuint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const;")
|
||||
result.append("\tvoid store_buffer(const uint8_t *p_src, uint64_t p_length);")
|
||||
|
||||
if class_name == "WorkerThreadPool":
|
||||
result.append("\tenum {")
|
||||
result.append("\tINVALID_TASK_ID = -1")
|
||||
result.append("\t\tINVALID_TASK_ID = -1")
|
||||
result.append("\t};")
|
||||
result.append("\ttypedef int64_t TaskID;")
|
||||
result.append("\ttypedef int64_t GroupID;")
|
||||
@@ -1720,8 +1523,6 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
|
||||
)
|
||||
|
||||
if class_name == "Object":
|
||||
result.append("")
|
||||
|
||||
result.append("\ttemplate <typename T>")
|
||||
result.append("\tstatic T *cast_to(Object *p_object);")
|
||||
|
||||
@@ -1736,7 +1537,6 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
|
||||
"\tT *get_node(const NodePath &p_path) const { return Object::cast_to<T>(get_node_internal(p_path)); }"
|
||||
)
|
||||
|
||||
result.append("")
|
||||
result.append("};")
|
||||
result.append("")
|
||||
|
||||
@@ -1820,7 +1620,7 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
|
||||
|
||||
result.append(method_body)
|
||||
result.append("\t} \\")
|
||||
result.append("\t;")
|
||||
result.append("\t")
|
||||
result.append("")
|
||||
|
||||
result.append("#define CLASSDB_SINGLETON_VARIANT_CAST \\")
|
||||
@@ -1832,10 +1632,11 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
|
||||
else:
|
||||
result.append(f'\tVARIANT_ENUM_CAST({class_api["alias_for"]}::{enum_api["name"]}); \\')
|
||||
|
||||
result.append("\t;")
|
||||
result.append("\t")
|
||||
result.append("")
|
||||
|
||||
result.append(f"#endif // ! {header_guard}")
|
||||
result.append("")
|
||||
|
||||
return "\n".join(result)
|
||||
|
||||
@@ -1857,10 +1658,16 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
|
||||
result.append("#include <godot_cpp/core/error_macros.hpp>")
|
||||
result.append("")
|
||||
|
||||
for included in used_classes:
|
||||
result.append(f"#include <godot_cpp/{get_include_path(included)}>")
|
||||
|
||||
if len(used_classes) > 0:
|
||||
includes = []
|
||||
for included in used_classes:
|
||||
includes.append(f"godot_cpp/{get_include_path(included)}")
|
||||
|
||||
includes.sort()
|
||||
|
||||
for included in includes:
|
||||
result.append(f"#include <{included}>")
|
||||
|
||||
result.append("")
|
||||
|
||||
result.append("namespace godot {")
|
||||
@@ -2010,8 +1817,8 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
|
||||
result.append(method_signature)
|
||||
result.append("")
|
||||
|
||||
result.append("} // namespace godot")
|
||||
result.append("")
|
||||
result.append("} // namespace godot ")
|
||||
|
||||
return "\n".join(result)
|
||||
|
||||
@@ -2039,23 +1846,24 @@ def generate_global_constants(api, output_dir):
|
||||
header.append("namespace godot {")
|
||||
header.append("")
|
||||
|
||||
for constant in api["global_constants"]:
|
||||
header.append(f'\tconst int64_t {escape_identifier(constant["name"])} = {constant["value"]};')
|
||||
if len(api["global_constants"]) > 0:
|
||||
for constant in api["global_constants"]:
|
||||
header.append(f'const int64_t {escape_identifier(constant["name"])} = {constant["value"]};')
|
||||
|
||||
header.append("")
|
||||
header.append("")
|
||||
|
||||
for enum_def in api["global_enums"]:
|
||||
if enum_def["name"].startswith("Variant."):
|
||||
continue
|
||||
|
||||
if enum_def["is_bitfield"]:
|
||||
header.append(f'\tenum {enum_def["name"]} : uint64_t {{')
|
||||
header.append(f'enum {enum_def["name"]} : uint64_t {{')
|
||||
else:
|
||||
header.append(f'\tenum {enum_def["name"]} {{')
|
||||
header.append(f'enum {enum_def["name"]} {{')
|
||||
|
||||
for value in enum_def["values"]:
|
||||
header.append(f'\t\t{value["name"]} = {value["value"]},')
|
||||
header.append("\t};")
|
||||
header.append(f'\t{value["name"]} = {value["value"]},')
|
||||
header.append("};")
|
||||
header.append("")
|
||||
|
||||
header.append("} // namespace godot")
|
||||
@@ -2166,19 +1974,19 @@ def generate_utility_functions(api, output_dir):
|
||||
header.append("public:")
|
||||
|
||||
for function in api["utility_functions"]:
|
||||
if function["name"] == "is_instance_valid":
|
||||
# The `is_instance_valid()` function doesn't work as developers expect, and unless used very
|
||||
# carefully will cause crashes. Instead, developers should use `ObjectDB::get_instance()`
|
||||
# with object ids to ensure that an instance is still valid.
|
||||
continue
|
||||
|
||||
vararg = "is_vararg" in function and function["is_vararg"]
|
||||
|
||||
if vararg:
|
||||
header.append("")
|
||||
header.append("private:")
|
||||
|
||||
function_signature = "\t"
|
||||
function_signature += make_signature("UtilityFunctions", function, for_header=True, static=True)
|
||||
header.append(function_signature + ";")
|
||||
|
||||
if vararg:
|
||||
header.append("")
|
||||
header.append("public:")
|
||||
# Add templated version.
|
||||
header += make_varargs_template(function, static=True)
|
||||
|
||||
@@ -2199,16 +2007,13 @@ def generate_utility_functions(api, output_dir):
|
||||
|
||||
source.append("#include <godot_cpp/variant/utility_functions.hpp>")
|
||||
source.append("")
|
||||
source.append("#include <godot_cpp/core/error_macros.hpp>")
|
||||
source.append("#include <godot_cpp/core/engine_ptrcall.hpp>")
|
||||
source.append("#include <godot_cpp/core/error_macros.hpp>")
|
||||
source.append("")
|
||||
source.append("namespace godot {")
|
||||
source.append("")
|
||||
|
||||
for function in api["utility_functions"]:
|
||||
if function["name"] == "is_instance_valid":
|
||||
continue
|
||||
|
||||
vararg = "is_vararg" in function and function["is_vararg"]
|
||||
|
||||
function_signature = make_signature("UtilityFunctions", function)
|
||||
@@ -2302,7 +2107,7 @@ def make_function_parameters(parameters, include_default=False, for_builtin=Fals
|
||||
signature.append(parameter)
|
||||
|
||||
if is_vararg:
|
||||
signature.append("const Args&... p_args")
|
||||
signature.append("const Args &...p_args")
|
||||
|
||||
return ", ".join(signature)
|
||||
|
||||
@@ -2339,6 +2144,10 @@ def get_encoded_arg(arg_name, type_name, type_meta):
|
||||
result.append(f"\t{get_gdextension_type(arg_type)} {name}_encoded;")
|
||||
result.append(f"\tPtrToArg<{correct_type(type_name)}>::encode({name}, &{name}_encoded);")
|
||||
name = f"&{name}_encoded"
|
||||
elif is_enum(type_name) and not is_bitfield(type_name):
|
||||
result.append(f"\tint64_t {name}_encoded;")
|
||||
result.append(f"\tPtrToArg<int64_t>::encode({name}, &{name}_encoded);")
|
||||
name = f"&{name}_encoded"
|
||||
elif is_engine_class(type_name):
|
||||
# `{name}` is a C++ wrapper, it contains a field which is the object's pointer Godot expects.
|
||||
# We have to check `nullptr` because when the caller sends `nullptr`, the wrapper itself will be null.
|
||||
@@ -2360,9 +2169,6 @@ def make_signature(
|
||||
if "is_virtual" in function_data and function_data["is_virtual"]:
|
||||
function_signature += "virtual "
|
||||
|
||||
if is_vararg:
|
||||
function_signature += "private: "
|
||||
|
||||
if static:
|
||||
function_signature += "static "
|
||||
|
||||
@@ -2415,7 +2221,6 @@ def make_varargs_template(
|
||||
function_data,
|
||||
static=False,
|
||||
class_befor_signature="",
|
||||
with_public_declare=True,
|
||||
with_indent=True,
|
||||
for_builtin_classes=False,
|
||||
):
|
||||
@@ -2423,10 +2228,7 @@ def make_varargs_template(
|
||||
|
||||
function_signature = ""
|
||||
|
||||
if with_public_declare:
|
||||
function_signature = "public: "
|
||||
|
||||
function_signature += "template <typename... Args> "
|
||||
result.append("template <typename... Args>")
|
||||
|
||||
if static:
|
||||
function_signature += "static "
|
||||
@@ -2469,7 +2271,7 @@ def make_varargs_template(
|
||||
function_signature += " {"
|
||||
result.append(function_signature)
|
||||
|
||||
args_array = f"\tstd::array<Variant, {len(method_arguments)} + sizeof...(Args)> variant_args {{ "
|
||||
args_array = f"\tstd::array<Variant, {len(method_arguments)} + sizeof...(Args)> variant_args{{ "
|
||||
for argument in method_arguments:
|
||||
if argument["type"] == "Variant":
|
||||
args_array += escape_argument(argument["name"])
|
||||
@@ -2586,7 +2388,6 @@ def is_packed_array(type_name):
|
||||
"PackedStringArray",
|
||||
"PackedVector2Array",
|
||||
"PackedVector3Array",
|
||||
"PackedVector4Array",
|
||||
]
|
||||
|
||||
|
||||
@@ -2655,20 +2456,6 @@ def is_refcounted(type_name):
|
||||
return type_name in engine_classes and engine_classes[type_name]
|
||||
|
||||
|
||||
def is_class_included(class_name, build_profile):
|
||||
"""
|
||||
Check if an engine class should be included.
|
||||
This removes classes according to a build profile of enabled or disabled classes.
|
||||
"""
|
||||
included = build_profile.get("enabled_classes", [])
|
||||
excluded = build_profile.get("disabled_classes", [])
|
||||
if included:
|
||||
return class_name in included
|
||||
if excluded:
|
||||
return class_name not in excluded
|
||||
return True
|
||||
|
||||
|
||||
def is_included(type_name, current_type):
|
||||
"""
|
||||
Check if a builtin type should be included.
|
||||
@@ -2719,8 +2506,6 @@ def correct_type(type_name, meta=None, use_alias=True):
|
||||
if meta is not None:
|
||||
if "int" in meta:
|
||||
return f"{meta}_t"
|
||||
elif meta in type_conversion:
|
||||
return type_conversion[type_name]
|
||||
else:
|
||||
return meta
|
||||
if type_name in type_conversion:
|
||||
@@ -2832,6 +2617,38 @@ def get_operator_id_name(op):
|
||||
return op_id_map[op]
|
||||
|
||||
|
||||
def get_operator_cpp_name(op):
|
||||
op_cpp_map = {
|
||||
"==": "==",
|
||||
"!=": "!=",
|
||||
"<": "<",
|
||||
"<=": "<=",
|
||||
">": ">",
|
||||
">=": ">=",
|
||||
"+": "+",
|
||||
"-": "-",
|
||||
"*": "*",
|
||||
"/": "/",
|
||||
"unary-": "-",
|
||||
"unary+": "+",
|
||||
"%": "%",
|
||||
"<<": "<<",
|
||||
">>": ">>",
|
||||
"&": "&",
|
||||
"|": "|",
|
||||
"^": "^",
|
||||
"~": "~",
|
||||
"and": "&&",
|
||||
"or": "||",
|
||||
"not": "!",
|
||||
}
|
||||
return op_cpp_map[op]
|
||||
|
||||
|
||||
def is_valid_cpp_operator(op):
|
||||
return op not in ["**", "xor", "in"]
|
||||
|
||||
|
||||
def get_default_value_for_type(type_name):
|
||||
if type_name == "int":
|
||||
return "0"
|
||||
|
||||
183
build_profile.py
Normal file
183
build_profile.py
Normal file
@@ -0,0 +1,183 @@
|
||||
import json
|
||||
import sys
|
||||
|
||||
|
||||
def parse_build_profile(profile_filepath, api):
|
||||
if profile_filepath == "":
|
||||
return {}
|
||||
|
||||
with open(profile_filepath, encoding="utf-8") as profile_file:
|
||||
profile = json.load(profile_file)
|
||||
|
||||
api_dict = {}
|
||||
parents = {}
|
||||
children = {}
|
||||
for engine_class in api["classes"]:
|
||||
api_dict[engine_class["name"]] = engine_class
|
||||
parent = engine_class.get("inherits", "")
|
||||
child = engine_class["name"]
|
||||
parents[child] = parent
|
||||
if parent == "":
|
||||
continue
|
||||
children[parent] = children.get(parent, [])
|
||||
children[parent].append(child)
|
||||
|
||||
included = []
|
||||
front = list(profile.get("enabled_classes", []))
|
||||
if front:
|
||||
# These must always be included
|
||||
front.append("WorkerThreadPool")
|
||||
front.append("ClassDB")
|
||||
front.append("ClassDBSingleton")
|
||||
# In src/classes/low_level.cpp
|
||||
front.append("FileAccess")
|
||||
front.append("Image")
|
||||
front.append("XMLParser")
|
||||
# In include/godot_cpp/templates/thread_work_pool.hpp
|
||||
front.append("Semaphore")
|
||||
while front:
|
||||
cls = front.pop()
|
||||
if cls in included:
|
||||
continue
|
||||
included.append(cls)
|
||||
parent = parents.get(cls, "")
|
||||
if parent:
|
||||
front.append(parent)
|
||||
|
||||
excluded = []
|
||||
front = list(profile.get("disabled_classes", []))
|
||||
while front:
|
||||
cls = front.pop()
|
||||
if cls in excluded:
|
||||
continue
|
||||
excluded.append(cls)
|
||||
front += children.get(cls, [])
|
||||
|
||||
if included and excluded:
|
||||
print(
|
||||
"WARNING: Cannot specify both 'enabled_classes' and 'disabled_classes' in build profile. 'disabled_classes' will be ignored."
|
||||
)
|
||||
|
||||
return {
|
||||
"enabled_classes": included,
|
||||
"disabled_classes": excluded,
|
||||
}
|
||||
|
||||
|
||||
def generate_trimmed_api(source_api_filepath, profile_filepath):
|
||||
with open(source_api_filepath, encoding="utf-8") as api_file:
|
||||
api = json.load(api_file)
|
||||
|
||||
if profile_filepath == "":
|
||||
return api
|
||||
|
||||
build_profile = parse_build_profile(profile_filepath, api)
|
||||
|
||||
engine_classes = {}
|
||||
for class_api in api["classes"]:
|
||||
engine_classes[class_api["name"]] = class_api["is_refcounted"]
|
||||
for native_struct in api["native_structures"]:
|
||||
if native_struct["name"] == "ObjectID":
|
||||
continue
|
||||
engine_classes[native_struct["name"]] = False
|
||||
|
||||
classes = []
|
||||
for class_api in api["classes"]:
|
||||
if not is_class_included(class_api["name"], build_profile):
|
||||
continue
|
||||
if "methods" in class_api:
|
||||
methods = []
|
||||
for method in class_api["methods"]:
|
||||
if not is_method_included(method, build_profile, engine_classes):
|
||||
continue
|
||||
methods.append(method)
|
||||
class_api["methods"] = methods
|
||||
classes.append(class_api)
|
||||
api["classes"] = classes
|
||||
|
||||
return api
|
||||
|
||||
|
||||
def is_class_included(class_name, build_profile):
|
||||
"""
|
||||
Check if an engine class should be included.
|
||||
This removes classes according to a build profile of enabled or disabled classes.
|
||||
"""
|
||||
included = build_profile.get("enabled_classes", [])
|
||||
excluded = build_profile.get("disabled_classes", [])
|
||||
if included:
|
||||
return class_name in included
|
||||
if excluded:
|
||||
return class_name not in excluded
|
||||
return True
|
||||
|
||||
|
||||
def is_method_included(method, build_profile, engine_classes):
|
||||
"""
|
||||
Check if an engine class method should be included.
|
||||
This removes methods according to a build profile of enabled or disabled classes.
|
||||
"""
|
||||
included = build_profile.get("enabled_classes", [])
|
||||
excluded = build_profile.get("disabled_classes", [])
|
||||
ref_cls = set()
|
||||
rtype = get_base_type(method.get("return_value", {}).get("type", ""))
|
||||
args = [get_base_type(a["type"]) for a in method.get("arguments", [])]
|
||||
if rtype in engine_classes:
|
||||
ref_cls.add(rtype)
|
||||
elif is_enum(rtype) and get_enum_class(rtype) in engine_classes:
|
||||
ref_cls.add(get_enum_class(rtype))
|
||||
for arg in args:
|
||||
if arg in engine_classes:
|
||||
ref_cls.add(arg)
|
||||
elif is_enum(arg) and get_enum_class(arg) in engine_classes:
|
||||
ref_cls.add(get_enum_class(arg))
|
||||
for acls in ref_cls:
|
||||
if len(included) > 0 and acls not in included:
|
||||
return False
|
||||
elif len(excluded) > 0 and acls in excluded:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def is_enum(type_name):
|
||||
return type_name.startswith("enum::") or type_name.startswith("bitfield::")
|
||||
|
||||
|
||||
def get_enum_class(enum_name: str):
|
||||
if "." in enum_name:
|
||||
if is_bitfield(enum_name):
|
||||
return enum_name.replace("bitfield::", "").split(".")[0]
|
||||
else:
|
||||
return enum_name.replace("enum::", "").split(".")[0]
|
||||
else:
|
||||
return "GlobalConstants"
|
||||
|
||||
|
||||
def get_base_type(type_name):
|
||||
if type_name.startswith("const "):
|
||||
type_name = type_name[6:]
|
||||
if type_name.endswith("*"):
|
||||
type_name = type_name[:-1]
|
||||
if type_name.startswith("typedarray::"):
|
||||
type_name = type_name.replace("typedarray::", "")
|
||||
return type_name
|
||||
|
||||
|
||||
def is_bitfield(type_name):
|
||||
return type_name.startswith("bitfield::")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 3 or len(sys.argv) > 4:
|
||||
print("Usage: %s BUILD_PROFILE INPUT_JSON [OUTPUT_JSON]" % (sys.argv[0]))
|
||||
sys.exit(1)
|
||||
profile = sys.argv[1]
|
||||
infile = sys.argv[2]
|
||||
outfile = sys.argv[3] if len(sys.argv) > 3 else ""
|
||||
api = generate_trimmed_api(infile, profile)
|
||||
|
||||
if outfile:
|
||||
with open(outfile, "w", encoding="utf-8") as f:
|
||||
json.dump(api, f)
|
||||
else:
|
||||
json.dump(api, sys.stdout)
|
||||
@@ -89,6 +89,6 @@ function( set_warning_as_error )
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
if ( GODOT_CPP_WARNING_AS_ERROR )
|
||||
if ( GODOT_WARNING_AS_ERROR )
|
||||
set_warning_as_error()
|
||||
endif()
|
||||
240
cmake/godotcpp.cmake
Normal file
240
cmake/godotcpp.cmake
Normal file
@@ -0,0 +1,240 @@
|
||||
function( godotcpp_options )
|
||||
|
||||
#TODO platform
|
||||
#TODO target
|
||||
|
||||
# Input from user for GDExtension interface header and the API JSON file
|
||||
set(GODOT_GDEXTENSION_DIR "gdextension" CACHE PATH
|
||||
"Path to a custom directory containing GDExtension interface header and API JSON file ( /path/to/gdextension_dir )" )
|
||||
set(GODOT_CUSTOM_API_FILE "" CACHE FILEPATH
|
||||
"Path to a custom GDExtension API JSON file (takes precedence over `gdextension_dir`) ( /path/to/custom_api_file )")
|
||||
|
||||
#TODO generate_bindings
|
||||
|
||||
option(GODOT_GENERATE_TEMPLATE_GET_NODE
|
||||
"Generate a template version of the Node class's get_node. (ON|OFF)" ON)
|
||||
|
||||
#TODO build_library
|
||||
|
||||
set(GODOT_PRECISION "single" CACHE STRING
|
||||
"Set the floating-point precision level (single|double)")
|
||||
|
||||
#TODO arch
|
||||
#TODO threads
|
||||
#TODO compiledb
|
||||
#TODO compiledb_file
|
||||
#TODO build_profile aka cmake preset
|
||||
|
||||
set(GODOT_USE_HOT_RELOAD "" CACHE BOOL
|
||||
"Enable the extra accounting required to support hot reload. (ON|OFF)")
|
||||
|
||||
option(GODOT_DISABLE_EXCEPTIONS "Force disabling exception handling code (ON|OFF)" ON )
|
||||
|
||||
set( GODOT_SYMBOL_VISIBILITY "hidden" CACHE STRING
|
||||
"Symbols visibility on GNU platforms. Use 'auto' to apply the default value. (auto|visible|hidden)")
|
||||
set_property( CACHE GODOT_SYMBOL_VISIBILITY PROPERTY STRINGS "auto;visible;hidden" )
|
||||
|
||||
#TODO optimize
|
||||
#TODO debug_symbols
|
||||
#TODO dev_build
|
||||
|
||||
# FIXME These options are not present in SCons, and perhaps should be added there.
|
||||
option(GODOT_SYSTEM_HEADERS "Expose headers as SYSTEM." ON)
|
||||
option(GODOT_WARNING_AS_ERROR "Treat warnings as errors" OFF)
|
||||
|
||||
# Run options commands on the following to populate cache for all platforms.
|
||||
# This type of thing is typically done conditionally
|
||||
# But as scons shows all options so shall we.
|
||||
#TODO ios_options()
|
||||
#TODO linux_options()
|
||||
#TODO macos_options()
|
||||
#TODO web_options()
|
||||
#TODO windows_options()
|
||||
endfunction()
|
||||
|
||||
|
||||
function( godotcpp_generate )
|
||||
# Set some helper variables for readability
|
||||
set( compiler_is_clang "$<OR:$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:Clang>>" )
|
||||
set( compiler_is_gnu "$<CXX_COMPILER_ID:GNU>" )
|
||||
set( compiler_is_msvc "$<CXX_COMPILER_ID:MSVC>" )
|
||||
|
||||
# CXX_VISIBILITY_PRESET supported values are: default, hidden, protected, and internal
|
||||
# which is inline with the gcc -fvisibility=
|
||||
# https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html
|
||||
# To match the scons options we need to change the text to match the -fvisibility flag
|
||||
# it is probably worth another PR which changes both to use the flag options
|
||||
if( ${GODOT_SYMBOL_VISIBILITY} STREQUAL "auto" OR ${GODOT_SYMBOL_VISIBILITY} STREQUAL "visible" )
|
||||
set( GODOT_SYMBOL_VISIBILITY "default" )
|
||||
endif ()
|
||||
|
||||
# Default build type is Debug in the SConstruct
|
||||
if("${CMAKE_BUILD_TYPE}" STREQUAL "")
|
||||
set(CMAKE_BUILD_TYPE Debug)
|
||||
endif()
|
||||
|
||||
# Hot reload is enabled by default in Debug-builds
|
||||
if( GODOT_USE_HOT_RELOAD STREQUAL "" AND NOT CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
set(GODOT_USE_HOT_RELOAD ON)
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED BITS)
|
||||
set(BITS 32)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(BITS 64)
|
||||
endif(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
endif()
|
||||
|
||||
|
||||
set(GODOT_GDEXTENSION_API_FILE "${GODOT_GDEXTENSION_DIR}/extension_api.json")
|
||||
if (NOT "${GODOT_CUSTOM_API_FILE}" STREQUAL "") # User-defined override.
|
||||
set(GODOT_GDEXTENSION_API_FILE "${GODOT_CUSTOM_API_FILE}")
|
||||
endif()
|
||||
|
||||
if ("${GODOT_PRECISION}" STREQUAL "double")
|
||||
add_definitions(-DREAL_T_IS_DOUBLE)
|
||||
endif()
|
||||
|
||||
set( GODOT_COMPILE_FLAGS )
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||
# using Visual Studio C++
|
||||
set(GODOT_COMPILE_FLAGS "/utf-8") # /GF /MP
|
||||
|
||||
if(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /MDd") # /Od /RTC1 /Zi
|
||||
else()
|
||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /MD /O2") # /Oy /GL /Gy
|
||||
endif(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
|
||||
add_definitions(-DNOMINMAX)
|
||||
else() # GCC/Clang
|
||||
if(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -fno-omit-frame-pointer -O0 -g")
|
||||
else()
|
||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -O3")
|
||||
endif(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
endif()
|
||||
|
||||
# Disable exception handling. Godot doesn't use exceptions anywhere, and this
|
||||
# saves around 20% of binary size and very significant build time (GH-80513).
|
||||
if (GODOT_DISABLE_EXCEPTIONS)
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -D_HAS_EXCEPTIONS=0")
|
||||
else()
|
||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -fno-exceptions")
|
||||
endif()
|
||||
else()
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /EHsc")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Generate source from the bindings file
|
||||
find_package(Python3 3.4 REQUIRED) # pathlib should be present
|
||||
if(GODOT_GENERATE_TEMPLATE_GET_NODE)
|
||||
set(GENERATE_BINDING_PARAMETERS "True")
|
||||
else()
|
||||
set(GENERATE_BINDING_PARAMETERS "False")
|
||||
endif()
|
||||
|
||||
execute_process(COMMAND "${Python3_EXECUTABLE}" "-c" "import binding_generator; binding_generator.print_file_list(\"${GODOT_GDEXTENSION_API_FILE}\", \"${CMAKE_CURRENT_BINARY_DIR}\", headers=True, sources=True)"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE GENERATED_FILES_LIST
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
add_custom_command(OUTPUT ${GENERATED_FILES_LIST}
|
||||
COMMAND "${Python3_EXECUTABLE}" "-c" "import binding_generator; binding_generator.generate_bindings(\"${GODOT_GDEXTENSION_API_FILE}\", \"${GENERATE_BINDING_PARAMETERS}\", \"${BITS}\", \"${GODOT_PRECISION}\", \"${CMAKE_CURRENT_BINARY_DIR}\")"
|
||||
VERBATIM
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
MAIN_DEPENDENCY ${GODOT_GDEXTENSION_API_FILE}
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/binding_generator.py
|
||||
COMMENT "Generating bindings"
|
||||
)
|
||||
|
||||
# Get Sources
|
||||
# As this cmake file was added using 'include(godotcpp)' from the root CMakeLists.txt,
|
||||
# the ${CMAKE_CURRENT_SOURCE_DIR} is still the root dir.
|
||||
file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS src/*.c**)
|
||||
file(GLOB_RECURSE HEADERS CONFIGURE_DEPENDS include/*.h**)
|
||||
|
||||
# Define our godot-cpp library
|
||||
add_library(${PROJECT_NAME} STATIC
|
||||
${SOURCES}
|
||||
${HEADERS}
|
||||
${GENERATED_FILES_LIST}
|
||||
)
|
||||
add_library(godot::cpp ALIAS ${PROJECT_NAME})
|
||||
|
||||
include(${PROJECT_SOURCE_DIR}/cmake/common_compiler_flags.cmake)
|
||||
|
||||
target_compile_features(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
cxx_std_17
|
||||
)
|
||||
|
||||
if(GODOT_USE_HOT_RELOAD)
|
||||
target_compile_definitions(${PROJECT_NAME} PUBLIC HOT_RELOAD_ENABLED)
|
||||
target_compile_options(${PROJECT_NAME} PUBLIC $<${compiler_is_gnu}:-fno-gnu-unique>)
|
||||
endif()
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME} PUBLIC
|
||||
$<$<CONFIG:Debug>:
|
||||
DEBUG_ENABLED
|
||||
DEBUG_METHODS_ENABLED
|
||||
>
|
||||
$<${compiler_is_msvc}:
|
||||
TYPED_METHOD_BIND
|
||||
>
|
||||
)
|
||||
|
||||
target_link_options(${PROJECT_NAME} PRIVATE
|
||||
$<$<NOT:${compiler_is_msvc}>:
|
||||
-static-libgcc
|
||||
-static-libstdc++
|
||||
-Wl,-R,'$$ORIGIN'
|
||||
>
|
||||
)
|
||||
|
||||
# Optionally mark headers as SYSTEM
|
||||
set(GODOT_SYSTEM_HEADERS_ATTRIBUTE "")
|
||||
if (GODOT_SYSTEM_HEADERS)
|
||||
set(GODOT_SYSTEM_HEADERS_ATTRIBUTE SYSTEM)
|
||||
endif ()
|
||||
|
||||
target_include_directories(${PROJECT_NAME} ${GODOT_SYSTEM_HEADERS_ATTRIBUTE} PUBLIC
|
||||
include
|
||||
${CMAKE_CURRENT_BINARY_DIR}/gen/include
|
||||
${GODOT_GDEXTENSION_DIR}
|
||||
)
|
||||
|
||||
# Add the compile flags
|
||||
set_property(TARGET ${PROJECT_NAME} APPEND_STRING PROPERTY COMPILE_FLAGS ${GODOT_COMPILE_FLAGS})
|
||||
|
||||
# Create the correct name (godot.os.build_type.system_bits)
|
||||
string(TOLOWER "${CMAKE_SYSTEM_NAME}" SYSTEM_NAME)
|
||||
string(TOLOWER "${CMAKE_BUILD_TYPE}" BUILD_TYPE)
|
||||
|
||||
if(ANDROID)
|
||||
# Added the android abi after system name
|
||||
set(SYSTEM_NAME ${SYSTEM_NAME}.${ANDROID_ABI})
|
||||
|
||||
# Android does not have the bits at the end if you look at the main godot repo build
|
||||
set(OUTPUT_NAME "godot-cpp.${SYSTEM_NAME}.${BUILD_TYPE}")
|
||||
else()
|
||||
set(OUTPUT_NAME "godot-cpp.${SYSTEM_NAME}.${BUILD_TYPE}.${BITS}")
|
||||
endif()
|
||||
|
||||
set_target_properties(${PROJECT_NAME}
|
||||
PROPERTIES
|
||||
CXX_EXTENSIONS OFF
|
||||
POSITION_INDEPENDENT_CODE ON
|
||||
CXX_VISIBILITY_PRESET ${GODOT_SYMBOL_VISIBILITY}
|
||||
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin"
|
||||
OUTPUT_NAME "${OUTPUT_NAME}"
|
||||
)
|
||||
|
||||
endfunction()
|
||||
57
doc/cmake.md
Normal file
57
doc/cmake.md
Normal file
@@ -0,0 +1,57 @@
|
||||
## CMake
|
||||
|
||||
### cmake arguments
|
||||
|
||||
`CMAKE_BUILD_TYPE`: Compilation target (Debug or Release defaults to Debug)
|
||||
|
||||
### godot-cpp cmake arguments
|
||||
- `GODOT_GDEXTENSION_DIR`: Path to the directory containing GDExtension interface header and API JSON file
|
||||
- `GODOT_SYSTEM_HEADERS`: Mark the header files as SYSTEM. This may be useful to suppress warnings in projects including this one.
|
||||
- `GODOT_WARNING_AS_ERROR`: Treat any warnings as errors
|
||||
- `GODOT_USE_HOT_RELOAD`: Build with hot reload support. Defaults to YES for Debug-builds and NO for Release-builds.
|
||||
- `GODOT_CUSTOM_API_FILE`: Path to a custom GDExtension API JSON file (takes precedence over `gdextension_dir`)
|
||||
- `GODOT_PRECISION`: Floating-point precision level ("single", "double")
|
||||
|
||||
### Android cmake arguments
|
||||
- `CMAKE_TOOLCHAIN_FILE`: The path to the android cmake toolchain ($ANDROID_NDK/build/cmake/android.toolchain.cmake)
|
||||
- `ANDROID_NDK`: The path to the android ndk root folder
|
||||
- `ANDROID_TOOLCHAIN_NAME`: The android toolchain (arm-linux-androideabi-4.9 or aarch64-linux-android-4.9 or x86-4.9 or x86_64-4.9)
|
||||
- `ANDROID_PLATFORM`: The android platform version (android-23)
|
||||
|
||||
- More info [here](https://godot.readthedocs.io/en/latest/development/compiling/compiling_for_android.html)
|
||||
|
||||
## Examples
|
||||
```shell
|
||||
Builds a debug version:
|
||||
cmake .
|
||||
cmake --build .
|
||||
```
|
||||
Builds a release version with clang
|
||||
|
||||
```shell
|
||||
CC=/usr/bin/clang CXX=/usr/bin/clang++ cmake -DCMAKE_BUILD_TYPE=Release -G "Unix Makefiles" .
|
||||
cmake --build .
|
||||
```
|
||||
Builds an android armeabi-v7a debug version:
|
||||
|
||||
``` shell
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake -DANDROID_NDK=$ANDROID_NDK \
|
||||
-DANDROID_TOOLCHAIN_NAME=arm-linux-androideabi-4.9 -DANDROID_PLATFORM=android-23 -DCMAKE_BUILD_TYPE=Debug .
|
||||
cmake --build .
|
||||
```
|
||||
|
||||
## Protip
|
||||
Generate the buildfiles in a sub directory to not clutter the root directory with build files:
|
||||
|
||||
```shell
|
||||
mkdir build && cd build && cmake -G "Unix Makefiles" .. && cmake --build .
|
||||
```
|
||||
|
||||
Ensure that you avoid exposing godot-cpp symbols - this might lead to hard to debug errors if you ever load multiple
|
||||
plugins using difference godot-cpp versions. Use visibility hidden whenever possible:
|
||||
```cmake
|
||||
set_target_properties(<all-my-plugin-related-targets> PROPERTIES CXX_VISIBILITY_PRESET hidden)
|
||||
```
|
||||
|
||||
## Todo
|
||||
Test build for Windows, Mac and mingw.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -96,7 +96,6 @@ typedef enum {
|
||||
GDEXTENSION_VARIANT_TYPE_PACKED_VECTOR2_ARRAY,
|
||||
GDEXTENSION_VARIANT_TYPE_PACKED_VECTOR3_ARRAY,
|
||||
GDEXTENSION_VARIANT_TYPE_PACKED_COLOR_ARRAY,
|
||||
GDEXTENSION_VARIANT_TYPE_PACKED_VECTOR4_ARRAY,
|
||||
|
||||
GDEXTENSION_VARIANT_TYPE_VARIANT_MAX
|
||||
} GDExtensionVariantType;
|
||||
@@ -257,7 +256,6 @@ typedef struct {
|
||||
|
||||
typedef const GDExtensionPropertyInfo *(*GDExtensionClassGetPropertyList)(GDExtensionClassInstancePtr p_instance, uint32_t *r_count);
|
||||
typedef void (*GDExtensionClassFreePropertyList)(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list);
|
||||
typedef void (*GDExtensionClassFreePropertyList2)(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list, uint32_t p_count);
|
||||
typedef GDExtensionBool (*GDExtensionClassPropertyCanRevert)(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name);
|
||||
typedef GDExtensionBool (*GDExtensionClassPropertyGetRevert)(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret);
|
||||
typedef GDExtensionBool (*GDExtensionClassValidateProperty)(GDExtensionClassInstancePtr p_instance, GDExtensionPropertyInfo *p_property);
|
||||
@@ -292,7 +290,7 @@ typedef struct {
|
||||
GDExtensionClassGetVirtual get_virtual_func; // Queries a virtual function by name and returns a callback to invoke the requested virtual function.
|
||||
GDExtensionClassGetRID get_rid_func;
|
||||
void *class_userdata; // Per-class user data, later accessible in instance bindings.
|
||||
} GDExtensionClassCreationInfo; // Deprecated. Use GDExtensionClassCreationInfo3 instead.
|
||||
} GDExtensionClassCreationInfo; // Deprecated. Use GDExtensionClassCreationInfo2 instead.
|
||||
|
||||
typedef struct {
|
||||
GDExtensionBool is_virtual;
|
||||
@@ -325,41 +323,7 @@ typedef struct {
|
||||
GDExtensionClassCallVirtualWithData call_virtual_with_data_func;
|
||||
GDExtensionClassGetRID get_rid_func;
|
||||
void *class_userdata; // Per-class user data, later accessible in instance bindings.
|
||||
} GDExtensionClassCreationInfo2; // Deprecated. Use GDExtensionClassCreationInfo3 instead.
|
||||
|
||||
typedef struct {
|
||||
GDExtensionBool is_virtual;
|
||||
GDExtensionBool is_abstract;
|
||||
GDExtensionBool is_exposed;
|
||||
GDExtensionBool is_runtime;
|
||||
GDExtensionClassSet set_func;
|
||||
GDExtensionClassGet get_func;
|
||||
GDExtensionClassGetPropertyList get_property_list_func;
|
||||
GDExtensionClassFreePropertyList2 free_property_list_func;
|
||||
GDExtensionClassPropertyCanRevert property_can_revert_func;
|
||||
GDExtensionClassPropertyGetRevert property_get_revert_func;
|
||||
GDExtensionClassValidateProperty validate_property_func;
|
||||
GDExtensionClassNotification2 notification_func;
|
||||
GDExtensionClassToString to_string_func;
|
||||
GDExtensionClassReference reference_func;
|
||||
GDExtensionClassUnreference unreference_func;
|
||||
GDExtensionClassCreateInstance create_instance_func; // (Default) constructor; mandatory. If the class is not instantiable, consider making it virtual or abstract.
|
||||
GDExtensionClassFreeInstance free_instance_func; // Destructor; mandatory.
|
||||
GDExtensionClassRecreateInstance recreate_instance_func;
|
||||
// Queries a virtual function by name and returns a callback to invoke the requested virtual function.
|
||||
GDExtensionClassGetVirtual get_virtual_func;
|
||||
// Paired with `call_virtual_with_data_func`, this is an alternative to `get_virtual_func` for extensions that
|
||||
// need or benefit from extra data when calling virtual functions.
|
||||
// Returns user data that will be passed to `call_virtual_with_data_func`.
|
||||
// Returning `NULL` from this function signals to Godot that the virtual function is not overridden.
|
||||
// Data returned from this function should be managed by the extension and must be valid until the extension is deinitialized.
|
||||
// You should supply either `get_virtual_func`, or `get_virtual_call_data_func` with `call_virtual_with_data_func`.
|
||||
GDExtensionClassGetVirtualCallData get_virtual_call_data_func;
|
||||
// Used to call virtual functions when `get_virtual_call_data_func` is not null.
|
||||
GDExtensionClassCallVirtualWithData call_virtual_with_data_func;
|
||||
GDExtensionClassGetRID get_rid_func;
|
||||
void *class_userdata; // Per-class user data, later accessible in instance bindings.
|
||||
} GDExtensionClassCreationInfo3;
|
||||
} GDExtensionClassCreationInfo2;
|
||||
|
||||
typedef void *GDExtensionClassLibraryPtr;
|
||||
|
||||
@@ -400,18 +364,13 @@ typedef struct {
|
||||
GDExtensionClassMethodPtrCall ptrcall_func;
|
||||
uint32_t method_flags; // Bitfield of `GDExtensionClassMethodFlags`.
|
||||
|
||||
/* If `has_return_value` is false, `return_value_info` and `return_value_metadata` are ignored.
|
||||
*
|
||||
* @todo Consider dropping `has_return_value` and making the other two properties match `GDExtensionMethodInfo` and `GDExtensionClassVirtualMethod` for consistency in future version of this struct.
|
||||
*/
|
||||
/* If `has_return_value` is false, `return_value_info` and `return_value_metadata` are ignored. */
|
||||
GDExtensionBool has_return_value;
|
||||
GDExtensionPropertyInfo *return_value_info;
|
||||
GDExtensionClassMethodArgumentMetadata return_value_metadata;
|
||||
|
||||
/* Arguments: `arguments_info` and `arguments_metadata` are array of size `argument_count`.
|
||||
* Name and hint information for the argument can be omitted in release builds. Class name should always be present if it applies.
|
||||
*
|
||||
* @todo Consider renaming `arguments_info` to `arguments` for consistency in future version of this struct.
|
||||
*/
|
||||
uint32_t argument_count;
|
||||
GDExtensionPropertyInfo *arguments_info;
|
||||
@@ -422,18 +381,6 @@ typedef struct {
|
||||
GDExtensionVariantPtr *default_arguments;
|
||||
} GDExtensionClassMethodInfo;
|
||||
|
||||
typedef struct {
|
||||
GDExtensionStringNamePtr name;
|
||||
uint32_t method_flags; // Bitfield of `GDExtensionClassMethodFlags`.
|
||||
|
||||
GDExtensionPropertyInfo return_value;
|
||||
GDExtensionClassMethodArgumentMetadata return_value_metadata;
|
||||
|
||||
uint32_t argument_count;
|
||||
GDExtensionPropertyInfo *arguments;
|
||||
GDExtensionClassMethodArgumentMetadata *arguments_metadata;
|
||||
} GDExtensionClassVirtualMethodInfo;
|
||||
|
||||
typedef void (*GDExtensionCallableCustomCall)(void *callable_userdata, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error);
|
||||
typedef GDExtensionBool (*GDExtensionCallableCustomIsValid)(void *callable_userdata);
|
||||
typedef void (*GDExtensionCallableCustomFree)(void *callable_userdata);
|
||||
@@ -444,8 +391,6 @@ typedef GDExtensionBool (*GDExtensionCallableCustomLessThan)(void *callable_user
|
||||
|
||||
typedef void (*GDExtensionCallableCustomToString)(void *callable_userdata, GDExtensionBool *r_is_valid, GDExtensionStringPtr r_out);
|
||||
|
||||
typedef GDExtensionInt (*GDExtensionCallableCustomGetArgumentCount)(void *callable_userdata, GDExtensionBool *r_is_valid);
|
||||
|
||||
typedef struct {
|
||||
/* Only `call_func` and `token` are strictly required, however, `object_id` should be passed if its not a static method.
|
||||
*
|
||||
@@ -475,40 +420,7 @@ typedef struct {
|
||||
GDExtensionCallableCustomLessThan less_than_func;
|
||||
|
||||
GDExtensionCallableCustomToString to_string_func;
|
||||
} GDExtensionCallableCustomInfo; // Deprecated. Use GDExtensionCallableCustomInfo2 instead.
|
||||
|
||||
typedef struct {
|
||||
/* Only `call_func` and `token` are strictly required, however, `object_id` should be passed if its not a static method.
|
||||
*
|
||||
* `token` should point to an address that uniquely identifies the GDExtension (for example, the
|
||||
* `GDExtensionClassLibraryPtr` passed to the entry symbol function.
|
||||
*
|
||||
* `hash_func`, `equal_func`, and `less_than_func` are optional. If not provided both `call_func` and
|
||||
* `callable_userdata` together are used as the identity of the callable for hashing and comparison purposes.
|
||||
*
|
||||
* The hash returned by `hash_func` is cached, `hash_func` will not be called more than once per callable.
|
||||
*
|
||||
* `is_valid_func` is necessary if the validity of the callable can change before destruction.
|
||||
*
|
||||
* `free_func` is necessary if `callable_userdata` needs to be cleaned up when the callable is freed.
|
||||
*/
|
||||
void *callable_userdata;
|
||||
void *token;
|
||||
|
||||
GDObjectInstanceID object_id;
|
||||
|
||||
GDExtensionCallableCustomCall call_func;
|
||||
GDExtensionCallableCustomIsValid is_valid_func;
|
||||
GDExtensionCallableCustomFree free_func;
|
||||
|
||||
GDExtensionCallableCustomHash hash_func;
|
||||
GDExtensionCallableCustomEqual equal_func;
|
||||
GDExtensionCallableCustomLessThan less_than_func;
|
||||
|
||||
GDExtensionCallableCustomToString to_string_func;
|
||||
|
||||
GDExtensionCallableCustomGetArgumentCount get_argument_count_func;
|
||||
} GDExtensionCallableCustomInfo2;
|
||||
} GDExtensionCallableCustomInfo;
|
||||
|
||||
/* SCRIPT INSTANCE EXTENSION */
|
||||
|
||||
@@ -517,8 +429,7 @@ typedef void *GDExtensionScriptInstanceDataPtr; // Pointer to custom ScriptInsta
|
||||
typedef GDExtensionBool (*GDExtensionScriptInstanceSet)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionConstVariantPtr p_value);
|
||||
typedef GDExtensionBool (*GDExtensionScriptInstanceGet)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret);
|
||||
typedef const GDExtensionPropertyInfo *(*GDExtensionScriptInstanceGetPropertyList)(GDExtensionScriptInstanceDataPtr p_instance, uint32_t *r_count);
|
||||
typedef void (*GDExtensionScriptInstanceFreePropertyList)(GDExtensionScriptInstanceDataPtr p_instance, const GDExtensionPropertyInfo *p_list); // Deprecated. Use GDExtensionScriptInstanceFreePropertyList2 instead.
|
||||
typedef void (*GDExtensionScriptInstanceFreePropertyList2)(GDExtensionScriptInstanceDataPtr p_instance, const GDExtensionPropertyInfo *p_list, uint32_t p_count);
|
||||
typedef void (*GDExtensionScriptInstanceFreePropertyList)(GDExtensionScriptInstanceDataPtr p_instance, const GDExtensionPropertyInfo *p_list);
|
||||
typedef GDExtensionBool (*GDExtensionScriptInstanceGetClassCategory)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionPropertyInfo *p_class_category);
|
||||
|
||||
typedef GDExtensionVariantType (*GDExtensionScriptInstanceGetPropertyType)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionBool *r_is_valid);
|
||||
@@ -532,13 +443,10 @@ typedef void (*GDExtensionScriptInstancePropertyStateAdd)(GDExtensionConstString
|
||||
typedef void (*GDExtensionScriptInstanceGetPropertyState)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionScriptInstancePropertyStateAdd p_add_func, void *p_userdata);
|
||||
|
||||
typedef const GDExtensionMethodInfo *(*GDExtensionScriptInstanceGetMethodList)(GDExtensionScriptInstanceDataPtr p_instance, uint32_t *r_count);
|
||||
typedef void (*GDExtensionScriptInstanceFreeMethodList)(GDExtensionScriptInstanceDataPtr p_instance, const GDExtensionMethodInfo *p_list); // Deprecated. Use GDExtensionScriptInstanceFreeMethodList2 instead.
|
||||
typedef void (*GDExtensionScriptInstanceFreeMethodList2)(GDExtensionScriptInstanceDataPtr p_instance, const GDExtensionMethodInfo *p_list, uint32_t p_count);
|
||||
typedef void (*GDExtensionScriptInstanceFreeMethodList)(GDExtensionScriptInstanceDataPtr p_instance, const GDExtensionMethodInfo *p_list);
|
||||
|
||||
typedef GDExtensionBool (*GDExtensionScriptInstanceHasMethod)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name);
|
||||
|
||||
typedef GDExtensionInt (*GDExtensionScriptInstanceGetMethodArgumentCount)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionBool *r_is_valid);
|
||||
|
||||
typedef void (*GDExtensionScriptInstanceCall)(GDExtensionScriptInstanceDataPtr p_self, GDExtensionConstStringNamePtr p_method, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error);
|
||||
typedef void (*GDExtensionScriptInstanceNotification)(GDExtensionScriptInstanceDataPtr p_instance, int32_t p_what); // Deprecated. Use GDExtensionScriptInstanceNotification2 instead.
|
||||
typedef void (*GDExtensionScriptInstanceNotification2)(GDExtensionScriptInstanceDataPtr p_instance, int32_t p_what, GDExtensionBool p_reversed);
|
||||
@@ -595,7 +503,7 @@ typedef struct {
|
||||
|
||||
GDExtensionScriptInstanceFree free_func;
|
||||
|
||||
} GDExtensionScriptInstanceInfo; // Deprecated. Use GDExtensionScriptInstanceInfo3 instead.
|
||||
} GDExtensionScriptInstanceInfo; // Deprecated. Use GDExtensionScriptInstanceInfo2 instead.
|
||||
|
||||
typedef struct {
|
||||
GDExtensionScriptInstanceSet set_func;
|
||||
@@ -636,50 +544,7 @@ typedef struct {
|
||||
|
||||
GDExtensionScriptInstanceFree free_func;
|
||||
|
||||
} GDExtensionScriptInstanceInfo2; // Deprecated. Use GDExtensionScriptInstanceInfo3 instead.
|
||||
|
||||
typedef struct {
|
||||
GDExtensionScriptInstanceSet set_func;
|
||||
GDExtensionScriptInstanceGet get_func;
|
||||
GDExtensionScriptInstanceGetPropertyList get_property_list_func;
|
||||
GDExtensionScriptInstanceFreePropertyList2 free_property_list_func;
|
||||
GDExtensionScriptInstanceGetClassCategory get_class_category_func; // Optional. Set to NULL for the default behavior.
|
||||
|
||||
GDExtensionScriptInstancePropertyCanRevert property_can_revert_func;
|
||||
GDExtensionScriptInstancePropertyGetRevert property_get_revert_func;
|
||||
|
||||
GDExtensionScriptInstanceGetOwner get_owner_func;
|
||||
GDExtensionScriptInstanceGetPropertyState get_property_state_func;
|
||||
|
||||
GDExtensionScriptInstanceGetMethodList get_method_list_func;
|
||||
GDExtensionScriptInstanceFreeMethodList2 free_method_list_func;
|
||||
GDExtensionScriptInstanceGetPropertyType get_property_type_func;
|
||||
GDExtensionScriptInstanceValidateProperty validate_property_func;
|
||||
|
||||
GDExtensionScriptInstanceHasMethod has_method_func;
|
||||
|
||||
GDExtensionScriptInstanceGetMethodArgumentCount get_method_argument_count_func;
|
||||
|
||||
GDExtensionScriptInstanceCall call_func;
|
||||
GDExtensionScriptInstanceNotification2 notification_func;
|
||||
|
||||
GDExtensionScriptInstanceToString to_string_func;
|
||||
|
||||
GDExtensionScriptInstanceRefCountIncremented refcount_incremented_func;
|
||||
GDExtensionScriptInstanceRefCountDecremented refcount_decremented_func;
|
||||
|
||||
GDExtensionScriptInstanceGetScript get_script_func;
|
||||
|
||||
GDExtensionScriptInstanceIsPlaceholder is_placeholder_func;
|
||||
|
||||
GDExtensionScriptInstanceSet set_fallback_func;
|
||||
GDExtensionScriptInstanceGet get_fallback_func;
|
||||
|
||||
GDExtensionScriptInstanceGetLanguage get_language_func;
|
||||
|
||||
GDExtensionScriptInstanceFree free_func;
|
||||
|
||||
} GDExtensionScriptInstanceInfo3;
|
||||
} GDExtensionScriptInstanceInfo2;
|
||||
|
||||
/* INITIALIZATION */
|
||||
|
||||
@@ -1582,7 +1447,6 @@ typedef void (*GDExtensionInterfaceStringNewWithLatin1CharsAndLen)(GDExtensionUn
|
||||
/**
|
||||
* @name string_new_with_utf8_chars_and_len
|
||||
* @since 4.1
|
||||
* @deprecated in Godot 4.3. Use `string_new_with_utf8_chars_and_len2` instead.
|
||||
*
|
||||
* Creates a String from a UTF-8 encoded C string with the given length.
|
||||
*
|
||||
@@ -1592,24 +1456,9 @@ typedef void (*GDExtensionInterfaceStringNewWithLatin1CharsAndLen)(GDExtensionUn
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceStringNewWithUtf8CharsAndLen)(GDExtensionUninitializedStringPtr r_dest, const char *p_contents, GDExtensionInt p_size);
|
||||
|
||||
/**
|
||||
* @name string_new_with_utf8_chars_and_len2
|
||||
* @since 4.3
|
||||
*
|
||||
* Creates a String from a UTF-8 encoded C string with the given length.
|
||||
*
|
||||
* @param r_dest A pointer to a Variant to hold the newly created String.
|
||||
* @param p_contents A pointer to a UTF-8 encoded C string.
|
||||
* @param p_size The number of bytes (not code units).
|
||||
*
|
||||
* @return Error code signifying if the operation successful.
|
||||
*/
|
||||
typedef GDExtensionInt (*GDExtensionInterfaceStringNewWithUtf8CharsAndLen2)(GDExtensionUninitializedStringPtr r_dest, const char *p_contents, GDExtensionInt p_size);
|
||||
|
||||
/**
|
||||
* @name string_new_with_utf16_chars_and_len
|
||||
* @since 4.1
|
||||
* @deprecated in Godot 4.3. Use `string_new_with_utf16_chars_and_len2` instead.
|
||||
*
|
||||
* Creates a String from a UTF-16 encoded C string with the given length.
|
||||
*
|
||||
@@ -1619,21 +1468,6 @@ typedef GDExtensionInt (*GDExtensionInterfaceStringNewWithUtf8CharsAndLen2)(GDEx
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceStringNewWithUtf16CharsAndLen)(GDExtensionUninitializedStringPtr r_dest, const char16_t *p_contents, GDExtensionInt p_char_count);
|
||||
|
||||
/**
|
||||
* @name string_new_with_utf16_chars_and_len2
|
||||
* @since 4.3
|
||||
*
|
||||
* Creates a String from a UTF-16 encoded C string with the given length.
|
||||
*
|
||||
* @param r_dest A pointer to a Variant to hold the newly created String.
|
||||
* @param p_contents A pointer to a UTF-16 encoded C string.
|
||||
* @param p_size The number of characters (not bytes).
|
||||
* @param p_default_little_endian If true, UTF-16 use little endian.
|
||||
*
|
||||
* @return Error code signifying if the operation successful.
|
||||
*/
|
||||
typedef GDExtensionInt (*GDExtensionInterfaceStringNewWithUtf16CharsAndLen2)(GDExtensionUninitializedStringPtr r_dest, const char16_t *p_contents, GDExtensionInt p_char_count, GDExtensionBool p_default_little_endian);
|
||||
|
||||
/**
|
||||
* @name string_new_with_utf32_chars_and_len
|
||||
* @since 4.1
|
||||
@@ -1930,36 +1764,6 @@ typedef void (*GDExtensionInterfaceFileAccessStoreBuffer)(GDExtensionObjectPtr p
|
||||
*/
|
||||
typedef uint64_t (*GDExtensionInterfaceFileAccessGetBuffer)(GDExtensionConstObjectPtr p_instance, uint8_t *p_dst, uint64_t p_length);
|
||||
|
||||
/* INTERFACE: Image Utilities */
|
||||
|
||||
/**
|
||||
* @name image_ptrw
|
||||
* @since 4.3
|
||||
*
|
||||
* Returns writable pointer to internal Image buffer.
|
||||
*
|
||||
* @param p_instance A pointer to a Image object.
|
||||
*
|
||||
* @return Pointer to internal Image buffer.
|
||||
*
|
||||
* @see Image::ptrw()
|
||||
*/
|
||||
typedef uint8_t *(*GDExtensionInterfaceImagePtrw)(GDExtensionObjectPtr p_instance);
|
||||
|
||||
/**
|
||||
* @name image_ptr
|
||||
* @since 4.3
|
||||
*
|
||||
* Returns read only pointer to internal Image buffer.
|
||||
*
|
||||
* @param p_instance A pointer to a Image object.
|
||||
*
|
||||
* @return Pointer to internal Image buffer.
|
||||
*
|
||||
* @see Image::ptr()
|
||||
*/
|
||||
typedef const uint8_t *(*GDExtensionInterfaceImagePtr)(GDExtensionObjectPtr p_instance);
|
||||
|
||||
/* INTERFACE: WorkerThreadPool Utilities */
|
||||
|
||||
/**
|
||||
@@ -2025,6 +1829,32 @@ typedef uint8_t *(*GDExtensionInterfacePackedByteArrayOperatorIndex)(GDExtension
|
||||
*/
|
||||
typedef const uint8_t *(*GDExtensionInterfacePackedByteArrayOperatorIndexConst)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index);
|
||||
|
||||
/**
|
||||
* @name packed_color_array_operator_index
|
||||
* @since 4.1
|
||||
*
|
||||
* Gets a pointer to a color in a PackedColorArray.
|
||||
*
|
||||
* @param p_self A pointer to a PackedColorArray object.
|
||||
* @param p_index The index of the Color to get.
|
||||
*
|
||||
* @return A pointer to the requested Color.
|
||||
*/
|
||||
typedef GDExtensionTypePtr (*GDExtensionInterfacePackedColorArrayOperatorIndex)(GDExtensionTypePtr p_self, GDExtensionInt p_index);
|
||||
|
||||
/**
|
||||
* @name packed_color_array_operator_index_const
|
||||
* @since 4.1
|
||||
*
|
||||
* Gets a const pointer to a color in a PackedColorArray.
|
||||
*
|
||||
* @param p_self A const pointer to a const PackedColorArray object.
|
||||
* @param p_index The index of the Color to get.
|
||||
*
|
||||
* @return A const pointer to the requested Color.
|
||||
*/
|
||||
typedef GDExtensionTypePtr (*GDExtensionInterfacePackedColorArrayOperatorIndexConst)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index);
|
||||
|
||||
/**
|
||||
* @name packed_float32_array_operator_index
|
||||
* @since 4.1
|
||||
@@ -2207,58 +2037,6 @@ typedef GDExtensionTypePtr (*GDExtensionInterfacePackedVector3ArrayOperatorIndex
|
||||
*/
|
||||
typedef GDExtensionTypePtr (*GDExtensionInterfacePackedVector3ArrayOperatorIndexConst)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index);
|
||||
|
||||
/**
|
||||
* @name packed_vector4_array_operator_index
|
||||
* @since 4.3
|
||||
*
|
||||
* Gets a pointer to a Vector4 in a PackedVector4Array.
|
||||
*
|
||||
* @param p_self A pointer to a PackedVector4Array object.
|
||||
* @param p_index The index of the Vector4 to get.
|
||||
*
|
||||
* @return A pointer to the requested Vector4.
|
||||
*/
|
||||
typedef GDExtensionTypePtr (*GDExtensionInterfacePackedVector4ArrayOperatorIndex)(GDExtensionTypePtr p_self, GDExtensionInt p_index);
|
||||
|
||||
/**
|
||||
* @name packed_vector4_array_operator_index_const
|
||||
* @since 4.3
|
||||
*
|
||||
* Gets a const pointer to a Vector4 in a PackedVector4Array.
|
||||
*
|
||||
* @param p_self A const pointer to a PackedVector4Array object.
|
||||
* @param p_index The index of the Vector4 to get.
|
||||
*
|
||||
* @return A const pointer to the requested Vector4.
|
||||
*/
|
||||
typedef GDExtensionTypePtr (*GDExtensionInterfacePackedVector4ArrayOperatorIndexConst)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index);
|
||||
|
||||
/**
|
||||
* @name packed_color_array_operator_index
|
||||
* @since 4.1
|
||||
*
|
||||
* Gets a pointer to a color in a PackedColorArray.
|
||||
*
|
||||
* @param p_self A pointer to a PackedColorArray object.
|
||||
* @param p_index The index of the Color to get.
|
||||
*
|
||||
* @return A pointer to the requested Color.
|
||||
*/
|
||||
typedef GDExtensionTypePtr (*GDExtensionInterfacePackedColorArrayOperatorIndex)(GDExtensionTypePtr p_self, GDExtensionInt p_index);
|
||||
|
||||
/**
|
||||
* @name packed_color_array_operator_index_const
|
||||
* @since 4.1
|
||||
*
|
||||
* Gets a const pointer to a color in a PackedColorArray.
|
||||
*
|
||||
* @param p_self A const pointer to a PackedColorArray object.
|
||||
* @param p_index The index of the Color to get.
|
||||
*
|
||||
* @return A const pointer to the requested Color.
|
||||
*/
|
||||
typedef GDExtensionTypePtr (*GDExtensionInterfacePackedColorArrayOperatorIndexConst)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index);
|
||||
|
||||
/**
|
||||
* @name array_operator_index
|
||||
* @since 4.1
|
||||
@@ -2445,9 +2223,6 @@ typedef void (*GDExtensionInterfaceObjectSetInstance)(GDExtensionObjectPtr p_o,
|
||||
*
|
||||
* Gets the class name of an Object.
|
||||
*
|
||||
* If the GDExtension wraps the Godot object in an abstraction specific to its class, this is the
|
||||
* function that should be used to determine which wrapper to use.
|
||||
*
|
||||
* @param p_object A pointer to the Object.
|
||||
* @param p_library A pointer the library received by the GDExtension's entry point function.
|
||||
* @param r_class_name A pointer to a String to receive the class name.
|
||||
@@ -2493,34 +2268,6 @@ typedef GDExtensionObjectPtr (*GDExtensionInterfaceObjectGetInstanceFromId)(GDOb
|
||||
*/
|
||||
typedef GDObjectInstanceID (*GDExtensionInterfaceObjectGetInstanceId)(GDExtensionConstObjectPtr p_object);
|
||||
|
||||
/**
|
||||
* @name object_has_script_method
|
||||
* @since 4.3
|
||||
*
|
||||
* Checks if this object has a script with the given method.
|
||||
*
|
||||
* @param p_object A pointer to the Object.
|
||||
* @param p_method A pointer to a StringName identifying the method.
|
||||
*
|
||||
* @returns true if the object has a script and that script has a method with the given name. Returns false if the object has no script.
|
||||
*/
|
||||
typedef GDExtensionBool (*GDExtensionInterfaceObjectHasScriptMethod)(GDExtensionConstObjectPtr p_object, GDExtensionConstStringNamePtr p_method);
|
||||
|
||||
/**
|
||||
* @name object_call_script_method
|
||||
* @since 4.3
|
||||
*
|
||||
* Call the given script method on this object.
|
||||
*
|
||||
* @param p_object A pointer to the Object.
|
||||
* @param p_method A pointer to a StringName identifying the method.
|
||||
* @param p_args A pointer to a C array of Variant.
|
||||
* @param p_argument_count The number of arguments.
|
||||
* @param r_return A pointer a Variant which will be assigned the return value.
|
||||
* @param r_error A pointer the structure which will hold error information.
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceObjectCallScriptMethod)(GDExtensionObjectPtr p_object, GDExtensionConstStringNamePtr p_method, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionUninitializedVariantPtr r_return, GDExtensionCallError *r_error);
|
||||
|
||||
/* INTERFACE: Reference */
|
||||
|
||||
/**
|
||||
@@ -2551,7 +2298,7 @@ typedef void (*GDExtensionInterfaceRefSetObject)(GDExtensionRefPtr p_ref, GDExte
|
||||
/**
|
||||
* @name script_instance_create
|
||||
* @since 4.1
|
||||
* @deprecated in Godot 4.2. Use `script_instance_create3` instead.
|
||||
* @deprecated in Godot 4.2. Use `script_instance_create2` instead.
|
||||
*
|
||||
* Creates a script instance that contains the given info and instance data.
|
||||
*
|
||||
@@ -2565,7 +2312,6 @@ typedef GDExtensionScriptInstancePtr (*GDExtensionInterfaceScriptInstanceCreate)
|
||||
/**
|
||||
* @name script_instance_create2
|
||||
* @since 4.2
|
||||
* @deprecated in Godot 4.3. Use `script_instance_create3` instead.
|
||||
*
|
||||
* Creates a script instance that contains the given info and instance data.
|
||||
*
|
||||
@@ -2576,19 +2322,6 @@ typedef GDExtensionScriptInstancePtr (*GDExtensionInterfaceScriptInstanceCreate)
|
||||
*/
|
||||
typedef GDExtensionScriptInstancePtr (*GDExtensionInterfaceScriptInstanceCreate2)(const GDExtensionScriptInstanceInfo2 *p_info, GDExtensionScriptInstanceDataPtr p_instance_data);
|
||||
|
||||
/**
|
||||
* @name script_instance_create3
|
||||
* @since 4.3
|
||||
*
|
||||
* Creates a script instance that contains the given info and instance data.
|
||||
*
|
||||
* @param p_info A pointer to a GDExtensionScriptInstanceInfo3 struct.
|
||||
* @param p_instance_data A pointer to a data representing the script instance in the GDExtension. This will be passed to all the function pointers on p_info.
|
||||
*
|
||||
* @return A pointer to a ScriptInstanceExtension object.
|
||||
*/
|
||||
typedef GDExtensionScriptInstancePtr (*GDExtensionInterfaceScriptInstanceCreate3)(const GDExtensionScriptInstanceInfo3 *p_info, GDExtensionScriptInstanceDataPtr p_instance_data);
|
||||
|
||||
/**
|
||||
* @name placeholder_script_instance_create
|
||||
* @since 4.2
|
||||
@@ -2638,7 +2371,6 @@ typedef GDExtensionScriptInstanceDataPtr (*GDExtensionInterfaceObjectGetScriptIn
|
||||
/**
|
||||
* @name callable_custom_create
|
||||
* @since 4.2
|
||||
* @deprecated in Godot 4.3. Use `callable_custom_create2` instead.
|
||||
*
|
||||
* Creates a custom Callable object from a function pointer.
|
||||
*
|
||||
@@ -2649,19 +2381,6 @@ typedef GDExtensionScriptInstanceDataPtr (*GDExtensionInterfaceObjectGetScriptIn
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceCallableCustomCreate)(GDExtensionUninitializedTypePtr r_callable, GDExtensionCallableCustomInfo *p_callable_custom_info);
|
||||
|
||||
/**
|
||||
* @name callable_custom_create2
|
||||
* @since 4.3
|
||||
*
|
||||
* Creates a custom Callable object from a function pointer.
|
||||
*
|
||||
* Provided struct can be safely freed once the function returns.
|
||||
*
|
||||
* @param r_callable A pointer that will receive the new Callable.
|
||||
* @param p_callable_custom_info The info required to construct a Callable.
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceCallableCustomCreate2)(GDExtensionUninitializedTypePtr r_callable, GDExtensionCallableCustomInfo2 *p_callable_custom_info);
|
||||
|
||||
/**
|
||||
* @name callable_custom_get_userdata
|
||||
* @since 4.2
|
||||
@@ -2722,7 +2441,7 @@ typedef void *(*GDExtensionInterfaceClassdbGetClassTag)(GDExtensionConstStringNa
|
||||
/**
|
||||
* @name classdb_register_extension_class
|
||||
* @since 4.1
|
||||
* @deprecated in Godot 4.2. Use `classdb_register_extension_class3` instead.
|
||||
* @deprecated in Godot 4.2. Use `classdb_register_extension_class2` instead.
|
||||
*
|
||||
* Registers an extension class in the ClassDB.
|
||||
*
|
||||
@@ -2738,7 +2457,6 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass)(GDExtensionCla
|
||||
/**
|
||||
* @name classdb_register_extension_class2
|
||||
* @since 4.2
|
||||
* @deprecated in Godot 4.3. Use `classdb_register_extension_class3` instead.
|
||||
*
|
||||
* Registers an extension class in the ClassDB.
|
||||
*
|
||||
@@ -2751,21 +2469,6 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass)(GDExtensionCla
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass2)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo2 *p_extension_funcs);
|
||||
|
||||
/**
|
||||
* @name classdb_register_extension_class3
|
||||
* @since 4.3
|
||||
*
|
||||
* Registers an extension class in the ClassDB.
|
||||
*
|
||||
* Provided struct can be safely freed once the function returns.
|
||||
*
|
||||
* @param p_library A pointer the library received by the GDExtension's entry point function.
|
||||
* @param p_class_name A pointer to a StringName with the class name.
|
||||
* @param p_parent_class_name A pointer to a StringName with the parent class name.
|
||||
* @param p_extension_funcs A pointer to a GDExtensionClassCreationInfo2 struct.
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass3)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo3 *p_extension_funcs);
|
||||
|
||||
/**
|
||||
* @name classdb_register_extension_class_method
|
||||
* @since 4.1
|
||||
@@ -2780,36 +2483,18 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass3)(GDExtensionCl
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassMethod)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, const GDExtensionClassMethodInfo *p_method_info);
|
||||
|
||||
/**
|
||||
* @name classdb_register_extension_class_virtual_method
|
||||
* @since 4.3
|
||||
*
|
||||
* Registers a virtual method on an extension class in ClassDB, that can be implemented by scripts or other extensions.
|
||||
*
|
||||
* Provided struct can be safely freed once the function returns.
|
||||
*
|
||||
* @param p_library A pointer the library received by the GDExtension's entry point function.
|
||||
* @param p_class_name A pointer to a StringName with the class name.
|
||||
* @param p_method_info A pointer to a GDExtensionClassMethodInfo struct.
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassVirtualMethod)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, const GDExtensionClassVirtualMethodInfo *p_method_info);
|
||||
|
||||
/**
|
||||
* @name classdb_register_extension_class_integer_constant
|
||||
* @since 4.1
|
||||
*
|
||||
* Registers an integer constant on an extension class in the ClassDB.
|
||||
*
|
||||
* Note about registering bitfield values (if p_is_bitfield is true): even though p_constant_value is signed, language bindings are
|
||||
* advised to treat bitfields as uint64_t, since this is generally clearer and can prevent mistakes like using -1 for setting all bits.
|
||||
* Language APIs should thus provide an abstraction that registers bitfields (uint64_t) separately from regular constants (int64_t).
|
||||
*
|
||||
* @param p_library A pointer the library received by the GDExtension's entry point function.
|
||||
* @param p_class_name A pointer to a StringName with the class name.
|
||||
* @param p_enum_name A pointer to a StringName with the enum name.
|
||||
* @param p_constant_name A pointer to a StringName with the constant name.
|
||||
* @param p_constant_value The constant value.
|
||||
* @param p_is_bitfield Whether or not this constant is part of a bitfield.
|
||||
* @param p_is_bitfield Whether or not this is a bit field.
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_enum_name, GDExtensionConstStringNamePtr p_constant_name, GDExtensionInt p_constant_value, GDExtensionBool p_is_bitfield);
|
||||
|
||||
@@ -2932,31 +2617,6 @@ typedef void (*GDExtensionInterfaceEditorAddPlugin)(GDExtensionConstStringNamePt
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceEditorRemovePlugin)(GDExtensionConstStringNamePtr p_class_name);
|
||||
|
||||
/**
|
||||
* @name editor_help_load_xml_from_utf8_chars
|
||||
* @since 4.3
|
||||
*
|
||||
* Loads new XML-formatted documentation data in the editor.
|
||||
*
|
||||
* The provided pointer can be immediately freed once the function returns.
|
||||
*
|
||||
* @param p_data A pointer to a UTF-8 encoded C string (null terminated).
|
||||
*/
|
||||
typedef void (*GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8Chars)(const char *p_data);
|
||||
|
||||
/**
|
||||
* @name editor_help_load_xml_from_utf8_chars_and_len
|
||||
* @since 4.3
|
||||
*
|
||||
* Loads new XML-formatted documentation data in the editor.
|
||||
*
|
||||
* The provided pointer can be immediately freed once the function returns.
|
||||
*
|
||||
* @param p_data A pointer to a UTF-8 encoded C string.
|
||||
* @param p_size The number of bytes (not code units).
|
||||
*/
|
||||
typedef void (*GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8CharsAndLen)(const char *p_data, GDExtensionInt p_size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -230,7 +230,9 @@ template <typename T>
|
||||
struct PtrToArg<Ref<T>> {
|
||||
_FORCE_INLINE_ static Ref<T> convert(const void *p_ptr) {
|
||||
GDExtensionRefPtr ref = (GDExtensionRefPtr)p_ptr;
|
||||
ERR_FAIL_NULL_V(p_ptr, Ref<T>());
|
||||
if (unlikely(!p_ptr)) {
|
||||
return Ref<T>();
|
||||
}
|
||||
return Ref<T>(reinterpret_cast<T *>(godot::internal::get_object_instance_binding(godot::internal::gdextension_interface_ref_get_object(ref))));
|
||||
}
|
||||
|
||||
@@ -254,15 +256,17 @@ struct PtrToArg<const Ref<T> &> {
|
||||
|
||||
_FORCE_INLINE_ static Ref<T> convert(const void *p_ptr) {
|
||||
GDExtensionRefPtr ref = const_cast<GDExtensionRefPtr>(p_ptr);
|
||||
ERR_FAIL_NULL_V(p_ptr, Ref<T>());
|
||||
if (unlikely(!p_ptr)) {
|
||||
return Ref<T>();
|
||||
}
|
||||
return Ref<T>(reinterpret_cast<T *>(godot::internal::get_object_instance_binding(godot::internal::gdextension_interface_ref_get_object(ref))));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct GetTypeInfo<Ref<T>, typename EnableIf<TypeInherits<RefCounted, T>::value>::type> {
|
||||
static constexpr GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_OBJECT;
|
||||
static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;
|
||||
static const GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_OBJECT;
|
||||
static const GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;
|
||||
|
||||
static inline PropertyInfo get_class_info() {
|
||||
return make_property_info(Variant::Type::OBJECT, "", PROPERTY_HINT_RESOURCE_TYPE, T::get_class_static());
|
||||
@@ -271,8 +275,8 @@ struct GetTypeInfo<Ref<T>, typename EnableIf<TypeInherits<RefCounted, T>::value>
|
||||
|
||||
template <typename T>
|
||||
struct GetTypeInfo<const Ref<T> &, typename EnableIf<TypeInherits<RefCounted, T>::value>::type> {
|
||||
static constexpr GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_OBJECT;
|
||||
static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;
|
||||
static const GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_OBJECT;
|
||||
static const GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;
|
||||
|
||||
static inline PropertyInfo get_class_info() {
|
||||
return make_property_info(Variant::Type::OBJECT, "", PROPERTY_HINT_RESOURCE_TYPE, T::get_class_static());
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
#include <godot_cpp/core/property_info.hpp>
|
||||
|
||||
#include <godot_cpp/templates/list.hpp>
|
||||
#include <godot_cpp/templates/vector.hpp>
|
||||
|
||||
#include <godot_cpp/godot.hpp>
|
||||
|
||||
@@ -46,31 +45,13 @@ class ClassDB;
|
||||
|
||||
typedef void GodotObject;
|
||||
|
||||
template <typename T, std::enable_if_t<std::is_base_of<::godot::Wrapped, T>::value, bool> = true>
|
||||
_ALWAYS_INLINE_ void _pre_initialize();
|
||||
|
||||
// Base for all engine classes, to contain the pointer to the engine instance.
|
||||
class Wrapped {
|
||||
friend class GDExtensionBinding;
|
||||
friend class ClassDB;
|
||||
friend void postinitialize_handler(Wrapped *);
|
||||
|
||||
template <typename T, std::enable_if_t<std::is_base_of<::godot::Wrapped, T>::value, bool>>
|
||||
friend _ALWAYS_INLINE_ void _pre_initialize();
|
||||
|
||||
thread_local static const StringName *_constructing_extension_class_name;
|
||||
thread_local static const GDExtensionInstanceBindingCallbacks *_constructing_class_binding_callbacks;
|
||||
|
||||
template <typename T>
|
||||
_ALWAYS_INLINE_ static void _set_construct_info() {
|
||||
_constructing_extension_class_name = T::_get_extension_class_name();
|
||||
_constructing_class_binding_callbacks = &T::_gde_binding_callbacks;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual bool _is_extension_class() const { return false; }
|
||||
static const StringName *_get_extension_class_name(); // This is needed to retrieve the class name before the godot object has its _extension and _extension_instance members assigned.
|
||||
|
||||
#ifdef HOT_RELOAD_ENABLED
|
||||
struct RecreateInstance {
|
||||
GDExtensionClassInstancePtr wrapper;
|
||||
@@ -80,6 +61,9 @@ protected:
|
||||
inline static RecreateInstance *recreate_instance = nullptr;
|
||||
#endif
|
||||
|
||||
virtual const StringName *_get_extension_class_name() const; // This is needed to retrieve the class name before the godot object has its _extension and _extension_instance members assigned.
|
||||
virtual const GDExtensionInstanceBindingCallbacks *_get_bindings_callbacks() const = 0;
|
||||
|
||||
void _notification(int p_what) {}
|
||||
bool _set(const StringName &p_name, const Variant &p_property) { return false; }
|
||||
bool _get(const StringName &p_name, Variant &r_property) const { return false; }
|
||||
@@ -93,7 +77,7 @@ protected:
|
||||
static GDExtensionBool set_bind(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionConstVariantPtr p_value) { return false; }
|
||||
static GDExtensionBool get_bind(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret) { return false; }
|
||||
static const GDExtensionPropertyInfo *get_property_list_bind(GDExtensionClassInstancePtr p_instance, uint32_t *r_count) { return nullptr; }
|
||||
static void free_property_list_bind(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list, uint32_t p_count) {}
|
||||
static void free_property_list_bind(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list) {}
|
||||
static GDExtensionBool property_can_revert_bind(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name) { return false; }
|
||||
static GDExtensionBool property_get_revert_bind(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret) { return false; }
|
||||
static GDExtensionBool validate_property_bind(GDExtensionClassInstancePtr p_instance, GDExtensionPropertyInfo *p_property) { return false; }
|
||||
@@ -124,31 +108,6 @@ public:
|
||||
GodotObject *_owner = nullptr;
|
||||
};
|
||||
|
||||
template <typename T, std::enable_if_t<std::is_base_of<::godot::Wrapped, T>::value, bool>>
|
||||
_ALWAYS_INLINE_ void _pre_initialize() {
|
||||
Wrapped::_set_construct_info<T>();
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void snarray_add_str(Vector<StringName> &arr) {
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void snarray_add_str(Vector<StringName> &arr, const StringName &p_str) {
|
||||
arr.push_back(p_str);
|
||||
}
|
||||
|
||||
template <typename... P>
|
||||
_FORCE_INLINE_ void snarray_add_str(Vector<StringName> &arr, const StringName &p_str, P... p_args) {
|
||||
arr.push_back(p_str);
|
||||
snarray_add_str(arr, p_args...);
|
||||
}
|
||||
|
||||
template <typename... P>
|
||||
_FORCE_INLINE_ Vector<StringName> snarray(P... p_args) {
|
||||
Vector<StringName> arr;
|
||||
snarray_add_str(arr, p_args...);
|
||||
return arr;
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
GDExtensionPropertyInfo *create_c_property_list(const ::godot::List<::godot::PropertyInfo> &plist_cpp, uint32_t *r_size);
|
||||
@@ -181,16 +140,17 @@ struct EngineClassRegistration {
|
||||
private: \
|
||||
void operator=(const m_class & /*p_rval*/) {} \
|
||||
friend class ::godot::ClassDB; \
|
||||
friend class ::godot::Wrapped; \
|
||||
\
|
||||
protected: \
|
||||
virtual bool _is_extension_class() const override { return true; } \
|
||||
\
|
||||
static const ::godot::StringName *_get_extension_class_name() { \
|
||||
const ::godot::StringName &string_name = get_class_static(); \
|
||||
virtual const ::godot::StringName *_get_extension_class_name() const override { \
|
||||
static ::godot::StringName string_name = get_class_static(); \
|
||||
return &string_name; \
|
||||
} \
|
||||
\
|
||||
virtual const GDExtensionInstanceBindingCallbacks *_get_bindings_callbacks() const override { \
|
||||
return &_gde_binding_callbacks; \
|
||||
} \
|
||||
\
|
||||
static void (*_get_bind_methods())() { \
|
||||
return &m_class::_bind_methods; \
|
||||
} \
|
||||
@@ -316,7 +276,7 @@ public:
|
||||
return ::godot::internal::create_c_property_list(plist_cpp, r_count); \
|
||||
} \
|
||||
\
|
||||
static void free_property_list_bind(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list, uint32_t /*p_count*/) { \
|
||||
static void free_property_list_bind(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list) { \
|
||||
if (p_instance) { \
|
||||
m_class *cls = reinterpret_cast<m_class *>(p_instance); \
|
||||
cls->plist_owned.clear(); \
|
||||
@@ -411,9 +371,12 @@ private:
|
||||
inline static ::godot::internal::EngineClassRegistration<m_class> _gde_engine_class_registration_helper; \
|
||||
void operator=(const m_class &p_rval) {} \
|
||||
friend class ::godot::ClassDB; \
|
||||
friend class ::godot::Wrapped; \
|
||||
\
|
||||
protected: \
|
||||
virtual const GDExtensionInstanceBindingCallbacks *_get_bindings_callbacks() const override { \
|
||||
return &_gde_binding_callbacks; \
|
||||
} \
|
||||
\
|
||||
m_class(const char *p_godot_class) : m_inherits(p_godot_class) {} \
|
||||
m_class(GodotObject *p_godot_object) : m_inherits(p_godot_object) {} \
|
||||
\
|
||||
@@ -501,14 +464,4 @@ private:
|
||||
// Don't use this for your classes, use GDCLASS() instead.
|
||||
#define GDEXTENSION_CLASS(m_class, m_inherits) GDEXTENSION_CLASS_ALIAS(m_class, m_class, m_inherits)
|
||||
|
||||
#define GDVIRTUAL_CALL(m_name, ...) _gdvirtual_##m_name##_call<false>(__VA_ARGS__)
|
||||
#define GDVIRTUAL_CALL_PTR(m_obj, m_name, ...) m_obj->_gdvirtual_##m_name##_call<false>(__VA_ARGS__)
|
||||
|
||||
#define GDVIRTUAL_REQUIRED_CALL(m_name, ...) _gdvirtual_##m_name##_call<true>(__VA_ARGS__)
|
||||
#define GDVIRTUAL_REQUIRED_CALL_PTR(m_obj, m_name, ...) m_obj->_gdvirtual_##m_name##_call<true>(__VA_ARGS__)
|
||||
|
||||
#define GDVIRTUAL_BIND(m_name, ...) ::godot::ClassDB::add_virtual_method(get_class_static(), _gdvirtual_##m_name##_get_method_info(), ::godot::snarray(__VA_ARGS__));
|
||||
#define GDVIRTUAL_IS_OVERRIDDEN(m_name) _gdvirtual_##m_name##_overridden()
|
||||
#define GDVIRTUAL_IS_OVERRIDDEN_PTR(m_obj, m_name) m_obj->_gdvirtual_##m_name##_overridden()
|
||||
|
||||
#endif // GODOT_WRAPPED_HPP
|
||||
|
||||
@@ -113,7 +113,7 @@ private:
|
||||
static void bind_method_godot(const StringName &p_class_name, MethodBind *p_method);
|
||||
|
||||
template <typename T, bool is_abstract>
|
||||
static void _register_class(bool p_virtual = false, bool p_exposed = true, bool p_runtime = false);
|
||||
static void _register_class(bool p_virtual = false, bool p_exposed = true);
|
||||
|
||||
template <typename T>
|
||||
static GDExtensionObjectPtr _create_instance_func(void *data) {
|
||||
@@ -149,8 +149,6 @@ public:
|
||||
static void register_abstract_class();
|
||||
template <typename T>
|
||||
static void register_internal_class();
|
||||
template <typename T>
|
||||
static void register_runtime_class();
|
||||
|
||||
_FORCE_INLINE_ static void _register_engine_class(const StringName &p_name, const GDExtensionInstanceBindingCallbacks *p_callbacks) {
|
||||
instance_binding_callbacks[p_name] = p_callbacks;
|
||||
@@ -185,10 +183,7 @@ public:
|
||||
static void add_property(const StringName &p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index = -1);
|
||||
static void add_signal(const StringName &p_class, const MethodInfo &p_signal);
|
||||
static void bind_integer_constant(const StringName &p_class_name, const StringName &p_enum_name, const StringName &p_constant_name, GDExtensionInt p_constant_value, bool p_is_bitfield = false);
|
||||
// Binds an implementation of a virtual method defined in Godot.
|
||||
static void bind_virtual_method(const StringName &p_class, const StringName &p_method, GDExtensionClassCallVirtual p_call);
|
||||
// Add a new virtual method that can be implemented by scripts.
|
||||
static void add_virtual_method(const StringName &p_class, const MethodInfo &p_method, const Vector<StringName> &p_arg_names = Vector<StringName>());
|
||||
|
||||
static MethodBind *get_method(const StringName &p_class, const StringName &p_method);
|
||||
|
||||
@@ -219,7 +214,7 @@ public:
|
||||
}
|
||||
|
||||
template <typename T, bool is_abstract>
|
||||
void ClassDB::_register_class(bool p_virtual, bool p_exposed, bool p_runtime) {
|
||||
void ClassDB::_register_class(bool p_virtual, bool p_exposed) {
|
||||
static_assert(TypesAreSame<typename T::self_type, T>::value, "Class not declared properly, please use GDCLASS.");
|
||||
static_assert(!FunctionsAreSame<T::self_type::_bind_methods, T::parent_type::_bind_methods>::value, "Class must declare 'static void _bind_methods'.");
|
||||
static_assert(!std::is_abstract_v<T> || is_abstract, "Class is abstract, please use GDREGISTER_ABSTRACT_CLASS.");
|
||||
@@ -239,15 +234,14 @@ void ClassDB::_register_class(bool p_virtual, bool p_exposed, bool p_runtime) {
|
||||
class_register_order.push_back(cl.name);
|
||||
|
||||
// Register this class with Godot
|
||||
GDExtensionClassCreationInfo3 class_info = {
|
||||
GDExtensionClassCreationInfo2 class_info = {
|
||||
p_virtual, // GDExtensionBool is_virtual;
|
||||
is_abstract, // GDExtensionBool is_abstract;
|
||||
p_exposed, // GDExtensionBool is_exposed;
|
||||
p_runtime, // GDExtensionBool is_runtime;
|
||||
T::set_bind, // GDExtensionClassSet set_func;
|
||||
T::get_bind, // GDExtensionClassGet get_func;
|
||||
T::has_get_property_list() ? T::get_property_list_bind : nullptr, // GDExtensionClassGetPropertyList get_property_list_func;
|
||||
T::free_property_list_bind, // GDExtensionClassFreePropertyList2 free_property_list_func;
|
||||
T::free_property_list_bind, // GDExtensionClassFreePropertyList free_property_list_func;
|
||||
T::property_can_revert_bind, // GDExtensionClassPropertyCanRevert property_can_revert_func;
|
||||
T::property_get_revert_bind, // GDExtensionClassPropertyGetRevert property_get_revert_func;
|
||||
T::validate_property_bind, // GDExtensionClassValidateProperty validate_property_func;
|
||||
@@ -265,7 +259,7 @@ void ClassDB::_register_class(bool p_virtual, bool p_exposed, bool p_runtime) {
|
||||
(void *)&T::get_class_static(), // void *class_userdata;
|
||||
};
|
||||
|
||||
internal::gdextension_interface_classdb_register_extension_class3(internal::library, cl.name._native_ptr(), cl.parent_name._native_ptr(), &class_info);
|
||||
internal::gdextension_interface_classdb_register_extension_class2(internal::library, cl.name._native_ptr(), cl.parent_name._native_ptr(), &class_info);
|
||||
|
||||
// call bind_methods etc. to register all members of the class
|
||||
T::initialize_class();
|
||||
@@ -289,11 +283,6 @@ void ClassDB::register_internal_class() {
|
||||
ClassDB::_register_class<T, false>(false, false);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void ClassDB::register_runtime_class() {
|
||||
ClassDB::_register_class<T, false>(false, true, true);
|
||||
}
|
||||
|
||||
template <typename N, typename M, typename... VarArgs>
|
||||
MethodBind *ClassDB::bind_method(N p_method_name, M p_method, VarArgs... p_args) {
|
||||
Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported.
|
||||
@@ -353,7 +342,6 @@ MethodBind *ClassDB::bind_vararg_method(uint32_t p_flags, StringName p_name, M p
|
||||
#define GDREGISTER_VIRTUAL_CLASS(m_class) ::godot::ClassDB::register_class<m_class>(true);
|
||||
#define GDREGISTER_ABSTRACT_CLASS(m_class) ::godot::ClassDB::register_abstract_class<m_class>();
|
||||
#define GDREGISTER_INTERNAL_CLASS(m_class) ::godot::ClassDB::register_internal_class<m_class>();
|
||||
#define GDREGISTER_RUNTIME_CLASS(m_class) ::godot::ClassDB::register_runtime_class<m_class>();
|
||||
|
||||
} // namespace godot
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
namespace godot {
|
||||
|
||||
#if !defined(GDE_EXPORT)
|
||||
#if defined(_WIN32)
|
||||
#define GDE_EXPORT __declspec(dllexport)
|
||||
@@ -127,4 +129,10 @@ struct BuildIndexSequence : BuildIndexSequence<N - 1, N - 1, Is...> {};
|
||||
template <size_t... Is>
|
||||
struct BuildIndexSequence<0, Is...> : IndexSequence<Is...> {};
|
||||
|
||||
} //namespace godot
|
||||
|
||||
// To maintain compatibility an alias is defined outside the namespace.
|
||||
// Consider it deprecated.
|
||||
using real_t = godot::real_t;
|
||||
|
||||
#endif // GODOT_DEFS_HPP
|
||||
|
||||
@@ -82,9 +82,6 @@ public:
|
||||
static void free_static(void *p_ptr, bool p_pad_align = false);
|
||||
};
|
||||
|
||||
template <typename T, std::enable_if_t<!std::is_base_of<::godot::Wrapped, T>::value, bool> = true>
|
||||
_ALWAYS_INLINE_ void _pre_initialize() {}
|
||||
|
||||
_ALWAYS_INLINE_ void postinitialize_handler(void *) {}
|
||||
|
||||
template <typename T>
|
||||
@@ -97,10 +94,10 @@ _ALWAYS_INLINE_ T *_post_initialize(T *p_obj) {
|
||||
#define memrealloc(m_mem, m_size) ::godot::Memory::realloc_static(m_mem, m_size)
|
||||
#define memfree(m_mem) ::godot::Memory::free_static(m_mem)
|
||||
|
||||
#define memnew(m_class) (::godot::_pre_initialize<std::remove_pointer_t<decltype(new ("", "") m_class)>>(), ::godot::_post_initialize(new ("", "") m_class))
|
||||
#define memnew(m_class) ::godot::_post_initialize(new ("", "") m_class)
|
||||
|
||||
#define memnew_allocator(m_class, m_allocator) (::godot::_pre_initialize<std::remove_pointer_t<decltype(new ("", "") m_class)>>(), ::godot::_post_initialize(new ("", m_allocator::alloc) m_class))
|
||||
#define memnew_placement(m_placement, m_class) (::godot::_pre_initialize<std::remove_pointer_t<decltype(new ("", "") m_class)>>(), ::godot::_post_initialize(new ("", m_placement, sizeof(m_class), "") m_class))
|
||||
#define memnew_allocator(m_class, m_allocator) ::godot::_post_initialize(new ("", m_allocator::alloc) m_class)
|
||||
#define memnew_placement(m_placement, m_class) ::godot::_post_initialize(new ("", m_placement, sizeof(m_class), "") m_class)
|
||||
|
||||
// Generic comparator used in Map, List, etc.
|
||||
template <typename T>
|
||||
|
||||
@@ -161,7 +161,6 @@ MAKE_PTRARG(PackedFloat64Array);
|
||||
MAKE_PTRARG(PackedStringArray);
|
||||
MAKE_PTRARG(PackedVector2Array);
|
||||
MAKE_PTRARG(PackedVector3Array);
|
||||
MAKE_PTRARG(PackedVector4Array);
|
||||
MAKE_PTRARG(PackedColorArray);
|
||||
MAKE_PTRARG_BY_REFERENCE(Variant);
|
||||
|
||||
|
||||
@@ -68,8 +68,6 @@ struct MethodInfo {
|
||||
int id = 0;
|
||||
std::vector<PropertyInfo> arguments;
|
||||
std::vector<Variant> default_arguments;
|
||||
GDExtensionClassMethodArgumentMetadata return_val_metadata;
|
||||
std::vector<GDExtensionClassMethodArgumentMetadata> arguments_metadata;
|
||||
|
||||
inline bool operator==(const MethodInfo &p_method) const { return id == p_method.id; }
|
||||
inline bool operator<(const MethodInfo &p_method) const { return id == p_method.id ? (name < p_method.name) : (id < p_method.id); }
|
||||
|
||||
@@ -114,17 +114,6 @@ struct PropertyInfo {
|
||||
p_info->usage = usage;
|
||||
*(reinterpret_cast<StringName *>(p_info->class_name)) = class_name;
|
||||
}
|
||||
|
||||
GDExtensionPropertyInfo _to_gdextension() const {
|
||||
return {
|
||||
(GDExtensionVariantType)type,
|
||||
name._native_ptr(),
|
||||
class_name._native_ptr(),
|
||||
hint,
|
||||
hint_string._native_ptr(),
|
||||
usage,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace godot
|
||||
|
||||
@@ -185,7 +185,6 @@ MAKE_TYPE_INFO(PackedFloat64Array, GDEXTENSION_VARIANT_TYPE_PACKED_FLOAT64_ARRAY
|
||||
MAKE_TYPE_INFO(PackedStringArray, GDEXTENSION_VARIANT_TYPE_PACKED_STRING_ARRAY)
|
||||
MAKE_TYPE_INFO(PackedVector2Array, GDEXTENSION_VARIANT_TYPE_PACKED_VECTOR2_ARRAY)
|
||||
MAKE_TYPE_INFO(PackedVector3Array, GDEXTENSION_VARIANT_TYPE_PACKED_VECTOR3_ARRAY)
|
||||
MAKE_TYPE_INFO(PackedVector4Array, GDEXTENSION_VARIANT_TYPE_PACKED_VECTOR4_ARRAY)
|
||||
MAKE_TYPE_INFO(PackedColorArray, GDEXTENSION_VARIANT_TYPE_PACKED_COLOR_ARRAY)
|
||||
|
||||
// For variant.
|
||||
@@ -209,8 +208,8 @@ struct GetTypeInfo<const Variant &> {
|
||||
|
||||
template <typename T>
|
||||
struct GetTypeInfo<T *, typename EnableIf<TypeInherits<Object, T>::value>::type> {
|
||||
static constexpr GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_OBJECT;
|
||||
static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;
|
||||
static const GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_OBJECT;
|
||||
static const GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;
|
||||
static inline PropertyInfo get_class_info() {
|
||||
return make_property_info(Variant::Type::OBJECT, "", PROPERTY_HINT_RESOURCE_TYPE, T::get_class_static());
|
||||
}
|
||||
@@ -218,8 +217,8 @@ struct GetTypeInfo<T *, typename EnableIf<TypeInherits<Object, T>::value>::type>
|
||||
|
||||
template <typename T>
|
||||
struct GetTypeInfo<const T *, typename EnableIf<TypeInherits<Object, T>::value>::type> {
|
||||
static constexpr GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_OBJECT;
|
||||
static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;
|
||||
static const GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_OBJECT;
|
||||
static const GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;
|
||||
static inline PropertyInfo get_class_info() {
|
||||
return make_property_info(Variant::Type::OBJECT, "", PROPERTY_HINT_RESOURCE_TYPE, T::get_class_static());
|
||||
}
|
||||
@@ -237,8 +236,8 @@ inline String enum_qualified_name_to_class_info_name(const String &p_qualified_n
|
||||
#define TEMPL_MAKE_ENUM_TYPE_INFO(m_enum, m_impl) \
|
||||
template <> \
|
||||
struct GetTypeInfo<m_impl> { \
|
||||
static constexpr Variant::Type VARIANT_TYPE = Variant::INT; \
|
||||
static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE; \
|
||||
static const Variant::Type VARIANT_TYPE = Variant::INT; \
|
||||
static const GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE; \
|
||||
static inline PropertyInfo get_class_info() { \
|
||||
return make_property_info(Variant::Type::INT, "", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_ENUM, \
|
||||
enum_qualified_name_to_class_info_name(#m_enum)); \
|
||||
@@ -275,8 +274,8 @@ public:
|
||||
#define TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, m_impl) \
|
||||
template <> \
|
||||
struct GetTypeInfo<m_impl> { \
|
||||
static constexpr Variant::Type VARIANT_TYPE = Variant::INT; \
|
||||
static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE; \
|
||||
static const Variant::Type VARIANT_TYPE = Variant::INT; \
|
||||
static const GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE; \
|
||||
static inline PropertyInfo get_class_info() { \
|
||||
return make_property_info(Variant::Type::INT, "", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_BITFIELD, \
|
||||
enum_qualified_name_to_class_info_name(#m_enum)); \
|
||||
@@ -284,8 +283,8 @@ public:
|
||||
}; \
|
||||
template <> \
|
||||
struct GetTypeInfo<BitField<m_impl>> { \
|
||||
static constexpr Variant::Type VARIANT_TYPE = Variant::INT; \
|
||||
static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE; \
|
||||
static const Variant::Type VARIANT_TYPE = Variant::INT; \
|
||||
static const GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE; \
|
||||
static inline PropertyInfo get_class_info() { \
|
||||
return make_property_info(Variant::Type::INT, "", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_BITFIELD, \
|
||||
enum_qualified_name_to_class_info_name(#m_enum)); \
|
||||
@@ -381,14 +380,11 @@ MAKE_TYPED_ARRAY_INFO(Rect2i, Variant::RECT2I)
|
||||
MAKE_TYPED_ARRAY_INFO(Vector3, Variant::VECTOR3)
|
||||
MAKE_TYPED_ARRAY_INFO(Vector3i, Variant::VECTOR3I)
|
||||
MAKE_TYPED_ARRAY_INFO(Transform2D, Variant::TRANSFORM2D)
|
||||
MAKE_TYPED_ARRAY_INFO(Vector4, Variant::VECTOR4)
|
||||
MAKE_TYPED_ARRAY_INFO(Vector4i, Variant::VECTOR4I)
|
||||
MAKE_TYPED_ARRAY_INFO(Plane, Variant::PLANE)
|
||||
MAKE_TYPED_ARRAY_INFO(Quaternion, Variant::QUATERNION)
|
||||
MAKE_TYPED_ARRAY_INFO(AABB, Variant::AABB)
|
||||
MAKE_TYPED_ARRAY_INFO(Basis, Variant::BASIS)
|
||||
MAKE_TYPED_ARRAY_INFO(Transform3D, Variant::TRANSFORM3D)
|
||||
MAKE_TYPED_ARRAY_INFO(Projection, Variant::PROJECTION)
|
||||
MAKE_TYPED_ARRAY_INFO(Color, Variant::COLOR)
|
||||
MAKE_TYPED_ARRAY_INFO(StringName, Variant::STRING_NAME)
|
||||
MAKE_TYPED_ARRAY_INFO(NodePath, Variant::NODE_PATH)
|
||||
@@ -397,20 +393,15 @@ MAKE_TYPED_ARRAY_INFO(Callable, Variant::CALLABLE)
|
||||
MAKE_TYPED_ARRAY_INFO(Signal, Variant::SIGNAL)
|
||||
MAKE_TYPED_ARRAY_INFO(Dictionary, Variant::DICTIONARY)
|
||||
MAKE_TYPED_ARRAY_INFO(Array, Variant::ARRAY)
|
||||
/*
|
||||
MAKE_TYPED_ARRAY_INFO(Vector<uint8_t>, Variant::PACKED_BYTE_ARRAY)
|
||||
MAKE_TYPED_ARRAY_INFO(Vector<int32_t>, Variant::PACKED_INT32_ARRAY)
|
||||
MAKE_TYPED_ARRAY_INFO(Vector<int64_t>, Variant::PACKED_INT64_ARRAY)
|
||||
MAKE_TYPED_ARRAY_INFO(Vector<float>, Variant::PACKED_FLOAT32_ARRAY)
|
||||
MAKE_TYPED_ARRAY_INFO(Vector<double>, Variant::PACKED_FLOAT64_ARRAY)
|
||||
MAKE_TYPED_ARRAY_INFO(Vector<String>, Variant::PACKED_STRING_ARRAY)
|
||||
MAKE_TYPED_ARRAY_INFO(Vector<Vector2>, Variant::PACKED_VECTOR2_ARRAY)
|
||||
MAKE_TYPED_ARRAY_INFO(Vector<Vector3>, Variant::PACKED_VECTOR3_ARRAY)
|
||||
MAKE_TYPED_ARRAY_INFO(Vector<Color>, Variant::PACKED_COLOR_ARRAY)
|
||||
MAKE_TYPED_ARRAY_INFO(IPAddress, Variant::STRING)
|
||||
*/
|
||||
|
||||
#undef MAKE_TYPED_ARRAY_INFO
|
||||
MAKE_TYPED_ARRAY_INFO(PackedByteArray, Variant::PACKED_BYTE_ARRAY)
|
||||
MAKE_TYPED_ARRAY_INFO(PackedInt32Array, Variant::PACKED_INT32_ARRAY)
|
||||
MAKE_TYPED_ARRAY_INFO(PackedInt64Array, Variant::PACKED_INT64_ARRAY)
|
||||
MAKE_TYPED_ARRAY_INFO(PackedFloat32Array, Variant::PACKED_FLOAT32_ARRAY)
|
||||
MAKE_TYPED_ARRAY_INFO(PackedFloat64Array, Variant::PACKED_FLOAT64_ARRAY)
|
||||
MAKE_TYPED_ARRAY_INFO(PackedStringArray, Variant::PACKED_STRING_ARRAY)
|
||||
MAKE_TYPED_ARRAY_INFO(PackedVector2Array, Variant::PACKED_VECTOR2_ARRAY)
|
||||
MAKE_TYPED_ARRAY_INFO(PackedVector3Array, Variant::PACKED_VECTOR3_ARRAY)
|
||||
MAKE_TYPED_ARRAY_INFO(PackedColorArray, Variant::PACKED_COLOR_ARRAY)
|
||||
|
||||
#define CLASS_INFO(m_type) (GetTypeInfo<m_type *>::get_class_info())
|
||||
|
||||
|
||||
@@ -108,9 +108,7 @@ extern "C" GDExtensionInterfaceStringNewWithUtf32Chars gdextension_interface_str
|
||||
extern "C" GDExtensionInterfaceStringNewWithWideChars gdextension_interface_string_new_with_wide_chars;
|
||||
extern "C" GDExtensionInterfaceStringNewWithLatin1CharsAndLen gdextension_interface_string_new_with_latin1_chars_and_len;
|
||||
extern "C" GDExtensionInterfaceStringNewWithUtf8CharsAndLen gdextension_interface_string_new_with_utf8_chars_and_len;
|
||||
extern "C" GDExtensionInterfaceStringNewWithUtf8CharsAndLen2 gdextension_interface_string_new_with_utf8_chars_and_len2;
|
||||
extern "C" GDExtensionInterfaceStringNewWithUtf16CharsAndLen gdextension_interface_string_new_with_utf16_chars_and_len;
|
||||
extern "C" GDExtensionInterfaceStringNewWithUtf16CharsAndLen2 gdextension_interface_string_new_with_utf16_chars_and_len2;
|
||||
extern "C" GDExtensionInterfaceStringNewWithUtf32CharsAndLen gdextension_interface_string_new_with_utf32_chars_and_len;
|
||||
extern "C" GDExtensionInterfaceStringNewWithWideCharsAndLen gdextension_interface_string_new_with_wide_chars_and_len;
|
||||
extern "C" GDExtensionInterfaceStringToLatin1Chars gdextension_interface_string_to_latin1_chars;
|
||||
@@ -150,8 +148,6 @@ extern "C" GDExtensionInterfacePackedVector2ArrayOperatorIndex gdextension_inter
|
||||
extern "C" GDExtensionInterfacePackedVector2ArrayOperatorIndexConst gdextension_interface_packed_vector2_array_operator_index_const;
|
||||
extern "C" GDExtensionInterfacePackedVector3ArrayOperatorIndex gdextension_interface_packed_vector3_array_operator_index;
|
||||
extern "C" GDExtensionInterfacePackedVector3ArrayOperatorIndexConst gdextension_interface_packed_vector3_array_operator_index_const;
|
||||
extern "C" GDExtensionInterfacePackedVector4ArrayOperatorIndex gdextension_interface_packed_vector4_array_operator_index;
|
||||
extern "C" GDExtensionInterfacePackedVector4ArrayOperatorIndexConst gdextension_interface_packed_vector4_array_operator_index_const;
|
||||
extern "C" GDExtensionInterfaceArrayOperatorIndex gdextension_interface_array_operator_index;
|
||||
extern "C" GDExtensionInterfaceArrayOperatorIndexConst gdextension_interface_array_operator_index_const;
|
||||
extern "C" GDExtensionInterfaceArrayRef gdextension_interface_array_ref;
|
||||
@@ -170,21 +166,18 @@ extern "C" GDExtensionInterfaceObjectGetClassName gdextension_interface_object_g
|
||||
extern "C" GDExtensionInterfaceObjectCastTo gdextension_interface_object_cast_to;
|
||||
extern "C" GDExtensionInterfaceObjectGetInstanceFromId gdextension_interface_object_get_instance_from_id;
|
||||
extern "C" GDExtensionInterfaceObjectGetInstanceId gdextension_interface_object_get_instance_id;
|
||||
extern "C" GDExtensionInterfaceObjectHasScriptMethod gdextension_interface_object_has_script_method;
|
||||
extern "C" GDExtensionInterfaceObjectCallScriptMethod gdextension_interface_object_call_script_method;
|
||||
extern "C" GDExtensionInterfaceCallableCustomCreate2 gdextension_interface_callable_custom_create2;
|
||||
extern "C" GDExtensionInterfaceCallableCustomCreate gdextension_interface_callable_custom_create;
|
||||
extern "C" GDExtensionInterfaceCallableCustomGetUserData gdextension_interface_callable_custom_get_userdata;
|
||||
extern "C" GDExtensionInterfaceRefGetObject gdextension_interface_ref_get_object;
|
||||
extern "C" GDExtensionInterfaceRefSetObject gdextension_interface_ref_set_object;
|
||||
extern "C" GDExtensionInterfaceScriptInstanceCreate3 gdextension_interface_script_instance_create3;
|
||||
extern "C" GDExtensionInterfaceScriptInstanceCreate2 gdextension_interface_script_instance_create2;
|
||||
extern "C" GDExtensionInterfacePlaceHolderScriptInstanceCreate gdextension_interface_placeholder_script_instance_create;
|
||||
extern "C" GDExtensionInterfacePlaceHolderScriptInstanceUpdate gdextension_interface_placeholder_script_instance_update;
|
||||
extern "C" GDExtensionInterfaceClassdbConstructObject gdextension_interface_classdb_construct_object;
|
||||
extern "C" GDExtensionInterfaceClassdbGetMethodBind gdextension_interface_classdb_get_method_bind;
|
||||
extern "C" GDExtensionInterfaceClassdbGetClassTag gdextension_interface_classdb_get_class_tag;
|
||||
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClass3 gdextension_interface_classdb_register_extension_class3;
|
||||
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClass2 gdextension_interface_classdb_register_extension_class2;
|
||||
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassMethod gdextension_interface_classdb_register_extension_class_method;
|
||||
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassVirtualMethod gdextension_interface_classdb_register_extension_class_virtual_method;
|
||||
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant gdextension_interface_classdb_register_extension_class_integer_constant;
|
||||
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassProperty gdextension_interface_classdb_register_extension_class_property;
|
||||
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassPropertyIndexed gdextension_interface_classdb_register_extension_class_property_indexed;
|
||||
@@ -195,15 +188,6 @@ extern "C" GDExtensionInterfaceClassdbUnregisterExtensionClass gdextension_inter
|
||||
extern "C" GDExtensionInterfaceGetLibraryPath gdextension_interface_get_library_path;
|
||||
extern "C" GDExtensionInterfaceEditorAddPlugin gdextension_interface_editor_add_plugin;
|
||||
extern "C" GDExtensionInterfaceEditorRemovePlugin gdextension_interface_editor_remove_plugin;
|
||||
extern "C" GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8Chars gdextension_interface_editor_help_load_xml_from_utf8_chars;
|
||||
extern "C" GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8CharsAndLen gdextension_interface_editor_help_load_xml_from_utf8_chars_and_len;
|
||||
extern "C" GDExtensionInterfaceImagePtrw gdextension_interface_image_ptrw;
|
||||
extern "C" GDExtensionInterfaceImagePtr gdextension_interface_image_ptr;
|
||||
|
||||
class DocDataRegistration {
|
||||
public:
|
||||
DocDataRegistration(const char *p_hash, int p_uncompressed_size, int p_compressed_size, const unsigned char *p_data);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
|
||||
@@ -139,6 +139,31 @@ public:
|
||||
|
||||
typedef T ValueType;
|
||||
|
||||
struct Iterator {
|
||||
_FORCE_INLINE_ T &operator*() const {
|
||||
return E->get();
|
||||
}
|
||||
_FORCE_INLINE_ T *operator->() const { return &E->get(); }
|
||||
_FORCE_INLINE_ Iterator &operator++() {
|
||||
E = E->next();
|
||||
return *this;
|
||||
}
|
||||
_FORCE_INLINE_ Iterator &operator--() {
|
||||
E = E->prev();
|
||||
return *this;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ bool operator==(const Iterator &b) const { return E == b.E; }
|
||||
_FORCE_INLINE_ bool operator!=(const Iterator &b) const { return E != b.E; }
|
||||
|
||||
Iterator(Element *p_E) { E = p_E; }
|
||||
Iterator() {}
|
||||
Iterator(const Iterator &p_it) { E = p_it.E; }
|
||||
|
||||
private:
|
||||
Element *E = nullptr;
|
||||
};
|
||||
|
||||
struct ConstIterator {
|
||||
_FORCE_INLINE_ const T &operator*() const {
|
||||
return E->get();
|
||||
@@ -164,35 +189,6 @@ public:
|
||||
const Element *E = nullptr;
|
||||
};
|
||||
|
||||
struct Iterator {
|
||||
_FORCE_INLINE_ T &operator*() const {
|
||||
return E->get();
|
||||
}
|
||||
_FORCE_INLINE_ T *operator->() const { return &E->get(); }
|
||||
_FORCE_INLINE_ Iterator &operator++() {
|
||||
E = E->next();
|
||||
return *this;
|
||||
}
|
||||
_FORCE_INLINE_ Iterator &operator--() {
|
||||
E = E->prev();
|
||||
return *this;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ bool operator==(const Iterator &b) const { return E == b.E; }
|
||||
_FORCE_INLINE_ bool operator!=(const Iterator &b) const { return E != b.E; }
|
||||
|
||||
Iterator(Element *p_E) { E = p_E; }
|
||||
Iterator() {}
|
||||
Iterator(const Iterator &p_it) { E = p_it.E; }
|
||||
|
||||
operator ConstIterator() const {
|
||||
return ConstIterator(E);
|
||||
}
|
||||
|
||||
private:
|
||||
Element *E = nullptr;
|
||||
};
|
||||
|
||||
_FORCE_INLINE_ Iterator begin() {
|
||||
return Iterator(front());
|
||||
}
|
||||
@@ -523,14 +519,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// Index operator, kept for compatibility.
|
||||
_FORCE_INLINE_ T &operator[](int p_index) {
|
||||
return get(p_index);
|
||||
}
|
||||
|
||||
// Random access to elements, use with care,
|
||||
// do not use for iteration.
|
||||
T &get(int p_index) {
|
||||
T &operator[](int p_index) {
|
||||
CRASH_BAD_INDEX(p_index, size());
|
||||
|
||||
Element *I = front();
|
||||
@@ -543,14 +532,7 @@ public:
|
||||
return I->get();
|
||||
}
|
||||
|
||||
// Index operator, kept for compatibility.
|
||||
_FORCE_INLINE_ const T &operator[](int p_index) const {
|
||||
return get(p_index);
|
||||
}
|
||||
|
||||
// Random access to elements, use with care,
|
||||
// do not use for iteration.
|
||||
const T &get(int p_index) const {
|
||||
const T &operator[](int p_index) const {
|
||||
CRASH_BAD_INDEX(p_index, size());
|
||||
|
||||
const Element *I = front();
|
||||
|
||||
@@ -257,10 +257,6 @@ public:
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool has(const T &p_val) const {
|
||||
return find(p_val) != -1;
|
||||
}
|
||||
|
||||
template <typename C>
|
||||
void sort_custom() {
|
||||
U len = count;
|
||||
|
||||
@@ -132,7 +132,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
_ALWAYS_INLINE_ explicit SafeNumeric<T>(T p_value = static_cast<T>(0)) {
|
||||
_ALWAYS_INLINE_ explicit SafeNumeric(T p_value = static_cast<T>(0)) {
|
||||
set(p_value);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -103,7 +103,7 @@ struct _NO_DISCARD_ AABB {
|
||||
_FORCE_INLINE_ void expand_to(const Vector3 &p_vector); /** expand to contain a point if necessary */
|
||||
|
||||
_FORCE_INLINE_ AABB abs() const {
|
||||
return AABB(position + size.minf(0), size.abs());
|
||||
return AABB(Vector3(position.x + MIN(size.x, (real_t)0), position.y + MIN(size.y, (real_t)0), position.z + MIN(size.z, (real_t)0)), size.abs());
|
||||
}
|
||||
|
||||
Variant intersects_segment_bind(const Vector3 &p_from, const Vector3 &p_to) const;
|
||||
|
||||
@@ -224,7 +224,7 @@ struct _NO_DISCARD_ Basis {
|
||||
|
||||
operator Quaternion() const { return get_quaternion(); }
|
||||
|
||||
static Basis looking_at(const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0));
|
||||
static Basis looking_at(const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0), bool p_use_model_front = false);
|
||||
|
||||
Basis(const Quaternion &p_quaternion) { set_quaternion(p_quaternion); }
|
||||
Basis(const Quaternion &p_quaternion, const Vector3 &p_scale) { set_quaternion_scale(p_quaternion, p_scale); }
|
||||
|
||||
@@ -41,7 +41,6 @@ class Object;
|
||||
class CallableCustomBase {
|
||||
public:
|
||||
virtual ObjectID get_object() const = 0;
|
||||
virtual int get_argument_count(bool &r_is_valid) const;
|
||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const = 0;
|
||||
virtual ~CallableCustomBase() {}
|
||||
};
|
||||
|
||||
@@ -73,11 +73,6 @@ public:
|
||||
return ObjectID(data.instance->get_instance_id());
|
||||
}
|
||||
|
||||
virtual int get_argument_count(bool &r_is_valid) const override {
|
||||
r_is_valid = true;
|
||||
return sizeof...(P);
|
||||
}
|
||||
|
||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const override {
|
||||
call_with_variant_args(data.instance, data.method, p_arguments, p_argcount, r_call_error);
|
||||
}
|
||||
@@ -115,11 +110,6 @@ public:
|
||||
return ObjectID(data.instance->get_instance_id());
|
||||
}
|
||||
|
||||
virtual int get_argument_count(bool &r_is_valid) const override {
|
||||
r_is_valid = true;
|
||||
return sizeof...(P);
|
||||
}
|
||||
|
||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const override {
|
||||
call_with_variant_args_ret(data.instance, data.method, p_arguments, p_argcount, r_return_value, r_call_error);
|
||||
}
|
||||
@@ -157,11 +147,6 @@ public:
|
||||
return ObjectID(data.instance->get_instance_id());
|
||||
}
|
||||
|
||||
virtual int get_argument_count(bool &r_is_valid) const override {
|
||||
r_is_valid = true;
|
||||
return sizeof...(P);
|
||||
}
|
||||
|
||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const override {
|
||||
call_with_variant_args_retc(data.instance, data.method, p_arguments, p_argcount, r_return_value, r_call_error);
|
||||
}
|
||||
@@ -197,11 +182,6 @@ public:
|
||||
return ObjectID();
|
||||
}
|
||||
|
||||
virtual int get_argument_count(bool &r_is_valid) const override {
|
||||
r_is_valid = true;
|
||||
return sizeof...(P);
|
||||
}
|
||||
|
||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const override {
|
||||
call_with_variant_args_static_ret(data.method, p_arguments, p_argcount, r_return_value, r_call_error);
|
||||
r_return_value = Variant();
|
||||
@@ -238,11 +218,6 @@ public:
|
||||
return ObjectID();
|
||||
}
|
||||
|
||||
virtual int get_argument_count(bool &r_is_valid) const override {
|
||||
r_is_valid = true;
|
||||
return sizeof...(P);
|
||||
}
|
||||
|
||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const override {
|
||||
call_with_variant_args_static_ret(data.method, p_arguments, p_argcount, r_return_value, r_call_error);
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#ifndef GODOT_QUATERNION_HPP
|
||||
#define GODOT_QUATERNION_HPP
|
||||
|
||||
#include <godot_cpp/classes/global_constants.hpp>
|
||||
#include <godot_cpp/core/math.hpp>
|
||||
#include <godot_cpp/variant/vector3.hpp>
|
||||
|
||||
@@ -47,11 +48,11 @@ struct _NO_DISCARD_ Quaternion {
|
||||
real_t components[4] = { 0, 0, 0, 1.0 };
|
||||
};
|
||||
|
||||
_FORCE_INLINE_ real_t &operator[](int idx) {
|
||||
return components[idx];
|
||||
_FORCE_INLINE_ real_t &operator[](int p_idx) {
|
||||
return components[p_idx];
|
||||
}
|
||||
_FORCE_INLINE_ const real_t &operator[](int idx) const {
|
||||
return components[idx];
|
||||
_FORCE_INLINE_ const real_t &operator[](int p_idx) const {
|
||||
return components[p_idx];
|
||||
}
|
||||
_FORCE_INLINE_ real_t length_squared() const;
|
||||
bool is_equal_approx(const Quaternion &p_quaternion) const;
|
||||
@@ -66,14 +67,13 @@ struct _NO_DISCARD_ Quaternion {
|
||||
_FORCE_INLINE_ real_t dot(const Quaternion &p_q) const;
|
||||
real_t angle_to(const Quaternion &p_to) const;
|
||||
|
||||
Vector3 get_euler_xyz() const;
|
||||
Vector3 get_euler_yxz() const;
|
||||
Vector3 get_euler() const { return get_euler_yxz(); }
|
||||
Vector3 get_euler(EulerOrder p_order = EulerOrder::EULER_ORDER_YXZ) const;
|
||||
static Quaternion from_euler(const Vector3 &p_euler);
|
||||
|
||||
Quaternion slerp(const Quaternion &p_to, const real_t &p_weight) const;
|
||||
Quaternion slerpni(const Quaternion &p_to, const real_t &p_weight) const;
|
||||
Quaternion spherical_cubic_interpolate(const Quaternion &p_b, const Quaternion &p_pre_a, const Quaternion &p_post_b, const real_t &p_weight) const;
|
||||
Quaternion spherical_cubic_interpolate_in_time(const Quaternion &p_b, const Quaternion &p_pre_a, const Quaternion &p_post_b, const real_t &p_weight, const real_t &p_b_t, const real_t &p_pre_a_t, const real_t &p_post_b_t) const;
|
||||
Quaternion slerp(const Quaternion &p_to, real_t p_weight) const;
|
||||
Quaternion slerpni(const Quaternion &p_to, real_t p_weight) const;
|
||||
Quaternion spherical_cubic_interpolate(const Quaternion &p_b, const Quaternion &p_pre_a, const Quaternion &p_post_b, real_t p_weight) const;
|
||||
Quaternion spherical_cubic_interpolate_in_time(const Quaternion &p_b, const Quaternion &p_pre_a, const Quaternion &p_post_b, real_t p_weight, real_t p_b_t, real_t p_pre_a_t, real_t p_post_b_t) const;
|
||||
|
||||
Vector3 get_axis() const;
|
||||
real_t get_angle() const;
|
||||
@@ -89,28 +89,28 @@ struct _NO_DISCARD_ Quaternion {
|
||||
void operator*=(const Quaternion &p_q);
|
||||
Quaternion operator*(const Quaternion &p_q) const;
|
||||
|
||||
_FORCE_INLINE_ Vector3 xform(const Vector3 &v) const {
|
||||
_FORCE_INLINE_ Vector3 xform(const Vector3 &p_v) const {
|
||||
#ifdef MATH_CHECKS
|
||||
ERR_FAIL_COND_V_MSG(!is_normalized(), v, "The quaternion must be normalized.");
|
||||
ERR_FAIL_COND_V_MSG(!is_normalized(), p_v, "The quaternion " + operator String() + " must be normalized.");
|
||||
#endif
|
||||
Vector3 u(x, y, z);
|
||||
Vector3 uv = u.cross(v);
|
||||
return v + ((uv * w) + u.cross(uv)) * ((real_t)2);
|
||||
Vector3 uv = u.cross(p_v);
|
||||
return p_v + ((uv * w) + u.cross(uv)) * ((real_t)2);
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Vector3 xform_inv(const Vector3 &v) const {
|
||||
return inverse().xform(v);
|
||||
_FORCE_INLINE_ Vector3 xform_inv(const Vector3 &p_v) const {
|
||||
return inverse().xform(p_v);
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void operator+=(const Quaternion &p_q);
|
||||
_FORCE_INLINE_ void operator-=(const Quaternion &p_q);
|
||||
_FORCE_INLINE_ void operator*=(const real_t &s);
|
||||
_FORCE_INLINE_ void operator/=(const real_t &s);
|
||||
_FORCE_INLINE_ Quaternion operator+(const Quaternion &q2) const;
|
||||
_FORCE_INLINE_ Quaternion operator-(const Quaternion &q2) const;
|
||||
_FORCE_INLINE_ void operator*=(real_t p_s);
|
||||
_FORCE_INLINE_ void operator/=(real_t p_s);
|
||||
_FORCE_INLINE_ Quaternion operator+(const Quaternion &p_q2) const;
|
||||
_FORCE_INLINE_ Quaternion operator-(const Quaternion &p_q2) const;
|
||||
_FORCE_INLINE_ Quaternion operator-() const;
|
||||
_FORCE_INLINE_ Quaternion operator*(const real_t &s) const;
|
||||
_FORCE_INLINE_ Quaternion operator/(const real_t &s) const;
|
||||
_FORCE_INLINE_ Quaternion operator*(real_t p_s) const;
|
||||
_FORCE_INLINE_ Quaternion operator/(real_t p_s) const;
|
||||
|
||||
_FORCE_INLINE_ bool operator==(const Quaternion &p_quaternion) const;
|
||||
_FORCE_INLINE_ bool operator!=(const Quaternion &p_quaternion) const;
|
||||
@@ -128,8 +128,6 @@ struct _NO_DISCARD_ Quaternion {
|
||||
|
||||
Quaternion(const Vector3 &p_axis, real_t p_angle);
|
||||
|
||||
Quaternion(const Vector3 &p_euler);
|
||||
|
||||
Quaternion(const Quaternion &p_q) :
|
||||
x(p_q.x),
|
||||
y(p_q.y),
|
||||
@@ -144,9 +142,9 @@ struct _NO_DISCARD_ Quaternion {
|
||||
w = p_q.w;
|
||||
}
|
||||
|
||||
Quaternion(const Vector3 &v0, const Vector3 &v1) { // Shortest arc.
|
||||
Vector3 c = v0.cross(v1);
|
||||
real_t d = v0.dot(v1);
|
||||
Quaternion(const Vector3 &p_v0, const Vector3 &p_v1) { // Shortest arc.
|
||||
Vector3 c = p_v0.cross(p_v1);
|
||||
real_t d = p_v0.dot(p_v1);
|
||||
|
||||
if (d < -1.0f + (real_t)CMP_EPSILON) {
|
||||
x = 0;
|
||||
@@ -187,25 +185,25 @@ void Quaternion::operator-=(const Quaternion &p_q) {
|
||||
w -= p_q.w;
|
||||
}
|
||||
|
||||
void Quaternion::operator*=(const real_t &s) {
|
||||
x *= s;
|
||||
y *= s;
|
||||
z *= s;
|
||||
w *= s;
|
||||
void Quaternion::operator*=(real_t p_s) {
|
||||
x *= p_s;
|
||||
y *= p_s;
|
||||
z *= p_s;
|
||||
w *= p_s;
|
||||
}
|
||||
|
||||
void Quaternion::operator/=(const real_t &s) {
|
||||
*this *= 1.0f / s;
|
||||
void Quaternion::operator/=(real_t p_s) {
|
||||
*this *= 1.0f / p_s;
|
||||
}
|
||||
|
||||
Quaternion Quaternion::operator+(const Quaternion &q2) const {
|
||||
Quaternion Quaternion::operator+(const Quaternion &p_q2) const {
|
||||
const Quaternion &q1 = *this;
|
||||
return Quaternion(q1.x + q2.x, q1.y + q2.y, q1.z + q2.z, q1.w + q2.w);
|
||||
return Quaternion(q1.x + p_q2.x, q1.y + p_q2.y, q1.z + p_q2.z, q1.w + p_q2.w);
|
||||
}
|
||||
|
||||
Quaternion Quaternion::operator-(const Quaternion &q2) const {
|
||||
Quaternion Quaternion::operator-(const Quaternion &p_q2) const {
|
||||
const Quaternion &q1 = *this;
|
||||
return Quaternion(q1.x - q2.x, q1.y - q2.y, q1.z - q2.z, q1.w - q2.w);
|
||||
return Quaternion(q1.x - p_q2.x, q1.y - p_q2.y, q1.z - p_q2.z, q1.w - p_q2.w);
|
||||
}
|
||||
|
||||
Quaternion Quaternion::operator-() const {
|
||||
@@ -213,12 +211,12 @@ Quaternion Quaternion::operator-() const {
|
||||
return Quaternion(-q2.x, -q2.y, -q2.z, -q2.w);
|
||||
}
|
||||
|
||||
Quaternion Quaternion::operator*(const real_t &s) const {
|
||||
return Quaternion(x * s, y * s, z * s, w * s);
|
||||
Quaternion Quaternion::operator*(real_t p_s) const {
|
||||
return Quaternion(x * p_s, y * p_s, z * p_s, w * p_s);
|
||||
}
|
||||
|
||||
Quaternion Quaternion::operator/(const real_t &s) const {
|
||||
return *this * (1.0f / s);
|
||||
Quaternion Quaternion::operator/(real_t p_s) const {
|
||||
return *this * (1.0f / p_s);
|
||||
}
|
||||
|
||||
bool Quaternion::operator==(const Quaternion &p_quaternion) const {
|
||||
@@ -229,7 +227,7 @@ bool Quaternion::operator!=(const Quaternion &p_quaternion) const {
|
||||
return x != p_quaternion.x || y != p_quaternion.y || z != p_quaternion.z || w != p_quaternion.w;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Quaternion operator*(const real_t &p_real, const Quaternion &p_quaternion) {
|
||||
_FORCE_INLINE_ Quaternion operator*(real_t p_real, const Quaternion &p_quaternion) {
|
||||
return p_quaternion * p_real;
|
||||
}
|
||||
|
||||
|
||||
@@ -154,12 +154,14 @@ struct _NO_DISCARD_ Rect2 {
|
||||
return Rect2();
|
||||
}
|
||||
|
||||
new_rect.position = p_rect.position.max(position);
|
||||
new_rect.position.x = Math::max(p_rect.position.x, position.x);
|
||||
new_rect.position.y = Math::max(p_rect.position.y, position.y);
|
||||
|
||||
Point2 p_rect_end = p_rect.position + p_rect.size;
|
||||
Point2 end = position + size;
|
||||
|
||||
new_rect.size = p_rect_end.min(end) - new_rect.position;
|
||||
new_rect.size.x = Math::min(p_rect_end.x, end.x) - new_rect.position.x;
|
||||
new_rect.size.y = Math::min(p_rect_end.y, end.y) - new_rect.position.y;
|
||||
|
||||
return new_rect;
|
||||
}
|
||||
@@ -172,9 +174,11 @@ struct _NO_DISCARD_ Rect2 {
|
||||
#endif
|
||||
Rect2 new_rect;
|
||||
|
||||
new_rect.position = p_rect.position.min(position);
|
||||
new_rect.position.x = Math::min(p_rect.position.x, position.x);
|
||||
new_rect.position.y = Math::min(p_rect.position.y, position.y);
|
||||
|
||||
new_rect.size = (p_rect.position + p_rect.size).max(position + size);
|
||||
new_rect.size.x = Math::max(p_rect.position.x + p_rect.size.x, position.x + size.x);
|
||||
new_rect.size.y = Math::max(p_rect.position.y + p_rect.size.y, position.y + size.y);
|
||||
|
||||
new_rect.size = new_rect.size - new_rect.position; // Make relative again.
|
||||
|
||||
@@ -280,7 +284,7 @@ struct _NO_DISCARD_ Rect2 {
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Rect2 abs() const {
|
||||
return Rect2(position + size.minf(0), size.abs());
|
||||
return Rect2(Point2(position.x + Math::min(size.x, (real_t)0), position.y + Math::min(size.y, (real_t)0)), size.abs());
|
||||
}
|
||||
|
||||
Vector2 get_support(const Vector2 &p_normal) const {
|
||||
|
||||
@@ -97,12 +97,14 @@ struct _NO_DISCARD_ Rect2i {
|
||||
return Rect2i();
|
||||
}
|
||||
|
||||
new_rect.position = p_rect.position.max(position);
|
||||
new_rect.position.x = Math::max(p_rect.position.x, position.x);
|
||||
new_rect.position.y = Math::max(p_rect.position.y, position.y);
|
||||
|
||||
Point2i p_rect_end = p_rect.position + p_rect.size;
|
||||
Point2i end = position + size;
|
||||
|
||||
new_rect.size = p_rect_end.min(end) - new_rect.position;
|
||||
new_rect.size.x = Math::min(p_rect_end.x, end.x) - new_rect.position.x;
|
||||
new_rect.size.y = Math::min(p_rect_end.y, end.y) - new_rect.position.y;
|
||||
|
||||
return new_rect;
|
||||
}
|
||||
@@ -115,9 +117,11 @@ struct _NO_DISCARD_ Rect2i {
|
||||
#endif
|
||||
Rect2i new_rect;
|
||||
|
||||
new_rect.position = p_rect.position.min(position);
|
||||
new_rect.position.x = Math::min(p_rect.position.x, position.x);
|
||||
new_rect.position.y = Math::min(p_rect.position.y, position.y);
|
||||
|
||||
new_rect.size = (p_rect.position + p_rect.size).max(position + size);
|
||||
new_rect.size.x = Math::max(p_rect.position.x + p_rect.size.x, position.x + size.x);
|
||||
new_rect.size.y = Math::max(p_rect.position.y + p_rect.size.y, position.y + size.y);
|
||||
|
||||
new_rect.size = new_rect.size - new_rect.position; // Make relative again.
|
||||
|
||||
@@ -215,7 +219,7 @@ struct _NO_DISCARD_ Rect2i {
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Rect2i abs() const {
|
||||
return Rect2i(position + size.mini(0), size.abs());
|
||||
return Rect2i(Point2i(position.x + Math::min(size.x, 0), position.y + Math::min(size.y, 0)), size.abs());
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void set_end(const Vector2i &p_end) {
|
||||
|
||||
@@ -85,8 +85,6 @@ public:
|
||||
} \
|
||||
};
|
||||
|
||||
// All Variant::OBJECT types are intentionally omitted from this list because they are handled by
|
||||
// the unspecialized TypedArray definition.
|
||||
MAKE_TYPED_ARRAY(bool, Variant::BOOL)
|
||||
MAKE_TYPED_ARRAY(uint8_t, Variant::INT)
|
||||
MAKE_TYPED_ARRAY(int8_t, Variant::INT)
|
||||
@@ -106,14 +104,11 @@ MAKE_TYPED_ARRAY(Rect2i, Variant::RECT2I)
|
||||
MAKE_TYPED_ARRAY(Vector3, Variant::VECTOR3)
|
||||
MAKE_TYPED_ARRAY(Vector3i, Variant::VECTOR3I)
|
||||
MAKE_TYPED_ARRAY(Transform2D, Variant::TRANSFORM2D)
|
||||
MAKE_TYPED_ARRAY(Vector4, Variant::VECTOR4)
|
||||
MAKE_TYPED_ARRAY(Vector4i, Variant::VECTOR4I)
|
||||
MAKE_TYPED_ARRAY(Plane, Variant::PLANE)
|
||||
MAKE_TYPED_ARRAY(Quaternion, Variant::QUATERNION)
|
||||
MAKE_TYPED_ARRAY(AABB, Variant::AABB)
|
||||
MAKE_TYPED_ARRAY(Basis, Variant::BASIS)
|
||||
MAKE_TYPED_ARRAY(Transform3D, Variant::TRANSFORM3D)
|
||||
MAKE_TYPED_ARRAY(Projection, Variant::PROJECTION)
|
||||
MAKE_TYPED_ARRAY(Color, Variant::COLOR)
|
||||
MAKE_TYPED_ARRAY(StringName, Variant::STRING_NAME)
|
||||
MAKE_TYPED_ARRAY(NodePath, Variant::NODE_PATH)
|
||||
@@ -130,12 +125,7 @@ MAKE_TYPED_ARRAY(PackedFloat64Array, Variant::PACKED_FLOAT64_ARRAY)
|
||||
MAKE_TYPED_ARRAY(PackedStringArray, Variant::PACKED_STRING_ARRAY)
|
||||
MAKE_TYPED_ARRAY(PackedVector2Array, Variant::PACKED_VECTOR2_ARRAY)
|
||||
MAKE_TYPED_ARRAY(PackedVector3Array, Variant::PACKED_VECTOR3_ARRAY)
|
||||
MAKE_TYPED_ARRAY(PackedVector4Array, Variant::PACKED_VECTOR4_ARRAY)
|
||||
MAKE_TYPED_ARRAY(PackedColorArray, Variant::PACKED_COLOR_ARRAY)
|
||||
// If the IPAddress struct is added to godot-cpp, the following could also be added:
|
||||
//MAKE_TYPED_ARRAY(IPAddress, Variant::STRING)
|
||||
|
||||
#undef MAKE_TYPED_ARRAY
|
||||
|
||||
} // namespace godot
|
||||
|
||||
|
||||
@@ -100,7 +100,6 @@ public:
|
||||
PACKED_VECTOR2_ARRAY,
|
||||
PACKED_VECTOR3_ARRAY,
|
||||
PACKED_COLOR_ARRAY,
|
||||
PACKED_VECTOR4_ARRAY,
|
||||
|
||||
VARIANT_MAX
|
||||
};
|
||||
@@ -213,7 +212,6 @@ public:
|
||||
Variant(const PackedVector2Array &v);
|
||||
Variant(const PackedVector3Array &v);
|
||||
Variant(const PackedColorArray &v);
|
||||
Variant(const PackedVector4Array &v);
|
||||
~Variant();
|
||||
|
||||
operator bool() const;
|
||||
@@ -262,7 +260,6 @@ public:
|
||||
operator PackedVector2Array() const;
|
||||
operator PackedVector3Array() const;
|
||||
operator PackedColorArray() const;
|
||||
operator PackedVector4Array() const;
|
||||
|
||||
Variant &operator=(const Variant &other);
|
||||
Variant &operator=(Variant &&other);
|
||||
@@ -327,8 +324,6 @@ public:
|
||||
bool booleanize() const;
|
||||
String stringify() const;
|
||||
Variant duplicate(bool deep = false) const;
|
||||
static void blend(const Variant &a, const Variant &b, float c, Variant &r_dst);
|
||||
static void interpolate(const Variant &a, const Variant &b, float c, Variant &r_dst);
|
||||
|
||||
static String get_type_name(Variant::Type type);
|
||||
static bool can_convert(Variant::Type from, Variant::Type to);
|
||||
|
||||
@@ -91,18 +91,10 @@ struct _NO_DISCARD_ Vector2 {
|
||||
return Vector2(MIN(x, p_vector2.x), MIN(y, p_vector2.y));
|
||||
}
|
||||
|
||||
Vector2 minf(real_t p_scalar) const {
|
||||
return Vector2(MIN(x, p_scalar), MIN(y, p_scalar));
|
||||
}
|
||||
|
||||
Vector2 max(const Vector2 &p_vector2) const {
|
||||
return Vector2(MAX(x, p_vector2.x), MAX(y, p_vector2.y));
|
||||
}
|
||||
|
||||
Vector2 maxf(real_t p_scalar) const {
|
||||
return Vector2(MAX(x, p_scalar), MAX(y, p_scalar));
|
||||
}
|
||||
|
||||
real_t distance_to(const Vector2 &p_vector2) const;
|
||||
real_t distance_squared_to(const Vector2 &p_vector2) const;
|
||||
real_t angle_to(const Vector2 &p_vector2) const;
|
||||
@@ -177,9 +169,7 @@ struct _NO_DISCARD_ Vector2 {
|
||||
Vector2 ceil() const;
|
||||
Vector2 round() const;
|
||||
Vector2 snapped(const Vector2 &p_by) const;
|
||||
Vector2 snappedf(real_t p_by) const;
|
||||
Vector2 clamp(const Vector2 &p_min, const Vector2 &p_max) const;
|
||||
Vector2 clampf(real_t p_min, real_t p_max) const;
|
||||
real_t aspect() const { return width / height; }
|
||||
|
||||
operator String() const;
|
||||
|
||||
@@ -83,18 +83,10 @@ struct _NO_DISCARD_ Vector2i {
|
||||
return Vector2i(MIN(x, p_vector2i.x), MIN(y, p_vector2i.y));
|
||||
}
|
||||
|
||||
Vector2i mini(int32_t p_scalar) const {
|
||||
return Vector2i(MIN(x, p_scalar), MIN(y, p_scalar));
|
||||
}
|
||||
|
||||
Vector2i max(const Vector2i &p_vector2i) const {
|
||||
return Vector2i(MAX(x, p_vector2i.x), MAX(y, p_vector2i.y));
|
||||
}
|
||||
|
||||
Vector2i maxi(int32_t p_scalar) const {
|
||||
return Vector2i(MAX(x, p_scalar), MAX(y, p_scalar));
|
||||
}
|
||||
|
||||
Vector2i operator+(const Vector2i &p_v) const;
|
||||
void operator+=(const Vector2i &p_v);
|
||||
Vector2i operator-(const Vector2i &p_v) const;
|
||||
@@ -125,16 +117,10 @@ struct _NO_DISCARD_ Vector2i {
|
||||
int64_t length_squared() const;
|
||||
double length() const;
|
||||
|
||||
int64_t distance_squared_to(const Vector2i &p_to) const;
|
||||
double distance_to(const Vector2i &p_to) const;
|
||||
|
||||
real_t aspect() const { return width / (real_t)height; }
|
||||
Vector2i sign() const { return Vector2i(SIGN(x), SIGN(y)); }
|
||||
Vector2i abs() const { return Vector2i(Math::abs(x), Math::abs(y)); }
|
||||
Vector2i snapped(const Vector2i &p_step) const;
|
||||
Vector2i snappedi(int32_t p_step) const;
|
||||
Vector2i clamp(const Vector2i &p_min, const Vector2i &p_max) const;
|
||||
Vector2i clampi(int32_t p_min, int32_t p_max) const;
|
||||
|
||||
operator String() const;
|
||||
operator Vector2() const;
|
||||
|
||||
@@ -82,18 +82,10 @@ struct _NO_DISCARD_ Vector3 {
|
||||
return Vector3(MIN(x, p_vector3.x), MIN(y, p_vector3.y), MIN(z, p_vector3.z));
|
||||
}
|
||||
|
||||
Vector3 minf(real_t p_scalar) const {
|
||||
return Vector3(MIN(x, p_scalar), MIN(y, p_scalar), MIN(z, p_scalar));
|
||||
}
|
||||
|
||||
Vector3 max(const Vector3 &p_vector3) const {
|
||||
return Vector3(MAX(x, p_vector3.x), MAX(y, p_vector3.y), MAX(z, p_vector3.z));
|
||||
}
|
||||
|
||||
Vector3 maxf(real_t p_scalar) const {
|
||||
return Vector3(MAX(x, p_scalar), MAX(y, p_scalar), MAX(z, p_scalar));
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ real_t length() const;
|
||||
_FORCE_INLINE_ real_t length_squared() const;
|
||||
|
||||
@@ -106,9 +98,7 @@ struct _NO_DISCARD_ Vector3 {
|
||||
_FORCE_INLINE_ void zero();
|
||||
|
||||
void snap(const Vector3 p_val);
|
||||
void snapf(real_t p_val);
|
||||
Vector3 snapped(const Vector3 p_val) const;
|
||||
Vector3 snappedf(real_t p_val) const;
|
||||
|
||||
void rotate(const Vector3 &p_axis, const real_t p_angle);
|
||||
Vector3 rotated(const Vector3 &p_axis, const real_t p_angle) const;
|
||||
@@ -138,7 +128,6 @@ struct _NO_DISCARD_ Vector3 {
|
||||
_FORCE_INLINE_ Vector3 ceil() const;
|
||||
_FORCE_INLINE_ Vector3 round() const;
|
||||
Vector3 clamp(const Vector3 &p_min, const Vector3 &p_max) const;
|
||||
Vector3 clampf(real_t p_min, real_t p_max) const;
|
||||
|
||||
_FORCE_INLINE_ real_t distance_to(const Vector3 &p_to) const;
|
||||
_FORCE_INLINE_ real_t distance_squared_to(const Vector3 &p_to) const;
|
||||
|
||||
@@ -75,32 +75,18 @@ struct _NO_DISCARD_ Vector3i {
|
||||
return Vector3i(MIN(x, p_vector3i.x), MIN(y, p_vector3i.y), MIN(z, p_vector3i.z));
|
||||
}
|
||||
|
||||
Vector3i mini(int32_t p_scalar) const {
|
||||
return Vector3i(MIN(x, p_scalar), MIN(y, p_scalar), MIN(z, p_scalar));
|
||||
}
|
||||
|
||||
Vector3i max(const Vector3i &p_vector3i) const {
|
||||
return Vector3i(MAX(x, p_vector3i.x), MAX(y, p_vector3i.y), MAX(z, p_vector3i.z));
|
||||
}
|
||||
|
||||
Vector3i maxi(int32_t p_scalar) const {
|
||||
return Vector3i(MAX(x, p_scalar), MAX(y, p_scalar), MAX(z, p_scalar));
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ int64_t length_squared() const;
|
||||
_FORCE_INLINE_ double length() const;
|
||||
|
||||
_FORCE_INLINE_ int64_t distance_squared_to(const Vector3i &p_to) const;
|
||||
_FORCE_INLINE_ double distance_to(const Vector3i &p_to) const;
|
||||
|
||||
_FORCE_INLINE_ void zero();
|
||||
|
||||
_FORCE_INLINE_ Vector3i abs() const;
|
||||
_FORCE_INLINE_ Vector3i sign() const;
|
||||
Vector3i snapped(const Vector3i &p_step) const;
|
||||
Vector3i snappedi(int32_t p_step) const;
|
||||
Vector3i clamp(const Vector3i &p_min, const Vector3i &p_max) const;
|
||||
Vector3i clampi(int32_t p_min, int32_t p_max) const;
|
||||
|
||||
/* Operators */
|
||||
|
||||
@@ -150,14 +136,6 @@ double Vector3i::length() const {
|
||||
return Math::sqrt((double)length_squared());
|
||||
}
|
||||
|
||||
int64_t Vector3i::distance_squared_to(const Vector3i &p_to) const {
|
||||
return (p_to - *this).length_squared();
|
||||
}
|
||||
|
||||
double Vector3i::distance_to(const Vector3i &p_to) const {
|
||||
return (p_to - *this).length();
|
||||
}
|
||||
|
||||
Vector3i Vector3i::abs() const {
|
||||
return Vector3i(Math::abs(x), Math::abs(y), Math::abs(z));
|
||||
}
|
||||
|
||||
@@ -55,16 +55,17 @@ struct _NO_DISCARD_ Vector4 {
|
||||
real_t z;
|
||||
real_t w;
|
||||
};
|
||||
real_t components[4] = { 0, 0, 0, 0 };
|
||||
[[deprecated("Use coord instead")]] real_t components[4];
|
||||
real_t coord[4] = { 0, 0, 0, 0 };
|
||||
};
|
||||
|
||||
_FORCE_INLINE_ real_t &operator[](const int p_axis) {
|
||||
DEV_ASSERT((unsigned int)p_axis < 4);
|
||||
return components[p_axis];
|
||||
return coord[p_axis];
|
||||
}
|
||||
_FORCE_INLINE_ const real_t &operator[](const int p_axis) const {
|
||||
DEV_ASSERT((unsigned int)p_axis < 4);
|
||||
return components[p_axis];
|
||||
return coord[p_axis];
|
||||
}
|
||||
|
||||
Vector4::Axis min_axis_index() const;
|
||||
@@ -74,18 +75,10 @@ struct _NO_DISCARD_ Vector4 {
|
||||
return Vector4(MIN(x, p_vector4.x), MIN(y, p_vector4.y), MIN(z, p_vector4.z), MIN(w, p_vector4.w));
|
||||
}
|
||||
|
||||
Vector4 minf(real_t p_scalar) const {
|
||||
return Vector4(MIN(x, p_scalar), MIN(y, p_scalar), MIN(z, p_scalar), MIN(w, p_scalar));
|
||||
}
|
||||
|
||||
Vector4 max(const Vector4 &p_vector4) const {
|
||||
return Vector4(MAX(x, p_vector4.x), MAX(y, p_vector4.y), MAX(z, p_vector4.z), MAX(w, p_vector4.w));
|
||||
}
|
||||
|
||||
Vector4 maxf(real_t p_scalar) const {
|
||||
return Vector4(MAX(x, p_scalar), MAX(y, p_scalar), MAX(z, p_scalar), MAX(w, p_scalar));
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ real_t length_squared() const;
|
||||
bool is_equal_approx(const Vector4 &p_vec4) const;
|
||||
bool is_zero_approx() const;
|
||||
@@ -111,11 +104,8 @@ struct _NO_DISCARD_ Vector4 {
|
||||
Vector4 posmod(const real_t p_mod) const;
|
||||
Vector4 posmodv(const Vector4 &p_modv) const;
|
||||
void snap(const Vector4 &p_step);
|
||||
void snapf(real_t p_step);
|
||||
Vector4 snapped(const Vector4 &p_step) const;
|
||||
Vector4 snappedf(real_t p_step) const;
|
||||
Vector4 clamp(const Vector4 &p_min, const Vector4 &p_max) const;
|
||||
Vector4 clampf(real_t p_min, real_t p_max) const;
|
||||
|
||||
Vector4 inverse() const;
|
||||
_FORCE_INLINE_ real_t dot(const Vector4 &p_vec4) const;
|
||||
|
||||
@@ -77,32 +77,18 @@ struct _NO_DISCARD_ Vector4i {
|
||||
return Vector4i(MIN(x, p_vector4i.x), MIN(y, p_vector4i.y), MIN(z, p_vector4i.z), MIN(w, p_vector4i.w));
|
||||
}
|
||||
|
||||
Vector4i mini(int32_t p_scalar) const {
|
||||
return Vector4i(MIN(x, p_scalar), MIN(y, p_scalar), MIN(z, p_scalar), MIN(w, p_scalar));
|
||||
}
|
||||
|
||||
Vector4i max(const Vector4i &p_vector4i) const {
|
||||
return Vector4i(MAX(x, p_vector4i.x), MAX(y, p_vector4i.y), MAX(z, p_vector4i.z), MAX(w, p_vector4i.w));
|
||||
}
|
||||
|
||||
Vector4i maxi(int32_t p_scalar) const {
|
||||
return Vector4i(MAX(x, p_scalar), MAX(y, p_scalar), MAX(z, p_scalar), MAX(w, p_scalar));
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ int64_t length_squared() const;
|
||||
_FORCE_INLINE_ double length() const;
|
||||
|
||||
_FORCE_INLINE_ int64_t distance_squared_to(const Vector4i &p_to) const;
|
||||
_FORCE_INLINE_ double distance_to(const Vector4i &p_to) const;
|
||||
|
||||
_FORCE_INLINE_ void zero();
|
||||
|
||||
_FORCE_INLINE_ Vector4i abs() const;
|
||||
_FORCE_INLINE_ Vector4i sign() const;
|
||||
Vector4i snapped(const Vector4i &p_step) const;
|
||||
Vector4i snappedi(int32_t p_step) const;
|
||||
Vector4i clamp(const Vector4i &p_min, const Vector4i &p_max) const;
|
||||
Vector4i clampi(int32_t p_min, int32_t p_max) const;
|
||||
|
||||
/* Operators */
|
||||
|
||||
@@ -154,14 +140,6 @@ double Vector4i::length() const {
|
||||
return Math::sqrt((double)length_squared());
|
||||
}
|
||||
|
||||
int64_t Vector4i::distance_squared_to(const Vector4i &p_to) const {
|
||||
return (p_to - *this).length_squared();
|
||||
}
|
||||
|
||||
double Vector4i::distance_to(const Vector4i &p_to) const {
|
||||
return (p_to - *this).length();
|
||||
}
|
||||
|
||||
Vector4i Vector4i::abs() const {
|
||||
return Vector4i(Math::abs(x), Math::abs(y), Math::abs(z), Math::abs(w));
|
||||
}
|
||||
|
||||
@@ -6,26 +6,40 @@ from pathlib import Path
|
||||
|
||||
sys.path.insert(1, os.path.join(os.path.dirname(__file__), "..", ".."))
|
||||
|
||||
from binding_generator import generate_bindings, get_file_list
|
||||
from binding_generator import _generate_bindings, _get_file_list
|
||||
from build_profile import generate_trimmed_api
|
||||
|
||||
api_filepath = "gdextension/extension_api.json"
|
||||
bits = "64"
|
||||
precision = "single"
|
||||
output_dir = "self_test"
|
||||
|
||||
generate_bindings(api_filepath, use_template_get_node=False, bits=bits, precision=precision, output_dir=output_dir)
|
||||
flist = get_file_list(api_filepath, output_dir, headers=True, sources=True)
|
||||
|
||||
p = Path(output_dir) / "gen"
|
||||
allfiles = [str(f.as_posix()) for f in p.glob("**/*.*")]
|
||||
missing = list(filter((lambda f: f not in flist), allfiles))
|
||||
extras = list(filter((lambda f: f not in allfiles), flist))
|
||||
if len(missing) > 0 or len(extras) > 0:
|
||||
print("Error!")
|
||||
for f in missing:
|
||||
print("MISSING: " + str(f))
|
||||
for f in extras:
|
||||
print("EXTRA: " + str(f))
|
||||
sys.exit(1)
|
||||
else:
|
||||
print("OK!")
|
||||
def test(profile_filepath=""):
|
||||
api = generate_trimmed_api(api_filepath, profile_filepath)
|
||||
_generate_bindings(
|
||||
api,
|
||||
use_template_get_node=False,
|
||||
bits=bits,
|
||||
precision=precision,
|
||||
output_dir=output_dir,
|
||||
)
|
||||
flist = _get_file_list(api, output_dir, headers=True, sources=True)
|
||||
|
||||
p = Path(output_dir) / "gen"
|
||||
allfiles = [str(f.as_posix()) for f in p.glob("**/*.*")]
|
||||
missing = list(filter((lambda f: f not in flist), allfiles))
|
||||
extras = list(filter((lambda f: f not in allfiles), flist))
|
||||
if len(missing) > 0 or len(extras) > 0:
|
||||
print("Error!")
|
||||
for f in missing:
|
||||
print("MISSING: " + str(f))
|
||||
for f in extras:
|
||||
print("EXTRA: " + str(f))
|
||||
sys.exit(1)
|
||||
else:
|
||||
print("OK!")
|
||||
|
||||
|
||||
test()
|
||||
test("test/build_profile.json")
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
/**************************************************************************/
|
||||
|
||||
#include <godot_cpp/classes/file_access.hpp>
|
||||
#include <godot_cpp/classes/image.hpp>
|
||||
#include <godot_cpp/classes/worker_thread_pool.hpp>
|
||||
#include <godot_cpp/classes/xml_parser.hpp>
|
||||
|
||||
@@ -56,12 +55,4 @@ WorkerThreadPool::GroupID WorkerThreadPool::add_native_group_task(void (*p_func)
|
||||
return (GroupID)internal::gdextension_interface_worker_thread_pool_add_native_group_task(_owner, p_func, p_userdata, p_elements, p_tasks, p_high_priority, (GDExtensionConstStringPtr)&p_description);
|
||||
}
|
||||
|
||||
uint8_t *Image::ptrw() {
|
||||
return internal::gdextension_interface_image_ptrw(_owner);
|
||||
}
|
||||
|
||||
const uint8_t *Image::ptr() {
|
||||
return internal::gdextension_interface_image_ptr(_owner);
|
||||
}
|
||||
|
||||
} // namespace godot
|
||||
|
||||
@@ -39,16 +39,18 @@
|
||||
#include <godot_cpp/core/class_db.hpp>
|
||||
|
||||
namespace godot {
|
||||
thread_local const StringName *Wrapped::_constructing_extension_class_name = nullptr;
|
||||
thread_local const GDExtensionInstanceBindingCallbacks *Wrapped::_constructing_class_binding_callbacks = nullptr;
|
||||
|
||||
const StringName *Wrapped::_get_extension_class_name() {
|
||||
const StringName *Wrapped::_get_extension_class_name() const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Wrapped::_postinitialize() {
|
||||
// Only send NOTIFICATION_POSTINITIALIZE for extension classes.
|
||||
if (_is_extension_class()) {
|
||||
const StringName *extension_class = _get_extension_class_name();
|
||||
if (extension_class) {
|
||||
godot::internal::gdextension_interface_object_set_instance(_owner, reinterpret_cast<GDExtensionConstStringNamePtr>(extension_class), this);
|
||||
}
|
||||
godot::internal::gdextension_interface_object_set_instance_binding(_owner, godot::internal::token, this, _get_bindings_callbacks());
|
||||
if (extension_class) {
|
||||
_notificationv(Object::NOTIFICATION_POSTINITIALIZE);
|
||||
}
|
||||
}
|
||||
@@ -74,18 +76,6 @@ Wrapped::Wrapped(const StringName p_godot_class) {
|
||||
}
|
||||
#endif
|
||||
_owner = godot::internal::gdextension_interface_classdb_construct_object(reinterpret_cast<GDExtensionConstStringNamePtr>(p_godot_class._native_ptr()));
|
||||
|
||||
if (_constructing_extension_class_name) {
|
||||
godot::internal::gdextension_interface_object_set_instance(_owner, reinterpret_cast<GDExtensionConstStringNamePtr>(_constructing_extension_class_name), this);
|
||||
_constructing_extension_class_name = nullptr;
|
||||
}
|
||||
|
||||
if (likely(_constructing_class_binding_callbacks)) {
|
||||
godot::internal::gdextension_interface_object_set_instance_binding(_owner, godot::internal::token, this, _constructing_class_binding_callbacks);
|
||||
_constructing_class_binding_callbacks = nullptr;
|
||||
} else {
|
||||
CRASH_NOW_MSG("BUG: Godot Object created without binding callbacks. Did you forget to use memnew()?");
|
||||
}
|
||||
}
|
||||
|
||||
Wrapped::Wrapped(GodotObject *p_godot_object) {
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
|
||||
#include <godot_cpp/core/error_macros.hpp>
|
||||
#include <godot_cpp/godot.hpp>
|
||||
#include <godot_cpp/templates/vector.hpp>
|
||||
|
||||
#include <godot_cpp/core/memory.hpp>
|
||||
|
||||
@@ -340,46 +339,6 @@ void ClassDB::bind_virtual_method(const StringName &p_class, const StringName &p
|
||||
type.virtual_methods[p_method] = p_call;
|
||||
}
|
||||
|
||||
void ClassDB::add_virtual_method(const StringName &p_class, const MethodInfo &p_method, const Vector<StringName> &p_arg_names) {
|
||||
std::unordered_map<StringName, ClassInfo>::iterator type_it = classes.find(p_class);
|
||||
ERR_FAIL_COND_MSG(type_it == classes.end(), String("Class '{0}' doesn't exist.").format(Array::make(p_class)));
|
||||
|
||||
GDExtensionClassVirtualMethodInfo mi;
|
||||
mi.name = (GDExtensionStringNamePtr)&p_method.name;
|
||||
mi.method_flags = p_method.flags;
|
||||
mi.return_value = p_method.return_val._to_gdextension();
|
||||
mi.return_value_metadata = p_method.return_val_metadata;
|
||||
mi.argument_count = p_method.arguments.size();
|
||||
if (mi.argument_count > 0) {
|
||||
mi.arguments = (GDExtensionPropertyInfo *)memalloc(sizeof(GDExtensionPropertyInfo) * mi.argument_count);
|
||||
mi.arguments_metadata = (GDExtensionClassMethodArgumentMetadata *)memalloc(sizeof(GDExtensionClassMethodArgumentMetadata) * mi.argument_count);
|
||||
for (uint32_t i = 0; i < mi.argument_count; i++) {
|
||||
mi.arguments[i] = p_method.arguments[i]._to_gdextension();
|
||||
mi.arguments_metadata[i] = p_method.arguments_metadata[i];
|
||||
}
|
||||
} else {
|
||||
mi.arguments = nullptr;
|
||||
mi.arguments_metadata = nullptr;
|
||||
}
|
||||
|
||||
if (p_arg_names.size() != mi.argument_count) {
|
||||
WARN_PRINT("Mismatch argument name count for virtual method: " + String(p_class) + "::" + p_method.name);
|
||||
} else {
|
||||
for (int i = 0; i < p_arg_names.size(); i++) {
|
||||
mi.arguments[i].name = (GDExtensionStringNamePtr)&p_arg_names[i];
|
||||
}
|
||||
}
|
||||
|
||||
internal::gdextension_interface_classdb_register_extension_class_virtual_method(internal::library, &p_class, &mi);
|
||||
|
||||
if (mi.arguments) {
|
||||
memfree(mi.arguments);
|
||||
}
|
||||
if (mi.arguments_metadata) {
|
||||
memfree(mi.arguments_metadata);
|
||||
}
|
||||
}
|
||||
|
||||
void ClassDB::initialize_class(const ClassInfo &p_cl) {
|
||||
}
|
||||
|
||||
|
||||
@@ -114,9 +114,7 @@ GDExtensionInterfaceStringNewWithUtf32Chars gdextension_interface_string_new_wit
|
||||
GDExtensionInterfaceStringNewWithWideChars gdextension_interface_string_new_with_wide_chars = nullptr;
|
||||
GDExtensionInterfaceStringNewWithLatin1CharsAndLen gdextension_interface_string_new_with_latin1_chars_and_len = nullptr;
|
||||
GDExtensionInterfaceStringNewWithUtf8CharsAndLen gdextension_interface_string_new_with_utf8_chars_and_len = nullptr;
|
||||
GDExtensionInterfaceStringNewWithUtf8CharsAndLen2 gdextension_interface_string_new_with_utf8_chars_and_len2 = nullptr;
|
||||
GDExtensionInterfaceStringNewWithUtf16CharsAndLen gdextension_interface_string_new_with_utf16_chars_and_len = nullptr;
|
||||
GDExtensionInterfaceStringNewWithUtf16CharsAndLen2 gdextension_interface_string_new_with_utf16_chars_and_len2 = nullptr;
|
||||
GDExtensionInterfaceStringNewWithUtf32CharsAndLen gdextension_interface_string_new_with_utf32_chars_and_len = nullptr;
|
||||
GDExtensionInterfaceStringNewWithWideCharsAndLen gdextension_interface_string_new_with_wide_chars_and_len = nullptr;
|
||||
GDExtensionInterfaceStringToLatin1Chars gdextension_interface_string_to_latin1_chars = nullptr;
|
||||
@@ -156,8 +154,6 @@ GDExtensionInterfacePackedVector2ArrayOperatorIndex gdextension_interface_packed
|
||||
GDExtensionInterfacePackedVector2ArrayOperatorIndexConst gdextension_interface_packed_vector2_array_operator_index_const = nullptr;
|
||||
GDExtensionInterfacePackedVector3ArrayOperatorIndex gdextension_interface_packed_vector3_array_operator_index = nullptr;
|
||||
GDExtensionInterfacePackedVector3ArrayOperatorIndexConst gdextension_interface_packed_vector3_array_operator_index_const = nullptr;
|
||||
GDExtensionInterfacePackedVector4ArrayOperatorIndex gdextension_interface_packed_vector4_array_operator_index = nullptr;
|
||||
GDExtensionInterfacePackedVector4ArrayOperatorIndexConst gdextension_interface_packed_vector4_array_operator_index_const = nullptr;
|
||||
GDExtensionInterfaceArrayOperatorIndex gdextension_interface_array_operator_index = nullptr;
|
||||
GDExtensionInterfaceArrayOperatorIndexConst gdextension_interface_array_operator_index_const = nullptr;
|
||||
GDExtensionInterfaceArrayRef gdextension_interface_array_ref = nullptr;
|
||||
@@ -176,21 +172,18 @@ GDExtensionInterfaceObjectGetClassName gdextension_interface_object_get_class_na
|
||||
GDExtensionInterfaceObjectCastTo gdextension_interface_object_cast_to = nullptr;
|
||||
GDExtensionInterfaceObjectGetInstanceFromId gdextension_interface_object_get_instance_from_id = nullptr;
|
||||
GDExtensionInterfaceObjectGetInstanceId gdextension_interface_object_get_instance_id = nullptr;
|
||||
GDExtensionInterfaceObjectHasScriptMethod gdextension_interface_object_has_script_method = nullptr;
|
||||
GDExtensionInterfaceObjectCallScriptMethod gdextension_interface_object_call_script_method = nullptr;
|
||||
GDExtensionInterfaceCallableCustomCreate2 gdextension_interface_callable_custom_create2 = nullptr;
|
||||
GDExtensionInterfaceCallableCustomCreate gdextension_interface_callable_custom_create = nullptr;
|
||||
GDExtensionInterfaceCallableCustomGetUserData gdextension_interface_callable_custom_get_userdata = nullptr;
|
||||
GDExtensionInterfaceRefGetObject gdextension_interface_ref_get_object = nullptr;
|
||||
GDExtensionInterfaceRefSetObject gdextension_interface_ref_set_object = nullptr;
|
||||
GDExtensionInterfaceScriptInstanceCreate3 gdextension_interface_script_instance_create3 = nullptr;
|
||||
GDExtensionInterfaceScriptInstanceCreate2 gdextension_interface_script_instance_create2 = nullptr;
|
||||
GDExtensionInterfacePlaceHolderScriptInstanceCreate gdextension_interface_placeholder_script_instance_create = nullptr;
|
||||
GDExtensionInterfacePlaceHolderScriptInstanceUpdate gdextension_interface_placeholder_script_instance_update = nullptr;
|
||||
GDExtensionInterfaceClassdbConstructObject gdextension_interface_classdb_construct_object = nullptr;
|
||||
GDExtensionInterfaceClassdbGetMethodBind gdextension_interface_classdb_get_method_bind = nullptr;
|
||||
GDExtensionInterfaceClassdbGetClassTag gdextension_interface_classdb_get_class_tag = nullptr;
|
||||
GDExtensionInterfaceClassdbRegisterExtensionClass3 gdextension_interface_classdb_register_extension_class3 = nullptr;
|
||||
GDExtensionInterfaceClassdbRegisterExtensionClass2 gdextension_interface_classdb_register_extension_class2 = nullptr;
|
||||
GDExtensionInterfaceClassdbRegisterExtensionClassMethod gdextension_interface_classdb_register_extension_class_method = nullptr;
|
||||
GDExtensionInterfaceClassdbRegisterExtensionClassVirtualMethod gdextension_interface_classdb_register_extension_class_virtual_method = nullptr;
|
||||
GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant gdextension_interface_classdb_register_extension_class_integer_constant = nullptr;
|
||||
GDExtensionInterfaceClassdbRegisterExtensionClassProperty gdextension_interface_classdb_register_extension_class_property = nullptr;
|
||||
GDExtensionInterfaceClassdbRegisterExtensionClassPropertyIndexed gdextension_interface_classdb_register_extension_class_property_indexed = nullptr;
|
||||
@@ -201,40 +194,6 @@ GDExtensionInterfaceClassdbUnregisterExtensionClass gdextension_interface_classd
|
||||
GDExtensionInterfaceGetLibraryPath gdextension_interface_get_library_path = nullptr;
|
||||
GDExtensionInterfaceEditorAddPlugin gdextension_interface_editor_add_plugin = nullptr;
|
||||
GDExtensionInterfaceEditorRemovePlugin gdextension_interface_editor_remove_plugin = nullptr;
|
||||
GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8Chars gdextension_interface_editor_help_load_xml_from_utf8_chars = nullptr;
|
||||
GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8CharsAndLen gdextension_interface_editor_help_load_xml_from_utf8_chars_and_len = nullptr;
|
||||
GDExtensionInterfaceImagePtrw gdextension_interface_image_ptrw = nullptr;
|
||||
GDExtensionInterfaceImagePtr gdextension_interface_image_ptr = nullptr;
|
||||
|
||||
struct DocData {
|
||||
const char *hash = nullptr;
|
||||
int uncompressed_size = 0;
|
||||
int compressed_size = 0;
|
||||
const unsigned char *data = nullptr;
|
||||
|
||||
inline bool is_valid() const {
|
||||
return hash != nullptr && uncompressed_size > 0 && compressed_size > 0 && data != nullptr;
|
||||
}
|
||||
|
||||
void load_data() const;
|
||||
};
|
||||
|
||||
static DocData &get_doc_data() {
|
||||
static DocData doc_data;
|
||||
return doc_data;
|
||||
}
|
||||
|
||||
DocDataRegistration::DocDataRegistration(const char *p_hash, int p_uncompressed_size, int p_compressed_size, const unsigned char *p_data) {
|
||||
DocData &doc_data = get_doc_data();
|
||||
if (doc_data.is_valid()) {
|
||||
printf("ERROR: Attempting to register documentation data when we already have some - discarding.\n");
|
||||
return;
|
||||
}
|
||||
doc_data.hash = p_hash;
|
||||
doc_data.uncompressed_size = p_uncompressed_size;
|
||||
doc_data.compressed_size = p_compressed_size;
|
||||
doc_data.data = p_data;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
@@ -393,9 +352,7 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
|
||||
LOAD_PROC_ADDRESS(string_new_with_wide_chars, GDExtensionInterfaceStringNewWithWideChars);
|
||||
LOAD_PROC_ADDRESS(string_new_with_latin1_chars_and_len, GDExtensionInterfaceStringNewWithLatin1CharsAndLen);
|
||||
LOAD_PROC_ADDRESS(string_new_with_utf8_chars_and_len, GDExtensionInterfaceStringNewWithUtf8CharsAndLen);
|
||||
LOAD_PROC_ADDRESS(string_new_with_utf8_chars_and_len2, GDExtensionInterfaceStringNewWithUtf8CharsAndLen2);
|
||||
LOAD_PROC_ADDRESS(string_new_with_utf16_chars_and_len, GDExtensionInterfaceStringNewWithUtf16CharsAndLen);
|
||||
LOAD_PROC_ADDRESS(string_new_with_utf16_chars_and_len2, GDExtensionInterfaceStringNewWithUtf16CharsAndLen2);
|
||||
LOAD_PROC_ADDRESS(string_new_with_utf32_chars_and_len, GDExtensionInterfaceStringNewWithUtf32CharsAndLen);
|
||||
LOAD_PROC_ADDRESS(string_new_with_wide_chars_and_len, GDExtensionInterfaceStringNewWithWideCharsAndLen);
|
||||
LOAD_PROC_ADDRESS(string_to_latin1_chars, GDExtensionInterfaceStringToLatin1Chars);
|
||||
@@ -435,8 +392,6 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
|
||||
LOAD_PROC_ADDRESS(packed_vector2_array_operator_index_const, GDExtensionInterfacePackedVector2ArrayOperatorIndexConst);
|
||||
LOAD_PROC_ADDRESS(packed_vector3_array_operator_index, GDExtensionInterfacePackedVector3ArrayOperatorIndex);
|
||||
LOAD_PROC_ADDRESS(packed_vector3_array_operator_index_const, GDExtensionInterfacePackedVector3ArrayOperatorIndexConst);
|
||||
LOAD_PROC_ADDRESS(packed_vector4_array_operator_index, GDExtensionInterfacePackedVector4ArrayOperatorIndex);
|
||||
LOAD_PROC_ADDRESS(packed_vector4_array_operator_index_const, GDExtensionInterfacePackedVector4ArrayOperatorIndexConst);
|
||||
LOAD_PROC_ADDRESS(array_operator_index, GDExtensionInterfaceArrayOperatorIndex);
|
||||
LOAD_PROC_ADDRESS(array_operator_index_const, GDExtensionInterfaceArrayOperatorIndexConst);
|
||||
LOAD_PROC_ADDRESS(array_ref, GDExtensionInterfaceArrayRef);
|
||||
@@ -455,21 +410,18 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
|
||||
LOAD_PROC_ADDRESS(object_cast_to, GDExtensionInterfaceObjectCastTo);
|
||||
LOAD_PROC_ADDRESS(object_get_instance_from_id, GDExtensionInterfaceObjectGetInstanceFromId);
|
||||
LOAD_PROC_ADDRESS(object_get_instance_id, GDExtensionInterfaceObjectGetInstanceId);
|
||||
LOAD_PROC_ADDRESS(object_has_script_method, GDExtensionInterfaceObjectHasScriptMethod);
|
||||
LOAD_PROC_ADDRESS(object_call_script_method, GDExtensionInterfaceObjectCallScriptMethod);
|
||||
LOAD_PROC_ADDRESS(callable_custom_create2, GDExtensionInterfaceCallableCustomCreate2);
|
||||
LOAD_PROC_ADDRESS(callable_custom_create, GDExtensionInterfaceCallableCustomCreate);
|
||||
LOAD_PROC_ADDRESS(callable_custom_get_userdata, GDExtensionInterfaceCallableCustomGetUserData);
|
||||
LOAD_PROC_ADDRESS(ref_get_object, GDExtensionInterfaceRefGetObject);
|
||||
LOAD_PROC_ADDRESS(ref_set_object, GDExtensionInterfaceRefSetObject);
|
||||
LOAD_PROC_ADDRESS(script_instance_create3, GDExtensionInterfaceScriptInstanceCreate3);
|
||||
LOAD_PROC_ADDRESS(script_instance_create2, GDExtensionInterfaceScriptInstanceCreate2);
|
||||
LOAD_PROC_ADDRESS(placeholder_script_instance_create, GDExtensionInterfacePlaceHolderScriptInstanceCreate);
|
||||
LOAD_PROC_ADDRESS(placeholder_script_instance_update, GDExtensionInterfacePlaceHolderScriptInstanceUpdate);
|
||||
LOAD_PROC_ADDRESS(classdb_construct_object, GDExtensionInterfaceClassdbConstructObject);
|
||||
LOAD_PROC_ADDRESS(classdb_get_method_bind, GDExtensionInterfaceClassdbGetMethodBind);
|
||||
LOAD_PROC_ADDRESS(classdb_get_class_tag, GDExtensionInterfaceClassdbGetClassTag);
|
||||
LOAD_PROC_ADDRESS(classdb_register_extension_class3, GDExtensionInterfaceClassdbRegisterExtensionClass3);
|
||||
LOAD_PROC_ADDRESS(classdb_register_extension_class2, GDExtensionInterfaceClassdbRegisterExtensionClass2);
|
||||
LOAD_PROC_ADDRESS(classdb_register_extension_class_method, GDExtensionInterfaceClassdbRegisterExtensionClassMethod);
|
||||
LOAD_PROC_ADDRESS(classdb_register_extension_class_virtual_method, GDExtensionInterfaceClassdbRegisterExtensionClassVirtualMethod);
|
||||
LOAD_PROC_ADDRESS(classdb_register_extension_class_integer_constant, GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant);
|
||||
LOAD_PROC_ADDRESS(classdb_register_extension_class_property, GDExtensionInterfaceClassdbRegisterExtensionClassProperty);
|
||||
LOAD_PROC_ADDRESS(classdb_register_extension_class_property_indexed, GDExtensionInterfaceClassdbRegisterExtensionClassPropertyIndexed);
|
||||
@@ -480,10 +432,6 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
|
||||
LOAD_PROC_ADDRESS(get_library_path, GDExtensionInterfaceGetLibraryPath);
|
||||
LOAD_PROC_ADDRESS(editor_add_plugin, GDExtensionInterfaceEditorAddPlugin);
|
||||
LOAD_PROC_ADDRESS(editor_remove_plugin, GDExtensionInterfaceEditorRemovePlugin);
|
||||
LOAD_PROC_ADDRESS(editor_help_load_xml_from_utf8_chars, GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8Chars);
|
||||
LOAD_PROC_ADDRESS(editor_help_load_xml_from_utf8_chars_and_len, GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8CharsAndLen);
|
||||
LOAD_PROC_ADDRESS(image_ptrw, GDExtensionInterfaceImagePtrw);
|
||||
LOAD_PROC_ADDRESS(image_ptr, GDExtensionInterfaceImagePtr);
|
||||
|
||||
r_initialization->initialize = initialize_level;
|
||||
r_initialization->deinitialize = deinitialize_level;
|
||||
@@ -513,13 +461,6 @@ void GDExtensionBinding::initialize_level(void *p_userdata, GDExtensionInitializ
|
||||
ClassDB::initialize(p_level);
|
||||
}
|
||||
level_initialized[p_level]++;
|
||||
|
||||
if ((ModuleInitializationLevel)p_level == MODULE_INITIALIZATION_LEVEL_EDITOR) {
|
||||
const internal::DocData &doc_data = internal::get_doc_data();
|
||||
if (doc_data.is_valid()) {
|
||||
doc_data.load_data();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GDExtensionBinding::deinitialize_level(void *p_userdata, GDExtensionInitializationLevel p_level) {
|
||||
@@ -586,15 +527,4 @@ GDExtensionBool GDExtensionBinding::InitObject::init() const {
|
||||
return GDExtensionBinding::init(get_proc_address, library, init_data, initialization);
|
||||
}
|
||||
|
||||
void internal::DocData::load_data() const {
|
||||
PackedByteArray compressed;
|
||||
compressed.resize(compressed_size);
|
||||
memcpy(compressed.ptrw(), data, compressed_size);
|
||||
|
||||
// FileAccess::COMPRESSION_DEFLATE = 1
|
||||
PackedByteArray decompressed = compressed.decompress(uncompressed_size, 1);
|
||||
|
||||
internal::gdextension_interface_editor_help_load_xml_from_utf8_chars_and_len(reinterpret_cast<const char *>(decompressed.ptr()), uncompressed_size);
|
||||
}
|
||||
|
||||
} // namespace godot
|
||||
|
||||
@@ -1037,12 +1037,15 @@ void Basis::rotate_sh(real_t *p_values) {
|
||||
p_values[8] = d4 * s_scale_dst4;
|
||||
}
|
||||
|
||||
Basis Basis::looking_at(const Vector3 &p_target, const Vector3 &p_up) {
|
||||
Basis Basis::looking_at(const Vector3 &p_target, const Vector3 &p_up, bool p_use_model_front) {
|
||||
#ifdef MATH_CHECKS
|
||||
ERR_FAIL_COND_V_MSG(p_target.is_zero_approx(), Basis(), "The target vector can't be zero.");
|
||||
ERR_FAIL_COND_V_MSG(p_up.is_zero_approx(), Basis(), "The up vector can't be zero.");
|
||||
#endif
|
||||
Vector3 v_z = -p_target.normalized();
|
||||
Vector3 v_z = p_target.normalized();
|
||||
if (!p_use_model_front) {
|
||||
v_z = -v_z;
|
||||
}
|
||||
Vector3 v_x = p_up.cross(v_z);
|
||||
#ifdef MATH_CHECKS
|
||||
ERR_FAIL_COND_V_MSG(v_x.is_zero_approx(), Basis(), "The target vector and up vector can't be parallel to each other.");
|
||||
|
||||
@@ -35,11 +35,6 @@
|
||||
|
||||
namespace godot {
|
||||
|
||||
int CallableCustomBase::get_argument_count(bool &r_is_valid) const {
|
||||
r_is_valid = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void callable_custom_call(void *p_userdata, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error) {
|
||||
CallableCustom *callable_custom = (CallableCustom *)p_userdata;
|
||||
callable_custom->call((const Variant **)p_args, p_argument_count, *(Variant *)r_return, *r_error);
|
||||
@@ -89,21 +84,13 @@ static GDExtensionBool callable_custom_less_than_func(void *p_a, void *p_b) {
|
||||
return func_a(a, b);
|
||||
}
|
||||
|
||||
static GDExtensionInt custom_callable_get_argument_count_func(void *p_userdata, GDExtensionBool *r_is_valid) {
|
||||
CallableCustom *callable_custom = (CallableCustom *)p_userdata;
|
||||
bool valid = false;
|
||||
int ret = callable_custom->get_argument_count(valid);
|
||||
*r_is_valid = valid;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool CallableCustom::is_valid() const {
|
||||
// The same default implementation as in Godot.
|
||||
return ObjectDB::get_instance(get_object());
|
||||
}
|
||||
|
||||
Callable::Callable(CallableCustom *p_callable_custom) {
|
||||
GDExtensionCallableCustomInfo2 info = {};
|
||||
GDExtensionCallableCustomInfo info = {};
|
||||
info.callable_userdata = p_callable_custom;
|
||||
info.token = internal::token;
|
||||
info.object_id = p_callable_custom->get_object();
|
||||
@@ -114,9 +101,8 @@ Callable::Callable(CallableCustom *p_callable_custom) {
|
||||
info.equal_func = &callable_custom_equal_func;
|
||||
info.less_than_func = &callable_custom_less_than_func;
|
||||
info.to_string_func = &callable_custom_to_string;
|
||||
info.get_argument_count_func = &custom_callable_get_argument_count_func;
|
||||
|
||||
::godot::internal::gdextension_interface_callable_custom_create2(_native_ptr(), &info);
|
||||
::godot::internal::gdextension_interface_callable_custom_create(_native_ptr(), &info);
|
||||
}
|
||||
|
||||
CallableCustom *Callable::get_custom() const {
|
||||
|
||||
@@ -77,14 +77,6 @@ static GDExtensionBool custom_callable_mp_less_than_func(void *p_a, void *p_b) {
|
||||
return memcmp(a->get_comp_ptr(), b->get_comp_ptr(), a->get_comp_size() * 4) < 0;
|
||||
}
|
||||
|
||||
static GDExtensionInt custom_callable_mp_get_argument_count_func(void *p_userdata, GDExtensionBool *r_is_valid) {
|
||||
CallableCustomMethodPointerBase *callable_method_pointer = (CallableCustomMethodPointerBase *)p_userdata;
|
||||
bool valid = false;
|
||||
int ret = callable_method_pointer->get_argument_count(valid);
|
||||
*r_is_valid = valid;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CallableCustomMethodPointerBase::_setup(uint32_t *p_base_ptr, uint32_t p_ptr_size) {
|
||||
comp_ptr = p_base_ptr;
|
||||
comp_size = p_ptr_size / 4;
|
||||
@@ -101,7 +93,7 @@ void CallableCustomMethodPointerBase::_setup(uint32_t *p_base_ptr, uint32_t p_pt
|
||||
namespace internal {
|
||||
|
||||
Callable create_callable_from_ccmp(CallableCustomMethodPointerBase *p_callable_method_pointer) {
|
||||
GDExtensionCallableCustomInfo2 info = {};
|
||||
GDExtensionCallableCustomInfo info = {};
|
||||
info.callable_userdata = p_callable_method_pointer;
|
||||
info.token = internal::token;
|
||||
info.object_id = p_callable_method_pointer->get_object();
|
||||
@@ -111,10 +103,9 @@ Callable create_callable_from_ccmp(CallableCustomMethodPointerBase *p_callable_m
|
||||
info.hash_func = &custom_callable_mp_hash;
|
||||
info.equal_func = &custom_callable_mp_equal_func;
|
||||
info.less_than_func = &custom_callable_mp_less_than_func;
|
||||
info.get_argument_count_func = &custom_callable_mp_get_argument_count_func;
|
||||
|
||||
Callable callable;
|
||||
::godot::internal::gdextension_interface_callable_custom_create2(callable._native_ptr(), &info);
|
||||
::godot::internal::gdextension_interface_callable_custom_create(callable._native_ptr(), &info);
|
||||
return callable;
|
||||
}
|
||||
|
||||
|
||||
@@ -178,8 +178,8 @@ String String::utf8(const char *from, int64_t len) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
Error String::parse_utf8(const char *from, int64_t len) {
|
||||
return (Error)internal::gdextension_interface_string_new_with_utf8_chars_and_len2(_native_ptr(), from, len);
|
||||
void String::parse_utf8(const char *from, int64_t len) {
|
||||
internal::gdextension_interface_string_new_with_utf8_chars_and_len(_native_ptr(), from, len);
|
||||
}
|
||||
|
||||
String String::utf16(const char16_t *from, int64_t len) {
|
||||
@@ -188,8 +188,8 @@ String String::utf16(const char16_t *from, int64_t len) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
Error String::parse_utf16(const char16_t *from, int64_t len, bool default_little_endian) {
|
||||
return (Error)internal::gdextension_interface_string_new_with_utf16_chars_and_len2(_native_ptr(), from, len, default_little_endian);
|
||||
void String::parse_utf16(const char16_t *from, int64_t len) {
|
||||
internal::gdextension_interface_string_new_with_utf16_chars_and_len(_native_ptr(), from, len);
|
||||
}
|
||||
|
||||
String String::num_real(double p_num, bool p_trailing) {
|
||||
|
||||
@@ -43,7 +43,6 @@
|
||||
#include <godot_cpp/variant/packed_string_array.hpp>
|
||||
#include <godot_cpp/variant/packed_vector2_array.hpp>
|
||||
#include <godot_cpp/variant/packed_vector3_array.hpp>
|
||||
#include <godot_cpp/variant/packed_vector4_array.hpp>
|
||||
|
||||
namespace godot {
|
||||
|
||||
@@ -199,24 +198,6 @@ Vector3 *PackedVector3Array::ptrw() {
|
||||
return (Vector3 *)internal::gdextension_interface_packed_vector3_array_operator_index((GDExtensionTypePtr *)this, 0);
|
||||
}
|
||||
|
||||
const Vector4 &PackedVector4Array::operator[](int64_t p_index) const {
|
||||
const Vector4 *vec = (const Vector4 *)internal::gdextension_interface_packed_vector4_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
|
||||
return *vec;
|
||||
}
|
||||
|
||||
Vector4 &PackedVector4Array::operator[](int64_t p_index) {
|
||||
Vector4 *vec = (Vector4 *)internal::gdextension_interface_packed_vector4_array_operator_index((GDExtensionTypePtr *)this, p_index);
|
||||
return *vec;
|
||||
}
|
||||
|
||||
const Vector4 *PackedVector4Array::ptr() const {
|
||||
return (const Vector4 *)internal::gdextension_interface_packed_vector4_array_operator_index_const((GDExtensionTypePtr *)this, 0);
|
||||
}
|
||||
|
||||
Vector4 *PackedVector4Array::ptrw() {
|
||||
return (Vector4 *)internal::gdextension_interface_packed_vector4_array_operator_index((GDExtensionTypePtr *)this, 0);
|
||||
}
|
||||
|
||||
const Variant &Array::operator[](int64_t p_index) const {
|
||||
const Variant *var = (const Variant *)internal::gdextension_interface_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
|
||||
return *var;
|
||||
|
||||
@@ -37,28 +37,15 @@ namespace godot {
|
||||
|
||||
real_t Quaternion::angle_to(const Quaternion &p_to) const {
|
||||
real_t d = dot(p_to);
|
||||
return Math::acos(CLAMP(d * d * 2 - 1, -1, 1));
|
||||
// acos does clamping.
|
||||
return Math::acos(d * d * 2 - 1);
|
||||
}
|
||||
|
||||
// get_euler_xyz returns a vector containing the Euler angles in the format
|
||||
// (ax,ay,az), where ax is the angle of rotation around x axis,
|
||||
// and similar for other axes.
|
||||
// This implementation uses XYZ convention (Z is the first rotation).
|
||||
Vector3 Quaternion::get_euler_xyz() const {
|
||||
Basis m(*this);
|
||||
return m.get_euler(EULER_ORDER_XYZ);
|
||||
}
|
||||
|
||||
// get_euler_yxz returns a vector containing the Euler angles in the format
|
||||
// (ax,ay,az), where ax is the angle of rotation around x axis,
|
||||
// and similar for other axes.
|
||||
// This implementation uses YXZ convention (Z is the first rotation).
|
||||
Vector3 Quaternion::get_euler_yxz() const {
|
||||
Vector3 Quaternion::get_euler(EulerOrder p_order) const {
|
||||
#ifdef MATH_CHECKS
|
||||
ERR_FAIL_COND_V_MSG(!is_normalized(), Vector3(0, 0, 0), "The quaternion must be normalized.");
|
||||
ERR_FAIL_COND_V_MSG(!is_normalized(), Vector3(0, 0, 0), "The quaternion " + operator String() + " must be normalized.");
|
||||
#endif
|
||||
Basis m(*this);
|
||||
return m.get_euler(EULER_ORDER_YXZ);
|
||||
return Basis(*this).get_euler(p_order);
|
||||
}
|
||||
|
||||
void Quaternion::operator*=(const Quaternion &p_q) {
|
||||
@@ -103,7 +90,7 @@ bool Quaternion::is_normalized() const {
|
||||
|
||||
Quaternion Quaternion::inverse() const {
|
||||
#ifdef MATH_CHECKS
|
||||
ERR_FAIL_COND_V_MSG(!is_normalized(), Quaternion(), "The quaternion must be normalized.");
|
||||
ERR_FAIL_COND_V_MSG(!is_normalized(), Quaternion(), "The quaternion " + operator String() + " must be normalized.");
|
||||
#endif
|
||||
return Quaternion(-x, -y, -z, w);
|
||||
}
|
||||
@@ -125,10 +112,10 @@ Quaternion Quaternion::exp() const {
|
||||
return Quaternion(src_v, theta);
|
||||
}
|
||||
|
||||
Quaternion Quaternion::slerp(const Quaternion &p_to, const real_t &p_weight) const {
|
||||
Quaternion Quaternion::slerp(const Quaternion &p_to, real_t p_weight) const {
|
||||
#ifdef MATH_CHECKS
|
||||
ERR_FAIL_COND_V_MSG(!is_normalized(), Quaternion(), "The start quaternion must be normalized.");
|
||||
ERR_FAIL_COND_V_MSG(!p_to.is_normalized(), Quaternion(), "The end quaternion must be normalized.");
|
||||
ERR_FAIL_COND_V_MSG(!is_normalized(), Quaternion(), "The start quaternion " + operator String() + " must be normalized.");
|
||||
ERR_FAIL_COND_V_MSG(!p_to.is_normalized(), Quaternion(), "The end quaternion " + p_to.operator String() + " must be normalized.");
|
||||
#endif
|
||||
Quaternion to1;
|
||||
real_t omega, cosom, sinom, scale0, scale1;
|
||||
@@ -166,10 +153,10 @@ Quaternion Quaternion::slerp(const Quaternion &p_to, const real_t &p_weight) con
|
||||
scale0 * w + scale1 * to1.w);
|
||||
}
|
||||
|
||||
Quaternion Quaternion::slerpni(const Quaternion &p_to, const real_t &p_weight) const {
|
||||
Quaternion Quaternion::slerpni(const Quaternion &p_to, real_t p_weight) const {
|
||||
#ifdef MATH_CHECKS
|
||||
ERR_FAIL_COND_V_MSG(!is_normalized(), Quaternion(), "The start quaternion must be normalized.");
|
||||
ERR_FAIL_COND_V_MSG(!p_to.is_normalized(), Quaternion(), "The end quaternion must be normalized.");
|
||||
ERR_FAIL_COND_V_MSG(!is_normalized(), Quaternion(), "The start quaternion " + operator String() + " must be normalized.");
|
||||
ERR_FAIL_COND_V_MSG(!p_to.is_normalized(), Quaternion(), "The end quaternion " + p_to.operator String() + " must be normalized.");
|
||||
#endif
|
||||
const Quaternion &from = *this;
|
||||
|
||||
@@ -190,10 +177,10 @@ Quaternion Quaternion::slerpni(const Quaternion &p_to, const real_t &p_weight) c
|
||||
invFactor * from.w + newFactor * p_to.w);
|
||||
}
|
||||
|
||||
Quaternion Quaternion::spherical_cubic_interpolate(const Quaternion &p_b, const Quaternion &p_pre_a, const Quaternion &p_post_b, const real_t &p_weight) const {
|
||||
Quaternion Quaternion::spherical_cubic_interpolate(const Quaternion &p_b, const Quaternion &p_pre_a, const Quaternion &p_post_b, real_t p_weight) const {
|
||||
#ifdef MATH_CHECKS
|
||||
ERR_FAIL_COND_V_MSG(!is_normalized(), Quaternion(), "The start quaternion must be normalized.");
|
||||
ERR_FAIL_COND_V_MSG(!p_b.is_normalized(), Quaternion(), "The end quaternion must be normalized.");
|
||||
ERR_FAIL_COND_V_MSG(!is_normalized(), Quaternion(), "The start quaternion " + operator String() + " must be normalized.");
|
||||
ERR_FAIL_COND_V_MSG(!p_b.is_normalized(), Quaternion(), "The end quaternion " + p_b.operator String() + " must be normalized.");
|
||||
#endif
|
||||
Quaternion from_q = *this;
|
||||
Quaternion pre_q = p_pre_a;
|
||||
@@ -236,15 +223,15 @@ Quaternion Quaternion::spherical_cubic_interpolate(const Quaternion &p_b, const
|
||||
ln.z = Math::cubic_interpolate(ln_from.z, ln_to.z, ln_pre.z, ln_post.z, p_weight);
|
||||
Quaternion q2 = to_q * ln.exp();
|
||||
|
||||
// To cancel error made by Expmap ambiguity, do blends.
|
||||
// To cancel error made by Expmap ambiguity, do blending.
|
||||
return q1.slerp(q2, p_weight);
|
||||
}
|
||||
|
||||
Quaternion Quaternion::spherical_cubic_interpolate_in_time(const Quaternion &p_b, const Quaternion &p_pre_a, const Quaternion &p_post_b, const real_t &p_weight,
|
||||
const real_t &p_b_t, const real_t &p_pre_a_t, const real_t &p_post_b_t) const {
|
||||
Quaternion Quaternion::spherical_cubic_interpolate_in_time(const Quaternion &p_b, const Quaternion &p_pre_a, const Quaternion &p_post_b, real_t p_weight,
|
||||
real_t p_b_t, real_t p_pre_a_t, real_t p_post_b_t) const {
|
||||
#ifdef MATH_CHECKS
|
||||
ERR_FAIL_COND_V_MSG(!is_normalized(), Quaternion(), "The start quaternion must be normalized.");
|
||||
ERR_FAIL_COND_V_MSG(!p_b.is_normalized(), Quaternion(), "The end quaternion must be normalized.");
|
||||
ERR_FAIL_COND_V_MSG(!is_normalized(), Quaternion(), "The start quaternion " + operator String() + " must be normalized.");
|
||||
ERR_FAIL_COND_V_MSG(!p_b.is_normalized(), Quaternion(), "The end quaternion " + p_b.operator String() + " must be normalized.");
|
||||
#endif
|
||||
Quaternion from_q = *this;
|
||||
Quaternion pre_q = p_pre_a;
|
||||
@@ -287,7 +274,7 @@ Quaternion Quaternion::spherical_cubic_interpolate_in_time(const Quaternion &p_b
|
||||
ln.z = Math::cubic_interpolate_in_time(ln_from.z, ln_to.z, ln_pre.z, ln_post.z, p_weight, p_b_t, p_pre_a_t, p_post_b_t);
|
||||
Quaternion q2 = to_q * ln.exp();
|
||||
|
||||
// To cancel error made by Expmap ambiguity, do blends.
|
||||
// To cancel error made by Expmap ambiguity, do blending.
|
||||
return q1.slerp(q2, p_weight);
|
||||
}
|
||||
|
||||
@@ -309,7 +296,7 @@ real_t Quaternion::get_angle() const {
|
||||
|
||||
Quaternion::Quaternion(const Vector3 &p_axis, real_t p_angle) {
|
||||
#ifdef MATH_CHECKS
|
||||
ERR_FAIL_COND_MSG(!p_axis.is_normalized(), "The axis Vector3 must be normalized.");
|
||||
ERR_FAIL_COND_MSG(!p_axis.is_normalized(), "The axis Vector3 " + p_axis.operator String() + " must be normalized.");
|
||||
#endif
|
||||
real_t d = p_axis.length();
|
||||
if (d == 0) {
|
||||
@@ -332,7 +319,7 @@ Quaternion::Quaternion(const Vector3 &p_axis, real_t p_angle) {
|
||||
// (ax, ay, az), where ax is the angle of rotation around x axis,
|
||||
// and similar for other axes.
|
||||
// This implementation uses YXZ convention (Z is the first rotation).
|
||||
Quaternion::Quaternion(const Vector3 &p_euler) {
|
||||
Quaternion Quaternion::from_euler(const Vector3 &p_euler) {
|
||||
real_t half_a1 = p_euler.y * 0.5f;
|
||||
real_t half_a2 = p_euler.x * 0.5f;
|
||||
real_t half_a3 = p_euler.z * 0.5f;
|
||||
@@ -348,10 +335,11 @@ Quaternion::Quaternion(const Vector3 &p_euler) {
|
||||
real_t cos_a3 = Math::cos(half_a3);
|
||||
real_t sin_a3 = Math::sin(half_a3);
|
||||
|
||||
x = sin_a1 * cos_a2 * sin_a3 + cos_a1 * sin_a2 * cos_a3;
|
||||
y = sin_a1 * cos_a2 * cos_a3 - cos_a1 * sin_a2 * sin_a3;
|
||||
z = -sin_a1 * sin_a2 * cos_a3 + cos_a1 * cos_a2 * sin_a3;
|
||||
w = sin_a1 * sin_a2 * sin_a3 + cos_a1 * cos_a2 * cos_a3;
|
||||
return Quaternion(
|
||||
sin_a1 * cos_a2 * sin_a3 + cos_a1 * sin_a2 * cos_a3,
|
||||
sin_a1 * cos_a2 * cos_a3 - cos_a1 * sin_a2 * sin_a3,
|
||||
-sin_a1 * sin_a2 * cos_a3 + cos_a1 * cos_a2 * sin_a3,
|
||||
sin_a1 * sin_a2 * sin_a3 + cos_a1 * cos_a2 * cos_a3);
|
||||
}
|
||||
|
||||
} // namespace godot
|
||||
|
||||
@@ -66,7 +66,6 @@ void Variant::init_bindings() {
|
||||
PackedStringArray::init_bindings();
|
||||
PackedVector2Array::init_bindings();
|
||||
PackedVector3Array::init_bindings();
|
||||
PackedVector4Array::init_bindings();
|
||||
PackedColorArray::init_bindings();
|
||||
}
|
||||
|
||||
@@ -249,10 +248,6 @@ Variant::Variant(const PackedColorArray &v) {
|
||||
from_type_constructor[PACKED_COLOR_ARRAY](_native_ptr(), v._native_ptr());
|
||||
}
|
||||
|
||||
Variant::Variant(const PackedVector4Array &v) {
|
||||
from_type_constructor[PACKED_VECTOR4_ARRAY](_native_ptr(), v._native_ptr());
|
||||
}
|
||||
|
||||
Variant::~Variant() {
|
||||
internal::gdextension_interface_variant_destroy(_native_ptr());
|
||||
}
|
||||
@@ -511,10 +506,6 @@ Variant::operator PackedColorArray() const {
|
||||
return PackedColorArray(this);
|
||||
}
|
||||
|
||||
Variant::operator PackedVector4Array() const {
|
||||
return PackedVector4Array(this);
|
||||
}
|
||||
|
||||
Variant &Variant::operator=(const Variant &other) {
|
||||
clear();
|
||||
internal::gdextension_interface_variant_new_copy(_native_ptr(), other._native_ptr());
|
||||
|
||||
@@ -137,24 +137,12 @@ Vector2 Vector2::clamp(const Vector2 &p_min, const Vector2 &p_max) const {
|
||||
CLAMP(y, p_min.y, p_max.y));
|
||||
}
|
||||
|
||||
Vector2 Vector2::clampf(real_t p_min, real_t p_max) const {
|
||||
return Vector2(
|
||||
CLAMP(x, p_min, p_max),
|
||||
CLAMP(y, p_min, p_max));
|
||||
}
|
||||
|
||||
Vector2 Vector2::snapped(const Vector2 &p_step) const {
|
||||
return Vector2(
|
||||
Math::snapped(x, p_step.x),
|
||||
Math::snapped(y, p_step.y));
|
||||
}
|
||||
|
||||
Vector2 Vector2::snappedf(real_t p_step) const {
|
||||
return Vector2(
|
||||
Math::snapped(x, p_step),
|
||||
Math::snapped(y, p_step));
|
||||
}
|
||||
|
||||
Vector2 Vector2::limit_length(const real_t p_len) const {
|
||||
const real_t l = length();
|
||||
Vector2 v = *this;
|
||||
|
||||
@@ -35,30 +35,12 @@
|
||||
|
||||
namespace godot {
|
||||
|
||||
Vector2i Vector2i::snapped(const Vector2i &p_step) const {
|
||||
return Vector2i(
|
||||
Math::snapped(x, p_step.x),
|
||||
Math::snapped(y, p_step.y));
|
||||
}
|
||||
|
||||
Vector2i Vector2i::snappedi(int32_t p_step) const {
|
||||
return Vector2i(
|
||||
Math::snapped(x, p_step),
|
||||
Math::snapped(y, p_step));
|
||||
}
|
||||
|
||||
Vector2i Vector2i::clamp(const Vector2i &p_min, const Vector2i &p_max) const {
|
||||
return Vector2i(
|
||||
CLAMP(x, p_min.x, p_max.x),
|
||||
CLAMP(y, p_min.y, p_max.y));
|
||||
}
|
||||
|
||||
Vector2i Vector2i::clampi(int32_t p_min, int32_t p_max) const {
|
||||
return Vector2i(
|
||||
CLAMP(x, p_min, p_max),
|
||||
CLAMP(y, p_min, p_max));
|
||||
}
|
||||
|
||||
int64_t Vector2i::length_squared() const {
|
||||
return x * (int64_t)x + y * (int64_t)y;
|
||||
}
|
||||
@@ -67,14 +49,6 @@ double Vector2i::length() const {
|
||||
return Math::sqrt((double)length_squared());
|
||||
}
|
||||
|
||||
int64_t Vector2i::distance_squared_to(const Vector2i &p_to) const {
|
||||
return (p_to - *this).length_squared();
|
||||
}
|
||||
|
||||
double Vector2i::distance_to(const Vector2i &p_to) const {
|
||||
return (p_to - *this).length();
|
||||
}
|
||||
|
||||
Vector2i Vector2i::operator+(const Vector2i &p_v) const {
|
||||
return Vector2i(x + p_v.x, y + p_v.y);
|
||||
}
|
||||
|
||||
@@ -54,37 +54,18 @@ Vector3 Vector3::clamp(const Vector3 &p_min, const Vector3 &p_max) const {
|
||||
CLAMP(z, p_min.z, p_max.z));
|
||||
}
|
||||
|
||||
Vector3 Vector3::clampf(real_t p_min, real_t p_max) const {
|
||||
return Vector3(
|
||||
CLAMP(x, p_min, p_max),
|
||||
CLAMP(y, p_min, p_max),
|
||||
CLAMP(z, p_min, p_max));
|
||||
}
|
||||
|
||||
void Vector3::snap(const Vector3 p_step) {
|
||||
x = Math::snapped(x, p_step.x);
|
||||
y = Math::snapped(y, p_step.y);
|
||||
z = Math::snapped(z, p_step.z);
|
||||
}
|
||||
|
||||
void Vector3::snapf(real_t p_step) {
|
||||
x = Math::snapped(x, p_step);
|
||||
y = Math::snapped(y, p_step);
|
||||
z = Math::snapped(z, p_step);
|
||||
}
|
||||
|
||||
Vector3 Vector3::snapped(const Vector3 p_step) const {
|
||||
Vector3 v = *this;
|
||||
v.snap(p_step);
|
||||
return v;
|
||||
}
|
||||
|
||||
Vector3 Vector3::snappedf(real_t p_step) const {
|
||||
Vector3 v = *this;
|
||||
v.snapf(p_step);
|
||||
return v;
|
||||
}
|
||||
|
||||
Vector3 Vector3::limit_length(const real_t p_len) const {
|
||||
const real_t l = length();
|
||||
Vector3 v = *this;
|
||||
|
||||
@@ -35,20 +35,6 @@
|
||||
|
||||
namespace godot {
|
||||
|
||||
Vector3i Vector3i::snapped(const Vector3i &p_step) const {
|
||||
return Vector3i(
|
||||
Math::snapped(x, p_step.x),
|
||||
Math::snapped(y, p_step.y),
|
||||
Math::snapped(z, p_step.z));
|
||||
}
|
||||
|
||||
Vector3i Vector3i::snappedi(int32_t p_step) const {
|
||||
return Vector3i(
|
||||
Math::snapped(x, p_step),
|
||||
Math::snapped(y, p_step),
|
||||
Math::snapped(z, p_step));
|
||||
}
|
||||
|
||||
Vector3i::Axis Vector3i::min_axis_index() const {
|
||||
return x < y ? (x < z ? Vector3i::AXIS_X : Vector3i::AXIS_Z) : (y < z ? Vector3i::AXIS_Y : Vector3i::AXIS_Z);
|
||||
}
|
||||
@@ -64,13 +50,6 @@ Vector3i Vector3i::clamp(const Vector3i &p_min, const Vector3i &p_max) const {
|
||||
CLAMP(z, p_min.z, p_max.z));
|
||||
}
|
||||
|
||||
Vector3i Vector3i::clampi(int32_t p_min, int32_t p_max) const {
|
||||
return Vector3i(
|
||||
CLAMP(x, p_min, p_max),
|
||||
CLAMP(y, p_min, p_max),
|
||||
CLAMP(z, p_min, p_max));
|
||||
}
|
||||
|
||||
Vector3i::operator String() const {
|
||||
return "(" + itos(x) + ", " + itos(y) + ", " + itos(z) + ")";
|
||||
}
|
||||
|
||||
@@ -173,25 +173,12 @@ void Vector4::snap(const Vector4 &p_step) {
|
||||
w = Math::snapped(w, p_step.w);
|
||||
}
|
||||
|
||||
void Vector4::snapf(real_t p_step) {
|
||||
x = Math::snapped(x, p_step);
|
||||
y = Math::snapped(y, p_step);
|
||||
z = Math::snapped(z, p_step);
|
||||
w = Math::snapped(w, p_step);
|
||||
}
|
||||
|
||||
Vector4 Vector4::snapped(const Vector4 &p_step) const {
|
||||
Vector4 v = *this;
|
||||
v.snap(p_step);
|
||||
return v;
|
||||
}
|
||||
|
||||
Vector4 Vector4::snappedf(real_t p_step) const {
|
||||
Vector4 v = *this;
|
||||
v.snapf(p_step);
|
||||
return v;
|
||||
}
|
||||
|
||||
Vector4 Vector4::inverse() const {
|
||||
return Vector4(1.0f / x, 1.0f / y, 1.0f / z, 1.0f / w);
|
||||
}
|
||||
@@ -204,14 +191,6 @@ Vector4 Vector4::clamp(const Vector4 &p_min, const Vector4 &p_max) const {
|
||||
CLAMP(w, p_min.w, p_max.w));
|
||||
}
|
||||
|
||||
Vector4 Vector4::clampf(real_t p_min, real_t p_max) const {
|
||||
return Vector4(
|
||||
CLAMP(x, p_min, p_max),
|
||||
CLAMP(y, p_min, p_max),
|
||||
CLAMP(z, p_min, p_max),
|
||||
CLAMP(w, p_min, p_max));
|
||||
}
|
||||
|
||||
Vector4::operator String() const {
|
||||
return "(" + String::num_real(x, false) + ", " + String::num_real(y, false) + ", " + String::num_real(z, false) + ", " + String::num_real(w, false) + ")";
|
||||
}
|
||||
|
||||
@@ -35,22 +35,6 @@
|
||||
|
||||
namespace godot {
|
||||
|
||||
Vector4i Vector4i::snapped(const Vector4i &p_step) const {
|
||||
return Vector4i(
|
||||
Math::snapped(x, p_step.x),
|
||||
Math::snapped(y, p_step.y),
|
||||
Math::snapped(z, p_step.z),
|
||||
Math::snapped(w, p_step.w));
|
||||
}
|
||||
|
||||
Vector4i Vector4i::snappedi(int32_t p_step) const {
|
||||
return Vector4i(
|
||||
Math::snapped(x, p_step),
|
||||
Math::snapped(y, p_step),
|
||||
Math::snapped(z, p_step),
|
||||
Math::snapped(w, p_step));
|
||||
}
|
||||
|
||||
Vector4i::Axis Vector4i::min_axis_index() const {
|
||||
uint32_t min_index = 0;
|
||||
int32_t min_value = x;
|
||||
@@ -83,14 +67,6 @@ Vector4i Vector4i::clamp(const Vector4i &p_min, const Vector4i &p_max) const {
|
||||
CLAMP(w, p_min.w, p_max.w));
|
||||
}
|
||||
|
||||
Vector4i Vector4i::clampi(int32_t p_min, int32_t p_max) const {
|
||||
return Vector4i(
|
||||
CLAMP(x, p_min, p_max),
|
||||
CLAMP(y, p_min, p_max),
|
||||
CLAMP(z, p_min, p_max),
|
||||
CLAMP(w, p_min, p_max));
|
||||
}
|
||||
|
||||
Vector4i::operator String() const {
|
||||
return "(" + itos(x) + ", " + itos(y) + ", " + itos(z) + ", " + itos(w) + ")";
|
||||
}
|
||||
|
||||
@@ -14,10 +14,6 @@ env = SConscript("../SConstruct")
|
||||
env.Append(CPPPATH=["src/"])
|
||||
sources = Glob("src/*.cpp")
|
||||
|
||||
if env["target"] in ["editor", "template_debug"]:
|
||||
doc_data = env.GodotCPPDocData("src/gen/doc_data.gen.cpp", source=Glob("doc_classes/*.xml"))
|
||||
sources.append(doc_data)
|
||||
|
||||
if env["platform"] == "macos":
|
||||
library = env.SharedLibrary(
|
||||
"project/bin/libgdexample.{}.{}.framework/libgdexample.{}.{}".format(
|
||||
@@ -42,4 +38,5 @@ else:
|
||||
source=sources,
|
||||
)
|
||||
|
||||
env.NoCache(library)
|
||||
Default(library)
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
{
|
||||
"enabled_classes": [
|
||||
"Control",
|
||||
"InputEventKey",
|
||||
"Label",
|
||||
"MultiplayerAPI",
|
||||
"MultiplayerPeer",
|
||||
"OS",
|
||||
"TileMap",
|
||||
"InputEventKey"
|
||||
"TileSet",
|
||||
"Viewport"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<class name="Example" inherits="Control" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/godotengine/godot/master/doc/class.xsd">
|
||||
<brief_description>
|
||||
A test control defined in GDExtension.
|
||||
</brief_description>
|
||||
<description>
|
||||
A control used for the automated GDExtension tests.
|
||||
</description>
|
||||
<tutorials>
|
||||
</tutorials>
|
||||
<methods>
|
||||
<method name="simple_func">
|
||||
<return type="void" />
|
||||
<description>
|
||||
Tests a simple function call.
|
||||
</description>
|
||||
</method>
|
||||
</methods>
|
||||
<members>
|
||||
</members>
|
||||
<signals>
|
||||
</signals>
|
||||
<constants>
|
||||
</constants>
|
||||
</class>
|
||||
@@ -1,5 +0,0 @@
|
||||
extends Example
|
||||
|
||||
func _do_something_virtual(p_name, p_value):
|
||||
custom_signal.emit(p_name, p_value)
|
||||
return "Implemented"
|
||||
@@ -9,15 +9,12 @@ class TestClass:
|
||||
func _ready():
|
||||
var example: Example = $Example
|
||||
|
||||
# Timing of set instance binding.
|
||||
assert_equal(example.is_object_binding_set_by_parent_constructor(), true)
|
||||
|
||||
# Signal.
|
||||
example.emit_custom_signal("Button", 42)
|
||||
assert_equal(custom_signal_emitted, ["Button", 42])
|
||||
|
||||
# To string.
|
||||
assert_equal(example.to_string(),'[ GDExtension::Example <--> Instance ID:%s ]' % example.get_instance_id())
|
||||
assert_equal(example.to_string(),'Example:[ GDExtension::Example <--> Instance ID:%s ]' % example.get_instance_id())
|
||||
# It appears there's a bug with instance ids :-(
|
||||
#assert_equal($Example/ExampleMin.to_string(), 'ExampleMin:[Wrapped:%s]' % $Example/ExampleMin.get_instance_id())
|
||||
|
||||
@@ -105,7 +102,6 @@ func _ready():
|
||||
# mp_callable() with void method.
|
||||
var mp_callable: Callable = example.test_callable_mp()
|
||||
assert_equal(mp_callable.is_valid(), true)
|
||||
assert_equal(mp_callable.get_argument_count(), 3)
|
||||
mp_callable.call(example, "void", 36)
|
||||
assert_equal(custom_signal_emitted, ["unbound_method1: Example - void", 36])
|
||||
|
||||
@@ -121,17 +117,14 @@ func _ready():
|
||||
|
||||
# mp_callable() with return value.
|
||||
var mp_callable_ret: Callable = example.test_callable_mp_ret()
|
||||
assert_equal(mp_callable_ret.get_argument_count(), 3)
|
||||
assert_equal(mp_callable_ret.call(example, "test", 77), "unbound_method2: Example - test - 77")
|
||||
|
||||
# mp_callable() with const method and return value.
|
||||
var mp_callable_retc: Callable = example.test_callable_mp_retc()
|
||||
assert_equal(mp_callable_retc.get_argument_count(), 3)
|
||||
assert_equal(mp_callable_retc.call(example, "const", 101), "unbound_method3: Example - const - 101")
|
||||
|
||||
# mp_callable_static() with void method.
|
||||
var mp_callable_static: Callable = example.test_callable_mp_static()
|
||||
assert_equal(mp_callable_static.get_argument_count(), 3)
|
||||
mp_callable_static.call(example, "static", 83)
|
||||
assert_equal(custom_signal_emitted, ["unbound_static_method1: Example - static", 83])
|
||||
|
||||
@@ -147,7 +140,6 @@ func _ready():
|
||||
|
||||
# mp_callable_static() with return value.
|
||||
var mp_callable_static_ret: Callable = example.test_callable_mp_static_ret()
|
||||
assert_equal(mp_callable_static_ret.get_argument_count(), 3)
|
||||
assert_equal(mp_callable_static_ret.call(example, "static-ret", 84), "unbound_static_method2: Example - static-ret - 84")
|
||||
|
||||
# CallableCustom.
|
||||
@@ -158,7 +150,6 @@ func _ready():
|
||||
assert_equal(custom_callable.hash(), 27);
|
||||
assert_equal(custom_callable.get_object(), null);
|
||||
assert_equal(custom_callable.get_method(), "");
|
||||
assert_equal(custom_callable.get_argument_count(), 2)
|
||||
assert_equal(str(custom_callable), "<MyCallableCustom>");
|
||||
|
||||
# PackedArray iterators
|
||||
@@ -255,10 +246,6 @@ func _ready():
|
||||
assert_equal(new_example_ref.was_post_initialized(), true)
|
||||
assert_equal(example.test_post_initialize(), true)
|
||||
|
||||
# Test a virtual method defined in GDExtension and implemented in script.
|
||||
assert_equal(example.test_virtual_implemented_in_script("Virtual", 939), "Implemented")
|
||||
assert_equal(custom_signal_emitted, ["Virtual", 939])
|
||||
|
||||
# Test that we can access an engine singleton.
|
||||
assert_equal(example.test_use_engine_singleton(), OS.get_name())
|
||||
|
||||
@@ -270,6 +257,12 @@ func _ready():
|
||||
assert_equal(example_child.get_value1(), 11)
|
||||
assert_equal(example_child.get_value2(), 22)
|
||||
|
||||
# Test that the extension's library path is absolute and valid.
|
||||
var library_path = Example.test_library_path()
|
||||
assert_equal(library_path.begins_with("res://"), false)
|
||||
assert_equal(library_path, ProjectSettings.globalize_path(library_path))
|
||||
assert_equal(FileAccess.file_exists(library_path), true)
|
||||
|
||||
exit_with_status()
|
||||
|
||||
func _on_Example_custom_signal(signal_name, value):
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://dmx2xuigcpvt4"]
|
||||
[gd_scene load_steps=2 format=3 uid="uid://dmx2xuigcpvt4"]
|
||||
|
||||
[ext_resource type="Script" path="res://main.gd" id="1_qesh5"]
|
||||
[ext_resource type="Script" path="res://example.gd" id="2_jju25"]
|
||||
|
||||
[node name="Node" type="Node"]
|
||||
script = ExtResource("1_qesh5")
|
||||
|
||||
[node name="Example" type="Example" parent="."]
|
||||
script = ExtResource("2_jju25")
|
||||
|
||||
[node name="ExampleMin" type="ExampleMin" parent="Example"]
|
||||
layout_mode = 0
|
||||
|
||||
@@ -12,7 +12,7 @@ config_version=5
|
||||
|
||||
config/name="GDExtension Test Project"
|
||||
run/main_scene="res://main.tscn"
|
||||
config/features=PackedStringArray("4.3")
|
||||
config/features=PackedStringArray("4.2")
|
||||
config/icon="res://icon.png"
|
||||
|
||||
[native_extensions]
|
||||
|
||||
@@ -50,11 +50,6 @@ public:
|
||||
return ObjectID();
|
||||
}
|
||||
|
||||
virtual int get_argument_count(bool &r_is_valid) const {
|
||||
r_is_valid = true;
|
||||
return 2;
|
||||
}
|
||||
|
||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const {
|
||||
r_return_value = "Hi";
|
||||
r_call_error.error = GDEXTENSION_CALL_OK;
|
||||
@@ -193,8 +188,6 @@ void Example::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("return_extended_ref"), &Example::return_extended_ref);
|
||||
ClassDB::bind_method(D_METHOD("extended_ref_checks", "ref"), &Example::extended_ref_checks);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("is_object_binding_set_by_parent_constructor"), &Example::is_object_binding_set_by_parent_constructor);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("test_array"), &Example::test_array);
|
||||
ClassDB::bind_method(D_METHOD("test_tarray_arg", "array"), &Example::test_tarray_arg);
|
||||
ClassDB::bind_method(D_METHOD("test_tarray"), &Example::test_tarray);
|
||||
@@ -204,6 +197,7 @@ void Example::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("test_str_utility"), &Example::test_str_utility);
|
||||
ClassDB::bind_method(D_METHOD("test_string_is_forty_two"), &Example::test_string_is_forty_two);
|
||||
ClassDB::bind_method(D_METHOD("test_string_resize"), &Example::test_string_resize);
|
||||
ClassDB::bind_method(D_METHOD("test_typed_array_of_packed"), &Example::test_typed_array_of_packed);
|
||||
ClassDB::bind_method(D_METHOD("test_vector_ops"), &Example::test_vector_ops);
|
||||
ClassDB::bind_method(D_METHOD("test_vector_init_list"), &Example::test_vector_init_list);
|
||||
|
||||
@@ -239,15 +233,13 @@ void Example::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("callable_bind"), &Example::callable_bind);
|
||||
ClassDB::bind_method(D_METHOD("test_post_initialize"), &Example::test_post_initialize);
|
||||
|
||||
GDVIRTUAL_BIND(_do_something_virtual, "name", "value");
|
||||
ClassDB::bind_method(D_METHOD("test_virtual_implemented_in_script"), &Example::test_virtual_implemented_in_script);
|
||||
GDVIRTUAL_BIND(_do_something_virtual_with_control, "control");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("test_use_engine_singleton"), &Example::test_use_engine_singleton);
|
||||
|
||||
ClassDB::bind_static_method("Example", D_METHOD("test_static", "a", "b"), &Example::test_static);
|
||||
ClassDB::bind_static_method("Example", D_METHOD("test_static2"), &Example::test_static2);
|
||||
|
||||
ClassDB::bind_static_method("Example", D_METHOD("test_library_path"), &Example::test_library_path);
|
||||
|
||||
{
|
||||
MethodInfo mi;
|
||||
mi.arguments.push_back(PropertyInfo(Variant::STRING, "some_argument"));
|
||||
@@ -293,17 +285,7 @@ void Example::_bind_methods() {
|
||||
BIND_ENUM_CONSTANT(OUTSIDE_OF_CLASS);
|
||||
}
|
||||
|
||||
bool Example::has_object_instance_binding() const {
|
||||
return internal::gdextension_interface_object_get_instance_binding(_owner, internal::token, nullptr);
|
||||
}
|
||||
|
||||
Example::Example() :
|
||||
object_instance_binding_set_by_parent_constructor(has_object_instance_binding()) {
|
||||
// Test conversion, to ensure users can use all parent class functions at this time.
|
||||
// It would crash if instance binding still not be initialized.
|
||||
Variant v = Variant(this);
|
||||
Object *o = (Object *)v;
|
||||
|
||||
Example::Example() {
|
||||
//UtilityFunctions::print("Constructor.");
|
||||
}
|
||||
|
||||
@@ -383,10 +365,6 @@ void Example::emit_custom_signal(const String &name, int value) {
|
||||
emit_signal("custom_signal", name, value);
|
||||
}
|
||||
|
||||
bool Example::is_object_binding_set_by_parent_constructor() const {
|
||||
return object_instance_binding_set_by_parent_constructor;
|
||||
}
|
||||
|
||||
Array Example::test_array() const {
|
||||
Array arr;
|
||||
|
||||
@@ -424,6 +402,19 @@ String Example::test_string_resize(String p_string) const {
|
||||
return p_string;
|
||||
}
|
||||
|
||||
TypedArray<PackedInt32Array> Example::test_typed_array_of_packed() const {
|
||||
TypedArray<PackedInt32Array> arr;
|
||||
PackedInt32Array packed_arr1;
|
||||
packed_arr1.push_back(1);
|
||||
packed_arr1.push_back(2);
|
||||
arr.push_back(packed_arr1);
|
||||
PackedInt32Array packed_arr2;
|
||||
packed_arr2.push_back(3);
|
||||
packed_arr2.push_back(4);
|
||||
arr.push_back(packed_arr2);
|
||||
return arr;
|
||||
}
|
||||
|
||||
int Example::test_vector_ops() const {
|
||||
PackedInt32Array arr;
|
||||
arr.push_back(10);
|
||||
@@ -683,34 +674,12 @@ void ExampleChild::_notification(int p_what) {
|
||||
}
|
||||
}
|
||||
|
||||
String Example::test_virtual_implemented_in_script(const String &p_name, int p_value) {
|
||||
String ret;
|
||||
if (GDVIRTUAL_CALL(_do_something_virtual, p_name, p_value, ret)) {
|
||||
return ret;
|
||||
}
|
||||
return "Unimplemented";
|
||||
}
|
||||
|
||||
String Example::test_use_engine_singleton() const {
|
||||
return OS::get_singleton()->get_name();
|
||||
}
|
||||
|
||||
void ExampleRuntime::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_prop_value", "value"), &ExampleRuntime::set_prop_value);
|
||||
ClassDB::bind_method(D_METHOD("get_prop_value"), &ExampleRuntime::get_prop_value);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "prop_value"), "set_prop_value", "get_prop_value");
|
||||
}
|
||||
|
||||
void ExampleRuntime::set_prop_value(int p_prop_value) {
|
||||
prop_value = p_prop_value;
|
||||
}
|
||||
|
||||
int ExampleRuntime::get_prop_value() const {
|
||||
return prop_value;
|
||||
}
|
||||
|
||||
ExampleRuntime::ExampleRuntime() {
|
||||
}
|
||||
|
||||
ExampleRuntime::~ExampleRuntime() {
|
||||
String Example::test_library_path() {
|
||||
String library_path;
|
||||
internal::gdextension_interface_get_library_path(internal::library, library_path._native_ptr());
|
||||
return library_path;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#include <godot_cpp/variant/variant.hpp>
|
||||
|
||||
#include <godot_cpp/core/binder_common.hpp>
|
||||
#include <godot_cpp/core/gdvirtual.gen.inc>
|
||||
|
||||
using namespace godot;
|
||||
|
||||
@@ -82,9 +81,6 @@ private:
|
||||
Vector2 dprop[3];
|
||||
int last_rpc_arg = 0;
|
||||
|
||||
const bool object_instance_binding_set_by_parent_constructor;
|
||||
bool has_object_instance_binding() const;
|
||||
|
||||
public:
|
||||
// Constants.
|
||||
enum Constants {
|
||||
@@ -123,8 +119,6 @@ public:
|
||||
void emit_custom_signal(const String &name, int value);
|
||||
int def_args(int p_a = 100, int p_b = 200);
|
||||
|
||||
bool is_object_binding_set_by_parent_constructor() const;
|
||||
|
||||
Array test_array() const;
|
||||
int test_tarray_arg(const TypedArray<int64_t> &p_array);
|
||||
TypedArray<Vector2> test_tarray() const;
|
||||
@@ -134,6 +128,7 @@ public:
|
||||
String test_str_utility() const;
|
||||
bool test_string_is_forty_two(const String &p_str) const;
|
||||
String test_string_resize(String p_original) const;
|
||||
TypedArray<PackedInt32Array> test_typed_array_of_packed() const;
|
||||
int test_vector_ops() const;
|
||||
int test_vector_init_list() const;
|
||||
|
||||
@@ -189,11 +184,9 @@ public:
|
||||
virtual bool _has_point(const Vector2 &point) const override;
|
||||
virtual void _input(const Ref<InputEvent> &event) override;
|
||||
|
||||
GDVIRTUAL2R(String, _do_something_virtual, String, int);
|
||||
String test_virtual_implemented_in_script(const String &p_name, int p_value);
|
||||
GDVIRTUAL1(_do_something_virtual_with_control, Control *);
|
||||
|
||||
String test_use_engine_singleton() const;
|
||||
|
||||
static String test_library_path();
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(Example::Constants);
|
||||
@@ -254,20 +247,4 @@ protected:
|
||||
void _notification(int p_what);
|
||||
};
|
||||
|
||||
class ExampleRuntime : public Node {
|
||||
GDCLASS(ExampleRuntime, Node);
|
||||
|
||||
int prop_value = 12;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
void set_prop_value(int p_prop_value);
|
||||
int get_prop_value() const;
|
||||
|
||||
ExampleRuntime();
|
||||
~ExampleRuntime();
|
||||
};
|
||||
|
||||
#endif // EXAMPLE_CLASS_H
|
||||
|
||||
@@ -29,7 +29,6 @@ void initialize_example_module(ModuleInitializationLevel p_level) {
|
||||
GDREGISTER_CLASS(ExampleConcrete);
|
||||
GDREGISTER_CLASS(ExampleBase);
|
||||
GDREGISTER_CLASS(ExampleChild);
|
||||
GDREGISTER_RUNTIME_CLASS(ExampleRuntime);
|
||||
}
|
||||
|
||||
void uninitialize_example_module(ModuleInitializationLevel p_level) {
|
||||
|
||||
@@ -120,4 +120,9 @@ def generate(env):
|
||||
|
||||
env.Append(CPPDEFINES=["ANDROID_ENABLED", "UNIX_ENABLED"])
|
||||
|
||||
# Refer to https://github.com/godotengine/godot/blob/master/platform/android/detect.py
|
||||
# LTO benefits for Android (size, performance) haven't been clearly established yet.
|
||||
if env["lto"] == "auto":
|
||||
env["lto"] = "none"
|
||||
|
||||
common_compiler_flags.generate(env)
|
||||
|
||||
@@ -22,6 +22,10 @@ def exists(env):
|
||||
|
||||
|
||||
def generate(env):
|
||||
assert env["lto"] in ["thin", "full", "none"], "Unrecognized lto: {}".format(env["lto"])
|
||||
if env["lto"] != "none":
|
||||
print("Using LTO: " + env["lto"])
|
||||
|
||||
# Require C++17
|
||||
if env.get("is_msvc", False):
|
||||
env.Append(CXXFLAGS=["/std:c++17"])
|
||||
@@ -64,6 +68,22 @@ def generate(env):
|
||||
env.Append(LINKFLAGS=["/OPT:REF"])
|
||||
elif env["optimize"] == "debug" or env["optimize"] == "none":
|
||||
env.Append(CCFLAGS=["/Od"])
|
||||
|
||||
if env["lto"] == "thin":
|
||||
if not env["use_llvm"]:
|
||||
print("ThinLTO is only compatible with LLVM, use `use_llvm=yes` or `lto=full`.")
|
||||
env.Exit(255)
|
||||
|
||||
env.Append(CCFLAGS=["-flto=thin"])
|
||||
env.Append(LINKFLAGS=["-flto=thin"])
|
||||
elif env["lto"] == "full":
|
||||
if env["use_llvm"]:
|
||||
env.Append(CCFLAGS=["-flto"])
|
||||
env.Append(LINKFLAGS=["-flto"])
|
||||
else:
|
||||
env.AppendUnique(CCFLAGS=["/GL"])
|
||||
env.AppendUnique(ARFLAGS=["/LTCG"])
|
||||
env.AppendUnique(LINKFLAGS=["/LTCG"])
|
||||
else:
|
||||
if env["debug_symbols"]:
|
||||
# Adding dwarf-4 explicitly makes stacktraces work with clang builds,
|
||||
@@ -74,7 +94,7 @@ def generate(env):
|
||||
else:
|
||||
env.Append(CCFLAGS=["-g2"])
|
||||
else:
|
||||
if using_clang(env) and not is_vanilla_clang(env):
|
||||
if using_clang(env) and not is_vanilla_clang(env) and not env["use_mingw"]:
|
||||
# Apple Clang, its linker doesn't like -s.
|
||||
env.Append(LINKFLAGS=["-Wl,-S", "-Wl,-x", "-Wl,-dead_strip"])
|
||||
else:
|
||||
@@ -91,3 +111,13 @@ def generate(env):
|
||||
env.Append(CCFLAGS=["-Og"])
|
||||
elif env["optimize"] == "none":
|
||||
env.Append(CCFLAGS=["-O0"])
|
||||
|
||||
if env["lto"] == "thin":
|
||||
if (env["platform"] == "windows" or env["platform"] == "linux") and not env["use_llvm"]:
|
||||
print("ThinLTO is only compatible with LLVM, use `use_llvm=yes` or `lto=full`.")
|
||||
env.Exit(255)
|
||||
env.Append(CCFLAGS=["-flto=thin"])
|
||||
env.Append(LINKFLAGS=["-flto=thin"])
|
||||
elif env["lto"] == "full":
|
||||
env.Append(CCFLAGS=["-flto"])
|
||||
env.Append(LINKFLAGS=["-flto"])
|
||||
|
||||
@@ -10,7 +10,8 @@ from SCons.Tool import Tool
|
||||
from SCons.Variables import BoolVariable, EnumVariable, PathVariable
|
||||
from SCons.Variables.BoolVariable import _text2bool
|
||||
|
||||
from binding_generator import scons_emit_files, scons_generate_bindings
|
||||
from binding_generator import _generate_bindings, _get_file_list, get_file_list
|
||||
from build_profile import generate_trimmed_api
|
||||
|
||||
|
||||
def add_sources(sources, dir, extension):
|
||||
@@ -129,6 +130,37 @@ def no_verbose(env):
|
||||
env.Append(GENCOMSTR=[generated_file_message])
|
||||
|
||||
|
||||
def scons_emit_files(target, source, env):
|
||||
profile_filepath = env.get("build_profile", "")
|
||||
if profile_filepath:
|
||||
profile_filepath = normalize_path(profile_filepath, env)
|
||||
|
||||
# Always clean all files
|
||||
env.Clean(target, [env.File(f) for f in get_file_list(str(source[0]), target[0].abspath, True, True)])
|
||||
|
||||
api = generate_trimmed_api(str(source[0]), profile_filepath)
|
||||
files = [env.File(f) for f in _get_file_list(api, target[0].abspath, True, True)]
|
||||
env["godot_cpp_gen_dir"] = target[0].abspath
|
||||
return files, source
|
||||
|
||||
|
||||
def scons_generate_bindings(target, source, env):
|
||||
profile_filepath = env.get("build_profile", "")
|
||||
if profile_filepath:
|
||||
profile_filepath = normalize_path(profile_filepath, env)
|
||||
|
||||
api = generate_trimmed_api(str(source[0]), profile_filepath)
|
||||
|
||||
_generate_bindings(
|
||||
api,
|
||||
env["generate_template_get_node"],
|
||||
"32" if "32" in env["arch"] else "64",
|
||||
env["precision"],
|
||||
env["godot_cpp_gen_dir"],
|
||||
)
|
||||
return None
|
||||
|
||||
|
||||
platforms = ["linux", "macos", "windows", "android", "ios", "web"]
|
||||
|
||||
# CPU architecture options.
|
||||
@@ -326,6 +358,14 @@ def options(opts, env):
|
||||
("none", "custom", "debug", "speed", "speed_trace", "size"),
|
||||
)
|
||||
)
|
||||
opts.Add(
|
||||
EnumVariable(
|
||||
"lto",
|
||||
"Link-time optimization",
|
||||
"none",
|
||||
("none", "auto", "thin", "full"),
|
||||
)
|
||||
)
|
||||
opts.Add(BoolVariable("debug_symbols", "Build with debugging symbols", True))
|
||||
opts.Add(BoolVariable("dev_build", "Developer build with dev-only debugging code (DEV_ENABLED)", False))
|
||||
opts.Add(BoolVariable("verbose", "Enable verbose output for the compilation", False))
|
||||
@@ -337,51 +377,6 @@ def options(opts, env):
|
||||
tool.options(opts)
|
||||
|
||||
|
||||
def make_doc_source(target, source, env):
|
||||
import zlib
|
||||
|
||||
dst = str(target[0])
|
||||
g = open(dst, "w", encoding="utf-8")
|
||||
buf = ""
|
||||
docbegin = ""
|
||||
docend = ""
|
||||
for src in source:
|
||||
src_path = str(src)
|
||||
if not src_path.endswith(".xml"):
|
||||
continue
|
||||
with open(src_path, "r", encoding="utf-8") as f:
|
||||
content = f.read()
|
||||
buf += content
|
||||
|
||||
buf = (docbegin + buf + docend).encode("utf-8")
|
||||
decomp_size = len(buf)
|
||||
|
||||
# Use maximum zlib compression level to further reduce file size
|
||||
# (at the cost of initial build times).
|
||||
buf = zlib.compress(buf, zlib.Z_BEST_COMPRESSION)
|
||||
|
||||
g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
|
||||
g.write("\n")
|
||||
g.write("#include <godot_cpp/godot.hpp>\n")
|
||||
g.write("\n")
|
||||
|
||||
g.write('static const char *_doc_data_hash = "' + str(hash(buf)) + '";\n')
|
||||
g.write("static const int _doc_data_uncompressed_size = " + str(decomp_size) + ";\n")
|
||||
g.write("static const int _doc_data_compressed_size = " + str(len(buf)) + ";\n")
|
||||
g.write("static const unsigned char _doc_data_compressed[] = {\n")
|
||||
for i in range(len(buf)):
|
||||
g.write("\t" + str(buf[i]) + ",\n")
|
||||
g.write("};\n")
|
||||
g.write("\n")
|
||||
|
||||
g.write(
|
||||
"static godot::internal::DocDataRegistration _doc_data_registration(_doc_data_hash, _doc_data_uncompressed_size, _doc_data_compressed_size, _doc_data_compressed);\n"
|
||||
)
|
||||
g.write("\n")
|
||||
|
||||
g.close()
|
||||
|
||||
|
||||
def generate(env):
|
||||
# Default num_jobs to local cpu count if not user specified.
|
||||
# SCons has a peculiarity where user-specified options won't be overridden
|
||||
@@ -513,8 +508,7 @@ def generate(env):
|
||||
# Builders
|
||||
env.Append(
|
||||
BUILDERS={
|
||||
"GodotCPPBindings": Builder(action=Action(scons_generate_bindings, "$GENCOMSTR"), emitter=scons_emit_files),
|
||||
"GodotCPPDocData": Builder(action=make_doc_source),
|
||||
"GodotCPPBindings": Builder(action=Action(scons_generate_bindings, "$GENCOMSTR"), emitter=scons_emit_files)
|
||||
}
|
||||
)
|
||||
env.AddMethod(_godot_cpp, "GodotCPP")
|
||||
@@ -552,6 +546,7 @@ def _godot_cpp(env):
|
||||
|
||||
if env["build_library"]:
|
||||
library = env.StaticLibrary(target=env.File("bin/%s" % library_name), source=sources)
|
||||
env.NoCache(library)
|
||||
default_args = [library]
|
||||
|
||||
# Add compiledb if the option is set
|
||||
|
||||
@@ -97,4 +97,9 @@ def generate(env):
|
||||
|
||||
env.Append(CPPDEFINES=["IOS_ENABLED", "UNIX_ENABLED"])
|
||||
|
||||
# Refer to https://github.com/godotengine/godot/blob/master/platform/ios/detect.py:
|
||||
# Disable by default as it makes linking in Xcode very slow.
|
||||
if env["lto"] == "auto":
|
||||
env["lto"] = "none"
|
||||
|
||||
common_compiler_flags.generate(env)
|
||||
|
||||
@@ -39,4 +39,8 @@ def generate(env):
|
||||
|
||||
env.Append(CPPDEFINES=["LINUX_ENABLED", "UNIX_ENABLED"])
|
||||
|
||||
# Refer to https://github.com/godotengine/godot/blob/master/platform/linuxbsd/detect.py
|
||||
if env["lto"] == "auto":
|
||||
env["lto"] = "full"
|
||||
|
||||
common_compiler_flags.generate(env)
|
||||
|
||||
@@ -73,4 +73,9 @@ def generate(env):
|
||||
|
||||
env.Append(CPPDEFINES=["MACOS_ENABLED", "UNIX_ENABLED"])
|
||||
|
||||
# Refer to https://github.com/godotengine/godot/blob/master/platform/macos/detect.py
|
||||
# LTO benefits for macOS (size, performance) haven't been clearly established yet.
|
||||
if env["lto"] == "auto":
|
||||
env["lto"] = "none"
|
||||
|
||||
common_compiler_flags.generate(env)
|
||||
|
||||
@@ -39,7 +39,7 @@ def generate(env):
|
||||
env.Append(LINKFLAGS=["-sUSE_PTHREADS=1"])
|
||||
|
||||
# Build as side module (shared library).
|
||||
env.Append(CPPFLAGS=["-sSIDE_MODULE=1"])
|
||||
env.Append(CCFLAGS=["-sSIDE_MODULE=1"])
|
||||
env.Append(LINKFLAGS=["-sSIDE_MODULE=1"])
|
||||
|
||||
# Force wasm longjmp mode.
|
||||
@@ -48,4 +48,8 @@ def generate(env):
|
||||
|
||||
env.Append(CPPDEFINES=["WEB_ENABLED", "UNIX_ENABLED"])
|
||||
|
||||
# Refer to https://github.com/godotengine/godot/blob/master/platform/web/detect.py
|
||||
if env["lto"] == "auto":
|
||||
env["lto"] = "full"
|
||||
|
||||
common_compiler_flags.generate(env)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
import common_compiler_flags
|
||||
@@ -72,10 +73,13 @@ def silence_msvc(env):
|
||||
|
||||
|
||||
def options(opts):
|
||||
mingw = os.getenv("MINGW_PREFIX", "")
|
||||
|
||||
opts.Add(BoolVariable("use_mingw", "Use the MinGW compiler instead of MSVC - only effective on Windows", False))
|
||||
opts.Add(BoolVariable("use_clang_cl", "Use the clang driver instead of MSVC - only effective on Windows", False))
|
||||
opts.Add(BoolVariable("use_static_cpp", "Link MinGW/MSVC C++ runtime libraries statically", True))
|
||||
opts.Add(BoolVariable("silence_msvc", "Silence MSVC's cl/link stdout bloat, redirecting errors to stderr.", True))
|
||||
opts.Add(BoolVariable("use_llvm", "Use the LLVM compiler (MVSC or MinGW depending on the use_mingw flag)", False))
|
||||
opts.Add("mingw_prefix", "MinGW prefix", mingw)
|
||||
|
||||
|
||||
def exists(env):
|
||||
@@ -86,12 +90,22 @@ def generate(env):
|
||||
if not env["use_mingw"] and msvc.exists(env):
|
||||
if env["arch"] == "x86_64":
|
||||
env["TARGET_ARCH"] = "amd64"
|
||||
elif env["arch"] == "arm64":
|
||||
env["TARGET_ARCH"] = "arm64"
|
||||
elif env["arch"] == "arm32":
|
||||
env["TARGET_ARCH"] = "arm"
|
||||
elif env["arch"] == "x86_32":
|
||||
env["TARGET_ARCH"] = "x86"
|
||||
|
||||
env["MSVC_SETUP_RUN"] = False # Need to set this to re-run the tool
|
||||
env["MSVS_VERSION"] = None
|
||||
env["MSVC_VERSION"] = None
|
||||
|
||||
env["is_msvc"] = True
|
||||
|
||||
# MSVC, linker, and archiver.
|
||||
msvc.generate(env)
|
||||
env.Tool("msvc")
|
||||
env.Tool("mslib")
|
||||
env.Tool("mslink")
|
||||
|
||||
@@ -99,7 +113,7 @@ def generate(env):
|
||||
env.Append(CCFLAGS=["/utf-8"])
|
||||
env.Append(LINKFLAGS=["/WX"])
|
||||
|
||||
if env["use_clang_cl"]:
|
||||
if env["use_llvm"]:
|
||||
env["CC"] = "clang-cl"
|
||||
env["CXX"] = "clang-cl"
|
||||
|
||||
@@ -111,7 +125,7 @@ def generate(env):
|
||||
if env["silence_msvc"] and not env.GetOption("clean"):
|
||||
silence_msvc(env)
|
||||
|
||||
elif sys.platform == "win32" or sys.platform == "msys":
|
||||
elif (sys.platform == "win32" or sys.platform == "msys") and not env["mingw_prefix"]:
|
||||
env["use_mingw"] = True
|
||||
mingw.generate(env)
|
||||
# Don't want lib prefixes
|
||||
@@ -137,12 +151,32 @@ def generate(env):
|
||||
else:
|
||||
env["use_mingw"] = True
|
||||
# Cross-compilation using MinGW
|
||||
prefix = "i686" if env["arch"] == "x86_32" else env["arch"]
|
||||
env["CXX"] = prefix + "-w64-mingw32-g++"
|
||||
env["CC"] = prefix + "-w64-mingw32-gcc"
|
||||
env["AR"] = prefix + "-w64-mingw32-ar"
|
||||
env["RANLIB"] = prefix + "-w64-mingw32-ranlib"
|
||||
env["LINK"] = prefix + "-w64-mingw32-g++"
|
||||
prefix = ""
|
||||
if env["mingw_prefix"]:
|
||||
prefix = env["mingw_prefix"] + "/bin/"
|
||||
|
||||
if env["arch"] == "x86_64":
|
||||
prefix += "x86_64"
|
||||
elif env["arch"] == "arm64":
|
||||
prefix += "aarch64"
|
||||
elif env["arch"] == "arm32":
|
||||
prefix += "armv7"
|
||||
elif env["arch"] == "x86_32":
|
||||
prefix += "i686"
|
||||
|
||||
if env["use_llvm"]:
|
||||
env["CXX"] = prefix + "-w64-mingw32-clang++"
|
||||
env["CC"] = prefix + "-w64-mingw32-clang"
|
||||
env["AR"] = prefix + "-w64-mingw32-llvm-ar"
|
||||
env["RANLIB"] = prefix + "-w64-mingw32-ranlib"
|
||||
env["LINK"] = prefix + "-w64-mingw32-clang"
|
||||
else:
|
||||
env["CXX"] = prefix + "-w64-mingw32-g++"
|
||||
env["CC"] = prefix + "-w64-mingw32-gcc"
|
||||
env["AR"] = prefix + "-w64-mingw32-gcc-ar"
|
||||
env["RANLIB"] = prefix + "-w64-mingw32-ranlib"
|
||||
env["LINK"] = prefix + "-w64-mingw32-g++"
|
||||
|
||||
# Want dll suffix
|
||||
env["SHLIBSUFFIX"] = ".dll"
|
||||
|
||||
@@ -156,7 +190,20 @@ def generate(env):
|
||||
"-static-libstdc++",
|
||||
]
|
||||
)
|
||||
if env["use_llvm"]:
|
||||
env.Append(LINKFLAGS=["-lstdc++"])
|
||||
|
||||
if sys.platform == "win32" or sys.platform == "msys":
|
||||
my_spawn.configure(env)
|
||||
|
||||
env.Append(CPPDEFINES=["WINDOWS_ENABLED"])
|
||||
|
||||
# Refer to https://github.com/godotengine/godot/blob/master/platform/windows/detect.py
|
||||
if env["lto"] == "auto":
|
||||
if env.get("is_msvc", False):
|
||||
# No LTO by default for MSVC, doesn't help.
|
||||
env["lto"] = "none"
|
||||
else: # Release
|
||||
env["lto"] = "full"
|
||||
|
||||
common_compiler_flags.generate(env)
|
||||
|
||||
Reference in New Issue
Block a user