mirror of
https://github.com/godotengine/godot-cpp.git
synced 2026-01-03 18:09:13 +03:00
Compare commits
3 Commits
godot-4.2-
...
godot-4.0.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a9118cb0d | ||
|
|
7fb46e9ea1 | ||
|
|
4d3afc0ad0 |
71
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
71
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -1,71 +0,0 @@
|
|||||||
name: Bug report
|
|
||||||
description: Report a bug in the godot-cpp GDExtension/GDNative integration
|
|
||||||
body:
|
|
||||||
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
- When reporting bugs, you'll make our life simpler (and the fix will come sooner) if you follow the guidelines in this template.
|
|
||||||
- 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/stable/about/release_policy.html).
|
|
||||||
|
|
||||||
- type: input
|
|
||||||
attributes:
|
|
||||||
label: Godot version
|
|
||||||
description: >
|
|
||||||
Specify the Git commit hash if using a development or non-official build.
|
|
||||||
If you use a custom build, please test if your issue is reproducible in official builds too.
|
|
||||||
placeholder: 3.3.stable, 4.0.dev (3041becc6)
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: input
|
|
||||||
attributes:
|
|
||||||
label: godot-cpp version
|
|
||||||
description: >
|
|
||||||
Specify the Git commit hash if using a development build.
|
|
||||||
placeholder: 3.3.stable, 4.0.dev (3041becc6)
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: input
|
|
||||||
attributes:
|
|
||||||
label: System information
|
|
||||||
description: |
|
|
||||||
- Specify the OS version, and when relevant hardware information.
|
|
||||||
- For issues that are likely OS-specific and/or graphics-related, please specify the CPU model and architecture.
|
|
||||||
- **Bug reports not including the required information may be closed at the maintainers' discretion.** If in doubt, always include all the requested information; it's better to include too much information than not enough information.
|
|
||||||
placeholder: Windows 10, Intel Core i5-7200U
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Issue description
|
|
||||||
description: |
|
|
||||||
Describe your issue briefly. What doesn't work, and how do you expect it to work instead?
|
|
||||||
You can include images or videos with drag and drop, and format code blocks or logs with <code>```</code> tags.
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Steps to reproduce
|
|
||||||
description: |
|
|
||||||
List of steps or sample code that reproduces the issue. Having reproducible issues is a prerequisite for contributors to be able to solve them.
|
|
||||||
If you include a minimal reproduction project below, you can detail how to use it here.
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Minimal reproduction project
|
|
||||||
description: |
|
|
||||||
- A small Godot project which reproduces the issue, with no unnecessary files included. Be sure to not include the `.godot` folder in the archive (but keep `project.godot`).
|
|
||||||
- Required, unless the reproduction steps are trivial and don't require any project files to be followed. In this case, write "N/A" in the field.
|
|
||||||
- Drag and drop a ZIP archive to upload it. **Do not select another field until the project is done uploading.**
|
|
||||||
- **If you've been asked by a maintainer to upload a minimal reproduction project, you *must* do so within 7 days.** Otherwise, your bug report will be closed as it'll be considered too difficult to diagnose.
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
14
.github/ISSUE_TEMPLATE/config.yml
vendored
14
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,14 +0,0 @@
|
|||||||
blank_issues_enabled: false
|
|
||||||
|
|
||||||
contact_links:
|
|
||||||
- name: Godot proposals
|
|
||||||
url: https://github.com/godotengine/godot-proposals
|
|
||||||
about: Please submit feature proposals on the Godot proposals repository, not here.
|
|
||||||
|
|
||||||
- name: Godot documentation repository
|
|
||||||
url: https://github.com/godotengine/godot-docs
|
|
||||||
about: Please report issues with documentation on the Godot documentation repository, not here.
|
|
||||||
|
|
||||||
- name: Godot community channels
|
|
||||||
url: https://godotengine.org/community
|
|
||||||
about: Please ask for technical support on one of the other community channels, not here.
|
|
||||||
80
.github/workflows/ci.yml
vendored
80
.github/workflows/ci.yml
vendored
@@ -22,7 +22,6 @@ jobs:
|
|||||||
platform: linux
|
platform: linux
|
||||||
artifact-name: godot-cpp-linux-glibc2.27-x86_64-release
|
artifact-name: godot-cpp-linux-glibc2.27-x86_64-release
|
||||||
artifact-path: bin/libgodot-cpp.linux.template_release.x86_64.a
|
artifact-path: bin/libgodot-cpp.linux.template_release.x86_64.a
|
||||||
run-tests: true
|
|
||||||
cache-name: linux-x86_64
|
cache-name: linux-x86_64
|
||||||
|
|
||||||
- name: 🐧 Linux (GCC, Double Precision)
|
- name: 🐧 Linux (GCC, Double Precision)
|
||||||
@@ -31,7 +30,6 @@ jobs:
|
|||||||
artifact-name: godot-cpp-linux-glibc2.27-x86_64-double-release
|
artifact-name: godot-cpp-linux-glibc2.27-x86_64-double-release
|
||||||
artifact-path: bin/libgodot-cpp.linux.template_release.double.x86_64.a
|
artifact-path: bin/libgodot-cpp.linux.template_release.double.x86_64.a
|
||||||
flags: precision=double
|
flags: precision=double
|
||||||
run-tests: false
|
|
||||||
cache-name: linux-x86_64-f64
|
cache-name: linux-x86_64-f64
|
||||||
|
|
||||||
- name: 🏁 Windows (x86_64, MSVC)
|
- name: 🏁 Windows (x86_64, MSVC)
|
||||||
@@ -39,7 +37,6 @@ jobs:
|
|||||||
platform: windows
|
platform: windows
|
||||||
artifact-name: godot-cpp-windows-msvc2019-x86_64-release
|
artifact-name: godot-cpp-windows-msvc2019-x86_64-release
|
||||||
artifact-path: bin/libgodot-cpp.windows.template_release.x86_64.lib
|
artifact-path: bin/libgodot-cpp.windows.template_release.x86_64.lib
|
||||||
run-tests: false
|
|
||||||
cache-name: windows-x86_64-msvc
|
cache-name: windows-x86_64-msvc
|
||||||
|
|
||||||
- name: 🏁 Windows (x86_64, MinGW)
|
- name: 🏁 Windows (x86_64, MinGW)
|
||||||
@@ -48,7 +45,6 @@ jobs:
|
|||||||
artifact-name: godot-cpp-linux-mingw-x86_64-release
|
artifact-name: godot-cpp-linux-mingw-x86_64-release
|
||||||
artifact-path: bin/libgodot-cpp.windows.template_release.x86_64.a
|
artifact-path: bin/libgodot-cpp.windows.template_release.x86_64.a
|
||||||
flags: use_mingw=yes
|
flags: use_mingw=yes
|
||||||
run-tests: false
|
|
||||||
cache-name: windows-x86_64-mingw
|
cache-name: windows-x86_64-mingw
|
||||||
|
|
||||||
- name: 🍎 macOS (universal)
|
- name: 🍎 macOS (universal)
|
||||||
@@ -57,7 +53,6 @@ jobs:
|
|||||||
artifact-name: godot-cpp-macos-universal-release
|
artifact-name: godot-cpp-macos-universal-release
|
||||||
artifact-path: bin/libgodot-cpp.macos.template_release.universal.a
|
artifact-path: bin/libgodot-cpp.macos.template_release.universal.a
|
||||||
flags: arch=universal
|
flags: arch=universal
|
||||||
run-tests: false
|
|
||||||
cache-name: macos-universal
|
cache-name: macos-universal
|
||||||
|
|
||||||
- name: 🤖 Android (arm64)
|
- name: 🤖 Android (arm64)
|
||||||
@@ -65,8 +60,7 @@ jobs:
|
|||||||
platform: android
|
platform: android
|
||||||
artifact-name: godot-cpp-android-arm64-release
|
artifact-name: godot-cpp-android-arm64-release
|
||||||
artifact-path: bin/libgodot-cpp.android.template_release.arm64.a
|
artifact-path: bin/libgodot-cpp.android.template_release.arm64.a
|
||||||
flags: arch=arm64
|
flags: ANDROID_NDK_ROOT=$ANDROID_NDK_LATEST_HOME arch=arm64
|
||||||
run-tests: false
|
|
||||||
cache-name: android-arm64
|
cache-name: android-arm64
|
||||||
|
|
||||||
- name: 🍏 iOS (arm64)
|
- name: 🍏 iOS (arm64)
|
||||||
@@ -75,25 +69,14 @@ jobs:
|
|||||||
artifact-name: godot-cpp-ios-arm64-release
|
artifact-name: godot-cpp-ios-arm64-release
|
||||||
artifact-path: bin/libgodot-cpp.ios.template_release.arm64.a
|
artifact-path: bin/libgodot-cpp.ios.template_release.arm64.a
|
||||||
flags: arch=arm64
|
flags: arch=arm64
|
||||||
run-tests: false
|
|
||||||
cache-name: ios-arm64
|
cache-name: ios-arm64
|
||||||
|
|
||||||
- name: 🌐 Web (wasm32)
|
|
||||||
os: ubuntu-20.04
|
|
||||||
platform: web
|
|
||||||
artifact-name: godot-cpp-web-wasm32-release
|
|
||||||
artifact-path: bin/libgodot-cpp.web.template_release.wasm32.a
|
|
||||||
run-tests: false
|
|
||||||
cache-name: web-wasm32
|
|
||||||
|
|
||||||
env:
|
env:
|
||||||
SCONS_CACHE: ${{ github.workspace }}/.scons-cache/
|
SCONS_CACHE: ${{ github.workspace }}/.scons-cache/
|
||||||
EM_VERSION: 3.1.39
|
|
||||||
EM_CACHE_FOLDER: "emsdk-cache"
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
@@ -108,30 +91,20 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
python-version: '3.x'
|
python-version: '3.x'
|
||||||
|
|
||||||
- name: Android dependencies
|
- name: Linux dependencies
|
||||||
if: ${{ matrix.platform == 'android' }}
|
if: ${{ matrix.platform == 'linux' }}
|
||||||
uses: nttld/setup-ndk@v1
|
run: |
|
||||||
with:
|
sudo apt-get update -qq
|
||||||
ndk-version: r23c
|
sudo apt-get install -qqq build-essential pkg-config
|
||||||
link-to-sdk: true
|
|
||||||
|
|
||||||
- name: Web dependencies
|
|
||||||
if: ${{ matrix.platform == 'web' }}
|
|
||||||
uses: mymindstorm/setup-emsdk@v13
|
|
||||||
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
|
- name: Install scons
|
||||||
run: |
|
run: |
|
||||||
python -m pip install scons==4.0.0
|
python -m pip install scons==4.0.0
|
||||||
|
|
||||||
|
- name: Setup MinGW for Windows/MinGW build
|
||||||
|
if: ${{ matrix.platform == 'windows' && matrix.flags == 'use_mingw=yes' }}
|
||||||
|
uses: egor-tensin/setup-mingw@v2
|
||||||
|
|
||||||
- name: Generate godot-cpp sources only
|
- name: Generate godot-cpp sources only
|
||||||
run: |
|
run: |
|
||||||
scons platform=${{ matrix.platform }} build_library=no ${{ matrix.flags }}
|
scons platform=${{ matrix.platform }} build_library=no ${{ matrix.flags }}
|
||||||
@@ -151,31 +124,6 @@ jobs:
|
|||||||
cd test
|
cd test
|
||||||
scons platform=${{ matrix.platform }} target=template_release ${{ matrix.flags }}
|
scons platform=${{ matrix.platform }} target=template_release ${{ matrix.flags }}
|
||||||
|
|
||||||
- name: Download latest Godot artifacts
|
|
||||||
uses: dsnopek/action-download-artifact@1322f74e2dac9feed2ee76a32d9ae1ca3b4cf4e9
|
|
||||||
if: ${{ matrix.run-tests }}
|
|
||||||
with:
|
|
||||||
repo: godotengine/godot
|
|
||||||
branch: master
|
|
||||||
event: push
|
|
||||||
workflow: linux_builds.yml
|
|
||||||
workflow_conclusion: success
|
|
||||||
name: linux-editor-mono
|
|
||||||
search_artifacts: true
|
|
||||||
check_artifacts: true
|
|
||||||
ensure_latest: true
|
|
||||||
path: godot-artifacts
|
|
||||||
|
|
||||||
- name: Run tests
|
|
||||||
if: ${{ matrix.run-tests }}
|
|
||||||
run: |
|
|
||||||
chmod +x ./godot-artifacts/godot.linuxbsd.editor.x86_64.mono
|
|
||||||
./godot-artifacts/godot.linuxbsd.editor.x86_64.mono --headless --version
|
|
||||||
cd test
|
|
||||||
# Need to run the editor so .godot is generated... but it crashes! Ignore that :-)
|
|
||||||
(cd project && (timeout 10 ../../godot-artifacts/godot.linuxbsd.editor.x86_64.mono --editor --headless --quit >/dev/null 2>&1 || true))
|
|
||||||
GODOT=../godot-artifacts/godot.linuxbsd.editor.x86_64.mono ./run-tests.sh
|
|
||||||
|
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
@@ -188,7 +136,7 @@ jobs:
|
|||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
@@ -212,7 +160,7 @@ jobs:
|
|||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
@@ -236,7 +184,7 @@ jobs:
|
|||||||
runs-on: windows-2019
|
runs-on: windows-2019
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
|
|||||||
2
.github/workflows/static_checks.yml
vendored
2
.github/workflows/static_checks.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
|||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
# Azure repositories are not reliable, we need to prevent Azure giving us packages.
|
# Azure repositories are not reliable, we need to prevent Azure giving us packages.
|
||||||
- name: Make apt sources.list use the default Ubuntu repositories
|
- name: Make apt sources.list use the default Ubuntu repositories
|
||||||
|
|||||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -100,7 +100,7 @@ AppPackages/
|
|||||||
|
|
||||||
# Others
|
# Others
|
||||||
sql/
|
sql/
|
||||||
*.[Cc]ache
|
*.Cache
|
||||||
ClientBin/
|
ClientBin/
|
||||||
[Ss]tyle[Cc]op.*
|
[Ss]tyle[Cc]op.*
|
||||||
~$*
|
~$*
|
||||||
@@ -191,7 +191,3 @@ godot.creator.*
|
|||||||
|
|
||||||
# compile commands (https://clang.llvm.org/docs/JSONCompilationDatabase.html)
|
# compile commands (https://clang.llvm.org/docs/JSONCompilationDatabase.html)
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
|
|
||||||
# Python development
|
|
||||||
.venv
|
|
||||||
venv
|
|
||||||
|
|||||||
@@ -37,8 +37,8 @@
|
|||||||
# Todo
|
# Todo
|
||||||
# Test build for Windows, Mac and mingw.
|
# Test build for Windows, Mac and mingw.
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.12)
|
|
||||||
project(godot-cpp LANGUAGES CXX)
|
project(godot-cpp LANGUAGES CXX)
|
||||||
|
cmake_minimum_required(VERSION 3.12)
|
||||||
|
|
||||||
option(GENERATE_TEMPLATE_GET_NODE "Generate a template version of the Node class's get_node." ON)
|
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_SYSTEM_HEADERS "Expose headers as SYSTEM." ON)
|
||||||
@@ -72,22 +72,21 @@ endif()
|
|||||||
# Input from user for GDExtension interface header and the API JSON file
|
# Input from user for GDExtension interface header and the API JSON file
|
||||||
set(GODOT_GDEXTENSION_DIR "gdextension" CACHE STRING "")
|
set(GODOT_GDEXTENSION_DIR "gdextension" CACHE STRING "")
|
||||||
set(GODOT_CUSTOM_API_FILE "" CACHE STRING "")
|
set(GODOT_CUSTOM_API_FILE "" CACHE STRING "")
|
||||||
|
set(FLOAT_PRECISION "single" CACHE STRING "")
|
||||||
|
if ("${FLOAT_PRECISION}" STREQUAL "double")
|
||||||
|
add_definitions(-DREAL_T_IS_DOUBLE)
|
||||||
|
endif()
|
||||||
|
|
||||||
set(GODOT_GDEXTENSION_API_FILE "${GODOT_GDEXTENSION_DIR}/extension_api.json")
|
set(GODOT_GDEXTENSION_API_FILE "${GODOT_GDEXTENSION_DIR}/extension_api.json")
|
||||||
if (NOT "${GODOT_CUSTOM_API_FILE}" STREQUAL "") # User-defined override.
|
if (NOT "${GODOT_CUSTOM_API_FILE}" STREQUAL "") # User-defined override.
|
||||||
set(GODOT_GDEXTENSION_API_FILE "${GODOT_CUSTOM_API_FILE}")
|
set(GODOT_GDEXTENSION_API_FILE "${GODOT_CUSTOM_API_FILE}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(FLOAT_PRECISION "single" CACHE STRING "")
|
|
||||||
if ("${FLOAT_PRECISION}" STREQUAL "double")
|
|
||||||
add_definitions(-DREAL_T_IS_DOUBLE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(GODOT_COMPILE_FLAGS )
|
set(GODOT_COMPILE_FLAGS )
|
||||||
|
|
||||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||||
# using Visual Studio C++
|
# using Visual Studio C++
|
||||||
set(GODOT_COMPILE_FLAGS "/utf-8") # /GF /MP
|
set(GODOT_COMPILE_FLAGS "/EHsc") # /GF /MP
|
||||||
|
|
||||||
if(CMAKE_BUILD_TYPE MATCHES Debug)
|
if(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /MDd") # /Od /RTC1 /Zi
|
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /MDd") # /Od /RTC1 /Zi
|
||||||
@@ -99,28 +98,15 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
|||||||
|
|
||||||
add_definitions(-DNOMINMAX)
|
add_definitions(-DNOMINMAX)
|
||||||
else() # GCC/Clang
|
else() # GCC/Clang
|
||||||
|
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -g")
|
||||||
|
|
||||||
if(CMAKE_BUILD_TYPE MATCHES Debug)
|
if(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -fno-omit-frame-pointer -O0 -g")
|
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -fno-omit-frame-pointer -O0")
|
||||||
else()
|
else()
|
||||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -O3")
|
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -O3")
|
||||||
endif(CMAKE_BUILD_TYPE MATCHES Debug)
|
endif(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||||
endif()
|
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()
|
|
||||||
|
|
||||||
# Generate source from the bindings file
|
# Generate source from the bindings file
|
||||||
find_package(Python3 3.4 REQUIRED) # pathlib should be present
|
find_package(Python3 3.4 REQUIRED) # pathlib should be present
|
||||||
if(GENERATE_TEMPLATE_GET_NODE)
|
if(GENERATE_TEMPLATE_GET_NODE)
|
||||||
@@ -132,7 +118,6 @@ 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)"
|
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}
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
OUTPUT_VARIABLE GENERATED_FILES_LIST
|
OUTPUT_VARIABLE GENERATED_FILES_LIST
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
|
||||||
)
|
)
|
||||||
|
|
||||||
add_custom_command(OUTPUT ${GENERATED_FILES_LIST}
|
add_custom_command(OUTPUT ${GENERATED_FILES_LIST}
|
||||||
|
|||||||
46
README.md
46
README.md
@@ -2,16 +2,8 @@
|
|||||||
|
|
||||||
> **Warning**
|
> **Warning**
|
||||||
>
|
>
|
||||||
> This repository's `master` branch is only usable with
|
> This repository's `master` branch is only usable with Godot's ([GDExtension](https://godotengine.org/article/introducing-gd-extensions))
|
||||||
> [GDExtension](https://godotengine.org/article/introducing-gd-extensions)
|
> API (Godot 4.0 and later).
|
||||||
> from Godot's `master` branch.
|
|
||||||
>
|
|
||||||
> For users of stable branches, switch to the branch matching your target Godot version:
|
|
||||||
> - [`4.2`](https://github.com/godotengine/godot-cpp/tree/4.2)
|
|
||||||
> - [`4.1`](https://github.com/godotengine/godot-cpp/tree/4.1)
|
|
||||||
> - [`4.0`](https://github.com/godotengine/godot-cpp/tree/4.0)
|
|
||||||
>
|
|
||||||
> Or check out the Git tag matching your Godot version (e.g. `godot-4.1.1-stable`).
|
|
||||||
>
|
>
|
||||||
> For GDNative users (Godot 3.x), switch to the [`3.x`](https://github.com/godotengine/godot-cpp/tree/3.x)
|
> For GDNative users (Godot 3.x), switch to the [`3.x`](https://github.com/godotengine/godot-cpp/tree/3.x)
|
||||||
> or the [`3.5`](https://github.com/godotengine/godot-cpp/tree/3.5) branch.
|
> or the [`3.5`](https://github.com/godotengine/godot-cpp/tree/3.5) branch.
|
||||||
@@ -57,10 +49,9 @@ first-party `godot-cpp` extension.
|
|||||||
|
|
||||||
Some compatibility breakage is to be expected as GDExtension and `godot-cpp`
|
Some compatibility breakage is to be expected as GDExtension and `godot-cpp`
|
||||||
get more used, documented, and critical issues get resolved. See the
|
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)
|
[issue tracker](https://github.com/godotengine/godot/issues) for a list of known
|
||||||
and the [godot-cpp issue tracker](https://github.com/godotengine/godot/issues)
|
issues, and be sure to provide feedback on issues and PRs which affect your use
|
||||||
for a list of known issues, and be sure to provide feedback on issues and PRs
|
of this extension.
|
||||||
which affect your use of this extension.
|
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
@@ -82,22 +73,21 @@ just like before.
|
|||||||
|
|
||||||
To use the shared lib in your Godot project you'll need a `.gdextension`
|
To use the shared lib in your Godot project you'll need a `.gdextension`
|
||||||
file, which replaces what was the `.gdnlib` before.
|
file, which replaces what was the `.gdnlib` before.
|
||||||
See [example.gdextension](test/project/example.gdextension) used in the test project:
|
Follow [the example](test/demo/example.gdextension):
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
[configuration]
|
[configuration]
|
||||||
|
|
||||||
entry_symbol = "example_library_init"
|
entry_symbol = "example_library_init"
|
||||||
compatibility_minimum = "4.1"
|
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
|
|
||||||
macos.debug = "res://bin/libgdexample.macos.debug.framework"
|
macos.debug = "bin/libgdexample.macos.debug.framework"
|
||||||
macos.release = "res://bin/libgdexample.macos.release.framework"
|
macos.release = "bin/libgdexample.macos.release.framework"
|
||||||
windows.debug.x86_64 = "res://bin/libgdexample.windows.debug.x86_64.dll"
|
windows.debug.x86_64 = "bin/libgdexample.windows.debug.x86_64.dll"
|
||||||
windows.release.x86_64 = "res://bin/libgdexample.windows.release.x86_64.dll"
|
windows.release.x86_64 = "bin/libgdexample.windows.release.x86_64.dll"
|
||||||
linux.debug.x86_64 = "res://bin/libgdexample.linux.debug.x86_64.so"
|
linux.debug.x86_64 = "bin/libgdexample.linux.debug.x86_64.so"
|
||||||
linux.release.x86_64 = "res://bin/libgdexample.linux.release.x86_64.so"
|
linux.release.x86_64 = "bin/libgdexample.linux.release.x86_64.so"
|
||||||
# Repeat for other architectures to support arm64, rv64, etc.
|
# Repeat for other architectures to support arm64, rv64, etc.
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -109,8 +99,8 @@ extern "C" {
|
|||||||
|
|
||||||
// Initialization.
|
// Initialization.
|
||||||
|
|
||||||
GDExtensionBool GDE_EXPORT example_library_init(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) {
|
GDExtensionBool GDE_EXPORT example_library_init(const GDExtensionInterface *p_interface, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) {
|
||||||
godot::GDExtensionBinding::InitObject init_obj(p_get_proc_address, p_library, r_initialization);
|
godot::GDExtensionBinding::InitObject init_obj(p_interface, p_library, r_initialization);
|
||||||
|
|
||||||
init_obj.register_initializer(initialize_example_module);
|
init_obj.register_initializer(initialize_example_module);
|
||||||
init_obj.register_terminator(uninitialize_example_module);
|
init_obj.register_terminator(uninitialize_example_module);
|
||||||
@@ -135,10 +125,6 @@ void initialize_example_module(ModuleInitializationLevel p_level) {
|
|||||||
|
|
||||||
Any node and resource you register will be available in the corresponding `Create...` dialog. Any class will be available to scripting as well.
|
Any node and resource you register will be available in the corresponding `Create...` dialog. Any class will be available to scripting as well.
|
||||||
|
|
||||||
## Examples and templates
|
## Included example
|
||||||
|
|
||||||
See the [godot-cpp-template](https://github.com/godotengine/godot-cpp-template) project for a
|
Check the project in the `test` folder for an example on how to use and register different things.
|
||||||
generic reusable template.
|
|
||||||
|
|
||||||
Or checkout the code for the [Summator example](https://github.com/paddy-exe/GDExtensionSummator)
|
|
||||||
as shown in the [official documentation](https://docs.godotengine.org/en/latest/tutorials/scripting/gdextension/gdextension_cpp_example.html).
|
|
||||||
|
|||||||
239
SConstruct
239
SConstruct
@@ -5,26 +5,76 @@ import platform
|
|||||||
import sys
|
import sys
|
||||||
import subprocess
|
import subprocess
|
||||||
from binding_generator import scons_generate_bindings, scons_emit_files
|
from binding_generator import scons_generate_bindings, scons_emit_files
|
||||||
|
from SCons.Errors import UserError
|
||||||
|
|
||||||
EnsureSConsVersion(4, 0)
|
EnsureSConsVersion(4, 0)
|
||||||
|
|
||||||
|
|
||||||
try:
|
def add_sources(sources, dir, extension):
|
||||||
Import("env")
|
for f in os.listdir(dir):
|
||||||
except:
|
if f.endswith("." + extension):
|
||||||
# Default tools with no platform defaults to gnu toolchain.
|
sources.append(dir + "/" + f)
|
||||||
# We apply platform specific toolchains via our custom tools.
|
|
||||||
env = Environment(tools=["default"], PLATFORM="")
|
|
||||||
|
|
||||||
env.PrependENVPath("PATH", os.getenv("PATH"))
|
|
||||||
|
def normalize_path(val):
|
||||||
|
return val if os.path.isabs(val) else os.path.join(env.Dir("#").abspath, val)
|
||||||
|
|
||||||
|
|
||||||
|
def validate_api_file(key, val, env):
|
||||||
|
if not os.path.isfile(normalize_path(val)):
|
||||||
|
raise UserError("GDExtension API file ('%s') does not exist: %s" % (key, val))
|
||||||
|
|
||||||
|
|
||||||
|
def validate_gdextension_dir(key, val, env):
|
||||||
|
if not os.path.isdir(normalize_path(val)):
|
||||||
|
raise UserError("GDExtension directory ('%s') does not exist: %s" % (key, val))
|
||||||
|
|
||||||
|
|
||||||
|
def get_gdextension_dir(env):
|
||||||
|
return normalize_path(env.get("gdextension_dir", env.Dir("gdextension").abspath))
|
||||||
|
|
||||||
|
|
||||||
|
def get_api_file(env):
|
||||||
|
return normalize_path(env.get("custom_api_file", os.path.join(get_gdextension_dir(env), "extension_api.json")))
|
||||||
|
|
||||||
|
|
||||||
|
# Try to detect the host platform automatically.
|
||||||
|
# This is used if no `platform` argument is passed
|
||||||
|
if sys.platform.startswith("linux"):
|
||||||
|
default_platform = "linux"
|
||||||
|
elif sys.platform == "darwin":
|
||||||
|
default_platform = "macos"
|
||||||
|
elif sys.platform == "win32" or sys.platform == "msys":
|
||||||
|
default_platform = "windows"
|
||||||
|
elif ARGUMENTS.get("platform", ""):
|
||||||
|
default_platform = ARGUMENTS.get("platform")
|
||||||
|
else:
|
||||||
|
raise ValueError("Could not detect platform automatically, please specify with platform=<platform>")
|
||||||
|
|
||||||
|
# Default tools with no platform defaults to gnu toolchain.
|
||||||
|
# We apply platform specific toolchains via our custom tools.
|
||||||
|
env = Environment(tools=["default"], PLATFORM="")
|
||||||
|
|
||||||
|
# Default num_jobs to local cpu count if not user specified.
|
||||||
|
# SCons has a peculiarity where user-specified options won't be overridden
|
||||||
|
# by SetOption, so we can rely on this to know if we should use our default.
|
||||||
|
initial_num_jobs = env.GetOption("num_jobs")
|
||||||
|
altered_num_jobs = initial_num_jobs + 1
|
||||||
|
env.SetOption("num_jobs", altered_num_jobs)
|
||||||
|
if env.GetOption("num_jobs") == altered_num_jobs:
|
||||||
|
cpu_count = os.cpu_count()
|
||||||
|
if cpu_count is None:
|
||||||
|
print("Couldn't auto-detect CPU count to configure build parallelism. Specify it with the -j argument.")
|
||||||
|
else:
|
||||||
|
safer_cpu_count = cpu_count if cpu_count <= 4 else cpu_count - 1
|
||||||
|
print(
|
||||||
|
"Auto-detected %d CPU cores available for build parallelism. Using %d cores by default. You can override it with the -j argument."
|
||||||
|
% (cpu_count, safer_cpu_count)
|
||||||
|
)
|
||||||
|
env.SetOption("num_jobs", safer_cpu_count)
|
||||||
|
|
||||||
# Custom options and profile flags.
|
# Custom options and profile flags.
|
||||||
customs = ["custom.py"]
|
customs = ["custom.py"]
|
||||||
try:
|
|
||||||
customs += Import("customs")
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
profile = ARGUMENTS.get("profile", "")
|
profile = ARGUMENTS.get("profile", "")
|
||||||
if profile:
|
if profile:
|
||||||
if os.path.isfile(profile):
|
if os.path.isfile(profile):
|
||||||
@@ -32,12 +82,113 @@ if profile:
|
|||||||
elif os.path.isfile(profile + ".py"):
|
elif os.path.isfile(profile + ".py"):
|
||||||
customs.append(profile + ".py")
|
customs.append(profile + ".py")
|
||||||
opts = Variables(customs, ARGUMENTS)
|
opts = Variables(customs, ARGUMENTS)
|
||||||
cpp_tool = Tool("godotcpp", toolpath=["tools"])
|
|
||||||
cpp_tool.options(opts, env)
|
|
||||||
opts.Update(env)
|
|
||||||
|
|
||||||
|
platforms = ("linux", "macos", "windows", "android", "ios", "javascript")
|
||||||
|
opts.Add(
|
||||||
|
EnumVariable(
|
||||||
|
"platform",
|
||||||
|
"Target platform",
|
||||||
|
default_platform,
|
||||||
|
allowed_values=platforms,
|
||||||
|
ignorecase=2,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Editor and template_debug are compatible (i.e. you can use the same binary for Godot editor builds and Godot debug templates).
|
||||||
|
# Godot release templates are only compatible with "template_release" builds.
|
||||||
|
# For this reason, we default to template_debug builds, unlike Godot which defaults to editor builds.
|
||||||
|
opts.Add(
|
||||||
|
EnumVariable("target", "Compilation target", "template_debug", ("editor", "template_release", "template_debug"))
|
||||||
|
)
|
||||||
|
opts.Add(
|
||||||
|
PathVariable(
|
||||||
|
"gdextension_dir",
|
||||||
|
"Path to a custom directory containing GDExtension interface header and API JSON file",
|
||||||
|
None,
|
||||||
|
validate_gdextension_dir,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
opts.Add(
|
||||||
|
PathVariable(
|
||||||
|
"custom_api_file",
|
||||||
|
"Path to a custom GDExtension API JSON file (takes precedence over `gdextension_dir`)",
|
||||||
|
None,
|
||||||
|
validate_api_file,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
opts.Add(
|
||||||
|
BoolVariable("generate_bindings", "Force GDExtension API bindings generation. Auto-detected by default.", False)
|
||||||
|
)
|
||||||
|
opts.Add(BoolVariable("generate_template_get_node", "Generate a template version of the Node class's get_node.", True))
|
||||||
|
|
||||||
|
opts.Add(BoolVariable("build_library", "Build the godot-cpp library.", True))
|
||||||
|
opts.Add(EnumVariable("precision", "Set the floating-point precision level", "single", ("single", "double")))
|
||||||
|
|
||||||
|
# Add platform options
|
||||||
|
tools = {}
|
||||||
|
for pl in platforms:
|
||||||
|
tool = Tool(pl, toolpath=["tools"])
|
||||||
|
if hasattr(tool, "options"):
|
||||||
|
tool.options(opts)
|
||||||
|
tools[pl] = tool
|
||||||
|
|
||||||
|
# CPU architecture options.
|
||||||
|
architecture_array = ["", "universal", "x86_32", "x86_64", "arm32", "arm64", "rv64", "ppc32", "ppc64", "wasm32"]
|
||||||
|
architecture_aliases = {
|
||||||
|
"x64": "x86_64",
|
||||||
|
"amd64": "x86_64",
|
||||||
|
"armv7": "arm32",
|
||||||
|
"armv8": "arm64",
|
||||||
|
"arm64v8": "arm64",
|
||||||
|
"aarch64": "arm64",
|
||||||
|
"rv": "rv64",
|
||||||
|
"riscv": "rv64",
|
||||||
|
"riscv64": "rv64",
|
||||||
|
"ppcle": "ppc32",
|
||||||
|
"ppc": "ppc32",
|
||||||
|
"ppc64le": "ppc64",
|
||||||
|
}
|
||||||
|
opts.Add(EnumVariable("arch", "CPU architecture", "", architecture_array, architecture_aliases))
|
||||||
|
|
||||||
|
# Targets flags tool (optimizations, debug symbols)
|
||||||
|
target_tool = Tool("targets", toolpath=["tools"])
|
||||||
|
target_tool.options(opts)
|
||||||
|
|
||||||
|
opts.Update(env)
|
||||||
Help(opts.GenerateHelpText(env))
|
Help(opts.GenerateHelpText(env))
|
||||||
|
|
||||||
|
# Process CPU architecture argument.
|
||||||
|
if env["arch"] == "":
|
||||||
|
# No architecture specified. Default to arm64 if building for Android,
|
||||||
|
# universal if building for macOS or iOS, wasm32 if building for web,
|
||||||
|
# otherwise default to the host architecture.
|
||||||
|
if env["platform"] in ["macos", "ios"]:
|
||||||
|
env["arch"] = "universal"
|
||||||
|
elif env["platform"] == "android":
|
||||||
|
env["arch"] = "arm64"
|
||||||
|
elif env["platform"] == "javascript":
|
||||||
|
env["arch"] = "wasm32"
|
||||||
|
else:
|
||||||
|
host_machine = platform.machine().lower()
|
||||||
|
if host_machine in architecture_array:
|
||||||
|
env["arch"] = host_machine
|
||||||
|
elif host_machine in architecture_aliases.keys():
|
||||||
|
env["arch"] = architecture_aliases[host_machine]
|
||||||
|
elif "86" in host_machine:
|
||||||
|
# Catches x86, i386, i486, i586, i686, etc.
|
||||||
|
env["arch"] = "x86_32"
|
||||||
|
else:
|
||||||
|
print("Unsupported CPU architecture: " + host_machine)
|
||||||
|
Exit()
|
||||||
|
|
||||||
|
tool = Tool(env["platform"], toolpath=["tools"])
|
||||||
|
|
||||||
|
if tool is None or not tool.exists(env):
|
||||||
|
raise ValueError("Required toolchain not found for platform " + env["platform"])
|
||||||
|
|
||||||
|
tool.generate(env)
|
||||||
|
target_tool.generate(env)
|
||||||
|
|
||||||
# Detect and print a warning listing unknown SCons variables to ease troubleshooting.
|
# Detect and print a warning listing unknown SCons variables to ease troubleshooting.
|
||||||
unknown = opts.UnknownVariables()
|
unknown = opts.UnknownVariables()
|
||||||
if unknown:
|
if unknown:
|
||||||
@@ -45,12 +196,66 @@ if unknown:
|
|||||||
for item in unknown.items():
|
for item in unknown.items():
|
||||||
print(" " + item[0] + "=" + item[1])
|
print(" " + item[0] + "=" + item[1])
|
||||||
|
|
||||||
|
print("Building for architecture " + env["arch"] + " on platform " + env["platform"])
|
||||||
|
|
||||||
|
# Require C++17
|
||||||
|
if env.get("is_msvc", False):
|
||||||
|
env.Append(CXXFLAGS=["/std:c++17"])
|
||||||
|
else:
|
||||||
|
env.Append(CXXFLAGS=["-std=c++17"])
|
||||||
|
|
||||||
|
if env["precision"] == "double":
|
||||||
|
env.Append(CPPDEFINES=["REAL_T_IS_DOUBLE"])
|
||||||
|
|
||||||
|
# Generate bindings
|
||||||
|
env.Append(BUILDERS={"GenerateBindings": Builder(action=scons_generate_bindings, emitter=scons_emit_files)})
|
||||||
|
|
||||||
|
bindings = env.GenerateBindings(
|
||||||
|
env.Dir("."),
|
||||||
|
[get_api_file(env), os.path.join(get_gdextension_dir(env), "gdextension_interface.h"), "binding_generator.py"],
|
||||||
|
)
|
||||||
|
|
||||||
scons_cache_path = os.environ.get("SCONS_CACHE")
|
scons_cache_path = os.environ.get("SCONS_CACHE")
|
||||||
if scons_cache_path is not None:
|
if scons_cache_path is not None:
|
||||||
CacheDir(scons_cache_path)
|
CacheDir(scons_cache_path)
|
||||||
Decider("MD5")
|
Decider("MD5")
|
||||||
|
|
||||||
cpp_tool.generate(env)
|
# Forces bindings regeneration.
|
||||||
library = env.GodotCPP()
|
if env["generate_bindings"]:
|
||||||
|
AlwaysBuild(bindings)
|
||||||
|
NoCache(bindings)
|
||||||
|
|
||||||
|
# Includes
|
||||||
|
env.Append(CPPPATH=[[env.Dir(d) for d in [get_gdextension_dir(env), "include", os.path.join("gen", "include")]]])
|
||||||
|
|
||||||
|
# Sources to compile
|
||||||
|
sources = []
|
||||||
|
add_sources(sources, "src", "cpp")
|
||||||
|
add_sources(sources, "src/classes", "cpp")
|
||||||
|
add_sources(sources, "src/core", "cpp")
|
||||||
|
add_sources(sources, "src/variant", "cpp")
|
||||||
|
sources.extend([f for f in bindings if str(f).endswith(".cpp")])
|
||||||
|
|
||||||
|
suffix = ".{}.{}".format(env["platform"], env["target"])
|
||||||
|
if env.dev_build:
|
||||||
|
suffix += ".dev"
|
||||||
|
if env["precision"] == "double":
|
||||||
|
suffix += ".double"
|
||||||
|
suffix += "." + env["arch"]
|
||||||
|
if env["ios_simulator"]:
|
||||||
|
suffix += ".simulator"
|
||||||
|
|
||||||
|
# Expose it when included from another project
|
||||||
|
env["suffix"] = suffix
|
||||||
|
|
||||||
|
library = None
|
||||||
|
env["OBJSUFFIX"] = suffix + env["OBJSUFFIX"]
|
||||||
|
library_name = "libgodot-cpp{}{}".format(suffix, env["LIBSUFFIX"])
|
||||||
|
|
||||||
|
if env["build_library"]:
|
||||||
|
library = env.StaticLibrary(target=env.File("bin/%s" % library_name), source=sources)
|
||||||
|
Default(library)
|
||||||
|
|
||||||
|
env.Append(LIBPATH=[env.Dir("bin")])
|
||||||
|
env.Append(LIBS=library_name)
|
||||||
Return("env")
|
Return("env")
|
||||||
|
|||||||
@@ -66,14 +66,14 @@ def generate_wrappers(target):
|
|||||||
|
|
||||||
txt += "\n#endif\n"
|
txt += "\n#endif\n"
|
||||||
|
|
||||||
with open(target, "w", encoding="utf-8") as f:
|
with open(target, "w") as f:
|
||||||
f.write(txt)
|
f.write(txt)
|
||||||
|
|
||||||
|
|
||||||
def get_file_list(api_filepath, output_dir, headers=False, sources=False):
|
def get_file_list(api_filepath, output_dir, headers=False, sources=False):
|
||||||
api = {}
|
api = {}
|
||||||
files = []
|
files = []
|
||||||
with open(api_filepath, encoding="utf-8") as api_file:
|
with open(api_filepath) as api_file:
|
||||||
api = json.load(api_file)
|
api = json.load(api_file)
|
||||||
|
|
||||||
core_gen_folder = Path(output_dir) / "gen" / "include" / "godot_cpp" / "core"
|
core_gen_folder = Path(output_dir) / "gen" / "include" / "godot_cpp" / "core"
|
||||||
@@ -97,10 +97,9 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False):
|
|||||||
files.append(str(source_filename.as_posix()))
|
files.append(str(source_filename.as_posix()))
|
||||||
|
|
||||||
for engine_class in api["classes"]:
|
for engine_class in api["classes"]:
|
||||||
# Generate code for the ClassDB singleton under a different name.
|
# TODO: Properly setup this singleton since it conflicts with ClassDB in the bindings.
|
||||||
if engine_class["name"] == "ClassDB":
|
if engine_class["name"] == "ClassDB":
|
||||||
engine_class["name"] = "ClassDBSingleton"
|
continue
|
||||||
engine_class["alias_for"] = "ClassDB"
|
|
||||||
header_filename = include_gen_folder / "classes" / (camel_to_snake(engine_class["name"]) + ".hpp")
|
header_filename = include_gen_folder / "classes" / (camel_to_snake(engine_class["name"]) + ".hpp")
|
||||||
source_filename = source_gen_folder / "classes" / (camel_to_snake(engine_class["name"]) + ".cpp")
|
source_filename = source_gen_folder / "classes" / (camel_to_snake(engine_class["name"]) + ".cpp")
|
||||||
if headers:
|
if headers:
|
||||||
@@ -110,8 +109,6 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False):
|
|||||||
|
|
||||||
for native_struct in api["native_structures"]:
|
for native_struct in api["native_structures"]:
|
||||||
struct_name = native_struct["name"]
|
struct_name = native_struct["name"]
|
||||||
if struct_name == "ObjectID":
|
|
||||||
continue
|
|
||||||
snake_struct_name = camel_to_snake(struct_name)
|
snake_struct_name = camel_to_snake(struct_name)
|
||||||
|
|
||||||
header_filename = include_gen_folder / "classes" / (snake_struct_name + ".hpp")
|
header_filename = include_gen_folder / "classes" / (snake_struct_name + ".hpp")
|
||||||
@@ -124,10 +121,8 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False):
|
|||||||
include_gen_folder / "variant" / "builtin_binds.hpp",
|
include_gen_folder / "variant" / "builtin_binds.hpp",
|
||||||
include_gen_folder / "variant" / "utility_functions.hpp",
|
include_gen_folder / "variant" / "utility_functions.hpp",
|
||||||
include_gen_folder / "variant" / "variant_size.hpp",
|
include_gen_folder / "variant" / "variant_size.hpp",
|
||||||
include_gen_folder / "variant" / "builtin_vararg_methods.hpp",
|
|
||||||
include_gen_folder / "classes" / "global_constants.hpp",
|
include_gen_folder / "classes" / "global_constants.hpp",
|
||||||
include_gen_folder / "classes" / "global_constants_binds.hpp",
|
include_gen_folder / "classes" / "global_constants_binds.hpp",
|
||||||
include_gen_folder / "core" / "version.hpp",
|
|
||||||
]:
|
]:
|
||||||
files.append(str(path.as_posix()))
|
files.append(str(path.as_posix()))
|
||||||
if sources:
|
if sources:
|
||||||
@@ -138,7 +133,9 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False):
|
|||||||
|
|
||||||
|
|
||||||
def print_file_list(api_filepath, output_dir, headers=False, sources=False):
|
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)
|
end = ";"
|
||||||
|
for f in get_file_list(api_filepath, output_dir, headers, sources):
|
||||||
|
print(f, end=end)
|
||||||
|
|
||||||
|
|
||||||
def scons_emit_files(target, source, env):
|
def scons_emit_files(target, source, env):
|
||||||
@@ -164,7 +161,7 @@ def generate_bindings(api_filepath, use_template_get_node, bits="64", precision=
|
|||||||
|
|
||||||
target_dir = Path(output_dir) / "gen"
|
target_dir = Path(output_dir) / "gen"
|
||||||
|
|
||||||
with open(api_filepath, encoding="utf-8") as api_file:
|
with open(api_filepath) as api_file:
|
||||||
api = json.load(api_file)
|
api = json.load(api_file)
|
||||||
|
|
||||||
shutil.rmtree(target_dir, ignore_errors=True)
|
shutil.rmtree(target_dir, ignore_errors=True)
|
||||||
@@ -174,7 +171,6 @@ def generate_bindings(api_filepath, use_template_get_node, bits="64", precision=
|
|||||||
print("Built-in type config: " + real_t + "_" + bits)
|
print("Built-in type config: " + real_t + "_" + bits)
|
||||||
|
|
||||||
generate_global_constants(api, target_dir)
|
generate_global_constants(api, target_dir)
|
||||||
generate_version_header(api, target_dir)
|
|
||||||
generate_global_constant_binds(api, target_dir)
|
generate_global_constant_binds(api, target_dir)
|
||||||
generate_builtin_bindings(api, target_dir, real_t + "_" + bits)
|
generate_builtin_bindings(api, target_dir, real_t + "_" + bits)
|
||||||
generate_engine_classes_bindings(api, target_dir, use_template_get_node)
|
generate_engine_classes_bindings(api, target_dir, use_template_get_node)
|
||||||
@@ -221,7 +217,7 @@ def generate_builtin_bindings(api, output_dir, build_config):
|
|||||||
|
|
||||||
# Create a file for Variant size, since that class isn't generated.
|
# Create a file for Variant size, since that class isn't generated.
|
||||||
variant_size_filename = include_gen_folder / "variant_size.hpp"
|
variant_size_filename = include_gen_folder / "variant_size.hpp"
|
||||||
with variant_size_filename.open("+w", encoding="utf-8") as variant_size_file:
|
with variant_size_filename.open("+w") as variant_size_file:
|
||||||
variant_size_source = []
|
variant_size_source = []
|
||||||
add_header("variant_size.hpp", variant_size_source)
|
add_header("variant_size.hpp", variant_size_source)
|
||||||
|
|
||||||
@@ -297,15 +293,15 @@ def generate_builtin_bindings(api, output_dir, build_config):
|
|||||||
fully_used_classes = list(fully_used_classes)
|
fully_used_classes = list(fully_used_classes)
|
||||||
fully_used_classes.sort()
|
fully_used_classes.sort()
|
||||||
|
|
||||||
with header_filename.open("w+", encoding="utf-8") as header_file:
|
with header_filename.open("w+") as header_file:
|
||||||
header_file.write(generate_builtin_class_header(builtin_api, size, used_classes, fully_used_classes))
|
header_file.write(generate_builtin_class_header(builtin_api, size, used_classes, fully_used_classes))
|
||||||
|
|
||||||
with source_filename.open("w+", encoding="utf-8") as source_file:
|
with source_filename.open("w+") as source_file:
|
||||||
source_file.write(generate_builtin_class_source(builtin_api, size, used_classes, fully_used_classes))
|
source_file.write(generate_builtin_class_source(builtin_api, size, used_classes, fully_used_classes))
|
||||||
|
|
||||||
# Create a header with all builtin types for convenience.
|
# Create a header with all builtin types for convenience.
|
||||||
builtin_header_filename = include_gen_folder / "builtin_types.hpp"
|
builtin_header_filename = include_gen_folder / "builtin_types.hpp"
|
||||||
with builtin_header_filename.open("w+", encoding="utf-8") as builtin_header_file:
|
with builtin_header_filename.open("w+") as builtin_header_file:
|
||||||
builtin_header = []
|
builtin_header = []
|
||||||
add_header("builtin_types.hpp", builtin_header)
|
add_header("builtin_types.hpp", builtin_header)
|
||||||
|
|
||||||
@@ -325,7 +321,7 @@ def generate_builtin_bindings(api, output_dir, build_config):
|
|||||||
|
|
||||||
# Create a header with bindings for builtin types.
|
# Create a header with bindings for builtin types.
|
||||||
builtin_binds_filename = include_gen_folder / "builtin_binds.hpp"
|
builtin_binds_filename = include_gen_folder / "builtin_binds.hpp"
|
||||||
with builtin_binds_filename.open("w+", encoding="utf-8") as builtin_binds_file:
|
with builtin_binds_filename.open("w+") as builtin_binds_file:
|
||||||
builtin_binds = []
|
builtin_binds = []
|
||||||
add_header("builtin_binds.hpp", builtin_binds)
|
add_header("builtin_binds.hpp", builtin_binds)
|
||||||
|
|
||||||
@@ -346,40 +342,6 @@ def generate_builtin_bindings(api, output_dir, build_config):
|
|||||||
|
|
||||||
builtin_binds_file.write("\n".join(builtin_binds))
|
builtin_binds_file.write("\n".join(builtin_binds))
|
||||||
|
|
||||||
# Create a header to implement all builtin class vararg methods and be included in "variant.hpp".
|
|
||||||
builtin_vararg_methods_header = include_gen_folder / "builtin_vararg_methods.hpp"
|
|
||||||
builtin_vararg_methods_header.open("w+").write(
|
|
||||||
generate_builtin_class_vararg_method_implements_header(api["builtin_classes"])
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def generate_builtin_class_vararg_method_implements_header(builtin_classes):
|
|
||||||
result = []
|
|
||||||
|
|
||||||
add_header("builtin_vararg_methods.hpp", result)
|
|
||||||
|
|
||||||
header_guard = "GODOT_CPP_BUILTIN_VARARG_METHODS_HPP"
|
|
||||||
result.append(f"#ifndef {header_guard}")
|
|
||||||
result.append(f"#define {header_guard}")
|
|
||||||
result.append("")
|
|
||||||
for builtin_api in builtin_classes:
|
|
||||||
if not "methods" in builtin_api:
|
|
||||||
continue
|
|
||||||
class_name = builtin_api["name"]
|
|
||||||
for method in builtin_api["methods"]:
|
|
||||||
if not method["is_vararg"]:
|
|
||||||
continue
|
|
||||||
|
|
||||||
result += make_varargs_template(
|
|
||||||
method, "is_static" in method and method["is_static"], class_name, False, False, True
|
|
||||||
)
|
|
||||||
result.append("")
|
|
||||||
|
|
||||||
result.append("")
|
|
||||||
result.append(f"#endif // ! {header_guard}")
|
|
||||||
|
|
||||||
return "\n".join(result)
|
|
||||||
|
|
||||||
|
|
||||||
def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_classes):
|
def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_classes):
|
||||||
result = []
|
result = []
|
||||||
@@ -402,7 +364,6 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
|
|||||||
if class_name == "String":
|
if class_name == "String":
|
||||||
result.append("#include <godot_cpp/variant/char_string.hpp>")
|
result.append("#include <godot_cpp/variant/char_string.hpp>")
|
||||||
result.append("#include <godot_cpp/variant/char_utils.hpp>")
|
result.append("#include <godot_cpp/variant/char_utils.hpp>")
|
||||||
result.append("#include <godot_cpp/classes/global_constants.hpp>")
|
|
||||||
|
|
||||||
if class_name == "PackedStringArray":
|
if class_name == "PackedStringArray":
|
||||||
result.append("#include <godot_cpp/variant/string.hpp>")
|
result.append("#include <godot_cpp/variant/string.hpp>")
|
||||||
@@ -416,9 +377,6 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
|
|||||||
if class_name == "Array":
|
if class_name == "Array":
|
||||||
result.append("#include <godot_cpp/variant/array_helpers.hpp>")
|
result.append("#include <godot_cpp/variant/array_helpers.hpp>")
|
||||||
|
|
||||||
if class_name == "Callable":
|
|
||||||
result.append("#include <godot_cpp/variant/callable_custom.hpp>")
|
|
||||||
|
|
||||||
for include in fully_used_classes:
|
for include in fully_used_classes:
|
||||||
if include == "TypedArray":
|
if include == "TypedArray":
|
||||||
result.append("#include <godot_cpp/variant/typed_array.hpp>")
|
result.append("#include <godot_cpp/variant/typed_array.hpp>")
|
||||||
@@ -521,16 +479,10 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
|
|||||||
|
|
||||||
# Special cases.
|
# Special cases.
|
||||||
if class_name == "String" or class_name == "StringName" or class_name == "NodePath":
|
if class_name == "String" or class_name == "StringName" or class_name == "NodePath":
|
||||||
if class_name == "StringName":
|
result.append(f"\t{class_name}(const char *from);")
|
||||||
result.append(f"\t{class_name}(const char *from, bool p_static = false);")
|
|
||||||
else:
|
|
||||||
result.append(f"\t{class_name}(const char *from);")
|
|
||||||
result.append(f"\t{class_name}(const wchar_t *from);")
|
result.append(f"\t{class_name}(const wchar_t *from);")
|
||||||
result.append(f"\t{class_name}(const char16_t *from);")
|
result.append(f"\t{class_name}(const char16_t *from);")
|
||||||
result.append(f"\t{class_name}(const char32_t *from);")
|
result.append(f"\t{class_name}(const char32_t *from);")
|
||||||
if class_name == "Callable":
|
|
||||||
result.append("\tCallable(CallableCustom *p_custom);")
|
|
||||||
result.append("\tCallableCustom *get_custom() const;")
|
|
||||||
|
|
||||||
if "constants" in builtin_api:
|
if "constants" in builtin_api:
|
||||||
axis_constants_count = 0
|
axis_constants_count = 0
|
||||||
@@ -598,7 +550,6 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
|
|||||||
result.append("\tChar32String utf32() const;")
|
result.append("\tChar32String utf32() const;")
|
||||||
result.append("\tCharWideString wide_string() const;")
|
result.append("\tCharWideString wide_string() const;")
|
||||||
result.append("\tstatic String num_real(double p_num, bool p_trailing = true);")
|
result.append("\tstatic String num_real(double p_num, bool p_trailing = true);")
|
||||||
result.append("\tError resize(int p_size);")
|
|
||||||
|
|
||||||
if "members" in builtin_api:
|
if "members" in builtin_api:
|
||||||
for member in builtin_api["members"]:
|
for member in builtin_api["members"]:
|
||||||
@@ -821,12 +772,12 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
|
|||||||
if "constructors" in builtin_api:
|
if "constructors" in builtin_api:
|
||||||
for constructor in builtin_api["constructors"]:
|
for constructor in builtin_api["constructors"]:
|
||||||
result.append(
|
result.append(
|
||||||
f'\t_method_bindings.constructor_{constructor["index"]} = internal::gdextension_interface_variant_get_ptr_constructor({enum_type_name}, {constructor["index"]});'
|
f'\t_method_bindings.constructor_{constructor["index"]} = internal::gde_interface->variant_get_ptr_constructor({enum_type_name}, {constructor["index"]});'
|
||||||
)
|
)
|
||||||
|
|
||||||
if builtin_api["has_destructor"]:
|
if builtin_api["has_destructor"]:
|
||||||
result.append(
|
result.append(
|
||||||
f"\t_method_bindings.destructor = internal::gdextension_interface_variant_get_ptr_destructor({enum_type_name});"
|
f"\t_method_bindings.destructor = internal::gde_interface->variant_get_ptr_destructor({enum_type_name});"
|
||||||
)
|
)
|
||||||
|
|
||||||
result.append("}")
|
result.append("}")
|
||||||
@@ -838,43 +789,43 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
|
|||||||
result.append("\tString::_init_bindings_constructors_destructor();")
|
result.append("\tString::_init_bindings_constructors_destructor();")
|
||||||
result.append(f"\t{class_name}::_init_bindings_constructors_destructor();")
|
result.append(f"\t{class_name}::_init_bindings_constructors_destructor();")
|
||||||
|
|
||||||
result.append("\tStringName _gde_name;")
|
result.append("\tStringName __name;")
|
||||||
|
|
||||||
if "methods" in builtin_api:
|
if "methods" in builtin_api:
|
||||||
for method in builtin_api["methods"]:
|
for method in builtin_api["methods"]:
|
||||||
# TODO: Add error check for hash mismatch.
|
# TODO: Add error check for hash mismatch.
|
||||||
result.append(f'\t_gde_name = StringName("{method["name"]}");')
|
result.append(f'\t__name = StringName("{method["name"]}");')
|
||||||
result.append(
|
result.append(
|
||||||
f'\t_method_bindings.method_{method["name"]} = internal::gdextension_interface_variant_get_ptr_builtin_method({enum_type_name}, _gde_name._native_ptr(), {method["hash"]});'
|
f'\t_method_bindings.method_{method["name"]} = internal::gde_interface->variant_get_ptr_builtin_method({enum_type_name}, __name._native_ptr(), {method["hash"]});'
|
||||||
)
|
)
|
||||||
|
|
||||||
if "members" in builtin_api:
|
if "members" in builtin_api:
|
||||||
for member in builtin_api["members"]:
|
for member in builtin_api["members"]:
|
||||||
result.append(f'\t_gde_name = StringName("{member["name"]}");')
|
result.append(f'\t__name = StringName("{member["name"]}");')
|
||||||
result.append(
|
result.append(
|
||||||
f'\t_method_bindings.member_{member["name"]}_setter = internal::gdextension_interface_variant_get_ptr_setter({enum_type_name}, _gde_name._native_ptr());'
|
f'\t_method_bindings.member_{member["name"]}_setter = internal::gde_interface->variant_get_ptr_setter({enum_type_name}, __name._native_ptr());'
|
||||||
)
|
)
|
||||||
result.append(
|
result.append(
|
||||||
f'\t_method_bindings.member_{member["name"]}_getter = internal::gdextension_interface_variant_get_ptr_getter({enum_type_name}, _gde_name._native_ptr());'
|
f'\t_method_bindings.member_{member["name"]}_getter = internal::gde_interface->variant_get_ptr_getter({enum_type_name}, __name._native_ptr());'
|
||||||
)
|
)
|
||||||
|
|
||||||
if "indexing_return_type" in builtin_api:
|
if "indexing_return_type" in builtin_api:
|
||||||
result.append(
|
result.append(
|
||||||
f"\t_method_bindings.indexed_setter = internal::gdextension_interface_variant_get_ptr_indexed_setter({enum_type_name});"
|
f"\t_method_bindings.indexed_setter = internal::gde_interface->variant_get_ptr_indexed_setter({enum_type_name});"
|
||||||
)
|
)
|
||||||
result.append(
|
result.append(
|
||||||
f"\t_method_bindings.indexed_getter = internal::gdextension_interface_variant_get_ptr_indexed_getter({enum_type_name});"
|
f"\t_method_bindings.indexed_getter = internal::gde_interface->variant_get_ptr_indexed_getter({enum_type_name});"
|
||||||
)
|
)
|
||||||
|
|
||||||
if "is_keyed" in builtin_api and builtin_api["is_keyed"]:
|
if "is_keyed" in builtin_api and builtin_api["is_keyed"]:
|
||||||
result.append(
|
result.append(
|
||||||
f"\t_method_bindings.keyed_setter = internal::gdextension_interface_variant_get_ptr_keyed_setter({enum_type_name});"
|
f"\t_method_bindings.keyed_setter = internal::gde_interface->variant_get_ptr_keyed_setter({enum_type_name});"
|
||||||
)
|
)
|
||||||
result.append(
|
result.append(
|
||||||
f"\t_method_bindings.keyed_getter = internal::gdextension_interface_variant_get_ptr_keyed_getter({enum_type_name});"
|
f"\t_method_bindings.keyed_getter = internal::gde_interface->variant_get_ptr_keyed_getter({enum_type_name});"
|
||||||
)
|
)
|
||||||
result.append(
|
result.append(
|
||||||
f"\t_method_bindings.keyed_checker = internal::gdextension_interface_variant_get_ptr_keyed_checker({enum_type_name});"
|
f"\t_method_bindings.keyed_checker = internal::gde_interface->variant_get_ptr_keyed_checker({enum_type_name});"
|
||||||
)
|
)
|
||||||
|
|
||||||
if "operators" in builtin_api:
|
if "operators" in builtin_api:
|
||||||
@@ -887,11 +838,11 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
|
|||||||
f"GDEXTENSION_VARIANT_TYPE_{camel_to_snake(operator['right_type']).upper()}"
|
f"GDEXTENSION_VARIANT_TYPE_{camel_to_snake(operator['right_type']).upper()}"
|
||||||
)
|
)
|
||||||
result.append(
|
result.append(
|
||||||
f'\t_method_bindings.operator_{get_operator_id_name(operator["name"])}_{operator["right_type"]} = internal::gdextension_interface_variant_get_ptr_operator_evaluator(GDEXTENSION_VARIANT_OP_{get_operator_id_name(operator["name"]).upper()}, {enum_type_name}, {right_type_variant_type});'
|
f'\t_method_bindings.operator_{get_operator_id_name(operator["name"])}_{operator["right_type"]} = internal::gde_interface->variant_get_ptr_operator_evaluator(GDEXTENSION_VARIANT_OP_{get_operator_id_name(operator["name"]).upper()}, {enum_type_name}, {right_type_variant_type});'
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
result.append(
|
result.append(
|
||||||
f'\t_method_bindings.operator_{get_operator_id_name(operator["name"])} = internal::gdextension_interface_variant_get_ptr_operator_evaluator(GDEXTENSION_VARIANT_OP_{get_operator_id_name(operator["name"]).upper()}, {enum_type_name}, GDEXTENSION_VARIANT_TYPE_NIL);'
|
f'\t_method_bindings.operator_{get_operator_id_name(operator["name"])} = internal::gde_interface->variant_get_ptr_operator_evaluator(GDEXTENSION_VARIANT_OP_{get_operator_id_name(operator["name"]).upper()}, {enum_type_name}, GDEXTENSION_VARIANT_TYPE_NIL);'
|
||||||
)
|
)
|
||||||
|
|
||||||
result.append("}")
|
result.append("}")
|
||||||
@@ -1083,25 +1034,21 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
|
|||||||
|
|
||||||
# First create map of classes and singletons.
|
# First create map of classes and singletons.
|
||||||
for class_api in api["classes"]:
|
for class_api in api["classes"]:
|
||||||
# Generate code for the ClassDB singleton under a different name.
|
# TODO: Properly setup this singleton since it conflicts with ClassDB in the bindings.
|
||||||
if class_api["name"] == "ClassDB":
|
if class_api["name"] == "ClassDB":
|
||||||
class_api["name"] = "ClassDBSingleton"
|
continue
|
||||||
class_api["alias_for"] = "ClassDB"
|
|
||||||
engine_classes[class_api["name"]] = class_api["is_refcounted"]
|
engine_classes[class_api["name"]] = class_api["is_refcounted"]
|
||||||
for native_struct in api["native_structures"]:
|
for native_struct in api["native_structures"]:
|
||||||
if native_struct["name"] == "ObjectID":
|
|
||||||
continue
|
|
||||||
engine_classes[native_struct["name"]] = False
|
engine_classes[native_struct["name"]] = False
|
||||||
native_structures.append(native_struct["name"])
|
native_structures.append(native_struct["name"])
|
||||||
|
|
||||||
for singleton in api["singletons"]:
|
for singleton in api["singletons"]:
|
||||||
# Generate code for the ClassDB singleton under a different name.
|
|
||||||
if singleton["name"] == "ClassDB":
|
|
||||||
singleton["name"] = "ClassDBSingleton"
|
|
||||||
singleton["alias_for"] = "ClassDB"
|
|
||||||
singletons.append(singleton["name"])
|
singletons.append(singleton["name"])
|
||||||
|
|
||||||
for class_api in api["classes"]:
|
for class_api in api["classes"]:
|
||||||
|
# TODO: Properly setup this singleton since it conflicts with ClassDB in the bindings.
|
||||||
|
if class_api["name"] == "ClassDB":
|
||||||
|
continue
|
||||||
# Check used classes for header include.
|
# Check used classes for header include.
|
||||||
used_classes = set()
|
used_classes = set()
|
||||||
fully_used_classes = set()
|
fully_used_classes = set()
|
||||||
@@ -1191,12 +1138,6 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
|
|||||||
else:
|
else:
|
||||||
fully_used_classes.add("Wrapped")
|
fully_used_classes.add("Wrapped")
|
||||||
|
|
||||||
# In order to ensure that PtrToArg specializations for native structs are
|
|
||||||
# always used, let's move any of them into 'fully_used_classes'.
|
|
||||||
for type_name in used_classes:
|
|
||||||
if is_struct_type(type_name) and not is_included_struct_type(type_name):
|
|
||||||
fully_used_classes.add(type_name)
|
|
||||||
|
|
||||||
for type_name in fully_used_classes:
|
for type_name in fully_used_classes:
|
||||||
if type_name in used_classes:
|
if type_name in used_classes:
|
||||||
used_classes.remove(type_name)
|
used_classes.remove(type_name)
|
||||||
@@ -1206,20 +1147,18 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
|
|||||||
fully_used_classes = list(fully_used_classes)
|
fully_used_classes = list(fully_used_classes)
|
||||||
fully_used_classes.sort()
|
fully_used_classes.sort()
|
||||||
|
|
||||||
with header_filename.open("w+", encoding="utf-8") as header_file:
|
with header_filename.open("w+") as header_file:
|
||||||
header_file.write(
|
header_file.write(
|
||||||
generate_engine_class_header(class_api, used_classes, fully_used_classes, use_template_get_node)
|
generate_engine_class_header(class_api, used_classes, fully_used_classes, use_template_get_node)
|
||||||
)
|
)
|
||||||
|
|
||||||
with source_filename.open("w+", encoding="utf-8") as source_file:
|
with source_filename.open("w+") as source_file:
|
||||||
source_file.write(
|
source_file.write(
|
||||||
generate_engine_class_source(class_api, used_classes, fully_used_classes, use_template_get_node)
|
generate_engine_class_source(class_api, used_classes, fully_used_classes, use_template_get_node)
|
||||||
)
|
)
|
||||||
|
|
||||||
for native_struct in api["native_structures"]:
|
for native_struct in api["native_structures"]:
|
||||||
struct_name = native_struct["name"]
|
struct_name = native_struct["name"]
|
||||||
if struct_name == "ObjectID":
|
|
||||||
continue
|
|
||||||
snake_struct_name = camel_to_snake(struct_name)
|
snake_struct_name = camel_to_snake(struct_name)
|
||||||
|
|
||||||
header_filename = include_gen_folder / (snake_struct_name + ".hpp")
|
header_filename = include_gen_folder / (snake_struct_name + ".hpp")
|
||||||
@@ -1244,9 +1183,8 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
|
|||||||
for included in used_classes:
|
for included in used_classes:
|
||||||
result.append(f"#include <godot_cpp/{get_include_path(included)}>")
|
result.append(f"#include <godot_cpp/{get_include_path(included)}>")
|
||||||
|
|
||||||
if len(used_classes) == 0:
|
if len(used_classes) > 0:
|
||||||
result.append("#include <godot_cpp/core/method_ptrcall.hpp>")
|
result.append("")
|
||||||
result.append("")
|
|
||||||
|
|
||||||
result.append("namespace godot {")
|
result.append("namespace godot {")
|
||||||
result.append("")
|
result.append("")
|
||||||
@@ -1264,7 +1202,7 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
|
|||||||
result.append("")
|
result.append("")
|
||||||
result.append(f"#endif // ! {header_guard}")
|
result.append(f"#endif // ! {header_guard}")
|
||||||
|
|
||||||
with header_filename.open("w+", encoding="utf-8") as header_file:
|
with header_filename.open("w+") as header_file:
|
||||||
header_file.write("\n".join(result))
|
header_file.write("\n".join(result))
|
||||||
|
|
||||||
|
|
||||||
@@ -1291,13 +1229,10 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
|
|||||||
else:
|
else:
|
||||||
result.append(f"#include <godot_cpp/{get_include_path(included)}>")
|
result.append(f"#include <godot_cpp/{get_include_path(included)}>")
|
||||||
|
|
||||||
if class_name == "EditorPlugin":
|
|
||||||
result.append("#include <godot_cpp/classes/editor_plugin_registration.hpp>")
|
|
||||||
|
|
||||||
if len(fully_used_classes) > 0:
|
if len(fully_used_classes) > 0:
|
||||||
result.append("")
|
result.append("")
|
||||||
|
|
||||||
if class_name != "Object" and class_name != "ClassDBSingleton":
|
if class_name != "Object":
|
||||||
result.append("#include <godot_cpp/core/class_db.hpp>")
|
result.append("#include <godot_cpp/core/class_db.hpp>")
|
||||||
result.append("")
|
result.append("")
|
||||||
result.append("#include <type_traits>")
|
result.append("#include <type_traits>")
|
||||||
@@ -1318,10 +1253,7 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
|
|||||||
inherits = class_api["inherits"] if "inherits" in class_api else "Wrapped"
|
inherits = class_api["inherits"] if "inherits" in class_api else "Wrapped"
|
||||||
result.append(f"class {class_name} : public {inherits} {{")
|
result.append(f"class {class_name} : public {inherits} {{")
|
||||||
|
|
||||||
if "alias_for" in class_api:
|
result.append(f"\tGDEXTENSION_CLASS({class_name}, {inherits})")
|
||||||
result.append(f"\tGDEXTENSION_CLASS_ALIAS({class_name}, {class_api['alias_for']}, {inherits})")
|
|
||||||
else:
|
|
||||||
result.append(f"\tGDEXTENSION_CLASS({class_name}, {inherits})")
|
|
||||||
result.append("")
|
result.append("")
|
||||||
|
|
||||||
result.append("public:")
|
result.append("public:")
|
||||||
@@ -1329,11 +1261,7 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
|
|||||||
|
|
||||||
if "enums" in class_api:
|
if "enums" in class_api:
|
||||||
for enum_api in class_api["enums"]:
|
for enum_api in class_api["enums"]:
|
||||||
if enum_api["is_bitfield"]:
|
result.append(f'\tenum {enum_api["name"]} {{')
|
||||||
result.append(f'\tenum {enum_api["name"]} : uint64_t {{')
|
|
||||||
else:
|
|
||||||
result.append(f'\tenum {enum_api["name"]} {{')
|
|
||||||
|
|
||||||
for value in enum_api["values"]:
|
for value in enum_api["values"]:
|
||||||
result.append(f'\t\t{value["name"]} = {value["value"]},')
|
result.append(f'\t\t{value["name"]} = {value["value"]},')
|
||||||
result.append("\t};")
|
result.append("\t};")
|
||||||
@@ -1459,51 +1387,6 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
|
|||||||
result.append(f'VARIANT_ENUM_CAST({class_name}::{enum_api["name"]});')
|
result.append(f'VARIANT_ENUM_CAST({class_name}::{enum_api["name"]});')
|
||||||
result.append("")
|
result.append("")
|
||||||
|
|
||||||
if class_name == "ClassDBSingleton":
|
|
||||||
result.append("#define CLASSDB_SINGLETON_FORWARD_METHODS \\")
|
|
||||||
for method in class_api["methods"]:
|
|
||||||
# ClassDBSingleton shouldn't have any static or vararg methods, but if some appear later, lets skip them.
|
|
||||||
if vararg:
|
|
||||||
continue
|
|
||||||
if "is_static" in method and method["is_static"]:
|
|
||||||
continue
|
|
||||||
|
|
||||||
method_signature = "\tstatic "
|
|
||||||
if "return_type" in method:
|
|
||||||
method_signature += f'{correct_type(method["return_type"])} '
|
|
||||||
elif "return_value" in method:
|
|
||||||
method_signature += (
|
|
||||||
correct_type(method["return_value"]["type"], method["return_value"].get("meta", None)) + " "
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
method_signature += "void "
|
|
||||||
|
|
||||||
method_signature += f'{method["name"]}('
|
|
||||||
|
|
||||||
method_arguments = []
|
|
||||||
if "arguments" in method:
|
|
||||||
method_arguments = method["arguments"]
|
|
||||||
|
|
||||||
method_signature += make_function_parameters(
|
|
||||||
method_arguments, include_default=True, for_builtin=True, is_vararg=False
|
|
||||||
)
|
|
||||||
|
|
||||||
method_signature += ") { \\"
|
|
||||||
|
|
||||||
result.append(method_signature)
|
|
||||||
|
|
||||||
method_body = "\t\t"
|
|
||||||
if "return_type" in method or "return_value" in method:
|
|
||||||
method_body += "return "
|
|
||||||
method_body += f'ClassDBSingleton::get_singleton()->{method["name"]}('
|
|
||||||
method_body += ", ".join(map(lambda x: escape_identifier(x["name"]), method_arguments))
|
|
||||||
method_body += "); \\"
|
|
||||||
|
|
||||||
result.append(method_body)
|
|
||||||
result.append("\t} \\")
|
|
||||||
result.append("\t;")
|
|
||||||
result.append("")
|
|
||||||
|
|
||||||
result.append(f"#endif // ! {header_guard}")
|
result.append(f"#endif // ! {header_guard}")
|
||||||
|
|
||||||
return "\n".join(result)
|
return "\n".join(result)
|
||||||
@@ -1536,22 +1419,16 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
|
|||||||
|
|
||||||
if is_singleton:
|
if is_singleton:
|
||||||
result.append(f"{class_name} *{class_name}::get_singleton() {{")
|
result.append(f"{class_name} *{class_name}::get_singleton() {{")
|
||||||
# We assume multi-threaded access is OK because each assignment will assign the same value every time
|
result.append(f"\tconst StringName __class_name = {class_name}::get_class_static();")
|
||||||
result.append(f"\tstatic {class_name} *singleton = nullptr;")
|
|
||||||
result.append("\tif (unlikely(singleton == nullptr)) {")
|
|
||||||
result.append(
|
result.append(
|
||||||
f"\t\tGDExtensionObjectPtr singleton_obj = internal::gdextension_interface_global_get_singleton({class_name}::get_class_static()._native_ptr());"
|
"\tstatic GDExtensionObjectPtr singleton_obj = internal::gde_interface->global_get_singleton(__class_name._native_ptr());"
|
||||||
)
|
)
|
||||||
result.append("#ifdef DEBUG_ENABLED")
|
result.append("#ifdef DEBUG_ENABLED")
|
||||||
result.append("\t\tERR_FAIL_NULL_V(singleton_obj, nullptr);")
|
result.append("\tERR_FAIL_COND_V(singleton_obj == nullptr, nullptr);")
|
||||||
result.append("#endif // DEBUG_ENABLED")
|
result.append("#endif // DEBUG_ENABLED")
|
||||||
result.append(
|
result.append(
|
||||||
f"\t\tsingleton = reinterpret_cast<{class_name} *>(internal::gdextension_interface_object_get_instance_binding(singleton_obj, internal::token, &{class_name}::_gde_binding_callbacks));"
|
f"\tstatic {class_name} *singleton = reinterpret_cast<{class_name} *>(internal::gde_interface->object_get_instance_binding(singleton_obj, internal::token, &{class_name}::___binding_callbacks));"
|
||||||
)
|
)
|
||||||
result.append("#ifdef DEBUG_ENABLED")
|
|
||||||
result.append("\t\tERR_FAIL_NULL_V(singleton, nullptr);")
|
|
||||||
result.append("#endif // DEBUG_ENABLED")
|
|
||||||
result.append("\t}")
|
|
||||||
result.append("\treturn singleton;")
|
result.append("\treturn singleton;")
|
||||||
result.append("}")
|
result.append("}")
|
||||||
result.append("")
|
result.append("")
|
||||||
@@ -1569,18 +1446,20 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
|
|||||||
result.append(method_signature + " {")
|
result.append(method_signature + " {")
|
||||||
|
|
||||||
# Method body.
|
# Method body.
|
||||||
|
result.append(f"\tconst StringName __class_name = {class_name}::get_class_static();")
|
||||||
|
result.append(f'\tconst StringName __method_name = "{method["name"]}";')
|
||||||
result.append(
|
result.append(
|
||||||
f'\tstatic GDExtensionMethodBindPtr _gde_method_bind = internal::gdextension_interface_classdb_get_method_bind({class_name}::get_class_static()._native_ptr(), StringName("{method["name"]}")._native_ptr(), {method["hash"]});'
|
f'\tstatic GDExtensionMethodBindPtr ___method_bind = internal::gde_interface->classdb_get_method_bind(__class_name._native_ptr(), __method_name._native_ptr(), {method["hash"]});'
|
||||||
)
|
)
|
||||||
method_call = "\t"
|
method_call = "\t"
|
||||||
has_return = "return_value" in method and method["return_value"]["type"] != "void"
|
has_return = "return_value" in method and method["return_value"]["type"] != "void"
|
||||||
|
|
||||||
if has_return:
|
if has_return:
|
||||||
result.append(
|
result.append(
|
||||||
f'\tCHECK_METHOD_BIND_RET(_gde_method_bind, {get_default_value_for_type(method["return_value"]["type"])});'
|
f'\tCHECK_METHOD_BIND_RET(___method_bind, {get_default_value_for_type(method["return_value"]["type"])});'
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
result.append("\tCHECK_METHOD_BIND(_gde_method_bind);")
|
result.append("\tCHECK_METHOD_BIND(___method_bind);")
|
||||||
|
|
||||||
is_ref = False
|
is_ref = False
|
||||||
if not vararg:
|
if not vararg:
|
||||||
@@ -1589,34 +1468,34 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
|
|||||||
meta_type = method["return_value"]["meta"] if "meta" in method["return_value"] else None
|
meta_type = method["return_value"]["meta"] if "meta" in method["return_value"] else None
|
||||||
if is_enum(return_type):
|
if is_enum(return_type):
|
||||||
if method["is_static"]:
|
if method["is_static"]:
|
||||||
method_call += f"return ({get_gdextension_type(correct_type(return_type, meta_type))})internal::_call_native_mb_ret<int64_t>(_gde_method_bind, nullptr"
|
method_call += f"return ({get_gdextension_type(correct_type(return_type, meta_type))})internal::_call_native_mb_ret<int64_t>(___method_bind, nullptr"
|
||||||
else:
|
else:
|
||||||
method_call += f"return ({get_gdextension_type(correct_type(return_type, meta_type))})internal::_call_native_mb_ret<int64_t>(_gde_method_bind, _owner"
|
method_call += f"return ({get_gdextension_type(correct_type(return_type, meta_type))})internal::_call_native_mb_ret<int64_t>(___method_bind, _owner"
|
||||||
elif is_pod_type(return_type) or is_variant(return_type):
|
elif is_pod_type(return_type) or is_variant(return_type):
|
||||||
if method["is_static"]:
|
if method["is_static"]:
|
||||||
method_call += f"return internal::_call_native_mb_ret<{get_gdextension_type(correct_type(return_type, meta_type))}>(_gde_method_bind, nullptr"
|
method_call += f"return internal::_call_native_mb_ret<{get_gdextension_type(correct_type(return_type, meta_type))}>(___method_bind, nullptr"
|
||||||
else:
|
else:
|
||||||
method_call += f"return internal::_call_native_mb_ret<{get_gdextension_type(correct_type(return_type, meta_type))}>(_gde_method_bind, _owner"
|
method_call += f"return internal::_call_native_mb_ret<{get_gdextension_type(correct_type(return_type, meta_type))}>(___method_bind, _owner"
|
||||||
elif is_refcounted(return_type):
|
elif is_refcounted(return_type):
|
||||||
if method["is_static"]:
|
if method["is_static"]:
|
||||||
method_call += f"return Ref<{return_type}>::_gde_internal_constructor(internal::_call_native_mb_ret_obj<{return_type}>(_gde_method_bind, nullptr"
|
method_call += f"return Ref<{return_type}>::___internal_constructor(internal::_call_native_mb_ret_obj<{return_type}>(___method_bind, nullptr"
|
||||||
else:
|
else:
|
||||||
method_call += f"return Ref<{return_type}>::_gde_internal_constructor(internal::_call_native_mb_ret_obj<{return_type}>(_gde_method_bind, _owner"
|
method_call += f"return Ref<{return_type}>::___internal_constructor(internal::_call_native_mb_ret_obj<{return_type}>(___method_bind, _owner"
|
||||||
is_ref = True
|
is_ref = True
|
||||||
else:
|
else:
|
||||||
if method["is_static"]:
|
if method["is_static"]:
|
||||||
method_call += (
|
method_call += (
|
||||||
f"return internal::_call_native_mb_ret_obj<{return_type}>(_gde_method_bind, nullptr"
|
f"return internal::_call_native_mb_ret_obj<{return_type}>(___method_bind, nullptr"
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
method_call += (
|
method_call += (
|
||||||
f"return internal::_call_native_mb_ret_obj<{return_type}>(_gde_method_bind, _owner"
|
f"return internal::_call_native_mb_ret_obj<{return_type}>(___method_bind, _owner"
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
if method["is_static"]:
|
if method["is_static"]:
|
||||||
method_call += "internal::_call_native_mb_no_ret(_gde_method_bind, nullptr"
|
method_call += "internal::_call_native_mb_no_ret(___method_bind, nullptr"
|
||||||
else:
|
else:
|
||||||
method_call += "internal::_call_native_mb_no_ret(_gde_method_bind, _owner"
|
method_call += "internal::_call_native_mb_no_ret(___method_bind, _owner"
|
||||||
|
|
||||||
if "arguments" in method:
|
if "arguments" in method:
|
||||||
method_call += ", "
|
method_call += ", "
|
||||||
@@ -1633,7 +1512,7 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
|
|||||||
else: # vararg.
|
else: # vararg.
|
||||||
result.append("\tGDExtensionCallError error;")
|
result.append("\tGDExtensionCallError error;")
|
||||||
result.append("\tVariant ret;")
|
result.append("\tVariant ret;")
|
||||||
method_call += "internal::gdextension_interface_object_method_bind_call(_gde_method_bind, _owner, reinterpret_cast<GDExtensionConstVariantPtr *>(args), arg_count, &ret, &error"
|
method_call += "internal::gde_interface->object_method_bind_call(___method_bind, _owner, reinterpret_cast<GDExtensionConstVariantPtr *>(args), arg_count, &ret, &error"
|
||||||
|
|
||||||
if is_ref:
|
if is_ref:
|
||||||
method_call += ")" # Close Ref<> constructor.
|
method_call += ")" # Close Ref<> constructor.
|
||||||
@@ -1690,8 +1569,6 @@ def generate_global_constants(api, output_dir):
|
|||||||
header.append(f"#ifndef {header_guard}")
|
header.append(f"#ifndef {header_guard}")
|
||||||
header.append(f"#define {header_guard}")
|
header.append(f"#define {header_guard}")
|
||||||
header.append("")
|
header.append("")
|
||||||
header.append("#include <cstdint>")
|
|
||||||
header.append("")
|
|
||||||
header.append("namespace godot {")
|
header.append("namespace godot {")
|
||||||
header.append("")
|
header.append("")
|
||||||
|
|
||||||
@@ -1704,11 +1581,7 @@ def generate_global_constants(api, output_dir):
|
|||||||
if enum_def["name"].startswith("Variant."):
|
if enum_def["name"].startswith("Variant."):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if enum_def["is_bitfield"]:
|
header.append(f'\tenum {enum_def["name"]} {{')
|
||||||
header.append(f'\tenum {enum_def["name"]} : uint64_t {{')
|
|
||||||
else:
|
|
||||||
header.append(f'\tenum {enum_def["name"]} {{')
|
|
||||||
|
|
||||||
for value in enum_def["values"]:
|
for value in enum_def["values"]:
|
||||||
header.append(f'\t\t{value["name"]} = {value["value"]},')
|
header.append(f'\t\t{value["name"]} = {value["value"]},')
|
||||||
header.append("\t};")
|
header.append("\t};")
|
||||||
@@ -1719,36 +1592,7 @@ def generate_global_constants(api, output_dir):
|
|||||||
header.append("")
|
header.append("")
|
||||||
header.append(f"#endif // ! {header_guard}")
|
header.append(f"#endif // ! {header_guard}")
|
||||||
|
|
||||||
with header_filename.open("w+", encoding="utf-8") as header_file:
|
with header_filename.open("w+") as header_file:
|
||||||
header_file.write("\n".join(header))
|
|
||||||
|
|
||||||
|
|
||||||
def generate_version_header(api, output_dir):
|
|
||||||
header = []
|
|
||||||
header_filename = "version.hpp"
|
|
||||||
add_header(header_filename, header)
|
|
||||||
|
|
||||||
include_gen_folder = Path(output_dir) / "include" / "godot_cpp" / "core"
|
|
||||||
include_gen_folder.mkdir(parents=True, exist_ok=True)
|
|
||||||
|
|
||||||
header_file_path = include_gen_folder / header_filename
|
|
||||||
|
|
||||||
header_guard = "GODOT_CPP_VERSION_HPP"
|
|
||||||
header.append(f"#ifndef {header_guard}")
|
|
||||||
header.append(f"#define {header_guard}")
|
|
||||||
header.append("")
|
|
||||||
|
|
||||||
header.append(f"#define GODOT_VERSION_MAJOR {api['header']['version_major']}")
|
|
||||||
header.append(f"#define GODOT_VERSION_MINOR {api['header']['version_minor']}")
|
|
||||||
header.append(f"#define GODOT_VERSION_PATCH {api['header']['version_patch']}")
|
|
||||||
header.append(f"#define GODOT_VERSION_STATUS \"{api['header']['version_status']}\"")
|
|
||||||
header.append(f"#define GODOT_VERSION_BUILD \"{api['header']['version_build']}\"")
|
|
||||||
|
|
||||||
header.append("")
|
|
||||||
header.append(f"#endif // {header_guard}")
|
|
||||||
header.append("")
|
|
||||||
|
|
||||||
with header_file_path.open("w+", encoding="utf-8") as header_file:
|
|
||||||
header_file.write("\n".join(header))
|
header_file.write("\n".join(header))
|
||||||
|
|
||||||
|
|
||||||
@@ -1789,7 +1633,7 @@ def generate_global_constant_binds(api, output_dir):
|
|||||||
|
|
||||||
header.append(f"#endif // ! {header_guard}")
|
header.append(f"#endif // ! {header_guard}")
|
||||||
|
|
||||||
with header_filename.open("w+", encoding="utf-8") as header_file:
|
with header_filename.open("w+") as header_file:
|
||||||
header_file.write("\n".join(header))
|
header_file.write("\n".join(header))
|
||||||
|
|
||||||
|
|
||||||
@@ -1838,7 +1682,7 @@ def generate_utility_functions(api, output_dir):
|
|||||||
header.append("")
|
header.append("")
|
||||||
header.append(f"#endif // ! {header_guard}")
|
header.append(f"#endif // ! {header_guard}")
|
||||||
|
|
||||||
with header_filename.open("w+", encoding="utf-8") as header_file:
|
with header_filename.open("w+") as header_file:
|
||||||
header_file.write("\n".join(header))
|
header_file.write("\n".join(header))
|
||||||
|
|
||||||
# Generate source.
|
# Generate source.
|
||||||
@@ -1863,27 +1707,28 @@ def generate_utility_functions(api, output_dir):
|
|||||||
|
|
||||||
# Function body.
|
# Function body.
|
||||||
|
|
||||||
|
source.append(f'\tconst StringName __function_name = "{function["name"]}";')
|
||||||
source.append(
|
source.append(
|
||||||
f'\tstatic GDExtensionPtrUtilityFunction _gde_function = internal::gdextension_interface_variant_get_ptr_utility_function(StringName("{function["name"]}")._native_ptr(), {function["hash"]});'
|
f'\tstatic GDExtensionPtrUtilityFunction ___function = internal::gde_interface->variant_get_ptr_utility_function(__function_name._native_ptr(), {function["hash"]});'
|
||||||
)
|
)
|
||||||
has_return = "return_type" in function and function["return_type"] != "void"
|
has_return = "return_type" in function and function["return_type"] != "void"
|
||||||
if has_return:
|
if has_return:
|
||||||
source.append(
|
source.append(
|
||||||
f'\tCHECK_METHOD_BIND_RET(_gde_function, {get_default_value_for_type(function["return_type"])});'
|
f'\tCHECK_METHOD_BIND_RET(___function, {get_default_value_for_type(function["return_type"])});'
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
source.append("\tCHECK_METHOD_BIND(_gde_function);")
|
source.append("\tCHECK_METHOD_BIND(___function);")
|
||||||
|
|
||||||
function_call = "\t"
|
function_call = "\t"
|
||||||
if not vararg:
|
if not vararg:
|
||||||
if has_return:
|
if has_return:
|
||||||
function_call += "return "
|
function_call += "return "
|
||||||
if function["return_type"] == "Object":
|
if function["return_type"] == "Object":
|
||||||
function_call += "internal::_call_utility_ret_obj(_gde_function"
|
function_call += "internal::_call_utility_ret_obj(___function"
|
||||||
else:
|
else:
|
||||||
function_call += f'internal::_call_utility_ret<{get_gdextension_type(correct_type(function["return_type"]))}>(_gde_function'
|
function_call += f'internal::_call_utility_ret<{get_gdextension_type(correct_type(function["return_type"]))}>(___function'
|
||||||
else:
|
else:
|
||||||
function_call += "internal::_call_utility_no_ret(_gde_function"
|
function_call += "internal::_call_utility_no_ret(___function"
|
||||||
|
|
||||||
if "arguments" in function:
|
if "arguments" in function:
|
||||||
function_call += ", "
|
function_call += ", "
|
||||||
@@ -1898,11 +1743,8 @@ def generate_utility_functions(api, output_dir):
|
|||||||
arguments.append(arg_name)
|
arguments.append(arg_name)
|
||||||
function_call += ", ".join(arguments)
|
function_call += ", ".join(arguments)
|
||||||
else:
|
else:
|
||||||
if has_return:
|
source.append("\tVariant ret;")
|
||||||
source.append(f'\t{get_gdextension_type(correct_type(function["return_type"]))} ret;')
|
function_call += "___function(&ret, reinterpret_cast<GDExtensionConstVariantPtr *>(args), arg_count"
|
||||||
else:
|
|
||||||
source.append("\tVariant ret;")
|
|
||||||
function_call += "_gde_function(&ret, reinterpret_cast<GDExtensionConstVariantPtr *>(args), arg_count"
|
|
||||||
|
|
||||||
function_call += ");"
|
function_call += ");"
|
||||||
source.append(function_call)
|
source.append(function_call)
|
||||||
@@ -1915,7 +1757,7 @@ def generate_utility_functions(api, output_dir):
|
|||||||
|
|
||||||
source.append("} // namespace godot")
|
source.append("} // namespace godot")
|
||||||
|
|
||||||
with source_filename.open("w+", encoding="utf-8") as source_file:
|
with source_filename.open("w+") as source_file:
|
||||||
source_file.write("\n".join(source))
|
source_file.write("\n".join(source))
|
||||||
|
|
||||||
|
|
||||||
@@ -1989,7 +1831,7 @@ def get_encoded_arg(arg_name, type_name, type_meta):
|
|||||||
elif is_engine_class(type_name):
|
elif is_engine_class(type_name):
|
||||||
# `{name}` is a C++ wrapper, it contains a field which is the object's pointer Godot expects.
|
# `{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.
|
# We have to check `nullptr` because when the caller sends `nullptr`, the wrapper itself will be null.
|
||||||
name = f"({name} != nullptr ? &{name}->_owner : nullptr)"
|
name = f"({name} != nullptr ? {name}->_owner : nullptr)"
|
||||||
else:
|
else:
|
||||||
name = f"&{name}"
|
name = f"&{name}"
|
||||||
|
|
||||||
@@ -2058,22 +1900,10 @@ def make_signature(
|
|||||||
return function_signature
|
return function_signature
|
||||||
|
|
||||||
|
|
||||||
def make_varargs_template(
|
def make_varargs_template(function_data, static=False):
|
||||||
function_data,
|
|
||||||
static=False,
|
|
||||||
class_befor_signature="",
|
|
||||||
with_public_declare=True,
|
|
||||||
with_indent=True,
|
|
||||||
for_builtin_classes=False,
|
|
||||||
):
|
|
||||||
result = []
|
result = []
|
||||||
|
|
||||||
function_signature = ""
|
function_signature = "\tpublic: template<class... Args> "
|
||||||
|
|
||||||
if with_public_declare:
|
|
||||||
function_signature = "public: "
|
|
||||||
|
|
||||||
function_signature += "template<class... Args> "
|
|
||||||
|
|
||||||
if static:
|
if static:
|
||||||
function_signature += "static "
|
function_signature += "static "
|
||||||
@@ -2094,8 +1924,6 @@ def make_varargs_template(
|
|||||||
if not function_signature.endswith("*"):
|
if not function_signature.endswith("*"):
|
||||||
function_signature += " "
|
function_signature += " "
|
||||||
|
|
||||||
if len(class_befor_signature) > 0:
|
|
||||||
function_signature += class_befor_signature + "::"
|
|
||||||
function_signature += f'{escape_identifier(function_data["name"])}'
|
function_signature += f'{escape_identifier(function_data["name"])}'
|
||||||
|
|
||||||
method_arguments = []
|
method_arguments = []
|
||||||
@@ -2116,7 +1944,7 @@ def make_varargs_template(
|
|||||||
function_signature += " {"
|
function_signature += " {"
|
||||||
result.append(function_signature)
|
result.append(function_signature)
|
||||||
|
|
||||||
args_array = f"\tstd::array<Variant, {len(method_arguments)} + sizeof...(Args)> variant_args {{ "
|
args_array = f"\t\tstd::array<Variant, {len(method_arguments)} + sizeof...(Args)> variant_args {{ "
|
||||||
for argument in method_arguments:
|
for argument in method_arguments:
|
||||||
if argument["type"] == "Variant":
|
if argument["type"] == "Variant":
|
||||||
args_array += argument["name"]
|
args_array += argument["name"]
|
||||||
@@ -2126,43 +1954,20 @@ def make_varargs_template(
|
|||||||
|
|
||||||
args_array += "Variant(args)... };"
|
args_array += "Variant(args)... };"
|
||||||
result.append(args_array)
|
result.append(args_array)
|
||||||
result.append(f"\tstd::array<const Variant *, {len(method_arguments)} + sizeof...(Args)> call_args;")
|
result.append(f"\t\tstd::array<const Variant *, {len(method_arguments)} + sizeof...(Args)> call_args;")
|
||||||
result.append("\tfor(size_t i = 0; i < variant_args.size(); i++) {")
|
result.append("\t\tfor(size_t i = 0; i < variant_args.size(); i++) {")
|
||||||
result.append("\t\tcall_args[i] = &variant_args[i];")
|
result.append("\t\t\tcall_args[i] = &variant_args[i];")
|
||||||
|
result.append("\t\t}")
|
||||||
|
|
||||||
|
call_line = "\t\t"
|
||||||
|
|
||||||
|
if return_type != "void":
|
||||||
|
call_line += "return "
|
||||||
|
|
||||||
|
call_line += f'{escape_identifier(function_data["name"])}_internal(call_args.data(), variant_args.size());'
|
||||||
|
result.append(call_line)
|
||||||
result.append("\t}")
|
result.append("\t}")
|
||||||
|
|
||||||
call_line = "\t"
|
|
||||||
|
|
||||||
if not for_builtin_classes:
|
|
||||||
if return_type != "void":
|
|
||||||
call_line += "return "
|
|
||||||
|
|
||||||
call_line += f'{escape_identifier(function_data["name"])}_internal(call_args.data(), variant_args.size());'
|
|
||||||
result.append(call_line)
|
|
||||||
else:
|
|
||||||
base = "(GDExtensionTypePtr)&opaque"
|
|
||||||
if static:
|
|
||||||
base = "nullptr"
|
|
||||||
|
|
||||||
ret = "nullptr"
|
|
||||||
if return_type != "void":
|
|
||||||
ret = "&ret"
|
|
||||||
result.append(f'\t{correct_type(function_data["return_type"])} ret;')
|
|
||||||
|
|
||||||
function_name = function_data["name"]
|
|
||||||
result.append(
|
|
||||||
f"\t_method_bindings.method_{function_name}({base}, reinterpret_cast<GDExtensionConstTypePtr *>(call_args.data()), {ret}, {len(method_arguments)} + sizeof...(Args));"
|
|
||||||
)
|
|
||||||
|
|
||||||
if return_type != "void":
|
|
||||||
result.append("\treturn ret;")
|
|
||||||
|
|
||||||
result.append("}")
|
|
||||||
|
|
||||||
if with_indent:
|
|
||||||
for i in range(len(result)):
|
|
||||||
result[i] = "\t" + result[i]
|
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
@@ -2411,7 +2216,6 @@ def escape_identifier(id):
|
|||||||
"operator": "_operator",
|
"operator": "_operator",
|
||||||
"typeof": "type_of",
|
"typeof": "type_of",
|
||||||
"typename": "type_name",
|
"typename": "type_name",
|
||||||
"enum": "_enum",
|
|
||||||
}
|
}
|
||||||
if id in cpp_keywords_map:
|
if id in cpp_keywords_map:
|
||||||
return cpp_keywords_map[id]
|
return cpp_keywords_map[id]
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,62 +0,0 @@
|
|||||||
/**************************************************************************/
|
|
||||||
/* editor_plugin_registration.hpp */
|
|
||||||
/**************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/**************************************************************************/
|
|
||||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
|
||||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* */
|
|
||||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
|
||||||
/* a copy of this software and associated documentation files (the */
|
|
||||||
/* "Software"), to deal in the Software without restriction, including */
|
|
||||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
|
||||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
|
||||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
|
||||||
/* the following conditions: */
|
|
||||||
/* */
|
|
||||||
/* The above copyright notice and this permission notice shall be */
|
|
||||||
/* included in all copies or substantial portions of the Software. */
|
|
||||||
/* */
|
|
||||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
|
||||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
|
||||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
|
||||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
|
||||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
|
||||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
|
||||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|
||||||
/**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef GODOT_EDITOR_PLUGIN_REGISTRATION_HPP
|
|
||||||
#define GODOT_EDITOR_PLUGIN_REGISTRATION_HPP
|
|
||||||
|
|
||||||
#include <godot_cpp/templates/vector.hpp>
|
|
||||||
|
|
||||||
namespace godot {
|
|
||||||
|
|
||||||
class EditorPlugin;
|
|
||||||
class StringName;
|
|
||||||
|
|
||||||
class EditorPlugins {
|
|
||||||
private:
|
|
||||||
static Vector<StringName> plugin_classes;
|
|
||||||
|
|
||||||
public:
|
|
||||||
static void add_plugin_class(const StringName &p_class_name);
|
|
||||||
static void remove_plugin_class(const StringName &p_class_name);
|
|
||||||
static void deinitialize(GDExtensionInitializationLevel p_level);
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
static void add_by_type() {
|
|
||||||
add_plugin_class(T::get_class_static());
|
|
||||||
}
|
|
||||||
template <class T>
|
|
||||||
static void remove_by_type() {
|
|
||||||
remove_plugin_class(T::get_class_static());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace godot
|
|
||||||
|
|
||||||
#endif // GODOT_EDITOR_PLUGIN_REGISTRATION_HPP
|
|
||||||
@@ -63,7 +63,7 @@ class Ref {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ref_pointer(T *p_ref) {
|
void ref_pointer(T *p_ref) {
|
||||||
ERR_FAIL_NULL(p_ref);
|
ERR_FAIL_COND(!p_ref);
|
||||||
|
|
||||||
if (p_ref->init_ref()) {
|
if (p_ref->init_ref()) {
|
||||||
reference = p_ref;
|
reference = p_ref;
|
||||||
@@ -88,15 +88,26 @@ public:
|
|||||||
return reference != p_r.reference;
|
return reference != p_r.reference;
|
||||||
}
|
}
|
||||||
|
|
||||||
_FORCE_INLINE_ T *operator*() const {
|
_FORCE_INLINE_ T *operator->() {
|
||||||
return reference;
|
return reference;
|
||||||
}
|
}
|
||||||
|
|
||||||
_FORCE_INLINE_ T *operator->() const {
|
_FORCE_INLINE_ T *operator*() {
|
||||||
return reference;
|
return reference;
|
||||||
}
|
}
|
||||||
|
|
||||||
_FORCE_INLINE_ T *ptr() const {
|
_FORCE_INLINE_ const T *operator->() const {
|
||||||
|
return reference;
|
||||||
|
}
|
||||||
|
|
||||||
|
_FORCE_INLINE_ const T *ptr() const {
|
||||||
|
return reference;
|
||||||
|
}
|
||||||
|
_FORCE_INLINE_ T *ptr() {
|
||||||
|
return reference;
|
||||||
|
}
|
||||||
|
|
||||||
|
_FORCE_INLINE_ const T *operator*() const {
|
||||||
return reference;
|
return reference;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,7 +230,7 @@ public:
|
|||||||
|
|
||||||
// Used exclusively in the bindings to recreate the Ref Godot encapsulates in return values,
|
// Used exclusively in the bindings to recreate the Ref Godot encapsulates in return values,
|
||||||
// without adding to the refcount.
|
// without adding to the refcount.
|
||||||
inline static Ref<T> _gde_internal_constructor(Object *obj) {
|
inline static Ref<T> ___internal_constructor(Object *obj) {
|
||||||
Ref<T> r;
|
Ref<T> r;
|
||||||
r.reference = (T *)obj;
|
r.reference = (T *)obj;
|
||||||
return r;
|
return r;
|
||||||
@@ -230,8 +241,10 @@ template <class T>
|
|||||||
struct PtrToArg<Ref<T>> {
|
struct PtrToArg<Ref<T>> {
|
||||||
_FORCE_INLINE_ static Ref<T> convert(const void *p_ptr) {
|
_FORCE_INLINE_ static Ref<T> convert(const void *p_ptr) {
|
||||||
GDExtensionRefPtr ref = (GDExtensionRefPtr)p_ptr;
|
GDExtensionRefPtr ref = (GDExtensionRefPtr)p_ptr;
|
||||||
ERR_FAIL_NULL_V(p_ptr, Ref<T>());
|
ERR_FAIL_NULL_V(ref, Ref<T>());
|
||||||
return Ref<T>(reinterpret_cast<T *>(godot::internal::get_object_instance_binding(godot::internal::gdextension_interface_ref_get_object(ref))));
|
|
||||||
|
T *obj = reinterpret_cast<T *>(godot::internal::gde_interface->object_get_instance_binding(godot::internal::gde_interface->ref_get_object(ref), godot::internal::token, &T::___binding_callbacks));
|
||||||
|
return Ref<T>(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef Ref<T> EncodeT;
|
typedef Ref<T> EncodeT;
|
||||||
@@ -243,7 +256,7 @@ struct PtrToArg<Ref<T>> {
|
|||||||
// This code assumes that p_ptr points to an unset Ref<T> variable on the Godot side
|
// This code assumes that p_ptr points to an unset Ref<T> variable on the Godot side
|
||||||
// so we only set it if we have an object to set.
|
// so we only set it if we have an object to set.
|
||||||
if (p_val.is_valid()) {
|
if (p_val.is_valid()) {
|
||||||
godot::internal::gdextension_interface_ref_set_object(ref, p_val->_owner);
|
godot::internal::gde_interface->ref_set_object(ref, p_val->_owner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -253,9 +266,7 @@ struct PtrToArg<const Ref<T> &> {
|
|||||||
typedef Ref<T> EncodeT;
|
typedef Ref<T> EncodeT;
|
||||||
|
|
||||||
_FORCE_INLINE_ static Ref<T> convert(const void *p_ptr) {
|
_FORCE_INLINE_ static Ref<T> convert(const void *p_ptr) {
|
||||||
GDExtensionRefPtr ref = const_cast<GDExtensionRefPtr>(p_ptr);
|
return Ref<T>(reinterpret_cast<T *>(godot::internal::gde_interface->object_get_instance_binding(*reinterpret_cast<GDExtensionObjectPtr *>(const_cast<void *>(p_ptr)), godot::internal::token, &T::___binding_callbacks)));
|
||||||
ERR_FAIL_NULL_V(p_ptr, Ref<T>());
|
|
||||||
return Ref<T>(reinterpret_cast<T *>(godot::internal::get_object_instance_binding(godot::internal::gdextension_interface_ref_get_object(ref))));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -51,15 +51,6 @@ class Wrapped {
|
|||||||
friend void postinitialize_handler(Wrapped *);
|
friend void postinitialize_handler(Wrapped *);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
#ifdef HOT_RELOAD_ENABLED
|
|
||||||
struct RecreateInstance {
|
|
||||||
GDExtensionClassInstancePtr wrapper;
|
|
||||||
GDExtensionObjectPtr owner;
|
|
||||||
RecreateInstance *next;
|
|
||||||
};
|
|
||||||
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 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;
|
virtual const GDExtensionInstanceBindingCallbacks *_get_bindings_callbacks() const = 0;
|
||||||
|
|
||||||
@@ -69,22 +60,20 @@ protected:
|
|||||||
void _get_property_list(List<PropertyInfo> *p_list) const {}
|
void _get_property_list(List<PropertyInfo> *p_list) const {}
|
||||||
bool _property_can_revert(const StringName &p_name) const { return false; }
|
bool _property_can_revert(const StringName &p_name) const { return false; }
|
||||||
bool _property_get_revert(const StringName &p_name, Variant &r_property) const { return false; }
|
bool _property_get_revert(const StringName &p_name, Variant &r_property) const { return false; }
|
||||||
void _validate_property(PropertyInfo &p_property) const {}
|
|
||||||
String _to_string() const { return "[" + String(get_class_static()) + ":" + itos(get_instance_id()) + "]"; }
|
String _to_string() const { return "[" + String(get_class_static()) + ":" + itos(get_instance_id()) + "]"; }
|
||||||
|
|
||||||
static void notification_bind(GDExtensionClassInstancePtr p_instance, int32_t p_what, GDExtensionBool p_reversed) {}
|
static void notification_bind(GDExtensionClassInstancePtr p_instance, int32_t p_what) {}
|
||||||
static GDExtensionBool set_bind(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionConstVariantPtr p_value) { return false; }
|
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 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 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) {}
|
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_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 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; }
|
|
||||||
static void to_string_bind(GDExtensionClassInstancePtr p_instance, GDExtensionBool *r_is_valid, GDExtensionStringPtr r_out) {}
|
static void to_string_bind(GDExtensionClassInstancePtr p_instance, GDExtensionBool *r_is_valid, GDExtensionStringPtr r_out) {}
|
||||||
|
|
||||||
// The only reason this has to be held here, is when we return results of `_get_property_list` to Godot, we pass
|
|
||||||
// pointers to strings in this list. They have to remain valid to pass the bridge, until the list is freed by Godot...
|
|
||||||
::godot::List<::godot::PropertyInfo> plist_owned;
|
::godot::List<::godot::PropertyInfo> plist_owned;
|
||||||
|
GDExtensionPropertyInfo *plist = nullptr;
|
||||||
|
uint32_t plist_size = 0;
|
||||||
|
|
||||||
void _postinitialize();
|
void _postinitialize();
|
||||||
|
|
||||||
@@ -106,46 +95,9 @@ public:
|
|||||||
GodotObject *_owner = nullptr;
|
GodotObject *_owner = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
GDExtensionPropertyInfo *create_c_property_list(const ::godot::List<::godot::PropertyInfo> &plist_cpp, uint32_t *r_size);
|
|
||||||
void free_c_property_list(GDExtensionPropertyInfo *plist);
|
|
||||||
|
|
||||||
typedef void (*EngineClassRegistrationCallback)();
|
|
||||||
void add_engine_class_registration_callback(EngineClassRegistrationCallback p_callback);
|
|
||||||
void register_engine_class(const StringName &p_name, const GDExtensionInstanceBindingCallbacks *p_callbacks);
|
|
||||||
void register_engine_classes();
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
struct EngineClassRegistration {
|
|
||||||
EngineClassRegistration() {
|
|
||||||
add_engine_class_registration_callback(&EngineClassRegistration<T>::callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void callback() {
|
|
||||||
register_engine_class(T::get_class_static(), &T::_gde_binding_callbacks);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
} // namespace godot
|
} // namespace godot
|
||||||
|
|
||||||
#ifdef HOT_RELOAD_ENABLED
|
#define GDCLASS(m_class, m_inherits) \
|
||||||
#define _GDCLASS_RECREATE(m_class, m_inherits) \
|
|
||||||
m_class *new_instance = (m_class *)memalloc(sizeof(m_class)); \
|
|
||||||
Wrapped::RecreateInstance recreate_data = { new_instance, obj, Wrapped::recreate_instance }; \
|
|
||||||
Wrapped::recreate_instance = &recreate_data; \
|
|
||||||
memnew_placement(new_instance, m_class); \
|
|
||||||
return new_instance;
|
|
||||||
#else
|
|
||||||
#define _GDCLASS_RECREATE(m_class, m_inherits) return nullptr;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Use this on top of your own classes.
|
|
||||||
// Note: the trail of `***` is to keep sane diffs in PRs, because clang-format otherwise moves every `\` which makes
|
|
||||||
// every line of the macro different
|
|
||||||
#define GDCLASS(m_class, m_inherits) /***********************************************************************************************************************************************/ \
|
|
||||||
private: \
|
private: \
|
||||||
void operator=(const m_class &p_rval) {} \
|
void operator=(const m_class &p_rval) {} \
|
||||||
friend class ::godot::ClassDB; \
|
friend class ::godot::ClassDB; \
|
||||||
@@ -157,7 +109,7 @@ protected:
|
|||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
virtual const GDExtensionInstanceBindingCallbacks *_get_bindings_callbacks() const override { \
|
virtual const GDExtensionInstanceBindingCallbacks *_get_bindings_callbacks() const override { \
|
||||||
return &_gde_binding_callbacks; \
|
return &___binding_callbacks; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static void (*_get_bind_methods())() { \
|
static void (*_get_bind_methods())() { \
|
||||||
@@ -180,20 +132,16 @@ protected:
|
|||||||
return (void(::godot::Wrapped::*)(::godot::List<::godot::PropertyInfo> * p_list) const) & m_class::_get_property_list; \
|
return (void(::godot::Wrapped::*)(::godot::List<::godot::PropertyInfo> * p_list) const) & m_class::_get_property_list; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static bool (::godot::Wrapped::*_get_property_can_revert())(const ::godot::StringName &p_name) const { \
|
static bool (::godot::Wrapped::*_get_property_can_revert())(const ::godot::StringName &p_name) { \
|
||||||
return (bool(::godot::Wrapped::*)(const ::godot::StringName &p_name) const) & m_class::_property_can_revert; \
|
return (bool(::godot::Wrapped::*)(const ::godot::StringName &p_name)) & m_class::_property_can_revert; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static bool (::godot::Wrapped::*_get_property_get_revert())(const ::godot::StringName &p_name, ::godot::Variant &) const { \
|
static bool (::godot::Wrapped::*_get_property_get_revert())(const ::godot::StringName &p_name, ::godot::Variant &) { \
|
||||||
return (bool(::godot::Wrapped::*)(const ::godot::StringName &p_name, ::godot::Variant &) const) & m_class::_property_get_revert; \
|
return (bool(::godot::Wrapped::*)(const ::godot::StringName &p_name, ::godot::Variant &)) & m_class::_property_get_revert; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static void (::godot::Wrapped::*_get_validate_property())(::godot::PropertyInfo & p_property) const { \
|
static ::godot::String (::godot::Wrapped::*_get_to_string())() { \
|
||||||
return (void(::godot::Wrapped::*)(::godot::PropertyInfo & p_property) const) & m_class::_validate_property; \
|
return (::godot::String(::godot::Wrapped::*)()) & m_class::_to_string; \
|
||||||
} \
|
|
||||||
\
|
|
||||||
static ::godot::String (::godot::Wrapped::*_get_to_string())() const { \
|
|
||||||
return (::godot::String(::godot::Wrapped::*)() const) & m_class::_to_string; \
|
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
template <class T, class B> \
|
template <class T, class B> \
|
||||||
@@ -202,8 +150,6 @@ protected:
|
|||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
public: \
|
public: \
|
||||||
typedef m_class self_type; \
|
|
||||||
\
|
|
||||||
static void initialize_class() { \
|
static void initialize_class() { \
|
||||||
static bool initialized = false; \
|
static bool initialized = false; \
|
||||||
if (initialized) { \
|
if (initialized) { \
|
||||||
@@ -231,17 +177,13 @@ public:
|
|||||||
return new_object->_owner; \
|
return new_object->_owner; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static GDExtensionClassInstancePtr recreate(void *data, GDExtensionObjectPtr obj) { \
|
static void notification_bind(GDExtensionClassInstancePtr p_instance, int32_t p_what) { \
|
||||||
_GDCLASS_RECREATE(m_class, m_inherits); \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
static void notification_bind(GDExtensionClassInstancePtr p_instance, int32_t p_what, GDExtensionBool p_reversed) { \
|
|
||||||
if (p_instance && m_class::_get_notification()) { \
|
if (p_instance && m_class::_get_notification()) { \
|
||||||
if (m_class::_get_notification() != m_inherits::_get_notification()) { \
|
if (m_class::_get_notification() != m_inherits::_get_notification()) { \
|
||||||
m_class *cls = reinterpret_cast<m_class *>(p_instance); \
|
m_class *cls = reinterpret_cast<m_class *>(p_instance); \
|
||||||
return cls->_notification(p_what); \
|
return cls->_notification(p_what); \
|
||||||
} \
|
} \
|
||||||
m_inherits::notification_bind(p_instance, p_what, p_reversed); \
|
m_inherits::notification_bind(p_instance, p_what); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
@@ -267,29 +209,40 @@ public:
|
|||||||
return false; \
|
return false; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static inline bool has_get_property_list() { \
|
|
||||||
return m_class::_get_get_property_list() && m_class::_get_get_property_list() != m_inherits::_get_get_property_list(); \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
static const GDExtensionPropertyInfo *get_property_list_bind(GDExtensionClassInstancePtr p_instance, uint32_t *r_count) { \
|
static const GDExtensionPropertyInfo *get_property_list_bind(GDExtensionClassInstancePtr p_instance, uint32_t *r_count) { \
|
||||||
if (!p_instance) { \
|
if (p_instance && m_class::_get_get_property_list()) { \
|
||||||
if (r_count) \
|
if (m_class::_get_get_property_list() != m_inherits::_get_get_property_list()) { \
|
||||||
*r_count = 0; \
|
m_class *cls = reinterpret_cast<m_class *>(p_instance); \
|
||||||
return nullptr; \
|
ERR_FAIL_COND_V_MSG(!cls->plist_owned.is_empty() || cls->plist != nullptr || cls->plist_size != 0, nullptr, "Internal error, property list was not freed by engine!"); \
|
||||||
|
cls->_get_property_list(&cls->plist_owned); \
|
||||||
|
cls->plist = reinterpret_cast<GDExtensionPropertyInfo *>(memalloc(sizeof(GDExtensionPropertyInfo) * cls->plist_owned.size())); \
|
||||||
|
cls->plist_size = 0; \
|
||||||
|
for (const ::godot::PropertyInfo &E : cls->plist_owned) { \
|
||||||
|
cls->plist[cls->plist_size].type = static_cast<GDExtensionVariantType>(E.type); \
|
||||||
|
cls->plist[cls->plist_size].name = E.name._native_ptr(); \
|
||||||
|
cls->plist[cls->plist_size].hint = E.hint; \
|
||||||
|
cls->plist[cls->plist_size].hint_string = E.hint_string._native_ptr(); \
|
||||||
|
cls->plist[cls->plist_size].class_name = E.class_name._native_ptr(); \
|
||||||
|
cls->plist[cls->plist_size].usage = E.usage; \
|
||||||
|
cls->plist_size++; \
|
||||||
|
} \
|
||||||
|
if (r_count) \
|
||||||
|
*r_count = cls->plist_size; \
|
||||||
|
return cls->plist; \
|
||||||
|
} \
|
||||||
|
return m_inherits::get_property_list_bind(p_instance, r_count); \
|
||||||
} \
|
} \
|
||||||
m_class *cls = reinterpret_cast<m_class *>(p_instance); \
|
return nullptr; \
|
||||||
::godot::List<::godot::PropertyInfo> &plist_cpp = cls->plist_owned; \
|
|
||||||
ERR_FAIL_COND_V_MSG(!plist_cpp.is_empty(), nullptr, "Internal error, property list was not freed by engine!"); \
|
|
||||||
cls->_get_property_list(&plist_cpp); \
|
|
||||||
return ::godot::internal::create_c_property_list(plist_cpp, r_count); \
|
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static void free_property_list_bind(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list) { \
|
static void free_property_list_bind(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list) { \
|
||||||
if (p_instance) { \
|
if (p_instance) { \
|
||||||
m_class *cls = reinterpret_cast<m_class *>(p_instance); \
|
m_class *cls = reinterpret_cast<m_class *>(p_instance); \
|
||||||
|
ERR_FAIL_COND_MSG(cls->plist == nullptr, "Internal error, property list double free!"); \
|
||||||
|
memfree(cls->plist); \
|
||||||
|
cls->plist = nullptr; \
|
||||||
|
cls->plist_size = 0; \
|
||||||
cls->plist_owned.clear(); \
|
cls->plist_owned.clear(); \
|
||||||
/* TODO `GDExtensionClassFreePropertyList` is ill-defined, we need a non-const pointer to free this. */ \
|
|
||||||
::godot::internal::free_c_property_list(const_cast<GDExtensionPropertyInfo *>(p_list)); \
|
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
@@ -315,21 +268,6 @@ public:
|
|||||||
return false; \
|
return false; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static GDExtensionBool validate_property_bind(GDExtensionClassInstancePtr p_instance, GDExtensionPropertyInfo *p_property) { \
|
|
||||||
bool ret = false; \
|
|
||||||
if (p_instance && m_class::_get_validate_property()) { \
|
|
||||||
ret = m_inherits::validate_property_bind(p_instance, p_property); \
|
|
||||||
if (m_class::_get_validate_property() != m_inherits::_get_validate_property()) { \
|
|
||||||
m_class *cls = reinterpret_cast<m_class *>(p_instance); \
|
|
||||||
::godot::PropertyInfo info(p_property); \
|
|
||||||
cls->_validate_property(info); \
|
|
||||||
info._update(p_property); \
|
|
||||||
return true; \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
return ret; \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
static void to_string_bind(GDExtensionClassInstancePtr p_instance, GDExtensionBool *r_is_valid, GDExtensionStringPtr r_out) { \
|
static void to_string_bind(GDExtensionClassInstancePtr p_instance, GDExtensionBool *r_is_valid, GDExtensionStringPtr r_out) { \
|
||||||
if (p_instance && m_class::_get_to_string()) { \
|
if (p_instance && m_class::_get_to_string()) { \
|
||||||
if (m_class::_get_to_string() != m_inherits::_get_to_string()) { \
|
if (m_class::_get_to_string() != m_inherits::_get_to_string()) { \
|
||||||
@@ -350,126 +288,97 @@ public:
|
|||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static void *_gde_binding_create_callback(void *p_token, void *p_instance) { \
|
static void *___binding_create_callback(void *p_token, void *p_instance) { \
|
||||||
return nullptr; \
|
return nullptr; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static void _gde_binding_free_callback(void *p_token, void *p_instance, void *p_binding) { \
|
static void ___binding_free_callback(void *p_token, void *p_instance, void *p_binding) { \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static GDExtensionBool _gde_binding_reference_callback(void *p_token, void *p_instance, GDExtensionBool p_reference) { \
|
static GDExtensionBool ___binding_reference_callback(void *p_token, void *p_instance, GDExtensionBool p_reference) { \
|
||||||
return true; \
|
return true; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static constexpr GDExtensionInstanceBindingCallbacks _gde_binding_callbacks = { \
|
static constexpr GDExtensionInstanceBindingCallbacks ___binding_callbacks = { \
|
||||||
_gde_binding_create_callback, \
|
___binding_create_callback, \
|
||||||
_gde_binding_free_callback, \
|
___binding_free_callback, \
|
||||||
_gde_binding_reference_callback, \
|
___binding_reference_callback, \
|
||||||
}; \
|
};
|
||||||
\
|
|
||||||
private:
|
|
||||||
|
|
||||||
// Don't use this for your classes, use GDCLASS() instead.
|
// Don't use this for your classes, use GDCLASS() instead.
|
||||||
#define GDEXTENSION_CLASS_ALIAS(m_class, m_alias_for, m_inherits) /******************************************************************************************************************/ \
|
#define GDEXTENSION_CLASS(m_class, m_inherits) \
|
||||||
private: \
|
private: \
|
||||||
inline static ::godot::internal::EngineClassRegistration<m_class> _gde_engine_class_registration_helper; \
|
void operator=(const m_class &p_rval) {} \
|
||||||
void operator=(const m_class &p_rval) {} \
|
\
|
||||||
\
|
protected: \
|
||||||
protected: \
|
virtual const GDExtensionInstanceBindingCallbacks *_get_bindings_callbacks() const override { \
|
||||||
virtual const GDExtensionInstanceBindingCallbacks *_get_bindings_callbacks() const override { \
|
return &___binding_callbacks; \
|
||||||
return &_gde_binding_callbacks; \
|
} \
|
||||||
} \
|
\
|
||||||
\
|
m_class(const char *p_godot_class) : m_inherits(p_godot_class) {} \
|
||||||
m_class(const char *p_godot_class) : m_inherits(p_godot_class) {} \
|
m_class(GodotObject *p_godot_object) : m_inherits(p_godot_object) {} \
|
||||||
m_class(GodotObject *p_godot_object) : m_inherits(p_godot_object) {} \
|
\
|
||||||
\
|
static void (*_get_bind_methods())() { \
|
||||||
static void (*_get_bind_methods())() { \
|
return nullptr; \
|
||||||
return nullptr; \
|
} \
|
||||||
} \
|
\
|
||||||
\
|
static void (Wrapped::*_get_notification())(int) { \
|
||||||
static void (Wrapped::*_get_notification())(int) { \
|
return nullptr; \
|
||||||
return nullptr; \
|
} \
|
||||||
} \
|
\
|
||||||
\
|
static bool (Wrapped::*_get_set())(const ::godot::StringName &p_name, const Variant &p_property) { \
|
||||||
static bool (Wrapped::*_get_set())(const ::godot::StringName &p_name, const Variant &p_property) { \
|
return nullptr; \
|
||||||
return nullptr; \
|
} \
|
||||||
} \
|
\
|
||||||
\
|
static bool (Wrapped::*_get_get())(const ::godot::StringName &p_name, Variant &r_ret) const { \
|
||||||
static bool (Wrapped::*_get_get())(const ::godot::StringName &p_name, Variant &r_ret) const { \
|
return nullptr; \
|
||||||
return nullptr; \
|
} \
|
||||||
} \
|
\
|
||||||
\
|
static void (Wrapped::*_get_get_property_list())(List<PropertyInfo> * p_list) const { \
|
||||||
static inline bool has_get_property_list() { \
|
return nullptr; \
|
||||||
return false; \
|
} \
|
||||||
} \
|
\
|
||||||
\
|
static bool (Wrapped::*_get_property_can_revert())(const ::godot::StringName &p_name) { \
|
||||||
static void (Wrapped::*_get_get_property_list())(List<PropertyInfo> * p_list) const { \
|
return nullptr; \
|
||||||
return nullptr; \
|
} \
|
||||||
} \
|
\
|
||||||
\
|
static bool (Wrapped::*_get_property_get_revert())(const ::godot::StringName &p_name, Variant &) { \
|
||||||
static bool (Wrapped::*_get_property_can_revert())(const ::godot::StringName &p_name) const { \
|
return nullptr; \
|
||||||
return nullptr; \
|
} \
|
||||||
} \
|
\
|
||||||
\
|
static String (Wrapped::*_get_to_string())() { \
|
||||||
static bool (Wrapped::*_get_property_get_revert())(const ::godot::StringName &p_name, Variant &) const { \
|
return nullptr; \
|
||||||
return nullptr; \
|
} \
|
||||||
} \
|
\
|
||||||
\
|
public: \
|
||||||
static void (Wrapped::*_get_validate_property())(::godot::PropertyInfo & p_property) const { \
|
static void initialize_class() {} \
|
||||||
return nullptr; \
|
\
|
||||||
} \
|
static ::godot::StringName &get_class_static() { \
|
||||||
\
|
static ::godot::StringName string_name = ::godot::StringName(#m_class); \
|
||||||
static String (Wrapped::*_get_to_string())() const { \
|
return string_name; \
|
||||||
return nullptr; \
|
} \
|
||||||
} \
|
\
|
||||||
\
|
static ::godot::StringName &get_parent_class_static() { \
|
||||||
public: \
|
return m_inherits::get_class_static(); \
|
||||||
typedef m_class self_type; \
|
} \
|
||||||
\
|
\
|
||||||
static void initialize_class() {} \
|
static void *___binding_create_callback(void *p_token, void *p_instance) { \
|
||||||
\
|
/* Do not call memnew here, we don't want the postinitializer to be called */ \
|
||||||
static ::godot::StringName &get_class_static() { \
|
return new ("") m_class((GodotObject *)p_instance); \
|
||||||
static ::godot::StringName string_name = ::godot::StringName(#m_alias_for); \
|
} \
|
||||||
return string_name; \
|
static void ___binding_free_callback(void *p_token, void *p_instance, void *p_binding) { \
|
||||||
} \
|
/* Explicitly call the deconstructor to ensure proper lifecycle for non-trivial members */ \
|
||||||
\
|
reinterpret_cast<m_class *>(p_binding)->~m_class(); \
|
||||||
static ::godot::StringName &get_parent_class_static() { \
|
Memory::free_static(reinterpret_cast<m_class *>(p_binding)); \
|
||||||
return m_inherits::get_class_static(); \
|
} \
|
||||||
} \
|
static GDExtensionBool ___binding_reference_callback(void *p_token, void *p_instance, GDExtensionBool p_reference) { \
|
||||||
\
|
return true; \
|
||||||
static GDExtensionObjectPtr create(void *data) { \
|
} \
|
||||||
return nullptr; \
|
static constexpr GDExtensionInstanceBindingCallbacks ___binding_callbacks = { \
|
||||||
} \
|
___binding_create_callback, \
|
||||||
\
|
___binding_free_callback, \
|
||||||
static GDExtensionClassInstancePtr recreate(void *data, GDExtensionObjectPtr obj) { \
|
___binding_reference_callback, \
|
||||||
return nullptr; \
|
}; \
|
||||||
} \
|
m_class() : m_class(#m_class) {}
|
||||||
\
|
|
||||||
static void free(void *data, GDExtensionClassInstancePtr ptr) { \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
static void *_gde_binding_create_callback(void *p_token, void *p_instance) { \
|
|
||||||
/* Do not call memnew here, we don't want the post-initializer to be called */ \
|
|
||||||
return new ("", "") m_class((GodotObject *)p_instance); \
|
|
||||||
} \
|
|
||||||
static void _gde_binding_free_callback(void *p_token, void *p_instance, void *p_binding) { \
|
|
||||||
/* Explicitly call the deconstructor to ensure proper lifecycle for non-trivial members */ \
|
|
||||||
reinterpret_cast<m_class *>(p_binding)->~m_class(); \
|
|
||||||
Memory::free_static(reinterpret_cast<m_class *>(p_binding)); \
|
|
||||||
} \
|
|
||||||
static GDExtensionBool _gde_binding_reference_callback(void *p_token, void *p_instance, GDExtensionBool p_reference) { \
|
|
||||||
return true; \
|
|
||||||
} \
|
|
||||||
static constexpr GDExtensionInstanceBindingCallbacks _gde_binding_callbacks = { \
|
|
||||||
_gde_binding_create_callback, \
|
|
||||||
_gde_binding_free_callback, \
|
|
||||||
_gde_binding_reference_callback, \
|
|
||||||
}; \
|
|
||||||
m_class() : m_class(#m_alias_for) {} \
|
|
||||||
\
|
|
||||||
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)
|
|
||||||
|
|
||||||
#endif // GODOT_WRAPPED_HPP
|
#endif // GODOT_WRAPPED_HPP
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ template <class T>
|
|||||||
struct VariantCasterAndValidate {
|
struct VariantCasterAndValidate {
|
||||||
static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, GDExtensionCallError &r_error) {
|
static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, GDExtensionCallError &r_error) {
|
||||||
GDExtensionVariantType argtype = GDExtensionVariantType(GetTypeInfo<T>::VARIANT_TYPE);
|
GDExtensionVariantType argtype = GDExtensionVariantType(GetTypeInfo<T>::VARIANT_TYPE);
|
||||||
if (!internal::gdextension_interface_variant_can_convert_strict(static_cast<GDExtensionVariantType>(p_args[p_arg_idx]->get_type()), argtype) ||
|
if (!internal::gde_interface->variant_can_convert_strict(static_cast<GDExtensionVariantType>(p_args[p_arg_idx]->get_type()), argtype) ||
|
||||||
!VariantObjectClassChecker<T>::check(p_args[p_arg_idx])) {
|
!VariantObjectClassChecker<T>::check(p_args[p_arg_idx])) {
|
||||||
r_error.error = GDEXTENSION_CALL_ERROR_INVALID_ARGUMENT;
|
r_error.error = GDEXTENSION_CALL_ERROR_INVALID_ARGUMENT;
|
||||||
r_error.argument = p_arg_idx;
|
r_error.argument = p_arg_idx;
|
||||||
@@ -163,7 +163,7 @@ template <class T>
|
|||||||
struct VariantCasterAndValidate<T &> {
|
struct VariantCasterAndValidate<T &> {
|
||||||
static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, GDExtensionCallError &r_error) {
|
static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, GDExtensionCallError &r_error) {
|
||||||
GDExtensionVariantType argtype = GDExtensionVariantType(GetTypeInfo<T>::VARIANT_TYPE);
|
GDExtensionVariantType argtype = GDExtensionVariantType(GetTypeInfo<T>::VARIANT_TYPE);
|
||||||
if (!internal::gdextension_interface_variant_can_convert_strict(static_cast<GDExtensionVariantType>(p_args[p_arg_idx]->get_type()), argtype) ||
|
if (!internal::gde_interface->variant_can_convert_strict(static_cast<GDExtensionVariantType>(p_args[p_arg_idx]->get_type()), argtype) ||
|
||||||
!VariantObjectClassChecker<T>::check(p_args[p_arg_idx])) {
|
!VariantObjectClassChecker<T>::check(p_args[p_arg_idx])) {
|
||||||
r_error.error = GDEXTENSION_CALL_ERROR_INVALID_ARGUMENT;
|
r_error.error = GDEXTENSION_CALL_ERROR_INVALID_ARGUMENT;
|
||||||
r_error.argument = p_arg_idx;
|
r_error.argument = p_arg_idx;
|
||||||
@@ -178,7 +178,7 @@ template <class T>
|
|||||||
struct VariantCasterAndValidate<const T &> {
|
struct VariantCasterAndValidate<const T &> {
|
||||||
static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, GDExtensionCallError &r_error) {
|
static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, GDExtensionCallError &r_error) {
|
||||||
GDExtensionVariantType argtype = GDExtensionVariantType(GetTypeInfo<T>::VARIANT_TYPE);
|
GDExtensionVariantType argtype = GDExtensionVariantType(GetTypeInfo<T>::VARIANT_TYPE);
|
||||||
if (!internal::gdextension_interface_variant_can_convert_strict(static_cast<GDExtensionVariantType>(p_args[p_arg_idx]->get_type()), argtype) ||
|
if (!internal::gde_interface->variant_can_convert_strict(static_cast<GDExtensionVariantType>(p_args[p_arg_idx]->get_type()), argtype) ||
|
||||||
!VariantObjectClassChecker<T>::check(p_args[p_arg_idx])) {
|
!VariantObjectClassChecker<T>::check(p_args[p_arg_idx])) {
|
||||||
r_error.error = GDEXTENSION_CALL_ERROR_INVALID_ARGUMENT;
|
r_error.error = GDEXTENSION_CALL_ERROR_INVALID_ARGUMENT;
|
||||||
r_error.argument = p_arg_idx;
|
r_error.argument = p_arg_idx;
|
||||||
@@ -276,60 +276,6 @@ void call_with_variant_args_retc_helper(T *p_instance, R (T::*p_method)(P...) co
|
|||||||
(void)p_args;
|
(void)p_args;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class... P>
|
|
||||||
void call_with_variant_args(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, int p_argcount, GDExtensionCallError &r_error) {
|
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
if ((size_t)p_argcount > sizeof...(P)) {
|
|
||||||
r_error.error = GDEXTENSION_CALL_ERROR_TOO_MANY_ARGUMENTS;
|
|
||||||
r_error.argument = (int32_t)sizeof...(P);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((size_t)p_argcount < sizeof...(P)) {
|
|
||||||
r_error.error = GDEXTENSION_CALL_ERROR_TOO_FEW_ARGUMENTS;
|
|
||||||
r_error.argument = (int32_t)sizeof...(P);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
call_with_variant_args_helper<T, P...>(p_instance, p_method, p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class R, class... P>
|
|
||||||
void call_with_variant_args_ret(T *p_instance, R (T::*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, GDExtensionCallError &r_error) {
|
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
if ((size_t)p_argcount > sizeof...(P)) {
|
|
||||||
r_error.error = GDEXTENSION_CALL_ERROR_TOO_MANY_ARGUMENTS;
|
|
||||||
r_error.argument = (int32_t)sizeof...(P);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((size_t)p_argcount < sizeof...(P)) {
|
|
||||||
r_error.error = GDEXTENSION_CALL_ERROR_TOO_FEW_ARGUMENTS;
|
|
||||||
r_error.argument = (int32_t)sizeof...(P);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
call_with_variant_args_ret_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class R, class... P>
|
|
||||||
void call_with_variant_args_retc(T *p_instance, R (T::*p_method)(P...) const, const Variant **p_args, int p_argcount, Variant &r_ret, GDExtensionCallError &r_error) {
|
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
if ((size_t)p_argcount > sizeof...(P)) {
|
|
||||||
r_error.error = GDEXTENSION_CALL_ERROR_TOO_MANY_ARGUMENTS;
|
|
||||||
r_error.argument = (int32_t)sizeof...(P);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((size_t)p_argcount < sizeof...(P)) {
|
|
||||||
r_error.error = GDEXTENSION_CALL_ERROR_TOO_FEW_ARGUMENTS;
|
|
||||||
r_error.argument = (int32_t)sizeof...(P);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
call_with_variant_args_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class... P>
|
template <class T, class... P>
|
||||||
void call_with_variant_args_dv(T *p_instance, void (T::*p_method)(P...), const GDExtensionConstVariantPtr *p_args, int p_argcount, GDExtensionCallError &r_error, const std::vector<Variant> &default_values) {
|
void call_with_variant_args_dv(T *p_instance, void (T::*p_method)(P...), const GDExtensionConstVariantPtr *p_args, int p_argcount, GDExtensionCallError &r_error, const std::vector<Variant> &default_values) {
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
@@ -592,42 +538,6 @@ void call_with_ptr_args_static_method(void (*p_method)(P...), const GDExtensionC
|
|||||||
call_with_ptr_args_static_method_helper<P...>(p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
|
call_with_ptr_args_static_method_helper<P...>(p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class R, class... P>
|
|
||||||
void call_with_variant_args_static_ret(R (*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, GDExtensionCallError &r_error) {
|
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
if ((size_t)p_argcount > sizeof...(P)) {
|
|
||||||
r_error.error = GDEXTENSION_CALL_ERROR_TOO_MANY_ARGUMENTS;
|
|
||||||
r_error.argument = (int32_t)sizeof...(P);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((size_t)p_argcount < sizeof...(P)) {
|
|
||||||
r_error.error = GDEXTENSION_CALL_ERROR_TOO_FEW_ARGUMENTS;
|
|
||||||
r_error.argument = (int32_t)sizeof...(P);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
call_with_variant_args_static_ret<R, P...>(p_method, p_args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class... P>
|
|
||||||
void call_with_variant_args_static_ret(void (*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, GDExtensionCallError &r_error) {
|
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
if ((size_t)p_argcount > sizeof...(P)) {
|
|
||||||
r_error.error = GDEXTENSION_CALL_ERROR_TOO_MANY_ARGUMENTS;
|
|
||||||
r_error.argument = (int32_t)sizeof...(P);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((size_t)p_argcount < sizeof...(P)) {
|
|
||||||
r_error.error = GDEXTENSION_CALL_ERROR_TOO_FEW_ARGUMENTS;
|
|
||||||
r_error.argument = (int32_t)sizeof...(P);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
call_with_variant_args_static<P...>(p_method, p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class R, class... P, size_t... Is>
|
template <class R, class... P, size_t... Is>
|
||||||
void call_with_variant_args_static_ret(R (*p_method)(P...), const Variant **p_args, Variant &r_ret, GDExtensionCallError &r_error, IndexSequence<Is...>) {
|
void call_with_variant_args_static_ret(R (*p_method)(P...), const Variant **p_args, Variant &r_ret, GDExtensionCallError &r_error, IndexSequence<Is...>) {
|
||||||
r_error.error = GDEXTENSION_CALL_OK;
|
r_error.error = GDEXTENSION_CALL_OK;
|
||||||
|
|||||||
@@ -38,12 +38,6 @@
|
|||||||
#include <godot_cpp/core/method_bind.hpp>
|
#include <godot_cpp/core/method_bind.hpp>
|
||||||
#include <godot_cpp/core/object.hpp>
|
#include <godot_cpp/core/object.hpp>
|
||||||
|
|
||||||
#include <godot_cpp/classes/class_db_singleton.hpp>
|
|
||||||
|
|
||||||
// Makes callable_mp readily available in all classes connecting signals.
|
|
||||||
// Needs to come after method_bind and object have been included.
|
|
||||||
#include <godot_cpp/variant/callable_method_pointer.hpp>
|
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -85,6 +79,15 @@ class ClassDB {
|
|||||||
friend class godot::GDExtensionBinding;
|
friend class godot::GDExtensionBinding;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
struct PropertySetGet {
|
||||||
|
int index;
|
||||||
|
StringName setter;
|
||||||
|
StringName getter;
|
||||||
|
MethodBind *_setptr;
|
||||||
|
MethodBind *_getptr;
|
||||||
|
Variant::Type type;
|
||||||
|
};
|
||||||
|
|
||||||
struct ClassInfo {
|
struct ClassInfo {
|
||||||
StringName name;
|
StringName name;
|
||||||
StringName parent_name;
|
StringName parent_name;
|
||||||
@@ -101,28 +104,19 @@ public:
|
|||||||
private:
|
private:
|
||||||
// This may only contain custom classes, not Godot classes
|
// This may only contain custom classes, not Godot classes
|
||||||
static std::unordered_map<StringName, ClassInfo> classes;
|
static std::unordered_map<StringName, ClassInfo> classes;
|
||||||
static std::unordered_map<StringName, const GDExtensionInstanceBindingCallbacks *> instance_binding_callbacks;
|
|
||||||
// Used to remember the custom class registration order.
|
|
||||||
static std::vector<StringName> class_register_order;
|
|
||||||
|
|
||||||
static MethodBind *bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const MethodDefinition &method_name, const void **p_defs, int p_defcount);
|
static MethodBind *bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const MethodDefinition &method_name, const void **p_defs, int p_defcount);
|
||||||
static void initialize_class(const ClassInfo &cl);
|
static void initialize_class(const ClassInfo &cl);
|
||||||
static void bind_method_godot(const StringName &p_class_name, MethodBind *p_method);
|
static void bind_method_godot(const StringName &p_class_name, MethodBind *p_method);
|
||||||
|
|
||||||
template <class T, bool is_abstract>
|
template <class T, bool is_abstract>
|
||||||
static void _register_class(bool p_virtual = false, bool p_exposed = true);
|
static void _register_class(bool p_virtual = false);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template <class T>
|
template <class T>
|
||||||
static void register_class(bool p_virtual = false);
|
static void register_class(bool p_virtual = false);
|
||||||
template <class T>
|
template <class T>
|
||||||
static void register_abstract_class();
|
static void register_abstract_class();
|
||||||
template <class T>
|
|
||||||
static void register_internal_class();
|
|
||||||
|
|
||||||
_FORCE_INLINE_ static void _register_engine_class(const StringName &p_name, const GDExtensionInstanceBindingCallbacks *p_callbacks) {
|
|
||||||
instance_binding_callbacks[p_name] = p_callbacks;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class N, class M, typename... VarArgs>
|
template <class N, class M, typename... VarArgs>
|
||||||
static MethodBind *bind_method(N p_method_name, M p_method, VarArgs... p_args);
|
static MethodBind *bind_method(N p_method_name, M p_method, VarArgs... p_args);
|
||||||
@@ -143,36 +137,30 @@ public:
|
|||||||
static MethodBind *get_method(const StringName &p_class, const StringName &p_method);
|
static MethodBind *get_method(const StringName &p_class, const StringName &p_method);
|
||||||
|
|
||||||
static GDExtensionClassCallVirtual get_virtual_func(void *p_userdata, GDExtensionConstStringNamePtr p_name);
|
static GDExtensionClassCallVirtual get_virtual_func(void *p_userdata, GDExtensionConstStringNamePtr p_name);
|
||||||
static const GDExtensionInstanceBindingCallbacks *get_instance_binding_callbacks(const StringName &p_class);
|
|
||||||
|
|
||||||
static void initialize(GDExtensionInitializationLevel p_level);
|
static void initialize(GDExtensionInitializationLevel p_level);
|
||||||
static void deinitialize(GDExtensionInitializationLevel p_level);
|
static void deinitialize(GDExtensionInitializationLevel p_level);
|
||||||
|
|
||||||
CLASSDB_SINGLETON_FORWARD_METHODS;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BIND_CONSTANT(m_constant) \
|
#define BIND_CONSTANT(m_constant) \
|
||||||
godot::ClassDB::bind_integer_constant(get_class_static(), "", #m_constant, m_constant);
|
godot::ClassDB::bind_integer_constant(get_class_static(), "", #m_constant, m_constant);
|
||||||
|
|
||||||
#define BIND_ENUM_CONSTANT(m_constant) \
|
#define BIND_ENUM_CONSTANT(m_constant) \
|
||||||
godot::ClassDB::bind_integer_constant(get_class_static(), godot::_gde_constant_get_enum_name(m_constant, #m_constant), #m_constant, m_constant);
|
godot::ClassDB::bind_integer_constant(get_class_static(), godot::__constant_get_enum_name(m_constant, #m_constant), #m_constant, m_constant);
|
||||||
|
|
||||||
#define BIND_BITFIELD_FLAG(m_constant) \
|
#define BIND_BITFIELD_FLAG(m_constant) \
|
||||||
godot::ClassDB::bind_integer_constant(get_class_static(), godot::_gde_constant_get_bitfield_name(m_constant, #m_constant), #m_constant, m_constant, true);
|
godot::ClassDB::bind_integer_constant(get_class_static(), godot::__constant_get_bitfield_name(m_constant, #m_constant), #m_constant, m_constant, true);
|
||||||
|
|
||||||
#define BIND_VIRTUAL_METHOD(m_class, m_method) \
|
#define BIND_VIRTUAL_METHOD(m_class, m_method) \
|
||||||
{ \
|
{ \
|
||||||
auto _call##m_method = [](GDExtensionObjectPtr p_instance, const GDExtensionConstTypePtr *p_args, GDExtensionTypePtr p_ret) -> void { \
|
auto ___call##m_method = [](GDExtensionObjectPtr p_instance, const GDExtensionConstTypePtr *p_args, GDExtensionTypePtr p_ret) -> void { \
|
||||||
call_with_ptr_args(reinterpret_cast<m_class *>(p_instance), &m_class::m_method, p_args, p_ret); \
|
call_with_ptr_args(reinterpret_cast<m_class *>(p_instance), &m_class::m_method, p_args, p_ret); \
|
||||||
}; \
|
}; \
|
||||||
godot::ClassDB::bind_virtual_method(m_class::get_class_static(), #m_method, _call##m_method); \
|
godot::ClassDB::bind_virtual_method(m_class::get_class_static(), #m_method, ___call##m_method); \
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, bool is_abstract>
|
template <class T, bool is_abstract>
|
||||||
void ClassDB::_register_class(bool p_virtual, bool p_exposed) {
|
void ClassDB::_register_class(bool p_virtual) {
|
||||||
static_assert(TypesAreSame<typename T::self_type, T>::value, "Class not declared properly, please use GDCLASS.");
|
|
||||||
instance_binding_callbacks[T::get_class_static()] = &T::_gde_binding_callbacks;
|
|
||||||
|
|
||||||
// Register this class within our plugin
|
// Register this class within our plugin
|
||||||
ClassInfo cl;
|
ClassInfo cl;
|
||||||
cl.name = T::get_class_static();
|
cl.name = T::get_class_static();
|
||||||
@@ -184,35 +172,29 @@ void ClassDB::_register_class(bool p_virtual, bool p_exposed) {
|
|||||||
cl.parent_ptr = &parent_it->second;
|
cl.parent_ptr = &parent_it->second;
|
||||||
}
|
}
|
||||||
classes[cl.name] = cl;
|
classes[cl.name] = cl;
|
||||||
class_register_order.push_back(cl.name);
|
|
||||||
|
|
||||||
// Register this class with Godot
|
// Register this class with Godot
|
||||||
GDExtensionClassCreationInfo2 class_info = {
|
GDExtensionClassCreationInfo class_info = {
|
||||||
p_virtual, // GDExtensionBool is_virtual;
|
p_virtual, // GDExtensionBool is_virtual;
|
||||||
is_abstract, // GDExtensionBool is_abstract;
|
is_abstract, // GDExtensionBool is_abstract;
|
||||||
p_exposed, // GDExtensionBool is_exposed;
|
|
||||||
T::set_bind, // GDExtensionClassSet set_func;
|
T::set_bind, // GDExtensionClassSet set_func;
|
||||||
T::get_bind, // GDExtensionClassGet get_func;
|
T::get_bind, // GDExtensionClassGet get_func;
|
||||||
T::has_get_property_list() ? T::get_property_list_bind : nullptr, // GDExtensionClassGetPropertyList get_property_list_func;
|
T::get_property_list_bind, // GDExtensionClassGetPropertyList get_property_list_func;
|
||||||
T::free_property_list_bind, // GDExtensionClassFreePropertyList 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_can_revert_bind, // GDExtensionClassPropertyCanRevert property_can_revert_func;
|
||||||
T::property_get_revert_bind, // GDExtensionClassPropertyGetRevert property_get_revert_func;
|
T::property_get_revert_bind, // GDExtensionClassPropertyGetRevert property_get_revert_func;
|
||||||
T::validate_property_bind, // GDExtensionClassValidateProperty validate_property_func;
|
T::notification_bind, // GDExtensionClassNotification notification_func;
|
||||||
T::notification_bind, // GDExtensionClassNotification2 notification_func;
|
|
||||||
T::to_string_bind, // GDExtensionClassToString to_string_func;
|
T::to_string_bind, // GDExtensionClassToString to_string_func;
|
||||||
nullptr, // GDExtensionClassReference reference_func;
|
nullptr, // GDExtensionClassReference reference_func;
|
||||||
nullptr, // GDExtensionClassUnreference unreference_func;
|
nullptr, // GDExtensionClassUnreference unreference_func;
|
||||||
T::create, // GDExtensionClassCreateInstance create_instance_func; /* this one is mandatory */
|
T::create, // GDExtensionClassCreateInstance create_instance_func; /* this one is mandatory */
|
||||||
T::free, // GDExtensionClassFreeInstance free_instance_func; /* this one is mandatory */
|
T::free, // GDExtensionClassFreeInstance free_instance_func; /* this one is mandatory */
|
||||||
T::recreate, // GDExtensionClassRecreateInstance recreate_instance_func;
|
|
||||||
&ClassDB::get_virtual_func, // GDExtensionClassGetVirtual get_virtual_func;
|
&ClassDB::get_virtual_func, // GDExtensionClassGetVirtual get_virtual_func;
|
||||||
nullptr, // GDExtensionClassGetVirtualCallData get_virtual_call_data_func;
|
|
||||||
nullptr, // GDExtensionClassCallVirtualWithData call_virtual_func;
|
|
||||||
nullptr, // GDExtensionClassGetRID get_rid;
|
nullptr, // GDExtensionClassGetRID get_rid;
|
||||||
(void *)&T::get_class_static(), // void *class_userdata;
|
(void *)&T::get_class_static(), // void *class_userdata;
|
||||||
};
|
};
|
||||||
|
|
||||||
internal::gdextension_interface_classdb_register_extension_class2(internal::library, cl.name._native_ptr(), cl.parent_name._native_ptr(), &class_info);
|
internal::gde_interface->classdb_register_extension_class(internal::library, cl.name._native_ptr(), cl.parent_name._native_ptr(), &class_info);
|
||||||
|
|
||||||
// call bind_methods etc. to register all members of the class
|
// call bind_methods etc. to register all members of the class
|
||||||
T::initialize_class();
|
T::initialize_class();
|
||||||
@@ -231,11 +213,6 @@ void ClassDB::register_abstract_class() {
|
|||||||
ClassDB::_register_class<T, true>();
|
ClassDB::_register_class<T, true>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
|
||||||
void ClassDB::register_internal_class() {
|
|
||||||
ClassDB::_register_class<T, false>(false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class N, class M, typename... VarArgs>
|
template <class N, class M, typename... VarArgs>
|
||||||
MethodBind *ClassDB::bind_method(N p_method_name, M p_method, VarArgs... p_args) {
|
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.
|
Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported.
|
||||||
@@ -262,7 +239,7 @@ MethodBind *ClassDB::bind_static_method(StringName p_class, N p_method_name, M p
|
|||||||
template <class M>
|
template <class M>
|
||||||
MethodBind *ClassDB::bind_vararg_method(uint32_t p_flags, StringName p_name, M p_method, const MethodInfo &p_info, const std::vector<Variant> &p_default_args, bool p_return_nil_is_variant) {
|
MethodBind *ClassDB::bind_vararg_method(uint32_t p_flags, StringName p_name, M p_method, const MethodInfo &p_info, const std::vector<Variant> &p_default_args, bool p_return_nil_is_variant) {
|
||||||
MethodBind *bind = create_vararg_method_bind(p_method, p_info, p_return_nil_is_variant);
|
MethodBind *bind = create_vararg_method_bind(p_method, p_info, p_return_nil_is_variant);
|
||||||
ERR_FAIL_NULL_V(bind, nullptr);
|
ERR_FAIL_COND_V(!bind, nullptr);
|
||||||
|
|
||||||
bind->set_name(p_name);
|
bind->set_name(p_name);
|
||||||
bind->set_default_arguments(p_default_args);
|
bind->set_default_arguments(p_default_args);
|
||||||
@@ -294,7 +271,6 @@ MethodBind *ClassDB::bind_vararg_method(uint32_t p_flags, StringName p_name, M p
|
|||||||
#define GDREGISTER_CLASS(m_class) ClassDB::register_class<m_class>();
|
#define GDREGISTER_CLASS(m_class) ClassDB::register_class<m_class>();
|
||||||
#define GDREGISTER_VIRTUAL_CLASS(m_class) ClassDB::register_class<m_class>(true);
|
#define GDREGISTER_VIRTUAL_CLASS(m_class) ClassDB::register_class<m_class>(true);
|
||||||
#define GDREGISTER_ABSTRACT_CLASS(m_class) ClassDB::register_abstract_class<m_class>();
|
#define GDREGISTER_ABSTRACT_CLASS(m_class) ClassDB::register_abstract_class<m_class>();
|
||||||
#define GDREGISTER_INTERNAL_CLASS(m_class) ClassDB::register_internal_class<m_class>();
|
|
||||||
|
|
||||||
} // namespace godot
|
} // namespace godot
|
||||||
|
|
||||||
|
|||||||
@@ -47,25 +47,25 @@ template <class O, class... Args>
|
|||||||
O *_call_native_mb_ret_obj(const GDExtensionMethodBindPtr mb, void *instance, const Args &...args) {
|
O *_call_native_mb_ret_obj(const GDExtensionMethodBindPtr mb, void *instance, const Args &...args) {
|
||||||
GodotObject *ret = nullptr;
|
GodotObject *ret = nullptr;
|
||||||
std::array<GDExtensionConstTypePtr, sizeof...(Args)> mb_args = { { (GDExtensionConstTypePtr)args... } };
|
std::array<GDExtensionConstTypePtr, sizeof...(Args)> mb_args = { { (GDExtensionConstTypePtr)args... } };
|
||||||
internal::gdextension_interface_object_method_bind_ptrcall(mb, instance, mb_args.data(), &ret);
|
internal::gde_interface->object_method_bind_ptrcall(mb, instance, mb_args.data(), &ret);
|
||||||
if (ret == nullptr) {
|
if (ret == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return reinterpret_cast<O *>(internal::get_object_instance_binding(ret));
|
return reinterpret_cast<O *>(internal::gde_interface->object_get_instance_binding(ret, internal::token, &O::___binding_callbacks));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class R, class... Args>
|
template <class R, class... Args>
|
||||||
R _call_native_mb_ret(const GDExtensionMethodBindPtr mb, void *instance, const Args &...args) {
|
R _call_native_mb_ret(const GDExtensionMethodBindPtr mb, void *instance, const Args &...args) {
|
||||||
R ret;
|
R ret;
|
||||||
std::array<GDExtensionConstTypePtr, sizeof...(Args)> mb_args = { { (GDExtensionConstTypePtr)args... } };
|
std::array<GDExtensionConstTypePtr, sizeof...(Args)> mb_args = { { (GDExtensionConstTypePtr)args... } };
|
||||||
internal::gdextension_interface_object_method_bind_ptrcall(mb, instance, mb_args.data(), &ret);
|
internal::gde_interface->object_method_bind_ptrcall(mb, instance, mb_args.data(), &ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class... Args>
|
template <class... Args>
|
||||||
void _call_native_mb_no_ret(const GDExtensionMethodBindPtr mb, void *instance, const Args &...args) {
|
void _call_native_mb_no_ret(const GDExtensionMethodBindPtr mb, void *instance, const Args &...args) {
|
||||||
std::array<GDExtensionConstTypePtr, sizeof...(Args)> mb_args = { { (GDExtensionConstTypePtr)args... } };
|
std::array<GDExtensionConstTypePtr, sizeof...(Args)> mb_args = { { (GDExtensionConstTypePtr)args... } };
|
||||||
internal::gdextension_interface_object_method_bind_ptrcall(mb, instance, mb_args.data(), nullptr);
|
internal::gde_interface->object_method_bind_ptrcall(mb, instance, mb_args.data(), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class R, class... Args>
|
template <class R, class... Args>
|
||||||
@@ -81,7 +81,7 @@ Object *_call_utility_ret_obj(const GDExtensionPtrUtilityFunction func, void *in
|
|||||||
GodotObject *ret = nullptr;
|
GodotObject *ret = nullptr;
|
||||||
std::array<GDExtensionConstTypePtr, sizeof...(Args)> mb_args = { { (GDExtensionConstTypePtr)args... } };
|
std::array<GDExtensionConstTypePtr, sizeof...(Args)> mb_args = { { (GDExtensionConstTypePtr)args... } };
|
||||||
func(&ret, mb_args.data(), mb_args.size());
|
func(&ret, mb_args.data(), mb_args.size());
|
||||||
return (Object *)internal::get_object_instance_binding(ret);
|
return (Object *)internal::gde_interface->object_get_instance_binding(ret, internal::token, &Object::___binding_callbacks);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class... Args>
|
template <class... Args>
|
||||||
|
|||||||
@@ -44,21 +44,20 @@
|
|||||||
#define PAD_ALIGN 16 //must always be greater than this at much
|
#define PAD_ALIGN 16 //must always be greater than this at much
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// p_dummy argument is added to avoid conflicts with the engine functions when both engine and GDExtension are built as a static library on iOS.
|
void *operator new(size_t p_size, const char *p_description); ///< operator new that takes a description and uses MemoryStaticPool
|
||||||
void *operator new(size_t p_size, const char *p_dummy, const char *p_description); ///< operator new that takes a description and uses MemoryStaticPool
|
void *operator new(size_t p_size, void *(*p_allocfunc)(size_t p_size)); ///< operator new that takes a description and uses MemoryStaticPool
|
||||||
void *operator new(size_t p_size, const char *p_dummy, void *(*p_allocfunc)(size_t p_size)); ///< operator new that takes a description and uses MemoryStaticPool
|
void *operator new(size_t p_size, void *p_pointer, size_t check, const char *p_description); ///< operator new that takes a description and uses a pointer to the preallocated memory
|
||||||
void *operator new(size_t p_size, const char *p_dummy, void *p_pointer, size_t check, const char *p_description); ///< operator new that takes a description and uses a pointer to the preallocated memory
|
|
||||||
|
|
||||||
_ALWAYS_INLINE_ void *operator new(size_t p_size, const char *p_dummy, void *p_pointer, size_t check, const char *p_description) {
|
_ALWAYS_INLINE_ void *operator new(size_t p_size, void *p_pointer, size_t check, const char *p_description) {
|
||||||
return p_pointer;
|
return p_pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
// When compiling with VC++ 2017, the above declarations of placement new generate many irrelevant warnings (C4291).
|
// When compiling with VC++ 2017, the above declarations of placement new generate many irrelevant warnings (C4291).
|
||||||
// The purpose of the following definitions is to muffle these warnings, not to provide a usable implementation of placement delete.
|
// The purpose of the following definitions is to muffle these warnings, not to provide a usable implementation of placement delete.
|
||||||
void operator delete(void *p_mem, const char *p_dummy, const char *p_description);
|
void operator delete(void *p_mem, const char *p_description);
|
||||||
void operator delete(void *p_mem, const char *p_dummy, void *(*p_allocfunc)(size_t p_size));
|
void operator delete(void *p_mem, void *(*p_allocfunc)(size_t p_size));
|
||||||
void operator delete(void *p_mem, const char *p_dummy, void *p_pointer, size_t check, const char *p_description);
|
void operator delete(void *p_mem, void *p_pointer, size_t check, const char *p_description);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace godot {
|
namespace godot {
|
||||||
@@ -86,10 +85,10 @@ _ALWAYS_INLINE_ T *_post_initialize(T *p_obj) {
|
|||||||
#define memrealloc(m_mem, m_size) ::godot::Memory::realloc_static(m_mem, m_size)
|
#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 memfree(m_mem) ::godot::Memory::free_static(m_mem)
|
||||||
|
|
||||||
#define memnew(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::_post_initialize(new ("", m_allocator::alloc) 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)
|
#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.
|
// Generic comparator used in Map, List, etc.
|
||||||
template <class T>
|
template <class T>
|
||||||
@@ -108,7 +107,7 @@ void memdelete(T *p_class, typename std::enable_if<!std::is_base_of_v<godot::Wra
|
|||||||
|
|
||||||
template <class T, std::enable_if_t<std::is_base_of_v<godot::Wrapped, T>, bool> = true>
|
template <class T, std::enable_if_t<std::is_base_of_v<godot::Wrapped, T>, bool> = true>
|
||||||
void memdelete(T *p_class) {
|
void memdelete(T *p_class) {
|
||||||
godot::internal::gdextension_interface_object_destroy(p_class->_owner);
|
godot::internal::gde_interface->object_destroy(p_class->_owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, class A>
|
template <class T, class A>
|
||||||
@@ -147,7 +146,7 @@ T *memnew_arr_template(size_t p_elements, const char *p_descr = "") {
|
|||||||
size_t len = sizeof(T) * p_elements;
|
size_t len = sizeof(T) * p_elements;
|
||||||
uint64_t *mem = (uint64_t *)Memory::alloc_static(len, true);
|
uint64_t *mem = (uint64_t *)Memory::alloc_static(len, true);
|
||||||
T *failptr = nullptr; // Get rid of a warning.
|
T *failptr = nullptr; // Get rid of a warning.
|
||||||
ERR_FAIL_NULL_V(mem, failptr);
|
ERR_FAIL_COND_V(!mem, failptr);
|
||||||
*(mem - 1) = p_elements;
|
*(mem - 1) = p_elements;
|
||||||
|
|
||||||
if (!std::is_trivially_destructible<T>::value) {
|
if (!std::is_trivially_destructible<T>::value) {
|
||||||
@@ -155,7 +154,7 @@ T *memnew_arr_template(size_t p_elements, const char *p_descr = "") {
|
|||||||
|
|
||||||
/* call operator new */
|
/* call operator new */
|
||||||
for (size_t i = 0; i < p_elements; i++) {
|
for (size_t i = 0; i < p_elements; i++) {
|
||||||
new ("", &elems[i], sizeof(T), p_descr) T;
|
new (&elems[i], sizeof(T), p_descr) T;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -268,8 +268,8 @@ MethodBind *create_vararg_method_bind(R (T::*p_method)(const Variant **, GDExten
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef TYPED_METHOD_BIND
|
#ifndef TYPED_METHOD_BIND
|
||||||
class _gde_UnexistingClass;
|
class ___UnexistingClass;
|
||||||
#define MB_T _gde_UnexistingClass
|
#define MB_T ___UnexistingClass
|
||||||
#else
|
#else
|
||||||
#define MB_T T
|
#define MB_T T
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -33,7 +33,6 @@
|
|||||||
|
|
||||||
#include <godot_cpp/core/defs.hpp>
|
#include <godot_cpp/core/defs.hpp>
|
||||||
|
|
||||||
#include <godot_cpp/core/object.hpp>
|
|
||||||
#include <godot_cpp/godot.hpp>
|
#include <godot_cpp/godot.hpp>
|
||||||
#include <godot_cpp/variant/variant.hpp>
|
#include <godot_cpp/variant/variant.hpp>
|
||||||
|
|
||||||
@@ -168,9 +167,8 @@ MAKE_PTRARG_BY_REFERENCE(Variant);
|
|||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
struct PtrToArg<T *> {
|
struct PtrToArg<T *> {
|
||||||
static_assert(std::is_base_of<Object, T>::value, "Cannot encode non-Object value as an Object");
|
|
||||||
_FORCE_INLINE_ static T *convert(const void *p_ptr) {
|
_FORCE_INLINE_ static T *convert(const void *p_ptr) {
|
||||||
return reinterpret_cast<T *>(godot::internal::get_object_instance_binding(*reinterpret_cast<GDExtensionObjectPtr *>(const_cast<void *>(p_ptr))));
|
return reinterpret_cast<T *>(godot::internal::gde_interface->object_get_instance_binding(*reinterpret_cast<GDExtensionObjectPtr *>(const_cast<void *>(p_ptr)), godot::internal::token, &T::___binding_callbacks));
|
||||||
}
|
}
|
||||||
typedef Object *EncodeT;
|
typedef Object *EncodeT;
|
||||||
_FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) {
|
_FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) {
|
||||||
@@ -180,9 +178,8 @@ struct PtrToArg<T *> {
|
|||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
struct PtrToArg<const T *> {
|
struct PtrToArg<const T *> {
|
||||||
static_assert(std::is_base_of<Object, T>::value, "Cannot encode non-Object value as an Object");
|
|
||||||
_FORCE_INLINE_ static const T *convert(const void *p_ptr) {
|
_FORCE_INLINE_ static const T *convert(const void *p_ptr) {
|
||||||
return reinterpret_cast<const T *>(godot::internal::get_object_instance_binding(*reinterpret_cast<GDExtensionObjectPtr *>(const_cast<void *>(p_ptr))));
|
return reinterpret_cast<const T *>(godot::internal::gde_interface->object_get_instance_binding(*reinterpret_cast<GDExtensionObjectPtr *>(const_cast<void *>(p_ptr)), godot::internal::token, &T::___binding_callbacks));
|
||||||
}
|
}
|
||||||
typedef const Object *EncodeT;
|
typedef const Object *EncodeT;
|
||||||
_FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) {
|
_FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) {
|
||||||
|
|||||||
@@ -33,8 +33,6 @@
|
|||||||
|
|
||||||
#include <godot_cpp/core/defs.hpp>
|
#include <godot_cpp/core/defs.hpp>
|
||||||
|
|
||||||
#include <godot_cpp/core/object_id.hpp>
|
|
||||||
|
|
||||||
#include <godot_cpp/core/property_info.hpp>
|
#include <godot_cpp/core/property_info.hpp>
|
||||||
|
|
||||||
#include <godot_cpp/variant/variant.hpp>
|
#include <godot_cpp/variant/variant.hpp>
|
||||||
@@ -51,16 +49,9 @@
|
|||||||
#define ADD_GROUP(m_name, m_prefix) godot::ClassDB::add_property_group(get_class_static(), m_name, m_prefix)
|
#define ADD_GROUP(m_name, m_prefix) godot::ClassDB::add_property_group(get_class_static(), m_name, m_prefix)
|
||||||
#define ADD_SUBGROUP(m_name, m_prefix) godot::ClassDB::add_property_subgroup(get_class_static(), m_name, m_prefix)
|
#define ADD_SUBGROUP(m_name, m_prefix) godot::ClassDB::add_property_subgroup(get_class_static(), m_name, m_prefix)
|
||||||
#define ADD_PROPERTY(m_property, m_setter, m_getter) godot::ClassDB::add_property(get_class_static(), m_property, m_setter, m_getter)
|
#define ADD_PROPERTY(m_property, m_setter, m_getter) godot::ClassDB::add_property(get_class_static(), m_property, m_setter, m_getter)
|
||||||
#define ADD_PROPERTYI(m_property, m_setter, m_getter, m_index) godot::ClassDB::add_property(get_class_static(), m_property, m_setter, m_getter, m_index)
|
|
||||||
|
|
||||||
namespace godot {
|
namespace godot {
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
Object *get_object_instance_binding(GodotObject *);
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
struct MethodInfo {
|
struct MethodInfo {
|
||||||
StringName name;
|
StringName name;
|
||||||
PropertyInfo return_val;
|
PropertyInfo return_val;
|
||||||
@@ -108,14 +99,36 @@ MethodInfo::MethodInfo(const PropertyInfo &p_ret, StringName p_name, const Args
|
|||||||
arguments = { args... };
|
arguments = { args... };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ObjectID {
|
||||||
|
uint64_t id = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
_FORCE_INLINE_ bool is_ref_counted() const { return (id & (uint64_t(1) << 63)) != 0; }
|
||||||
|
_FORCE_INLINE_ bool is_valid() const { return id != 0; }
|
||||||
|
_FORCE_INLINE_ bool is_null() const { return id == 0; }
|
||||||
|
_FORCE_INLINE_ operator uint64_t() const { return id; }
|
||||||
|
_FORCE_INLINE_ operator int64_t() const { return id; }
|
||||||
|
|
||||||
|
_FORCE_INLINE_ bool operator==(const ObjectID &p_id) const { return id == p_id.id; }
|
||||||
|
_FORCE_INLINE_ bool operator!=(const ObjectID &p_id) const { return id != p_id.id; }
|
||||||
|
_FORCE_INLINE_ bool operator<(const ObjectID &p_id) const { return id < p_id.id; }
|
||||||
|
|
||||||
|
_FORCE_INLINE_ void operator=(int64_t p_int64) { id = p_int64; }
|
||||||
|
_FORCE_INLINE_ void operator=(uint64_t p_uint64) { id = p_uint64; }
|
||||||
|
|
||||||
|
_FORCE_INLINE_ ObjectID() {}
|
||||||
|
_FORCE_INLINE_ explicit ObjectID(const uint64_t p_id) { id = p_id; }
|
||||||
|
_FORCE_INLINE_ explicit ObjectID(const int64_t p_id) { id = p_id; }
|
||||||
|
};
|
||||||
|
|
||||||
class ObjectDB {
|
class ObjectDB {
|
||||||
public:
|
public:
|
||||||
static Object *get_instance(uint64_t p_object_id) {
|
static Object *get_instance(uint64_t p_object_id) {
|
||||||
GDExtensionObjectPtr obj = internal::gdextension_interface_object_get_instance_from_id(p_object_id);
|
GDExtensionObjectPtr obj = internal::gde_interface->object_get_instance_from_id(p_object_id);
|
||||||
if (obj == nullptr) {
|
if (obj == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return internal::get_object_instance_binding(obj);
|
return reinterpret_cast<Object *>(internal::gde_interface->object_get_instance_binding(obj, internal::token, &Object::___binding_callbacks));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -125,11 +138,11 @@ T *Object::cast_to(Object *p_object) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
StringName class_name = T::get_class_static();
|
StringName class_name = T::get_class_static();
|
||||||
GDExtensionObjectPtr casted = internal::gdextension_interface_object_cast_to(p_object->_owner, internal::gdextension_interface_classdb_get_class_tag(class_name._native_ptr()));
|
GDExtensionObjectPtr casted = internal::gde_interface->object_cast_to(p_object->_owner, internal::gde_interface->classdb_get_class_tag(class_name._native_ptr()));
|
||||||
if (casted == nullptr) {
|
if (casted == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return dynamic_cast<T *>(internal::get_object_instance_binding(casted));
|
return reinterpret_cast<T *>(internal::gde_interface->object_get_instance_binding(casted, internal::token, &T::___binding_callbacks));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
@@ -138,11 +151,11 @@ const T *Object::cast_to(const Object *p_object) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
StringName class_name = T::get_class_static();
|
StringName class_name = T::get_class_static();
|
||||||
GDExtensionObjectPtr casted = internal::gdextension_interface_object_cast_to(p_object->_owner, internal::gdextension_interface_classdb_get_class_tag(class_name._native_ptr()));
|
GDExtensionObjectPtr casted = internal::gde_interface->object_cast_to(p_object->_owner, internal::gde_interface->classdb_get_class_tag(class_name._native_ptr()));
|
||||||
if (casted == nullptr) {
|
if (casted == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return dynamic_cast<const T *>(internal::get_object_instance_binding(casted));
|
return reinterpret_cast<const T *>(internal::gde_interface->object_get_instance_binding(casted, internal::token, &T::___binding_callbacks));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace godot
|
} // namespace godot
|
||||||
|
|||||||
@@ -1,62 +0,0 @@
|
|||||||
/**************************************************************************/
|
|
||||||
/* object_id.hpp */
|
|
||||||
/**************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/**************************************************************************/
|
|
||||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
|
||||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* */
|
|
||||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
|
||||||
/* a copy of this software and associated documentation files (the */
|
|
||||||
/* "Software"), to deal in the Software without restriction, including */
|
|
||||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
|
||||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
|
||||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
|
||||||
/* the following conditions: */
|
|
||||||
/* */
|
|
||||||
/* The above copyright notice and this permission notice shall be */
|
|
||||||
/* included in all copies or substantial portions of the Software. */
|
|
||||||
/* */
|
|
||||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
|
||||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
|
||||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
|
||||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
|
||||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
|
||||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
|
||||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|
||||||
/**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef GODOT_OBJECT_ID_HPP
|
|
||||||
#define GODOT_OBJECT_ID_HPP
|
|
||||||
|
|
||||||
#include <godot_cpp/core/defs.hpp>
|
|
||||||
|
|
||||||
namespace godot {
|
|
||||||
|
|
||||||
class ObjectID {
|
|
||||||
uint64_t id = 0;
|
|
||||||
|
|
||||||
public:
|
|
||||||
_FORCE_INLINE_ bool is_ref_counted() const { return (id & (uint64_t(1) << 63)) != 0; }
|
|
||||||
_FORCE_INLINE_ bool is_valid() const { return id != 0; }
|
|
||||||
_FORCE_INLINE_ bool is_null() const { return id == 0; }
|
|
||||||
_FORCE_INLINE_ operator uint64_t() const { return id; }
|
|
||||||
_FORCE_INLINE_ operator int64_t() const { return id; }
|
|
||||||
|
|
||||||
_FORCE_INLINE_ bool operator==(const ObjectID &p_id) const { return id == p_id.id; }
|
|
||||||
_FORCE_INLINE_ bool operator!=(const ObjectID &p_id) const { return id != p_id.id; }
|
|
||||||
_FORCE_INLINE_ bool operator<(const ObjectID &p_id) const { return id < p_id.id; }
|
|
||||||
|
|
||||||
_FORCE_INLINE_ void operator=(int64_t p_int64) { id = p_int64; }
|
|
||||||
_FORCE_INLINE_ void operator=(uint64_t p_uint64) { id = p_uint64; }
|
|
||||||
|
|
||||||
_FORCE_INLINE_ ObjectID() {}
|
|
||||||
_FORCE_INLINE_ explicit ObjectID(const uint64_t p_id) { id = p_id; }
|
|
||||||
_FORCE_INLINE_ explicit ObjectID(const int64_t p_id) { id = p_id; }
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace godot
|
|
||||||
|
|
||||||
#endif // GODOT_OBJECT_ID_HPP
|
|
||||||
@@ -68,18 +68,6 @@ struct PropertyInfo {
|
|||||||
|
|
||||||
PropertyInfo(GDExtensionVariantType p_type, const StringName &p_name, PropertyHint p_hint = PROPERTY_HINT_NONE, const String &p_hint_string = "", uint32_t p_usage = PROPERTY_USAGE_DEFAULT, const StringName &p_class_name = "") :
|
PropertyInfo(GDExtensionVariantType p_type, const StringName &p_name, PropertyHint p_hint = PROPERTY_HINT_NONE, const String &p_hint_string = "", uint32_t p_usage = PROPERTY_USAGE_DEFAULT, const StringName &p_class_name = "") :
|
||||||
PropertyInfo((Variant::Type)p_type, p_name, p_hint, p_hint_string, p_usage, p_class_name) {}
|
PropertyInfo((Variant::Type)p_type, p_name, p_hint, p_hint_string, p_usage, p_class_name) {}
|
||||||
|
|
||||||
PropertyInfo(const GDExtensionPropertyInfo *p_info) :
|
|
||||||
PropertyInfo(p_info->type, *reinterpret_cast<StringName *>(p_info->name), (PropertyHint)p_info->hint, *reinterpret_cast<String *>(p_info->hint_string), p_info->usage, *reinterpret_cast<StringName *>(p_info->class_name)) {}
|
|
||||||
|
|
||||||
void _update(GDExtensionPropertyInfo *p_info) {
|
|
||||||
p_info->type = (GDExtensionVariantType)type;
|
|
||||||
*(reinterpret_cast<StringName *>(p_info->name)) = name;
|
|
||||||
p_info->hint = hint;
|
|
||||||
*(reinterpret_cast<String *>(p_info->hint_string)) = hint_string;
|
|
||||||
p_info->usage = usage;
|
|
||||||
*(reinterpret_cast<StringName *>(p_info->class_name)) = class_name;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace godot
|
} // namespace godot
|
||||||
|
|||||||
@@ -241,7 +241,7 @@ inline String enum_qualified_name_to_class_info_name(const String &p_qualified_n
|
|||||||
TEMPL_MAKE_ENUM_TYPE_INFO(m_enum, const m_enum &)
|
TEMPL_MAKE_ENUM_TYPE_INFO(m_enum, const m_enum &)
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline StringName _gde_constant_get_enum_name(T param, StringName p_constant) {
|
inline StringName __constant_get_enum_name(T param, StringName p_constant) {
|
||||||
if (GetTypeInfo<T>::VARIANT_TYPE == Variant::NIL) {
|
if (GetTypeInfo<T>::VARIANT_TYPE == Variant::NIL) {
|
||||||
ERR_PRINT(("Missing VARIANT_ENUM_CAST for constant's enum: " + String(p_constant)).utf8().get_data());
|
ERR_PRINT(("Missing VARIANT_ENUM_CAST for constant's enum: " + String(p_constant)).utf8().get_data());
|
||||||
}
|
}
|
||||||
@@ -288,7 +288,7 @@ public:
|
|||||||
TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, const m_enum &)
|
TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, const m_enum &)
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline StringName _gde_constant_get_bitfield_name(T param, StringName p_constant) {
|
inline StringName __constant_get_bitfield_name(T param, StringName p_constant) {
|
||||||
if (GetTypeInfo<T>::VARIANT_TYPE == Variant::NIL) {
|
if (GetTypeInfo<T>::VARIANT_TYPE == Variant::NIL) {
|
||||||
ERR_PRINT(("Missing VARIANT_ENUM_CAST for constant's bitfield: " + String(p_constant)).utf8().get_data());
|
ERR_PRINT(("Missing VARIANT_ENUM_CAST for constant's bitfield: " + String(p_constant)).utf8().get_data());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,204 +37,42 @@ namespace godot {
|
|||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
extern "C" GDExtensionInterfaceGetProcAddress gdextension_interface_get_proc_address;
|
extern "C" const GDExtensionInterface *gde_interface;
|
||||||
extern "C" GDExtensionClassLibraryPtr library;
|
extern "C" GDExtensionClassLibraryPtr library;
|
||||||
extern "C" void *token;
|
extern "C" void *token;
|
||||||
|
|
||||||
extern "C" GDExtensionGodotVersion godot_version;
|
|
||||||
|
|
||||||
// All of the GDExtension interface functions.
|
|
||||||
extern "C" GDExtensionInterfaceGetGodotVersion gdextension_interface_get_godot_version;
|
|
||||||
extern "C" GDExtensionInterfaceMemAlloc gdextension_interface_mem_alloc;
|
|
||||||
extern "C" GDExtensionInterfaceMemRealloc gdextension_interface_mem_realloc;
|
|
||||||
extern "C" GDExtensionInterfaceMemFree gdextension_interface_mem_free;
|
|
||||||
extern "C" GDExtensionInterfacePrintError gdextension_interface_print_error;
|
|
||||||
extern "C" GDExtensionInterfacePrintErrorWithMessage gdextension_interface_print_error_with_message;
|
|
||||||
extern "C" GDExtensionInterfacePrintWarning gdextension_interface_print_warning;
|
|
||||||
extern "C" GDExtensionInterfacePrintWarningWithMessage gdextension_interface_print_warning_with_message;
|
|
||||||
extern "C" GDExtensionInterfacePrintScriptError gdextension_interface_print_script_error;
|
|
||||||
extern "C" GDExtensionInterfacePrintScriptErrorWithMessage gdextension_interface_print_script_error_with_message;
|
|
||||||
extern "C" GDExtensionInterfaceGetNativeStructSize gdextension_interface_get_native_struct_size;
|
|
||||||
extern "C" GDExtensionInterfaceVariantNewCopy gdextension_interface_variant_new_copy;
|
|
||||||
extern "C" GDExtensionInterfaceVariantNewNil gdextension_interface_variant_new_nil;
|
|
||||||
extern "C" GDExtensionInterfaceVariantDestroy gdextension_interface_variant_destroy;
|
|
||||||
extern "C" GDExtensionInterfaceVariantCall gdextension_interface_variant_call;
|
|
||||||
extern "C" GDExtensionInterfaceVariantCallStatic gdextension_interface_variant_call_static;
|
|
||||||
extern "C" GDExtensionInterfaceVariantEvaluate gdextension_interface_variant_evaluate;
|
|
||||||
extern "C" GDExtensionInterfaceVariantSet gdextension_interface_variant_set;
|
|
||||||
extern "C" GDExtensionInterfaceVariantSetNamed gdextension_interface_variant_set_named;
|
|
||||||
extern "C" GDExtensionInterfaceVariantSetKeyed gdextension_interface_variant_set_keyed;
|
|
||||||
extern "C" GDExtensionInterfaceVariantSetIndexed gdextension_interface_variant_set_indexed;
|
|
||||||
extern "C" GDExtensionInterfaceVariantGet gdextension_interface_variant_get;
|
|
||||||
extern "C" GDExtensionInterfaceVariantGetNamed gdextension_interface_variant_get_named;
|
|
||||||
extern "C" GDExtensionInterfaceVariantGetKeyed gdextension_interface_variant_get_keyed;
|
|
||||||
extern "C" GDExtensionInterfaceVariantGetIndexed gdextension_interface_variant_get_indexed;
|
|
||||||
extern "C" GDExtensionInterfaceVariantIterInit gdextension_interface_variant_iter_init;
|
|
||||||
extern "C" GDExtensionInterfaceVariantIterNext gdextension_interface_variant_iter_next;
|
|
||||||
extern "C" GDExtensionInterfaceVariantIterGet gdextension_interface_variant_iter_get;
|
|
||||||
extern "C" GDExtensionInterfaceVariantHash gdextension_interface_variant_hash;
|
|
||||||
extern "C" GDExtensionInterfaceVariantRecursiveHash gdextension_interface_variant_recursive_hash;
|
|
||||||
extern "C" GDExtensionInterfaceVariantHashCompare gdextension_interface_variant_hash_compare;
|
|
||||||
extern "C" GDExtensionInterfaceVariantBooleanize gdextension_interface_variant_booleanize;
|
|
||||||
extern "C" GDExtensionInterfaceVariantDuplicate gdextension_interface_variant_duplicate;
|
|
||||||
extern "C" GDExtensionInterfaceVariantStringify gdextension_interface_variant_stringify;
|
|
||||||
extern "C" GDExtensionInterfaceVariantGetType gdextension_interface_variant_get_type;
|
|
||||||
extern "C" GDExtensionInterfaceVariantHasMethod gdextension_interface_variant_has_method;
|
|
||||||
extern "C" GDExtensionInterfaceVariantHasMember gdextension_interface_variant_has_member;
|
|
||||||
extern "C" GDExtensionInterfaceVariantHasKey gdextension_interface_variant_has_key;
|
|
||||||
extern "C" GDExtensionInterfaceVariantGetTypeName gdextension_interface_variant_get_type_name;
|
|
||||||
extern "C" GDExtensionInterfaceVariantCanConvert gdextension_interface_variant_can_convert;
|
|
||||||
extern "C" GDExtensionInterfaceVariantCanConvertStrict gdextension_interface_variant_can_convert_strict;
|
|
||||||
extern "C" GDExtensionInterfaceGetVariantFromTypeConstructor gdextension_interface_get_variant_from_type_constructor;
|
|
||||||
extern "C" GDExtensionInterfaceGetVariantToTypeConstructor gdextension_interface_get_variant_to_type_constructor;
|
|
||||||
extern "C" GDExtensionInterfaceVariantGetPtrOperatorEvaluator gdextension_interface_variant_get_ptr_operator_evaluator;
|
|
||||||
extern "C" GDExtensionInterfaceVariantGetPtrBuiltinMethod gdextension_interface_variant_get_ptr_builtin_method;
|
|
||||||
extern "C" GDExtensionInterfaceVariantGetPtrConstructor gdextension_interface_variant_get_ptr_constructor;
|
|
||||||
extern "C" GDExtensionInterfaceVariantGetPtrDestructor gdextension_interface_variant_get_ptr_destructor;
|
|
||||||
extern "C" GDExtensionInterfaceVariantConstruct gdextension_interface_variant_construct;
|
|
||||||
extern "C" GDExtensionInterfaceVariantGetPtrSetter gdextension_interface_variant_get_ptr_setter;
|
|
||||||
extern "C" GDExtensionInterfaceVariantGetPtrGetter gdextension_interface_variant_get_ptr_getter;
|
|
||||||
extern "C" GDExtensionInterfaceVariantGetPtrIndexedSetter gdextension_interface_variant_get_ptr_indexed_setter;
|
|
||||||
extern "C" GDExtensionInterfaceVariantGetPtrIndexedGetter gdextension_interface_variant_get_ptr_indexed_getter;
|
|
||||||
extern "C" GDExtensionInterfaceVariantGetPtrKeyedSetter gdextension_interface_variant_get_ptr_keyed_setter;
|
|
||||||
extern "C" GDExtensionInterfaceVariantGetPtrKeyedGetter gdextension_interface_variant_get_ptr_keyed_getter;
|
|
||||||
extern "C" GDExtensionInterfaceVariantGetPtrKeyedChecker gdextension_interface_variant_get_ptr_keyed_checker;
|
|
||||||
extern "C" GDExtensionInterfaceVariantGetConstantValue gdextension_interface_variant_get_constant_value;
|
|
||||||
extern "C" GDExtensionInterfaceVariantGetPtrUtilityFunction gdextension_interface_variant_get_ptr_utility_function;
|
|
||||||
extern "C" GDExtensionInterfaceStringNewWithLatin1Chars gdextension_interface_string_new_with_latin1_chars;
|
|
||||||
extern "C" GDExtensionInterfaceStringNewWithUtf8Chars gdextension_interface_string_new_with_utf8_chars;
|
|
||||||
extern "C" GDExtensionInterfaceStringNewWithUtf16Chars gdextension_interface_string_new_with_utf16_chars;
|
|
||||||
extern "C" GDExtensionInterfaceStringNewWithUtf32Chars gdextension_interface_string_new_with_utf32_chars;
|
|
||||||
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" GDExtensionInterfaceStringNewWithUtf16CharsAndLen gdextension_interface_string_new_with_utf16_chars_and_len;
|
|
||||||
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;
|
|
||||||
extern "C" GDExtensionInterfaceStringToUtf8Chars gdextension_interface_string_to_utf8_chars;
|
|
||||||
extern "C" GDExtensionInterfaceStringToUtf16Chars gdextension_interface_string_to_utf16_chars;
|
|
||||||
extern "C" GDExtensionInterfaceStringToUtf32Chars gdextension_interface_string_to_utf32_chars;
|
|
||||||
extern "C" GDExtensionInterfaceStringToWideChars gdextension_interface_string_to_wide_chars;
|
|
||||||
extern "C" GDExtensionInterfaceStringOperatorIndex gdextension_interface_string_operator_index;
|
|
||||||
extern "C" GDExtensionInterfaceStringOperatorIndexConst gdextension_interface_string_operator_index_const;
|
|
||||||
extern "C" GDExtensionInterfaceStringOperatorPlusEqString gdextension_interface_string_operator_plus_eq_string;
|
|
||||||
extern "C" GDExtensionInterfaceStringOperatorPlusEqChar gdextension_interface_string_operator_plus_eq_char;
|
|
||||||
extern "C" GDExtensionInterfaceStringOperatorPlusEqCstr gdextension_interface_string_operator_plus_eq_cstr;
|
|
||||||
extern "C" GDExtensionInterfaceStringOperatorPlusEqWcstr gdextension_interface_string_operator_plus_eq_wcstr;
|
|
||||||
extern "C" GDExtensionInterfaceStringOperatorPlusEqC32str gdextension_interface_string_operator_plus_eq_c32str;
|
|
||||||
extern "C" GDExtensionInterfaceStringResize gdextension_interface_string_resize;
|
|
||||||
extern "C" GDExtensionInterfaceStringNameNewWithLatin1Chars gdextension_interface_string_name_new_with_latin1_chars;
|
|
||||||
extern "C" GDExtensionInterfaceXmlParserOpenBuffer gdextension_interface_xml_parser_open_buffer;
|
|
||||||
extern "C" GDExtensionInterfaceFileAccessStoreBuffer gdextension_interface_file_access_store_buffer;
|
|
||||||
extern "C" GDExtensionInterfaceFileAccessGetBuffer gdextension_interface_file_access_get_buffer;
|
|
||||||
extern "C" GDExtensionInterfaceWorkerThreadPoolAddNativeGroupTask gdextension_interface_worker_thread_pool_add_native_group_task;
|
|
||||||
extern "C" GDExtensionInterfaceWorkerThreadPoolAddNativeTask gdextension_interface_worker_thread_pool_add_native_task;
|
|
||||||
extern "C" GDExtensionInterfacePackedByteArrayOperatorIndex gdextension_interface_packed_byte_array_operator_index;
|
|
||||||
extern "C" GDExtensionInterfacePackedByteArrayOperatorIndexConst gdextension_interface_packed_byte_array_operator_index_const;
|
|
||||||
extern "C" GDExtensionInterfacePackedColorArrayOperatorIndex gdextension_interface_packed_color_array_operator_index;
|
|
||||||
extern "C" GDExtensionInterfacePackedColorArrayOperatorIndexConst gdextension_interface_packed_color_array_operator_index_const;
|
|
||||||
extern "C" GDExtensionInterfacePackedFloat32ArrayOperatorIndex gdextension_interface_packed_float32_array_operator_index;
|
|
||||||
extern "C" GDExtensionInterfacePackedFloat32ArrayOperatorIndexConst gdextension_interface_packed_float32_array_operator_index_const;
|
|
||||||
extern "C" GDExtensionInterfacePackedFloat64ArrayOperatorIndex gdextension_interface_packed_float64_array_operator_index;
|
|
||||||
extern "C" GDExtensionInterfacePackedFloat64ArrayOperatorIndexConst gdextension_interface_packed_float64_array_operator_index_const;
|
|
||||||
extern "C" GDExtensionInterfacePackedInt32ArrayOperatorIndex gdextension_interface_packed_int32_array_operator_index;
|
|
||||||
extern "C" GDExtensionInterfacePackedInt32ArrayOperatorIndexConst gdextension_interface_packed_int32_array_operator_index_const;
|
|
||||||
extern "C" GDExtensionInterfacePackedInt64ArrayOperatorIndex gdextension_interface_packed_int64_array_operator_index;
|
|
||||||
extern "C" GDExtensionInterfacePackedInt64ArrayOperatorIndexConst gdextension_interface_packed_int64_array_operator_index_const;
|
|
||||||
extern "C" GDExtensionInterfacePackedStringArrayOperatorIndex gdextension_interface_packed_string_array_operator_index;
|
|
||||||
extern "C" GDExtensionInterfacePackedStringArrayOperatorIndexConst gdextension_interface_packed_string_array_operator_index_const;
|
|
||||||
extern "C" GDExtensionInterfacePackedVector2ArrayOperatorIndex gdextension_interface_packed_vector2_array_operator_index;
|
|
||||||
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" GDExtensionInterfaceArrayOperatorIndex gdextension_interface_array_operator_index;
|
|
||||||
extern "C" GDExtensionInterfaceArrayOperatorIndexConst gdextension_interface_array_operator_index_const;
|
|
||||||
extern "C" GDExtensionInterfaceArrayRef gdextension_interface_array_ref;
|
|
||||||
extern "C" GDExtensionInterfaceArraySetTyped gdextension_interface_array_set_typed;
|
|
||||||
extern "C" GDExtensionInterfaceDictionaryOperatorIndex gdextension_interface_dictionary_operator_index;
|
|
||||||
extern "C" GDExtensionInterfaceDictionaryOperatorIndexConst gdextension_interface_dictionary_operator_index_const;
|
|
||||||
extern "C" GDExtensionInterfaceObjectMethodBindCall gdextension_interface_object_method_bind_call;
|
|
||||||
extern "C" GDExtensionInterfaceObjectMethodBindPtrcall gdextension_interface_object_method_bind_ptrcall;
|
|
||||||
extern "C" GDExtensionInterfaceObjectDestroy gdextension_interface_object_destroy;
|
|
||||||
extern "C" GDExtensionInterfaceGlobalGetSingleton gdextension_interface_global_get_singleton;
|
|
||||||
extern "C" GDExtensionInterfaceObjectGetInstanceBinding gdextension_interface_object_get_instance_binding;
|
|
||||||
extern "C" GDExtensionInterfaceObjectSetInstanceBinding gdextension_interface_object_set_instance_binding;
|
|
||||||
extern "C" GDExtensionInterfaceObjectSetInstance gdextension_interface_object_set_instance;
|
|
||||||
extern "C" GDExtensionInterfaceObjectGetClassName gdextension_interface_object_get_class_name;
|
|
||||||
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" 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" 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" GDExtensionInterfaceClassdbRegisterExtensionClass2 gdextension_interface_classdb_register_extension_class2;
|
|
||||||
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassMethod gdextension_interface_classdb_register_extension_class_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;
|
|
||||||
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassPropertyGroup gdextension_interface_classdb_register_extension_class_property_group;
|
|
||||||
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassPropertySubgroup gdextension_interface_classdb_register_extension_class_property_subgroup;
|
|
||||||
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassSignal gdextension_interface_classdb_register_extension_class_signal;
|
|
||||||
extern "C" GDExtensionInterfaceClassdbUnregisterExtensionClass gdextension_interface_classdb_unregister_extension_class;
|
|
||||||
extern "C" GDExtensionInterfaceGetLibraryPath gdextension_interface_get_library_path;
|
|
||||||
extern "C" GDExtensionInterfaceEditorAddPlugin gdextension_interface_editor_add_plugin;
|
|
||||||
extern "C" GDExtensionInterfaceEditorRemovePlugin gdextension_interface_editor_remove_plugin;
|
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
enum ModuleInitializationLevel {
|
enum ModuleInitializationLevel {
|
||||||
MODULE_INITIALIZATION_LEVEL_CORE = GDEXTENSION_INITIALIZATION_CORE,
|
MODULE_INITIALIZATION_LEVEL_CORE = GDEXTENSION_INITIALIZATION_CORE,
|
||||||
MODULE_INITIALIZATION_LEVEL_SERVERS = GDEXTENSION_INITIALIZATION_SERVERS,
|
MODULE_INITIALIZATION_LEVEL_SERVERS = GDEXTENSION_INITIALIZATION_SERVERS,
|
||||||
MODULE_INITIALIZATION_LEVEL_SCENE = GDEXTENSION_INITIALIZATION_SCENE,
|
MODULE_INITIALIZATION_LEVEL_SCENE = GDEXTENSION_INITIALIZATION_SCENE,
|
||||||
MODULE_INITIALIZATION_LEVEL_EDITOR = GDEXTENSION_INITIALIZATION_EDITOR,
|
MODULE_INITIALIZATION_LEVEL_EDITOR = GDEXTENSION_INITIALIZATION_EDITOR
|
||||||
MODULE_INITIALIZATION_LEVEL_MAX
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class GDExtensionBinding {
|
class GDExtensionBinding {
|
||||||
public:
|
public:
|
||||||
using Callback = void (*)(ModuleInitializationLevel p_level);
|
using Callback = void (*)(ModuleInitializationLevel p_level);
|
||||||
|
|
||||||
struct InitData {
|
static Callback init_callback;
|
||||||
GDExtensionInitializationLevel minimum_initialization_level = GDEXTENSION_INITIALIZATION_CORE;
|
static Callback terminate_callback;
|
||||||
Callback init_callback = nullptr;
|
static GDExtensionInitializationLevel minimum_initialization_level;
|
||||||
Callback terminate_callback = nullptr;
|
static GDExtensionBool init(const GDExtensionInterface *p_interface, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization);
|
||||||
};
|
|
||||||
|
|
||||||
class InitDataList {
|
|
||||||
int data_count = 0;
|
|
||||||
int data_capacity = 0;
|
|
||||||
InitData **data = nullptr;
|
|
||||||
|
|
||||||
public:
|
|
||||||
void add(InitData *p_cb);
|
|
||||||
~InitDataList();
|
|
||||||
};
|
|
||||||
|
|
||||||
static bool api_initialized;
|
|
||||||
static int level_initialized[MODULE_INITIALIZATION_LEVEL_MAX];
|
|
||||||
static InitDataList initdata;
|
|
||||||
static GDExtensionBool init(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, InitData *p_init_data, GDExtensionInitialization *r_initialization);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void initialize_level(void *p_userdata, GDExtensionInitializationLevel p_level);
|
static void initialize_level(void *userdata, GDExtensionInitializationLevel p_level);
|
||||||
static void deinitialize_level(void *p_userdata, GDExtensionInitializationLevel p_level);
|
static void deinitialize_level(void *userdata, GDExtensionInitializationLevel p_level);
|
||||||
|
|
||||||
class InitObject {
|
class InitObject {
|
||||||
GDExtensionInterfaceGetProcAddress get_proc_address;
|
const GDExtensionInterface *gde_interface;
|
||||||
GDExtensionClassLibraryPtr library;
|
GDExtensionClassLibraryPtr library;
|
||||||
GDExtensionInitialization *initialization;
|
GDExtensionInitialization *initialization;
|
||||||
mutable InitData *init_data = nullptr;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
InitObject(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization);
|
InitObject(const GDExtensionInterface *p_interface, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) :
|
||||||
|
gde_interface(p_interface),
|
||||||
|
library(p_library),
|
||||||
|
initialization(r_initialization) {}
|
||||||
|
|
||||||
void register_initializer(Callback p_init) const;
|
void register_initializer(Callback p_init) const;
|
||||||
void register_terminator(Callback p_init) const;
|
void register_terminator(Callback p_init) const;
|
||||||
|
|||||||
@@ -32,14 +32,13 @@
|
|||||||
#define GODOT_COWDATA_HPP
|
#define GODOT_COWDATA_HPP
|
||||||
|
|
||||||
#include <godot_cpp/classes/global_constants.hpp>
|
#include <godot_cpp/classes/global_constants.hpp>
|
||||||
|
#include <godot_cpp/core/class_db.hpp>
|
||||||
#include <godot_cpp/core/error_macros.hpp>
|
#include <godot_cpp/core/error_macros.hpp>
|
||||||
#include <godot_cpp/core/math.hpp>
|
#include <godot_cpp/core/math.hpp>
|
||||||
#include <godot_cpp/core/memory.hpp>
|
#include <godot_cpp/core/memory.hpp>
|
||||||
#include <godot_cpp/templates/safe_refcount.hpp>
|
#include <godot_cpp/templates/safe_refcount.hpp>
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <new>
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
namespace godot {
|
namespace godot {
|
||||||
|
|
||||||
@@ -49,9 +48,6 @@ class Vector;
|
|||||||
template <class T, class V>
|
template <class T, class V>
|
||||||
class VMap;
|
class VMap;
|
||||||
|
|
||||||
template <class T>
|
|
||||||
class CharStringT;
|
|
||||||
|
|
||||||
// Silence a false positive warning (see GH-52119).
|
// Silence a false positive warning (see GH-52119).
|
||||||
#if defined(__GNUC__) && !defined(__clang__)
|
#if defined(__GNUC__) && !defined(__clang__)
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
@@ -66,9 +62,6 @@ class CowData {
|
|||||||
template <class TV, class VV>
|
template <class TV, class VV>
|
||||||
friend class VMap;
|
friend class VMap;
|
||||||
|
|
||||||
template <class TS>
|
|
||||||
friend class CharStringT;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable T *_ptr = nullptr;
|
mutable T *_ptr = nullptr;
|
||||||
|
|
||||||
@@ -102,10 +95,6 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
_FORCE_INLINE_ bool _get_alloc_size_checked(size_t p_elements, size_t *out) const {
|
_FORCE_INLINE_ bool _get_alloc_size_checked(size_t p_elements, size_t *out) const {
|
||||||
if (unlikely(p_elements == 0)) {
|
|
||||||
*out = 0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
size_t o;
|
size_t o;
|
||||||
size_t p;
|
size_t p;
|
||||||
@@ -117,12 +106,13 @@ private:
|
|||||||
if (__builtin_add_overflow(o, static_cast<size_t>(32), &p)) {
|
if (__builtin_add_overflow(o, static_cast<size_t>(32), &p)) {
|
||||||
return false; // No longer allocated here.
|
return false; // No longer allocated here.
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
#else
|
#else
|
||||||
// Speed is more important than correctness here, do the operations unchecked
|
// Speed is more important than correctness here, do the operations unchecked
|
||||||
// and hope for the best.
|
// and hope for the best.
|
||||||
*out = _get_alloc_size(p_elements);
|
*out = _get_alloc_size(p_elements);
|
||||||
|
return true;
|
||||||
#endif
|
#endif
|
||||||
return *out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _unref(void *p_data);
|
void _unref(void *p_data);
|
||||||
@@ -214,9 +204,9 @@ void CowData<T>::_unref(void *p_data) {
|
|||||||
if (refc->decrement() > 0) {
|
if (refc->decrement() > 0) {
|
||||||
return; // still in use
|
return; // still in use
|
||||||
}
|
}
|
||||||
|
|
||||||
// clean up
|
// clean up
|
||||||
if (!std::is_trivially_destructible<T>::value) {
|
|
||||||
|
if (!__has_trivial_destructor(T)) {
|
||||||
uint32_t *count = _get_size();
|
uint32_t *count = _get_size();
|
||||||
T *data = (T *)(count + 1);
|
T *data = (T *)(count + 1);
|
||||||
|
|
||||||
@@ -251,7 +241,7 @@ uint32_t CowData<T>::_copy_on_write() {
|
|||||||
T *_data = (T *)(mem_new);
|
T *_data = (T *)(mem_new);
|
||||||
|
|
||||||
// initialize new elements
|
// initialize new elements
|
||||||
if (std::is_trivially_copyable<T>::value) {
|
if (__has_trivial_copy(T)) {
|
||||||
memcpy(mem_new, _ptr, current_size * sizeof(T));
|
memcpy(mem_new, _ptr, current_size * sizeof(T));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -297,7 +287,7 @@ Error CowData<T>::resize(int p_size) {
|
|||||||
if (current_size == 0) {
|
if (current_size == 0) {
|
||||||
// alloc from scratch
|
// alloc from scratch
|
||||||
uint32_t *ptr = (uint32_t *)Memory::alloc_static(alloc_size, true);
|
uint32_t *ptr = (uint32_t *)Memory::alloc_static(alloc_size, true);
|
||||||
ERR_FAIL_NULL_V(ptr, ERR_OUT_OF_MEMORY);
|
ERR_FAIL_COND_V(!ptr, ERR_OUT_OF_MEMORY);
|
||||||
*(ptr - 1) = 0; // size, currently none
|
*(ptr - 1) = 0; // size, currently none
|
||||||
new (ptr - 2) SafeNumeric<uint32_t>(1); // refcount
|
new (ptr - 2) SafeNumeric<uint32_t>(1); // refcount
|
||||||
|
|
||||||
@@ -305,7 +295,7 @@ Error CowData<T>::resize(int p_size) {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
uint32_t *_ptrnew = (uint32_t *)Memory::realloc_static(_ptr, alloc_size, true);
|
uint32_t *_ptrnew = (uint32_t *)Memory::realloc_static(_ptr, alloc_size, true);
|
||||||
ERR_FAIL_NULL_V(_ptrnew, ERR_OUT_OF_MEMORY);
|
ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY);
|
||||||
new (_ptrnew - 2) SafeNumeric<uint32_t>(rc); // refcount
|
new (_ptrnew - 2) SafeNumeric<uint32_t>(rc); // refcount
|
||||||
|
|
||||||
_ptr = (T *)(_ptrnew);
|
_ptr = (T *)(_ptrnew);
|
||||||
@@ -314,7 +304,7 @@ Error CowData<T>::resize(int p_size) {
|
|||||||
|
|
||||||
// construct the newly created elements
|
// construct the newly created elements
|
||||||
|
|
||||||
if (!std::is_trivially_constructible<T>::value) {
|
if (!__has_trivial_constructor(T)) {
|
||||||
T *elems = _get_data();
|
T *elems = _get_data();
|
||||||
|
|
||||||
for (int i = *_get_size(); i < p_size; i++) {
|
for (int i = *_get_size(); i < p_size; i++) {
|
||||||
@@ -325,7 +315,7 @@ Error CowData<T>::resize(int p_size) {
|
|||||||
*_get_size() = p_size;
|
*_get_size() = p_size;
|
||||||
|
|
||||||
} else if (p_size < current_size) {
|
} else if (p_size < current_size) {
|
||||||
if (!std::is_trivially_destructible<T>::value) {
|
if (!__has_trivial_destructor(T)) {
|
||||||
// deinitialize no longer needed elements
|
// deinitialize no longer needed elements
|
||||||
for (uint32_t i = p_size; i < *_get_size(); i++) {
|
for (uint32_t i = p_size; i < *_get_size(); i++) {
|
||||||
T *t = &_get_data()[i];
|
T *t = &_get_data()[i];
|
||||||
@@ -335,7 +325,7 @@ Error CowData<T>::resize(int p_size) {
|
|||||||
|
|
||||||
if (alloc_size != current_alloc_size) {
|
if (alloc_size != current_alloc_size) {
|
||||||
uint32_t *_ptrnew = (uint32_t *)Memory::realloc_static(_ptr, alloc_size, true);
|
uint32_t *_ptrnew = (uint32_t *)Memory::realloc_static(_ptr, alloc_size, true);
|
||||||
ERR_FAIL_NULL_V(_ptrnew, ERR_OUT_OF_MEMORY);
|
ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY);
|
||||||
new (_ptrnew - 2) SafeNumeric<uint32_t>(rc); // refcount
|
new (_ptrnew - 2) SafeNumeric<uint32_t>(rc); // refcount
|
||||||
|
|
||||||
_ptr = (T *)(_ptrnew);
|
_ptr = (T *)(_ptrnew);
|
||||||
|
|||||||
@@ -221,7 +221,7 @@ private:
|
|||||||
int size_cache = 0;
|
int size_cache = 0;
|
||||||
|
|
||||||
bool erase(const Element *p_I) {
|
bool erase(const Element *p_I) {
|
||||||
ERR_FAIL_NULL_V(p_I, false);
|
ERR_FAIL_COND_V(!p_I, false);
|
||||||
ERR_FAIL_COND_V(p_I->data != this, false);
|
ERR_FAIL_COND_V(p_I->data != this, false);
|
||||||
|
|
||||||
if (first == p_I) {
|
if (first == p_I) {
|
||||||
|
|||||||
@@ -186,12 +186,12 @@ public:
|
|||||||
}
|
}
|
||||||
void initialize_rid(RID p_rid) {
|
void initialize_rid(RID p_rid) {
|
||||||
T *mem = get_or_null(p_rid, true);
|
T *mem = get_or_null(p_rid, true);
|
||||||
ERR_FAIL_NULL(mem);
|
ERR_FAIL_COND(!mem);
|
||||||
memnew_placement(mem, T);
|
memnew_placement(mem, T);
|
||||||
}
|
}
|
||||||
void initialize_rid(RID p_rid, const T &p_value) {
|
void initialize_rid(RID p_rid, const T &p_value) {
|
||||||
T *mem = get_or_null(p_rid, true);
|
T *mem = get_or_null(p_rid, true);
|
||||||
ERR_FAIL_NULL(mem);
|
ERR_FAIL_COND(!mem);
|
||||||
memnew_placement(mem, T(p_value));
|
memnew_placement(mem, T(p_value));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -374,7 +374,7 @@ public:
|
|||||||
|
|
||||||
_FORCE_INLINE_ void replace(const RID &p_rid, T *p_new_ptr) {
|
_FORCE_INLINE_ void replace(const RID &p_rid, T *p_new_ptr) {
|
||||||
T **ptr = alloc.get_or_null(p_rid);
|
T **ptr = alloc.get_or_null(p_rid);
|
||||||
ERR_FAIL_NULL(ptr);
|
ERR_FAIL_COND(!ptr);
|
||||||
*ptr = p_new_ptr;
|
*ptr = p_new_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ class ThreadWorkPool {
|
|||||||
public:
|
public:
|
||||||
template <class C, class M, class U>
|
template <class C, class M, class U>
|
||||||
void begin_work(uint32_t p_elements, C *p_instance, M p_method, U p_userdata) {
|
void begin_work(uint32_t p_elements, C *p_instance, M p_method, U p_userdata) {
|
||||||
ERR_FAIL_NULL(threads); // Never initialized.
|
ERR_FAIL_COND(!threads); // never initialized
|
||||||
ERR_FAIL_COND(current_work != nullptr);
|
ERR_FAIL_COND(current_work != nullptr);
|
||||||
|
|
||||||
index.store(0, std::memory_order_release);
|
index.store(0, std::memory_order_release);
|
||||||
@@ -123,18 +123,18 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool is_done_dispatching() const {
|
bool is_done_dispatching() const {
|
||||||
ERR_FAIL_NULL_V(current_work, true);
|
ERR_FAIL_COND_V(current_work == nullptr, true);
|
||||||
return index.load(std::memory_order_acquire) >= current_work->max_elements;
|
return index.load(std::memory_order_acquire) >= current_work->max_elements;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t get_work_index() const {
|
uint32_t get_work_index() const {
|
||||||
ERR_FAIL_NULL_V(current_work, 0);
|
ERR_FAIL_COND_V(current_work == nullptr, 0);
|
||||||
uint32_t idx = index.load(std::memory_order_acquire);
|
uint32_t idx = index.load(std::memory_order_acquire);
|
||||||
return Math::min(idx, current_work->max_elements);
|
return Math::min(idx, current_work->max_elements);
|
||||||
}
|
}
|
||||||
|
|
||||||
void end_work() {
|
void end_work() {
|
||||||
ERR_FAIL_NULL(current_work);
|
ERR_FAIL_COND(current_work == nullptr);
|
||||||
for (uint32_t i = 0; i < threads_working; i++) {
|
for (uint32_t i = 0; i < threads_working; i++) {
|
||||||
threads[i].completed.wait();
|
threads[i].completed.wait();
|
||||||
threads[i].work = nullptr;
|
threads[i].work = nullptr;
|
||||||
|
|||||||
@@ -1,64 +0,0 @@
|
|||||||
/**************************************************************************/
|
|
||||||
/* callable_custom.hpp */
|
|
||||||
/**************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/**************************************************************************/
|
|
||||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
|
||||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* */
|
|
||||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
|
||||||
/* a copy of this software and associated documentation files (the */
|
|
||||||
/* "Software"), to deal in the Software without restriction, including */
|
|
||||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
|
||||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
|
||||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
|
||||||
/* the following conditions: */
|
|
||||||
/* */
|
|
||||||
/* The above copyright notice and this permission notice shall be */
|
|
||||||
/* included in all copies or substantial portions of the Software. */
|
|
||||||
/* */
|
|
||||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
|
||||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
|
||||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
|
||||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
|
||||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
|
||||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
|
||||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|
||||||
/**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef GODOT_CALLABLE_CUSTOM_HPP
|
|
||||||
#define GODOT_CALLABLE_CUSTOM_HPP
|
|
||||||
|
|
||||||
#include <godot_cpp/core/object_id.hpp>
|
|
||||||
#include <godot_cpp/variant/string_name.hpp>
|
|
||||||
|
|
||||||
namespace godot {
|
|
||||||
|
|
||||||
class Object;
|
|
||||||
|
|
||||||
class CallableCustomBase {
|
|
||||||
public:
|
|
||||||
virtual ObjectID get_object() const = 0;
|
|
||||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const = 0;
|
|
||||||
virtual ~CallableCustomBase() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class CallableCustom : public CallableCustomBase {
|
|
||||||
public:
|
|
||||||
typedef bool (*CompareEqualFunc)(const CallableCustom *p_a, const CallableCustom *p_b);
|
|
||||||
typedef bool (*CompareLessFunc)(const CallableCustom *p_a, const CallableCustom *p_b);
|
|
||||||
|
|
||||||
virtual uint32_t hash() const = 0;
|
|
||||||
virtual String get_as_text() const = 0;
|
|
||||||
virtual CompareEqualFunc get_compare_equal_func() const = 0;
|
|
||||||
virtual CompareLessFunc get_compare_less_func() const = 0;
|
|
||||||
virtual bool is_valid() const;
|
|
||||||
virtual ObjectID get_object() const = 0;
|
|
||||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace godot
|
|
||||||
|
|
||||||
#endif // GODOT_CALLABLE_CUSTOM_HPP
|
|
||||||
@@ -1,248 +0,0 @@
|
|||||||
/**************************************************************************/
|
|
||||||
/* callable_method_pointer.hpp */
|
|
||||||
/**************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/**************************************************************************/
|
|
||||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
|
||||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* */
|
|
||||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
|
||||||
/* a copy of this software and associated documentation files (the */
|
|
||||||
/* "Software"), to deal in the Software without restriction, including */
|
|
||||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
|
||||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
|
||||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
|
||||||
/* the following conditions: */
|
|
||||||
/* */
|
|
||||||
/* The above copyright notice and this permission notice shall be */
|
|
||||||
/* included in all copies or substantial portions of the Software. */
|
|
||||||
/* */
|
|
||||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
|
||||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
|
||||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
|
||||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
|
||||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
|
||||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
|
||||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|
||||||
/**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef GODOT_CALLABLE_METHOD_POINTER_HPP
|
|
||||||
#define GODOT_CALLABLE_METHOD_POINTER_HPP
|
|
||||||
|
|
||||||
#include <godot_cpp/core/binder_common.hpp>
|
|
||||||
#include <godot_cpp/variant/variant.hpp>
|
|
||||||
|
|
||||||
namespace godot {
|
|
||||||
|
|
||||||
class CallableCustomMethodPointerBase : public CallableCustomBase {
|
|
||||||
uint32_t *comp_ptr = nullptr;
|
|
||||||
uint32_t comp_size;
|
|
||||||
uint32_t h;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void _setup(uint32_t *p_base_ptr, uint32_t p_ptr_size);
|
|
||||||
|
|
||||||
public:
|
|
||||||
_FORCE_INLINE_ const uint32_t *get_comp_ptr() const { return comp_ptr; }
|
|
||||||
_FORCE_INLINE_ uint32_t get_comp_size() const { return comp_size; }
|
|
||||||
_FORCE_INLINE_ uint32_t get_hash() const { return h; }
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
Callable create_callable_from_ccmp(CallableCustomMethodPointerBase *p_callable_method_pointer);
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
//
|
|
||||||
// No return value.
|
|
||||||
//
|
|
||||||
|
|
||||||
template <class T, class... P>
|
|
||||||
class CallableCustomMethodPointer : public CallableCustomMethodPointerBase {
|
|
||||||
struct Data {
|
|
||||||
T *instance;
|
|
||||||
void (T::*method)(P...);
|
|
||||||
} data;
|
|
||||||
static_assert(sizeof(Data) % 4 == 0);
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual ObjectID get_object() const override {
|
|
||||||
return ObjectID(data.instance->get_instance_id());
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
CallableCustomMethodPointer(T *p_instance, void (T::*p_method)(P...)) {
|
|
||||||
memset(&data, 0, sizeof(Data));
|
|
||||||
data.instance = p_instance;
|
|
||||||
data.method = p_method;
|
|
||||||
_setup((uint32_t *)&data, sizeof(Data));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T, class... P>
|
|
||||||
Callable create_custom_callable_function_pointer(T *p_instance, void (T::*p_method)(P...)) {
|
|
||||||
typedef CallableCustomMethodPointer<T, P...> CCMP;
|
|
||||||
CCMP *ccmp = memnew(CCMP(p_instance, p_method));
|
|
||||||
return ::godot::internal::create_callable_from_ccmp(ccmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// With return value.
|
|
||||||
//
|
|
||||||
|
|
||||||
template <class T, class R, class... P>
|
|
||||||
class CallableCustomMethodPointerRet : public CallableCustomMethodPointerBase {
|
|
||||||
struct Data {
|
|
||||||
T *instance;
|
|
||||||
R(T::*method)
|
|
||||||
(P...);
|
|
||||||
} data;
|
|
||||||
static_assert(sizeof(Data) % 4 == 0);
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual ObjectID get_object() const override {
|
|
||||||
return ObjectID(data.instance->get_instance_id());
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
CallableCustomMethodPointerRet(T *p_instance, R (T::*p_method)(P...)) {
|
|
||||||
memset(&data, 0, sizeof(Data));
|
|
||||||
data.instance = p_instance;
|
|
||||||
data.method = p_method;
|
|
||||||
_setup((uint32_t *)&data, sizeof(Data));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T, class R, class... P>
|
|
||||||
Callable create_custom_callable_function_pointer(T *p_instance, R (T::*p_method)(P...)) {
|
|
||||||
typedef CallableCustomMethodPointerRet<T, R, P...> CCMP; // Messes with memnew otherwise.
|
|
||||||
CCMP *ccmp = memnew(CCMP(p_instance, p_method));
|
|
||||||
return ::godot::internal::create_callable_from_ccmp(ccmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Const with return value.
|
|
||||||
//
|
|
||||||
|
|
||||||
template <class T, class R, class... P>
|
|
||||||
class CallableCustomMethodPointerRetC : public CallableCustomMethodPointerBase {
|
|
||||||
struct Data {
|
|
||||||
T *instance;
|
|
||||||
R(T::*method)
|
|
||||||
(P...) const;
|
|
||||||
} data;
|
|
||||||
static_assert(sizeof(Data) % 4 == 0);
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual ObjectID get_object() const override {
|
|
||||||
return ObjectID(data.instance->get_instance_id());
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
CallableCustomMethodPointerRetC(const T *p_instance, R (T::*p_method)(P...) const) {
|
|
||||||
memset(&data, 0, sizeof(Data));
|
|
||||||
data.instance = const_cast<T *>(p_instance);
|
|
||||||
data.method = p_method;
|
|
||||||
_setup((uint32_t *)&data, sizeof(Data));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T, class R, class... P>
|
|
||||||
Callable create_custom_callable_function_pointer(const T *p_instance, R (T::*p_method)(P...) const) {
|
|
||||||
typedef CallableCustomMethodPointerRetC<T, R, P...> CCMP; // Messes with memnew otherwise.
|
|
||||||
CCMP *ccmp = memnew(CCMP(p_instance, p_method));
|
|
||||||
return ::godot::internal::create_callable_from_ccmp(ccmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Static method with no return value.
|
|
||||||
//
|
|
||||||
|
|
||||||
template <class... P>
|
|
||||||
class CallableCustomStaticMethodPointer : public CallableCustomMethodPointerBase {
|
|
||||||
struct Data {
|
|
||||||
void (*method)(P...);
|
|
||||||
} data;
|
|
||||||
static_assert(sizeof(Data) % 4 == 0);
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual ObjectID get_object() const override {
|
|
||||||
return ObjectID();
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
CallableCustomStaticMethodPointer(void (*p_method)(P...)) {
|
|
||||||
memset(&data, 0, sizeof(Data));
|
|
||||||
data.method = p_method;
|
|
||||||
_setup((uint32_t *)&data, sizeof(Data));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class... P>
|
|
||||||
Callable create_custom_callable_static_function_pointer(void (*p_method)(P...)) {
|
|
||||||
typedef CallableCustomStaticMethodPointer<P...> CCMP;
|
|
||||||
CCMP *ccmp = memnew(CCMP(p_method));
|
|
||||||
return ::godot::internal::create_callable_from_ccmp(ccmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Static method with return value.
|
|
||||||
//
|
|
||||||
|
|
||||||
template <class R, class... P>
|
|
||||||
class CallableCustomStaticMethodPointerRet : public CallableCustomMethodPointerBase {
|
|
||||||
struct Data {
|
|
||||||
R(*method)
|
|
||||||
(P...);
|
|
||||||
} data;
|
|
||||||
static_assert(sizeof(Data) % 4 == 0);
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual ObjectID get_object() const override {
|
|
||||||
return ObjectID();
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
CallableCustomStaticMethodPointerRet(R (*p_method)(P...)) {
|
|
||||||
memset(&data, 0, sizeof(Data));
|
|
||||||
data.method = p_method;
|
|
||||||
_setup((uint32_t *)&data, sizeof(Data));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class R, class... P>
|
|
||||||
Callable create_custom_callable_static_function_pointer(R (*p_method)(P...)) {
|
|
||||||
typedef CallableCustomStaticMethodPointerRet<R, P...> CCMP;
|
|
||||||
CCMP *ccmp = memnew(CCMP(p_method));
|
|
||||||
return ::godot::internal::create_callable_from_ccmp(ccmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// The API:
|
|
||||||
//
|
|
||||||
|
|
||||||
#define callable_mp(I, M) ::godot::create_custom_callable_function_pointer(I, M)
|
|
||||||
#define callable_mp_static(M) ::godot::create_custom_callable_static_function_pointer(M)
|
|
||||||
|
|
||||||
} // namespace godot
|
|
||||||
|
|
||||||
#endif // GODOT_CALLABLE_METHOD_POINTER_HPP
|
|
||||||
@@ -31,111 +31,82 @@
|
|||||||
#ifndef GODOT_CHAR_STRING_HPP
|
#ifndef GODOT_CHAR_STRING_HPP
|
||||||
#define GODOT_CHAR_STRING_HPP
|
#define GODOT_CHAR_STRING_HPP
|
||||||
|
|
||||||
#include <godot_cpp/templates/cowdata.hpp>
|
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
namespace godot {
|
namespace godot {
|
||||||
|
|
||||||
template <class T>
|
class CharString {
|
||||||
class CharStringT;
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
class CharProxy {
|
|
||||||
template <class TS>
|
|
||||||
friend class CharStringT;
|
|
||||||
|
|
||||||
const int _index;
|
|
||||||
CowData<T> &_cowdata;
|
|
||||||
static inline const T _null = 0;
|
|
||||||
|
|
||||||
_FORCE_INLINE_ CharProxy(const int &p_index, CowData<T> &p_cowdata) :
|
|
||||||
_index(p_index),
|
|
||||||
_cowdata(p_cowdata) {}
|
|
||||||
|
|
||||||
public:
|
|
||||||
_FORCE_INLINE_ CharProxy(const CharProxy<T> &p_other) :
|
|
||||||
_index(p_other._index),
|
|
||||||
_cowdata(p_other._cowdata) {}
|
|
||||||
|
|
||||||
_FORCE_INLINE_ operator T() const {
|
|
||||||
if (unlikely(_index == _cowdata.size())) {
|
|
||||||
return _null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _cowdata.get(_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
_FORCE_INLINE_ const T *operator&() const {
|
|
||||||
return _cowdata.ptr() + _index;
|
|
||||||
}
|
|
||||||
|
|
||||||
_FORCE_INLINE_ void operator=(const T &p_other) const {
|
|
||||||
_cowdata.set(_index, p_other);
|
|
||||||
}
|
|
||||||
|
|
||||||
_FORCE_INLINE_ void operator=(const CharProxy<T> &p_other) const {
|
|
||||||
_cowdata.set(_index, p_other.operator T());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
class CharStringT {
|
|
||||||
friend class String;
|
friend class String;
|
||||||
|
|
||||||
CowData<T> _cowdata;
|
const char *_data = nullptr;
|
||||||
static inline const T _null = 0;
|
int _length = 0;
|
||||||
|
|
||||||
|
CharString(const char *str, int length);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
_FORCE_INLINE_ T *ptrw() { return _cowdata.ptrw(); }
|
int length() const;
|
||||||
_FORCE_INLINE_ const T *ptr() const { return _cowdata.ptr(); }
|
const char *get_data() const;
|
||||||
_FORCE_INLINE_ int size() const { return _cowdata.size(); }
|
|
||||||
Error resize(int p_size) { return _cowdata.resize(p_size); }
|
|
||||||
|
|
||||||
_FORCE_INLINE_ T get(int p_index) const { return _cowdata.get(p_index); }
|
CharString(CharString &&p_str);
|
||||||
_FORCE_INLINE_ void set(int p_index, const T &p_elem) { _cowdata.set(p_index, p_elem); }
|
void operator=(CharString &&p_str);
|
||||||
_FORCE_INLINE_ const T &operator[](int p_index) const {
|
CharString() {}
|
||||||
if (unlikely(p_index == _cowdata.size())) {
|
~CharString();
|
||||||
return _null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _cowdata.get(p_index);
|
|
||||||
}
|
|
||||||
_FORCE_INLINE_ CharProxy<T> operator[](int p_index) { return CharProxy<T>(p_index, _cowdata); }
|
|
||||||
|
|
||||||
_FORCE_INLINE_ CharStringT() {}
|
|
||||||
_FORCE_INLINE_ CharStringT(const CharStringT<T> &p_str) { _cowdata._ref(p_str._cowdata); }
|
|
||||||
_FORCE_INLINE_ void operator=(const CharStringT<T> &p_str) { _cowdata._ref(p_str._cowdata); }
|
|
||||||
_FORCE_INLINE_ CharStringT(const T *p_cstr) { copy_from(p_cstr); }
|
|
||||||
|
|
||||||
void operator=(const T *p_cstr);
|
|
||||||
bool operator<(const CharStringT<T> &p_right) const;
|
|
||||||
CharStringT<T> &operator+=(T p_char);
|
|
||||||
int length() const { return size() ? size() - 1 : 0; }
|
|
||||||
const T *get_data() const;
|
|
||||||
operator const T *() const { return get_data(); };
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void copy_from(const T *p_cstr);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
class Char16String {
|
||||||
const char *CharStringT<char>::get_data() const;
|
friend class String;
|
||||||
|
|
||||||
template <>
|
const char16_t *_data = nullptr;
|
||||||
const char16_t *CharStringT<char16_t>::get_data() const;
|
int _length = 0;
|
||||||
|
|
||||||
template <>
|
Char16String(const char16_t *str, int length);
|
||||||
const char32_t *CharStringT<char32_t>::get_data() const;
|
|
||||||
|
|
||||||
template <>
|
public:
|
||||||
const wchar_t *CharStringT<wchar_t>::get_data() const;
|
int length() const;
|
||||||
|
const char16_t *get_data() const;
|
||||||
|
|
||||||
typedef CharStringT<char> CharString;
|
Char16String(Char16String &&p_str);
|
||||||
typedef CharStringT<char16_t> Char16String;
|
void operator=(Char16String &&p_str);
|
||||||
typedef CharStringT<char32_t> Char32String;
|
Char16String() {}
|
||||||
typedef CharStringT<wchar_t> CharWideString;
|
~Char16String();
|
||||||
|
};
|
||||||
|
|
||||||
|
class Char32String {
|
||||||
|
friend class String;
|
||||||
|
|
||||||
|
const char32_t *_data = nullptr;
|
||||||
|
int _length = 0;
|
||||||
|
|
||||||
|
Char32String(const char32_t *str, int length);
|
||||||
|
|
||||||
|
public:
|
||||||
|
int length() const;
|
||||||
|
const char32_t *get_data() const;
|
||||||
|
|
||||||
|
Char32String(Char32String &&p_str);
|
||||||
|
void operator=(Char32String &&p_str);
|
||||||
|
Char32String() {}
|
||||||
|
~Char32String();
|
||||||
|
};
|
||||||
|
|
||||||
|
class CharWideString {
|
||||||
|
friend class String;
|
||||||
|
|
||||||
|
const wchar_t *_data = nullptr;
|
||||||
|
int _length = 0;
|
||||||
|
|
||||||
|
CharWideString(const wchar_t *str, int length);
|
||||||
|
|
||||||
|
public:
|
||||||
|
int length() const;
|
||||||
|
const wchar_t *get_data() const;
|
||||||
|
|
||||||
|
CharWideString(CharWideString &&p_str);
|
||||||
|
void operator=(CharWideString &&p_str);
|
||||||
|
CharWideString() {}
|
||||||
|
~CharWideString();
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace godot
|
} // namespace godot
|
||||||
|
|
||||||
|
|||||||
@@ -154,17 +154,9 @@ public:
|
|||||||
Variant(int64_t v);
|
Variant(int64_t v);
|
||||||
Variant(int32_t v) :
|
Variant(int32_t v) :
|
||||||
Variant(static_cast<int64_t>(v)) {}
|
Variant(static_cast<int64_t>(v)) {}
|
||||||
Variant(int16_t v) :
|
|
||||||
Variant(static_cast<int64_t>(v)) {}
|
|
||||||
Variant(int8_t v) :
|
|
||||||
Variant(static_cast<int64_t>(v)) {}
|
|
||||||
Variant(uint64_t v) :
|
|
||||||
Variant(static_cast<int64_t>(v)) {}
|
|
||||||
Variant(uint32_t v) :
|
Variant(uint32_t v) :
|
||||||
Variant(static_cast<int64_t>(v)) {}
|
Variant(static_cast<int64_t>(v)) {}
|
||||||
Variant(uint16_t v) :
|
Variant(uint64_t v) :
|
||||||
Variant(static_cast<int64_t>(v)) {}
|
|
||||||
Variant(uint8_t v) :
|
|
||||||
Variant(static_cast<int64_t>(v)) {}
|
Variant(static_cast<int64_t>(v)) {}
|
||||||
Variant(double v);
|
Variant(double v);
|
||||||
Variant(float v) :
|
Variant(float v) :
|
||||||
@@ -217,12 +209,8 @@ public:
|
|||||||
operator bool() const;
|
operator bool() const;
|
||||||
operator int64_t() const;
|
operator int64_t() const;
|
||||||
operator int32_t() const;
|
operator int32_t() const;
|
||||||
operator int16_t() const;
|
|
||||||
operator int8_t() const;
|
|
||||||
operator uint64_t() const;
|
operator uint64_t() const;
|
||||||
operator uint32_t() const;
|
operator uint32_t() const;
|
||||||
operator uint16_t() const;
|
|
||||||
operator uint8_t() const;
|
|
||||||
operator double() const;
|
operator double() const;
|
||||||
operator float() const;
|
operator float() const;
|
||||||
operator String() const;
|
operator String() const;
|
||||||
@@ -267,33 +255,25 @@ public:
|
|||||||
bool operator!=(const Variant &other) const;
|
bool operator!=(const Variant &other) const;
|
||||||
bool operator<(const Variant &other) const;
|
bool operator<(const Variant &other) const;
|
||||||
|
|
||||||
void callp(const StringName &method, const Variant **args, int argcount, Variant &r_ret, GDExtensionCallError &r_error);
|
void call(const StringName &method, const Variant **args, int argcount, Variant &r_ret, GDExtensionCallError &r_error);
|
||||||
|
|
||||||
template <class... Args>
|
template <class... Args>
|
||||||
Variant call(const StringName &method, Args... args) {
|
Variant call(const StringName &method, Args... args) {
|
||||||
std::array<Variant, sizeof...(args)> vargs = { args... };
|
|
||||||
std::array<const Variant *, sizeof...(args)> argptrs;
|
|
||||||
for (size_t i = 0; i < vargs.size(); i++) {
|
|
||||||
argptrs[i] = &vargs[i];
|
|
||||||
}
|
|
||||||
Variant result;
|
Variant result;
|
||||||
GDExtensionCallError error;
|
GDExtensionCallError error;
|
||||||
callp(method, argptrs.data(), argptrs.size(), result, error);
|
std::array<GDExtensionConstVariantPtr, sizeof...(Args)> call_args = { Variant(args)... };
|
||||||
|
call(method, call_args.data(), call_args.size(), result, error);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void callp_static(Variant::Type type, const StringName &method, const Variant **args, int argcount, Variant &r_ret, GDExtensionCallError &r_error);
|
static void call_static(Variant::Type type, const StringName &method, const Variant **args, int argcount, Variant &r_ret, GDExtensionCallError &r_error);
|
||||||
|
|
||||||
template <class... Args>
|
template <class... Args>
|
||||||
static Variant call_static(Variant::Type type, const StringName &method, Args... args) {
|
static Variant call_static(Variant::Type type, const StringName &method, Args... args) {
|
||||||
std::array<Variant, sizeof...(args)> vargs = { args... };
|
|
||||||
std::array<const Variant *, sizeof...(args)> argptrs;
|
|
||||||
for (size_t i = 0; i < vargs.size(); i++) {
|
|
||||||
argptrs[i] = &vargs[i];
|
|
||||||
}
|
|
||||||
Variant result;
|
Variant result;
|
||||||
GDExtensionCallError error;
|
GDExtensionCallError error;
|
||||||
callp_static(type, method, argptrs.data(), argptrs.size(), sizeof...(args), result, error);
|
std::array<GDExtensionConstVariantPtr, sizeof...(Args)> call_args = { Variant(args)... };
|
||||||
|
call_static(type, method, call_args.data(), call_args.size(), result, error);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,8 +334,6 @@ String vformat(const String &p_text, const VarArgs... p_args) {
|
|||||||
return p_text % args_array;
|
return p_text % args_array;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <godot_cpp/variant/builtin_vararg_methods.hpp>
|
|
||||||
|
|
||||||
} // namespace godot
|
} // namespace godot
|
||||||
|
|
||||||
#endif // GODOT_VARIANT_HPP
|
#endif // GODOT_VARIANT_HPP
|
||||||
|
|||||||
@@ -78,14 +78,6 @@ struct _NO_DISCARD_ Vector3 {
|
|||||||
return x < y ? (y < z ? Vector3::AXIS_Z : Vector3::AXIS_Y) : (x < z ? Vector3::AXIS_Z : Vector3::AXIS_X);
|
return x < y ? (y < z ? Vector3::AXIS_Z : Vector3::AXIS_Y) : (x < z ? Vector3::AXIS_Z : Vector3::AXIS_X);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 min(const Vector3 &p_vector3) const {
|
|
||||||
return Vector3(MIN(x, p_vector3.x), MIN(y, p_vector3.y), MIN(z, p_vector3.z));
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 max(const Vector3 &p_vector3) const {
|
|
||||||
return Vector3(MAX(x, p_vector3.x), MAX(y, p_vector3.y), MAX(z, p_vector3.z));
|
|
||||||
}
|
|
||||||
|
|
||||||
_FORCE_INLINE_ real_t length() const;
|
_FORCE_INLINE_ real_t length() const;
|
||||||
_FORCE_INLINE_ real_t length_squared() const;
|
_FORCE_INLINE_ real_t length_squared() const;
|
||||||
|
|
||||||
|
|||||||
@@ -71,14 +71,6 @@ struct _NO_DISCARD_ Vector3i {
|
|||||||
Vector3i::Axis min_axis_index() const;
|
Vector3i::Axis min_axis_index() const;
|
||||||
Vector3i::Axis max_axis_index() const;
|
Vector3i::Axis max_axis_index() const;
|
||||||
|
|
||||||
Vector3i min(const Vector3i &p_vector3i) const {
|
|
||||||
return Vector3i(MIN(x, p_vector3i.x), MIN(y, p_vector3i.y), MIN(z, p_vector3i.z));
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3i max(const Vector3i &p_vector3i) const {
|
|
||||||
return Vector3i(MAX(x, p_vector3i.x), MAX(y, p_vector3i.y), MAX(z, p_vector3i.z));
|
|
||||||
}
|
|
||||||
|
|
||||||
_FORCE_INLINE_ int64_t length_squared() const;
|
_FORCE_INLINE_ int64_t length_squared() const;
|
||||||
_FORCE_INLINE_ double length() const;
|
_FORCE_INLINE_ double length() const;
|
||||||
|
|
||||||
|
|||||||
@@ -70,14 +70,6 @@ struct _NO_DISCARD_ Vector4 {
|
|||||||
Vector4::Axis min_axis_index() const;
|
Vector4::Axis min_axis_index() const;
|
||||||
Vector4::Axis max_axis_index() const;
|
Vector4::Axis max_axis_index() const;
|
||||||
|
|
||||||
Vector4 min(const Vector4 &p_vector4) const {
|
|
||||||
return Vector4(MIN(x, p_vector4.x), MIN(y, p_vector4.y), MIN(z, p_vector4.z), MIN(w, p_vector4.w));
|
|
||||||
}
|
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
_FORCE_INLINE_ real_t length_squared() const;
|
_FORCE_INLINE_ real_t length_squared() const;
|
||||||
bool is_equal_approx(const Vector4 &p_vec4) const;
|
bool is_equal_approx(const Vector4 &p_vec4) const;
|
||||||
bool is_zero_approx() const;
|
bool is_zero_approx() const;
|
||||||
|
|||||||
@@ -73,14 +73,6 @@ struct _NO_DISCARD_ Vector4i {
|
|||||||
Vector4i::Axis min_axis_index() const;
|
Vector4i::Axis min_axis_index() const;
|
||||||
Vector4i::Axis max_axis_index() const;
|
Vector4i::Axis max_axis_index() const;
|
||||||
|
|
||||||
Vector4i min(const Vector4i &p_vector4i) const {
|
|
||||||
return Vector4i(MIN(x, p_vector4i.x), MIN(y, p_vector4i.y), MIN(z, p_vector4i.z), MIN(w, p_vector4i.w));
|
|
||||||
}
|
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
_FORCE_INLINE_ int64_t length_squared() const;
|
_FORCE_INLINE_ int64_t length_squared() const;
|
||||||
_FORCE_INLINE_ double length() const;
|
_FORCE_INLINE_ double length() const;
|
||||||
|
|
||||||
|
|||||||
@@ -1,61 +0,0 @@
|
|||||||
/**************************************************************************/
|
|
||||||
/* editor_plugin_registration.cpp */
|
|
||||||
/**************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/**************************************************************************/
|
|
||||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
|
||||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* */
|
|
||||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
|
||||||
/* a copy of this software and associated documentation files (the */
|
|
||||||
/* "Software"), to deal in the Software without restriction, including */
|
|
||||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
|
||||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
|
||||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
|
||||||
/* the following conditions: */
|
|
||||||
/* */
|
|
||||||
/* The above copyright notice and this permission notice shall be */
|
|
||||||
/* included in all copies or substantial portions of the Software. */
|
|
||||||
/* */
|
|
||||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
|
||||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
|
||||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
|
||||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
|
||||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
|
||||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
|
||||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|
||||||
/**************************************************************************/
|
|
||||||
|
|
||||||
#include <godot_cpp/classes/editor_plugin_registration.hpp>
|
|
||||||
|
|
||||||
#include <godot_cpp/variant/variant.hpp>
|
|
||||||
|
|
||||||
namespace godot {
|
|
||||||
|
|
||||||
Vector<StringName> EditorPlugins::plugin_classes;
|
|
||||||
|
|
||||||
void EditorPlugins::add_plugin_class(const StringName &p_class_name) {
|
|
||||||
ERR_FAIL_COND_MSG(plugin_classes.find(p_class_name) != -1, vformat("Editor plugin already registered: %s", p_class_name));
|
|
||||||
plugin_classes.push_back(p_class_name);
|
|
||||||
internal::gdextension_interface_editor_add_plugin(p_class_name._native_ptr());
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditorPlugins::remove_plugin_class(const StringName &p_class_name) {
|
|
||||||
int index = plugin_classes.find(p_class_name);
|
|
||||||
ERR_FAIL_COND_MSG(index == -1, vformat("Editor plugin is not registered: %s", p_class_name));
|
|
||||||
plugin_classes.remove_at(index);
|
|
||||||
internal::gdextension_interface_editor_remove_plugin(p_class_name._native_ptr());
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditorPlugins::deinitialize(GDExtensionInitializationLevel p_level) {
|
|
||||||
if (p_level == GDEXTENSION_INITIALIZATION_EDITOR) {
|
|
||||||
for (const StringName &class_name : plugin_classes) {
|
|
||||||
internal::gdextension_interface_editor_remove_plugin(class_name._native_ptr());
|
|
||||||
}
|
|
||||||
plugin_classes.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace godot
|
|
||||||
@@ -36,23 +36,23 @@
|
|||||||
|
|
||||||
namespace godot {
|
namespace godot {
|
||||||
Error XMLParser::_open_buffer(const uint8_t *p_buffer, size_t p_size) {
|
Error XMLParser::_open_buffer(const uint8_t *p_buffer, size_t p_size) {
|
||||||
return (Error)internal::gdextension_interface_xml_parser_open_buffer(_owner, p_buffer, p_size);
|
return (Error)internal::gde_interface->xml_parser_open_buffer(_owner, p_buffer, p_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t FileAccess::get_buffer(uint8_t *p_dst, uint64_t p_length) const {
|
uint64_t FileAccess::get_buffer(uint8_t *p_dst, uint64_t p_length) const {
|
||||||
return internal::gdextension_interface_file_access_get_buffer(_owner, p_dst, p_length);
|
return internal::gde_interface->file_access_get_buffer(_owner, p_dst, p_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileAccess::store_buffer(const uint8_t *p_src, uint64_t p_length) {
|
void FileAccess::store_buffer(const uint8_t *p_src, uint64_t p_length) {
|
||||||
internal::gdextension_interface_file_access_store_buffer(_owner, p_src, p_length);
|
internal::gde_interface->file_access_store_buffer(_owner, p_src, p_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
WorkerThreadPool::TaskID WorkerThreadPool::add_native_task(void (*p_func)(void *), void *p_userdata, bool p_high_priority, const String &p_description) {
|
WorkerThreadPool::TaskID WorkerThreadPool::add_native_task(void (*p_func)(void *), void *p_userdata, bool p_high_priority, const String &p_description) {
|
||||||
return (TaskID)internal::gdextension_interface_worker_thread_pool_add_native_task(_owner, p_func, p_userdata, p_high_priority, (GDExtensionConstStringPtr)&p_description);
|
return (TaskID)internal::gde_interface->worker_thread_pool_add_native_task(_owner, p_func, p_userdata, p_high_priority, (GDExtensionConstStringPtr)&p_description);
|
||||||
}
|
}
|
||||||
|
|
||||||
WorkerThreadPool::GroupID WorkerThreadPool::add_native_group_task(void (*p_func)(void *, uint32_t), void *p_userdata, int p_elements, int p_tasks, bool p_high_priority, const String &p_description) {
|
WorkerThreadPool::GroupID WorkerThreadPool::add_native_group_task(void (*p_func)(void *, uint32_t), void *p_userdata, int p_elements, int p_tasks, bool p_high_priority, const String &p_description) {
|
||||||
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);
|
return (GroupID)internal::gde_interface->worker_thread_pool_add_native_group_task(_owner, p_func, p_userdata, p_elements, p_tasks, p_high_priority, (GDExtensionConstStringPtr)&p_description);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace godot
|
} // namespace godot
|
||||||
|
|||||||
@@ -28,16 +28,12 @@
|
|||||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <godot_cpp/classes/wrapped.hpp>
|
#include <godot_cpp/classes/wrapped.hpp>
|
||||||
|
|
||||||
#include <godot_cpp/variant/builtin_types.hpp>
|
#include <godot_cpp/variant/builtin_types.hpp>
|
||||||
|
|
||||||
#include <godot_cpp/classes/object.hpp>
|
#include <godot_cpp/classes/object.hpp>
|
||||||
|
|
||||||
#include <godot_cpp/core/class_db.hpp>
|
|
||||||
|
|
||||||
namespace godot {
|
namespace godot {
|
||||||
|
|
||||||
const StringName *Wrapped::_get_extension_class_name() const {
|
const StringName *Wrapped::_get_extension_class_name() const {
|
||||||
@@ -47,38 +43,13 @@ const StringName *Wrapped::_get_extension_class_name() const {
|
|||||||
void Wrapped::_postinitialize() {
|
void Wrapped::_postinitialize() {
|
||||||
const StringName *extension_class = _get_extension_class_name();
|
const StringName *extension_class = _get_extension_class_name();
|
||||||
if (extension_class) {
|
if (extension_class) {
|
||||||
godot::internal::gdextension_interface_object_set_instance(_owner, reinterpret_cast<GDExtensionConstStringNamePtr>(extension_class), this);
|
godot::internal::gde_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) {
|
|
||||||
Object *obj = dynamic_cast<Object *>(this);
|
|
||||||
if (obj) {
|
|
||||||
obj->notification(Object::NOTIFICATION_POSTINITIALIZE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
godot::internal::gde_interface->object_set_instance_binding(_owner, godot::internal::token, this, _get_bindings_callbacks());
|
||||||
}
|
}
|
||||||
|
|
||||||
Wrapped::Wrapped(const StringName p_godot_class) {
|
Wrapped::Wrapped(const StringName p_godot_class) {
|
||||||
#ifdef HOT_RELOAD_ENABLED
|
_owner = godot::internal::gde_interface->classdb_construct_object(reinterpret_cast<GDExtensionConstStringNamePtr>(p_godot_class._native_ptr()));
|
||||||
if (unlikely(Wrapped::recreate_instance)) {
|
|
||||||
RecreateInstance *recreate_data = Wrapped::recreate_instance;
|
|
||||||
RecreateInstance *previous = nullptr;
|
|
||||||
while (recreate_data) {
|
|
||||||
if (recreate_data->wrapper == this) {
|
|
||||||
_owner = recreate_data->owner;
|
|
||||||
if (previous) {
|
|
||||||
previous->next = recreate_data->next;
|
|
||||||
} else {
|
|
||||||
Wrapped::recreate_instance = recreate_data->next;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
previous = recreate_data;
|
|
||||||
recreate_data = recreate_data->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
_owner = godot::internal::gdextension_interface_classdb_construct_object(reinterpret_cast<GDExtensionConstStringNamePtr>(p_godot_class._native_ptr()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Wrapped::Wrapped(GodotObject *p_godot_object) {
|
Wrapped::Wrapped(GodotObject *p_godot_object) {
|
||||||
@@ -89,54 +60,4 @@ void postinitialize_handler(Wrapped *p_wrapped) {
|
|||||||
p_wrapped->_postinitialize();
|
p_wrapped->_postinitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
std::vector<EngineClassRegistrationCallback> &get_engine_class_registration_callbacks() {
|
|
||||||
static std::vector<EngineClassRegistrationCallback> engine_class_registration_callbacks;
|
|
||||||
return engine_class_registration_callbacks;
|
|
||||||
}
|
|
||||||
|
|
||||||
GDExtensionPropertyInfo *create_c_property_list(const ::godot::List<::godot::PropertyInfo> &plist_cpp, uint32_t *r_size) {
|
|
||||||
GDExtensionPropertyInfo *plist = nullptr;
|
|
||||||
// Linked list size can be expensive to get so we cache it
|
|
||||||
const uint32_t plist_size = plist_cpp.size();
|
|
||||||
if (r_size != nullptr) {
|
|
||||||
*r_size = plist_size;
|
|
||||||
}
|
|
||||||
plist = reinterpret_cast<GDExtensionPropertyInfo *>(memalloc(sizeof(GDExtensionPropertyInfo) * plist_size));
|
|
||||||
unsigned int i = 0;
|
|
||||||
for (const ::godot::PropertyInfo &E : plist_cpp) {
|
|
||||||
plist[i].type = static_cast<GDExtensionVariantType>(E.type);
|
|
||||||
plist[i].name = E.name._native_ptr();
|
|
||||||
plist[i].hint = E.hint;
|
|
||||||
plist[i].hint_string = E.hint_string._native_ptr();
|
|
||||||
plist[i].class_name = E.class_name._native_ptr();
|
|
||||||
plist[i].usage = E.usage;
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
return plist;
|
|
||||||
}
|
|
||||||
|
|
||||||
void free_c_property_list(GDExtensionPropertyInfo *plist) {
|
|
||||||
memfree(plist);
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_engine_class_registration_callback(EngineClassRegistrationCallback p_callback) {
|
|
||||||
get_engine_class_registration_callbacks().push_back(p_callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
void register_engine_class(const StringName &p_name, const GDExtensionInstanceBindingCallbacks *p_callbacks) {
|
|
||||||
ClassDB::_register_engine_class(p_name, p_callbacks);
|
|
||||||
}
|
|
||||||
|
|
||||||
void register_engine_classes() {
|
|
||||||
std::vector<EngineClassRegistrationCallback> &engine_class_registration_callbacks = get_engine_class_registration_callbacks();
|
|
||||||
for (EngineClassRegistrationCallback cb : engine_class_registration_callbacks) {
|
|
||||||
cb();
|
|
||||||
}
|
|
||||||
engine_class_registration_callbacks.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
} // namespace godot
|
} // namespace godot
|
||||||
|
|||||||
@@ -40,8 +40,6 @@
|
|||||||
namespace godot {
|
namespace godot {
|
||||||
|
|
||||||
std::unordered_map<StringName, ClassDB::ClassInfo> ClassDB::classes;
|
std::unordered_map<StringName, ClassDB::ClassInfo> ClassDB::classes;
|
||||||
std::unordered_map<StringName, const GDExtensionInstanceBindingCallbacks *> ClassDB::instance_binding_callbacks;
|
|
||||||
std::vector<StringName> ClassDB::class_register_order;
|
|
||||||
GDExtensionInitializationLevel ClassDB::current_level = GDEXTENSION_INITIALIZATION_CORE;
|
GDExtensionInitializationLevel ClassDB::current_level = GDEXTENSION_INITIALIZATION_CORE;
|
||||||
|
|
||||||
MethodDefinition D_METHOD(StringName p_name) {
|
MethodDefinition D_METHOD(StringName p_name) {
|
||||||
@@ -57,13 +55,13 @@ MethodDefinition D_METHOD(StringName p_name, StringName p_arg1) {
|
|||||||
void ClassDB::add_property_group(const StringName &p_class, const String &p_name, const String &p_prefix) {
|
void ClassDB::add_property_group(const StringName &p_class, const String &p_name, const String &p_prefix) {
|
||||||
ERR_FAIL_COND_MSG(classes.find(p_class) == classes.end(), String("Trying to add property '{0}{1}' to non-existing class '{2}'.").format(Array::make(p_prefix, p_name, p_class)));
|
ERR_FAIL_COND_MSG(classes.find(p_class) == classes.end(), String("Trying to add property '{0}{1}' to non-existing class '{2}'.").format(Array::make(p_prefix, p_name, p_class)));
|
||||||
|
|
||||||
internal::gdextension_interface_classdb_register_extension_class_property_group(internal::library, p_class._native_ptr(), p_name._native_ptr(), p_prefix._native_ptr());
|
internal::gde_interface->classdb_register_extension_class_property_group(internal::library, p_class._native_ptr(), p_name._native_ptr(), p_prefix._native_ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassDB::add_property_subgroup(const StringName &p_class, const String &p_name, const String &p_prefix) {
|
void ClassDB::add_property_subgroup(const StringName &p_class, const String &p_name, const String &p_prefix) {
|
||||||
ERR_FAIL_COND_MSG(classes.find(p_class) == classes.end(), String("Trying to add property '{0}{1}' to non-existing class '{2}'.").format(Array::make(p_prefix, p_name, p_class)));
|
ERR_FAIL_COND_MSG(classes.find(p_class) == classes.end(), String("Trying to add property '{0}{1}' to non-existing class '{2}'.").format(Array::make(p_prefix, p_name, p_class)));
|
||||||
|
|
||||||
internal::gdextension_interface_classdb_register_extension_class_property_subgroup(internal::library, p_class._native_ptr(), p_name._native_ptr(), p_prefix._native_ptr());
|
internal::gde_interface->classdb_register_extension_class_property_subgroup(internal::library, p_class._native_ptr(), p_name._native_ptr(), p_prefix._native_ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassDB::add_property(const StringName &p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index) {
|
void ClassDB::add_property(const StringName &p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index) {
|
||||||
@@ -77,7 +75,7 @@ void ClassDB::add_property(const StringName &p_class, const PropertyInfo &p_pinf
|
|||||||
if (p_setter != String("")) {
|
if (p_setter != String("")) {
|
||||||
setter = get_method(p_class, p_setter);
|
setter = get_method(p_class, p_setter);
|
||||||
|
|
||||||
ERR_FAIL_NULL_MSG(setter, String("Setter method '{0}::{1}()' not found for property '{2}::{3}'.").format(Array::make(p_class, p_setter, p_class, p_pinfo.name)));
|
ERR_FAIL_COND_MSG(!setter, String("Setter method '{0}::{1}()' not found for property '{2}::{3}'.").format(Array::make(p_class, p_setter, p_class, p_pinfo.name)));
|
||||||
|
|
||||||
size_t exp_args = 1 + (p_index >= 0 ? 1 : 0);
|
size_t exp_args = 1 + (p_index >= 0 ? 1 : 0);
|
||||||
ERR_FAIL_COND_MSG((int)exp_args != setter->get_argument_count(), String("Setter method '{0}::{1}()' must take a single argument.").format(Array::make(p_class, p_setter)));
|
ERR_FAIL_COND_MSG((int)exp_args != setter->get_argument_count(), String("Setter method '{0}::{1}()' must take a single argument.").format(Array::make(p_class, p_setter)));
|
||||||
@@ -86,7 +84,7 @@ void ClassDB::add_property(const StringName &p_class, const PropertyInfo &p_pinf
|
|||||||
ERR_FAIL_COND_MSG(p_getter == String(""), String("Getter method must be specified for '{0}::{1}'.").format(Array::make(p_class, p_pinfo.name)));
|
ERR_FAIL_COND_MSG(p_getter == String(""), String("Getter method must be specified for '{0}::{1}'.").format(Array::make(p_class, p_pinfo.name)));
|
||||||
|
|
||||||
MethodBind *getter = get_method(p_class, p_getter);
|
MethodBind *getter = get_method(p_class, p_getter);
|
||||||
ERR_FAIL_NULL_MSG(getter, String("Getter method '{0}::{1}()' not found for property '{2}::{3}'.").format(Array::make(p_class, p_getter, p_class, p_pinfo.name)));
|
ERR_FAIL_COND_MSG(!getter, String("Getter method '{0}::{1}()' not found for property '{2}::{3}'.").format(Array::make(p_class, p_getter, p_class, p_pinfo.name)));
|
||||||
{
|
{
|
||||||
size_t exp_args = 0 + (p_index >= 0 ? 1 : 0);
|
size_t exp_args = 0 + (p_index >= 0 ? 1 : 0);
|
||||||
ERR_FAIL_COND_MSG((int)exp_args != getter->get_argument_count(), String("Getter method '{0}::{1}()' must not take any argument.").format(Array::make(p_class, p_getter)));
|
ERR_FAIL_COND_MSG((int)exp_args != getter->get_argument_count(), String("Getter method '{0}::{1}()' must not take any argument.").format(Array::make(p_class, p_getter)));
|
||||||
@@ -105,7 +103,15 @@ void ClassDB::add_property(const StringName &p_class, const PropertyInfo &p_pinf
|
|||||||
p_pinfo.usage, // DEFAULT //uint32_t usage;
|
p_pinfo.usage, // DEFAULT //uint32_t usage;
|
||||||
};
|
};
|
||||||
|
|
||||||
internal::gdextension_interface_classdb_register_extension_class_property_indexed(internal::library, info.name._native_ptr(), &prop_info, p_setter._native_ptr(), p_getter._native_ptr(), p_index);
|
PropertySetGet setget;
|
||||||
|
setget.setter = p_setter;
|
||||||
|
setget.getter = p_getter;
|
||||||
|
setget._setptr = setter;
|
||||||
|
setget._getptr = getter;
|
||||||
|
setget.index = p_index;
|
||||||
|
setget.type = p_pinfo.type;
|
||||||
|
|
||||||
|
internal::gde_interface->classdb_register_extension_class_property(internal::library, info.name._native_ptr(), &prop_info, setget.setter._native_ptr(), setget.getter._native_ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodBind *ClassDB::get_method(const StringName &p_class, const StringName &p_method) {
|
MethodBind *ClassDB::get_method(const StringName &p_class, const StringName &p_method) {
|
||||||
@@ -228,7 +234,7 @@ void ClassDB::bind_method_godot(const StringName &p_class_name, MethodBind *p_me
|
|||||||
(uint32_t)p_method->get_default_argument_count(), // uint32_t default_argument_count;
|
(uint32_t)p_method->get_default_argument_count(), // uint32_t default_argument_count;
|
||||||
def_args.data(), // GDExtensionVariantPtr *default_arguments;
|
def_args.data(), // GDExtensionVariantPtr *default_arguments;
|
||||||
};
|
};
|
||||||
internal::gdextension_interface_classdb_register_extension_class_method(internal::library, p_class_name._native_ptr(), &method_info);
|
internal::gde_interface->classdb_register_extension_class_method(internal::library, p_class_name._native_ptr(), &method_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassDB::add_signal(const StringName &p_class, const MethodInfo &p_signal) {
|
void ClassDB::add_signal(const StringName &p_class, const MethodInfo &p_signal) {
|
||||||
@@ -263,7 +269,7 @@ void ClassDB::add_signal(const StringName &p_class, const MethodInfo &p_signal)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
internal::gdextension_interface_classdb_register_extension_class_signal(internal::library, cl.name._native_ptr(), p_signal.name._native_ptr(), parameters.data(), parameters.size());
|
internal::gde_interface->classdb_register_extension_class_signal(internal::library, cl.name._native_ptr(), p_signal.name._native_ptr(), parameters.data(), parameters.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassDB::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) {
|
void ClassDB::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) {
|
||||||
@@ -280,7 +286,7 @@ void ClassDB::bind_integer_constant(const StringName &p_class_name, const String
|
|||||||
type.constant_names.insert(p_constant_name);
|
type.constant_names.insert(p_constant_name);
|
||||||
|
|
||||||
// Register it with Godot
|
// Register it with Godot
|
||||||
internal::gdextension_interface_classdb_register_extension_class_integer_constant(internal::library, p_class_name._native_ptr(), p_enum_name._native_ptr(), p_constant_name._native_ptr(), p_constant_value, p_is_bitfield);
|
internal::gde_interface->classdb_register_extension_class_integer_constant(internal::library, p_class_name._native_ptr(), p_enum_name._native_ptr(), p_constant_name._native_ptr(), p_constant_value, p_is_bitfield);
|
||||||
}
|
}
|
||||||
GDExtensionClassCallVirtual ClassDB::get_virtual_func(void *p_userdata, GDExtensionConstStringNamePtr p_name) {
|
GDExtensionClassCallVirtual ClassDB::get_virtual_func(void *p_userdata, GDExtensionConstStringNamePtr p_name) {
|
||||||
// This is called by Godot the first time it calls a virtual function, and it caches the result, per object instance.
|
// This is called by Godot the first time it calls a virtual function, and it caches the result, per object instance.
|
||||||
@@ -308,23 +314,6 @@ GDExtensionClassCallVirtual ClassDB::get_virtual_func(void *p_userdata, GDExtens
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const GDExtensionInstanceBindingCallbacks *ClassDB::get_instance_binding_callbacks(const StringName &p_class) {
|
|
||||||
std::unordered_map<StringName, const GDExtensionInstanceBindingCallbacks *>::iterator callbacks_it = instance_binding_callbacks.find(p_class);
|
|
||||||
if (likely(callbacks_it != instance_binding_callbacks.end())) {
|
|
||||||
return callbacks_it->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we don't have an instance binding callback for the given class, find the closest parent where we do.
|
|
||||||
StringName class_name = p_class;
|
|
||||||
do {
|
|
||||||
class_name = get_parent_class(class_name);
|
|
||||||
ERR_FAIL_COND_V_MSG(class_name == StringName(), nullptr, String("Cannot find instance binding callbacks for class '{0}'.").format(Array::make(p_class)));
|
|
||||||
callbacks_it = instance_binding_callbacks.find(class_name);
|
|
||||||
} while (callbacks_it == instance_binding_callbacks.end());
|
|
||||||
|
|
||||||
return callbacks_it->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClassDB::bind_virtual_method(const StringName &p_class, const StringName &p_method, GDExtensionClassCallVirtual p_call) {
|
void ClassDB::bind_virtual_method(const StringName &p_class, const StringName &p_method, GDExtensionClassCallVirtual p_call) {
|
||||||
std::unordered_map<StringName, ClassInfo>::iterator type_it = classes.find(p_class);
|
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)));
|
ERR_FAIL_COND_MSG(type_it == classes.end(), String("Class '{0}' doesn't exist.").format(Array::make(p_class)));
|
||||||
@@ -352,31 +341,17 @@ void ClassDB::initialize(GDExtensionInitializationLevel p_level) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ClassDB::deinitialize(GDExtensionInitializationLevel p_level) {
|
void ClassDB::deinitialize(GDExtensionInitializationLevel p_level) {
|
||||||
std::set<StringName> to_erase;
|
for (const std::pair<StringName, ClassInfo> pair : classes) {
|
||||||
for (std::vector<StringName>::reverse_iterator i = class_register_order.rbegin(); i != class_register_order.rend(); ++i) {
|
const ClassInfo &cl = pair.second;
|
||||||
const StringName &name = *i;
|
|
||||||
const ClassInfo &cl = classes[name];
|
|
||||||
|
|
||||||
if (cl.level != p_level) {
|
if (cl.level != p_level) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal::gdextension_interface_classdb_unregister_extension_class(internal::library, name._native_ptr());
|
internal::gde_interface->classdb_unregister_extension_class(internal::library, cl.name._native_ptr());
|
||||||
|
|
||||||
for (const std::pair<const StringName, MethodBind *> &method : cl.method_map) {
|
for (auto method : cl.method_map) {
|
||||||
memdelete(method.second);
|
memdelete(method.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
classes.erase(name);
|
|
||||||
to_erase.insert(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
// The following is equivalent to c++20 `std::erase_if(class_register_order, [&](const StringName& name){ return to_erase.contains(name); });`
|
|
||||||
std::vector<StringName>::iterator it = std::remove_if(class_register_order.begin(), class_register_order.end(), [&](const StringName &p_name) {
|
|
||||||
return to_erase.count(p_name) > 0;
|
|
||||||
});
|
|
||||||
class_register_order.erase(it, class_register_order.end());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,9 +39,9 @@ namespace godot {
|
|||||||
|
|
||||||
void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, bool p_editor_notify, bool p_is_warning) {
|
void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, bool p_editor_notify, bool p_is_warning) {
|
||||||
if (p_is_warning) {
|
if (p_is_warning) {
|
||||||
internal::gdextension_interface_print_warning(p_error, p_function, p_file, p_line, p_editor_notify);
|
internal::gde_interface->print_warning(p_error, p_function, p_file, p_line, p_editor_notify);
|
||||||
} else {
|
} else {
|
||||||
internal::gdextension_interface_print_error(p_error, p_function, p_file, p_line, p_editor_notify);
|
internal::gde_interface->print_error(p_error, p_function, p_file, p_line, p_editor_notify);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,9 +51,9 @@ void _err_print_error(const char *p_function, const char *p_file, int p_line, co
|
|||||||
|
|
||||||
void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_message, bool p_editor_notify, bool p_is_warning) {
|
void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_message, bool p_editor_notify, bool p_is_warning) {
|
||||||
if (p_is_warning) {
|
if (p_is_warning) {
|
||||||
internal::gdextension_interface_print_warning_with_message(p_error, p_message, p_function, p_file, p_line, p_editor_notify);
|
internal::gde_interface->print_warning_with_message(p_error, p_message, p_function, p_file, p_line, p_editor_notify);
|
||||||
} else {
|
} else {
|
||||||
internal::gdextension_interface_print_error_with_message(p_error, p_message, p_function, p_file, p_line, p_editor_notify);
|
internal::gde_interface->print_error_with_message(p_error, p_message, p_function, p_file, p_line, p_editor_notify);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,8 +41,8 @@ void *Memory::alloc_static(size_t p_bytes, bool p_pad_align) {
|
|||||||
bool prepad = p_pad_align;
|
bool prepad = p_pad_align;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void *mem = internal::gdextension_interface_mem_alloc(p_bytes + (prepad ? PAD_ALIGN : 0));
|
void *mem = internal::gde_interface->mem_alloc(p_bytes + (prepad ? PAD_ALIGN : 0));
|
||||||
ERR_FAIL_NULL_V(mem, nullptr);
|
ERR_FAIL_COND_V(!mem, nullptr);
|
||||||
|
|
||||||
if (prepad) {
|
if (prepad) {
|
||||||
uint8_t *s8 = (uint8_t *)mem;
|
uint8_t *s8 = (uint8_t *)mem;
|
||||||
@@ -70,11 +70,11 @@ void *Memory::realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align) {
|
|||||||
|
|
||||||
if (prepad) {
|
if (prepad) {
|
||||||
mem -= PAD_ALIGN;
|
mem -= PAD_ALIGN;
|
||||||
mem = (uint8_t *)internal::gdextension_interface_mem_realloc(mem, p_bytes + PAD_ALIGN);
|
mem = (uint8_t *)internal::gde_interface->mem_realloc(mem, p_bytes + PAD_ALIGN);
|
||||||
ERR_FAIL_NULL_V(mem, nullptr);
|
ERR_FAIL_COND_V(!mem, nullptr);
|
||||||
return mem + PAD_ALIGN;
|
return mem + PAD_ALIGN;
|
||||||
} else {
|
} else {
|
||||||
return (uint8_t *)internal::gdextension_interface_mem_realloc(mem, p_bytes);
|
return (uint8_t *)internal::gde_interface->mem_realloc(mem, p_bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@ void Memory::free_static(void *p_ptr, bool p_pad_align) {
|
|||||||
if (prepad) {
|
if (prepad) {
|
||||||
mem -= PAD_ALIGN;
|
mem -= PAD_ALIGN;
|
||||||
}
|
}
|
||||||
internal::gdextension_interface_mem_free(mem);
|
internal::gde_interface->mem_free(mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
_GlobalNil::_GlobalNil() {
|
_GlobalNil::_GlobalNil() {
|
||||||
@@ -103,29 +103,28 @@ _GlobalNil _GlobalNilClass::_nil;
|
|||||||
|
|
||||||
} // namespace godot
|
} // namespace godot
|
||||||
|
|
||||||
// p_dummy argument is added to avoid conflicts with the engine functions when both engine and GDExtension are built as a static library on iOS.
|
void *operator new(size_t p_size, const char *p_description) {
|
||||||
void *operator new(size_t p_size, const char *p_dummy, const char *p_description) {
|
|
||||||
return godot::Memory::alloc_static(p_size);
|
return godot::Memory::alloc_static(p_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *operator new(size_t p_size, const char *p_dummy, void *(*p_allocfunc)(size_t p_size)) {
|
void *operator new(size_t p_size, void *(*p_allocfunc)(size_t p_size)) {
|
||||||
return p_allocfunc(p_size);
|
return p_allocfunc(p_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace godot;
|
using namespace godot;
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
void operator delete(void *p_mem, const char *p_dummy, const char *p_description) {
|
void operator delete(void *p_mem, const char *p_description) {
|
||||||
ERR_PRINT("Call to placement delete should not happen.");
|
ERR_PRINT("Call to placement delete should not happen.");
|
||||||
CRASH_NOW();
|
CRASH_NOW();
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator delete(void *p_mem, const char *p_dummy, void *(*p_allocfunc)(size_t p_size)) {
|
void operator delete(void *p_mem, void *(*p_allocfunc)(size_t p_size)) {
|
||||||
ERR_PRINT("Call to placement delete should not happen.");
|
ERR_PRINT("Call to placement delete should not happen.");
|
||||||
CRASH_NOW();
|
CRASH_NOW();
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator delete(void *p_mem, const char *p_dummy, void *p_pointer, size_t check, const char *p_description) {
|
void operator delete(void *p_mem, void *p_pointer, size_t check, const char *p_description) {
|
||||||
ERR_PRINT("Call to placement delete should not happen.");
|
ERR_PRINT("Call to placement delete should not happen.");
|
||||||
CRASH_NOW();
|
CRASH_NOW();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ void MethodBind::bind_call(void *p_method_userdata, GDExtensionClassInstancePtr
|
|||||||
Variant ret = bind->call(p_instance, p_args, p_argument_count, *r_error);
|
Variant ret = bind->call(p_instance, p_args, p_argument_count, *r_error);
|
||||||
// This assumes the return value is an empty Variant, so it doesn't need to call the destructor first.
|
// This assumes the return value is an empty Variant, so it doesn't need to call the destructor first.
|
||||||
// Since only GDExtensionMethodBind calls this from the Godot side, it should always be the case.
|
// Since only GDExtensionMethodBind calls this from the Godot side, it should always be the case.
|
||||||
internal::gdextension_interface_variant_new_copy(r_return, ret._native_ptr());
|
internal::gde_interface->variant_new_copy(r_return, ret._native_ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MethodBind::bind_ptrcall(void *p_method_userdata, GDExtensionClassInstancePtr p_instance, const GDExtensionConstTypePtr *p_args, GDExtensionTypePtr r_return) {
|
void MethodBind::bind_ptrcall(void *p_method_userdata, GDExtensionClassInstancePtr p_instance, const GDExtensionConstTypePtr *p_args, GDExtensionTypePtr r_return) {
|
||||||
|
|||||||
@@ -30,38 +30,8 @@
|
|||||||
|
|
||||||
#include <godot_cpp/core/object.hpp>
|
#include <godot_cpp/core/object.hpp>
|
||||||
|
|
||||||
#include <godot_cpp/core/class_db.hpp>
|
|
||||||
|
|
||||||
namespace godot {
|
namespace godot {
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
Object *get_object_instance_binding(GodotObject *p_engine_object) {
|
|
||||||
if (p_engine_object == nullptr) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get existing instance binding, if one already exists.
|
|
||||||
GDExtensionObjectPtr instance = gdextension_interface_object_get_instance_binding(p_engine_object, token, nullptr);
|
|
||||||
if (instance != nullptr) {
|
|
||||||
return reinterpret_cast<Object *>(instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, try to look up the correct binding callbacks.
|
|
||||||
const GDExtensionInstanceBindingCallbacks *binding_callbacks = nullptr;
|
|
||||||
StringName class_name;
|
|
||||||
if (gdextension_interface_object_get_class_name(p_engine_object, library, reinterpret_cast<GDExtensionStringNamePtr>(class_name._native_ptr()))) {
|
|
||||||
binding_callbacks = ClassDB::get_instance_binding_callbacks(class_name);
|
|
||||||
}
|
|
||||||
if (binding_callbacks == nullptr) {
|
|
||||||
binding_callbacks = &Object::_gde_binding_callbacks;
|
|
||||||
}
|
|
||||||
|
|
||||||
return reinterpret_cast<Object *>(gdextension_interface_object_get_instance_binding(p_engine_object, token, binding_callbacks));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
MethodInfo::MethodInfo() :
|
MethodInfo::MethodInfo() :
|
||||||
flags(GDEXTENSION_METHOD_FLAG_NORMAL) {}
|
flags(GDEXTENSION_METHOD_FLAG_NORMAL) {}
|
||||||
|
|
||||||
|
|||||||
470
src/godot.cpp
470
src/godot.cpp
@@ -30,11 +30,9 @@
|
|||||||
|
|
||||||
#include <godot_cpp/godot.hpp>
|
#include <godot_cpp/godot.hpp>
|
||||||
|
|
||||||
#include <godot_cpp/classes/editor_plugin_registration.hpp>
|
|
||||||
#include <godot_cpp/classes/wrapped.hpp>
|
#include <godot_cpp/classes/wrapped.hpp>
|
||||||
#include <godot_cpp/core/class_db.hpp>
|
#include <godot_cpp/core/class_db.hpp>
|
||||||
#include <godot_cpp/core/memory.hpp>
|
#include <godot_cpp/core/memory.hpp>
|
||||||
#include <godot_cpp/core/version.hpp>
|
|
||||||
#include <godot_cpp/variant/variant.hpp>
|
#include <godot_cpp/variant/variant.hpp>
|
||||||
|
|
||||||
#include <godot_cpp/core/error_macros.hpp>
|
#include <godot_cpp/core/error_macros.hpp>
|
||||||
@@ -43,481 +41,77 @@ namespace godot {
|
|||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
GDExtensionInterfaceGetProcAddress gdextension_interface_get_proc_address = nullptr;
|
const GDExtensionInterface *gde_interface = nullptr;
|
||||||
GDExtensionClassLibraryPtr library = nullptr;
|
GDExtensionClassLibraryPtr library = nullptr;
|
||||||
void *token = nullptr;
|
void *token = nullptr;
|
||||||
|
|
||||||
GDExtensionGodotVersion godot_version = { 0, 0, 0, nullptr };
|
|
||||||
|
|
||||||
// All of the GDExtension interface functions.
|
|
||||||
GDExtensionInterfaceGetGodotVersion gdextension_interface_get_godot_version = nullptr;
|
|
||||||
GDExtensionInterfaceMemAlloc gdextension_interface_mem_alloc = nullptr;
|
|
||||||
GDExtensionInterfaceMemRealloc gdextension_interface_mem_realloc = nullptr;
|
|
||||||
GDExtensionInterfaceMemFree gdextension_interface_mem_free = nullptr;
|
|
||||||
GDExtensionInterfacePrintError gdextension_interface_print_error = nullptr;
|
|
||||||
GDExtensionInterfacePrintErrorWithMessage gdextension_interface_print_error_with_message = nullptr;
|
|
||||||
GDExtensionInterfacePrintWarning gdextension_interface_print_warning = nullptr;
|
|
||||||
GDExtensionInterfacePrintWarningWithMessage gdextension_interface_print_warning_with_message = nullptr;
|
|
||||||
GDExtensionInterfacePrintScriptError gdextension_interface_print_script_error = nullptr;
|
|
||||||
GDExtensionInterfacePrintScriptErrorWithMessage gdextension_interface_print_script_error_with_message = nullptr;
|
|
||||||
GDExtensionInterfaceGetNativeStructSize gdextension_interface_get_native_struct_size = nullptr;
|
|
||||||
GDExtensionInterfaceVariantNewCopy gdextension_interface_variant_new_copy = nullptr;
|
|
||||||
GDExtensionInterfaceVariantNewNil gdextension_interface_variant_new_nil = nullptr;
|
|
||||||
GDExtensionInterfaceVariantDestroy gdextension_interface_variant_destroy = nullptr;
|
|
||||||
GDExtensionInterfaceVariantCall gdextension_interface_variant_call = nullptr;
|
|
||||||
GDExtensionInterfaceVariantCallStatic gdextension_interface_variant_call_static = nullptr;
|
|
||||||
GDExtensionInterfaceVariantEvaluate gdextension_interface_variant_evaluate = nullptr;
|
|
||||||
GDExtensionInterfaceVariantSet gdextension_interface_variant_set = nullptr;
|
|
||||||
GDExtensionInterfaceVariantSetNamed gdextension_interface_variant_set_named = nullptr;
|
|
||||||
GDExtensionInterfaceVariantSetKeyed gdextension_interface_variant_set_keyed = nullptr;
|
|
||||||
GDExtensionInterfaceVariantSetIndexed gdextension_interface_variant_set_indexed = nullptr;
|
|
||||||
GDExtensionInterfaceVariantGet gdextension_interface_variant_get = nullptr;
|
|
||||||
GDExtensionInterfaceVariantGetNamed gdextension_interface_variant_get_named = nullptr;
|
|
||||||
GDExtensionInterfaceVariantGetKeyed gdextension_interface_variant_get_keyed = nullptr;
|
|
||||||
GDExtensionInterfaceVariantGetIndexed gdextension_interface_variant_get_indexed = nullptr;
|
|
||||||
GDExtensionInterfaceVariantIterInit gdextension_interface_variant_iter_init = nullptr;
|
|
||||||
GDExtensionInterfaceVariantIterNext gdextension_interface_variant_iter_next = nullptr;
|
|
||||||
GDExtensionInterfaceVariantIterGet gdextension_interface_variant_iter_get = nullptr;
|
|
||||||
GDExtensionInterfaceVariantHash gdextension_interface_variant_hash = nullptr;
|
|
||||||
GDExtensionInterfaceVariantRecursiveHash gdextension_interface_variant_recursive_hash = nullptr;
|
|
||||||
GDExtensionInterfaceVariantHashCompare gdextension_interface_variant_hash_compare = nullptr;
|
|
||||||
GDExtensionInterfaceVariantBooleanize gdextension_interface_variant_booleanize = nullptr;
|
|
||||||
GDExtensionInterfaceVariantDuplicate gdextension_interface_variant_duplicate = nullptr;
|
|
||||||
GDExtensionInterfaceVariantStringify gdextension_interface_variant_stringify = nullptr;
|
|
||||||
GDExtensionInterfaceVariantGetType gdextension_interface_variant_get_type = nullptr;
|
|
||||||
GDExtensionInterfaceVariantHasMethod gdextension_interface_variant_has_method = nullptr;
|
|
||||||
GDExtensionInterfaceVariantHasMember gdextension_interface_variant_has_member = nullptr;
|
|
||||||
GDExtensionInterfaceVariantHasKey gdextension_interface_variant_has_key = nullptr;
|
|
||||||
GDExtensionInterfaceVariantGetTypeName gdextension_interface_variant_get_type_name = nullptr;
|
|
||||||
GDExtensionInterfaceVariantCanConvert gdextension_interface_variant_can_convert = nullptr;
|
|
||||||
GDExtensionInterfaceVariantCanConvertStrict gdextension_interface_variant_can_convert_strict = nullptr;
|
|
||||||
GDExtensionInterfaceGetVariantFromTypeConstructor gdextension_interface_get_variant_from_type_constructor = nullptr;
|
|
||||||
GDExtensionInterfaceGetVariantToTypeConstructor gdextension_interface_get_variant_to_type_constructor = nullptr;
|
|
||||||
GDExtensionInterfaceVariantGetPtrOperatorEvaluator gdextension_interface_variant_get_ptr_operator_evaluator = nullptr;
|
|
||||||
GDExtensionInterfaceVariantGetPtrBuiltinMethod gdextension_interface_variant_get_ptr_builtin_method = nullptr;
|
|
||||||
GDExtensionInterfaceVariantGetPtrConstructor gdextension_interface_variant_get_ptr_constructor = nullptr;
|
|
||||||
GDExtensionInterfaceVariantGetPtrDestructor gdextension_interface_variant_get_ptr_destructor = nullptr;
|
|
||||||
GDExtensionInterfaceVariantConstruct gdextension_interface_variant_construct = nullptr;
|
|
||||||
GDExtensionInterfaceVariantGetPtrSetter gdextension_interface_variant_get_ptr_setter = nullptr;
|
|
||||||
GDExtensionInterfaceVariantGetPtrGetter gdextension_interface_variant_get_ptr_getter = nullptr;
|
|
||||||
GDExtensionInterfaceVariantGetPtrIndexedSetter gdextension_interface_variant_get_ptr_indexed_setter = nullptr;
|
|
||||||
GDExtensionInterfaceVariantGetPtrIndexedGetter gdextension_interface_variant_get_ptr_indexed_getter = nullptr;
|
|
||||||
GDExtensionInterfaceVariantGetPtrKeyedSetter gdextension_interface_variant_get_ptr_keyed_setter = nullptr;
|
|
||||||
GDExtensionInterfaceVariantGetPtrKeyedGetter gdextension_interface_variant_get_ptr_keyed_getter = nullptr;
|
|
||||||
GDExtensionInterfaceVariantGetPtrKeyedChecker gdextension_interface_variant_get_ptr_keyed_checker = nullptr;
|
|
||||||
GDExtensionInterfaceVariantGetConstantValue gdextension_interface_variant_get_constant_value = nullptr;
|
|
||||||
GDExtensionInterfaceVariantGetPtrUtilityFunction gdextension_interface_variant_get_ptr_utility_function = nullptr;
|
|
||||||
GDExtensionInterfaceStringNewWithLatin1Chars gdextension_interface_string_new_with_latin1_chars = nullptr;
|
|
||||||
GDExtensionInterfaceStringNewWithUtf8Chars gdextension_interface_string_new_with_utf8_chars = nullptr;
|
|
||||||
GDExtensionInterfaceStringNewWithUtf16Chars gdextension_interface_string_new_with_utf16_chars = nullptr;
|
|
||||||
GDExtensionInterfaceStringNewWithUtf32Chars gdextension_interface_string_new_with_utf32_chars = nullptr;
|
|
||||||
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;
|
|
||||||
GDExtensionInterfaceStringNewWithUtf16CharsAndLen gdextension_interface_string_new_with_utf16_chars_and_len = 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;
|
|
||||||
GDExtensionInterfaceStringToUtf8Chars gdextension_interface_string_to_utf8_chars = nullptr;
|
|
||||||
GDExtensionInterfaceStringToUtf16Chars gdextension_interface_string_to_utf16_chars = nullptr;
|
|
||||||
GDExtensionInterfaceStringToUtf32Chars gdextension_interface_string_to_utf32_chars = nullptr;
|
|
||||||
GDExtensionInterfaceStringToWideChars gdextension_interface_string_to_wide_chars = nullptr;
|
|
||||||
GDExtensionInterfaceStringOperatorIndex gdextension_interface_string_operator_index = nullptr;
|
|
||||||
GDExtensionInterfaceStringOperatorIndexConst gdextension_interface_string_operator_index_const = nullptr;
|
|
||||||
GDExtensionInterfaceStringOperatorPlusEqString gdextension_interface_string_operator_plus_eq_string = nullptr;
|
|
||||||
GDExtensionInterfaceStringOperatorPlusEqChar gdextension_interface_string_operator_plus_eq_char = nullptr;
|
|
||||||
GDExtensionInterfaceStringOperatorPlusEqCstr gdextension_interface_string_operator_plus_eq_cstr = nullptr;
|
|
||||||
GDExtensionInterfaceStringOperatorPlusEqWcstr gdextension_interface_string_operator_plus_eq_wcstr = nullptr;
|
|
||||||
GDExtensionInterfaceStringOperatorPlusEqC32str gdextension_interface_string_operator_plus_eq_c32str = nullptr;
|
|
||||||
GDExtensionInterfaceStringResize gdextension_interface_string_resize = nullptr;
|
|
||||||
GDExtensionInterfaceStringNameNewWithLatin1Chars gdextension_interface_string_name_new_with_latin1_chars = nullptr;
|
|
||||||
GDExtensionInterfaceXmlParserOpenBuffer gdextension_interface_xml_parser_open_buffer = nullptr;
|
|
||||||
GDExtensionInterfaceFileAccessStoreBuffer gdextension_interface_file_access_store_buffer = nullptr;
|
|
||||||
GDExtensionInterfaceFileAccessGetBuffer gdextension_interface_file_access_get_buffer = nullptr;
|
|
||||||
GDExtensionInterfaceWorkerThreadPoolAddNativeGroupTask gdextension_interface_worker_thread_pool_add_native_group_task = nullptr;
|
|
||||||
GDExtensionInterfaceWorkerThreadPoolAddNativeTask gdextension_interface_worker_thread_pool_add_native_task = nullptr;
|
|
||||||
GDExtensionInterfacePackedByteArrayOperatorIndex gdextension_interface_packed_byte_array_operator_index = nullptr;
|
|
||||||
GDExtensionInterfacePackedByteArrayOperatorIndexConst gdextension_interface_packed_byte_array_operator_index_const = nullptr;
|
|
||||||
GDExtensionInterfacePackedColorArrayOperatorIndex gdextension_interface_packed_color_array_operator_index = nullptr;
|
|
||||||
GDExtensionInterfacePackedColorArrayOperatorIndexConst gdextension_interface_packed_color_array_operator_index_const = nullptr;
|
|
||||||
GDExtensionInterfacePackedFloat32ArrayOperatorIndex gdextension_interface_packed_float32_array_operator_index = nullptr;
|
|
||||||
GDExtensionInterfacePackedFloat32ArrayOperatorIndexConst gdextension_interface_packed_float32_array_operator_index_const = nullptr;
|
|
||||||
GDExtensionInterfacePackedFloat64ArrayOperatorIndex gdextension_interface_packed_float64_array_operator_index = nullptr;
|
|
||||||
GDExtensionInterfacePackedFloat64ArrayOperatorIndexConst gdextension_interface_packed_float64_array_operator_index_const = nullptr;
|
|
||||||
GDExtensionInterfacePackedInt32ArrayOperatorIndex gdextension_interface_packed_int32_array_operator_index = nullptr;
|
|
||||||
GDExtensionInterfacePackedInt32ArrayOperatorIndexConst gdextension_interface_packed_int32_array_operator_index_const = nullptr;
|
|
||||||
GDExtensionInterfacePackedInt64ArrayOperatorIndex gdextension_interface_packed_int64_array_operator_index = nullptr;
|
|
||||||
GDExtensionInterfacePackedInt64ArrayOperatorIndexConst gdextension_interface_packed_int64_array_operator_index_const = nullptr;
|
|
||||||
GDExtensionInterfacePackedStringArrayOperatorIndex gdextension_interface_packed_string_array_operator_index = nullptr;
|
|
||||||
GDExtensionInterfacePackedStringArrayOperatorIndexConst gdextension_interface_packed_string_array_operator_index_const = nullptr;
|
|
||||||
GDExtensionInterfacePackedVector2ArrayOperatorIndex gdextension_interface_packed_vector2_array_operator_index = nullptr;
|
|
||||||
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;
|
|
||||||
GDExtensionInterfaceArrayOperatorIndex gdextension_interface_array_operator_index = nullptr;
|
|
||||||
GDExtensionInterfaceArrayOperatorIndexConst gdextension_interface_array_operator_index_const = nullptr;
|
|
||||||
GDExtensionInterfaceArrayRef gdextension_interface_array_ref = nullptr;
|
|
||||||
GDExtensionInterfaceArraySetTyped gdextension_interface_array_set_typed = nullptr;
|
|
||||||
GDExtensionInterfaceDictionaryOperatorIndex gdextension_interface_dictionary_operator_index = nullptr;
|
|
||||||
GDExtensionInterfaceDictionaryOperatorIndexConst gdextension_interface_dictionary_operator_index_const = nullptr;
|
|
||||||
GDExtensionInterfaceObjectMethodBindCall gdextension_interface_object_method_bind_call = nullptr;
|
|
||||||
GDExtensionInterfaceObjectMethodBindPtrcall gdextension_interface_object_method_bind_ptrcall = nullptr;
|
|
||||||
GDExtensionInterfaceObjectDestroy gdextension_interface_object_destroy = nullptr;
|
|
||||||
GDExtensionInterfaceGlobalGetSingleton gdextension_interface_global_get_singleton = nullptr;
|
|
||||||
GDExtensionInterfaceObjectGetInstanceBinding gdextension_interface_object_get_instance_binding = nullptr;
|
|
||||||
GDExtensionInterfaceObjectSetInstanceBinding gdextension_interface_object_set_instance_binding = nullptr;
|
|
||||||
GDExtensionInterfaceObjectSetInstance gdextension_interface_object_set_instance = nullptr;
|
|
||||||
GDExtensionInterfaceObjectGetClassName gdextension_interface_object_get_class_name = nullptr;
|
|
||||||
GDExtensionInterfaceObjectCastTo gdextension_interface_object_cast_to = nullptr;
|
|
||||||
GDExtensionInterfaceObjectGetInstanceFromId gdextension_interface_object_get_instance_from_id = nullptr;
|
|
||||||
GDExtensionInterfaceObjectGetInstanceId gdextension_interface_object_get_instance_id = 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;
|
|
||||||
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;
|
|
||||||
GDExtensionInterfaceClassdbRegisterExtensionClass2 gdextension_interface_classdb_register_extension_class2 = nullptr;
|
|
||||||
GDExtensionInterfaceClassdbRegisterExtensionClassMethod gdextension_interface_classdb_register_extension_class_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;
|
|
||||||
GDExtensionInterfaceClassdbRegisterExtensionClassPropertyGroup gdextension_interface_classdb_register_extension_class_property_group = nullptr;
|
|
||||||
GDExtensionInterfaceClassdbRegisterExtensionClassPropertySubgroup gdextension_interface_classdb_register_extension_class_property_subgroup = nullptr;
|
|
||||||
GDExtensionInterfaceClassdbRegisterExtensionClassSignal gdextension_interface_classdb_register_extension_class_signal = nullptr;
|
|
||||||
GDExtensionInterfaceClassdbUnregisterExtensionClass gdextension_interface_classdb_unregister_extension_class = nullptr;
|
|
||||||
GDExtensionInterfaceGetLibraryPath gdextension_interface_get_library_path = nullptr;
|
|
||||||
GDExtensionInterfaceEditorAddPlugin gdextension_interface_editor_add_plugin = nullptr;
|
|
||||||
GDExtensionInterfaceEditorRemovePlugin gdextension_interface_editor_remove_plugin = nullptr;
|
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
bool GDExtensionBinding::api_initialized = false;
|
GDExtensionBinding::Callback GDExtensionBinding::init_callback = nullptr;
|
||||||
int GDExtensionBinding::level_initialized[MODULE_INITIALIZATION_LEVEL_MAX] = { 0 };
|
GDExtensionBinding::Callback GDExtensionBinding::terminate_callback = nullptr;
|
||||||
GDExtensionBinding::InitDataList GDExtensionBinding::initdata;
|
GDExtensionInitializationLevel GDExtensionBinding::minimum_initialization_level = GDEXTENSION_INITIALIZATION_CORE;
|
||||||
|
|
||||||
#define ERR_PRINT_EARLY(m_msg) \
|
GDExtensionBool GDExtensionBinding::init(const GDExtensionInterface *p_interface, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) {
|
||||||
internal::gdextension_interface_print_error(m_msg, FUNCTION_STR, __FILE__, __LINE__, false)
|
internal::gde_interface = p_interface;
|
||||||
|
|
||||||
#define LOAD_PROC_ADDRESS(m_name, m_type) \
|
|
||||||
internal::gdextension_interface_##m_name = (m_type)p_get_proc_address(#m_name); \
|
|
||||||
if (!internal::gdextension_interface_##m_name) { \
|
|
||||||
ERR_PRINT_EARLY("Unable to load GDExtension interface function " #m_name "()"); \
|
|
||||||
return false; \
|
|
||||||
}
|
|
||||||
|
|
||||||
// Partial definition of the legacy interface so we can detect it and show an error.
|
|
||||||
typedef struct {
|
|
||||||
uint32_t version_major;
|
|
||||||
uint32_t version_minor;
|
|
||||||
uint32_t version_patch;
|
|
||||||
const char *version_string;
|
|
||||||
|
|
||||||
GDExtensionInterfaceFunctionPtr unused1;
|
|
||||||
GDExtensionInterfaceFunctionPtr unused2;
|
|
||||||
GDExtensionInterfaceFunctionPtr unused3;
|
|
||||||
|
|
||||||
GDExtensionInterfacePrintError print_error;
|
|
||||||
GDExtensionInterfacePrintErrorWithMessage print_error_with_message;
|
|
||||||
} LegacyGDExtensionInterface;
|
|
||||||
|
|
||||||
GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, InitData *p_init_data, GDExtensionInitialization *r_initialization) {
|
|
||||||
if (!p_init_data || !p_init_data->init_callback) {
|
|
||||||
ERR_FAIL_V_MSG(false, "Initialization callback must be defined.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (api_initialized) {
|
|
||||||
r_initialization->initialize = initialize_level;
|
|
||||||
r_initialization->deinitialize = deinitialize_level;
|
|
||||||
r_initialization->userdata = p_init_data;
|
|
||||||
r_initialization->minimum_initialization_level = p_init_data->minimum_initialization_level;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure we weren't passed the legacy struct.
|
|
||||||
uint32_t *raw_interface = (uint32_t *)(void *)p_get_proc_address;
|
|
||||||
if (raw_interface[0] == 4 && raw_interface[1] == 0) {
|
|
||||||
// Use the legacy interface only to give a nice error.
|
|
||||||
LegacyGDExtensionInterface *legacy_interface = (LegacyGDExtensionInterface *)p_get_proc_address;
|
|
||||||
internal::gdextension_interface_print_error = (GDExtensionInterfacePrintError)legacy_interface->print_error;
|
|
||||||
ERR_PRINT_EARLY("Cannot load a GDExtension built for Godot 4.1+ in Godot 4.0.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load the "print_error" function first (needed by the ERR_PRINT_EARLY() macro).
|
|
||||||
internal::gdextension_interface_print_error = (GDExtensionInterfacePrintError)p_get_proc_address("print_error");
|
|
||||||
if (!internal::gdextension_interface_print_error) {
|
|
||||||
printf("ERROR: Unable to load GDExtension interface function print_error().\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal::gdextension_interface_get_proc_address = p_get_proc_address;
|
|
||||||
internal::library = p_library;
|
internal::library = p_library;
|
||||||
internal::token = p_library;
|
internal::token = p_library;
|
||||||
|
|
||||||
LOAD_PROC_ADDRESS(get_godot_version, GDExtensionInterfaceGetGodotVersion);
|
|
||||||
internal::gdextension_interface_get_godot_version(&internal::godot_version);
|
|
||||||
|
|
||||||
// Check that godot-cpp was compiled using an extension_api.json older or at the
|
|
||||||
// same version as the Godot that is loading it.
|
|
||||||
bool compatible;
|
|
||||||
if (internal::godot_version.major != GODOT_VERSION_MAJOR) {
|
|
||||||
compatible = internal::godot_version.major > GODOT_VERSION_MAJOR;
|
|
||||||
} else if (internal::godot_version.minor != GODOT_VERSION_MINOR) {
|
|
||||||
compatible = internal::godot_version.minor > GODOT_VERSION_MINOR;
|
|
||||||
} else {
|
|
||||||
compatible = internal::godot_version.patch >= GODOT_VERSION_PATCH;
|
|
||||||
}
|
|
||||||
if (!compatible) {
|
|
||||||
// We need to use snprintf() here because vformat() uses Variant, and we haven't loaded
|
|
||||||
// the GDExtension interface far enough to use Variants yet.
|
|
||||||
char msg[128];
|
|
||||||
snprintf(msg, 128, "Cannot load a GDExtension built for Godot %d.%d.%d using an older version of Godot (%d.%d.%d).",
|
|
||||||
GODOT_VERSION_MAJOR, GODOT_VERSION_MINOR, GODOT_VERSION_PATCH,
|
|
||||||
internal::godot_version.major, internal::godot_version.minor, internal::godot_version.patch);
|
|
||||||
ERR_PRINT_EARLY(msg);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOAD_PROC_ADDRESS(mem_alloc, GDExtensionInterfaceMemAlloc);
|
|
||||||
LOAD_PROC_ADDRESS(mem_realloc, GDExtensionInterfaceMemRealloc);
|
|
||||||
LOAD_PROC_ADDRESS(mem_free, GDExtensionInterfaceMemFree);
|
|
||||||
LOAD_PROC_ADDRESS(print_error_with_message, GDExtensionInterfacePrintErrorWithMessage);
|
|
||||||
LOAD_PROC_ADDRESS(print_warning, GDExtensionInterfacePrintWarning);
|
|
||||||
LOAD_PROC_ADDRESS(print_warning_with_message, GDExtensionInterfacePrintWarningWithMessage);
|
|
||||||
LOAD_PROC_ADDRESS(print_script_error, GDExtensionInterfacePrintScriptError);
|
|
||||||
LOAD_PROC_ADDRESS(print_script_error_with_message, GDExtensionInterfacePrintScriptErrorWithMessage);
|
|
||||||
LOAD_PROC_ADDRESS(get_native_struct_size, GDExtensionInterfaceGetNativeStructSize);
|
|
||||||
LOAD_PROC_ADDRESS(variant_new_copy, GDExtensionInterfaceVariantNewCopy);
|
|
||||||
LOAD_PROC_ADDRESS(variant_new_nil, GDExtensionInterfaceVariantNewNil);
|
|
||||||
LOAD_PROC_ADDRESS(variant_destroy, GDExtensionInterfaceVariantDestroy);
|
|
||||||
LOAD_PROC_ADDRESS(variant_call, GDExtensionInterfaceVariantCall);
|
|
||||||
LOAD_PROC_ADDRESS(variant_call_static, GDExtensionInterfaceVariantCallStatic);
|
|
||||||
LOAD_PROC_ADDRESS(variant_evaluate, GDExtensionInterfaceVariantEvaluate);
|
|
||||||
LOAD_PROC_ADDRESS(variant_set, GDExtensionInterfaceVariantSet);
|
|
||||||
LOAD_PROC_ADDRESS(variant_set_named, GDExtensionInterfaceVariantSetNamed);
|
|
||||||
LOAD_PROC_ADDRESS(variant_set_keyed, GDExtensionInterfaceVariantSetKeyed);
|
|
||||||
LOAD_PROC_ADDRESS(variant_set_indexed, GDExtensionInterfaceVariantSetIndexed);
|
|
||||||
LOAD_PROC_ADDRESS(variant_get, GDExtensionInterfaceVariantGet);
|
|
||||||
LOAD_PROC_ADDRESS(variant_get_named, GDExtensionInterfaceVariantGetNamed);
|
|
||||||
LOAD_PROC_ADDRESS(variant_get_keyed, GDExtensionInterfaceVariantGetKeyed);
|
|
||||||
LOAD_PROC_ADDRESS(variant_get_indexed, GDExtensionInterfaceVariantGetIndexed);
|
|
||||||
LOAD_PROC_ADDRESS(variant_iter_init, GDExtensionInterfaceVariantIterInit);
|
|
||||||
LOAD_PROC_ADDRESS(variant_iter_next, GDExtensionInterfaceVariantIterNext);
|
|
||||||
LOAD_PROC_ADDRESS(variant_iter_get, GDExtensionInterfaceVariantIterGet);
|
|
||||||
LOAD_PROC_ADDRESS(variant_hash, GDExtensionInterfaceVariantHash);
|
|
||||||
LOAD_PROC_ADDRESS(variant_recursive_hash, GDExtensionInterfaceVariantRecursiveHash);
|
|
||||||
LOAD_PROC_ADDRESS(variant_hash_compare, GDExtensionInterfaceVariantHashCompare);
|
|
||||||
LOAD_PROC_ADDRESS(variant_booleanize, GDExtensionInterfaceVariantBooleanize);
|
|
||||||
LOAD_PROC_ADDRESS(variant_duplicate, GDExtensionInterfaceVariantDuplicate);
|
|
||||||
LOAD_PROC_ADDRESS(variant_stringify, GDExtensionInterfaceVariantStringify);
|
|
||||||
LOAD_PROC_ADDRESS(variant_get_type, GDExtensionInterfaceVariantGetType);
|
|
||||||
LOAD_PROC_ADDRESS(variant_has_method, GDExtensionInterfaceVariantHasMethod);
|
|
||||||
LOAD_PROC_ADDRESS(variant_has_member, GDExtensionInterfaceVariantHasMember);
|
|
||||||
LOAD_PROC_ADDRESS(variant_has_key, GDExtensionInterfaceVariantHasKey);
|
|
||||||
LOAD_PROC_ADDRESS(variant_get_type_name, GDExtensionInterfaceVariantGetTypeName);
|
|
||||||
LOAD_PROC_ADDRESS(variant_can_convert, GDExtensionInterfaceVariantCanConvert);
|
|
||||||
LOAD_PROC_ADDRESS(variant_can_convert_strict, GDExtensionInterfaceVariantCanConvertStrict);
|
|
||||||
LOAD_PROC_ADDRESS(get_variant_from_type_constructor, GDExtensionInterfaceGetVariantFromTypeConstructor);
|
|
||||||
LOAD_PROC_ADDRESS(get_variant_to_type_constructor, GDExtensionInterfaceGetVariantToTypeConstructor);
|
|
||||||
LOAD_PROC_ADDRESS(variant_get_ptr_operator_evaluator, GDExtensionInterfaceVariantGetPtrOperatorEvaluator);
|
|
||||||
LOAD_PROC_ADDRESS(variant_get_ptr_builtin_method, GDExtensionInterfaceVariantGetPtrBuiltinMethod);
|
|
||||||
LOAD_PROC_ADDRESS(variant_get_ptr_constructor, GDExtensionInterfaceVariantGetPtrConstructor);
|
|
||||||
LOAD_PROC_ADDRESS(variant_get_ptr_destructor, GDExtensionInterfaceVariantGetPtrDestructor);
|
|
||||||
LOAD_PROC_ADDRESS(variant_construct, GDExtensionInterfaceVariantConstruct);
|
|
||||||
LOAD_PROC_ADDRESS(variant_get_ptr_setter, GDExtensionInterfaceVariantGetPtrSetter);
|
|
||||||
LOAD_PROC_ADDRESS(variant_get_ptr_getter, GDExtensionInterfaceVariantGetPtrGetter);
|
|
||||||
LOAD_PROC_ADDRESS(variant_get_ptr_indexed_setter, GDExtensionInterfaceVariantGetPtrIndexedSetter);
|
|
||||||
LOAD_PROC_ADDRESS(variant_get_ptr_indexed_getter, GDExtensionInterfaceVariantGetPtrIndexedGetter);
|
|
||||||
LOAD_PROC_ADDRESS(variant_get_ptr_keyed_setter, GDExtensionInterfaceVariantGetPtrKeyedSetter);
|
|
||||||
LOAD_PROC_ADDRESS(variant_get_ptr_keyed_getter, GDExtensionInterfaceVariantGetPtrKeyedGetter);
|
|
||||||
LOAD_PROC_ADDRESS(variant_get_ptr_keyed_checker, GDExtensionInterfaceVariantGetPtrKeyedChecker);
|
|
||||||
LOAD_PROC_ADDRESS(variant_get_constant_value, GDExtensionInterfaceVariantGetConstantValue);
|
|
||||||
LOAD_PROC_ADDRESS(variant_get_ptr_utility_function, GDExtensionInterfaceVariantGetPtrUtilityFunction);
|
|
||||||
LOAD_PROC_ADDRESS(string_new_with_latin1_chars, GDExtensionInterfaceStringNewWithLatin1Chars);
|
|
||||||
LOAD_PROC_ADDRESS(string_new_with_utf8_chars, GDExtensionInterfaceStringNewWithUtf8Chars);
|
|
||||||
LOAD_PROC_ADDRESS(string_new_with_utf16_chars, GDExtensionInterfaceStringNewWithUtf16Chars);
|
|
||||||
LOAD_PROC_ADDRESS(string_new_with_utf32_chars, GDExtensionInterfaceStringNewWithUtf32Chars);
|
|
||||||
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_utf16_chars_and_len, GDExtensionInterfaceStringNewWithUtf16CharsAndLen);
|
|
||||||
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);
|
|
||||||
LOAD_PROC_ADDRESS(string_to_utf8_chars, GDExtensionInterfaceStringToUtf8Chars);
|
|
||||||
LOAD_PROC_ADDRESS(string_to_utf16_chars, GDExtensionInterfaceStringToUtf16Chars);
|
|
||||||
LOAD_PROC_ADDRESS(string_to_utf32_chars, GDExtensionInterfaceStringToUtf32Chars);
|
|
||||||
LOAD_PROC_ADDRESS(string_to_wide_chars, GDExtensionInterfaceStringToWideChars);
|
|
||||||
LOAD_PROC_ADDRESS(string_operator_index, GDExtensionInterfaceStringOperatorIndex);
|
|
||||||
LOAD_PROC_ADDRESS(string_operator_index_const, GDExtensionInterfaceStringOperatorIndexConst);
|
|
||||||
LOAD_PROC_ADDRESS(string_operator_plus_eq_string, GDExtensionInterfaceStringOperatorPlusEqString);
|
|
||||||
LOAD_PROC_ADDRESS(string_operator_plus_eq_char, GDExtensionInterfaceStringOperatorPlusEqChar);
|
|
||||||
LOAD_PROC_ADDRESS(string_operator_plus_eq_cstr, GDExtensionInterfaceStringOperatorPlusEqCstr);
|
|
||||||
LOAD_PROC_ADDRESS(string_operator_plus_eq_wcstr, GDExtensionInterfaceStringOperatorPlusEqWcstr);
|
|
||||||
LOAD_PROC_ADDRESS(string_operator_plus_eq_c32str, GDExtensionInterfaceStringOperatorPlusEqC32str);
|
|
||||||
LOAD_PROC_ADDRESS(string_resize, GDExtensionInterfaceStringResize);
|
|
||||||
LOAD_PROC_ADDRESS(string_name_new_with_latin1_chars, GDExtensionInterfaceStringNameNewWithLatin1Chars);
|
|
||||||
LOAD_PROC_ADDRESS(xml_parser_open_buffer, GDExtensionInterfaceXmlParserOpenBuffer);
|
|
||||||
LOAD_PROC_ADDRESS(file_access_store_buffer, GDExtensionInterfaceFileAccessStoreBuffer);
|
|
||||||
LOAD_PROC_ADDRESS(file_access_get_buffer, GDExtensionInterfaceFileAccessGetBuffer);
|
|
||||||
LOAD_PROC_ADDRESS(worker_thread_pool_add_native_group_task, GDExtensionInterfaceWorkerThreadPoolAddNativeGroupTask);
|
|
||||||
LOAD_PROC_ADDRESS(worker_thread_pool_add_native_task, GDExtensionInterfaceWorkerThreadPoolAddNativeTask);
|
|
||||||
LOAD_PROC_ADDRESS(packed_byte_array_operator_index, GDExtensionInterfacePackedByteArrayOperatorIndex);
|
|
||||||
LOAD_PROC_ADDRESS(packed_byte_array_operator_index_const, GDExtensionInterfacePackedByteArrayOperatorIndexConst);
|
|
||||||
LOAD_PROC_ADDRESS(packed_color_array_operator_index, GDExtensionInterfacePackedColorArrayOperatorIndex);
|
|
||||||
LOAD_PROC_ADDRESS(packed_color_array_operator_index_const, GDExtensionInterfacePackedColorArrayOperatorIndexConst);
|
|
||||||
LOAD_PROC_ADDRESS(packed_float32_array_operator_index, GDExtensionInterfacePackedFloat32ArrayOperatorIndex);
|
|
||||||
LOAD_PROC_ADDRESS(packed_float32_array_operator_index_const, GDExtensionInterfacePackedFloat32ArrayOperatorIndexConst);
|
|
||||||
LOAD_PROC_ADDRESS(packed_float64_array_operator_index, GDExtensionInterfacePackedFloat64ArrayOperatorIndex);
|
|
||||||
LOAD_PROC_ADDRESS(packed_float64_array_operator_index_const, GDExtensionInterfacePackedFloat64ArrayOperatorIndexConst);
|
|
||||||
LOAD_PROC_ADDRESS(packed_int32_array_operator_index, GDExtensionInterfacePackedInt32ArrayOperatorIndex);
|
|
||||||
LOAD_PROC_ADDRESS(packed_int32_array_operator_index_const, GDExtensionInterfacePackedInt32ArrayOperatorIndexConst);
|
|
||||||
LOAD_PROC_ADDRESS(packed_int64_array_operator_index, GDExtensionInterfacePackedInt64ArrayOperatorIndex);
|
|
||||||
LOAD_PROC_ADDRESS(packed_int64_array_operator_index_const, GDExtensionInterfacePackedInt64ArrayOperatorIndexConst);
|
|
||||||
LOAD_PROC_ADDRESS(packed_string_array_operator_index, GDExtensionInterfacePackedStringArrayOperatorIndex);
|
|
||||||
LOAD_PROC_ADDRESS(packed_string_array_operator_index_const, GDExtensionInterfacePackedStringArrayOperatorIndexConst);
|
|
||||||
LOAD_PROC_ADDRESS(packed_vector2_array_operator_index, GDExtensionInterfacePackedVector2ArrayOperatorIndex);
|
|
||||||
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(array_operator_index, GDExtensionInterfaceArrayOperatorIndex);
|
|
||||||
LOAD_PROC_ADDRESS(array_operator_index_const, GDExtensionInterfaceArrayOperatorIndexConst);
|
|
||||||
LOAD_PROC_ADDRESS(array_ref, GDExtensionInterfaceArrayRef);
|
|
||||||
LOAD_PROC_ADDRESS(array_set_typed, GDExtensionInterfaceArraySetTyped);
|
|
||||||
LOAD_PROC_ADDRESS(dictionary_operator_index, GDExtensionInterfaceDictionaryOperatorIndex);
|
|
||||||
LOAD_PROC_ADDRESS(dictionary_operator_index_const, GDExtensionInterfaceDictionaryOperatorIndexConst);
|
|
||||||
LOAD_PROC_ADDRESS(object_method_bind_call, GDExtensionInterfaceObjectMethodBindCall);
|
|
||||||
LOAD_PROC_ADDRESS(object_method_bind_ptrcall, GDExtensionInterfaceObjectMethodBindPtrcall);
|
|
||||||
LOAD_PROC_ADDRESS(object_destroy, GDExtensionInterfaceObjectDestroy);
|
|
||||||
LOAD_PROC_ADDRESS(global_get_singleton, GDExtensionInterfaceGlobalGetSingleton);
|
|
||||||
LOAD_PROC_ADDRESS(object_get_instance_binding, GDExtensionInterfaceObjectGetInstanceBinding);
|
|
||||||
LOAD_PROC_ADDRESS(object_set_instance_binding, GDExtensionInterfaceObjectSetInstanceBinding);
|
|
||||||
LOAD_PROC_ADDRESS(object_set_instance, GDExtensionInterfaceObjectSetInstance);
|
|
||||||
LOAD_PROC_ADDRESS(object_get_class_name, GDExtensionInterfaceObjectGetClassName);
|
|
||||||
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(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_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_class2, GDExtensionInterfaceClassdbRegisterExtensionClass2);
|
|
||||||
LOAD_PROC_ADDRESS(classdb_register_extension_class_method, GDExtensionInterfaceClassdbRegisterExtensionClassMethod);
|
|
||||||
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);
|
|
||||||
LOAD_PROC_ADDRESS(classdb_register_extension_class_property_group, GDExtensionInterfaceClassdbRegisterExtensionClassPropertyGroup);
|
|
||||||
LOAD_PROC_ADDRESS(classdb_register_extension_class_property_subgroup, GDExtensionInterfaceClassdbRegisterExtensionClassPropertySubgroup);
|
|
||||||
LOAD_PROC_ADDRESS(classdb_register_extension_class_signal, GDExtensionInterfaceClassdbRegisterExtensionClassSignal);
|
|
||||||
LOAD_PROC_ADDRESS(classdb_unregister_extension_class, GDExtensionInterfaceClassdbUnregisterExtensionClass);
|
|
||||||
LOAD_PROC_ADDRESS(get_library_path, GDExtensionInterfaceGetLibraryPath);
|
|
||||||
LOAD_PROC_ADDRESS(editor_add_plugin, GDExtensionInterfaceEditorAddPlugin);
|
|
||||||
LOAD_PROC_ADDRESS(editor_remove_plugin, GDExtensionInterfaceEditorRemovePlugin);
|
|
||||||
|
|
||||||
r_initialization->initialize = initialize_level;
|
r_initialization->initialize = initialize_level;
|
||||||
r_initialization->deinitialize = deinitialize_level;
|
r_initialization->deinitialize = deinitialize_level;
|
||||||
r_initialization->userdata = p_init_data;
|
r_initialization->minimum_initialization_level = minimum_initialization_level;
|
||||||
r_initialization->minimum_initialization_level = p_init_data->minimum_initialization_level;
|
|
||||||
|
ERR_FAIL_COND_V_MSG(init_callback == nullptr, false, "Initialization callback must be defined.");
|
||||||
|
|
||||||
Variant::init_bindings();
|
Variant::init_bindings();
|
||||||
godot::internal::register_engine_classes();
|
|
||||||
|
|
||||||
api_initialized = true;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef LOAD_PROC_ADDRESS
|
void GDExtensionBinding::initialize_level(void *userdata, GDExtensionInitializationLevel p_level) {
|
||||||
#undef ERR_PRINT_EARLY
|
|
||||||
|
|
||||||
void GDExtensionBinding::initialize_level(void *p_userdata, GDExtensionInitializationLevel p_level) {
|
|
||||||
ERR_FAIL_COND(static_cast<ModuleInitializationLevel>(p_level) >= MODULE_INITIALIZATION_LEVEL_MAX);
|
|
||||||
ClassDB::current_level = p_level;
|
ClassDB::current_level = p_level;
|
||||||
|
|
||||||
InitData *init_data = static_cast<InitData *>(p_userdata);
|
if (init_callback) {
|
||||||
if (init_data && init_data->init_callback) {
|
init_callback(static_cast<ModuleInitializationLevel>(p_level));
|
||||||
init_data->init_callback(static_cast<ModuleInitializationLevel>(p_level));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (level_initialized[p_level] == 0) {
|
ClassDB::initialize(p_level);
|
||||||
ClassDB::initialize(p_level);
|
|
||||||
}
|
|
||||||
level_initialized[p_level]++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GDExtensionBinding::deinitialize_level(void *p_userdata, GDExtensionInitializationLevel p_level) {
|
void GDExtensionBinding::deinitialize_level(void *userdata, GDExtensionInitializationLevel p_level) {
|
||||||
ERR_FAIL_COND(static_cast<ModuleInitializationLevel>(p_level) >= MODULE_INITIALIZATION_LEVEL_MAX);
|
|
||||||
ClassDB::current_level = p_level;
|
ClassDB::current_level = p_level;
|
||||||
|
|
||||||
InitData *init_data = static_cast<InitData *>(p_userdata);
|
if (terminate_callback) {
|
||||||
if (init_data && init_data->terminate_callback) {
|
terminate_callback(static_cast<ModuleInitializationLevel>(p_level));
|
||||||
init_data->terminate_callback(static_cast<ModuleInitializationLevel>(p_level));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
level_initialized[p_level]--;
|
ClassDB::deinitialize(p_level);
|
||||||
if (level_initialized[p_level] == 0) {
|
|
||||||
EditorPlugins::deinitialize(p_level);
|
|
||||||
ClassDB::deinitialize(p_level);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GDExtensionBinding::InitDataList::add(InitData *p_data) {
|
|
||||||
if (data_count == data_capacity) {
|
|
||||||
void *new_ptr = realloc(data, sizeof(InitData *) * (data_capacity + 32));
|
|
||||||
if (new_ptr) {
|
|
||||||
data = (InitData **)(new_ptr);
|
|
||||||
data_capacity += 32;
|
|
||||||
} else {
|
|
||||||
ERR_FAIL_MSG("Unable to allocate memory for extension callbacks.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
data[data_count++] = p_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
GDExtensionBinding::InitDataList::~InitDataList() {
|
|
||||||
for (int i = 0; i < data_count; i++) {
|
|
||||||
if (data[i]) {
|
|
||||||
delete data[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (data) {
|
|
||||||
free(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GDExtensionBinding::InitObject::InitObject(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) {
|
|
||||||
get_proc_address = p_get_proc_address;
|
|
||||||
library = p_library;
|
|
||||||
initialization = r_initialization;
|
|
||||||
init_data = new InitData();
|
|
||||||
GDExtensionBinding::initdata.add(init_data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GDExtensionBinding::InitObject::register_initializer(Callback p_init) const {
|
void GDExtensionBinding::InitObject::register_initializer(Callback p_init) const {
|
||||||
init_data->init_callback = p_init;
|
GDExtensionBinding::init_callback = p_init;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GDExtensionBinding::InitObject::register_terminator(Callback p_terminate) const {
|
void GDExtensionBinding::InitObject::register_terminator(Callback p_terminate) const {
|
||||||
init_data->terminate_callback = p_terminate;
|
GDExtensionBinding::terminate_callback = p_terminate;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GDExtensionBinding::InitObject::set_minimum_library_initialization_level(ModuleInitializationLevel p_level) const {
|
void GDExtensionBinding::InitObject::set_minimum_library_initialization_level(ModuleInitializationLevel p_level) const {
|
||||||
init_data->minimum_initialization_level = static_cast<GDExtensionInitializationLevel>(p_level);
|
GDExtensionBinding::minimum_initialization_level = static_cast<GDExtensionInitializationLevel>(p_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
GDExtensionBool GDExtensionBinding::InitObject::init() const {
|
GDExtensionBool GDExtensionBinding::InitObject::init() const {
|
||||||
return GDExtensionBinding::init(get_proc_address, library, init_data, initialization);
|
return GDExtensionBinding::init(gde_interface, library, initialization);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace godot
|
} // namespace godot
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
void GDE_EXPORT initialize_level(void *userdata, GDExtensionInitializationLevel p_level) {
|
||||||
|
godot::GDExtensionBinding::initialize_level(userdata, p_level);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GDE_EXPORT deinitialize_level(void *userdata, GDExtensionInitializationLevel p_level) {
|
||||||
|
godot::GDExtensionBinding::deinitialize_level(userdata, p_level);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,113 +0,0 @@
|
|||||||
/**************************************************************************/
|
|
||||||
/* callable_custom.cpp */
|
|
||||||
/**************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/**************************************************************************/
|
|
||||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
|
||||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* */
|
|
||||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
|
||||||
/* a copy of this software and associated documentation files (the */
|
|
||||||
/* "Software"), to deal in the Software without restriction, including */
|
|
||||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
|
||||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
|
||||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
|
||||||
/* the following conditions: */
|
|
||||||
/* */
|
|
||||||
/* The above copyright notice and this permission notice shall be */
|
|
||||||
/* included in all copies or substantial portions of the Software. */
|
|
||||||
/* */
|
|
||||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
|
||||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
|
||||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
|
||||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
|
||||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
|
||||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
|
||||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|
||||||
/**************************************************************************/
|
|
||||||
|
|
||||||
#include <godot_cpp/variant/callable_custom.hpp>
|
|
||||||
|
|
||||||
#include <godot_cpp/core/object.hpp>
|
|
||||||
#include <godot_cpp/variant/callable.hpp>
|
|
||||||
|
|
||||||
namespace godot {
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
static GDExtensionBool callable_custom_is_valid(void *p_userdata) {
|
|
||||||
CallableCustom *callable_custom = (CallableCustom *)p_userdata;
|
|
||||||
return callable_custom->is_valid();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void callable_custom_free(void *p_userdata) {
|
|
||||||
CallableCustom *callable_custom = (CallableCustom *)p_userdata;
|
|
||||||
memdelete(callable_custom);
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t callable_custom_hash(void *p_userdata) {
|
|
||||||
CallableCustom *callable_custom = (CallableCustom *)p_userdata;
|
|
||||||
return callable_custom->hash();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void callable_custom_to_string(void *p_userdata, GDExtensionBool *r_is_valid, GDExtensionStringPtr r_out) {
|
|
||||||
CallableCustom *callable_custom = (CallableCustom *)p_userdata;
|
|
||||||
*((String *)r_out) = callable_custom->get_as_text();
|
|
||||||
*r_is_valid = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static GDExtensionBool callable_custom_equal_func(void *p_a, void *p_b) {
|
|
||||||
CallableCustom *a = (CallableCustom *)p_a;
|
|
||||||
CallableCustom *b = (CallableCustom *)p_b;
|
|
||||||
CallableCustom::CompareEqualFunc func_a = a->get_compare_equal_func();
|
|
||||||
CallableCustom::CompareEqualFunc func_b = b->get_compare_equal_func();
|
|
||||||
if (func_a != func_b) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return func_a(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
static GDExtensionBool callable_custom_less_than_func(void *p_a, void *p_b) {
|
|
||||||
CallableCustom *a = (CallableCustom *)p_a;
|
|
||||||
CallableCustom *b = (CallableCustom *)p_b;
|
|
||||||
CallableCustom::CompareEqualFunc func_a = a->get_compare_less_func();
|
|
||||||
CallableCustom::CompareEqualFunc func_b = b->get_compare_less_func();
|
|
||||||
if (func_a != func_b) {
|
|
||||||
// Just compare the addresses.
|
|
||||||
return p_a < p_b;
|
|
||||||
}
|
|
||||||
return func_a(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CallableCustom::is_valid() const {
|
|
||||||
// The same default implementation as in Godot.
|
|
||||||
return ObjectDB::get_instance(get_object());
|
|
||||||
}
|
|
||||||
|
|
||||||
Callable::Callable(CallableCustom *p_callable_custom) {
|
|
||||||
GDExtensionCallableCustomInfo info = {};
|
|
||||||
info.callable_userdata = p_callable_custom;
|
|
||||||
info.token = internal::token;
|
|
||||||
info.object_id = p_callable_custom->get_object();
|
|
||||||
info.call_func = &callable_custom_call;
|
|
||||||
info.is_valid_func = &callable_custom_is_valid;
|
|
||||||
info.free_func = &callable_custom_free;
|
|
||||||
info.hash_func = &callable_custom_hash;
|
|
||||||
info.equal_func = &callable_custom_equal_func;
|
|
||||||
info.less_than_func = &callable_custom_less_than_func;
|
|
||||||
info.to_string_func = &callable_custom_to_string;
|
|
||||||
|
|
||||||
::godot::internal::gdextension_interface_callable_custom_create(_native_ptr(), &info);
|
|
||||||
}
|
|
||||||
|
|
||||||
CallableCustom *Callable::get_custom() const {
|
|
||||||
CallableCustomBase *callable_custom = (CallableCustomBase *)::godot::internal::gdextension_interface_callable_custom_get_userdata(_native_ptr(), internal::token);
|
|
||||||
return dynamic_cast<CallableCustom *>(callable_custom);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace godot
|
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
/**************************************************************************/
|
|
||||||
/* callable_method_pointer.cpp */
|
|
||||||
/**************************************************************************/
|
|
||||||
/* This file is part of: */
|
|
||||||
/* GODOT ENGINE */
|
|
||||||
/* https://godotengine.org */
|
|
||||||
/**************************************************************************/
|
|
||||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
|
||||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
|
||||||
/* */
|
|
||||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
|
||||||
/* a copy of this software and associated documentation files (the */
|
|
||||||
/* "Software"), to deal in the Software without restriction, including */
|
|
||||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
|
||||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
|
||||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
|
||||||
/* the following conditions: */
|
|
||||||
/* */
|
|
||||||
/* The above copyright notice and this permission notice shall be */
|
|
||||||
/* included in all copies or substantial portions of the Software. */
|
|
||||||
/* */
|
|
||||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
|
||||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
|
||||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
|
||||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
|
||||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
|
||||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
|
||||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|
||||||
/**************************************************************************/
|
|
||||||
|
|
||||||
#include <godot_cpp/variant/callable_method_pointer.hpp>
|
|
||||||
|
|
||||||
#include <godot_cpp/templates/hashfuncs.hpp>
|
|
||||||
|
|
||||||
namespace godot {
|
|
||||||
|
|
||||||
static void custom_callable_mp_call(void *p_userdata, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error) {
|
|
||||||
CallableCustomMethodPointerBase *callable_method_pointer = (CallableCustomMethodPointerBase *)p_userdata;
|
|
||||||
callable_method_pointer->call((const Variant **)p_args, p_argument_count, *(Variant *)r_return, *r_error);
|
|
||||||
}
|
|
||||||
|
|
||||||
static GDExtensionBool custom_callable_mp_is_valid(void *p_userdata) {
|
|
||||||
CallableCustomMethodPointerBase *callable_method_pointer = (CallableCustomMethodPointerBase *)p_userdata;
|
|
||||||
ObjectID object = callable_method_pointer->get_object();
|
|
||||||
return object == ObjectID() || ObjectDB::get_instance(object);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void custom_callable_mp_free(void *p_userdata) {
|
|
||||||
CallableCustomMethodPointerBase *callable_method_pointer = (CallableCustomMethodPointerBase *)p_userdata;
|
|
||||||
memdelete(callable_method_pointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t custom_callable_mp_hash(void *p_userdata) {
|
|
||||||
CallableCustomMethodPointerBase *callable_method_pointer = (CallableCustomMethodPointerBase *)p_userdata;
|
|
||||||
return callable_method_pointer->get_hash();
|
|
||||||
}
|
|
||||||
|
|
||||||
static GDExtensionBool custom_callable_mp_equal_func(void *p_a, void *p_b) {
|
|
||||||
CallableCustomMethodPointerBase *a = (CallableCustomMethodPointerBase *)p_a;
|
|
||||||
CallableCustomMethodPointerBase *b = (CallableCustomMethodPointerBase *)p_b;
|
|
||||||
|
|
||||||
if (a->get_comp_size() != b->get_comp_size()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return memcmp(a->get_comp_ptr(), b->get_comp_ptr(), a->get_comp_size() * 4) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static GDExtensionBool custom_callable_mp_less_than_func(void *p_a, void *p_b) {
|
|
||||||
CallableCustomMethodPointerBase *a = (CallableCustomMethodPointerBase *)p_a;
|
|
||||||
CallableCustomMethodPointerBase *b = (CallableCustomMethodPointerBase *)p_b;
|
|
||||||
|
|
||||||
if (a->get_comp_size() != b->get_comp_size()) {
|
|
||||||
return a->get_comp_size() < b->get_comp_size();
|
|
||||||
}
|
|
||||||
|
|
||||||
return memcmp(a->get_comp_ptr(), b->get_comp_ptr(), a->get_comp_size() * 4) < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CallableCustomMethodPointerBase::_setup(uint32_t *p_base_ptr, uint32_t p_ptr_size) {
|
|
||||||
comp_ptr = p_base_ptr;
|
|
||||||
comp_size = p_ptr_size / 4;
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < comp_size; i++) {
|
|
||||||
if (i == 0) {
|
|
||||||
h = hash_murmur3_one_32(comp_ptr[i]);
|
|
||||||
} else {
|
|
||||||
h = hash_murmur3_one_32(comp_ptr[i], h);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
Callable create_callable_from_ccmp(CallableCustomMethodPointerBase *p_callable_method_pointer) {
|
|
||||||
GDExtensionCallableCustomInfo info = {};
|
|
||||||
info.callable_userdata = p_callable_method_pointer;
|
|
||||||
info.token = internal::token;
|
|
||||||
info.object_id = p_callable_method_pointer->get_object();
|
|
||||||
info.call_func = &custom_callable_mp_call;
|
|
||||||
info.is_valid_func = &custom_callable_mp_is_valid;
|
|
||||||
info.free_func = &custom_callable_mp_free;
|
|
||||||
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;
|
|
||||||
|
|
||||||
Callable callable;
|
|
||||||
::godot::internal::gdextension_interface_callable_custom_create(callable._native_ptr(), &info);
|
|
||||||
return callable;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
} // namespace godot
|
|
||||||
@@ -38,138 +38,134 @@
|
|||||||
#include <godot_cpp/godot.hpp>
|
#include <godot_cpp/godot.hpp>
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace godot {
|
namespace godot {
|
||||||
|
|
||||||
template <typename L, typename R>
|
int CharString::length() const {
|
||||||
_FORCE_INLINE_ bool is_str_less(const L *l_ptr, const R *r_ptr) {
|
return _length;
|
||||||
while (true) {
|
}
|
||||||
const char32_t l = *l_ptr;
|
|
||||||
const char32_t r = *r_ptr;
|
|
||||||
|
|
||||||
if (l == 0 && r == 0) {
|
const char *CharString::get_data() const {
|
||||||
return false;
|
return _data;
|
||||||
} else if (l == 0) {
|
}
|
||||||
return true;
|
|
||||||
} else if (r == 0) {
|
|
||||||
return false;
|
|
||||||
} else if (l < r) {
|
|
||||||
return true;
|
|
||||||
} else if (l > r) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
l_ptr++;
|
CharString::CharString(CharString &&p_str) {
|
||||||
r_ptr++;
|
SWAP(_length, p_str._length);
|
||||||
|
SWAP(_data, p_str._data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CharString::operator=(CharString &&p_str) {
|
||||||
|
SWAP(_length, p_str._length);
|
||||||
|
SWAP(_data, p_str._data);
|
||||||
|
}
|
||||||
|
|
||||||
|
CharString::CharString(const char *str, int length) :
|
||||||
|
_data(str), _length(length) {}
|
||||||
|
|
||||||
|
CharString::~CharString() {
|
||||||
|
if (_data != nullptr) {
|
||||||
|
memdelete_arr(_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
int Char16String::length() const {
|
||||||
bool CharStringT<T>::operator<(const CharStringT<T> &p_right) const {
|
return _length;
|
||||||
if (length() == 0) {
|
|
||||||
return p_right.length() != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return is_str_less(get_data(), p_right.get_data());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
const char16_t *Char16String::get_data() const {
|
||||||
CharStringT<T> &CharStringT<T>::operator+=(T p_char) {
|
return _data;
|
||||||
const int lhs_len = length();
|
|
||||||
resize(lhs_len + 2);
|
|
||||||
|
|
||||||
T *dst = ptrw();
|
|
||||||
dst[lhs_len] = p_char;
|
|
||||||
dst[lhs_len + 1] = 0;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
Char16String::Char16String(Char16String &&p_str) {
|
||||||
void CharStringT<T>::operator=(const T *p_cstr) {
|
SWAP(_length, p_str._length);
|
||||||
copy_from(p_cstr);
|
SWAP(_data, p_str._data);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
void Char16String::operator=(Char16String &&p_str) {
|
||||||
const char *CharStringT<char>::get_data() const {
|
SWAP(_length, p_str._length);
|
||||||
if (size()) {
|
SWAP(_data, p_str._data);
|
||||||
return &operator[](0);
|
}
|
||||||
} else {
|
|
||||||
return "";
|
Char16String::Char16String(const char16_t *str, int length) :
|
||||||
|
_data(str), _length(length) {}
|
||||||
|
|
||||||
|
Char16String::~Char16String() {
|
||||||
|
if (_data != nullptr) {
|
||||||
|
memdelete_arr(_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
int Char32String::length() const {
|
||||||
const char16_t *CharStringT<char16_t>::get_data() const {
|
return _length;
|
||||||
if (size()) {
|
}
|
||||||
return &operator[](0);
|
|
||||||
} else {
|
const char32_t *Char32String::get_data() const {
|
||||||
return u"";
|
return _data;
|
||||||
|
}
|
||||||
|
|
||||||
|
Char32String::Char32String(Char32String &&p_str) {
|
||||||
|
SWAP(_length, p_str._length);
|
||||||
|
SWAP(_data, p_str._data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Char32String::operator=(Char32String &&p_str) {
|
||||||
|
SWAP(_length, p_str._length);
|
||||||
|
SWAP(_data, p_str._data);
|
||||||
|
}
|
||||||
|
|
||||||
|
Char32String::Char32String(const char32_t *str, int length) :
|
||||||
|
_data(str), _length(length) {}
|
||||||
|
|
||||||
|
Char32String::~Char32String() {
|
||||||
|
if (_data != nullptr) {
|
||||||
|
memdelete_arr(_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
int CharWideString::length() const {
|
||||||
const char32_t *CharStringT<char32_t>::get_data() const {
|
return _length;
|
||||||
if (size()) {
|
|
||||||
return &operator[](0);
|
|
||||||
} else {
|
|
||||||
return U"";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
const wchar_t *CharWideString::get_data() const {
|
||||||
const wchar_t *CharStringT<wchar_t>::get_data() const {
|
return _data;
|
||||||
if (size()) {
|
|
||||||
return &operator[](0);
|
|
||||||
} else {
|
|
||||||
return L"";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
CharWideString::CharWideString(CharWideString &&p_str) {
|
||||||
void CharStringT<T>::copy_from(const T *p_cstr) {
|
SWAP(_length, p_str._length);
|
||||||
if (!p_cstr) {
|
SWAP(_data, p_str._data);
|
||||||
resize(0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t len = std::char_traits<T>::length(p_cstr);
|
|
||||||
|
|
||||||
if (len == 0) {
|
|
||||||
resize(0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Error err = resize(++len); // include terminating null char
|
|
||||||
|
|
||||||
ERR_FAIL_COND_MSG(err != OK, "Failed to copy C-string.");
|
|
||||||
|
|
||||||
memcpy(ptrw(), p_cstr, len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template class CharStringT<char>;
|
void CharWideString::operator=(CharWideString &&p_str) {
|
||||||
template class CharStringT<char16_t>;
|
SWAP(_length, p_str._length);
|
||||||
template class CharStringT<char32_t>;
|
SWAP(_data, p_str._data);
|
||||||
template class CharStringT<wchar_t>;
|
}
|
||||||
|
|
||||||
|
CharWideString::CharWideString(const wchar_t *str, int length) :
|
||||||
|
_data(str), _length(length) {}
|
||||||
|
|
||||||
|
CharWideString::~CharWideString() {
|
||||||
|
if (_data != nullptr) {
|
||||||
|
memdelete_arr(_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Custom String functions that are not part of bound API.
|
// Custom String functions that are not part of bound API.
|
||||||
// It's easier to have them written in C++ directly than in a Python script that generates them.
|
// It's easier to have them written in C++ directly than in a Python script that generates them.
|
||||||
|
|
||||||
String::String(const char *from) {
|
String::String(const char *from) {
|
||||||
internal::gdextension_interface_string_new_with_latin1_chars(_native_ptr(), from);
|
internal::gde_interface->string_new_with_latin1_chars(_native_ptr(), from);
|
||||||
}
|
}
|
||||||
|
|
||||||
String::String(const wchar_t *from) {
|
String::String(const wchar_t *from) {
|
||||||
internal::gdextension_interface_string_new_with_wide_chars(_native_ptr(), from);
|
internal::gde_interface->string_new_with_wide_chars(_native_ptr(), from);
|
||||||
}
|
}
|
||||||
|
|
||||||
String::String(const char16_t *from) {
|
String::String(const char16_t *from) {
|
||||||
internal::gdextension_interface_string_new_with_utf16_chars(_native_ptr(), from);
|
internal::gde_interface->string_new_with_utf16_chars(_native_ptr(), from);
|
||||||
}
|
}
|
||||||
|
|
||||||
String::String(const char32_t *from) {
|
String::String(const char32_t *from) {
|
||||||
internal::gdextension_interface_string_new_with_utf32_chars(_native_ptr(), from);
|
internal::gde_interface->string_new_with_utf32_chars(_native_ptr(), from);
|
||||||
}
|
}
|
||||||
|
|
||||||
String String::utf8(const char *from, int len) {
|
String String::utf8(const char *from, int len) {
|
||||||
@@ -179,7 +175,7 @@ String String::utf8(const char *from, int len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void String::parse_utf8(const char *from, int len) {
|
void String::parse_utf8(const char *from, int len) {
|
||||||
internal::gdextension_interface_string_new_with_utf8_chars_and_len(_native_ptr(), from, len);
|
internal::gde_interface->string_new_with_utf8_chars_and_len(_native_ptr(), from, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
String String::utf16(const char16_t *from, int len) {
|
String String::utf16(const char16_t *from, int len) {
|
||||||
@@ -189,7 +185,7 @@ String String::utf16(const char16_t *from, int len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void String::parse_utf16(const char16_t *from, int len) {
|
void String::parse_utf16(const char16_t *from, int len) {
|
||||||
internal::gdextension_interface_string_new_with_utf16_chars_and_len(_native_ptr(), from, len);
|
internal::gde_interface->string_new_with_utf16_chars_and_len(_native_ptr(), from, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
String String::num_real(double p_num, bool p_trailing) {
|
String String::num_real(double p_num, bool p_trailing) {
|
||||||
@@ -230,67 +226,58 @@ String rtoss(double p_val) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CharString String::utf8() const {
|
CharString String::utf8() const {
|
||||||
int length = internal::gdextension_interface_string_to_utf8_chars(_native_ptr(), nullptr, 0);
|
int length = internal::gde_interface->string_to_utf8_chars(_native_ptr(), nullptr, 0);
|
||||||
int size = length + 1;
|
int size = length + 1;
|
||||||
CharString str;
|
char *cstr = memnew_arr(char, size);
|
||||||
str.resize(size);
|
internal::gde_interface->string_to_utf8_chars(_native_ptr(), cstr, length);
|
||||||
internal::gdextension_interface_string_to_utf8_chars(_native_ptr(), str.ptrw(), length);
|
|
||||||
|
|
||||||
str[length] = '\0';
|
cstr[length] = '\0';
|
||||||
|
|
||||||
return str;
|
return CharString(cstr, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
CharString String::ascii() const {
|
CharString String::ascii() const {
|
||||||
int length = internal::gdextension_interface_string_to_latin1_chars(_native_ptr(), nullptr, 0);
|
int length = internal::gde_interface->string_to_latin1_chars(_native_ptr(), nullptr, 0);
|
||||||
int size = length + 1;
|
int size = length + 1;
|
||||||
CharString str;
|
char *cstr = memnew_arr(char, size);
|
||||||
str.resize(size);
|
internal::gde_interface->string_to_latin1_chars(_native_ptr(), cstr, length);
|
||||||
internal::gdextension_interface_string_to_latin1_chars(_native_ptr(), str.ptrw(), length);
|
|
||||||
|
|
||||||
str[length] = '\0';
|
cstr[length] = '\0';
|
||||||
|
|
||||||
return str;
|
return CharString(cstr, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
Char16String String::utf16() const {
|
Char16String String::utf16() const {
|
||||||
int length = internal::gdextension_interface_string_to_utf16_chars(_native_ptr(), nullptr, 0);
|
int length = internal::gde_interface->string_to_utf16_chars(_native_ptr(), nullptr, 0);
|
||||||
int size = length + 1;
|
int size = length + 1;
|
||||||
Char16String str;
|
char16_t *cstr = memnew_arr(char16_t, size);
|
||||||
str.resize(size);
|
internal::gde_interface->string_to_utf16_chars(_native_ptr(), cstr, length);
|
||||||
internal::gdextension_interface_string_to_utf16_chars(_native_ptr(), str.ptrw(), length);
|
|
||||||
|
|
||||||
str[length] = '\0';
|
cstr[length] = '\0';
|
||||||
|
|
||||||
return str;
|
return Char16String(cstr, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
Char32String String::utf32() const {
|
Char32String String::utf32() const {
|
||||||
int length = internal::gdextension_interface_string_to_utf32_chars(_native_ptr(), nullptr, 0);
|
int length = internal::gde_interface->string_to_utf32_chars(_native_ptr(), nullptr, 0);
|
||||||
int size = length + 1;
|
int size = length + 1;
|
||||||
Char32String str;
|
char32_t *cstr = memnew_arr(char32_t, size);
|
||||||
str.resize(size);
|
internal::gde_interface->string_to_utf32_chars(_native_ptr(), cstr, length);
|
||||||
internal::gdextension_interface_string_to_utf32_chars(_native_ptr(), str.ptrw(), length);
|
|
||||||
|
|
||||||
str[length] = '\0';
|
cstr[length] = '\0';
|
||||||
|
|
||||||
return str;
|
return Char32String(cstr, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
CharWideString String::wide_string() const {
|
CharWideString String::wide_string() const {
|
||||||
int length = internal::gdextension_interface_string_to_wide_chars(_native_ptr(), nullptr, 0);
|
int length = internal::gde_interface->string_to_wide_chars(_native_ptr(), nullptr, 0);
|
||||||
int size = length + 1;
|
int size = length + 1;
|
||||||
CharWideString str;
|
wchar_t *cstr = memnew_arr(wchar_t, size);
|
||||||
str.resize(size);
|
internal::gde_interface->string_to_wide_chars(_native_ptr(), cstr, length);
|
||||||
internal::gdextension_interface_string_to_wide_chars(_native_ptr(), str.ptrw(), length);
|
|
||||||
|
|
||||||
str[length] = '\0';
|
cstr[length] = '\0';
|
||||||
|
|
||||||
return str;
|
return CharWideString(cstr, length);
|
||||||
}
|
|
||||||
|
|
||||||
Error String::resize(int p_size) {
|
|
||||||
return (Error)internal::gdextension_interface_string_resize(_native_ptr(), p_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String &String::operator=(const char *p_str) {
|
String &String::operator=(const char *p_str) {
|
||||||
@@ -366,44 +353,44 @@ String String::operator+(const char32_t p_char) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String &String::operator+=(const String &p_str) {
|
String &String::operator+=(const String &p_str) {
|
||||||
internal::gdextension_interface_string_operator_plus_eq_string((GDExtensionStringPtr)this, (GDExtensionConstStringPtr)&p_str);
|
internal::gde_interface->string_operator_plus_eq_string((GDExtensionStringPtr)this, (GDExtensionConstStringPtr)&p_str);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
String &String::operator+=(char32_t p_char) {
|
String &String::operator+=(char32_t p_char) {
|
||||||
internal::gdextension_interface_string_operator_plus_eq_char((GDExtensionStringPtr)this, p_char);
|
internal::gde_interface->string_operator_plus_eq_char((GDExtensionStringPtr)this, p_char);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
String &String::operator+=(const char *p_str) {
|
String &String::operator+=(const char *p_str) {
|
||||||
internal::gdextension_interface_string_operator_plus_eq_cstr((GDExtensionStringPtr)this, p_str);
|
internal::gde_interface->string_operator_plus_eq_cstr((GDExtensionStringPtr)this, p_str);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
String &String::operator+=(const wchar_t *p_str) {
|
String &String::operator+=(const wchar_t *p_str) {
|
||||||
internal::gdextension_interface_string_operator_plus_eq_wcstr((GDExtensionStringPtr)this, p_str);
|
internal::gde_interface->string_operator_plus_eq_wcstr((GDExtensionStringPtr)this, p_str);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
String &String::operator+=(const char32_t *p_str) {
|
String &String::operator+=(const char32_t *p_str) {
|
||||||
internal::gdextension_interface_string_operator_plus_eq_c32str((GDExtensionStringPtr)this, p_str);
|
internal::gde_interface->string_operator_plus_eq_c32str((GDExtensionStringPtr)this, p_str);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char32_t &String::operator[](int p_index) const {
|
const char32_t &String::operator[](int p_index) const {
|
||||||
return *internal::gdextension_interface_string_operator_index_const((GDExtensionStringPtr)this, p_index);
|
return *internal::gde_interface->string_operator_index_const((GDExtensionStringPtr)this, p_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
char32_t &String::operator[](int p_index) {
|
char32_t &String::operator[](int p_index) {
|
||||||
return *internal::gdextension_interface_string_operator_index((GDExtensionStringPtr)this, p_index);
|
return *internal::gde_interface->string_operator_index((GDExtensionStringPtr)this, p_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char32_t *String::ptr() const {
|
const char32_t *String::ptr() const {
|
||||||
return internal::gdextension_interface_string_operator_index_const((GDExtensionStringPtr)this, 0);
|
return internal::gde_interface->string_operator_index_const((GDExtensionStringPtr)this, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
char32_t *String::ptrw() {
|
char32_t *String::ptrw() {
|
||||||
return internal::gdextension_interface_string_operator_index((GDExtensionStringPtr)this, 0);
|
return internal::gde_interface->string_operator_index((GDExtensionStringPtr)this, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const char *p_chr, const String &p_str) {
|
bool operator==(const char *p_chr, const String &p_str) {
|
||||||
@@ -458,9 +445,8 @@ String operator+(char32_t p_char, const String &p_str) {
|
|||||||
return String::chr(p_char) + p_str;
|
return String::chr(p_char) + p_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringName::StringName(const char *from, bool p_static) {
|
StringName::StringName(const char *from) :
|
||||||
internal::gdextension_interface_string_name_new_with_latin1_chars(&opaque, from, p_static);
|
StringName(String(from)) {}
|
||||||
}
|
|
||||||
|
|
||||||
StringName::StringName(const wchar_t *from) :
|
StringName::StringName(const wchar_t *from) :
|
||||||
StringName(String(from)) {}
|
StringName(String(from)) {}
|
||||||
|
|||||||
@@ -47,183 +47,183 @@
|
|||||||
namespace godot {
|
namespace godot {
|
||||||
|
|
||||||
const uint8_t &PackedByteArray::operator[](int p_index) const {
|
const uint8_t &PackedByteArray::operator[](int p_index) const {
|
||||||
return *internal::gdextension_interface_packed_byte_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
|
return *internal::gde_interface->packed_byte_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t &PackedByteArray::operator[](int p_index) {
|
uint8_t &PackedByteArray::operator[](int p_index) {
|
||||||
return *internal::gdextension_interface_packed_byte_array_operator_index((GDExtensionTypePtr *)this, p_index);
|
return *internal::gde_interface->packed_byte_array_operator_index((GDExtensionTypePtr *)this, p_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t *PackedByteArray::ptr() const {
|
const uint8_t *PackedByteArray::ptr() const {
|
||||||
return internal::gdextension_interface_packed_byte_array_operator_index_const((GDExtensionTypePtr *)this, 0);
|
return internal::gde_interface->packed_byte_array_operator_index_const((GDExtensionTypePtr *)this, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *PackedByteArray::ptrw() {
|
uint8_t *PackedByteArray::ptrw() {
|
||||||
return internal::gdextension_interface_packed_byte_array_operator_index((GDExtensionTypePtr *)this, 0);
|
return internal::gde_interface->packed_byte_array_operator_index((GDExtensionTypePtr *)this, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Color &PackedColorArray::operator[](int p_index) const {
|
const Color &PackedColorArray::operator[](int p_index) const {
|
||||||
const Color *color = (const Color *)internal::gdextension_interface_packed_color_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
|
const Color *color = (const Color *)internal::gde_interface->packed_color_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
|
||||||
return *color;
|
return *color;
|
||||||
}
|
}
|
||||||
|
|
||||||
Color &PackedColorArray::operator[](int p_index) {
|
Color &PackedColorArray::operator[](int p_index) {
|
||||||
Color *color = (Color *)internal::gdextension_interface_packed_color_array_operator_index((GDExtensionTypePtr *)this, p_index);
|
Color *color = (Color *)internal::gde_interface->packed_color_array_operator_index((GDExtensionTypePtr *)this, p_index);
|
||||||
return *color;
|
return *color;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Color *PackedColorArray::ptr() const {
|
const Color *PackedColorArray::ptr() const {
|
||||||
return (const Color *)internal::gdextension_interface_packed_color_array_operator_index_const((GDExtensionTypePtr *)this, 0);
|
return (const Color *)internal::gde_interface->packed_color_array_operator_index_const((GDExtensionTypePtr *)this, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Color *PackedColorArray::ptrw() {
|
Color *PackedColorArray::ptrw() {
|
||||||
return (Color *)internal::gdextension_interface_packed_color_array_operator_index((GDExtensionTypePtr *)this, 0);
|
return (Color *)internal::gde_interface->packed_color_array_operator_index((GDExtensionTypePtr *)this, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const float &PackedFloat32Array::operator[](int p_index) const {
|
const float &PackedFloat32Array::operator[](int p_index) const {
|
||||||
return *internal::gdextension_interface_packed_float32_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
|
return *internal::gde_interface->packed_float32_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
float &PackedFloat32Array::operator[](int p_index) {
|
float &PackedFloat32Array::operator[](int p_index) {
|
||||||
return *internal::gdextension_interface_packed_float32_array_operator_index((GDExtensionTypePtr *)this, p_index);
|
return *internal::gde_interface->packed_float32_array_operator_index((GDExtensionTypePtr *)this, p_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
const float *PackedFloat32Array::ptr() const {
|
const float *PackedFloat32Array::ptr() const {
|
||||||
return internal::gdextension_interface_packed_float32_array_operator_index_const((GDExtensionTypePtr *)this, 0);
|
return internal::gde_interface->packed_float32_array_operator_index_const((GDExtensionTypePtr *)this, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
float *PackedFloat32Array::ptrw() {
|
float *PackedFloat32Array::ptrw() {
|
||||||
return internal::gdextension_interface_packed_float32_array_operator_index((GDExtensionTypePtr *)this, 0);
|
return internal::gde_interface->packed_float32_array_operator_index((GDExtensionTypePtr *)this, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const double &PackedFloat64Array::operator[](int p_index) const {
|
const double &PackedFloat64Array::operator[](int p_index) const {
|
||||||
return *internal::gdextension_interface_packed_float64_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
|
return *internal::gde_interface->packed_float64_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
double &PackedFloat64Array::operator[](int p_index) {
|
double &PackedFloat64Array::operator[](int p_index) {
|
||||||
return *internal::gdextension_interface_packed_float64_array_operator_index((GDExtensionTypePtr *)this, p_index);
|
return *internal::gde_interface->packed_float64_array_operator_index((GDExtensionTypePtr *)this, p_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
const double *PackedFloat64Array::ptr() const {
|
const double *PackedFloat64Array::ptr() const {
|
||||||
return internal::gdextension_interface_packed_float64_array_operator_index_const((GDExtensionTypePtr *)this, 0);
|
return internal::gde_interface->packed_float64_array_operator_index_const((GDExtensionTypePtr *)this, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
double *PackedFloat64Array::ptrw() {
|
double *PackedFloat64Array::ptrw() {
|
||||||
return internal::gdextension_interface_packed_float64_array_operator_index((GDExtensionTypePtr *)this, 0);
|
return internal::gde_interface->packed_float64_array_operator_index((GDExtensionTypePtr *)this, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const int32_t &PackedInt32Array::operator[](int p_index) const {
|
const int32_t &PackedInt32Array::operator[](int p_index) const {
|
||||||
return *internal::gdextension_interface_packed_int32_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
|
return *internal::gde_interface->packed_int32_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t &PackedInt32Array::operator[](int p_index) {
|
int32_t &PackedInt32Array::operator[](int p_index) {
|
||||||
return *internal::gdextension_interface_packed_int32_array_operator_index((GDExtensionTypePtr *)this, p_index);
|
return *internal::gde_interface->packed_int32_array_operator_index((GDExtensionTypePtr *)this, p_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
const int32_t *PackedInt32Array::ptr() const {
|
const int32_t *PackedInt32Array::ptr() const {
|
||||||
return internal::gdextension_interface_packed_int32_array_operator_index_const((GDExtensionTypePtr *)this, 0);
|
return internal::gde_interface->packed_int32_array_operator_index_const((GDExtensionTypePtr *)this, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t *PackedInt32Array::ptrw() {
|
int32_t *PackedInt32Array::ptrw() {
|
||||||
return internal::gdextension_interface_packed_int32_array_operator_index((GDExtensionTypePtr *)this, 0);
|
return internal::gde_interface->packed_int32_array_operator_index((GDExtensionTypePtr *)this, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const int64_t &PackedInt64Array::operator[](int p_index) const {
|
const int64_t &PackedInt64Array::operator[](int p_index) const {
|
||||||
return *internal::gdextension_interface_packed_int64_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
|
return *internal::gde_interface->packed_int64_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t &PackedInt64Array::operator[](int p_index) {
|
int64_t &PackedInt64Array::operator[](int p_index) {
|
||||||
return *internal::gdextension_interface_packed_int64_array_operator_index((GDExtensionTypePtr *)this, p_index);
|
return *internal::gde_interface->packed_int64_array_operator_index((GDExtensionTypePtr *)this, p_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
const int64_t *PackedInt64Array::ptr() const {
|
const int64_t *PackedInt64Array::ptr() const {
|
||||||
return internal::gdextension_interface_packed_int64_array_operator_index_const((GDExtensionTypePtr *)this, 0);
|
return internal::gde_interface->packed_int64_array_operator_index_const((GDExtensionTypePtr *)this, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t *PackedInt64Array::ptrw() {
|
int64_t *PackedInt64Array::ptrw() {
|
||||||
return internal::gdextension_interface_packed_int64_array_operator_index((GDExtensionTypePtr *)this, 0);
|
return internal::gde_interface->packed_int64_array_operator_index((GDExtensionTypePtr *)this, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const String &PackedStringArray::operator[](int p_index) const {
|
const String &PackedStringArray::operator[](int p_index) const {
|
||||||
const String *string = (const String *)internal::gdextension_interface_packed_string_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
|
const String *string = (const String *)internal::gde_interface->packed_string_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
|
||||||
return *string;
|
return *string;
|
||||||
}
|
}
|
||||||
|
|
||||||
String &PackedStringArray::operator[](int p_index) {
|
String &PackedStringArray::operator[](int p_index) {
|
||||||
String *string = (String *)internal::gdextension_interface_packed_string_array_operator_index((GDExtensionTypePtr *)this, p_index);
|
String *string = (String *)internal::gde_interface->packed_string_array_operator_index((GDExtensionTypePtr *)this, p_index);
|
||||||
return *string;
|
return *string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const String *PackedStringArray::ptr() const {
|
const String *PackedStringArray::ptr() const {
|
||||||
return (const String *)internal::gdextension_interface_packed_string_array_operator_index_const((GDExtensionTypePtr *)this, 0);
|
return (const String *)internal::gde_interface->packed_string_array_operator_index_const((GDExtensionTypePtr *)this, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
String *PackedStringArray::ptrw() {
|
String *PackedStringArray::ptrw() {
|
||||||
return (String *)internal::gdextension_interface_packed_string_array_operator_index((GDExtensionTypePtr *)this, 0);
|
return (String *)internal::gde_interface->packed_string_array_operator_index((GDExtensionTypePtr *)this, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Vector2 &PackedVector2Array::operator[](int p_index) const {
|
const Vector2 &PackedVector2Array::operator[](int p_index) const {
|
||||||
const Vector2 *vec = (const Vector2 *)internal::gdextension_interface_packed_vector2_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
|
const Vector2 *vec = (const Vector2 *)internal::gde_interface->packed_vector2_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
|
||||||
return *vec;
|
return *vec;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2 &PackedVector2Array::operator[](int p_index) {
|
Vector2 &PackedVector2Array::operator[](int p_index) {
|
||||||
Vector2 *vec = (Vector2 *)internal::gdextension_interface_packed_vector2_array_operator_index((GDExtensionTypePtr *)this, p_index);
|
Vector2 *vec = (Vector2 *)internal::gde_interface->packed_vector2_array_operator_index((GDExtensionTypePtr *)this, p_index);
|
||||||
return *vec;
|
return *vec;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Vector2 *PackedVector2Array::ptr() const {
|
const Vector2 *PackedVector2Array::ptr() const {
|
||||||
return (const Vector2 *)internal::gdextension_interface_packed_vector2_array_operator_index_const((GDExtensionTypePtr *)this, 0);
|
return (const Vector2 *)internal::gde_interface->packed_vector2_array_operator_index_const((GDExtensionTypePtr *)this, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2 *PackedVector2Array::ptrw() {
|
Vector2 *PackedVector2Array::ptrw() {
|
||||||
return (Vector2 *)internal::gdextension_interface_packed_vector2_array_operator_index((GDExtensionTypePtr *)this, 0);
|
return (Vector2 *)internal::gde_interface->packed_vector2_array_operator_index((GDExtensionTypePtr *)this, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Vector3 &PackedVector3Array::operator[](int p_index) const {
|
const Vector3 &PackedVector3Array::operator[](int p_index) const {
|
||||||
const Vector3 *vec = (const Vector3 *)internal::gdextension_interface_packed_vector3_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
|
const Vector3 *vec = (const Vector3 *)internal::gde_interface->packed_vector3_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
|
||||||
return *vec;
|
return *vec;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 &PackedVector3Array::operator[](int p_index) {
|
Vector3 &PackedVector3Array::operator[](int p_index) {
|
||||||
Vector3 *vec = (Vector3 *)internal::gdextension_interface_packed_vector3_array_operator_index((GDExtensionTypePtr *)this, p_index);
|
Vector3 *vec = (Vector3 *)internal::gde_interface->packed_vector3_array_operator_index((GDExtensionTypePtr *)this, p_index);
|
||||||
return *vec;
|
return *vec;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Vector3 *PackedVector3Array::ptr() const {
|
const Vector3 *PackedVector3Array::ptr() const {
|
||||||
return (const Vector3 *)internal::gdextension_interface_packed_vector3_array_operator_index_const((GDExtensionTypePtr *)this, 0);
|
return (const Vector3 *)internal::gde_interface->packed_vector3_array_operator_index_const((GDExtensionTypePtr *)this, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 *PackedVector3Array::ptrw() {
|
Vector3 *PackedVector3Array::ptrw() {
|
||||||
return (Vector3 *)internal::gdextension_interface_packed_vector3_array_operator_index((GDExtensionTypePtr *)this, 0);
|
return (Vector3 *)internal::gde_interface->packed_vector3_array_operator_index((GDExtensionTypePtr *)this, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Variant &Array::operator[](int p_index) const {
|
const Variant &Array::operator[](int p_index) const {
|
||||||
const Variant *var = (const Variant *)internal::gdextension_interface_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
|
const Variant *var = (const Variant *)internal::gde_interface->array_operator_index_const((GDExtensionTypePtr *)this, p_index);
|
||||||
return *var;
|
return *var;
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant &Array::operator[](int p_index) {
|
Variant &Array::operator[](int p_index) {
|
||||||
Variant *var = (Variant *)internal::gdextension_interface_array_operator_index((GDExtensionTypePtr *)this, p_index);
|
Variant *var = (Variant *)internal::gde_interface->array_operator_index((GDExtensionTypePtr *)this, p_index);
|
||||||
return *var;
|
return *var;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Array::set_typed(uint32_t p_type, const StringName &p_class_name, const Variant &p_script) {
|
void Array::set_typed(uint32_t p_type, const StringName &p_class_name, const Variant &p_script) {
|
||||||
// p_type is not Variant::Type so that header doesn't depend on <variant.hpp>.
|
// p_type is not Variant::Type so that header doesn't depend on <variant.hpp>.
|
||||||
internal::gdextension_interface_array_set_typed((GDExtensionTypePtr *)this, (GDExtensionVariantType)p_type, (GDExtensionConstStringNamePtr)&p_class_name, (GDExtensionConstVariantPtr)&p_script);
|
internal::gde_interface->array_set_typed((GDExtensionTypePtr *)this, (GDExtensionVariantType)p_type, (GDExtensionConstStringNamePtr)&p_class_name, (GDExtensionConstVariantPtr)&p_script);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Array::_ref(const Array &p_from) const {
|
void Array::_ref(const Array &p_from) const {
|
||||||
internal::gdextension_interface_array_ref((GDExtensionTypePtr *)this, (GDExtensionConstTypePtr *)&p_from);
|
internal::gde_interface->array_ref((GDExtensionTypePtr *)this, (GDExtensionConstTypePtr *)&p_from);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Variant &Dictionary::operator[](const Variant &p_key) const {
|
const Variant &Dictionary::operator[](const Variant &p_key) const {
|
||||||
const Variant *var = (const Variant *)internal::gdextension_interface_dictionary_operator_index_const((GDExtensionTypePtr *)this, (GDExtensionVariantPtr)&p_key);
|
const Variant *var = (const Variant *)internal::gde_interface->dictionary_operator_index_const((GDExtensionTypePtr *)this, (GDExtensionVariantPtr)&p_key);
|
||||||
return *var;
|
return *var;
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant &Dictionary::operator[](const Variant &p_key) {
|
Variant &Dictionary::operator[](const Variant &p_key) {
|
||||||
Variant *var = (Variant *)internal::gdextension_interface_dictionary_operator_index((GDExtensionTypePtr *)this, (GDExtensionVariantPtr)&p_key);
|
Variant *var = (Variant *)internal::gde_interface->dictionary_operator_index((GDExtensionTypePtr *)this, (GDExtensionVariantPtr)&p_key);
|
||||||
return *var;
|
return *var;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,6 @@
|
|||||||
#include <godot_cpp/godot.hpp>
|
#include <godot_cpp/godot.hpp>
|
||||||
|
|
||||||
#include <godot_cpp/core/binder_common.hpp>
|
#include <godot_cpp/core/binder_common.hpp>
|
||||||
#include <godot_cpp/core/class_db.hpp>
|
|
||||||
#include <godot_cpp/core/defs.hpp>
|
#include <godot_cpp/core/defs.hpp>
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@@ -46,8 +45,8 @@ GDExtensionTypeFromVariantConstructorFunc Variant::to_type_constructor[Variant::
|
|||||||
void Variant::init_bindings() {
|
void Variant::init_bindings() {
|
||||||
// Start from 1 to skip NIL.
|
// Start from 1 to skip NIL.
|
||||||
for (int i = 1; i < VARIANT_MAX; i++) {
|
for (int i = 1; i < VARIANT_MAX; i++) {
|
||||||
from_type_constructor[i] = internal::gdextension_interface_get_variant_from_type_constructor((GDExtensionVariantType)i);
|
from_type_constructor[i] = internal::gde_interface->get_variant_from_type_constructor((GDExtensionVariantType)i);
|
||||||
to_type_constructor[i] = internal::gdextension_interface_get_variant_to_type_constructor((GDExtensionVariantType)i);
|
to_type_constructor[i] = internal::gde_interface->get_variant_to_type_constructor((GDExtensionVariantType)i);
|
||||||
}
|
}
|
||||||
|
|
||||||
StringName::init_bindings();
|
StringName::init_bindings();
|
||||||
@@ -70,15 +69,15 @@ void Variant::init_bindings() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Variant::Variant() {
|
Variant::Variant() {
|
||||||
internal::gdextension_interface_variant_new_nil(_native_ptr());
|
internal::gde_interface->variant_new_nil(_native_ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant::Variant(GDExtensionConstVariantPtr native_ptr) {
|
Variant::Variant(GDExtensionConstVariantPtr native_ptr) {
|
||||||
internal::gdextension_interface_variant_new_copy(_native_ptr(), native_ptr);
|
internal::gde_interface->variant_new_copy(_native_ptr(), native_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant::Variant(const Variant &other) {
|
Variant::Variant(const Variant &other) {
|
||||||
internal::gdextension_interface_variant_new_copy(_native_ptr(), other._native_ptr());
|
internal::gde_interface->variant_new_copy(_native_ptr(), other._native_ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant::Variant(Variant &&other) {
|
Variant::Variant(Variant &&other) {
|
||||||
@@ -249,7 +248,7 @@ Variant::Variant(const PackedColorArray &v) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Variant::~Variant() {
|
Variant::~Variant() {
|
||||||
internal::gdextension_interface_variant_destroy(_native_ptr());
|
internal::gde_interface->variant_destroy(_native_ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant::operator bool() const {
|
Variant::operator bool() const {
|
||||||
@@ -268,14 +267,6 @@ Variant::operator int32_t() const {
|
|||||||
return static_cast<int32_t>(operator int64_t());
|
return static_cast<int32_t>(operator int64_t());
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant::operator int16_t() const {
|
|
||||||
return static_cast<int16_t>(operator int64_t());
|
|
||||||
}
|
|
||||||
|
|
||||||
Variant::operator int8_t() const {
|
|
||||||
return static_cast<int8_t>(operator int64_t());
|
|
||||||
}
|
|
||||||
|
|
||||||
Variant::operator uint64_t() const {
|
Variant::operator uint64_t() const {
|
||||||
return static_cast<uint64_t>(operator int64_t());
|
return static_cast<uint64_t>(operator int64_t());
|
||||||
}
|
}
|
||||||
@@ -284,14 +275,6 @@ Variant::operator uint32_t() const {
|
|||||||
return static_cast<uint32_t>(operator int64_t());
|
return static_cast<uint32_t>(operator int64_t());
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant::operator uint16_t() const {
|
|
||||||
return static_cast<uint16_t>(operator int64_t());
|
|
||||||
}
|
|
||||||
|
|
||||||
Variant::operator uint8_t() const {
|
|
||||||
return static_cast<uint8_t>(operator int64_t());
|
|
||||||
}
|
|
||||||
|
|
||||||
Variant::operator double() const {
|
Variant::operator double() const {
|
||||||
double result;
|
double result;
|
||||||
to_type_constructor[FLOAT](&result, _native_ptr());
|
to_type_constructor[FLOAT](&result, _native_ptr());
|
||||||
@@ -428,7 +411,7 @@ Variant::operator Object *() const {
|
|||||||
if (obj == nullptr) {
|
if (obj == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return internal::get_object_instance_binding(obj);
|
return reinterpret_cast<Object *>(internal::gde_interface->object_get_instance_binding(obj, internal::token, &Object::___binding_callbacks));
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant::operator ObjectID() const {
|
Variant::operator ObjectID() const {
|
||||||
@@ -526,7 +509,7 @@ Variant::operator PackedColorArray() const {
|
|||||||
|
|
||||||
Variant &Variant::operator=(const Variant &other) {
|
Variant &Variant::operator=(const Variant &other) {
|
||||||
clear();
|
clear();
|
||||||
internal::gdextension_interface_variant_new_copy(_native_ptr(), other._native_ptr());
|
internal::gde_interface->variant_new_copy(_native_ptr(), other._native_ptr());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -565,23 +548,23 @@ bool Variant::operator<(const Variant &other) const {
|
|||||||
return result.operator bool();
|
return result.operator bool();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Variant::callp(const StringName &method, const Variant **args, int argcount, Variant &r_ret, GDExtensionCallError &r_error) {
|
void Variant::call(const StringName &method, const Variant **args, int argcount, Variant &r_ret, GDExtensionCallError &r_error) {
|
||||||
internal::gdextension_interface_variant_call(_native_ptr(), method._native_ptr(), reinterpret_cast<GDExtensionConstVariantPtr *>(args), argcount, r_ret._native_ptr(), &r_error);
|
internal::gde_interface->variant_call(_native_ptr(), method._native_ptr(), reinterpret_cast<GDExtensionConstVariantPtr *>(args), argcount, r_ret._native_ptr(), &r_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Variant::callp_static(Variant::Type type, const StringName &method, const Variant **args, int argcount, Variant &r_ret, GDExtensionCallError &r_error) {
|
void Variant::call_static(Variant::Type type, const StringName &method, const Variant **args, int argcount, Variant &r_ret, GDExtensionCallError &r_error) {
|
||||||
internal::gdextension_interface_variant_call_static(static_cast<GDExtensionVariantType>(type), method._native_ptr(), reinterpret_cast<GDExtensionConstVariantPtr *>(args), argcount, r_ret._native_ptr(), &r_error);
|
internal::gde_interface->variant_call_static(static_cast<GDExtensionVariantType>(type), method._native_ptr(), reinterpret_cast<GDExtensionConstVariantPtr *>(args), argcount, r_ret._native_ptr(), &r_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Variant::evaluate(const Operator &op, const Variant &a, const Variant &b, Variant &r_ret, bool &r_valid) {
|
void Variant::evaluate(const Operator &op, const Variant &a, const Variant &b, Variant &r_ret, bool &r_valid) {
|
||||||
GDExtensionBool valid;
|
GDExtensionBool valid;
|
||||||
internal::gdextension_interface_variant_evaluate(static_cast<GDExtensionVariantOperator>(op), a._native_ptr(), b._native_ptr(), r_ret._native_ptr(), &valid);
|
internal::gde_interface->variant_evaluate(static_cast<GDExtensionVariantOperator>(op), a._native_ptr(), b._native_ptr(), r_ret._native_ptr(), &valid);
|
||||||
r_valid = PtrToArg<bool>::convert(&valid);
|
r_valid = PtrToArg<bool>::convert(&valid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Variant::set(const Variant &key, const Variant &value, bool *r_valid) {
|
void Variant::set(const Variant &key, const Variant &value, bool *r_valid) {
|
||||||
GDExtensionBool valid;
|
GDExtensionBool valid;
|
||||||
internal::gdextension_interface_variant_set(_native_ptr(), key._native_ptr(), value._native_ptr(), &valid);
|
internal::gde_interface->variant_set(_native_ptr(), key._native_ptr(), value._native_ptr(), &valid);
|
||||||
if (r_valid) {
|
if (r_valid) {
|
||||||
*r_valid = PtrToArg<bool>::convert(&valid);
|
*r_valid = PtrToArg<bool>::convert(&valid);
|
||||||
}
|
}
|
||||||
@@ -589,27 +572,27 @@ void Variant::set(const Variant &key, const Variant &value, bool *r_valid) {
|
|||||||
|
|
||||||
void Variant::set_named(const StringName &name, const Variant &value, bool &r_valid) {
|
void Variant::set_named(const StringName &name, const Variant &value, bool &r_valid) {
|
||||||
GDExtensionBool valid;
|
GDExtensionBool valid;
|
||||||
internal::gdextension_interface_variant_set_named(_native_ptr(), name._native_ptr(), value._native_ptr(), &valid);
|
internal::gde_interface->variant_set_named(_native_ptr(), name._native_ptr(), value._native_ptr(), &valid);
|
||||||
r_valid = PtrToArg<bool>::convert(&valid);
|
r_valid = PtrToArg<bool>::convert(&valid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Variant::set_indexed(int64_t index, const Variant &value, bool &r_valid, bool &r_oob) {
|
void Variant::set_indexed(int64_t index, const Variant &value, bool &r_valid, bool &r_oob) {
|
||||||
GDExtensionBool valid, oob;
|
GDExtensionBool valid, oob;
|
||||||
internal::gdextension_interface_variant_set_indexed(_native_ptr(), index, value._native_ptr(), &valid, &oob);
|
internal::gde_interface->variant_set_indexed(_native_ptr(), index, value._native_ptr(), &valid, &oob);
|
||||||
r_valid = PtrToArg<bool>::convert(&valid);
|
r_valid = PtrToArg<bool>::convert(&valid);
|
||||||
r_oob = PtrToArg<bool>::convert(&oob);
|
r_oob = PtrToArg<bool>::convert(&oob);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Variant::set_keyed(const Variant &key, const Variant &value, bool &r_valid) {
|
void Variant::set_keyed(const Variant &key, const Variant &value, bool &r_valid) {
|
||||||
GDExtensionBool valid;
|
GDExtensionBool valid;
|
||||||
internal::gdextension_interface_variant_set_keyed(_native_ptr(), key._native_ptr(), value._native_ptr(), &valid);
|
internal::gde_interface->variant_set_keyed(_native_ptr(), key._native_ptr(), value._native_ptr(), &valid);
|
||||||
r_valid = PtrToArg<bool>::convert(&valid);
|
r_valid = PtrToArg<bool>::convert(&valid);
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant Variant::get(const Variant &key, bool *r_valid) const {
|
Variant Variant::get(const Variant &key, bool *r_valid) const {
|
||||||
Variant result;
|
Variant result;
|
||||||
GDExtensionBool valid;
|
GDExtensionBool valid;
|
||||||
internal::gdextension_interface_variant_get(_native_ptr(), key._native_ptr(), result._native_ptr(), &valid);
|
internal::gde_interface->variant_get(_native_ptr(), key._native_ptr(), result._native_ptr(), &valid);
|
||||||
if (r_valid) {
|
if (r_valid) {
|
||||||
*r_valid = PtrToArg<bool>::convert(&valid);
|
*r_valid = PtrToArg<bool>::convert(&valid);
|
||||||
}
|
}
|
||||||
@@ -619,7 +602,7 @@ Variant Variant::get(const Variant &key, bool *r_valid) const {
|
|||||||
Variant Variant::get_named(const StringName &name, bool &r_valid) const {
|
Variant Variant::get_named(const StringName &name, bool &r_valid) const {
|
||||||
Variant result;
|
Variant result;
|
||||||
GDExtensionBool valid;
|
GDExtensionBool valid;
|
||||||
internal::gdextension_interface_variant_get_named(_native_ptr(), name._native_ptr(), result._native_ptr(), &valid);
|
internal::gde_interface->variant_get_named(_native_ptr(), name._native_ptr(), result._native_ptr(), &valid);
|
||||||
r_valid = PtrToArg<bool>::convert(&valid);
|
r_valid = PtrToArg<bool>::convert(&valid);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -628,7 +611,7 @@ Variant Variant::get_indexed(int64_t index, bool &r_valid, bool &r_oob) const {
|
|||||||
Variant result;
|
Variant result;
|
||||||
GDExtensionBool valid;
|
GDExtensionBool valid;
|
||||||
GDExtensionBool oob;
|
GDExtensionBool oob;
|
||||||
internal::gdextension_interface_variant_get_indexed(_native_ptr(), index, result._native_ptr(), &valid, &oob);
|
internal::gde_interface->variant_get_indexed(_native_ptr(), index, result._native_ptr(), &valid, &oob);
|
||||||
r_valid = PtrToArg<bool>::convert(&valid);
|
r_valid = PtrToArg<bool>::convert(&valid);
|
||||||
r_oob = PtrToArg<bool>::convert(&oob);
|
r_oob = PtrToArg<bool>::convert(&oob);
|
||||||
return result;
|
return result;
|
||||||
@@ -637,7 +620,7 @@ Variant Variant::get_indexed(int64_t index, bool &r_valid, bool &r_oob) const {
|
|||||||
Variant Variant::get_keyed(const Variant &key, bool &r_valid) const {
|
Variant Variant::get_keyed(const Variant &key, bool &r_valid) const {
|
||||||
Variant result;
|
Variant result;
|
||||||
GDExtensionBool valid;
|
GDExtensionBool valid;
|
||||||
internal::gdextension_interface_variant_get_keyed(_native_ptr(), key._native_ptr(), result._native_ptr(), &valid);
|
internal::gde_interface->variant_get_keyed(_native_ptr(), key._native_ptr(), result._native_ptr(), &valid);
|
||||||
r_valid = PtrToArg<bool>::convert(&valid);
|
r_valid = PtrToArg<bool>::convert(&valid);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -654,38 +637,36 @@ bool Variant::in(const Variant &index, bool *r_valid) const {
|
|||||||
|
|
||||||
bool Variant::iter_init(Variant &r_iter, bool &r_valid) const {
|
bool Variant::iter_init(Variant &r_iter, bool &r_valid) const {
|
||||||
GDExtensionBool valid;
|
GDExtensionBool valid;
|
||||||
GDExtensionBool result = internal::gdextension_interface_variant_iter_init(_native_ptr(), r_iter._native_ptr(), &valid);
|
internal::gde_interface->variant_iter_init(_native_ptr(), r_iter._native_ptr(), &valid);
|
||||||
r_valid = PtrToArg<bool>::convert(&valid);
|
return PtrToArg<bool>::convert(&valid);
|
||||||
return PtrToArg<bool>::convert(&result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Variant::iter_next(Variant &r_iter, bool &r_valid) const {
|
bool Variant::iter_next(Variant &r_iter, bool &r_valid) const {
|
||||||
GDExtensionBool valid;
|
GDExtensionBool valid;
|
||||||
GDExtensionBool result = internal::gdextension_interface_variant_iter_next(_native_ptr(), r_iter._native_ptr(), &valid);
|
internal::gde_interface->variant_iter_next(_native_ptr(), r_iter._native_ptr(), &valid);
|
||||||
r_valid = PtrToArg<bool>::convert(&valid);
|
return PtrToArg<bool>::convert(&valid);
|
||||||
return PtrToArg<bool>::convert(&result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const {
|
Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const {
|
||||||
Variant result;
|
Variant result;
|
||||||
GDExtensionBool valid;
|
GDExtensionBool valid;
|
||||||
internal::gdextension_interface_variant_iter_get(_native_ptr(), r_iter._native_ptr(), result._native_ptr(), &valid);
|
internal::gde_interface->variant_iter_get(_native_ptr(), r_iter._native_ptr(), result._native_ptr(), &valid);
|
||||||
r_valid = PtrToArg<bool>::convert(&valid);
|
r_valid = PtrToArg<bool>::convert(&valid);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant::Type Variant::get_type() const {
|
Variant::Type Variant::get_type() const {
|
||||||
return static_cast<Variant::Type>(internal::gdextension_interface_variant_get_type(_native_ptr()));
|
return static_cast<Variant::Type>(internal::gde_interface->variant_get_type(_native_ptr()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Variant::has_method(const StringName &method) const {
|
bool Variant::has_method(const StringName &method) const {
|
||||||
GDExtensionBool has = internal::gdextension_interface_variant_has_method(_native_ptr(), method._native_ptr());
|
GDExtensionBool has = internal::gde_interface->variant_has_method(_native_ptr(), method._native_ptr());
|
||||||
return PtrToArg<bool>::convert(&has);
|
return PtrToArg<bool>::convert(&has);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Variant::has_key(const Variant &key, bool *r_valid) const {
|
bool Variant::has_key(const Variant &key, bool *r_valid) const {
|
||||||
GDExtensionBool valid;
|
GDExtensionBool valid;
|
||||||
GDExtensionBool has = internal::gdextension_interface_variant_has_key(_native_ptr(), key._native_ptr(), &valid);
|
GDExtensionBool has = internal::gde_interface->variant_has_key(_native_ptr(), key._native_ptr(), &valid);
|
||||||
if (r_valid) {
|
if (r_valid) {
|
||||||
*r_valid = PtrToArg<bool>::convert(&valid);
|
*r_valid = PtrToArg<bool>::convert(&valid);
|
||||||
}
|
}
|
||||||
@@ -693,33 +674,33 @@ bool Variant::has_key(const Variant &key, bool *r_valid) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Variant::has_member(Variant::Type type, const StringName &member) {
|
bool Variant::has_member(Variant::Type type, const StringName &member) {
|
||||||
GDExtensionBool has = internal::gdextension_interface_variant_has_member(static_cast<GDExtensionVariantType>(type), member._native_ptr());
|
GDExtensionBool has = internal::gde_interface->variant_has_member(static_cast<GDExtensionVariantType>(type), member._native_ptr());
|
||||||
return PtrToArg<bool>::convert(&has);
|
return PtrToArg<bool>::convert(&has);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Variant::hash() const {
|
uint32_t Variant::hash() const {
|
||||||
GDExtensionInt hash = internal::gdextension_interface_variant_hash(_native_ptr());
|
GDExtensionInt hash = internal::gde_interface->variant_hash(_native_ptr());
|
||||||
return PtrToArg<uint32_t>::convert(&hash);
|
return PtrToArg<uint32_t>::convert(&hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Variant::recursive_hash(int recursion_count) const {
|
uint32_t Variant::recursive_hash(int recursion_count) const {
|
||||||
GDExtensionInt hash = internal::gdextension_interface_variant_recursive_hash(_native_ptr(), recursion_count);
|
GDExtensionInt hash = internal::gde_interface->variant_recursive_hash(_native_ptr(), recursion_count);
|
||||||
return PtrToArg<uint32_t>::convert(&hash);
|
return PtrToArg<uint32_t>::convert(&hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Variant::hash_compare(const Variant &variant) const {
|
bool Variant::hash_compare(const Variant &variant) const {
|
||||||
GDExtensionBool compare = internal::gdextension_interface_variant_hash_compare(_native_ptr(), variant._native_ptr());
|
GDExtensionBool compare = internal::gde_interface->variant_hash_compare(_native_ptr(), variant._native_ptr());
|
||||||
return PtrToArg<bool>::convert(&compare);
|
return PtrToArg<bool>::convert(&compare);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Variant::booleanize() const {
|
bool Variant::booleanize() const {
|
||||||
GDExtensionBool booleanized = internal::gdextension_interface_variant_booleanize(_native_ptr());
|
GDExtensionBool booleanized = internal::gde_interface->variant_booleanize(_native_ptr());
|
||||||
return PtrToArg<bool>::convert(&booleanized);
|
return PtrToArg<bool>::convert(&booleanized);
|
||||||
}
|
}
|
||||||
|
|
||||||
String Variant::stringify() const {
|
String Variant::stringify() const {
|
||||||
String result;
|
String result;
|
||||||
internal::gdextension_interface_variant_stringify(_native_ptr(), result._native_ptr());
|
internal::gde_interface->variant_stringify(_native_ptr(), result._native_ptr());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -727,23 +708,23 @@ Variant Variant::duplicate(bool deep) const {
|
|||||||
Variant result;
|
Variant result;
|
||||||
GDExtensionBool _deep;
|
GDExtensionBool _deep;
|
||||||
PtrToArg<bool>::encode(deep, &_deep);
|
PtrToArg<bool>::encode(deep, &_deep);
|
||||||
internal::gdextension_interface_variant_duplicate(_native_ptr(), result._native_ptr(), _deep);
|
internal::gde_interface->variant_duplicate(_native_ptr(), result._native_ptr(), _deep);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
String Variant::get_type_name(Variant::Type type) {
|
String Variant::get_type_name(Variant::Type type) {
|
||||||
String result;
|
String result;
|
||||||
internal::gdextension_interface_variant_get_type_name(static_cast<GDExtensionVariantType>(type), result._native_ptr());
|
internal::gde_interface->variant_get_type_name(static_cast<GDExtensionVariantType>(type), result._native_ptr());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Variant::can_convert(Variant::Type from, Variant::Type to) {
|
bool Variant::can_convert(Variant::Type from, Variant::Type to) {
|
||||||
GDExtensionBool can = internal::gdextension_interface_variant_can_convert(static_cast<GDExtensionVariantType>(from), static_cast<GDExtensionVariantType>(to));
|
GDExtensionBool can = internal::gde_interface->variant_can_convert(static_cast<GDExtensionVariantType>(from), static_cast<GDExtensionVariantType>(to));
|
||||||
return PtrToArg<bool>::convert(&can);
|
return PtrToArg<bool>::convert(&can);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Variant::can_convert_strict(Variant::Type from, Variant::Type to) {
|
bool Variant::can_convert_strict(Variant::Type from, Variant::Type to) {
|
||||||
GDExtensionBool can = internal::gdextension_interface_variant_can_convert_strict(static_cast<GDExtensionVariantType>(from), static_cast<GDExtensionVariantType>(to));
|
GDExtensionBool can = internal::gde_interface->variant_can_convert_strict(static_cast<GDExtensionVariantType>(from), static_cast<GDExtensionVariantType>(to));
|
||||||
return PtrToArg<bool>::convert(&can);
|
return PtrToArg<bool>::convert(&can);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -794,9 +775,9 @@ void Variant::clear() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (unlikely(needs_deinit[get_type()])) { // Make it fast for types that don't need deinit.
|
if (unlikely(needs_deinit[get_type()])) { // Make it fast for types that don't need deinit.
|
||||||
internal::gdextension_interface_variant_destroy(_native_ptr());
|
internal::gde_interface->variant_destroy(_native_ptr());
|
||||||
}
|
}
|
||||||
internal::gdextension_interface_variant_new_nil(_native_ptr());
|
internal::gde_interface->variant_new_nil(_native_ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace godot
|
} // namespace godot
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ set(GODOT_LINKER_FLAGS )
|
|||||||
|
|
||||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||||
# using Visual Studio C++
|
# using Visual Studio C++
|
||||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /WX") # /GF /MP
|
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /EHsc /WX") # /GF /MP
|
||||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /DTYPED_METHOD_BIND")
|
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /DTYPED_METHOD_BIND")
|
||||||
|
|
||||||
if(CMAKE_BUILD_TYPE MATCHES Debug)
|
if(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||||
@@ -92,21 +92,6 @@ else()
|
|||||||
endif(CMAKE_BUILD_TYPE MATCHES Debug)
|
endif(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||||
endif()
|
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()
|
|
||||||
|
|
||||||
# Get Sources
|
# Get Sources
|
||||||
file(GLOB_RECURSE SOURCES src/*.c**)
|
file(GLOB_RECURSE SOURCES src/*.c**)
|
||||||
file(GLOB_RECURSE HEADERS include/*.h**)
|
file(GLOB_RECURSE HEADERS include/*.h**)
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
# godot-cpp integration test
|
# godot-cpp example / integration test
|
||||||
|
|
||||||
This project is used to perform integration testing of the godot-cpp
|
This project is used to perform integration testing of the godot-cpp
|
||||||
extension, to validate PRs and implemented APIs.
|
extension, to validate PRs and implemented APIs.
|
||||||
|
|
||||||
|
It can also be used as a quick example of how to set up a godot-cpp
|
||||||
|
project, both on the C++ side and in the Godot project itself.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
This is free and unencumbered software released into the public domain.
|
This is free and unencumbered software released into the public domain.
|
||||||
|
|||||||
@@ -18,25 +18,14 @@ sources = Glob("src/*.cpp")
|
|||||||
|
|
||||||
if env["platform"] == "macos":
|
if env["platform"] == "macos":
|
||||||
library = env.SharedLibrary(
|
library = env.SharedLibrary(
|
||||||
"project/bin/libgdexample.{}.{}.framework/libgdexample.{}.{}".format(
|
"demo/bin/libgdexample.{}.{}.framework/libgdexample.{}.{}".format(
|
||||||
env["platform"], env["target"], env["platform"], env["target"]
|
env["platform"], env["target"], env["platform"], env["target"]
|
||||||
),
|
),
|
||||||
source=sources,
|
source=sources,
|
||||||
)
|
)
|
||||||
elif env["platform"] == "ios":
|
|
||||||
if env["ios_simulator"]:
|
|
||||||
library = env.StaticLibrary(
|
|
||||||
"project/bin/libgdexample.{}.{}.simulator.a".format(env["platform"], env["target"]),
|
|
||||||
source=sources,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
library = env.StaticLibrary(
|
|
||||||
"project/bin/libgdexample.{}.{}.a".format(env["platform"], env["target"]),
|
|
||||||
source=sources,
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
library = env.SharedLibrary(
|
library = env.SharedLibrary(
|
||||||
"project/bin/libgdexample{}{}".format(env["suffix"], env["SHLIBSUFFIX"]),
|
"demo/bin/libgdexample{}{}".format(env["suffix"], env["SHLIBSUFFIX"]),
|
||||||
source=sources,
|
source=sources,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -4,4 +4,4 @@
|
|||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
background_mode = 2
|
background_mode = 2
|
||||||
sky = SubResource("1")
|
sky = SubResource( "1" )
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
[configuration]
|
[configuration]
|
||||||
|
|
||||||
entry_symbol = "example_library_init"
|
entry_symbol = "example_library_init"
|
||||||
compatibility_minimum = "4.1"
|
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
|
|
||||||
@@ -11,14 +10,8 @@ windows.debug.x86_32 = "res://bin/libgdexample.windows.template_debug.x86_32.dll
|
|||||||
windows.release.x86_32 = "res://bin/libgdexample.windows.template_release.x86_32.dll"
|
windows.release.x86_32 = "res://bin/libgdexample.windows.template_release.x86_32.dll"
|
||||||
windows.debug.x86_64 = "res://bin/libgdexample.windows.template_debug.x86_64.dll"
|
windows.debug.x86_64 = "res://bin/libgdexample.windows.template_debug.x86_64.dll"
|
||||||
windows.release.x86_64 = "res://bin/libgdexample.windows.template_release.x86_64.dll"
|
windows.release.x86_64 = "res://bin/libgdexample.windows.template_release.x86_64.dll"
|
||||||
windows.debug.arm64 = "res://bin/libgdexample.windows.template_debug.arm64.dll"
|
|
||||||
windows.release.arm64 = "res://bin/libgdexample.windows.template_release.arm64.dll"
|
|
||||||
linux.debug.x86_32 = "res://bin/libgdexample.linux.template_debug.x86_32.so"
|
|
||||||
linux.release.x86_32 = "res://bin/libgdexample.linux.template_release.x86_32.so"
|
|
||||||
linux.debug.x86_64 = "res://bin/libgdexample.linux.template_debug.x86_64.so"
|
linux.debug.x86_64 = "res://bin/libgdexample.linux.template_debug.x86_64.so"
|
||||||
linux.release.x86_64 = "res://bin/libgdexample.linux.template_release.x86_64.so"
|
linux.release.x86_64 = "res://bin/libgdexample.linux.template_release.x86_64.so"
|
||||||
linux.debug.arm32 = "res://bin/libgdexample.linux.template_debug.arm32.so"
|
|
||||||
linux.release.arm32 = "res://bin/libgdexample.linux.template_release.arm32.so"
|
|
||||||
linux.debug.arm64 = "res://bin/libgdexample.linux.template_debug.arm64.so"
|
linux.debug.arm64 = "res://bin/libgdexample.linux.template_debug.arm64.so"
|
||||||
linux.release.arm64 = "res://bin/libgdexample.linux.template_release.arm64.so"
|
linux.release.arm64 = "res://bin/libgdexample.linux.template_release.arm64.so"
|
||||||
linux.debug.rv64 = "res://bin/libgdexample.linux.template_debug.rv64.so"
|
linux.debug.rv64 = "res://bin/libgdexample.linux.template_debug.rv64.so"
|
||||||
@@ -27,15 +20,3 @@ android.debug.x86_64 = "res://bin/libgdexample.android.template_debug.x86_64.so"
|
|||||||
android.release.x86_64 = "res://bin/libgdexample.android.template_release.x86_64.so"
|
android.release.x86_64 = "res://bin/libgdexample.android.template_release.x86_64.so"
|
||||||
android.debug.arm64 = "res://bin/libgdexample.android.template_debug.arm64.so"
|
android.debug.arm64 = "res://bin/libgdexample.android.template_debug.arm64.so"
|
||||||
android.release.arm64 = "res://bin/libgdexample.android.template_release.arm64.so"
|
android.release.arm64 = "res://bin/libgdexample.android.template_release.arm64.so"
|
||||||
ios.debug = "res://bin/libgdexample.ios.template_debug.xcframework"
|
|
||||||
ios.release = "res://bin/libgdexample.ios.template_release.xcframework"
|
|
||||||
web.debug.wasm32 = "res://bin/libgdexample.web.template_debug.wasm32.wasm"
|
|
||||||
web.release.wasm32 = "res://bin/libgdexample.web.template_release.wasm32.wasm"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
ios.debug = {
|
|
||||||
"res://bin/libgodot-cpp.ios.template_debug.xcframework": ""
|
|
||||||
}
|
|
||||||
ios.release = {
|
|
||||||
"res://bin/libgodot-cpp.ios.template_release.xcframework": ""
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
@@ -16,9 +16,9 @@ dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.cte
|
|||||||
[params]
|
[params]
|
||||||
|
|
||||||
compress/mode=0
|
compress/mode=0
|
||||||
compress/high_quality=false
|
|
||||||
compress/lossy_quality=0.7
|
compress/lossy_quality=0.7
|
||||||
compress/hdr_compression=1
|
compress/hdr_compression=1
|
||||||
|
compress/bptc_ldr=0
|
||||||
compress/normal_map=0
|
compress/normal_map=0
|
||||||
compress/channel_pack=0
|
compress/channel_pack=0
|
||||||
mipmaps/generate=false
|
mipmaps/generate=false
|
||||||
80
test/demo/main.gd
Normal file
80
test/demo/main.gd
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
extends Node
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
# Bind signals
|
||||||
|
prints("Signal bind")
|
||||||
|
$Button.button_up.connect($Example.emit_custom_signal.bind("Button", 42))
|
||||||
|
|
||||||
|
prints("")
|
||||||
|
|
||||||
|
# To string.
|
||||||
|
prints("To string")
|
||||||
|
prints(" Example --> ", $Example.to_string())
|
||||||
|
prints(" ExampleMin --> ", $Example/ExampleMin.to_string())
|
||||||
|
|
||||||
|
# Call static methods.
|
||||||
|
prints("Static method calls")
|
||||||
|
prints(" static (109)", Example.test_static(9, 100));
|
||||||
|
Example.test_static2();
|
||||||
|
|
||||||
|
# Property list.
|
||||||
|
prints("Property list")
|
||||||
|
$Example.property_from_list = Vector3(100, 200, 300)
|
||||||
|
prints(" property value ", $Example.property_from_list)
|
||||||
|
|
||||||
|
# Call methods.
|
||||||
|
prints("Instance method calls")
|
||||||
|
$Example.simple_func()
|
||||||
|
($Example as Example).simple_const_func() # Force use of ptrcall
|
||||||
|
prints(" returned", $Example.return_something("some string"))
|
||||||
|
prints(" returned const", $Example.return_something_const())
|
||||||
|
var null_ref = $Example.return_empty_ref()
|
||||||
|
prints(" returned empty ref", null_ref)
|
||||||
|
var ret_ref = $Example.return_extended_ref()
|
||||||
|
prints(" returned ref", ret_ref.get_instance_id(), ", id:", ret_ref.get_id())
|
||||||
|
prints(" returned ", $Example.get_v4())
|
||||||
|
prints(" test node argument", $Example.test_node_argument($Example))
|
||||||
|
|
||||||
|
prints("VarArg method calls")
|
||||||
|
var ref = ExampleRef.new()
|
||||||
|
prints(" sending ref: ", ref.get_instance_id(), "returned ref: ", $Example.extended_ref_checks(ref).get_instance_id())
|
||||||
|
prints(" vararg args", $Example.varargs_func("some", "arguments", "to", "test"))
|
||||||
|
prints(" vararg_nv ret", $Example.varargs_func_nv("some", "arguments", "to", "test"))
|
||||||
|
$Example.varargs_func_void("some", "arguments", "to", "test")
|
||||||
|
|
||||||
|
prints("Method calls with default values")
|
||||||
|
prints(" defval (300)", $Example.def_args())
|
||||||
|
prints(" defval (250)", $Example.def_args(50))
|
||||||
|
prints(" defval (150)", $Example.def_args(50, 100))
|
||||||
|
|
||||||
|
prints("Array and Dictionary")
|
||||||
|
prints(" test array", $Example.test_array())
|
||||||
|
prints(" test tarray", $Example.test_tarray())
|
||||||
|
prints(" test dictionary", $Example.test_dictionary())
|
||||||
|
var array: Array[int] = [1, 2, 3]
|
||||||
|
$Example.test_tarray_arg(array)
|
||||||
|
|
||||||
|
prints("String += operator")
|
||||||
|
prints(" test string +=", $Example.test_string_ops())
|
||||||
|
|
||||||
|
prints("PackedArray iterators")
|
||||||
|
prints(" test packed array iterators", $Example.test_vector_ops())
|
||||||
|
|
||||||
|
prints("Properties")
|
||||||
|
prints(" custom position is", $Example.group_subgroup_custom_position)
|
||||||
|
$Example.group_subgroup_custom_position = Vector2(50, 50)
|
||||||
|
prints(" custom position now is", $Example.group_subgroup_custom_position)
|
||||||
|
|
||||||
|
prints("Constants")
|
||||||
|
prints(" FIRST", $Example.FIRST)
|
||||||
|
prints(" ANSWER_TO_EVERYTHING", $Example.ANSWER_TO_EVERYTHING)
|
||||||
|
prints(" CONSTANT_WITHOUT_ENUM", $Example.CONSTANT_WITHOUT_ENUM)
|
||||||
|
|
||||||
|
prints("BitFields")
|
||||||
|
prints(" FLAG_ONE", Example.FLAG_ONE)
|
||||||
|
prints(" FLAG_TWO", Example.FLAG_TWO)
|
||||||
|
prints(" returned BitField", $Example.test_bitfield(0))
|
||||||
|
prints(" returned BitField", $Example.test_bitfield(Example.FLAG_ONE | Example.FLAG_TWO))
|
||||||
|
|
||||||
|
func _on_Example_custom_signal(signal_name, value):
|
||||||
|
prints("Example emitted:", signal_name, value)
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
[gd_scene load_steps=2 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://main.gd" id="1_c326s"]
|
||||||
|
|
||||||
[node name="Node" type="Node"]
|
[node name="Node" type="Node"]
|
||||||
script = ExtResource("1_qesh5")
|
script = ExtResource("1_c326s")
|
||||||
|
|
||||||
[node name="Example" type="Example" parent="."]
|
[node name="Example" type="Example" parent="."]
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@ config_version=5
|
|||||||
|
|
||||||
config/name="GDExtension Test Project"
|
config/name="GDExtension Test Project"
|
||||||
run/main_scene="res://main.tscn"
|
run/main_scene="res://main.tscn"
|
||||||
config/features=PackedStringArray("4.2")
|
config/features=PackedStringArray("4.0")
|
||||||
config/icon="res://icon.png"
|
config/icon="res://icon.png"
|
||||||
|
|
||||||
[native_extensions]
|
[native_extensions]
|
||||||
@@ -21,5 +21,4 @@ paths=["res://example.gdextension"]
|
|||||||
|
|
||||||
[rendering]
|
[rendering]
|
||||||
|
|
||||||
textures/vram_compression/import_etc2_astc=true
|
|
||||||
environment/defaults/default_environment="res://default_env.tres"
|
environment/defaults/default_environment="res://default_env.tres"
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
scons arch=universal ios_simulator=yes platform=ios target=$1 $2
|
|
||||||
scons arch=arm64 ios_simulator=no platform=ios target=$1 $2
|
|
||||||
|
|
||||||
xcodebuild -create-xcframework -library ./project/bin/libgdexample.ios.$1.a -library ./project/bin/libgdexample.ios.$1.simulator.a -output ./project/bin/libgdexample.ios.$1.xcframework
|
|
||||||
xcodebuild -create-xcframework -library ../bin/libgodot-cpp.ios.$1.arm64.a -library ../bin/libgodot-cpp.ios.$1.universal.simulator.a -output ./project/bin/libgodot-cpp.ios.$1.xcframework
|
|
||||||
@@ -1,247 +0,0 @@
|
|||||||
extends "res://test_base.gd"
|
|
||||||
|
|
||||||
var custom_signal_emitted = null
|
|
||||||
|
|
||||||
class TestClass:
|
|
||||||
func test(p_msg: String) -> String:
|
|
||||||
return p_msg + " world"
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
var example: Example = $Example
|
|
||||||
|
|
||||||
# Signal.
|
|
||||||
example.emit_custom_signal("Button", 42)
|
|
||||||
assert_equal(custom_signal_emitted, ["Button", 42])
|
|
||||||
|
|
||||||
# To string.
|
|
||||||
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())
|
|
||||||
|
|
||||||
# Call static methods.
|
|
||||||
assert_equal(Example.test_static(9, 100), 109);
|
|
||||||
# It's void and static, so all we know is that it didn't crash.
|
|
||||||
Example.test_static2()
|
|
||||||
|
|
||||||
# Property list.
|
|
||||||
example.property_from_list = Vector3(100, 200, 300)
|
|
||||||
assert_equal(example.property_from_list, Vector3(100, 200, 300))
|
|
||||||
var prop_list = example.get_property_list()
|
|
||||||
for prop_info in prop_list:
|
|
||||||
if prop_info['name'] == 'mouse_filter':
|
|
||||||
assert_equal(prop_info['usage'], PROPERTY_USAGE_NO_EDITOR)
|
|
||||||
|
|
||||||
# Call simple methods.
|
|
||||||
example.simple_func()
|
|
||||||
assert_equal(custom_signal_emitted, ['simple_func', 3])
|
|
||||||
example.simple_const_func()
|
|
||||||
assert_equal(custom_signal_emitted, ['simple_const_func', 4])
|
|
||||||
|
|
||||||
# Pass custom reference.
|
|
||||||
assert_equal(example.custom_ref_func(null), -1)
|
|
||||||
var ref1 = ExampleRef.new()
|
|
||||||
ref1.id = 27
|
|
||||||
assert_equal(example.custom_ref_func(ref1), 27)
|
|
||||||
ref1.id += 1;
|
|
||||||
assert_equal(example.custom_const_ref_func(ref1), 28)
|
|
||||||
|
|
||||||
# Pass core reference.
|
|
||||||
assert_equal(example.image_ref_func(null), "invalid")
|
|
||||||
assert_equal(example.image_const_ref_func(null), "invalid")
|
|
||||||
var image = Image.new()
|
|
||||||
assert_equal(example.image_ref_func(image), "valid")
|
|
||||||
assert_equal(example.image_const_ref_func(image), "valid")
|
|
||||||
|
|
||||||
# Return values.
|
|
||||||
assert_equal(example.return_something("some string"), "some string42")
|
|
||||||
assert_equal(example.return_something_const(), get_viewport())
|
|
||||||
var null_ref = example.return_empty_ref()
|
|
||||||
assert_equal(null_ref, null)
|
|
||||||
var ret_ref = example.return_extended_ref()
|
|
||||||
assert_not_equal(ret_ref.get_instance_id(), 0)
|
|
||||||
assert_equal(ret_ref.get_id(), 0)
|
|
||||||
assert_equal(example.get_v4(), Vector4(1.2, 3.4, 5.6, 7.8))
|
|
||||||
assert_equal(example.test_node_argument(example), example)
|
|
||||||
|
|
||||||
# VarArg method calls.
|
|
||||||
var var_ref = ExampleRef.new()
|
|
||||||
assert_not_equal(example.extended_ref_checks(var_ref).get_instance_id(), var_ref.get_instance_id())
|
|
||||||
assert_equal(example.varargs_func("some", "arguments", "to", "test"), 4)
|
|
||||||
assert_equal(example.varargs_func_nv("some", "arguments", "to", "test"), 46)
|
|
||||||
example.varargs_func_void("some", "arguments", "to", "test")
|
|
||||||
assert_equal(custom_signal_emitted, ["varargs_func_void", 5])
|
|
||||||
|
|
||||||
# Method calls with default values.
|
|
||||||
assert_equal(example.def_args(), 300)
|
|
||||||
assert_equal(example.def_args(50), 250)
|
|
||||||
assert_equal(example.def_args(50, 100), 150)
|
|
||||||
|
|
||||||
# Array and Dictionary
|
|
||||||
assert_equal(example.test_array(), [1, 2])
|
|
||||||
assert_equal(example.test_tarray(), [ Vector2(1, 2), Vector2(2, 3) ])
|
|
||||||
assert_equal(example.test_dictionary(), {"hello": "world", "foo": "bar"})
|
|
||||||
var array: Array[int] = [1, 2, 3]
|
|
||||||
assert_equal(example.test_tarray_arg(array), 6)
|
|
||||||
|
|
||||||
example.callable_bind()
|
|
||||||
assert_equal(custom_signal_emitted, ["bound", 11])
|
|
||||||
|
|
||||||
# String += operator
|
|
||||||
assert_equal(example.test_string_ops(), "ABCĎE")
|
|
||||||
|
|
||||||
# UtilityFunctions::str()
|
|
||||||
assert_equal(example.test_str_utility(), "Hello, World! The answer is 42")
|
|
||||||
|
|
||||||
# Test converting string to char* and doing comparison.
|
|
||||||
assert_equal(example.test_string_is_fourty_two("blah"), false)
|
|
||||||
assert_equal(example.test_string_is_fourty_two("fourty two"), true)
|
|
||||||
|
|
||||||
# String::resize().
|
|
||||||
assert_equal(example.test_string_resize("What"), "What!?")
|
|
||||||
|
|
||||||
# mp_callable() with void method.
|
|
||||||
var mp_callable: Callable = example.test_callable_mp()
|
|
||||||
assert_equal(mp_callable.is_valid(), true)
|
|
||||||
mp_callable.call(example, "void", 36)
|
|
||||||
assert_equal(custom_signal_emitted, ["unbound_method1: Example - void", 36])
|
|
||||||
|
|
||||||
# Check that it works with is_connected().
|
|
||||||
assert_equal(example.renamed.is_connected(mp_callable), false)
|
|
||||||
example.renamed.connect(mp_callable)
|
|
||||||
assert_equal(example.renamed.is_connected(mp_callable), true)
|
|
||||||
# Make sure a new object is still treated as equivalent.
|
|
||||||
assert_equal(example.renamed.is_connected(example.test_callable_mp()), true)
|
|
||||||
assert_equal(mp_callable.hash(), example.test_callable_mp().hash())
|
|
||||||
example.renamed.disconnect(mp_callable)
|
|
||||||
assert_equal(example.renamed.is_connected(mp_callable), false)
|
|
||||||
|
|
||||||
# mp_callable() with return value.
|
|
||||||
var mp_callable_ret: Callable = example.test_callable_mp_ret()
|
|
||||||
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.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()
|
|
||||||
mp_callable_static.call(example, "static", 83)
|
|
||||||
assert_equal(custom_signal_emitted, ["unbound_static_method1: Example - static", 83])
|
|
||||||
|
|
||||||
# Check that it works with is_connected().
|
|
||||||
assert_equal(example.renamed.is_connected(mp_callable_static), false)
|
|
||||||
example.renamed.connect(mp_callable_static)
|
|
||||||
assert_equal(example.renamed.is_connected(mp_callable_static), true)
|
|
||||||
# Make sure a new object is still treated as equivalent.
|
|
||||||
assert_equal(example.renamed.is_connected(example.test_callable_mp_static()), true)
|
|
||||||
assert_equal(mp_callable_static.hash(), example.test_callable_mp_static().hash())
|
|
||||||
example.renamed.disconnect(mp_callable_static)
|
|
||||||
assert_equal(example.renamed.is_connected(mp_callable_static), false)
|
|
||||||
|
|
||||||
# mp_callable_static() with return value.
|
|
||||||
var mp_callable_static_ret: Callable = example.test_callable_mp_static_ret()
|
|
||||||
assert_equal(mp_callable_static_ret.call(example, "static-ret", 84), "unbound_static_method2: Example - static-ret - 84")
|
|
||||||
|
|
||||||
# CallableCustom.
|
|
||||||
var custom_callable: Callable = example.test_custom_callable();
|
|
||||||
assert_equal(custom_callable.is_custom(), true);
|
|
||||||
assert_equal(custom_callable.is_valid(), true);
|
|
||||||
assert_equal(custom_callable.call(), "Hi")
|
|
||||||
assert_equal(custom_callable.hash(), 27);
|
|
||||||
assert_equal(custom_callable.get_object(), null);
|
|
||||||
assert_equal(custom_callable.get_method(), "");
|
|
||||||
assert_equal(str(custom_callable), "<MyCallableCustom>");
|
|
||||||
|
|
||||||
# PackedArray iterators
|
|
||||||
assert_equal(example.test_vector_ops(), 105)
|
|
||||||
|
|
||||||
# Properties.
|
|
||||||
assert_equal(example.group_subgroup_custom_position, Vector2(0, 0))
|
|
||||||
example.group_subgroup_custom_position = Vector2(50, 50)
|
|
||||||
assert_equal(example.group_subgroup_custom_position, Vector2(50, 50))
|
|
||||||
|
|
||||||
# Test Object::cast_to<>() and that correct wrappers are being used.
|
|
||||||
var control = Control.new()
|
|
||||||
var sprite = Sprite2D.new()
|
|
||||||
var example_ref = ExampleRef.new()
|
|
||||||
|
|
||||||
assert_equal(example.test_object_cast_to_node(control), true)
|
|
||||||
assert_equal(example.test_object_cast_to_control(control), true)
|
|
||||||
assert_equal(example.test_object_cast_to_example(control), false)
|
|
||||||
|
|
||||||
assert_equal(example.test_object_cast_to_node(example), true)
|
|
||||||
assert_equal(example.test_object_cast_to_control(example), true)
|
|
||||||
assert_equal(example.test_object_cast_to_example(example), true)
|
|
||||||
|
|
||||||
assert_equal(example.test_object_cast_to_node(sprite), true)
|
|
||||||
assert_equal(example.test_object_cast_to_control(sprite), false)
|
|
||||||
assert_equal(example.test_object_cast_to_example(sprite), false)
|
|
||||||
|
|
||||||
assert_equal(example.test_object_cast_to_node(example_ref), false)
|
|
||||||
assert_equal(example.test_object_cast_to_control(example_ref), false)
|
|
||||||
assert_equal(example.test_object_cast_to_example(example_ref), false)
|
|
||||||
|
|
||||||
control.queue_free()
|
|
||||||
sprite.queue_free()
|
|
||||||
|
|
||||||
# Test conversions to and from Variant.
|
|
||||||
assert_equal(example.test_variant_vector2i_conversion(Vector2i(1, 1)), Vector2i(1, 1))
|
|
||||||
assert_equal(example.test_variant_vector2i_conversion(Vector2(1.0, 1.0)), Vector2i(1, 1))
|
|
||||||
assert_equal(example.test_variant_int_conversion(10), 10)
|
|
||||||
assert_equal(example.test_variant_int_conversion(10.0), 10)
|
|
||||||
assert_equal(example.test_variant_float_conversion(10.0), 10.0)
|
|
||||||
assert_equal(example.test_variant_float_conversion(10), 10.0)
|
|
||||||
|
|
||||||
# Test that ptrcalls from GDExtension to the engine are correctly encoding Object and RefCounted.
|
|
||||||
var new_node = Node.new()
|
|
||||||
example.test_add_child(new_node)
|
|
||||||
assert_equal(new_node.get_parent(), example)
|
|
||||||
|
|
||||||
var new_tileset = TileSet.new()
|
|
||||||
var new_tilemap = TileMap.new()
|
|
||||||
example.test_set_tileset(new_tilemap, new_tileset)
|
|
||||||
assert_equal(new_tilemap.tile_set, new_tileset)
|
|
||||||
new_tilemap.queue_free()
|
|
||||||
|
|
||||||
# Test variant call.
|
|
||||||
var test_obj = TestClass.new()
|
|
||||||
assert_equal(example.test_variant_call(test_obj), "hello world")
|
|
||||||
|
|
||||||
# Constants.
|
|
||||||
assert_equal(Example.FIRST, 0)
|
|
||||||
assert_equal(Example.ANSWER_TO_EVERYTHING, 42)
|
|
||||||
assert_equal(Example.CONSTANT_WITHOUT_ENUM, 314)
|
|
||||||
|
|
||||||
# BitFields.
|
|
||||||
assert_equal(Example.FLAG_ONE, 1)
|
|
||||||
assert_equal(Example.FLAG_TWO, 2)
|
|
||||||
assert_equal(example.test_bitfield(0), 0)
|
|
||||||
assert_equal(example.test_bitfield(Example.FLAG_ONE | Example.FLAG_TWO), 3)
|
|
||||||
|
|
||||||
# Test variant iterator.
|
|
||||||
assert_equal(example.test_variant_iterator([10, 20, 30]), [15, 25, 35])
|
|
||||||
assert_equal(example.test_variant_iterator(null), "iter_init: not valid")
|
|
||||||
|
|
||||||
# RPCs.
|
|
||||||
assert_equal(example.return_last_rpc_arg(), 0)
|
|
||||||
example.test_rpc(42)
|
|
||||||
assert_equal(example.return_last_rpc_arg(), 42)
|
|
||||||
example.test_send_rpc(100)
|
|
||||||
assert_equal(example.return_last_rpc_arg(), 100)
|
|
||||||
|
|
||||||
# Virtual method.
|
|
||||||
var event = InputEventKey.new()
|
|
||||||
event.key_label = KEY_H
|
|
||||||
event.unicode = 72
|
|
||||||
get_viewport().push_input(event)
|
|
||||||
assert_equal(custom_signal_emitted, ["_input: H", 72])
|
|
||||||
|
|
||||||
# Check NOTIFICATION_POST_INITIALIZED, both when created from GDScript and godot-cpp.
|
|
||||||
var new_example_ref = ExampleRef.new()
|
|
||||||
assert_equal(new_example_ref.was_post_initialized(), true)
|
|
||||||
assert_equal(example.test_post_initialize(), true)
|
|
||||||
|
|
||||||
exit_with_status()
|
|
||||||
|
|
||||||
func _on_Example_custom_signal(signal_name, value):
|
|
||||||
custom_signal_emitted = [signal_name, value]
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
extends Node
|
|
||||||
|
|
||||||
var test_passes := 0
|
|
||||||
var test_failures := 0
|
|
||||||
|
|
||||||
func __get_stack_frame():
|
|
||||||
var me = get_script()
|
|
||||||
for s in get_stack():
|
|
||||||
if s.source == me.resource_path:
|
|
||||||
return s
|
|
||||||
return null
|
|
||||||
|
|
||||||
func __assert_pass():
|
|
||||||
test_passes += 1
|
|
||||||
|
|
||||||
func __assert_fail():
|
|
||||||
test_failures += 1
|
|
||||||
var s = __get_stack_frame()
|
|
||||||
if s != null:
|
|
||||||
print_rich ("[color=red] == FAILURE: In function %s() from '%s' on line %s[/color]" % [s.function, s.source, s.line])
|
|
||||||
else:
|
|
||||||
print_rich ("[color=red] == FAILURE (run with --debug to get more information!) ==[/color]")
|
|
||||||
|
|
||||||
func assert_equal(actual, expected):
|
|
||||||
if actual == expected:
|
|
||||||
__assert_pass()
|
|
||||||
else:
|
|
||||||
__assert_fail()
|
|
||||||
print (" |-> Expected '%s' but got '%s'" % [expected, actual])
|
|
||||||
|
|
||||||
func assert_true(v):
|
|
||||||
assert_equal(v, true)
|
|
||||||
|
|
||||||
func assert_false(v):
|
|
||||||
assert_equal(v, false)
|
|
||||||
|
|
||||||
func assert_not_equal(actual, expected):
|
|
||||||
if actual != expected:
|
|
||||||
__assert_pass()
|
|
||||||
else:
|
|
||||||
__assert_fail()
|
|
||||||
print (" |-> Expected '%s' NOT to equal '%s'" % [expected, actual])
|
|
||||||
|
|
||||||
func exit_with_status() -> void:
|
|
||||||
var success: bool = (test_failures == 0)
|
|
||||||
print ("")
|
|
||||||
print_rich ("[color=%s] ==== TESTS FINISHED ==== [/color]" % ("green" if success else "red"))
|
|
||||||
print ("")
|
|
||||||
print_rich (" PASSES: [color=green]%s[/color]" % test_passes)
|
|
||||||
print_rich (" FAILURES: [color=red]%s[/color]" % test_failures)
|
|
||||||
print ("")
|
|
||||||
|
|
||||||
if success:
|
|
||||||
print_rich("[color=green] ******** PASSED ******** [/color]")
|
|
||||||
else:
|
|
||||||
print_rich("[color=red] ******** FAILED ********[/color]")
|
|
||||||
print("")
|
|
||||||
|
|
||||||
get_tree().quit(0 if success else 1)
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
GODOT=${GODOT:-godot}
|
|
||||||
|
|
||||||
END_STRING="==== TESTS FINISHED ===="
|
|
||||||
FAILURE_STRING="******** FAILED ********"
|
|
||||||
|
|
||||||
OUTPUT=$($GODOT --path project --debug --headless --quit)
|
|
||||||
ERRCODE=$?
|
|
||||||
|
|
||||||
echo "$OUTPUT"
|
|
||||||
echo
|
|
||||||
|
|
||||||
if ! echo "$OUTPUT" | grep -e "$END_STRING" >/dev/null; then
|
|
||||||
echo "ERROR: Tests failed to complete"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if echo "$OUTPUT" | grep -e "$FAILURE_STRING" >/dev/null; then
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Success!
|
|
||||||
exit 0
|
|
||||||
@@ -9,80 +9,31 @@
|
|||||||
|
|
||||||
#include <godot_cpp/classes/global_constants.hpp>
|
#include <godot_cpp/classes/global_constants.hpp>
|
||||||
#include <godot_cpp/classes/label.hpp>
|
#include <godot_cpp/classes/label.hpp>
|
||||||
#include <godot_cpp/classes/multiplayer_api.hpp>
|
|
||||||
#include <godot_cpp/classes/multiplayer_peer.hpp>
|
|
||||||
#include <godot_cpp/variant/utility_functions.hpp>
|
#include <godot_cpp/variant/utility_functions.hpp>
|
||||||
|
|
||||||
using namespace godot;
|
using namespace godot;
|
||||||
|
|
||||||
class MyCallableCustom : public CallableCustom {
|
int ExampleRef::instance_count = 0;
|
||||||
public:
|
int ExampleRef::last_id = 0;
|
||||||
virtual uint32_t hash() const {
|
|
||||||
return 27;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual String get_as_text() const {
|
|
||||||
return "<MyCallableCustom>";
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool compare_equal_func(const CallableCustom *p_a, const CallableCustom *p_b) {
|
|
||||||
return p_a == p_b;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual CompareEqualFunc get_compare_equal_func() const {
|
|
||||||
return &MyCallableCustom::compare_equal_func;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool compare_less_func(const CallableCustom *p_a, const CallableCustom *p_b) {
|
|
||||||
return (void *)p_a < (void *)p_b;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual CompareLessFunc get_compare_less_func() const {
|
|
||||||
return &MyCallableCustom::compare_less_func;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_valid() const {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ObjectID get_object() const {
|
|
||||||
return ObjectID();
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void ExampleRef::set_id(int p_id) {
|
|
||||||
id = p_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ExampleRef::get_id() const {
|
int ExampleRef::get_id() const {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExampleRef::_notification(int p_what) {
|
|
||||||
if (p_what == NOTIFICATION_POSTINITIALIZE) {
|
|
||||||
post_initialized = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExampleRef::_bind_methods() {
|
void ExampleRef::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("set_id", "id"), &ExampleRef::set_id);
|
|
||||||
ClassDB::bind_method(D_METHOD("get_id"), &ExampleRef::get_id);
|
ClassDB::bind_method(D_METHOD("get_id"), &ExampleRef::get_id);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("was_post_initialized"), &ExampleRef::was_post_initialized);
|
|
||||||
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "id"), "set_id", "get_id");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ExampleRef::ExampleRef() {
|
ExampleRef::ExampleRef() {
|
||||||
id = 0;
|
id = ++last_id;
|
||||||
|
instance_count++;
|
||||||
|
|
||||||
|
UtilityFunctions::print("ExampleRef ", itos(id), " created, current instance count: ", itos(instance_count));
|
||||||
}
|
}
|
||||||
|
|
||||||
ExampleRef::~ExampleRef() {
|
ExampleRef::~ExampleRef() {
|
||||||
|
instance_count--;
|
||||||
|
UtilityFunctions::print("ExampleRef ", itos(id), " destroyed, current instance count: ", itos(instance_count));
|
||||||
}
|
}
|
||||||
|
|
||||||
int Example::test_static(int p_a, int p_b) {
|
int Example::test_static(int p_a, int p_b) {
|
||||||
@@ -90,7 +41,7 @@ int Example::test_static(int p_a, int p_b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Example::test_static2() {
|
void Example::test_static2() {
|
||||||
//UtilityFunctions::print(" void static");
|
UtilityFunctions::print(" void static");
|
||||||
}
|
}
|
||||||
|
|
||||||
int Example::def_args(int p_a, int p_b) {
|
int Example::def_args(int p_a, int p_b) {
|
||||||
@@ -98,15 +49,7 @@ int Example::def_args(int p_a, int p_b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Example::_notification(int p_what) {
|
void Example::_notification(int p_what) {
|
||||||
if (p_what == NOTIFICATION_READY) {
|
UtilityFunctions::print("Notification: ", String::num(p_what));
|
||||||
Dictionary opts;
|
|
||||||
opts["rpc_mode"] = MultiplayerAPI::RPC_MODE_AUTHORITY;
|
|
||||||
opts["transfer_mode"] = MultiplayerPeer::TRANSFER_MODE_RELIABLE;
|
|
||||||
opts["call_local"] = true;
|
|
||||||
opts["channel"] = 0;
|
|
||||||
rpc_config("test_rpc", opts);
|
|
||||||
}
|
|
||||||
//UtilityFunctions::print("Notification: ", String::num(p_what));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Example::_set(const StringName &p_name, const Variant &p_value) {
|
bool Example::_set(const StringName &p_name, const Variant &p_value) {
|
||||||
@@ -165,22 +108,10 @@ bool Example::_property_get_revert(const StringName &p_name, Variant &r_property
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void Example::_validate_property(PropertyInfo &p_property) const {
|
|
||||||
String name = p_property.name;
|
|
||||||
// Test hiding the "mouse_filter" property from the editor.
|
|
||||||
if (name == "mouse_filter") {
|
|
||||||
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Example::_bind_methods() {
|
void Example::_bind_methods() {
|
||||||
// Methods.
|
// Methods.
|
||||||
ClassDB::bind_method(D_METHOD("simple_func"), &Example::simple_func);
|
ClassDB::bind_method(D_METHOD("simple_func"), &Example::simple_func);
|
||||||
ClassDB::bind_method(D_METHOD("simple_const_func"), &Example::simple_const_func);
|
ClassDB::bind_method(D_METHOD("simple_const_func"), &Example::simple_const_func);
|
||||||
ClassDB::bind_method(D_METHOD("custom_ref_func", "ref"), &Example::custom_ref_func);
|
|
||||||
ClassDB::bind_method(D_METHOD("custom_const_ref_func", "ref"), &Example::custom_const_ref_func);
|
|
||||||
ClassDB::bind_method(D_METHOD("image_ref_func", "image"), &Example::image_ref_func);
|
|
||||||
ClassDB::bind_method(D_METHOD("image_const_ref_func", "image"), &Example::image_const_ref_func);
|
|
||||||
ClassDB::bind_method(D_METHOD("return_something"), &Example::return_something);
|
ClassDB::bind_method(D_METHOD("return_something"), &Example::return_something);
|
||||||
ClassDB::bind_method(D_METHOD("return_something_const"), &Example::return_something_const);
|
ClassDB::bind_method(D_METHOD("return_something_const"), &Example::return_something_const);
|
||||||
ClassDB::bind_method(D_METHOD("return_empty_ref"), &Example::return_empty_ref);
|
ClassDB::bind_method(D_METHOD("return_empty_ref"), &Example::return_empty_ref);
|
||||||
@@ -193,42 +124,11 @@ void Example::_bind_methods() {
|
|||||||
ClassDB::bind_method(D_METHOD("test_dictionary"), &Example::test_dictionary);
|
ClassDB::bind_method(D_METHOD("test_dictionary"), &Example::test_dictionary);
|
||||||
ClassDB::bind_method(D_METHOD("test_node_argument"), &Example::test_node_argument);
|
ClassDB::bind_method(D_METHOD("test_node_argument"), &Example::test_node_argument);
|
||||||
ClassDB::bind_method(D_METHOD("test_string_ops"), &Example::test_string_ops);
|
ClassDB::bind_method(D_METHOD("test_string_ops"), &Example::test_string_ops);
|
||||||
ClassDB::bind_method(D_METHOD("test_str_utility"), &Example::test_str_utility);
|
|
||||||
ClassDB::bind_method(D_METHOD("test_string_is_fourty_two"), &Example::test_string_is_fourty_two);
|
|
||||||
ClassDB::bind_method(D_METHOD("test_string_resize"), &Example::test_string_resize);
|
|
||||||
ClassDB::bind_method(D_METHOD("test_vector_ops"), &Example::test_vector_ops);
|
ClassDB::bind_method(D_METHOD("test_vector_ops"), &Example::test_vector_ops);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("test_object_cast_to_node", "object"), &Example::test_object_cast_to_node);
|
|
||||||
ClassDB::bind_method(D_METHOD("test_object_cast_to_control", "object"), &Example::test_object_cast_to_control);
|
|
||||||
ClassDB::bind_method(D_METHOD("test_object_cast_to_example", "object"), &Example::test_object_cast_to_example);
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("test_variant_vector2i_conversion", "variant"), &Example::test_variant_vector2i_conversion);
|
|
||||||
ClassDB::bind_method(D_METHOD("test_variant_int_conversion", "variant"), &Example::test_variant_int_conversion);
|
|
||||||
ClassDB::bind_method(D_METHOD("test_variant_float_conversion", "variant"), &Example::test_variant_float_conversion);
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("test_add_child", "node"), &Example::test_add_child);
|
|
||||||
ClassDB::bind_method(D_METHOD("test_set_tileset", "tilemap", "tileset"), &Example::test_set_tileset);
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("test_variant_call", "variant"), &Example::test_variant_call);
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("test_callable_mp"), &Example::test_callable_mp);
|
|
||||||
ClassDB::bind_method(D_METHOD("test_callable_mp_ret"), &Example::test_callable_mp_ret);
|
|
||||||
ClassDB::bind_method(D_METHOD("test_callable_mp_retc"), &Example::test_callable_mp_retc);
|
|
||||||
ClassDB::bind_method(D_METHOD("test_callable_mp_static"), &Example::test_callable_mp_static);
|
|
||||||
ClassDB::bind_method(D_METHOD("test_callable_mp_static_ret"), &Example::test_callable_mp_static_ret);
|
|
||||||
ClassDB::bind_method(D_METHOD("test_custom_callable"), &Example::test_custom_callable);
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("test_bitfield", "flags"), &Example::test_bitfield);
|
ClassDB::bind_method(D_METHOD("test_bitfield", "flags"), &Example::test_bitfield);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("test_variant_iterator", "input"), &Example::test_variant_iterator);
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("test_rpc", "value"), &Example::test_rpc);
|
|
||||||
ClassDB::bind_method(D_METHOD("test_send_rpc", "value"), &Example::test_send_rpc);
|
|
||||||
ClassDB::bind_method(D_METHOD("return_last_rpc_arg"), &Example::return_last_rpc_arg);
|
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("def_args", "a", "b"), &Example::def_args, DEFVAL(100), DEFVAL(200));
|
ClassDB::bind_method(D_METHOD("def_args", "a", "b"), &Example::def_args, DEFVAL(100), DEFVAL(200));
|
||||||
ClassDB::bind_method(D_METHOD("callable_bind"), &Example::callable_bind);
|
|
||||||
ClassDB::bind_method(D_METHOD("test_post_initialize"), &Example::test_post_initialize);
|
|
||||||
|
|
||||||
ClassDB::bind_static_method("Example", D_METHOD("test_static", "a", "b"), &Example::test_static);
|
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_static2"), &Example::test_static2);
|
||||||
@@ -279,43 +179,29 @@ void Example::_bind_methods() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Example::Example() {
|
Example::Example() {
|
||||||
//UtilityFunctions::print("Constructor.");
|
UtilityFunctions::print("Constructor.");
|
||||||
}
|
}
|
||||||
|
|
||||||
Example::~Example() {
|
Example::~Example() {
|
||||||
//UtilityFunctions::print("Destructor.");
|
UtilityFunctions::print("Destructor.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Methods.
|
// Methods.
|
||||||
void Example::simple_func() {
|
void Example::simple_func() {
|
||||||
emit_custom_signal("simple_func", 3);
|
UtilityFunctions::print(" Simple func called.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Example::simple_const_func() const {
|
void Example::simple_const_func() const {
|
||||||
((Example *)this)->emit_custom_signal("simple_const_func", 4);
|
UtilityFunctions::print(" Simple const func called.");
|
||||||
}
|
|
||||||
|
|
||||||
int Example::custom_ref_func(Ref<ExampleRef> p_ref) {
|
|
||||||
return p_ref.is_valid() ? p_ref->get_id() : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Example::custom_const_ref_func(const Ref<ExampleRef> &p_ref) {
|
|
||||||
return p_ref.is_valid() ? p_ref->get_id() : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
String Example::image_ref_func(Ref<Image> p_image) {
|
|
||||||
return p_image.is_valid() ? String("valid") : String("invalid");
|
|
||||||
}
|
|
||||||
|
|
||||||
String Example::image_const_ref_func(const Ref<Image> &p_image) {
|
|
||||||
return p_image.is_valid() ? String("valid") : String("invalid");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String Example::return_something(const String &base) {
|
String Example::return_something(const String &base) {
|
||||||
return base + String("42");
|
UtilityFunctions::print(" Return something called.");
|
||||||
|
return base;
|
||||||
}
|
}
|
||||||
|
|
||||||
Viewport *Example::return_something_const() const {
|
Viewport *Example::return_something_const() const {
|
||||||
|
UtilityFunctions::print(" Return something const called.");
|
||||||
if (is_inside_tree()) {
|
if (is_inside_tree()) {
|
||||||
Viewport *result = get_viewport();
|
Viewport *result = get_viewport();
|
||||||
return result;
|
return result;
|
||||||
@@ -335,23 +221,32 @@ ExampleRef *Example::return_extended_ref() const {
|
|||||||
return memnew(ExampleRef());
|
return memnew(ExampleRef());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Example *Example::test_node_argument(Example *p_node) const {
|
||||||
|
UtilityFunctions::print(" Test node argument called with ", p_node ? String::num(p_node->get_instance_id()) : "null");
|
||||||
|
return p_node;
|
||||||
|
}
|
||||||
|
|
||||||
Ref<ExampleRef> Example::extended_ref_checks(Ref<ExampleRef> p_ref) const {
|
Ref<ExampleRef> Example::extended_ref_checks(Ref<ExampleRef> p_ref) const {
|
||||||
// This is therefor the prefered way of instancing and returning a refcounted object:
|
// This is therefor the prefered way of instancing and returning a refcounted object:
|
||||||
Ref<ExampleRef> ref;
|
Ref<ExampleRef> ref;
|
||||||
ref.instantiate();
|
ref.instantiate();
|
||||||
|
|
||||||
|
UtilityFunctions::print(" Example ref checks called with value: ", p_ref->get_instance_id(), ", returning value: ", ref->get_instance_id());
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant Example::varargs_func(const Variant **args, GDExtensionInt arg_count, GDExtensionCallError &error) {
|
Variant Example::varargs_func(const Variant **args, GDExtensionInt arg_count, GDExtensionCallError &error) {
|
||||||
|
UtilityFunctions::print(" Varargs (Variant return) called with ", String::num((double)arg_count), " arguments");
|
||||||
return arg_count;
|
return arg_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Example::varargs_func_nv(const Variant **args, GDExtensionInt arg_count, GDExtensionCallError &error) {
|
int Example::varargs_func_nv(const Variant **args, GDExtensionInt arg_count, GDExtensionCallError &error) {
|
||||||
return 42 + arg_count;
|
UtilityFunctions::print(" Varargs (int return) called with ", String::num((double)arg_count), " arguments");
|
||||||
|
return 42;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Example::varargs_func_void(const Variant **args, GDExtensionInt arg_count, GDExtensionCallError &error) {
|
void Example::varargs_func_void(const Variant **args, GDExtensionInt arg_count, GDExtensionCallError &error) {
|
||||||
emit_custom_signal("varargs_func_void", arg_count + 1);
|
UtilityFunctions::print(" Varargs (no return) called with ", String::num((double)arg_count), " arguments");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Example::emit_custom_signal(const String &name, int value) {
|
void Example::emit_custom_signal(const String &name, int value) {
|
||||||
@@ -377,24 +272,6 @@ String Example::test_string_ops() const {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
String Example::test_str_utility() const {
|
|
||||||
return UtilityFunctions::str("Hello, ", "World", "! The answer is ", 42);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Example::test_string_is_fourty_two(const String &p_string) const {
|
|
||||||
return strcmp(p_string.utf8().ptr(), "fourty two") == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
String Example::test_string_resize(String p_string) const {
|
|
||||||
int orig_len = p_string.length();
|
|
||||||
p_string.resize(orig_len + 3);
|
|
||||||
char32_t *data = p_string.ptrw();
|
|
||||||
data[orig_len + 0] = '!';
|
|
||||||
data[orig_len + 1] = '?';
|
|
||||||
data[orig_len + 2] = '\0';
|
|
||||||
return p_string;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Example::test_vector_ops() const {
|
int Example::test_vector_ops() const {
|
||||||
PackedInt32Array arr;
|
PackedInt32Array arr;
|
||||||
arr.push_back(10);
|
arr.push_back(10);
|
||||||
@@ -408,74 +285,10 @@ int Example::test_vector_ops() const {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
Callable Example::test_callable_mp() {
|
void Example::test_tarray_arg(const TypedArray<int64_t> &p_array) {
|
||||||
return callable_mp(this, &Example::unbound_method1);
|
|
||||||
}
|
|
||||||
|
|
||||||
Callable Example::test_callable_mp_ret() {
|
|
||||||
return callable_mp(this, &Example::unbound_method2);
|
|
||||||
}
|
|
||||||
|
|
||||||
Callable Example::test_callable_mp_retc() const {
|
|
||||||
return callable_mp(this, &Example::unbound_method3);
|
|
||||||
}
|
|
||||||
|
|
||||||
Callable Example::test_callable_mp_static() const {
|
|
||||||
return callable_mp_static(&Example::unbound_static_method1);
|
|
||||||
}
|
|
||||||
|
|
||||||
Callable Example::test_callable_mp_static_ret() const {
|
|
||||||
return callable_mp_static(&Example::unbound_static_method2);
|
|
||||||
}
|
|
||||||
|
|
||||||
Callable Example::test_custom_callable() const {
|
|
||||||
return Callable(memnew(MyCallableCustom));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Example::unbound_method1(Object *p_object, String p_string, int p_int) {
|
|
||||||
String test = "unbound_method1: ";
|
|
||||||
test += p_object->get_class();
|
|
||||||
test += " - " + p_string;
|
|
||||||
emit_custom_signal(test, p_int);
|
|
||||||
}
|
|
||||||
|
|
||||||
String Example::unbound_method2(Object *p_object, String p_string, int p_int) {
|
|
||||||
String test = "unbound_method2: ";
|
|
||||||
test += p_object->get_class();
|
|
||||||
test += " - " + p_string;
|
|
||||||
test += " - " + itos(p_int);
|
|
||||||
return test;
|
|
||||||
}
|
|
||||||
|
|
||||||
String Example::unbound_method3(Object *p_object, String p_string, int p_int) const {
|
|
||||||
String test = "unbound_method3: ";
|
|
||||||
test += p_object->get_class();
|
|
||||||
test += " - " + p_string;
|
|
||||||
test += " - " + itos(p_int);
|
|
||||||
return test;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Example::unbound_static_method1(Example *p_object, String p_string, int p_int) {
|
|
||||||
String test = "unbound_static_method1: ";
|
|
||||||
test += p_object->get_class();
|
|
||||||
test += " - " + p_string;
|
|
||||||
p_object->emit_custom_signal(test, p_int);
|
|
||||||
}
|
|
||||||
|
|
||||||
String Example::unbound_static_method2(Object *p_object, String p_string, int p_int) {
|
|
||||||
String test = "unbound_static_method2: ";
|
|
||||||
test += p_object->get_class();
|
|
||||||
test += " - " + p_string;
|
|
||||||
test += " - " + itos(p_int);
|
|
||||||
return test;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Example::test_tarray_arg(const TypedArray<int64_t> &p_array) {
|
|
||||||
int sum = 0;
|
|
||||||
for (int i = 0; i < p_array.size(); i++) {
|
for (int i = 0; i < p_array.size(); i++) {
|
||||||
sum += (int)p_array[i];
|
UtilityFunctions::print(p_array[i]);
|
||||||
}
|
}
|
||||||
return sum;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TypedArray<Vector2> Example::test_tarray() const {
|
TypedArray<Vector2> Example::test_tarray() const {
|
||||||
@@ -497,102 +310,11 @@ Dictionary Example::test_dictionary() const {
|
|||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
Example *Example::test_node_argument(Example *p_node) const {
|
|
||||||
return p_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Example::test_object_cast_to_node(Object *p_object) const {
|
|
||||||
return Object::cast_to<Node>(p_object) != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Example::test_object_cast_to_control(Object *p_object) const {
|
|
||||||
return Object::cast_to<Control>(p_object) != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Example::test_object_cast_to_example(Object *p_object) const {
|
|
||||||
return Object::cast_to<Example>(p_object) != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2i Example::test_variant_vector2i_conversion(const Variant &p_variant) const {
|
|
||||||
return p_variant;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Example::test_variant_int_conversion(const Variant &p_variant) const {
|
|
||||||
return p_variant;
|
|
||||||
}
|
|
||||||
|
|
||||||
float Example::test_variant_float_conversion(const Variant &p_variant) const {
|
|
||||||
return p_variant;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Example::test_add_child(Node *p_node) {
|
|
||||||
add_child(p_node);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Example::test_set_tileset(TileMap *p_tilemap, const Ref<TileSet> &p_tileset) const {
|
|
||||||
p_tilemap->set_tileset(p_tileset);
|
|
||||||
}
|
|
||||||
|
|
||||||
Variant Example::test_variant_call(Variant p_variant) {
|
|
||||||
return p_variant.call("test", "hello");
|
|
||||||
}
|
|
||||||
|
|
||||||
BitField<Example::Flags> Example::test_bitfield(BitField<Flags> flags) {
|
BitField<Example::Flags> Example::test_bitfield(BitField<Flags> flags) {
|
||||||
|
UtilityFunctions::print(" Got BitField: ", String::num_int64(flags));
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant Example::test_variant_iterator(const Variant &p_input) {
|
|
||||||
Array output;
|
|
||||||
|
|
||||||
Variant iter;
|
|
||||||
|
|
||||||
bool is_init_valid = true;
|
|
||||||
if (!p_input.iter_init(iter, is_init_valid)) {
|
|
||||||
if (!is_init_valid) {
|
|
||||||
return "iter_init: not valid";
|
|
||||||
}
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_iter_next_valid = true;
|
|
||||||
bool is_iter_get_valid = true;
|
|
||||||
do {
|
|
||||||
if (!is_iter_next_valid) {
|
|
||||||
return "iter_next: not valid";
|
|
||||||
}
|
|
||||||
|
|
||||||
Variant value = p_input.iter_get(iter, is_iter_get_valid);
|
|
||||||
if (!is_iter_get_valid) {
|
|
||||||
return "iter_get: not valid";
|
|
||||||
}
|
|
||||||
output.push_back(((int)value) + 5);
|
|
||||||
|
|
||||||
} while (p_input.iter_next(iter, is_iter_next_valid));
|
|
||||||
|
|
||||||
if (!is_iter_next_valid) {
|
|
||||||
return "iter_next: not valid";
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Example::test_rpc(int p_value) {
|
|
||||||
last_rpc_arg = p_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Example::test_send_rpc(int p_value) {
|
|
||||||
rpc("test_rpc", p_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Example::return_last_rpc_arg() {
|
|
||||||
return last_rpc_arg;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Example::callable_bind() {
|
|
||||||
Callable c = Callable(this, "emit_custom_signal").bind("bound", 11);
|
|
||||||
c.call();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Properties.
|
// Properties.
|
||||||
void Example::set_custom_position(const Vector2 &pos) {
|
void Example::set_custom_position(const Vector2 &pos) {
|
||||||
custom_position = pos;
|
custom_position = pos;
|
||||||
@@ -606,12 +328,6 @@ Vector4 Example::get_v4() const {
|
|||||||
return Vector4(1.2, 3.4, 5.6, 7.8);
|
return Vector4(1.2, 3.4, 5.6, 7.8);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Example::test_post_initialize() const {
|
|
||||||
Ref<ExampleRef> new_example_ref;
|
|
||||||
new_example_ref.instantiate();
|
|
||||||
return new_example_ref->was_post_initialized();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Virtual function override.
|
// Virtual function override.
|
||||||
bool Example::_has_point(const Vector2 &point) const {
|
bool Example::_has_point(const Vector2 &point) const {
|
||||||
Label *label = get_node<Label>("Label");
|
Label *label = get_node<Label>("Label");
|
||||||
@@ -619,10 +335,3 @@ bool Example::_has_point(const Vector2 &point) const {
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Example::_input(const Ref<InputEvent> &event) {
|
|
||||||
const InputEventKey *key_event = Object::cast_to<const InputEventKey>(*event);
|
|
||||||
if (key_event) {
|
|
||||||
emit_custom_signal(String("_input: ") + key_event->get_key_label(), key_event->get_unicode());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -16,12 +16,7 @@
|
|||||||
|
|
||||||
#include <godot_cpp/classes/control.hpp>
|
#include <godot_cpp/classes/control.hpp>
|
||||||
#include <godot_cpp/classes/global_constants.hpp>
|
#include <godot_cpp/classes/global_constants.hpp>
|
||||||
#include <godot_cpp/classes/image.hpp>
|
|
||||||
#include <godot_cpp/classes/input_event_key.hpp>
|
|
||||||
#include <godot_cpp/classes/tile_map.hpp>
|
|
||||||
#include <godot_cpp/classes/tile_set.hpp>
|
|
||||||
#include <godot_cpp/classes/viewport.hpp>
|
#include <godot_cpp/classes/viewport.hpp>
|
||||||
#include <godot_cpp/variant/variant.hpp>
|
|
||||||
|
|
||||||
#include <godot_cpp/core/binder_common.hpp>
|
#include <godot_cpp/core/binder_common.hpp>
|
||||||
|
|
||||||
@@ -35,21 +30,15 @@ private:
|
|||||||
static int last_id;
|
static int last_id;
|
||||||
|
|
||||||
int id;
|
int id;
|
||||||
bool post_initialized = false;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
void _notification(int p_what);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ExampleRef();
|
ExampleRef();
|
||||||
~ExampleRef();
|
~ExampleRef();
|
||||||
|
|
||||||
void set_id(int p_id);
|
|
||||||
int get_id() const;
|
int get_id() const;
|
||||||
|
|
||||||
bool was_post_initialized() const { return post_initialized; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ExampleMin : public Control {
|
class ExampleMin : public Control {
|
||||||
@@ -71,7 +60,6 @@ protected:
|
|||||||
void _get_property_list(List<PropertyInfo> *p_list) const;
|
void _get_property_list(List<PropertyInfo> *p_list) const;
|
||||||
bool _property_can_revert(const StringName &p_name) const;
|
bool _property_can_revert(const StringName &p_name) const;
|
||||||
bool _property_get_revert(const StringName &p_name, Variant &r_property) const;
|
bool _property_get_revert(const StringName &p_name, Variant &r_property) const;
|
||||||
void _validate_property(PropertyInfo &p_property) const;
|
|
||||||
|
|
||||||
String _to_string() const;
|
String _to_string() const;
|
||||||
|
|
||||||
@@ -79,7 +67,6 @@ private:
|
|||||||
Vector2 custom_position;
|
Vector2 custom_position;
|
||||||
Vector3 property_from_list;
|
Vector3 property_from_list;
|
||||||
Vector2 dprop[3];
|
Vector2 dprop[3];
|
||||||
int last_rpc_arg = 0;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Constants.
|
// Constants.
|
||||||
@@ -103,13 +90,8 @@ public:
|
|||||||
// Functions.
|
// Functions.
|
||||||
void simple_func();
|
void simple_func();
|
||||||
void simple_const_func() const;
|
void simple_const_func() const;
|
||||||
int custom_ref_func(Ref<ExampleRef> p_ref);
|
|
||||||
int custom_const_ref_func(const Ref<ExampleRef> &p_ref);
|
|
||||||
String image_ref_func(Ref<Image> p_image);
|
|
||||||
String image_const_ref_func(const Ref<Image> &p_image);
|
|
||||||
String return_something(const String &base);
|
String return_something(const String &base);
|
||||||
Viewport *return_something_const() const;
|
Viewport *return_something_const() const;
|
||||||
Ref<ExampleRef> return_ref() const;
|
|
||||||
Ref<ExampleRef> return_empty_ref() const;
|
Ref<ExampleRef> return_empty_ref() const;
|
||||||
ExampleRef *return_extended_ref() const;
|
ExampleRef *return_extended_ref() const;
|
||||||
Ref<ExampleRef> extended_ref_checks(Ref<ExampleRef> p_ref) const;
|
Ref<ExampleRef> extended_ref_checks(Ref<ExampleRef> p_ref) const;
|
||||||
@@ -120,67 +102,26 @@ public:
|
|||||||
int def_args(int p_a = 100, int p_b = 200);
|
int def_args(int p_a = 100, int p_b = 200);
|
||||||
|
|
||||||
Array test_array() const;
|
Array test_array() const;
|
||||||
int test_tarray_arg(const TypedArray<int64_t> &p_array);
|
void test_tarray_arg(const TypedArray<int64_t> &p_array);
|
||||||
TypedArray<Vector2> test_tarray() const;
|
TypedArray<Vector2> test_tarray() const;
|
||||||
Dictionary test_dictionary() const;
|
Dictionary test_dictionary() const;
|
||||||
Example *test_node_argument(Example *p_node) const;
|
Example *test_node_argument(Example *p_node) const;
|
||||||
String test_string_ops() const;
|
String test_string_ops() const;
|
||||||
String test_str_utility() const;
|
|
||||||
bool test_string_is_fourty_two(const String &p_str) const;
|
|
||||||
String test_string_resize(String p_original) const;
|
|
||||||
int test_vector_ops() const;
|
int test_vector_ops() const;
|
||||||
|
|
||||||
bool test_object_cast_to_node(Object *p_object) const;
|
|
||||||
bool test_object_cast_to_control(Object *p_object) const;
|
|
||||||
bool test_object_cast_to_example(Object *p_object) const;
|
|
||||||
|
|
||||||
Vector2i test_variant_vector2i_conversion(const Variant &p_variant) const;
|
|
||||||
int test_variant_int_conversion(const Variant &p_variant) const;
|
|
||||||
float test_variant_float_conversion(const Variant &p_variant) const;
|
|
||||||
|
|
||||||
void test_add_child(Node *p_node);
|
|
||||||
void test_set_tileset(TileMap *p_tilemap, const Ref<TileSet> &p_tileset) const;
|
|
||||||
|
|
||||||
Variant test_variant_call(Variant p_variant);
|
|
||||||
|
|
||||||
Callable test_callable_mp();
|
|
||||||
Callable test_callable_mp_ret();
|
|
||||||
Callable test_callable_mp_retc() const;
|
|
||||||
Callable test_callable_mp_static() const;
|
|
||||||
Callable test_callable_mp_static_ret() const;
|
|
||||||
Callable test_custom_callable() const;
|
|
||||||
|
|
||||||
void unbound_method1(Object *p_object, String p_string, int p_int);
|
|
||||||
String unbound_method2(Object *p_object, String p_string, int p_int);
|
|
||||||
String unbound_method3(Object *p_object, String p_string, int p_int) const;
|
|
||||||
static void unbound_static_method1(Example *p_object, String p_string, int p_int);
|
|
||||||
static String unbound_static_method2(Object *p_object, String p_string, int p_int);
|
|
||||||
|
|
||||||
BitField<Flags> test_bitfield(BitField<Flags> flags);
|
BitField<Flags> test_bitfield(BitField<Flags> flags);
|
||||||
|
|
||||||
Variant test_variant_iterator(const Variant &p_input);
|
|
||||||
|
|
||||||
// RPC
|
|
||||||
void test_rpc(int p_value);
|
|
||||||
void test_send_rpc(int p_value);
|
|
||||||
int return_last_rpc_arg();
|
|
||||||
|
|
||||||
void callable_bind();
|
|
||||||
|
|
||||||
// Property.
|
// Property.
|
||||||
void set_custom_position(const Vector2 &pos);
|
void set_custom_position(const Vector2 &pos);
|
||||||
Vector2 get_custom_position() const;
|
Vector2 get_custom_position() const;
|
||||||
Vector4 get_v4() const;
|
Vector4 get_v4() const;
|
||||||
|
|
||||||
bool test_post_initialize() const;
|
|
||||||
|
|
||||||
// Static method.
|
// Static method.
|
||||||
static int test_static(int p_a, int p_b);
|
static int test_static(int p_a, int p_b);
|
||||||
static void test_static2();
|
static void test_static2();
|
||||||
|
|
||||||
// Virtual function override (no need to bind manually).
|
// Virtual function override (no need to bind manually).
|
||||||
virtual bool _has_point(const Vector2 &point) const override;
|
virtual bool _has_point(const Vector2 &point) const override;
|
||||||
virtual void _input(const Ref<InputEvent> &event) override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
VARIANT_ENUM_CAST(Example::Constants);
|
VARIANT_ENUM_CAST(Example::Constants);
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ void uninitialize_example_module(ModuleInitializationLevel p_level) {
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
// Initialization.
|
// Initialization.
|
||||||
GDExtensionBool GDE_EXPORT example_library_init(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) {
|
GDExtensionBool GDE_EXPORT example_library_init(const GDExtensionInterface *p_interface, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) {
|
||||||
godot::GDExtensionBinding::InitObject init_obj(p_get_proc_address, p_library, r_initialization);
|
godot::GDExtensionBinding::InitObject init_obj(p_interface, p_library, r_initialization);
|
||||||
|
|
||||||
init_obj.register_initializer(initialize_example_module);
|
init_obj.register_initializer(initialize_example_module);
|
||||||
init_obj.register_terminator(uninitialize_example_module);
|
init_obj.register_terminator(uninitialize_example_module);
|
||||||
|
|||||||
@@ -8,51 +8,41 @@ def options(opts):
|
|||||||
opts.Add(
|
opts.Add(
|
||||||
"android_api_level",
|
"android_api_level",
|
||||||
"Target Android API level",
|
"Target Android API level",
|
||||||
"21",
|
"18" if "32" in ARGUMENTS.get("arch", "arm64") else "21",
|
||||||
)
|
)
|
||||||
opts.Add(
|
opts.Add(
|
||||||
"ANDROID_HOME",
|
"ANDROID_NDK_ROOT",
|
||||||
"Path to your Android SDK installation. By default, uses ANDROID_HOME from your defined environment variables.",
|
"Path to your Android NDK installation. By default, uses ANDROID_NDK_ROOT from your defined environment variables.",
|
||||||
os.environ.get("ANDROID_HOME", os.environ.get("ANDROID_SDK_ROOT")),
|
os.environ.get("ANDROID_NDK_ROOT", None),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def exists(env):
|
def exists(env):
|
||||||
return get_android_ndk_root(env) is not None
|
return "ANDROID_NDK_ROOT" in os.environ or "ANDROID_NDK_ROOT" in ARGUMENTS
|
||||||
|
|
||||||
|
|
||||||
# This must be kept in sync with the value in https://github.com/godotengine/godot/blob/master/platform/android/detect.py#L58.
|
|
||||||
def get_ndk_version():
|
|
||||||
return "23.2.8568313"
|
|
||||||
|
|
||||||
|
|
||||||
def get_android_ndk_root(env):
|
|
||||||
if env["ANDROID_HOME"]:
|
|
||||||
return env["ANDROID_HOME"] + "/ndk/" + get_ndk_version()
|
|
||||||
else:
|
|
||||||
return os.environ.get("ANDROID_NDK_ROOT")
|
|
||||||
|
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
if get_android_ndk_root(env) is None:
|
if "ANDROID_NDK_ROOT" not in env:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"To build for Android, the path to the NDK must be defined. Please set ANDROID_HOME to the root folder of your Android SDK installation."
|
"To build for Android, ANDROID_NDK_ROOT must be defined. Please set ANDROID_NDK_ROOT to the root folder of your Android NDK installation."
|
||||||
)
|
)
|
||||||
|
|
||||||
if env["arch"] not in ("arm64", "x86_64", "arm32", "x86_32"):
|
if env["arch"] not in ("arm64", "x86_64", "arm32", "x86_32"):
|
||||||
print("Only arm64, x86_64, arm32, and x86_32 are supported on Android. Exiting.")
|
print("Only arm64, x86_64, arm32, and x86_32 are supported on Android. Exiting.")
|
||||||
env.Exit(1)
|
Exit()
|
||||||
|
|
||||||
if sys.platform == "win32" or sys.platform == "msys":
|
if sys.platform == "win32" or sys.platform == "msys":
|
||||||
my_spawn.configure(env)
|
my_spawn.configure(env)
|
||||||
|
|
||||||
# Validate API level
|
# Validate API level
|
||||||
if int(env["android_api_level"]) < 21:
|
api_level = int(env["android_api_level"])
|
||||||
print("WARNING: minimum supported Android target api is 21. Forcing target api 21.")
|
if "64" in env["arch"] and api_level < 21:
|
||||||
|
print("WARN: 64-bit Android architectures require an API level of at least 21; setting android_api_level=21")
|
||||||
env["android_api_level"] = "21"
|
env["android_api_level"] = "21"
|
||||||
|
api_level = 21
|
||||||
|
|
||||||
# Setup toolchain
|
# Setup toolchain
|
||||||
toolchain = get_android_ndk_root(env) + "/toolchains/llvm/prebuilt/"
|
toolchain = env["ANDROID_NDK_ROOT"] + "/toolchains/llvm/prebuilt/"
|
||||||
if sys.platform == "win32" or sys.platform == "msys":
|
if sys.platform == "win32" or sys.platform == "msys":
|
||||||
toolchain += "windows"
|
toolchain += "windows"
|
||||||
import platform as pltfm
|
import platform as pltfm
|
||||||
@@ -110,5 +100,3 @@ def generate(env):
|
|||||||
)
|
)
|
||||||
env.Append(CCFLAGS=arch_info["ccflags"])
|
env.Append(CCFLAGS=arch_info["ccflags"])
|
||||||
env.Append(LINKFLAGS=["--target=" + arch_info["target"] + env["android_api_level"], "-march=" + arch_info["march"]])
|
env.Append(LINKFLAGS=["--target=" + arch_info["target"] + env["android_api_level"], "-march=" + arch_info["march"]])
|
||||||
|
|
||||||
env.Append(CPPDEFINES=["ANDROID_ENABLED", "UNIX_ENABLED"])
|
|
||||||
|
|||||||
@@ -1,361 +0,0 @@
|
|||||||
import os, sys, platform
|
|
||||||
|
|
||||||
from SCons.Variables import EnumVariable, PathVariable, BoolVariable
|
|
||||||
from SCons.Tool import Tool
|
|
||||||
from SCons.Builder import Builder
|
|
||||||
from SCons.Errors import UserError
|
|
||||||
|
|
||||||
from binding_generator import scons_generate_bindings, scons_emit_files
|
|
||||||
|
|
||||||
|
|
||||||
def add_sources(sources, dir, extension):
|
|
||||||
for f in os.listdir(dir):
|
|
||||||
if f.endswith("." + extension):
|
|
||||||
sources.append(dir + "/" + f)
|
|
||||||
|
|
||||||
|
|
||||||
def normalize_path(val, env):
|
|
||||||
return val if os.path.isabs(val) else os.path.join(env.Dir("#").abspath, val)
|
|
||||||
|
|
||||||
|
|
||||||
def validate_file(key, val, env):
|
|
||||||
if not os.path.isfile(normalize_path(val, env)):
|
|
||||||
raise UserError("'%s' is not a file: %s" % (key, val))
|
|
||||||
|
|
||||||
|
|
||||||
def validate_dir(key, val, env):
|
|
||||||
if not os.path.isdir(normalize_path(val, env)):
|
|
||||||
raise UserError("'%s' is not a directory: %s" % (key, val))
|
|
||||||
|
|
||||||
|
|
||||||
def validate_parent_dir(key, val, env):
|
|
||||||
if not os.path.isdir(normalize_path(os.path.dirname(val), env)):
|
|
||||||
raise UserError("'%s' is not a directory: %s" % (key, os.path.dirname(val)))
|
|
||||||
|
|
||||||
|
|
||||||
platforms = ("linux", "macos", "windows", "android", "ios", "web")
|
|
||||||
|
|
||||||
# CPU architecture options.
|
|
||||||
architecture_array = [
|
|
||||||
"",
|
|
||||||
"universal",
|
|
||||||
"x86_32",
|
|
||||||
"x86_64",
|
|
||||||
"arm32",
|
|
||||||
"arm64",
|
|
||||||
"rv64",
|
|
||||||
"ppc32",
|
|
||||||
"ppc64",
|
|
||||||
"wasm32",
|
|
||||||
]
|
|
||||||
architecture_aliases = {
|
|
||||||
"x64": "x86_64",
|
|
||||||
"amd64": "x86_64",
|
|
||||||
"armv7": "arm32",
|
|
||||||
"armv8": "arm64",
|
|
||||||
"arm64v8": "arm64",
|
|
||||||
"aarch64": "arm64",
|
|
||||||
"rv": "rv64",
|
|
||||||
"riscv": "rv64",
|
|
||||||
"riscv64": "rv64",
|
|
||||||
"ppcle": "ppc32",
|
|
||||||
"ppc": "ppc32",
|
|
||||||
"ppc64le": "ppc64",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def exists(env):
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def options(opts, env):
|
|
||||||
# Try to detect the host platform automatically.
|
|
||||||
# This is used if no `platform` argument is passed
|
|
||||||
if sys.platform.startswith("linux"):
|
|
||||||
default_platform = "linux"
|
|
||||||
elif sys.platform == "darwin":
|
|
||||||
default_platform = "macos"
|
|
||||||
elif sys.platform == "win32" or sys.platform == "msys":
|
|
||||||
default_platform = "windows"
|
|
||||||
elif ARGUMENTS.get("platform", ""):
|
|
||||||
default_platform = ARGUMENTS.get("platform")
|
|
||||||
else:
|
|
||||||
raise ValueError("Could not detect platform automatically, please specify with platform=<platform>")
|
|
||||||
|
|
||||||
opts.Add(
|
|
||||||
EnumVariable(
|
|
||||||
key="platform",
|
|
||||||
help="Target platform",
|
|
||||||
default=env.get("platform", default_platform),
|
|
||||||
allowed_values=platforms,
|
|
||||||
ignorecase=2,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
# Editor and template_debug are compatible (i.e. you can use the same binary for Godot editor builds and Godot debug templates).
|
|
||||||
# Godot release templates are only compatible with "template_release" builds.
|
|
||||||
# For this reason, we default to template_debug builds, unlike Godot which defaults to editor builds.
|
|
||||||
opts.Add(
|
|
||||||
EnumVariable(
|
|
||||||
key="target",
|
|
||||||
help="Compilation target",
|
|
||||||
default=env.get("target", "template_debug"),
|
|
||||||
allowed_values=("editor", "template_release", "template_debug"),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
opts.Add(
|
|
||||||
PathVariable(
|
|
||||||
key="gdextension_dir",
|
|
||||||
help="Path to a custom directory containing GDExtension interface header and API JSON file",
|
|
||||||
default=env.get("gdextension_dir", None),
|
|
||||||
validator=validate_dir,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
opts.Add(
|
|
||||||
PathVariable(
|
|
||||||
key="custom_api_file",
|
|
||||||
help="Path to a custom GDExtension API JSON file (takes precedence over `gdextension_dir`)",
|
|
||||||
default=env.get("custom_api_file", None),
|
|
||||||
validator=validate_file,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
opts.Add(
|
|
||||||
BoolVariable(
|
|
||||||
key="generate_bindings",
|
|
||||||
help="Force GDExtension API bindings generation. Auto-detected by default.",
|
|
||||||
default=env.get("generate_bindings", False),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
opts.Add(
|
|
||||||
BoolVariable(
|
|
||||||
key="generate_template_get_node",
|
|
||||||
help="Generate a template version of the Node class's get_node.",
|
|
||||||
default=env.get("generate_template_get_node", True),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
opts.Add(
|
|
||||||
BoolVariable(
|
|
||||||
key="build_library",
|
|
||||||
help="Build the godot-cpp library.",
|
|
||||||
default=env.get("build_library", True),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
opts.Add(
|
|
||||||
EnumVariable(
|
|
||||||
key="precision",
|
|
||||||
help="Set the floating-point precision level",
|
|
||||||
default=env.get("precision", "single"),
|
|
||||||
allowed_values=("single", "double"),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
opts.Add(
|
|
||||||
EnumVariable(
|
|
||||||
key="arch",
|
|
||||||
help="CPU architecture",
|
|
||||||
default=env.get("arch", ""),
|
|
||||||
allowed_values=architecture_array,
|
|
||||||
map=architecture_aliases,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
# compiledb
|
|
||||||
opts.Add(
|
|
||||||
BoolVariable(
|
|
||||||
key="compiledb",
|
|
||||||
help="Generate compilation DB (`compile_commands.json`) for external tools",
|
|
||||||
default=env.get("compiledb", False),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
opts.Add(
|
|
||||||
PathVariable(
|
|
||||||
key="compiledb_file",
|
|
||||||
help="Path to a custom `compile_commands.json` file",
|
|
||||||
default=env.get("compiledb_file", "compile_commands.json"),
|
|
||||||
validator=validate_parent_dir,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
opts.Add(
|
|
||||||
BoolVariable(
|
|
||||||
key="use_hot_reload",
|
|
||||||
help="Enable the extra accounting required to support hot reload.",
|
|
||||||
default=env.get("use_hot_reload", None),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
opts.Add(
|
|
||||||
BoolVariable(
|
|
||||||
"disable_exceptions", "Force disabling exception handling code", default=env.get("disable_exceptions", True)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
opts.Add(
|
|
||||||
EnumVariable(
|
|
||||||
key="symbols_visibility",
|
|
||||||
help="Symbols visibility on GNU platforms. Use 'auto' to apply the default value.",
|
|
||||||
default=env.get("symbols_visibility", "hidden"),
|
|
||||||
allowed_values=["auto", "visible", "hidden"],
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
# Add platform options
|
|
||||||
for pl in platforms:
|
|
||||||
tool = Tool(pl, toolpath=["tools"])
|
|
||||||
if hasattr(tool, "options"):
|
|
||||||
tool.options(opts)
|
|
||||||
|
|
||||||
# Targets flags tool (optimizations, debug symbols)
|
|
||||||
target_tool = Tool("targets", toolpath=["tools"])
|
|
||||||
target_tool.options(opts)
|
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
# by SetOption, so we can rely on this to know if we should use our default.
|
|
||||||
initial_num_jobs = env.GetOption("num_jobs")
|
|
||||||
altered_num_jobs = initial_num_jobs + 1
|
|
||||||
env.SetOption("num_jobs", altered_num_jobs)
|
|
||||||
if env.GetOption("num_jobs") == altered_num_jobs:
|
|
||||||
cpu_count = os.cpu_count()
|
|
||||||
if cpu_count is None:
|
|
||||||
print("Couldn't auto-detect CPU count to configure build parallelism. Specify it with the -j argument.")
|
|
||||||
else:
|
|
||||||
safer_cpu_count = cpu_count if cpu_count <= 4 else cpu_count - 1
|
|
||||||
print(
|
|
||||||
"Auto-detected %d CPU cores available for build parallelism. Using %d cores by default. You can override it with the -j argument."
|
|
||||||
% (cpu_count, safer_cpu_count)
|
|
||||||
)
|
|
||||||
env.SetOption("num_jobs", safer_cpu_count)
|
|
||||||
|
|
||||||
# Process CPU architecture argument.
|
|
||||||
if env["arch"] == "":
|
|
||||||
# No architecture specified. Default to arm64 if building for Android,
|
|
||||||
# universal if building for macOS or iOS, wasm32 if building for web,
|
|
||||||
# otherwise default to the host architecture.
|
|
||||||
if env["platform"] in ["macos", "ios"]:
|
|
||||||
env["arch"] = "universal"
|
|
||||||
elif env["platform"] == "android":
|
|
||||||
env["arch"] = "arm64"
|
|
||||||
elif env["platform"] == "web":
|
|
||||||
env["arch"] = "wasm32"
|
|
||||||
else:
|
|
||||||
host_machine = platform.machine().lower()
|
|
||||||
if host_machine in architecture_array:
|
|
||||||
env["arch"] = host_machine
|
|
||||||
elif host_machine in architecture_aliases.keys():
|
|
||||||
env["arch"] = architecture_aliases[host_machine]
|
|
||||||
elif "86" in host_machine:
|
|
||||||
# Catches x86, i386, i486, i586, i686, etc.
|
|
||||||
env["arch"] = "x86_32"
|
|
||||||
else:
|
|
||||||
print("Unsupported CPU architecture: " + host_machine)
|
|
||||||
env.Exit(1)
|
|
||||||
|
|
||||||
print("Building for architecture " + env["arch"] + " on platform " + env["platform"])
|
|
||||||
|
|
||||||
if env.get("use_hot_reload") is None:
|
|
||||||
env["use_hot_reload"] = env["target"] != "template_release"
|
|
||||||
if env["use_hot_reload"]:
|
|
||||||
env.Append(CPPDEFINES=["HOT_RELOAD_ENABLED"])
|
|
||||||
|
|
||||||
tool = Tool(env["platform"], toolpath=["tools"])
|
|
||||||
|
|
||||||
if tool is None or not tool.exists(env):
|
|
||||||
raise ValueError("Required toolchain not found for platform " + env["platform"])
|
|
||||||
|
|
||||||
tool.generate(env)
|
|
||||||
target_tool = Tool("targets", toolpath=["tools"])
|
|
||||||
target_tool.generate(env)
|
|
||||||
|
|
||||||
# Disable exception handling. Godot doesn't use exceptions anywhere, and this
|
|
||||||
# saves around 20% of binary size and very significant build time.
|
|
||||||
if env["disable_exceptions"]:
|
|
||||||
if env.get("is_msvc", False):
|
|
||||||
env.Append(CPPDEFINES=[("_HAS_EXCEPTIONS", 0)])
|
|
||||||
else:
|
|
||||||
env.Append(CXXFLAGS=["-fno-exceptions"])
|
|
||||||
elif env.get("is_msvc", False):
|
|
||||||
env.Append(CXXFLAGS=["/EHsc"])
|
|
||||||
|
|
||||||
if not env.get("is_msvc", False):
|
|
||||||
if env["symbols_visibility"] == "visible":
|
|
||||||
env.Append(CCFLAGS=["-fvisibility=default"])
|
|
||||||
env.Append(LINKFLAGS=["-fvisibility=default"])
|
|
||||||
elif env["symbols_visibility"] == "hidden":
|
|
||||||
env.Append(CCFLAGS=["-fvisibility=hidden"])
|
|
||||||
env.Append(LINKFLAGS=["-fvisibility=hidden"])
|
|
||||||
|
|
||||||
# Require C++17
|
|
||||||
if env.get("is_msvc", False):
|
|
||||||
env.Append(CXXFLAGS=["/std:c++17"])
|
|
||||||
else:
|
|
||||||
env.Append(CXXFLAGS=["-std=c++17"])
|
|
||||||
|
|
||||||
if env["precision"] == "double":
|
|
||||||
env.Append(CPPDEFINES=["REAL_T_IS_DOUBLE"])
|
|
||||||
|
|
||||||
# Suffix
|
|
||||||
suffix = ".{}.{}".format(env["platform"], env["target"])
|
|
||||||
if env.dev_build:
|
|
||||||
suffix += ".dev"
|
|
||||||
if env["precision"] == "double":
|
|
||||||
suffix += ".double"
|
|
||||||
suffix += "." + env["arch"]
|
|
||||||
if env["ios_simulator"]:
|
|
||||||
suffix += ".simulator"
|
|
||||||
|
|
||||||
env["suffix"] = suffix # Exposed when included from another project
|
|
||||||
env["OBJSUFFIX"] = suffix + env["OBJSUFFIX"]
|
|
||||||
|
|
||||||
# compile_commands.json
|
|
||||||
env.Tool("compilation_db")
|
|
||||||
env.Alias("compiledb", env.CompilationDatabase(normalize_path(env["compiledb_file"], env)))
|
|
||||||
|
|
||||||
# Builders
|
|
||||||
env.Append(BUILDERS={"GodotCPPBindings": Builder(action=scons_generate_bindings, emitter=scons_emit_files)})
|
|
||||||
env.AddMethod(_godot_cpp, "GodotCPP")
|
|
||||||
|
|
||||||
|
|
||||||
def _godot_cpp(env):
|
|
||||||
extension_dir = normalize_path(env.get("gdextension_dir", env.Dir("gdextension").abspath), env)
|
|
||||||
api_file = normalize_path(env.get("custom_api_file", env.File(extension_dir + "/extension_api.json").abspath), env)
|
|
||||||
bindings = env.GodotCPPBindings(
|
|
||||||
env.Dir("."),
|
|
||||||
[
|
|
||||||
api_file,
|
|
||||||
os.path.join(extension_dir, "gdextension_interface.h"),
|
|
||||||
"binding_generator.py",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
# Forces bindings regeneration.
|
|
||||||
if env["generate_bindings"]:
|
|
||||||
env.AlwaysBuild(bindings)
|
|
||||||
env.NoCache(bindings)
|
|
||||||
|
|
||||||
# Sources to compile
|
|
||||||
sources = []
|
|
||||||
add_sources(sources, "src", "cpp")
|
|
||||||
add_sources(sources, "src/classes", "cpp")
|
|
||||||
add_sources(sources, "src/core", "cpp")
|
|
||||||
add_sources(sources, "src/variant", "cpp")
|
|
||||||
sources.extend([f for f in bindings if str(f).endswith(".cpp")])
|
|
||||||
|
|
||||||
# Includes
|
|
||||||
env.AppendUnique(CPPPATH=[env.Dir(d) for d in [extension_dir, "include", "gen/include"]])
|
|
||||||
|
|
||||||
library = None
|
|
||||||
library_name = "libgodot-cpp" + env["suffix"] + env["LIBSUFFIX"]
|
|
||||||
|
|
||||||
if env["build_library"]:
|
|
||||||
library = env.StaticLibrary(target=env.File("bin/%s" % library_name), source=sources)
|
|
||||||
default_args = [library]
|
|
||||||
|
|
||||||
# Add compiledb if the option is set
|
|
||||||
if env.get("compiledb", False):
|
|
||||||
default_args += ["compiledb"]
|
|
||||||
|
|
||||||
env.Default(*default_args)
|
|
||||||
|
|
||||||
env.AppendUnique(LIBS=[env.File("bin/%s" % library_name)])
|
|
||||||
return library
|
|
||||||
39
tools/ios.py
39
tools/ios.py
@@ -1,6 +1,7 @@
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import ios_osxcross
|
||||||
from SCons.Variables import *
|
from SCons.Variables import *
|
||||||
|
|
||||||
if sys.version_info < (3,):
|
if sys.version_info < (3,):
|
||||||
@@ -15,31 +16,26 @@ else:
|
|||||||
return codecs.utf_8_decode(x)[0]
|
return codecs.utf_8_decode(x)[0]
|
||||||
|
|
||||||
|
|
||||||
def has_ios_osxcross():
|
|
||||||
return "OSXCROSS_IOS" in os.environ
|
|
||||||
|
|
||||||
|
|
||||||
def options(opts):
|
def options(opts):
|
||||||
opts.Add(BoolVariable("ios_simulator", "Target iOS Simulator", False))
|
opts.Add(BoolVariable("ios_simulator", "Target iOS Simulator", False))
|
||||||
opts.Add("ios_min_version", "Target minimum iphoneos/iphonesimulator version", "12.0")
|
opts.Add("ios_min_version", "Target minimum iphoneos/iphonesimulator version", "10.0")
|
||||||
opts.Add(
|
opts.Add(
|
||||||
"IOS_TOOLCHAIN_PATH",
|
"IOS_TOOLCHAIN_PATH",
|
||||||
"Path to iOS toolchain",
|
"Path to iOS toolchain",
|
||||||
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain",
|
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain",
|
||||||
)
|
)
|
||||||
opts.Add("IOS_SDK_PATH", "Path to the iOS SDK", "")
|
opts.Add("IOS_SDK_PATH", "Path to the iOS SDK", "")
|
||||||
|
ios_osxcross.options(opts)
|
||||||
if has_ios_osxcross():
|
|
||||||
opts.Add("ios_triple", "Triple for ios toolchain", "")
|
|
||||||
|
|
||||||
|
|
||||||
def exists(env):
|
def exists(env):
|
||||||
return sys.platform == "darwin" or has_ios_osxcross()
|
return sys.platform == "darwin" or ios_osxcross.exists(env)
|
||||||
|
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
if env["arch"] not in ("universal", "arm64", "x86_64"):
|
if env["arch"] not in ("universal", "arm64", "x86_64"):
|
||||||
raise ValueError("Only universal, arm64, and x86_64 are supported on iOS. Exiting.")
|
print("Only universal, arm64, and x86_64 are supported on iOS. Exiting.")
|
||||||
|
Exit()
|
||||||
|
|
||||||
if env["ios_simulator"]:
|
if env["ios_simulator"]:
|
||||||
sdk_name = "iphonesimulator"
|
sdk_name = "iphonesimulator"
|
||||||
@@ -68,26 +64,7 @@ def generate(env):
|
|||||||
env["ENV"]["PATH"] = env["IOS_TOOLCHAIN_PATH"] + "/Developer/usr/bin/:" + env["ENV"]["PATH"]
|
env["ENV"]["PATH"] = env["IOS_TOOLCHAIN_PATH"] + "/Developer/usr/bin/:" + env["ENV"]["PATH"]
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# OSXCross
|
ios_osxcross.generate(env)
|
||||||
compiler_path = "$IOS_TOOLCHAIN_PATH/usr/bin/${ios_triple}"
|
|
||||||
env["CC"] = compiler_path + "clang"
|
|
||||||
env["CXX"] = compiler_path + "clang++"
|
|
||||||
env["AR"] = compiler_path + "ar"
|
|
||||||
env["RANLIB"] = compiler_path + "ranlib"
|
|
||||||
env["SHLIBSUFFIX"] = ".dylib"
|
|
||||||
|
|
||||||
env.Prepend(
|
|
||||||
CPPPATH=[
|
|
||||||
"$IOS_SDK_PATH/usr/include",
|
|
||||||
"$IOS_SDK_PATH/System/Library/Frameworks/AudioUnit.framework/Headers",
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
env.Append(CCFLAGS=["-stdlib=libc++"])
|
|
||||||
|
|
||||||
binpath = os.path.join(env["IOS_TOOLCHAIN_PATH"], "usr", "bin")
|
|
||||||
if binpath not in env["ENV"]["PATH"]:
|
|
||||||
env.PrependENVPath("PATH", binpath)
|
|
||||||
|
|
||||||
if env["arch"] == "universal":
|
if env["arch"] == "universal":
|
||||||
if env["ios_simulator"]:
|
if env["ios_simulator"]:
|
||||||
@@ -102,5 +79,3 @@ def generate(env):
|
|||||||
|
|
||||||
env.Append(CCFLAGS=["-isysroot", env["IOS_SDK_PATH"]])
|
env.Append(CCFLAGS=["-isysroot", env["IOS_SDK_PATH"]])
|
||||||
env.Append(LINKFLAGS=["-isysroot", env["IOS_SDK_PATH"], "-F" + env["IOS_SDK_PATH"]])
|
env.Append(LINKFLAGS=["-isysroot", env["IOS_SDK_PATH"], "-F" + env["IOS_SDK_PATH"]])
|
||||||
|
|
||||||
env.Append(CPPDEFINES=["IOS_ENABLED", "UNIX_ENABLED"])
|
|
||||||
|
|||||||
26
tools/ios_osxcross.py
Normal file
26
tools/ios_osxcross.py
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
def options(opts):
|
||||||
|
opts.Add("ios_triple", "Triple for ios toolchain", "")
|
||||||
|
|
||||||
|
|
||||||
|
def exists(env):
|
||||||
|
return "OSXCROSS_IOS" in os.environ
|
||||||
|
|
||||||
|
|
||||||
|
def generate(env):
|
||||||
|
compiler_path = "$IOS_TOOLCHAIN_PATH/usr/bin/${ios_triple}"
|
||||||
|
env["CC"] = compiler_path + "clang"
|
||||||
|
env["CXX"] = compiler_path + "clang++"
|
||||||
|
env["AR"] = compiler_path + "ar"
|
||||||
|
env["RANLIB"] = compiler_path + "ranlib"
|
||||||
|
env["SHLIBSUFFIX"] = ".dylib"
|
||||||
|
|
||||||
|
env.Prepend(
|
||||||
|
CPPPATH=[
|
||||||
|
"$IOS_SDK_PATH/usr/include",
|
||||||
|
"$IOS_SDK_PATH/System/Library/Frameworks/AudioUnit.framework/Headers",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
env.Append(CCFLAGS=["-stdlib=libc++"])
|
||||||
@@ -1,44 +1,45 @@
|
|||||||
import os
|
import os
|
||||||
from SCons.Util import WhereIs
|
|
||||||
|
|
||||||
|
|
||||||
def exists(env):
|
def exists(env):
|
||||||
return WhereIs("emcc") is not None
|
return "EM_CONFIG" in os.environ
|
||||||
|
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
if env["arch"] not in ("wasm32"):
|
if env["arch"] not in ("wasm32"):
|
||||||
print("Only wasm32 supported on web. Exiting.")
|
print("Only wasm32 supported on web. Exiting.")
|
||||||
env.Exit(1)
|
Exit()
|
||||||
|
|
||||||
|
if "EM_CONFIG" in os.environ:
|
||||||
|
env["ENV"] = os.environ
|
||||||
|
|
||||||
# Emscripten toolchain
|
|
||||||
env["CC"] = "emcc"
|
env["CC"] = "emcc"
|
||||||
env["CXX"] = "em++"
|
env["CXX"] = "em++"
|
||||||
env["AR"] = "emar"
|
env["AR"] = "emar"
|
||||||
env["RANLIB"] = "emranlib"
|
env["RANLIB"] = "emranlib"
|
||||||
|
env.Append(CPPFLAGS=["-s", "SIDE_MODULE=1"])
|
||||||
|
env.Append(LINKFLAGS=["-s", "SIDE_MODULE=1"])
|
||||||
|
env["SHOBJSUFFIX"] = ".bc"
|
||||||
|
env["SHLIBSUFFIX"] = ".wasm"
|
||||||
# Use TempFileMunge since some AR invocations are too long for cmd.exe.
|
# Use TempFileMunge since some AR invocations are too long for cmd.exe.
|
||||||
# Use POSIX-style paths, required with TempFileMunge.
|
# Use POSIX-style paths, required with TempFileMunge.
|
||||||
env["ARCOM_POSIX"] = env["ARCOM"].replace("$TARGET", "$TARGET.posix").replace("$SOURCES", "$SOURCES.posix")
|
env["ARCOM_POSIX"] = env["ARCOM"].replace("$TARGET", "$TARGET.posix").replace("$SOURCES", "$SOURCES.posix")
|
||||||
env["ARCOM"] = "${TEMPFILE(ARCOM_POSIX)}"
|
env["ARCOM"] = "${TEMPFILE(ARCOM_POSIX)}"
|
||||||
|
|
||||||
# All intermediate files are just object files.
|
# All intermediate files are just LLVM bitcode.
|
||||||
env["OBJSUFFIX"] = ".o"
|
env["OBJPREFIX"] = ""
|
||||||
env["SHOBJSUFFIX"] = ".o"
|
env["OBJSUFFIX"] = ".bc"
|
||||||
|
env["PROGPREFIX"] = ""
|
||||||
# Static libraries clang-style.
|
# Program() output consists of multiple files, so specify suffixes manually at builder.
|
||||||
|
env["PROGSUFFIX"] = ""
|
||||||
env["LIBPREFIX"] = "lib"
|
env["LIBPREFIX"] = "lib"
|
||||||
env["LIBSUFFIX"] = ".a"
|
env["LIBSUFFIX"] = ".a"
|
||||||
|
env["LIBPREFIXES"] = ["$LIBPREFIX"]
|
||||||
|
env["LIBSUFFIXES"] = ["$LIBSUFFIX"]
|
||||||
|
env.Replace(SHLINKFLAGS="$LINKFLAGS")
|
||||||
|
env.Replace(SHLINKFLAGS="$LINKFLAGS")
|
||||||
|
|
||||||
# Shared library as wasm.
|
if env["target"] == "debug":
|
||||||
env["SHLIBSUFFIX"] = ".wasm"
|
env.Append(CCFLAGS=["-O0", "-g"])
|
||||||
|
elif env["target"] == "release":
|
||||||
# Thread support (via SharedArrayBuffer).
|
env.Append(CCFLAGS=["-O3"])
|
||||||
env.Append(CCFLAGS=["-s", "USE_PTHREADS=1"])
|
|
||||||
env.Append(LINKFLAGS=["-s", "USE_PTHREADS=1"])
|
|
||||||
|
|
||||||
# Build as side module (shared library).
|
|
||||||
env.Append(CPPFLAGS=["-s", "SIDE_MODULE=1"])
|
|
||||||
env.Append(LINKFLAGS=["-s", "SIDE_MODULE=1"])
|
|
||||||
|
|
||||||
env.Append(CPPDEFINES=["WEB_ENABLED", "UNIX_ENABLED"])
|
|
||||||
@@ -14,9 +14,6 @@ def generate(env):
|
|||||||
if env["use_llvm"]:
|
if env["use_llvm"]:
|
||||||
clang.generate(env)
|
clang.generate(env)
|
||||||
clangxx.generate(env)
|
clangxx.generate(env)
|
||||||
elif env["use_hot_reload"]:
|
|
||||||
# Required for extensions to truly unload.
|
|
||||||
env.Append(CXXFLAGS=["-fno-gnu-unique"])
|
|
||||||
|
|
||||||
env.Append(CCFLAGS=["-fPIC", "-Wwrite-strings"])
|
env.Append(CCFLAGS=["-fPIC", "-Wwrite-strings"])
|
||||||
env.Append(LINKFLAGS=["-Wl,-R,'$$ORIGIN'"])
|
env.Append(LINKFLAGS=["-Wl,-R,'$$ORIGIN'"])
|
||||||
@@ -35,5 +32,3 @@ def generate(env):
|
|||||||
elif env["arch"] == "rv64":
|
elif env["arch"] == "rv64":
|
||||||
env.Append(CCFLAGS=["-march=rv64gc"])
|
env.Append(CCFLAGS=["-march=rv64gc"])
|
||||||
env.Append(LINKFLAGS=["-march=rv64gc"])
|
env.Append(LINKFLAGS=["-march=rv64gc"])
|
||||||
|
|
||||||
env.Append(CPPDEFINES=["LINUX_ENABLED", "UNIX_ENABLED"])
|
|
||||||
|
|||||||
@@ -1,51 +1,31 @@
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import macos_osxcross
|
||||||
|
|
||||||
def has_osxcross():
|
|
||||||
return "OSXCROSS_ROOT" in os.environ
|
|
||||||
|
|
||||||
|
|
||||||
def options(opts):
|
def options(opts):
|
||||||
opts.Add("macos_deployment_target", "macOS deployment target", "default")
|
opts.Add("macos_deployment_target", "macOS deployment target", "default")
|
||||||
opts.Add("macos_sdk_path", "macOS SDK path", "")
|
opts.Add("macos_sdk_path", "macOS SDK path", "")
|
||||||
if has_osxcross():
|
macos_osxcross.options(opts)
|
||||||
opts.Add("osxcross_sdk", "OSXCross SDK version", "darwin16")
|
|
||||||
|
|
||||||
|
|
||||||
def exists(env):
|
def exists(env):
|
||||||
return sys.platform == "darwin" or has_osxcross()
|
return sys.platform == "darwin" or macos_osxcross.exists(env)
|
||||||
|
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
if env["arch"] not in ("universal", "arm64", "x86_64"):
|
if env["arch"] not in ("universal", "arm64", "x86_64"):
|
||||||
print("Only universal, arm64, and x86_64 are supported on macOS. Exiting.")
|
print("Only universal, arm64, and x86_64 are supported on macOS. Exiting.")
|
||||||
env.Exit(1)
|
Exit()
|
||||||
|
|
||||||
if sys.platform == "darwin":
|
if sys.platform == "darwin":
|
||||||
# Use clang on macOS by default
|
# Use clang on macOS by default
|
||||||
env["CXX"] = "clang++"
|
env["CXX"] = "clang++"
|
||||||
env["CC"] = "clang"
|
env["CC"] = "clang"
|
||||||
else:
|
else:
|
||||||
# OSXCross
|
# Use osxcross
|
||||||
root = os.environ.get("OSXCROSS_ROOT", "")
|
macos_osxcross.generate(env)
|
||||||
if env["arch"] == "arm64":
|
|
||||||
basecmd = root + "/target/bin/arm64-apple-" + env["osxcross_sdk"] + "-"
|
|
||||||
else:
|
|
||||||
basecmd = root + "/target/bin/x86_64-apple-" + env["osxcross_sdk"] + "-"
|
|
||||||
|
|
||||||
env["CC"] = basecmd + "clang"
|
|
||||||
env["CXX"] = basecmd + "clang++"
|
|
||||||
env["AR"] = basecmd + "ar"
|
|
||||||
env["RANLIB"] = basecmd + "ranlib"
|
|
||||||
env["AS"] = basecmd + "as"
|
|
||||||
|
|
||||||
binpath = os.path.join(root, "target", "bin")
|
|
||||||
if binpath not in env["ENV"]["PATH"]:
|
|
||||||
# Add OSXCROSS bin folder to PATH (required for linking).
|
|
||||||
env.PrependENVPath("PATH", binpath)
|
|
||||||
|
|
||||||
# Common flags
|
|
||||||
if env["arch"] == "universal":
|
if env["arch"] == "universal":
|
||||||
env.Append(LINKFLAGS=["-arch", "x86_64", "-arch", "arm64"])
|
env.Append(LINKFLAGS=["-arch", "x86_64", "-arch", "arm64"])
|
||||||
env.Append(CCFLAGS=["-arch", "x86_64", "-arch", "arm64"])
|
env.Append(CCFLAGS=["-arch", "x86_64", "-arch", "arm64"])
|
||||||
@@ -68,5 +48,3 @@ def generate(env):
|
|||||||
"-Wl,-undefined,dynamic_lookup",
|
"-Wl,-undefined,dynamic_lookup",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
env.Append(CPPDEFINES=["MACOS_ENABLED", "UNIX_ENABLED"])
|
|
||||||
|
|||||||
28
tools/macos_osxcross.py
Normal file
28
tools/macos_osxcross.py
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
def options(opts):
|
||||||
|
opts.Add("osxcross_sdk", "OSXCross SDK version", "darwin16")
|
||||||
|
|
||||||
|
|
||||||
|
def exists(env):
|
||||||
|
return "OSXCROSS_ROOT" in os.environ
|
||||||
|
|
||||||
|
|
||||||
|
def generate(env):
|
||||||
|
root = os.environ.get("OSXCROSS_ROOT", "")
|
||||||
|
if env["arch"] == "arm64":
|
||||||
|
basecmd = root + "/target/bin/arm64-apple-" + env["osxcross_sdk"] + "-"
|
||||||
|
else:
|
||||||
|
basecmd = root + "/target/bin/x86_64-apple-" + env["osxcross_sdk"] + "-"
|
||||||
|
|
||||||
|
env["CC"] = basecmd + "clang"
|
||||||
|
env["CXX"] = basecmd + "clang++"
|
||||||
|
env["AR"] = basecmd + "ar"
|
||||||
|
env["RANLIB"] = basecmd + "ranlib"
|
||||||
|
env["AS"] = basecmd + "as"
|
||||||
|
|
||||||
|
binpath = os.path.join(root, "target", "bin")
|
||||||
|
if binpath not in env["ENV"]["PATH"]:
|
||||||
|
# Add OSXCROSS bin folder to PATH (required for linking).
|
||||||
|
env["ENV"]["PATH"] = "%s:%s" % (binpath, env["ENV"]["PATH"])
|
||||||
@@ -1,14 +1,10 @@
|
|||||||
import os
|
import os
|
||||||
import subprocess
|
|
||||||
import sys
|
import sys
|
||||||
from SCons.Script import ARGUMENTS
|
from SCons.Script import ARGUMENTS
|
||||||
from SCons.Variables import *
|
from SCons.Variables import *
|
||||||
from SCons.Variables.BoolVariable import _text2bool
|
from SCons.Variables.BoolVariable import _text2bool
|
||||||
|
|
||||||
|
|
||||||
# Helper methods
|
|
||||||
|
|
||||||
|
|
||||||
def get_cmdline_bool(option, default):
|
def get_cmdline_bool(option, default):
|
||||||
"""We use `ARGUMENTS.get()` to check if options were manually overridden on the command line,
|
"""We use `ARGUMENTS.get()` to check if options were manually overridden on the command line,
|
||||||
and SCons' _text2bool helper to convert them to booleans, otherwise they're handled as strings.
|
and SCons' _text2bool helper to convert them to booleans, otherwise they're handled as strings.
|
||||||
@@ -20,24 +16,6 @@ def get_cmdline_bool(option, default):
|
|||||||
return default
|
return default
|
||||||
|
|
||||||
|
|
||||||
def using_clang(env):
|
|
||||||
return "clang" in os.path.basename(env["CC"])
|
|
||||||
|
|
||||||
|
|
||||||
def is_vanilla_clang(env):
|
|
||||||
if not using_clang(env):
|
|
||||||
return False
|
|
||||||
try:
|
|
||||||
version = subprocess.check_output([env.subst(env["CXX"]), "--version"]).strip().decode("utf-8")
|
|
||||||
except (subprocess.CalledProcessError, OSError):
|
|
||||||
print("Couldn't parse CXX environment variable to infer compiler version.")
|
|
||||||
return False
|
|
||||||
return not version.startswith("Apple")
|
|
||||||
|
|
||||||
|
|
||||||
# Main tool definition
|
|
||||||
|
|
||||||
|
|
||||||
def options(opts):
|
def options(opts):
|
||||||
opts.Add(
|
opts.Add(
|
||||||
EnumVariable(
|
EnumVariable(
|
||||||
@@ -56,21 +34,19 @@ def exists(env):
|
|||||||
|
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
# Configuration of build targets:
|
|
||||||
# - Editor or template
|
|
||||||
# - Debug features (DEBUG_ENABLED code)
|
|
||||||
# - Dev only code (DEV_ENABLED code)
|
|
||||||
# - Optimization level
|
|
||||||
# - Debug symbols for crash traces / debuggers
|
|
||||||
|
|
||||||
# Keep this configuration in sync with SConstruct in upstream Godot.
|
|
||||||
|
|
||||||
env.editor_build = env["target"] == "editor"
|
|
||||||
env.dev_build = env["dev_build"]
|
env.dev_build = env["dev_build"]
|
||||||
env.debug_features = env["target"] in ["editor", "template_debug"]
|
env.debug_features = env["target"] in ["editor", "template_debug"]
|
||||||
|
env.editor_build = env["target"] == "editor"
|
||||||
|
|
||||||
|
if env.editor_build:
|
||||||
|
env.AppendUnique(CPPDEFINES=["TOOLS_ENABLED"])
|
||||||
|
|
||||||
|
if env.debug_features:
|
||||||
|
env.AppendUnique(CPPDEFINES=["DEBUG_ENABLED", "DEBUG_METHODS_ENABLED"])
|
||||||
|
|
||||||
if env.dev_build:
|
if env.dev_build:
|
||||||
opt_level = "none"
|
opt_level = "none"
|
||||||
|
env.AppendUnique(CPPDEFINES=["DEV_ENABLED"])
|
||||||
elif env.debug_features:
|
elif env.debug_features:
|
||||||
opt_level = "speed_trace"
|
opt_level = "speed_trace"
|
||||||
else: # Release
|
else: # Release
|
||||||
@@ -79,57 +55,29 @@ def generate(env):
|
|||||||
env["optimize"] = ARGUMENTS.get("optimize", opt_level)
|
env["optimize"] = ARGUMENTS.get("optimize", opt_level)
|
||||||
env["debug_symbols"] = get_cmdline_bool("debug_symbols", env.dev_build)
|
env["debug_symbols"] = get_cmdline_bool("debug_symbols", env.dev_build)
|
||||||
|
|
||||||
if env.editor_build:
|
|
||||||
env.Append(CPPDEFINES=["TOOLS_ENABLED"])
|
|
||||||
|
|
||||||
if env.debug_features:
|
|
||||||
# DEBUG_ENABLED enables debugging *features* and debug-only code, which is intended
|
|
||||||
# to give *users* extra debugging information for their game development.
|
|
||||||
env.Append(CPPDEFINES=["DEBUG_ENABLED"])
|
|
||||||
# In upstream Godot this is added in typedefs.h when DEBUG_ENABLED is set.
|
|
||||||
env.Append(CPPDEFINES=["DEBUG_METHODS_ENABLED"])
|
|
||||||
|
|
||||||
if env.dev_build:
|
|
||||||
# DEV_ENABLED enables *engine developer* code which should only be compiled for those
|
|
||||||
# working on the engine itself.
|
|
||||||
env.Append(CPPDEFINES=["DEV_ENABLED"])
|
|
||||||
else:
|
|
||||||
# Disable assert() for production targets (only used in thirdparty code).
|
|
||||||
env.Append(CPPDEFINES=["NDEBUG"])
|
|
||||||
|
|
||||||
# Set optimize and debug_symbols flags.
|
|
||||||
# "custom" means do nothing and let users set their own optimization flags.
|
|
||||||
if env.get("is_msvc", False):
|
if env.get("is_msvc", False):
|
||||||
if env["debug_symbols"]:
|
if env["debug_symbols"]:
|
||||||
env.Append(CCFLAGS=["/Zi", "/FS"])
|
env.Append(CCFLAGS=["/Zi", "/FS"])
|
||||||
env.Append(LINKFLAGS=["/DEBUG:FULL"])
|
env.Append(LINKFLAGS=["/DEBUG:FULL"])
|
||||||
|
|
||||||
if env["optimize"] == "speed":
|
if env["optimize"] == "speed" or env["optimize"] == "speed_trace":
|
||||||
env.Append(CCFLAGS=["/O2"])
|
env.Append(CCFLAGS=["/O2"])
|
||||||
env.Append(LINKFLAGS=["/OPT:REF"])
|
env.Append(LINKFLAGS=["/OPT:REF"])
|
||||||
elif env["optimize"] == "speed_trace":
|
|
||||||
env.Append(CCFLAGS=["/O2"])
|
|
||||||
env.Append(LINKFLAGS=["/OPT:REF", "/OPT:NOICF"])
|
|
||||||
elif env["optimize"] == "size":
|
elif env["optimize"] == "size":
|
||||||
env.Append(CCFLAGS=["/O1"])
|
env.Append(CCFLAGS=["/O1"])
|
||||||
env.Append(LINKFLAGS=["/OPT:REF"])
|
env.Append(LINKFLAGS=["/OPT:REF"])
|
||||||
elif env["optimize"] == "debug" or env["optimize"] == "none":
|
|
||||||
env.Append(CCFLAGS=["/Od"])
|
if env["optimize"] == "debug" or env["optimize"] == "none":
|
||||||
|
env.Append(CCFLAGS=["/MDd", "/Od"])
|
||||||
|
else:
|
||||||
|
env.Append(CCFLAGS=["/MD"])
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if env["debug_symbols"]:
|
if env["debug_symbols"]:
|
||||||
# Adding dwarf-4 explicitly makes stacktraces work with clang builds,
|
|
||||||
# otherwise addr2line doesn't understand them.
|
|
||||||
env.Append(CCFLAGS=["-gdwarf-4"])
|
|
||||||
if env.dev_build:
|
if env.dev_build:
|
||||||
env.Append(CCFLAGS=["-g3"])
|
env.Append(CCFLAGS=["-g3"])
|
||||||
else:
|
else:
|
||||||
env.Append(CCFLAGS=["-g2"])
|
env.Append(CCFLAGS=["-g2"])
|
||||||
else:
|
|
||||||
if using_clang(env) and not is_vanilla_clang(env):
|
|
||||||
# Apple Clang, its linker doesn't like -s.
|
|
||||||
env.Append(LINKFLAGS=["-Wl,-S", "-Wl,-x", "-Wl,-dead_strip"])
|
|
||||||
else:
|
|
||||||
env.Append(LINKFLAGS=["-s"])
|
|
||||||
|
|
||||||
if env["optimize"] == "speed":
|
if env["optimize"] == "speed":
|
||||||
env.Append(CCFLAGS=["-O3"])
|
env.Append(CCFLAGS=["-O3"])
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ from SCons.Variables import *
|
|||||||
def options(opts):
|
def options(opts):
|
||||||
opts.Add(BoolVariable("use_mingw", "Use the MinGW compiler instead of MSVC - only effective on Windows", False))
|
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_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))
|
|
||||||
|
|
||||||
|
|
||||||
def exists(env):
|
def exists(env):
|
||||||
@@ -31,18 +30,13 @@ def generate(env):
|
|||||||
env.Tool("mslink")
|
env.Tool("mslink")
|
||||||
|
|
||||||
env.Append(CPPDEFINES=["TYPED_METHOD_BIND", "NOMINMAX"])
|
env.Append(CPPDEFINES=["TYPED_METHOD_BIND", "NOMINMAX"])
|
||||||
env.Append(CCFLAGS=["/utf-8"])
|
env.Append(CCFLAGS=["/EHsc"])
|
||||||
env.Append(LINKFLAGS=["/WX"])
|
env.Append(LINKFLAGS=["/WX"])
|
||||||
|
|
||||||
if env["use_clang_cl"]:
|
if env["use_clang_cl"]:
|
||||||
env["CC"] = "clang-cl"
|
env["CC"] = "clang-cl"
|
||||||
env["CXX"] = "clang-cl"
|
env["CXX"] = "clang-cl"
|
||||||
|
|
||||||
if env["use_static_cpp"]:
|
|
||||||
env.Append(CCFLAGS=["/MT"])
|
|
||||||
else:
|
|
||||||
env.Append(CCFLAGS=["/MD"])
|
|
||||||
|
|
||||||
elif sys.platform == "win32" or sys.platform == "msys":
|
elif sys.platform == "win32" or sys.platform == "msys":
|
||||||
env["use_mingw"] = True
|
env["use_mingw"] = True
|
||||||
mingw.generate(env)
|
mingw.generate(env)
|
||||||
@@ -51,18 +45,6 @@ def generate(env):
|
|||||||
env["SHLIBPREFIX"] = ""
|
env["SHLIBPREFIX"] = ""
|
||||||
# Want dll suffix
|
# Want dll suffix
|
||||||
env["SHLIBSUFFIX"] = ".dll"
|
env["SHLIBSUFFIX"] = ".dll"
|
||||||
|
|
||||||
env.Append(CCFLAGS=["-Wwrite-strings"])
|
|
||||||
env.Append(LINKFLAGS=["-Wl,--no-undefined"])
|
|
||||||
if env["use_static_cpp"]:
|
|
||||||
env.Append(
|
|
||||||
LINKFLAGS=[
|
|
||||||
"-static",
|
|
||||||
"-static-libgcc",
|
|
||||||
"-static-libstdc++",
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
# Long line hack. Use custom spawn, quick AR append (to avoid files with the same names to override each other).
|
# Long line hack. Use custom spawn, quick AR append (to avoid files with the same names to override each other).
|
||||||
my_spawn.configure(env)
|
my_spawn.configure(env)
|
||||||
|
|
||||||
@@ -78,15 +60,13 @@ def generate(env):
|
|||||||
# Want dll suffix
|
# Want dll suffix
|
||||||
env["SHLIBSUFFIX"] = ".dll"
|
env["SHLIBSUFFIX"] = ".dll"
|
||||||
|
|
||||||
env.Append(CCFLAGS=["-Wwrite-strings"])
|
# These options are for a release build even using target=debug
|
||||||
env.Append(LINKFLAGS=["-Wl,--no-undefined"])
|
env.Append(CCFLAGS=["-O3", "-Wwrite-strings"])
|
||||||
if env["use_static_cpp"]:
|
env.Append(
|
||||||
env.Append(
|
LINKFLAGS=[
|
||||||
LINKFLAGS=[
|
"--static",
|
||||||
"-static",
|
"-Wl,--no-undefined",
|
||||||
"-static-libgcc",
|
"-static-libgcc",
|
||||||
"-static-libstdc++",
|
"-static-libstdc++",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
env.Append(CPPDEFINES=["WINDOWS_ENABLED"])
|
|
||||||
|
|||||||
Reference in New Issue
Block a user