mirror of
https://github.com/godotengine/godot-cpp.git
synced 2026-01-01 05:48:37 +03:00
Compare commits
334 Commits
4.2
...
godot-4.4-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
714c9e2c16 | ||
|
|
06082d7727 | ||
|
|
26358b5e3a | ||
|
|
e3816585fe | ||
|
|
d0dd282d73 | ||
|
|
c8c25cd312 | ||
|
|
4a9409a30f | ||
|
|
375c0d1575 | ||
|
|
e7f07dab87 | ||
|
|
98ea2f60bb | ||
|
|
48baa0c812 | ||
|
|
89fd27608f | ||
|
|
5eb6e6bf61 | ||
|
|
23c24073f4 | ||
|
|
79f9bc9600 | ||
|
|
3f54a86554 | ||
|
|
847dca4792 | ||
|
|
18a926e836 | ||
|
|
35469fd839 | ||
|
|
9d9099adcd | ||
|
|
f398ebb8ce | ||
|
|
560f786599 | ||
|
|
91f81f51e1 | ||
|
|
ee2a895ea4 | ||
|
|
f06af65c87 | ||
|
|
3c55ca7a14 | ||
|
|
9ce7a71cbf | ||
|
|
13cd2d921c | ||
|
|
b86cf321d0 | ||
|
|
faf6facffc | ||
|
|
dfc51960f9 | ||
|
|
7576dc5930 | ||
|
|
bd3cf478c6 | ||
|
|
befe3ee2f2 | ||
|
|
8814ac51ac | ||
|
|
94a1f4f2fb | ||
|
|
65046d00a5 | ||
|
|
5c9529fc84 | ||
|
|
ae198fe860 | ||
|
|
012b8ffc3a | ||
|
|
7d3870bc87 | ||
|
|
0cfe01eff2 | ||
|
|
c4f1abe3f9 | ||
|
|
6f7293cef4 | ||
|
|
47f11bc5c7 | ||
|
|
2fd3a80505 | ||
|
|
27ffd8c6be | ||
|
|
47d9cb9bed | ||
|
|
97c16d3379 | ||
|
|
9943675dcb | ||
|
|
38056d1086 | ||
|
|
ef9778a392 | ||
|
|
ce66e6bb39 | ||
|
|
542ab19a21 | ||
|
|
163189fba9 | ||
|
|
4eaef4ca9a | ||
|
|
72aeb35691 | ||
|
|
9df3a66a88 | ||
|
|
732df06a81 | ||
|
|
bb567060f4 | ||
|
|
daef7d48ea | ||
|
|
5255034fb0 | ||
|
|
b378d8c21f | ||
|
|
af4eaa76d7 | ||
|
|
3a8d7a25ae | ||
|
|
bc6f79c67a | ||
|
|
b7dbd26d8f | ||
|
|
f174b4a445 | ||
|
|
ac466e4766 | ||
|
|
597055d13c | ||
|
|
a42b3634d2 | ||
|
|
8534e2104f | ||
|
|
c20a84e483 | ||
|
|
5f7cf05043 | ||
|
|
f298ddd3c4 | ||
|
|
1e3b24f658 | ||
|
|
253e095c81 | ||
|
|
450c3d65cd | ||
|
|
259c757cce | ||
|
|
23c9d41d2a | ||
|
|
7871cec1e7 | ||
|
|
688ed4b388 | ||
|
|
7796fcc890 | ||
|
|
42e398e4e2 | ||
|
|
ca5179f7d7 | ||
|
|
1e169bb809 | ||
|
|
fa3dfa0e3c | ||
|
|
7fca545885 | ||
|
|
dfdc047459 | ||
|
|
2004af63a0 | ||
|
|
7f47d3951e | ||
|
|
0602c32986 | ||
|
|
91833c852e | ||
|
|
a98d41f62b | ||
|
|
96675a814b | ||
|
|
291147e21b | ||
|
|
42a35a1852 | ||
|
|
02fd535454 | ||
|
|
c1524f7c86 | ||
|
|
7f02301a91 | ||
|
|
6facde3c29 | ||
|
|
709bad01d1 | ||
|
|
83c0f15ab9 | ||
|
|
96565e1de5 | ||
|
|
78f5d99fd9 | ||
|
|
9f5daa2d90 | ||
|
|
2402a044eb | ||
|
|
64221facda | ||
|
|
78498da7c3 | ||
|
|
4717a78144 | ||
|
|
07704f8f48 | ||
|
|
57bd88ad99 | ||
|
|
536ea8561e | ||
|
|
b93d6e887e | ||
|
|
2ffff669f5 | ||
|
|
730ccaae39 | ||
|
|
9b98b19913 | ||
|
|
cb543c192a | ||
|
|
390a9a5590 | ||
|
|
4131b7f95f | ||
|
|
02bdc6665a | ||
|
|
aed9b5c7df | ||
|
|
4d8c05f405 | ||
|
|
f4d3817d99 | ||
|
|
d477589104 | ||
|
|
05571971cc | ||
|
|
aac0164b7a | ||
|
|
fd8f196008 | ||
|
|
16bc0a0fff | ||
|
|
d18fa929fb | ||
|
|
7b31f39bea | ||
|
|
f36acd8e31 | ||
|
|
10c3d1bc5f | ||
|
|
19c83a8837 | ||
|
|
9a89d226c7 | ||
|
|
265412cc53 | ||
|
|
92ace04989 | ||
|
|
62305943a7 | ||
|
|
9949d09f3e | ||
|
|
8b80d9146b | ||
|
|
4829199081 | ||
|
|
fbbf9ec4ef | ||
|
|
2e4c350b83 | ||
|
|
f2353da5a3 | ||
|
|
9b98377a62 | ||
|
|
92e6ea7303 | ||
|
|
11773e52b0 | ||
|
|
937b1d809a | ||
|
|
738859f49b | ||
|
|
9da1e0cee1 | ||
|
|
3f4590f8e1 | ||
|
|
e3e8101e8c | ||
|
|
26459dc47b | ||
|
|
daf6ad3649 | ||
|
|
c77d44f3f6 | ||
|
|
f2b521f55a | ||
|
|
628606b28b | ||
|
|
958776dfc3 | ||
|
|
f131efb791 | ||
|
|
0a1e31fa45 | ||
|
|
8012716ee3 | ||
|
|
76b38de01a | ||
|
|
6d939e6878 | ||
|
|
56cd3fd99e | ||
|
|
99926d8e20 | ||
|
|
e65ec904b8 | ||
|
|
2b34bd0d8b | ||
|
|
53b546e1df | ||
|
|
7abe4ca9e4 | ||
|
|
316dde80ba | ||
|
|
7d7799b56e | ||
|
|
90c6ea2a12 | ||
|
|
1989b1bf57 | ||
|
|
7a96d0314e | ||
|
|
999018e7d1 | ||
|
|
e0d363aad8 | ||
|
|
c414c2b37d | ||
|
|
78b63203d4 | ||
|
|
0efc6cddbc | ||
|
|
e7a13e3bf4 | ||
|
|
ed1e963a31 | ||
|
|
068e930c6a | ||
|
|
2dd8917508 | ||
|
|
89831ff333 | ||
|
|
f2ac49aea5 | ||
|
|
1186c488bd | ||
|
|
8cdd56e149 | ||
|
|
f1b7ba3e06 | ||
|
|
5d8f80bc55 | ||
|
|
9e2771f918 | ||
|
|
ee9acbcf10 | ||
|
|
64f1bc847a | ||
|
|
1bb543b6f4 | ||
|
|
37e7a6da05 | ||
|
|
6c4064125b | ||
|
|
9f6fe36633 | ||
|
|
2360f84513 | ||
|
|
6cd6c8923a | ||
|
|
e04a26b2bc | ||
|
|
c5986e666f | ||
|
|
7d4758eace | ||
|
|
4f7439d4cf | ||
|
|
fe0647202b | ||
|
|
7f74fe7bb2 | ||
|
|
41aa71f8c3 | ||
|
|
8c6cc1ec15 | ||
|
|
21d526e5e5 | ||
|
|
246a803954 | ||
|
|
45be6d0bd4 | ||
|
|
21b86b6770 | ||
|
|
76cbc66785 | ||
|
|
3e9afccae8 | ||
|
|
b697ba8896 | ||
|
|
e4a4d76cb3 | ||
|
|
3db8549e19 | ||
|
|
340dde31a2 | ||
|
|
6b39ed0732 | ||
|
|
16cad7ba24 | ||
|
|
798fbab653 | ||
|
|
88df025aa0 | ||
|
|
85172dad1b | ||
|
|
996d229b26 | ||
|
|
5bad5d6958 | ||
|
|
e3f3cb58b7 | ||
|
|
17a82e7f94 | ||
|
|
f5c2b38724 | ||
|
|
3d0d9cd0e2 | ||
|
|
43be24f34c | ||
|
|
a434850069 | ||
|
|
d0bdd6096c | ||
|
|
12a1283663 | ||
|
|
23178e81ff | ||
|
|
505076c9a9 | ||
|
|
b0296bb562 | ||
|
|
54fe2f9891 | ||
|
|
8cc78cfea9 | ||
|
|
2cd3d39108 | ||
|
|
1d829f2e4a | ||
|
|
ca46ef4d25 | ||
|
|
e23b117ac3 | ||
|
|
d304f12dcd | ||
|
|
61450b3e1b | ||
|
|
06373ce1cf | ||
|
|
e1b3b32db5 | ||
|
|
2a041b5240 | ||
|
|
ad307e4b9c | ||
|
|
6873658d26 | ||
|
|
9ff49b7b1b | ||
|
|
048f49af39 | ||
|
|
e160966163 | ||
|
|
e4ae69f607 | ||
|
|
4b7661a60a | ||
|
|
d389171905 | ||
|
|
b65970860e | ||
|
|
1fa7a9cb19 | ||
|
|
a537b4af4d | ||
|
|
b05c21bb1d | ||
|
|
37542dc2ec | ||
|
|
b02124595f | ||
|
|
d055b575fb | ||
|
|
7d4a24caab | ||
|
|
3715bfe253 | ||
|
|
44d78ec881 | ||
|
|
5c12bd2287 | ||
|
|
87ecf17242 | ||
|
|
a62f633ceb | ||
|
|
ec166295ba | ||
|
|
916b4ff2d5 | ||
|
|
fb79d5ff98 | ||
|
|
e6b6df5893 | ||
|
|
d78fe9853f | ||
|
|
12ebe4b180 | ||
|
|
efb46f7f82 | ||
|
|
7cff8ca896 | ||
|
|
87f5fb0691 | ||
|
|
e607790647 | ||
|
|
7ed8ef7221 | ||
|
|
cc1217a43c | ||
|
|
f444616553 | ||
|
|
fc986c2d12 | ||
|
|
8c98a90f32 | ||
|
|
8b92368165 | ||
|
|
e55b792fea | ||
|
|
c4fde852e6 | ||
|
|
23c010900c | ||
|
|
f90085917b | ||
|
|
a6d9393341 | ||
|
|
16df4bff30 | ||
|
|
620104e700 | ||
|
|
349b081b18 | ||
|
|
baaad7ada2 | ||
|
|
fb884573ea | ||
|
|
5fcc43e54d | ||
|
|
9a13efa0e3 | ||
|
|
8fbb7cf795 | ||
|
|
6a3753c076 | ||
|
|
7c547c6c6b | ||
|
|
349b5a3146 | ||
|
|
b173a4d935 | ||
|
|
32ca574f49 | ||
|
|
36847f6af0 | ||
|
|
8a535d0ecc | ||
|
|
cd5673bf2e | ||
|
|
0145e900f3 | ||
|
|
6c04514039 | ||
|
|
480a0f8c06 | ||
|
|
5f350e2572 | ||
|
|
3943e41d2f | ||
|
|
0ddef6ed96 | ||
|
|
64529361b4 | ||
|
|
edf1637c2c | ||
|
|
ee169b201b | ||
|
|
59a5a8b104 | ||
|
|
bd40a94424 | ||
|
|
f037a697eb | ||
|
|
dd62b9685f | ||
|
|
8d13acca91 | ||
|
|
b1769a70f0 | ||
|
|
b733102f4a | ||
|
|
718d0baea3 | ||
|
|
b77cb648c3 | ||
|
|
3f44e9b404 | ||
|
|
1c19d627aa | ||
|
|
646c71c277 | ||
|
|
e17c7bf530 | ||
|
|
b17e668c15 | ||
|
|
0a078d9ec9 | ||
|
|
31179ee47c | ||
|
|
48afa82f29 | ||
|
|
39ca745d0d | ||
|
|
a7becb43e6 | ||
|
|
41517eacb1 | ||
|
|
17137b2e2e | ||
|
|
cad5be53b1 |
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -9,7 +9,7 @@ body:
|
||||
- Write a descriptive issue title above.
|
||||
- The golden rule is to **always open *one* issue for *one* bug**. If you notice several bugs and want to report them, make sure to create one new issue for each of them.
|
||||
- Search [open](https://github.com/godotengine/godot-cpp/issues) and [closed](https://github.com/godotengine/godot-cpp/issues?q=is%3Aissue+is%3Aclosed) issues to ensure it has not already been reported. If you don't find a relevant match or if you're unsure, don't hesitate to **open a new issue**. The bugsquad will handle it from there if it's a duplicate.
|
||||
- Verify that you are using a [supported Godot version](https://docs.godotengine.org/en/stable/about/release_policy.html).
|
||||
- Verify that you are using a [supported Godot version](https://docs.godotengine.org/en/latest/about/release_policy.html).
|
||||
|
||||
- type: input
|
||||
attributes:
|
||||
|
||||
65
.github/workflows/ci.yml
vendored
65
.github/workflows/ci.yml
vendored
@@ -6,7 +6,10 @@ env:
|
||||
# Only used for the cache key. Increment version to force clean build.
|
||||
GODOT_BASE_BRANCH: master
|
||||
# Used to select the version of Godot to run the tests with.
|
||||
GODOT_TEST_VERSION: 4.2.2-stable
|
||||
GODOT_TEST_VERSION: master
|
||||
# Use UTF-8 on Linux.
|
||||
LANG: en_US.UTF-8
|
||||
LC_ALL: en_US.UTF-8
|
||||
|
||||
concurrency:
|
||||
group: ci-${{ github.actor }}-${{ github.head_ref || github.run_number }}-${{ github.ref }}
|
||||
@@ -21,7 +24,7 @@ jobs:
|
||||
matrix:
|
||||
include:
|
||||
- name: 🐧 Linux (GCC)
|
||||
os: ubuntu-20.04
|
||||
os: ubuntu-22.04
|
||||
platform: linux
|
||||
artifact-name: godot-cpp-linux-glibc2.27-x86_64-release
|
||||
artifact-path: bin/libgodot-cpp.linux.template_release.x86_64.a
|
||||
@@ -29,7 +32,7 @@ jobs:
|
||||
cache-name: linux-x86_64
|
||||
|
||||
- name: 🐧 Linux (GCC, Double Precision)
|
||||
os: ubuntu-20.04
|
||||
os: ubuntu-22.04
|
||||
platform: linux
|
||||
artifact-name: godot-cpp-linux-glibc2.27-x86_64-double-release
|
||||
artifact-path: bin/libgodot-cpp.linux.template_release.double.x86_64.a
|
||||
@@ -64,7 +67,7 @@ jobs:
|
||||
cache-name: macos-universal
|
||||
|
||||
- name: 🤖 Android (arm64)
|
||||
os: ubuntu-20.04
|
||||
os: ubuntu-22.04
|
||||
platform: android
|
||||
artifact-name: godot-cpp-android-arm64-release
|
||||
artifact-path: bin/libgodot-cpp.android.template_release.arm64.a
|
||||
@@ -82,7 +85,7 @@ jobs:
|
||||
cache-name: ios-arm64
|
||||
|
||||
- name: 🌐 Web (wasm32)
|
||||
os: ubuntu-20.04
|
||||
os: ubuntu-22.04
|
||||
platform: web
|
||||
artifact-name: godot-cpp-web-wasm32-release
|
||||
artifact-path: bin/libgodot-cpp.web.template_release.wasm32.a
|
||||
@@ -171,43 +174,19 @@ jobs:
|
||||
$GODOT --headless --version
|
||||
cd test
|
||||
# Need to run the editor so .godot is generated... but it crashes! Ignore that :-)
|
||||
(cd project && (timeout 30 $GODOT --editor --headless --quit >/dev/null 2>&1 || true))
|
||||
(cd project && (timeout 30 $GODOT --import --headless >/dev/null 2>&1 || true))
|
||||
./run-tests.sh
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ matrix.artifact-name }}
|
||||
path: ${{ matrix.artifact-path }}
|
||||
if-no-files-found: error
|
||||
|
||||
linux-cmake:
|
||||
name: 🐧 Build (Linux, GCC, CMake)
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update -qq
|
||||
sudo apt-get install -qqq build-essential pkg-config cmake
|
||||
|
||||
- name: Build godot-cpp
|
||||
run: |
|
||||
cmake -DCMAKE_BUILD_TYPE=Release .
|
||||
make -j $(nproc) VERBOSE=1
|
||||
|
||||
- name: Build test GDExtension library
|
||||
run: |
|
||||
cd test && cmake -DCMAKE_BUILD_TYPE=Release -DGODOT_HEADERS_PATH="../godot-headers" -DCPP_BINDINGS_PATH=".." .
|
||||
make -j $(nproc) VERBOSE=1
|
||||
|
||||
linux-cmake-ninja:
|
||||
name: 🐧 Build (Linux, GCC, CMake Ninja)
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
@@ -219,15 +198,12 @@ jobs:
|
||||
sudo apt-get update -qq
|
||||
sudo apt-get install -qqq build-essential pkg-config cmake ninja-build
|
||||
|
||||
- name: Build godot-cpp
|
||||
run: |
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -GNinja .
|
||||
cmake --build . -j $(nproc) --verbose
|
||||
|
||||
- name: Build test GDExtension library
|
||||
run: |
|
||||
cd test && cmake -DCMAKE_BUILD_TYPE=Release -DGODOT_HEADERS_PATH="../godot-headers" -DCPP_BINDINGS_PATH=".." -GNinja .
|
||||
cmake --build . -j $(nproc) --verbose
|
||||
mkdir cmake-build
|
||||
cd cmake-build
|
||||
cmake ../ -DGODOTCPP_ENABLE_TESTING=YES
|
||||
cmake --build . --verbose -j $(nproc) -t godot-cpp.test.template_release --config Release
|
||||
|
||||
windows-msvc-cmake:
|
||||
name: 🏁 Build (Windows, MSVC, CMake)
|
||||
@@ -238,12 +214,9 @@ jobs:
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Build godot-cpp
|
||||
run: |
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -G"Visual Studio 16 2019" .
|
||||
cmake --build . --verbose --config Release
|
||||
|
||||
- name: Build test GDExtension library
|
||||
run: |
|
||||
cd test && cmake -DCMAKE_BUILD_TYPE=Release -DGODOT_HEADERS_PATH="../godot-headers" -DCPP_BINDINGS_PATH=".." -G"Visual Studio 16 2019" .
|
||||
cmake --build . --verbose --config Release
|
||||
mkdir cmake-build
|
||||
cd cmake-build
|
||||
cmake ../ -DGODOTCPP_ENABLE_TESTING=YES
|
||||
cmake --build . --verbose -t godot-cpp.test.template_release --config Release
|
||||
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -198,4 +198,7 @@ venv
|
||||
|
||||
# Clion Configuration
|
||||
.idea/
|
||||
cmake-build-*
|
||||
cmake-build*/
|
||||
|
||||
# CMake related
|
||||
CMakeUserPresets.json
|
||||
|
||||
@@ -1,24 +1,62 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
project(godot-cpp LANGUAGES CXX)
|
||||
cmake_minimum_required(VERSION 3.17)
|
||||
|
||||
# Configure CMake
|
||||
# https://discourse.cmake.org/t/how-do-i-remove-compile-options-from-target/5965
|
||||
# https://stackoverflow.com/questions/74426638/how-to-remove-rtc1-from-specific-target-or-file-in-cmake
|
||||
if(${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC)
|
||||
if(NOT CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
STRING(REGEX REPLACE "/RTC(su|[1su])" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
string(REPLACE "/RTC1" "" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
|
||||
endif ()
|
||||
endif ()
|
||||
#[=======================================================================[.rst:
|
||||
|
||||
include( ${PROJECT_SOURCE_DIR}/cmake/godotcpp.cmake )
|
||||
CMake Version requirements
|
||||
--------------------------
|
||||
|
||||
# I know this doesn't look like a typical CMakeLists.txt, but as we are
|
||||
# attempting mostly feature parity with SCons, and easy maintenance, the closer
|
||||
# the two build systems look the easier they will be to keep in lockstep.
|
||||
To enable use of the emscripten emsdk hack for pseudo shared library support
|
||||
without polluting options for consumers we need to use the
|
||||
CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE which was introduced in version 3.17
|
||||
|
||||
# The typical target definitions are in ${PROJECT_SOURCE_DIR}/cmake/godotcpp.cmake
|
||||
Scons Compatibility
|
||||
-------------------
|
||||
|
||||
There is an understandable conflict between build systems as they define
|
||||
similar concepts in different ways. When there isn't a 1:1 relationship,
|
||||
compromises need to be made to resolve those differences.
|
||||
|
||||
As we are attempting to maintain feature parity, and ease of maintenance, these
|
||||
CMake scripts are built to resemble the SCons build system wherever possible.
|
||||
|
||||
The file structure and file content are made to match, if not in content then
|
||||
in spirit. The closer the two build systems look the easier they will be to
|
||||
maintain.
|
||||
|
||||
Where the SCons additional scripts in the tools directory, The CMake scripts
|
||||
are in the cmake directory.
|
||||
|
||||
For example, the tools/godotcpp.py is sourced into SCons, and the 'options'
|
||||
function is run.
|
||||
|
||||
.. highlight:: python
|
||||
|
||||
cpp_tool = Tool("godotcpp", toolpath=["tools"])
|
||||
cpp_tool.options(opts, env)
|
||||
|
||||
The CMake equivalent is below.
|
||||
]=======================================================================]
|
||||
|
||||
include( cmake/godotcpp.cmake )
|
||||
|
||||
godotcpp_options()
|
||||
|
||||
# Define our project.
|
||||
project( godot-cpp
|
||||
VERSION 4.4
|
||||
DESCRIPTION "C++ bindings for the Godot Engine's GDExtensions API."
|
||||
HOMEPAGE_URL "https://github.com/godotengine/godot-cpp"
|
||||
LANGUAGES CXX)
|
||||
|
||||
compiler_detection()
|
||||
godotcpp_generate()
|
||||
|
||||
# Conditionally enable the godot-cpp.test.<target> integration testing targets
|
||||
if( GODOTCPP_ENABLE_TESTING )
|
||||
add_subdirectory( test )
|
||||
endif()
|
||||
|
||||
# If this is the top level CMakeLists.txt, Generators which honor the
|
||||
# USE_FOLDERS flag will organize godot-cpp targets under the subfolder
|
||||
# 'godot-cpp'. This is enable by default from CMake version 3.26
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
|
||||
26
README.md
26
README.md
@@ -1,6 +1,6 @@
|
||||
# godot-cpp
|
||||
|
||||
> **Warning**
|
||||
> [!WARNING]
|
||||
>
|
||||
> This repository's `master` branch is only usable with
|
||||
> [GDExtension](https://godotengine.org/article/introducing-gd-extensions)
|
||||
@@ -22,7 +22,7 @@ This repository contains the *C++ bindings* for the [**Godot Engine**](https://
|
||||
- [**Compatibility**](#compatibility)
|
||||
- [**Contributing**](#contributing)
|
||||
- [**Getting started**](#getting-started)
|
||||
- [**Included example**](#included-example)
|
||||
- [**Examples and templates**](#examples-and-templates)
|
||||
|
||||
## Versioning
|
||||
|
||||
@@ -49,18 +49,20 @@ Godot version.**
|
||||
|
||||
## Compatibility
|
||||
|
||||
**Warning:** The GDExtension API is brand new in Godot 4.0, and is still
|
||||
> [!WARNING]
|
||||
>
|
||||
> The GDExtension API is brand new in Godot 4.0, and is still
|
||||
considered in **beta** stage, despite Godot 4.0 itself being released.
|
||||
|
||||
This applies to both the GDExtension interface header, the API JSON, and this
|
||||
>
|
||||
> This applies to both the GDExtension interface header, the API JSON, and this
|
||||
first-party `godot-cpp` extension.
|
||||
|
||||
Some compatibility breakage is to be expected as GDExtension and `godot-cpp`
|
||||
get more used, documented, and critical issues get resolved. See the
|
||||
[Godot issue tracker](https://github.com/godotengine/godot/issues?q=is%3Aissue+is%3Aopen+label%3Atopic%3Agdextension)
|
||||
and the [godot-cpp issue tracker](https://github.com/godotengine/godot-cpp/issues)
|
||||
for a list of known issues, and be sure to provide feedback on issues and PRs
|
||||
which affect your use of this extension.
|
||||
>
|
||||
> Some compatibility breakage is to be expected as GDExtension and `godot-cpp`
|
||||
> get more used, documented, and critical issues get resolved. See the
|
||||
> [Godot issue tracker](https://github.com/godotengine/godot/issues?q=is%3Aissue+is%3Aopen+label%3Atopic%3Agdextension)
|
||||
> and the [godot-cpp issue tracker](https://github.com/godotengine/godot-cpp/issues)
|
||||
> for a list of known issues, and be sure to provide feedback on issues and PRs
|
||||
> which affect your use of this extension.
|
||||
|
||||
## Contributing
|
||||
|
||||
|
||||
@@ -70,7 +70,146 @@ def generate_wrappers(target):
|
||||
f.write(txt)
|
||||
|
||||
|
||||
def get_file_list(api_filepath, output_dir, headers=False, sources=False, profile_filepath=""):
|
||||
def generate_virtual_version(argcount, const=False, returns=False, required=False):
|
||||
s = """#define GDVIRTUAL$VER($RET m_name $ARG)\\
|
||||
::godot::StringName _gdvirtual_##m_name##_sn = #m_name;\\
|
||||
_FORCE_INLINE_ bool _gdvirtual_##m_name##_call($CALLARGS) $CONST {\\
|
||||
if (::godot::internal::gdextension_interface_object_has_script_method(_owner, &_gdvirtual_##m_name##_sn)) { \\
|
||||
GDExtensionCallError ce;\\
|
||||
$CALLSIARGS\\
|
||||
::godot::Variant ret;\\
|
||||
::godot::internal::gdextension_interface_object_call_script_method(_owner, &_gdvirtual_##m_name##_sn, $CALLSIARGPASS, &ret, &ce);\\
|
||||
if (ce.error == GDEXTENSION_CALL_OK) {\\
|
||||
$CALLSIRET\\
|
||||
return true;\\
|
||||
}\\
|
||||
}\\
|
||||
$REQCHECK\\
|
||||
$RVOID\\
|
||||
return false;\\
|
||||
}\\
|
||||
_FORCE_INLINE_ bool _gdvirtual_##m_name##_overridden() const {\\
|
||||
return ::godot::internal::gdextension_interface_object_has_script_method(_owner, &_gdvirtual_##m_name##_sn); \\
|
||||
}\\
|
||||
_FORCE_INLINE_ static ::godot::MethodInfo _gdvirtual_##m_name##_get_method_info() {\\
|
||||
::godot::MethodInfo method_info;\\
|
||||
method_info.name = #m_name;\\
|
||||
method_info.flags = $METHOD_FLAGS;\\
|
||||
$FILL_METHOD_INFO\\
|
||||
return method_info;\\
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
sproto = str(argcount)
|
||||
method_info = ""
|
||||
method_flags = "METHOD_FLAG_VIRTUAL"
|
||||
if returns:
|
||||
sproto += "R"
|
||||
s = s.replace("$RET", "m_ret,")
|
||||
s = s.replace("$RVOID", "(void)r_ret;") # If required, may lead to uninitialized errors
|
||||
method_info += "method_info.return_val = ::godot::GetTypeInfo<m_ret>::get_class_info();\\\n"
|
||||
method_info += "\t\tmethod_info.return_val_metadata = ::godot::GetTypeInfo<m_ret>::METADATA;"
|
||||
else:
|
||||
s = s.replace("$RET ", "")
|
||||
s = s.replace("\t\t$RVOID\\\n", "")
|
||||
|
||||
if const:
|
||||
sproto += "C"
|
||||
method_flags += " | METHOD_FLAG_CONST"
|
||||
s = s.replace("$CONST", "const")
|
||||
else:
|
||||
s = s.replace("$CONST ", "")
|
||||
|
||||
if required:
|
||||
sproto += "_REQUIRED"
|
||||
method_flags += " | METHOD_FLAG_VIRTUAL_REQUIRED"
|
||||
s = s.replace(
|
||||
"$REQCHECK",
|
||||
'ERR_PRINT_ONCE("Required virtual method " + get_class() + "::" + #m_name + " must be overridden before calling.");',
|
||||
)
|
||||
else:
|
||||
s = s.replace("\t\t$REQCHECK\\\n", "")
|
||||
|
||||
s = s.replace("$METHOD_FLAGS", method_flags)
|
||||
s = s.replace("$VER", sproto)
|
||||
argtext = ""
|
||||
callargtext = ""
|
||||
callsiargs = ""
|
||||
callsiargptrs = ""
|
||||
if argcount > 0:
|
||||
argtext += ", "
|
||||
callsiargs = f"::godot::Variant vargs[{argcount}] = {{ "
|
||||
callsiargptrs = f"\t\t\tconst ::godot::Variant *vargptrs[{argcount}] = {{ "
|
||||
for i in range(argcount):
|
||||
if i > 0:
|
||||
argtext += ", "
|
||||
callargtext += ", "
|
||||
callsiargs += ", "
|
||||
callsiargptrs += ", "
|
||||
argtext += f"m_type{i + 1}"
|
||||
callargtext += f"m_type{i + 1} arg{i + 1}"
|
||||
callsiargs += f"::godot::Variant(arg{i + 1})"
|
||||
callsiargptrs += f"&vargs[{i}]"
|
||||
if method_info:
|
||||
method_info += "\\\n\t\t"
|
||||
method_info += f"method_info.arguments.push_back(::godot::GetTypeInfo<m_type{i + 1}>::get_class_info());\\\n"
|
||||
method_info += f"\t\tmethod_info.arguments_metadata.push_back(::godot::GetTypeInfo<m_type{i + 1}>::METADATA);"
|
||||
|
||||
if argcount:
|
||||
callsiargs += " };\\\n"
|
||||
callsiargptrs += " };"
|
||||
s = s.replace("$CALLSIARGS", callsiargs + callsiargptrs)
|
||||
s = s.replace("$CALLSIARGPASS", f"(const GDExtensionConstVariantPtr *)vargptrs, {argcount}")
|
||||
else:
|
||||
s = s.replace("\t\t\t$CALLSIARGS\\\n", "")
|
||||
s = s.replace("$CALLSIARGPASS", "nullptr, 0")
|
||||
|
||||
if returns:
|
||||
if argcount > 0:
|
||||
callargtext += ", "
|
||||
callargtext += "m_ret &r_ret"
|
||||
s = s.replace("$CALLSIRET", "r_ret = ::godot::VariantCaster<m_ret>::cast(ret);")
|
||||
else:
|
||||
s = s.replace("\t\t\t\t$CALLSIRET\\\n", "")
|
||||
|
||||
s = s.replace(" $ARG", argtext)
|
||||
s = s.replace("$CALLARGS", callargtext)
|
||||
if method_info:
|
||||
s = s.replace("$FILL_METHOD_INFO", method_info)
|
||||
else:
|
||||
s = s.replace("\t\t$FILL_METHOD_INFO\\\n", method_info)
|
||||
|
||||
return s
|
||||
|
||||
|
||||
def generate_virtuals(target):
|
||||
max_versions = 12
|
||||
|
||||
txt = """/* THIS FILE IS GENERATED DO NOT EDIT */
|
||||
#ifndef GDEXTENSION_GDVIRTUAL_GEN_H
|
||||
#define GDEXTENSION_GDVIRTUAL_GEN_H
|
||||
|
||||
"""
|
||||
|
||||
for i in range(max_versions + 1):
|
||||
txt += f"/* {i} Arguments */\n\n"
|
||||
txt += generate_virtual_version(i, False, False)
|
||||
txt += generate_virtual_version(i, False, True)
|
||||
txt += generate_virtual_version(i, True, False)
|
||||
txt += generate_virtual_version(i, True, True)
|
||||
txt += generate_virtual_version(i, False, False, True)
|
||||
txt += generate_virtual_version(i, False, True, True)
|
||||
txt += generate_virtual_version(i, True, False, True)
|
||||
txt += generate_virtual_version(i, True, True, True)
|
||||
|
||||
txt += "#endif // GDEXTENSION_GDVIRTUAL_GEN_H\n"
|
||||
|
||||
with open(target, "w", encoding="utf-8") as f:
|
||||
f.write(txt)
|
||||
|
||||
|
||||
def get_file_list(api_filepath, output_dir, headers=False, sources=False):
|
||||
api = {}
|
||||
with open(api_filepath, encoding="utf-8") as api_file:
|
||||
api = json.load(api_file)
|
||||
@@ -86,6 +225,7 @@ def _get_file_list(api, output_dir, headers=False, sources=False):
|
||||
source_gen_folder = Path(output_dir) / "gen" / "src"
|
||||
|
||||
files.append(str((core_gen_folder / "ext_wrappers.gen.inc").as_posix()))
|
||||
files.append(str((core_gen_folder / "gdvirtual.gen.inc").as_posix()))
|
||||
|
||||
for builtin_class in api["builtin_classes"]:
|
||||
if is_pod_type(builtin_class["name"]):
|
||||
@@ -197,6 +337,7 @@ def generate_builtin_bindings(api, output_dir, build_config):
|
||||
source_gen_folder.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
generate_wrappers(core_gen_folder / "ext_wrappers.gen.inc")
|
||||
generate_virtuals(core_gen_folder / "gdvirtual.gen.inc")
|
||||
|
||||
# Store types beforehand.
|
||||
for builtin_api in api["builtin_classes"]:
|
||||
@@ -415,6 +556,9 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
|
||||
if class_name == "PackedVector3Array":
|
||||
result.append("#include <godot_cpp/variant/vector3.hpp>")
|
||||
result.append("")
|
||||
if class_name == "PackedVector4Array":
|
||||
result.append("#include <godot_cpp/variant/vector4.hpp>")
|
||||
result.append("")
|
||||
|
||||
if is_packed_array(class_name):
|
||||
result.append("#include <godot_cpp/core/error_macros.hpp>")
|
||||
@@ -434,6 +578,8 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
|
||||
for include in fully_used_classes:
|
||||
if include == "TypedArray":
|
||||
includes.append("godot_cpp/variant/typed_array.hpp")
|
||||
elif include == "TypedDictionary":
|
||||
includes.append("godot_cpp/variant/typed_dictionary.hpp")
|
||||
else:
|
||||
includes.append(f"godot_cpp/{get_include_path(include)}")
|
||||
|
||||
@@ -612,9 +758,11 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
|
||||
# Special cases.
|
||||
if class_name == "String":
|
||||
result.append("\tstatic String utf8(const char *p_from, int64_t p_len = -1);")
|
||||
result.append("\tvoid parse_utf8(const char *p_from, int64_t p_len = -1);")
|
||||
result.append("\tError parse_utf8(const char *p_from, int64_t p_len = -1);")
|
||||
result.append("\tstatic String utf16(const char16_t *p_from, int64_t p_len = -1);")
|
||||
result.append("\tvoid parse_utf16(const char16_t *p_from, int64_t p_len = -1);")
|
||||
result.append(
|
||||
"\tError parse_utf16(const char16_t *p_from, int64_t p_len = -1, bool p_default_little_endian = true);"
|
||||
)
|
||||
result.append("\tCharString utf8() const;")
|
||||
result.append("\tCharString ascii() const;")
|
||||
result.append("\tChar16String utf16() const;")
|
||||
@@ -782,6 +930,9 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
|
||||
if class_name == "Dictionary":
|
||||
result.append("\tconst Variant &operator[](const Variant &p_key) const;")
|
||||
result.append("\tVariant &operator[](const Variant &p_key);")
|
||||
result.append(
|
||||
"\tvoid set_typed(uint32_t p_key_type, const StringName &p_key_class_name, const Variant &p_key_script, uint32_t p_value_type, const StringName &p_value_class_name, const Variant &p_value_script);"
|
||||
)
|
||||
|
||||
result.append("};")
|
||||
|
||||
@@ -1198,6 +1349,32 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
|
||||
fully_used_classes.add(array_type_name)
|
||||
else:
|
||||
used_classes.add(array_type_name)
|
||||
elif type_name.startswith("typeddictionary::"):
|
||||
fully_used_classes.add("TypedDictionary")
|
||||
dict_type_name = type_name.replace("typeddictionary::", "")
|
||||
if dict_type_name.startswith("const "):
|
||||
dict_type_name = dict_type_name[6:]
|
||||
dict_type_names = dict_type_name.split(";")
|
||||
dict_type_name = dict_type_names[0]
|
||||
if dict_type_name.endswith("*"):
|
||||
dict_type_name = dict_type_name[:-1]
|
||||
if is_included(dict_type_name, class_name):
|
||||
if is_enum(dict_type_name):
|
||||
fully_used_classes.add(get_enum_class(dict_type_name))
|
||||
elif "default_value" in argument:
|
||||
fully_used_classes.add(dict_type_name)
|
||||
else:
|
||||
used_classes.add(dict_type_name)
|
||||
dict_type_name = dict_type_names[2]
|
||||
if dict_type_name.endswith("*"):
|
||||
dict_type_name = dict_type_name[:-1]
|
||||
if is_included(dict_type_name, class_name):
|
||||
if is_enum(dict_type_name):
|
||||
fully_used_classes.add(get_enum_class(dict_type_name))
|
||||
elif "default_value" in argument:
|
||||
fully_used_classes.add(dict_type_name)
|
||||
else:
|
||||
used_classes.add(dict_type_name)
|
||||
elif is_enum(type_name):
|
||||
fully_used_classes.add(get_enum_class(type_name))
|
||||
elif "default_value" in argument:
|
||||
@@ -1227,6 +1404,32 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
|
||||
fully_used_classes.add(array_type_name)
|
||||
else:
|
||||
used_classes.add(array_type_name)
|
||||
elif type_name.startswith("typeddictionary::"):
|
||||
fully_used_classes.add("TypedDictionary")
|
||||
dict_type_name = type_name.replace("typeddictionary::", "")
|
||||
if dict_type_name.startswith("const "):
|
||||
dict_type_name = dict_type_name[6:]
|
||||
dict_type_names = dict_type_name.split(";")
|
||||
dict_type_name = dict_type_names[0]
|
||||
if dict_type_name.endswith("*"):
|
||||
dict_type_name = dict_type_name[:-1]
|
||||
if is_included(dict_type_name, class_name):
|
||||
if is_enum(dict_type_name):
|
||||
fully_used_classes.add(get_enum_class(dict_type_name))
|
||||
elif is_variant(dict_type_name):
|
||||
fully_used_classes.add(dict_type_name)
|
||||
else:
|
||||
used_classes.add(dict_type_name)
|
||||
dict_type_name = dict_type_names[2]
|
||||
if dict_type_name.endswith("*"):
|
||||
dict_type_name = dict_type_name[:-1]
|
||||
if is_included(dict_type_name, class_name):
|
||||
if is_enum(dict_type_name):
|
||||
fully_used_classes.add(get_enum_class(dict_type_name))
|
||||
elif is_variant(dict_type_name):
|
||||
fully_used_classes.add(dict_type_name)
|
||||
else:
|
||||
used_classes.add(dict_type_name)
|
||||
elif is_enum(type_name):
|
||||
fully_used_classes.add(get_enum_class(type_name))
|
||||
elif is_variant(type_name):
|
||||
@@ -1360,6 +1563,8 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
|
||||
for included in fully_used_classes:
|
||||
if included == "TypedArray":
|
||||
includes.append("godot_cpp/variant/typed_array.hpp")
|
||||
elif included == "TypedDictionary":
|
||||
includes.append("godot_cpp/variant/typed_dictionary.hpp")
|
||||
else:
|
||||
includes.append(f"godot_cpp/{get_include_path(included)}")
|
||||
|
||||
@@ -1489,7 +1694,7 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
|
||||
# condition returns false (in such cases it can't compile due to ambiguity).
|
||||
f"\t\tif constexpr (!std::is_same_v<decltype(&B::{method_name}), decltype(&T::{method_name})>) {{"
|
||||
)
|
||||
result.append(f"\t\t\tBIND_VIRTUAL_METHOD(T, {method_name});")
|
||||
result.append(f"\t\t\tBIND_VIRTUAL_METHOD(T, {method_name}, {method['hash']});")
|
||||
result.append("\t\t}")
|
||||
|
||||
result.append("\t}")
|
||||
@@ -1505,6 +1710,10 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
|
||||
if class_name == "XMLParser":
|
||||
result.append("\tError _open_buffer(const uint8_t *p_buffer, size_t p_size);")
|
||||
|
||||
if class_name == "Image":
|
||||
result.append("\tuint8_t *ptrw();")
|
||||
result.append("\tconst uint8_t *ptr();")
|
||||
|
||||
if class_name == "FileAccess":
|
||||
result.append("\tuint64_t get_buffer(uint8_t *p_dst, uint64_t p_length) const;")
|
||||
result.append("\tvoid store_buffer(const uint8_t *p_src, uint64_t p_length);")
|
||||
@@ -1974,6 +2183,12 @@ def generate_utility_functions(api, output_dir):
|
||||
header.append("public:")
|
||||
|
||||
for function in api["utility_functions"]:
|
||||
if function["name"] == "is_instance_valid":
|
||||
# The `is_instance_valid()` function doesn't work as developers expect, and unless used very
|
||||
# carefully will cause crashes. Instead, developers should use `ObjectDB::get_instance()`
|
||||
# with object ids to ensure that an instance is still valid.
|
||||
continue
|
||||
|
||||
vararg = "is_vararg" in function and function["is_vararg"]
|
||||
|
||||
if vararg:
|
||||
@@ -2014,6 +2229,9 @@ def generate_utility_functions(api, output_dir):
|
||||
source.append("")
|
||||
|
||||
for function in api["utility_functions"]:
|
||||
if function["name"] == "is_instance_valid":
|
||||
continue
|
||||
|
||||
vararg = "is_vararg" in function and function["is_vararg"]
|
||||
|
||||
function_signature = make_signature("UtilityFunctions", function)
|
||||
@@ -2388,6 +2606,7 @@ def is_packed_array(type_name):
|
||||
"PackedStringArray",
|
||||
"PackedVector2Array",
|
||||
"PackedVector3Array",
|
||||
"PackedVector4Array",
|
||||
]
|
||||
|
||||
|
||||
@@ -2438,6 +2657,7 @@ def is_variant(type_name):
|
||||
or type_name in builtin_classes
|
||||
or type_name == "Nil"
|
||||
or type_name.startswith("typedarray::")
|
||||
or type_name.startswith("typeddictionary::")
|
||||
)
|
||||
|
||||
|
||||
@@ -2463,6 +2683,8 @@ def is_included(type_name, current_type):
|
||||
"""
|
||||
if type_name.startswith("typedarray::"):
|
||||
return True
|
||||
if type_name.startswith("typeddictionary::"):
|
||||
return True
|
||||
to_include = get_enum_class(type_name) if is_enum(type_name) else type_name
|
||||
if to_include == current_type or is_pod_type(to_include):
|
||||
return False
|
||||
@@ -2501,17 +2723,27 @@ def correct_typed_array(type_name):
|
||||
return type_name
|
||||
|
||||
|
||||
def correct_typed_dictionary(type_name):
|
||||
if type_name.startswith("typeddictionary::"):
|
||||
return type_name.replace("typeddictionary::", "TypedDictionary<").replace(";", ", ") + ">"
|
||||
return type_name
|
||||
|
||||
|
||||
def correct_type(type_name, meta=None, use_alias=True):
|
||||
type_conversion = {"float": "double", "int": "int64_t", "Nil": "Variant"}
|
||||
if meta is not None:
|
||||
if "int" in meta:
|
||||
return f"{meta}_t"
|
||||
elif "char" in meta:
|
||||
return f"{meta}_t"
|
||||
else:
|
||||
return meta
|
||||
if type_name in type_conversion:
|
||||
return type_conversion[type_name]
|
||||
if type_name.startswith("typedarray::"):
|
||||
return type_name.replace("typedarray::", "TypedArray<") + ">"
|
||||
if type_name.startswith("typeddictionary::"):
|
||||
return type_name.replace("typeddictionary::", "TypedDictionary<").replace(";", ", ") + ">"
|
||||
if is_enum(type_name):
|
||||
if is_bitfield(type_name):
|
||||
base_class = get_enum_class(type_name)
|
||||
@@ -2658,6 +2890,8 @@ def get_default_value_for_type(type_name):
|
||||
return "false"
|
||||
if type_name.startswith("typedarray::"):
|
||||
return f"{correct_type(type_name)}()"
|
||||
if type_name.startswith("typeddictionary::"):
|
||||
return f"{correct_type(type_name)}()"
|
||||
if is_enum(type_name):
|
||||
return f"{correct_type(type_name)}(0)"
|
||||
if is_variant(type_name):
|
||||
|
||||
169
cmake/GodotCPPModule.cmake
Normal file
169
cmake/GodotCPPModule.cmake
Normal file
@@ -0,0 +1,169 @@
|
||||
#[=======================================================================[.rst:
|
||||
GodotCPPModule.cmake
|
||||
---------------------
|
||||
|
||||
This file contains functions and tests which may be needed by consumers.
|
||||
|
||||
* Generate Trimmed API
|
||||
* Generate File List
|
||||
* Generate Bindings
|
||||
|
||||
If you want to use these functions in your project extend the CMAKE_MODULE_PATH
|
||||
by adding these two lines into your CMakeLists.txt after the inclusion
|
||||
godot-cpp
|
||||
|
||||
.. highlight:: cmake
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${godot-cpp_SOURCE_DIR}/cmake")
|
||||
include( GodotCPPModule )
|
||||
|
||||
]=======================================================================]
|
||||
find_package(Python3 3.4 REQUIRED) # pathlib should be present
|
||||
|
||||
#[[ Generate Trimmed API
|
||||
|
||||
The build_profile.py has a __main__ and is used as a tool
|
||||
Its usage is listed as:
|
||||
$ python build_profile.py BUILD_PROFILE INPUT_JSON [OUTPUT_JSON]
|
||||
]]
|
||||
function( build_profile_generate_trimmed_api BUILD_PROFILE INPUT_JSON OUTPUT_JSON )
|
||||
execute_process(
|
||||
COMMAND "${Python3_EXECUTABLE}"
|
||||
"${godot-cpp_SOURCE_DIR}/build_profile.py"
|
||||
"${BUILD_PROFILE}"
|
||||
"${INPUT_JSON}"
|
||||
"${OUTPUT_JSON}"
|
||||
WORKING_DIRECTORY ${godot-cpp_SOURCE_DIR}
|
||||
)
|
||||
endfunction( )
|
||||
|
||||
|
||||
#[[ Generate File List
|
||||
|
||||
Use the binding_generator.py Python script to determine the list of files that
|
||||
will be passed to the code generator using extension_api.json.
|
||||
NOTE: This happens for every configure.]]
|
||||
function( binding_generator_get_file_list OUT_VAR_NAME API_FILEPATH OUTPUT_DIR )
|
||||
|
||||
# This code snippet will be squashed into a single line
|
||||
# The two strings make this a list, in CMake lists are semicolon delimited strings.
|
||||
set( PYTHON_SCRIPT
|
||||
"from binding_generator import print_file_list"
|
||||
"print_file_list( api_filepath='${API_FILEPATH}',
|
||||
output_dir='${OUTPUT_DIR}',
|
||||
headers=True,
|
||||
sources=True)")
|
||||
message( DEBUG "Python:\n${PYTHON_SCRIPT}" )
|
||||
|
||||
# Strip newlines and whitespace to make it a one-liner.
|
||||
string( REGEX REPLACE "\n *" " " PYTHON_SCRIPT "${PYTHON_SCRIPT}" )
|
||||
|
||||
execute_process( COMMAND "${Python3_EXECUTABLE}" "-c" "${PYTHON_SCRIPT}"
|
||||
WORKING_DIRECTORY "${godot-cpp_SOURCE_DIR}"
|
||||
OUTPUT_VARIABLE GENERATED_FILES_LIST
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
# Debug output
|
||||
message( DEBUG "FileList-Begin" )
|
||||
foreach( PATH ${GENERATED_FILES_LIST} )
|
||||
message( DEBUG ${PATH} )
|
||||
endforeach()
|
||||
|
||||
# Error out if the file list generator returned no files.
|
||||
list( LENGTH GENERATED_FILES_LIST LIST_LENGTH )
|
||||
if( NOT LIST_LENGTH GREATER 0 )
|
||||
message( FATAL_ERROR "File List Generation Failed")
|
||||
endif()
|
||||
message( STATUS "There are ${LIST_LENGTH} Files to generate" )
|
||||
|
||||
set( ${OUT_VAR_NAME} ${GENERATED_FILES_LIST} PARENT_SCOPE )
|
||||
endfunction( )
|
||||
|
||||
|
||||
#[[ Generate Bindings
|
||||
|
||||
Using the generated file list, use the binding_generator.py to generate the
|
||||
godot-cpp bindings. This will run at build time only if there are files
|
||||
missing. ]]
|
||||
function( binding_generator_generate_bindings API_FILE USE_TEMPLATE_GET_NODE, BITS, PRECISION, OUTPUT_DIR )
|
||||
# This code snippet will be squashed into a single line
|
||||
set( PYTHON_SCRIPT
|
||||
"from binding_generator import generate_bindings"
|
||||
"generate_bindings(
|
||||
api_filepath='${API_FILE}',
|
||||
use_template_get_node='${USE_TEMPLATE_GET_NODE}',
|
||||
bits='${BITS}',
|
||||
precision='${PRECISION}',
|
||||
output_dir='${OUTPUT_DIR}')")
|
||||
|
||||
message( DEBUG "Python:\n${PYTHON_SCRIPT}" )
|
||||
|
||||
# Strip newlines and whitespace to make it a one-liner.
|
||||
string( REGEX REPLACE "\n *" " " PYTHON_SCRIPT "${PYTHON_SCRIPT}" )
|
||||
|
||||
add_custom_command(OUTPUT ${GENERATED_FILES_LIST}
|
||||
COMMAND "${Python3_EXECUTABLE}" "-c" "${PYTHON_SCRIPT}"
|
||||
VERBATIM
|
||||
WORKING_DIRECTORY ${godot-cpp_SOURCE_DIR}
|
||||
MAIN_DEPENDENCY ${GODOTCPP_GDEXTENSION_API_FILE}
|
||||
DEPENDS ${godot-cpp_SOURCE_DIR}/binding_generator.py
|
||||
COMMENT "Generating bindings"
|
||||
)
|
||||
endfunction( )
|
||||
|
||||
#[[ Generate doc_data.cpp
|
||||
The documentation displayed in the Godot editor is compiled into the extension.
|
||||
It takes a list of XML source files, and transforms them into a cpp file that
|
||||
is added to the sources list.]]
|
||||
function( generate_doc_source OUTPUT_PATH SOURCES )
|
||||
# Transform SOURCES CMake LIST
|
||||
# quote each path with ''
|
||||
# join with , to transform into a python list minus the surrounding []
|
||||
set( PYTHON_LIST "${SOURCES}")
|
||||
list( TRANSFORM PYTHON_LIST REPLACE "(.*\.xml)" "'\\1'" )
|
||||
list( JOIN PYTHON_LIST "," PYTHON_LIST )
|
||||
|
||||
get_filename_component(OUTPUT_DIR "${OUTPUT_PATH}" DIRECTORY)
|
||||
file(MAKE_DIRECTORY ${OUTPUT_DIR} )
|
||||
|
||||
# Python one-liner to run our command
|
||||
# lists in CMake are just strings delimited by ';', so this works.
|
||||
set( PYTHON_SCRIPT "from doc_source_generator import generate_doc_source"
|
||||
"generate_doc_source( '${OUTPUT_PATH}', [${PYTHON_LIST}] )" )
|
||||
|
||||
add_custom_command( OUTPUT "${OUTPUT_PATH}"
|
||||
COMMAND "${Python3_EXECUTABLE}" "-c" "${PYTHON_SCRIPT}"
|
||||
VERBATIM
|
||||
WORKING_DIRECTORY "${godot-cpp_SOURCE_DIR}"
|
||||
DEPENDS
|
||||
"${godot-cpp_SOURCE_DIR}/doc_source_generator.py"
|
||||
"${SOURCES}"
|
||||
COMMENT "Generating: ${OUTPUT_PATH}"
|
||||
)
|
||||
endfunction()
|
||||
|
||||
#[[ target_doc_sources
|
||||
A simpler interface to add xml files as doc source to a output target.
|
||||
TARGET: The gdexension library target
|
||||
SOURCES: a list of xml files to use for source generation and inclusion.
|
||||
This function also adds a doc_gen target to test source generation.]]
|
||||
function( target_doc_sources TARGET SOURCES )
|
||||
# set the generated file name
|
||||
set( DOC_SOURCE_FILE "${CMAKE_CURRENT_BINARY_DIR}/gen/doc_source.cpp" )
|
||||
|
||||
# Create the file generation target, this won't be triggered unless a target
|
||||
# that depends on DOC_SOURCE_FILE is built
|
||||
generate_doc_source( "${DOC_SOURCE_FILE}" ${SOURCES} )
|
||||
|
||||
# Add DOC_SOURCE_FILE as a dependency to TARGET
|
||||
target_sources( ${TARGET} PRIVATE "${DOC_SOURCE_FILE}" )
|
||||
|
||||
# Create a dummy target that depends on the source so that users can
|
||||
# test the file generation task.
|
||||
if( TARGET doc_gen )
|
||||
else()
|
||||
add_custom_target( doc_gen )
|
||||
endif()
|
||||
target_sources( doc_gen PRIVATE "${DOC_SOURCE_FILE}" )
|
||||
endfunction()
|
||||
40
cmake/android.cmake
Normal file
40
cmake/android.cmake
Normal file
@@ -0,0 +1,40 @@
|
||||
#[=======================================================================[.rst:
|
||||
Android
|
||||
-------
|
||||
|
||||
This file contains functions for options and configuration for targeting the
|
||||
Android platform
|
||||
|
||||
Configuration of the Android toolchain is done using toolchain files,
|
||||
CMakePresets, or variables on the command line.
|
||||
|
||||
The `Android SDK`_ provides toolchain files to help with configuration.
|
||||
|
||||
CMake has its own `built-in support`_ for cross compiling to the
|
||||
Android platforms.
|
||||
|
||||
.. warning::
|
||||
|
||||
Android does not support or test the CMake built-in workflow, recommend
|
||||
using their toolchain file.
|
||||
|
||||
.. _Android SDK:https://developer.android.com/ndk/guides/cmake
|
||||
|
||||
.. _built-in support:https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling-for-android
|
||||
|
||||
There is further information and examples in the doc/cmake.rst file.
|
||||
|
||||
]=======================================================================]
|
||||
function( android_options )
|
||||
# Android Options
|
||||
endfunction()
|
||||
|
||||
function( android_generate )
|
||||
target_compile_definitions(${TARGET_NAME}
|
||||
PUBLIC
|
||||
ANDROID_ENABLED
|
||||
UNIX_ENABLED
|
||||
)
|
||||
|
||||
common_compiler_flags()
|
||||
endfunction()
|
||||
@@ -1,94 +1,177 @@
|
||||
# Add warnings based on compiler & version
|
||||
# Set some helper variables for readability
|
||||
set( compiler_less_than_v8 "$<VERSION_LESS:$<CXX_COMPILER_VERSION>,8>" )
|
||||
set( compiler_greater_than_or_equal_v9 "$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,9>" )
|
||||
set( compiler_greater_than_or_equal_v11 "$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,11>" )
|
||||
set( compiler_less_than_v11 "$<VERSION_LESS:$<CXX_COMPILER_VERSION>,11>" )
|
||||
set( compiler_greater_than_or_equal_v12 "$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,12>" )
|
||||
#[=======================================================================[.rst:
|
||||
Common Compiler Flags
|
||||
---------------------
|
||||
|
||||
# These compiler options reflect what is in godot/SConstruct.
|
||||
target_compile_options( ${PROJECT_NAME} PRIVATE
|
||||
# MSVC only
|
||||
$<${compiler_is_msvc}:
|
||||
/W4
|
||||
This file contains host platform toolchain and target platform agnostic
|
||||
configuration. It includes flags like optimization levels, warnings, and
|
||||
features. For target platform specific flags look to each of the
|
||||
``cmake/<platform>.cmake`` files.
|
||||
|
||||
# Disable warnings which we don't plan to fix.
|
||||
/wd4100 # C4100 (unreferenced formal parameter): Doesn't play nice with polymorphism.
|
||||
/wd4127 # C4127 (conditional expression is constant)
|
||||
/wd4201 # C4201 (non-standard nameless struct/union): Only relevant for C89.
|
||||
/wd4244 # C4244 C4245 C4267 (narrowing conversions): Unavoidable at this scale.
|
||||
/wd4245
|
||||
/wd4267
|
||||
/wd4305 # C4305 (truncation): double to float or real_t, too hard to avoid.
|
||||
/wd4514 # C4514 (unreferenced inline function has been removed)
|
||||
/wd4714 # C4714 (function marked as __forceinline not inlined)
|
||||
/wd4820 # C4820 (padding added after construct)
|
||||
>
|
||||
]=======================================================================]
|
||||
|
||||
# Clang and GNU common options
|
||||
$<$<OR:${compiler_is_clang},${compiler_is_gnu}>:
|
||||
-Wall
|
||||
-Wctor-dtor-privacy
|
||||
-Wextra
|
||||
-Wno-unused-parameter
|
||||
-Wnon-virtual-dtor
|
||||
-Wwrite-strings
|
||||
>
|
||||
#[[ Compiler Configuration, not to be confused with build targets ]]
|
||||
set( DEBUG_SYMBOLS "$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>" )
|
||||
|
||||
# Clang only
|
||||
$<${compiler_is_clang}:
|
||||
-Wimplicit-fallthrough
|
||||
-Wno-ordered-compare-function-pointers
|
||||
>
|
||||
#[[ Compiler Identification ]]
|
||||
set( IS_CLANG "$<CXX_COMPILER_ID:Clang>" )
|
||||
set( IS_APPLECLANG "$<CXX_COMPILER_ID:AppleClang>" )
|
||||
set( IS_GNU "$<CXX_COMPILER_ID:GNU>" )
|
||||
set( IS_MSVC "$<CXX_COMPILER_ID:MSVC>" )
|
||||
set( NOT_MSVC "$<NOT:$<CXX_COMPILER_ID:MSVC>>" )
|
||||
|
||||
# GNU only
|
||||
$<${compiler_is_gnu}:
|
||||
-Walloc-zero
|
||||
-Wduplicated-branches
|
||||
-Wduplicated-cond
|
||||
-Wno-misleading-indentation
|
||||
-Wplacement-new=1
|
||||
-Wshadow-local
|
||||
-Wstringop-overflow=4
|
||||
>
|
||||
$<$<AND:${compiler_is_gnu},${compiler_less_than_v8}>:
|
||||
# Bogus warning fixed in 8+.
|
||||
-Wno-strict-overflow
|
||||
>
|
||||
$<$<AND:${compiler_is_gnu},${compiler_greater_than_or_equal_v9}>:
|
||||
-Wattribute-alias=2
|
||||
>
|
||||
$<$<AND:${compiler_is_gnu},${compiler_greater_than_or_equal_v11}>:
|
||||
# Broke on MethodBind templates before GCC 11.
|
||||
-Wlogical-op
|
||||
>
|
||||
$<$<AND:${compiler_is_gnu},${compiler_less_than_v11}>:
|
||||
# Regression in GCC 9/10, spams so much in our variadic templates that we need to outright disable it.
|
||||
-Wno-type-limits
|
||||
>
|
||||
$<$<AND:${compiler_is_gnu},${compiler_greater_than_or_equal_v12}>:
|
||||
# False positives in our error macros, see GH-58747.
|
||||
-Wno-return-type
|
||||
>
|
||||
)
|
||||
set( GNU_LT_V8 "$<VERSION_LESS:$<CXX_COMPILER_VERSION>,8>" )
|
||||
set( GNU_GE_V9 "$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,9>" )
|
||||
set( GNU_GT_V11 "$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,11>" )
|
||||
set( GNU_LT_V11 "$<VERSION_LESS:$<CXX_COMPILER_VERSION>,11>" )
|
||||
set( GNU_GE_V12 "$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,12>" )
|
||||
|
||||
#[[ Check for clang-cl with MSVC frontend
|
||||
The compiler is tested and set when the project command is called.
|
||||
The variable CXX_COMPILER_FRONTEND_VARIANT was introduced in 3.14
|
||||
The generator expression $<CXX_COMPILER_FRONTEND_VARIANT> wasn't introduced
|
||||
until CMake 3.30 so we can't use it yet.
|
||||
|
||||
So to support clang downloaded from llvm.org which uses the MSVC frontend
|
||||
by default, we need to test for it. ]]
|
||||
function( compiler_detection )
|
||||
if( ${CMAKE_CXX_COMPILER_ID} STREQUAL Clang )
|
||||
if( ${CMAKE_CXX_COMPILER_FRONTEND_VARIANT} STREQUAL MSVC )
|
||||
message( "Using clang-cl" )
|
||||
set( IS_CLANG "0" PARENT_SCOPE )
|
||||
set( IS_MSVC "1" PARENT_SCOPE )
|
||||
set( NOT_MSVC "0" PARENT_SCOPE )
|
||||
endif ()
|
||||
endif ()
|
||||
endfunction( )
|
||||
|
||||
function( common_compiler_flags )
|
||||
|
||||
target_compile_features(${TARGET_NAME}
|
||||
PUBLIC
|
||||
cxx_std_17
|
||||
)
|
||||
|
||||
# These compiler options reflect what is in godot/SConstruct.
|
||||
target_compile_options( ${TARGET_NAME}
|
||||
PUBLIC
|
||||
# Disable exception handling. Godot doesn't use exceptions anywhere, and this
|
||||
# saves around 20% of binary size and very significant build time.
|
||||
$<${DISABLE_EXCEPTIONS}:
|
||||
$<${NOT_MSVC}:-fno-exceptions>
|
||||
>
|
||||
|
||||
# Enabling Debug Symbols
|
||||
$<${DEBUG_SYMBOLS}:
|
||||
# Adding dwarf-4 explicitly makes stacktraces work with clang builds,
|
||||
# otherwise addr2line doesn't understand them.
|
||||
$<${NOT_MSVC}:
|
||||
-gdwarf-4
|
||||
$<IF:${IS_DEV_BUILD},-g3,-g2>
|
||||
>
|
||||
>
|
||||
|
||||
$<${IS_DEV_BUILD}:
|
||||
$<${NOT_MSVC}:-fno-omit-frame-pointer -O0>
|
||||
>
|
||||
|
||||
$<${HOT_RELOAD}:
|
||||
$<${IS_GNU}:-fno-gnu-unique>
|
||||
>
|
||||
|
||||
# MSVC only
|
||||
$<${IS_MSVC}:
|
||||
# /MP isn't valid for clang-cl with msvc frontend
|
||||
$<$<CXX_COMPILER_ID:MSVC>:/MP${PROC_N}>
|
||||
/W4
|
||||
|
||||
# Disable warnings which we don't plan to fix.
|
||||
/wd4100 # C4100 (unreferenced formal parameter): Doesn't play nice with polymorphism.
|
||||
/wd4127 # C4127 (conditional expression is constant)
|
||||
/wd4201 # C4201 (non-standard nameless struct/union): Only relevant for C89.
|
||||
/wd4244 # C4244 C4245 C4267 (narrowing conversions): Unavoidable at this scale.
|
||||
/wd4245
|
||||
/wd4267
|
||||
/wd4305 # C4305 (truncation): double to float or real_t, too hard to avoid.
|
||||
/wd4514 # C4514 (unreferenced inline function has been removed)
|
||||
/wd4714 # C4714 (function marked as __forceinline not inlined)
|
||||
/wd4820 # C4820 (padding added after construct)
|
||||
|
||||
/utf-8
|
||||
>
|
||||
|
||||
# Clang and GNU common options
|
||||
$<$<OR:${IS_CLANG},${IS_GNU}>:
|
||||
-Wall
|
||||
-Wctor-dtor-privacy
|
||||
-Wextra
|
||||
-Wno-unused-parameter
|
||||
-Wnon-virtual-dtor
|
||||
-Wwrite-strings
|
||||
>
|
||||
|
||||
# Clang only
|
||||
$<${IS_CLANG}:
|
||||
-Wimplicit-fallthrough
|
||||
-Wno-ordered-compare-function-pointers
|
||||
>
|
||||
|
||||
# GNU only
|
||||
$<${IS_GNU}:
|
||||
-Walloc-zero
|
||||
-Wduplicated-branches
|
||||
-Wduplicated-cond
|
||||
-Wno-misleading-indentation
|
||||
-Wplacement-new=1
|
||||
-Wshadow-local
|
||||
-Wstringop-overflow=4
|
||||
|
||||
# Bogus warning fixed in 8+.
|
||||
$<${GNU_LT_V8}:-Wno-strict-overflow>
|
||||
|
||||
$<${GNU_GE_V9}:-Wattribute-alias=2>
|
||||
|
||||
# Broke on MethodBind templates before GCC 11.
|
||||
$<${GNU_GT_V11}:-Wlogical-op>
|
||||
|
||||
# Regression in GCC 9/10, spams so much in our variadic templates that we need to outright disable it.
|
||||
$<${GNU_LT_V11}:-Wno-type-limits>
|
||||
|
||||
# False positives in our error macros, see GH-58747.
|
||||
$<${GNU_GE_V12}:-Wno-return-type>
|
||||
>
|
||||
)
|
||||
|
||||
target_compile_definitions(${TARGET_NAME}
|
||||
PUBLIC
|
||||
GDEXTENSION
|
||||
|
||||
# features
|
||||
$<${DEBUG_FEATURES}:DEBUG_ENABLED DEBUG_METHODS_ENABLED>
|
||||
|
||||
$<${IS_DEV_BUILD}:DEV_ENABLED>
|
||||
|
||||
$<${HOT_RELOAD}:HOT_RELOAD_ENABLED>
|
||||
|
||||
$<$<STREQUAL:${GODOTCPP_PRECISION},double>:REAL_T_IS_DOUBLE>
|
||||
|
||||
$<${IS_MSVC}:$<${DISABLE_EXCEPTIONS}:_HAS_EXCEPTIONS=0>>
|
||||
|
||||
$<${THREADS_ENABLED}:THREADS_ENABLED>
|
||||
)
|
||||
|
||||
target_link_options( ${TARGET_NAME}
|
||||
PUBLIC
|
||||
$<${IS_MSVC}:
|
||||
/WX # treat link warnings as errors.
|
||||
/MANIFEST:NO # We dont need a manifest
|
||||
>
|
||||
|
||||
$<${DEBUG_SYMBOLS}:$<${IS_MSVC}:/DEBUG:FULL>>
|
||||
$<$<NOT:${DEBUG_SYMBOLS}>:
|
||||
$<${IS_GNU}:-s>
|
||||
$<${IS_CLANG}:-s>
|
||||
$<${IS_APPLECLANG}:-Wl,-S -Wl,-x -Wl,-dead_strip>
|
||||
>
|
||||
)
|
||||
|
||||
# Treat warnings as errors
|
||||
function( set_warning_as_error )
|
||||
message( STATUS "[${PROJECT_NAME}] Treating warnings as errors")
|
||||
if ( CMAKE_VERSION VERSION_GREATER_EQUAL "3.24" )
|
||||
set_target_properties( ${PROJECT_NAME}
|
||||
PROPERTIES
|
||||
COMPILE_WARNING_AS_ERROR ON
|
||||
)
|
||||
else()
|
||||
target_compile_options( ${PROJECT_NAME}
|
||||
PRIVATE
|
||||
$<${compiler_is_msvc}:/WX>
|
||||
$<$<OR:${compiler_is_clang},${compiler_is_gnu}>:-Werror>
|
||||
)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
if ( GODOT_WARNING_AS_ERROR )
|
||||
set_warning_as_error()
|
||||
endif()
|
||||
|
||||
40
cmake/emsdkHack.cmake
Normal file
40
cmake/emsdkHack.cmake
Normal file
@@ -0,0 +1,40 @@
|
||||
#[=======================================================================[.rst:
|
||||
emsdkHack
|
||||
---------
|
||||
|
||||
The Emscripten platform doesn't support the use of shared libraries as known by cmake.
|
||||
|
||||
* https://github.com/emscripten-core/emscripten/issues/15276
|
||||
* https://github.com/emscripten-core/emscripten/issues/17804
|
||||
|
||||
This workaround only works due to the way the cmake scripts are loaded.
|
||||
|
||||
Prior to the use of ``project( ... )`` directive we need to set
|
||||
``CMAKE_PROJECT_INCLUDE=cmake/emscripten.cmake``.
|
||||
This file will be loaded after the toolchain overriding the settings that
|
||||
prevent shared library building.
|
||||
|
||||
CMAKE_PROJECT_INCLUDE was Added in version 3.15.
|
||||
``CMAKE_PROJECT_<projectName>_INCLUDE`` was Added in version 3.17:
|
||||
|
||||
More information on cmake's `code injection`_
|
||||
|
||||
.. _code injection:https://cmake.org/cmake/help/latest/command/project.html#code-injection
|
||||
|
||||
Overwrite Shared Library Properties to allow shared libs to be generated.
|
||||
]=======================================================================]
|
||||
if( EMSCRIPTEN )
|
||||
set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE)
|
||||
set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-sSIDE_MODULE=1")
|
||||
set(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS "-sSIDE_MODULE=1")
|
||||
set(CMAKE_SHARED_LIBRARY_SUFFIX) # remove the suffix from the shared lib
|
||||
set(CMAKE_STRIP FALSE) # used by default in pybind11 on .so modules
|
||||
|
||||
# The Emscripten toolchain sets the default value for EMSCRIPTEN_SYSTEM_PROCESSOR to x86
|
||||
# and CMAKE_SYSTEM_PROCESSOR to this value. I don't want that.
|
||||
set(CMAKE_SYSTEM_PROCESSOR "wasm32" )
|
||||
# the above prevents the need for logic like:
|
||||
#if( ${CMAKE_SYSTEM_NAME} STREQUAL Emscripten )
|
||||
# set( SYSTEM_ARCH wasm32 )
|
||||
#endif ()
|
||||
endif ()
|
||||
@@ -1,240 +1,373 @@
|
||||
function( godotcpp_options )
|
||||
#[=======================================================================[.rst:
|
||||
godotcpp.cmake
|
||||
--------------
|
||||
|
||||
#TODO platform
|
||||
#TODO target
|
||||
As godot-cpp is a C++ project, there are no C files, and detection of a C
|
||||
compiler is unnecessary. When CMake performs the configure process, if a
|
||||
C compiler is specified, like in a toolchain, or from an IDE, then it will
|
||||
print a warning stating that the CMAKE_C_COMPILER compiler is unused.
|
||||
This if statement simply silences that warning.
|
||||
]=======================================================================]
|
||||
if( CMAKE_C_COMPILER )
|
||||
endif ()
|
||||
|
||||
#[=======================================================================[.rst:
|
||||
Include Platform Files
|
||||
----------------------
|
||||
|
||||
Because these files are included into the top level CMakelists.txt before the
|
||||
project directive, it means that
|
||||
|
||||
* ``CMAKE_CURRENT_SOURCE_DIR`` is the location of godot-cpp's CMakeLists.txt
|
||||
* ``CMAKE_SOURCE_DIR`` is the location where any prior ``project(...)``
|
||||
directive was
|
||||
|
||||
]=======================================================================]
|
||||
include( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/GodotCPPModule.cmake)
|
||||
include( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/common_compiler_flags.cmake)
|
||||
include( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/android.cmake)
|
||||
include( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/ios.cmake)
|
||||
include( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/linux.cmake)
|
||||
include( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos.cmake)
|
||||
include( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/web.cmake)
|
||||
include( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/windows.cmake)
|
||||
|
||||
|
||||
# Detect number of processors
|
||||
include(ProcessorCount)
|
||||
ProcessorCount(PROC_MAX)
|
||||
message( "Auto-detected ${PROC_MAX} CPU cores available for build parallelism." )
|
||||
|
||||
# List of known platforms
|
||||
set( PLATFORM_LIST linux macos windows android ios web )
|
||||
|
||||
# List of known architectures
|
||||
set( ARCH_LIST x86_32 x86_64 arm32 arm64 rv64 ppc32 ppc64 wasm32 )
|
||||
|
||||
# Function to map processors to known architectures
|
||||
function( godot_arch_name OUTVAR )
|
||||
|
||||
# Special case for macos universal builds that target both x86_64 and arm64
|
||||
if( DEFINED CMAKE_OSX_ARCHITECTURES)
|
||||
if( "x86_64" IN_LIST CMAKE_OSX_ARCHITECTURES AND "arm64" IN_LIST CMAKE_OSX_ARCHITECTURES)
|
||||
set(${OUTVAR} "universal" PARENT_SCOPE )
|
||||
return()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Direct match early out.
|
||||
string( TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" ARCH )
|
||||
if( ARCH IN_LIST ARCH_LIST )
|
||||
set( ${OUTVAR} "${ARCH}" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Known aliases
|
||||
set( x86_64 "w64;amd64;x86-64" )
|
||||
set( arm32 "armv7;armv7-a" )
|
||||
set( arm64 "armv8;arm64v8;aarch64;armv8-a" )
|
||||
set( rv64 "rv;riscv;riscv64" )
|
||||
set( ppc32 "ppcle;ppc" )
|
||||
set( ppc64 "ppc64le" )
|
||||
|
||||
if( ARCH IN_LIST x86_64 )
|
||||
set(${OUTVAR} "x86_64" PARENT_SCOPE )
|
||||
|
||||
elseif( ARCH IN_LIST arm32 )
|
||||
set(${OUTVAR} "arm32" PARENT_SCOPE )
|
||||
|
||||
elseif( ARCH IN_LIST arm64 )
|
||||
set(${OUTVAR} "arm64" PARENT_SCOPE )
|
||||
|
||||
elseif( ARCH IN_LIST rv64 )
|
||||
set(${OUTVAR} "rv64" PARENT_SCOPE )
|
||||
|
||||
elseif( ARCH IN_LIST ppc32 )
|
||||
set(${OUTVAR} "ppc32" PARENT_SCOPE )
|
||||
|
||||
elseif( ARCH IN_LIST ppc64 )
|
||||
set(${OUTVAR} "ppc64" PARENT_SCOPE )
|
||||
|
||||
elseif( ARCH MATCHES "86")
|
||||
# Catches x86, i386, i486, i586, i686, etc.
|
||||
set(${OUTVAR} "x86_32" PARENT_SCOPE )
|
||||
|
||||
else()
|
||||
# Default value is whatever the processor is.
|
||||
set(${OUTVAR} ${CMAKE_SYSTEM_PROCESSOR} PARENT_SCOPE )
|
||||
endif ()
|
||||
endfunction()
|
||||
|
||||
# Function to define all the options.
|
||||
function( godotcpp_options )
|
||||
#NOTE: platform is managed using toolchain files.
|
||||
#NOTE: arch is managed by using toolchain files.
|
||||
# Except for macos universal, which can be set by GODOTCPP_MACOS_UNIVERSAL=YES
|
||||
|
||||
# Input from user for GDExtension interface header and the API JSON file
|
||||
set(GODOT_GDEXTENSION_DIR "gdextension" CACHE PATH
|
||||
set( GODOTCPP_GDEXTENSION_DIR "gdextension" CACHE PATH
|
||||
"Path to a custom directory containing GDExtension interface header and API JSON file ( /path/to/gdextension_dir )" )
|
||||
set(GODOT_CUSTOM_API_FILE "" CACHE FILEPATH
|
||||
"Path to a custom GDExtension API JSON file (takes precedence over `gdextension_dir`) ( /path/to/custom_api_file )")
|
||||
set( GODOTCPP_CUSTOM_API_FILE "" CACHE FILEPATH
|
||||
"Path to a custom GDExtension API JSON file (takes precedence over `GODOTCPP_GDEXTENSION_DIR`) ( /path/to/custom_api_file )")
|
||||
|
||||
#TODO generate_bindings
|
||||
|
||||
option(GODOT_GENERATE_TEMPLATE_GET_NODE
|
||||
option( GODOTCPP_GENERATE_TEMPLATE_GET_NODE
|
||||
"Generate a template version of the Node class's get_node. (ON|OFF)" ON)
|
||||
|
||||
#TODO build_library
|
||||
|
||||
set(GODOT_PRECISION "single" CACHE STRING
|
||||
set( GODOTCPP_PRECISION "single" CACHE STRING
|
||||
"Set the floating-point precision level (single|double)")
|
||||
|
||||
#TODO arch
|
||||
#TODO threads
|
||||
set( GODOTCPP_THREADS ON CACHE BOOL "Enable threading support" )
|
||||
|
||||
#TODO compiledb
|
||||
#TODO compiledb_file
|
||||
#TODO build_profile aka cmake preset
|
||||
|
||||
set(GODOT_USE_HOT_RELOAD "" CACHE BOOL
|
||||
set( GODOTCPP_BUILD_PROFILE "" CACHE PATH
|
||||
"Path to a file containing a feature build profile" )
|
||||
|
||||
set( GODOTCPP_USE_HOT_RELOAD "" CACHE BOOL
|
||||
"Enable the extra accounting required to support hot reload. (ON|OFF)")
|
||||
|
||||
option(GODOT_DISABLE_EXCEPTIONS "Force disabling exception handling code (ON|OFF)" ON )
|
||||
|
||||
set( GODOT_SYMBOL_VISIBILITY "hidden" CACHE STRING
|
||||
"Symbols visibility on GNU platforms. Use 'auto' to apply the default value. (auto|visible|hidden)")
|
||||
set_property( CACHE GODOT_SYMBOL_VISIBILITY PROPERTY STRINGS "auto;visible;hidden" )
|
||||
|
||||
#TODO optimize
|
||||
#TODO debug_symbols
|
||||
#TODO dev_build
|
||||
|
||||
# FIXME These options are not present in SCons, and perhaps should be added there.
|
||||
option(GODOT_SYSTEM_HEADERS "Expose headers as SYSTEM." ON)
|
||||
option(GODOT_WARNING_AS_ERROR "Treat warnings as errors" OFF)
|
||||
|
||||
# Run options commands on the following to populate cache for all platforms.
|
||||
# This type of thing is typically done conditionally
|
||||
# But as scons shows all options so shall we.
|
||||
#TODO ios_options()
|
||||
#TODO linux_options()
|
||||
#TODO macos_options()
|
||||
#TODO web_options()
|
||||
#TODO windows_options()
|
||||
endfunction()
|
||||
|
||||
|
||||
function( godotcpp_generate )
|
||||
# Set some helper variables for readability
|
||||
set( compiler_is_clang "$<OR:$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:Clang>>" )
|
||||
set( compiler_is_gnu "$<CXX_COMPILER_ID:GNU>" )
|
||||
set( compiler_is_msvc "$<CXX_COMPILER_ID:MSVC>" )
|
||||
|
||||
# CXX_VISIBILITY_PRESET supported values are: default, hidden, protected, and internal
|
||||
# which is inline with the gcc -fvisibility=
|
||||
# https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html
|
||||
# To match the scons options we need to change the text to match the -fvisibility flag
|
||||
# it is probably worth another PR which changes both to use the flag options
|
||||
if( ${GODOT_SYMBOL_VISIBILITY} STREQUAL "auto" OR ${GODOT_SYMBOL_VISIBILITY} STREQUAL "visible" )
|
||||
set( GODOT_SYMBOL_VISIBILITY "default" )
|
||||
endif ()
|
||||
|
||||
# Default build type is Debug in the SConstruct
|
||||
if("${CMAKE_BUILD_TYPE}" STREQUAL "")
|
||||
set(CMAKE_BUILD_TYPE Debug)
|
||||
endif()
|
||||
|
||||
# Hot reload is enabled by default in Debug-builds
|
||||
if( GODOT_USE_HOT_RELOAD STREQUAL "" AND NOT CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
set(GODOT_USE_HOT_RELOAD ON)
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED BITS)
|
||||
set(BITS 32)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(BITS 64)
|
||||
endif(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
endif()
|
||||
|
||||
|
||||
set(GODOT_GDEXTENSION_API_FILE "${GODOT_GDEXTENSION_DIR}/extension_api.json")
|
||||
if (NOT "${GODOT_CUSTOM_API_FILE}" STREQUAL "") # User-defined override.
|
||||
set(GODOT_GDEXTENSION_API_FILE "${GODOT_CUSTOM_API_FILE}")
|
||||
endif()
|
||||
|
||||
if ("${GODOT_PRECISION}" STREQUAL "double")
|
||||
add_definitions(-DREAL_T_IS_DOUBLE)
|
||||
endif()
|
||||
|
||||
set( GODOT_COMPILE_FLAGS )
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||
# using Visual Studio C++
|
||||
set(GODOT_COMPILE_FLAGS "/utf-8") # /GF /MP
|
||||
|
||||
if(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /MDd") # /Od /RTC1 /Zi
|
||||
else()
|
||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /MD /O2") # /Oy /GL /Gy
|
||||
endif(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
|
||||
add_definitions(-DNOMINMAX)
|
||||
else() # GCC/Clang
|
||||
if(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -fno-omit-frame-pointer -O0 -g")
|
||||
else()
|
||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -O3")
|
||||
endif(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
endif()
|
||||
|
||||
# Disable exception handling. Godot doesn't use exceptions anywhere, and this
|
||||
# saves around 20% of binary size and very significant build time (GH-80513).
|
||||
if (GODOT_DISABLE_EXCEPTIONS)
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -D_HAS_EXCEPTIONS=0")
|
||||
else()
|
||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -fno-exceptions")
|
||||
endif()
|
||||
else()
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /EHsc")
|
||||
endif()
|
||||
endif()
|
||||
option( GODOTCPP_DISABLE_EXCEPTIONS "Force disabling exception handling code (ON|OFF)" ON )
|
||||
|
||||
# Generate source from the bindings file
|
||||
find_package(Python3 3.4 REQUIRED) # pathlib should be present
|
||||
if(GODOT_GENERATE_TEMPLATE_GET_NODE)
|
||||
set(GENERATE_BINDING_PARAMETERS "True")
|
||||
else()
|
||||
set(GENERATE_BINDING_PARAMETERS "False")
|
||||
endif()
|
||||
set( GODOTCPP_SYMBOL_VISIBILITY "hidden" CACHE STRING
|
||||
"Symbols visibility on GNU platforms. Use 'auto' to apply the default value. (auto|visible|hidden)")
|
||||
set_property( CACHE GODOTCPP_SYMBOL_VISIBILITY PROPERTY STRINGS "auto;visible;hidden" )
|
||||
|
||||
execute_process(COMMAND "${Python3_EXECUTABLE}" "-c" "import binding_generator; binding_generator.print_file_list(\"${GODOT_GDEXTENSION_API_FILE}\", \"${CMAKE_CURRENT_BINARY_DIR}\", headers=True, sources=True)"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE GENERATED_FILES_LIST
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
#TODO optimize
|
||||
|
||||
add_custom_command(OUTPUT ${GENERATED_FILES_LIST}
|
||||
COMMAND "${Python3_EXECUTABLE}" "-c" "import binding_generator; binding_generator.generate_bindings(\"${GODOT_GDEXTENSION_API_FILE}\", \"${GENERATE_BINDING_PARAMETERS}\", \"${BITS}\", \"${GODOT_PRECISION}\", \"${CMAKE_CURRENT_BINARY_DIR}\")"
|
||||
VERBATIM
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
MAIN_DEPENDENCY ${GODOT_GDEXTENSION_API_FILE}
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/binding_generator.py
|
||||
COMMENT "Generating bindings"
|
||||
)
|
||||
option( GODOTCPP_DEV_BUILD "Developer build with dev-only debugging code (DEV_ENABLED)" OFF )
|
||||
|
||||
# Get Sources
|
||||
# As this cmake file was added using 'include(godotcpp)' from the root CMakeLists.txt,
|
||||
# the ${CMAKE_CURRENT_SOURCE_DIR} is still the root dir.
|
||||
file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS src/*.c**)
|
||||
file(GLOB_RECURSE HEADERS CONFIGURE_DEPENDS include/*.h**)
|
||||
#[[ debug_symbols
|
||||
Debug symbols are enabled by using the Debug or RelWithDebInfo build configurations.
|
||||
Single Config Generator is set at configure time
|
||||
|
||||
# Define our godot-cpp library
|
||||
add_library(${PROJECT_NAME} STATIC
|
||||
${SOURCES}
|
||||
${HEADERS}
|
||||
${GENERATED_FILES_LIST}
|
||||
)
|
||||
add_library(godot::cpp ALIAS ${PROJECT_NAME})
|
||||
cmake ../ -DCMAKE_BUILD_TYPE=Debug
|
||||
|
||||
include(${PROJECT_SOURCE_DIR}/cmake/common_compiler_flags.cmake)
|
||||
Multi-Config Generator is set at build time
|
||||
|
||||
target_compile_features(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
cxx_std_17
|
||||
)
|
||||
cmake --build . --config Debug
|
||||
|
||||
if(GODOT_USE_HOT_RELOAD)
|
||||
target_compile_definitions(${PROJECT_NAME} PUBLIC HOT_RELOAD_ENABLED)
|
||||
target_compile_options(${PROJECT_NAME} PUBLIC $<${compiler_is_gnu}:-fno-gnu-unique>)
|
||||
endif()
|
||||
]]
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME} PUBLIC
|
||||
$<$<CONFIG:Debug>:
|
||||
DEBUG_ENABLED
|
||||
DEBUG_METHODS_ENABLED
|
||||
>
|
||||
$<${compiler_is_msvc}:
|
||||
TYPED_METHOD_BIND
|
||||
>
|
||||
)
|
||||
# FIXME These options are not present in SCons, and perhaps should be added there.
|
||||
option( GODOTCPP_SYSTEM_HEADERS "Expose headers as SYSTEM." OFF )
|
||||
option( GODOTCPP_WARNING_AS_ERROR "Treat warnings as errors" OFF )
|
||||
|
||||
target_link_options(${PROJECT_NAME} PRIVATE
|
||||
$<$<NOT:${compiler_is_msvc}>:
|
||||
-static-libgcc
|
||||
-static-libstdc++
|
||||
-Wl,-R,'$$ORIGIN'
|
||||
>
|
||||
)
|
||||
# Enable Testing
|
||||
option( GODOTCPP_ENABLE_TESTING "Enable the godot-cpp.test.<target> integration testing targets" OFF )
|
||||
|
||||
# Optionally mark headers as SYSTEM
|
||||
set(GODOT_SYSTEM_HEADERS_ATTRIBUTE "")
|
||||
if (GODOT_SYSTEM_HEADERS)
|
||||
set(GODOT_SYSTEM_HEADERS_ATTRIBUTE SYSTEM)
|
||||
#[[ Target Platform Options ]]
|
||||
android_options()
|
||||
ios_options()
|
||||
linux_options()
|
||||
macos_options()
|
||||
web_options()
|
||||
windows_options()
|
||||
endfunction()
|
||||
|
||||
# Function to configure and generate the targets
|
||||
function( godotcpp_generate )
|
||||
#[[ Multi-Threaded MSVC Compilation
|
||||
When using the MSVC compiler the build command -j <n> only specifies
|
||||
parallel jobs or targets, and not multi-threaded compilation To speed up
|
||||
compile times on msvc, the /MP <n> flag can be set. But we need to set it
|
||||
at configure time.
|
||||
|
||||
MSVC is true when the compiler is some version of Microsoft Visual C++ or
|
||||
another compiler simulating the Visual C++ cl command-line syntax. ]]
|
||||
if( MSVC )
|
||||
math( EXPR PROC_N "(${PROC_MAX}-1) | (${X}-2)>>31 & 1" )
|
||||
message( "Using ${PROC_N} cores for multi-threaded compilation.")
|
||||
# TODO You can override it at configure time with ...." )
|
||||
else ()
|
||||
message( "Using ${CMAKE_BUILD_PARALLEL_LEVEL} cores, You can override"
|
||||
" it at configure time by using -j <n> or --parallel <n> on the build"
|
||||
" command.")
|
||||
message( " eg. cmake --build . -j 7 ...")
|
||||
endif ()
|
||||
|
||||
target_include_directories(${PROJECT_NAME} ${GODOT_SYSTEM_HEADERS_ATTRIBUTE} PUBLIC
|
||||
include
|
||||
${CMAKE_CURRENT_BINARY_DIR}/gen/include
|
||||
${GODOT_GDEXTENSION_DIR}
|
||||
)
|
||||
#[[ GODOTCPP_SYMBOL_VISIBLITY
|
||||
To match the SCons options, the allowed values are "auto", "visible", and "hidden"
|
||||
This effects the compiler flag_ -fvisibility=[default|internal|hidden|protected]
|
||||
The corresponding target option CXX_VISIBILITY_PRESET accepts the compiler values.
|
||||
|
||||
# Add the compile flags
|
||||
set_property(TARGET ${PROJECT_NAME} APPEND_STRING PROPERTY COMPILE_FLAGS ${GODOT_COMPILE_FLAGS})
|
||||
TODO: It is probably worth a pull request which changes both to use the compiler values
|
||||
.. _flag:https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#index-fvisibility
|
||||
]]
|
||||
if( ${GODOTCPP_SYMBOL_VISIBILITY} STREQUAL "auto" OR ${GODOTCPP_SYMBOL_VISIBILITY} STREQUAL "visible" )
|
||||
set( GODOTCPP_SYMBOL_VISIBILITY "default" )
|
||||
endif ()
|
||||
|
||||
# Create the correct name (godot.os.build_type.system_bits)
|
||||
string(TOLOWER "${CMAKE_SYSTEM_NAME}" SYSTEM_NAME)
|
||||
string(TOLOWER "${CMAKE_BUILD_TYPE}" BUILD_TYPE)
|
||||
# Setup variable to optionally mark headers as SYSTEM
|
||||
set( GODOTCPP_SYSTEM_HEADERS_ATTRIBUTE "")
|
||||
if( GODOTCPP_SYSTEM_HEADERS)
|
||||
set( GODOTCPP_SYSTEM_HEADERS_ATTRIBUTE SYSTEM)
|
||||
endif ()
|
||||
|
||||
if(ANDROID)
|
||||
# Added the android abi after system name
|
||||
set(SYSTEM_NAME ${SYSTEM_NAME}.${ANDROID_ABI})
|
||||
|
||||
# Android does not have the bits at the end if you look at the main godot repo build
|
||||
set(OUTPUT_NAME "godot-cpp.${SYSTEM_NAME}.${BUILD_TYPE}")
|
||||
else()
|
||||
set(OUTPUT_NAME "godot-cpp.${SYSTEM_NAME}.${BUILD_TYPE}.${BITS}")
|
||||
#[[ Configure Binding Variables ]]
|
||||
# Generate Binding Parameters (True|False)
|
||||
set( USE_TEMPLATE_GET_NODE "False" )
|
||||
if( GODOTCPP_GENERATE_TEMPLATE_GET_NODE )
|
||||
set( USE_TEMPLATE_GET_NODE "True" )
|
||||
endif()
|
||||
|
||||
set_target_properties(${PROJECT_NAME}
|
||||
PROPERTIES
|
||||
CXX_EXTENSIONS OFF
|
||||
POSITION_INDEPENDENT_CODE ON
|
||||
CXX_VISIBILITY_PRESET ${GODOT_SYMBOL_VISIBILITY}
|
||||
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin"
|
||||
OUTPUT_NAME "${OUTPUT_NAME}"
|
||||
# Bits (32|64)
|
||||
math( EXPR BITS "${CMAKE_SIZEOF_VOID_P} * 8" ) # CMAKE_SIZEOF_VOID_P refers to target architecture.
|
||||
|
||||
# API json File
|
||||
set( GODOTCPP_GDEXTENSION_API_FILE "${GODOTCPP_GDEXTENSION_DIR}/extension_api.json")
|
||||
if( GODOTCPP_CUSTOM_API_FILE ) # User-defined override.
|
||||
set( GODOTCPP_GDEXTENSION_API_FILE "${GODOTCPP_CUSTOM_API_FILE}")
|
||||
endif()
|
||||
|
||||
# Build Profile
|
||||
if( GODOTCPP_BUILD_PROFILE )
|
||||
message( STATUS "Using build profile to trim api file")
|
||||
message( "\tBUILD_PROFILE = '${GODOTCPP_BUILD_PROFILE}'")
|
||||
message( "\tAPI_SOURCE = '${GODOTCPP_GDEXTENSION_API_FILE}'")
|
||||
build_profile_generate_trimmed_api(
|
||||
"${GODOTCPP_BUILD_PROFILE}"
|
||||
"${GODOTCPP_GDEXTENSION_API_FILE}"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/extension_api.json" )
|
||||
set( GODOTCPP_GDEXTENSION_API_FILE "${CMAKE_CURRENT_BINARY_DIR}/extension_api.json" )
|
||||
endif()
|
||||
|
||||
message( STATUS "GODOTCPP_GDEXTENSION_API_FILE = '${GODOTCPP_GDEXTENSION_API_FILE}'")
|
||||
|
||||
# generate the file list to use
|
||||
binding_generator_get_file_list( GENERATED_FILES_LIST
|
||||
"${GODOTCPP_GDEXTENSION_API_FILE}"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}" )
|
||||
|
||||
binding_generator_generate_bindings(
|
||||
"${GODOTCPP_GDEXTENSION_API_FILE}"
|
||||
"${USE_TEMPLATE_GET_NODE}"
|
||||
"${BITS}"
|
||||
"${GODOTCPP_PRECISION}"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}" )
|
||||
|
||||
add_custom_target( godot-cpp.generate_bindings DEPENDS ${GENERATED_FILES_LIST} )
|
||||
set_target_properties( godot-cpp.generate_bindings PROPERTIES FOLDER "godot-cpp" )
|
||||
|
||||
### Platform is derived from the toolchain target
|
||||
# See GeneratorExpressions PLATFORM_ID and CMAKE_SYSTEM_NAME
|
||||
string( CONCAT SYSTEM_NAME
|
||||
"$<$<PLATFORM_ID:Android>:android.${ANDROID_ABI}>"
|
||||
"$<$<PLATFORM_ID:iOS>:ios>"
|
||||
"$<$<PLATFORM_ID:Linux>:linux>"
|
||||
"$<$<PLATFORM_ID:Darwin>:macos>"
|
||||
"$<$<PLATFORM_ID:Emscripten>:web>"
|
||||
"$<$<PLATFORM_ID:Windows>:windows>"
|
||||
"$<$<PLATFORM_ID:Msys>:windows>"
|
||||
)
|
||||
|
||||
# Process CPU architecture argument.
|
||||
godot_arch_name( ARCH_NAME )
|
||||
|
||||
# Transform options into generator expressions
|
||||
set( HOT_RELOAD-UNSET "$<STREQUAL:${GODOTCPP_USE_HOT_RELOAD},>")
|
||||
|
||||
set( DISABLE_EXCEPTIONS "$<BOOL:${GODOTCPP_DISABLE_EXCEPTIONS}>")
|
||||
|
||||
set( THREADS_ENABLED "$<BOOL:${GODOTCPP_THREADS}>" )
|
||||
|
||||
# GODOTCPP_DEV_BUILD
|
||||
set( RELEASE_TYPES "Release;MinSizeRel")
|
||||
get_property( IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG )
|
||||
if( IS_MULTI_CONFIG )
|
||||
message( NOTICE "=> Default build type is Debug. For other build types add --config <type> to build command")
|
||||
elseif( GODOTCPP_DEV_BUILD AND CMAKE_BUILD_TYPE IN_LIST RELEASE_TYPES )
|
||||
message( WARNING "=> GODOTCPP_DEV_BUILD implies a Debug-like build but CMAKE_BUILD_TYPE is '${CMAKE_BUILD_TYPE}'")
|
||||
endif ()
|
||||
set( IS_DEV_BUILD "$<BOOL:${GODOTCPP_DEV_BUILD}>")
|
||||
|
||||
### Define our godot-cpp library targets
|
||||
foreach ( TARGET_ALIAS template_debug template_release editor )
|
||||
set( TARGET_NAME "godot-cpp.${TARGET_ALIAS}" )
|
||||
|
||||
# Generator Expressions that rely on the target
|
||||
set( DEBUG_FEATURES "$<NOT:$<STREQUAL:${TARGET_ALIAS},template_release>>" )
|
||||
set( HOT_RELOAD "$<IF:${HOT_RELOAD-UNSET},${DEBUG_FEATURES},$<BOOL:${GODOTCPP_USE_HOT_RELOAD}>>" )
|
||||
|
||||
# Suffix
|
||||
string( CONCAT GODOTCPP_SUFFIX
|
||||
"$<1:.${SYSTEM_NAME}>"
|
||||
"$<1:.${TARGET_ALIAS}>"
|
||||
"$<${IS_DEV_BUILD}:.dev>"
|
||||
"$<$<STREQUAL:${GODOTCPP_PRECISION},double>:.double>"
|
||||
"$<1:.${ARCH_NAME}>"
|
||||
# TODO IOS_SIMULATOR
|
||||
"$<$<NOT:${THREADS_ENABLED}>:.nothreads>"
|
||||
)
|
||||
|
||||
# the godot-cpp.* library targets
|
||||
add_library( ${TARGET_NAME} STATIC EXCLUDE_FROM_ALL )
|
||||
add_library( godot-cpp::${TARGET_ALIAS} ALIAS ${TARGET_NAME} )
|
||||
|
||||
file( GLOB_RECURSE GODOTCPP_SOURCES LIST_DIRECTORIES NO CONFIGURE_DEPENDS src/*.cpp )
|
||||
|
||||
target_sources( ${TARGET_NAME}
|
||||
PRIVATE
|
||||
${GODOTCPP_SOURCES}
|
||||
${GENERATED_FILES_LIST}
|
||||
)
|
||||
|
||||
target_include_directories( ${TARGET_NAME} ${GODOTCPP_SYSTEM_HEADERS_ATTRIBUTE} PUBLIC
|
||||
include
|
||||
${CMAKE_CURRENT_BINARY_DIR}/gen/include
|
||||
${GODOTCPP_GDEXTENSION_DIR}
|
||||
)
|
||||
|
||||
set_target_properties( ${TARGET_NAME}
|
||||
PROPERTIES
|
||||
CXX_STANDARD 17
|
||||
CXX_EXTENSIONS OFF
|
||||
CXX_VISIBILITY_PRESET ${GODOTCPP_SYMBOL_VISIBILITY}
|
||||
|
||||
COMPILE_WARNING_AS_ERROR ${GODOTCPP_WARNING_AS_ERROR}
|
||||
POSITION_INDEPENDENT_CODE ON
|
||||
BUILD_RPATH_USE_ORIGIN ON
|
||||
|
||||
PREFIX "lib"
|
||||
OUTPUT_NAME "${PROJECT_NAME}${GODOTCPP_SUFFIX}"
|
||||
|
||||
ARCHIVE_OUTPUT_DIRECTORY "$<1:${CMAKE_BINARY_DIR}/bin>"
|
||||
|
||||
# Things that are handy to know for dependent targets
|
||||
GODOTCPP_PLATFORM "${SYSTEM_NAME}"
|
||||
GODOTCPP_TARGET "${TARGET_ALIAS}"
|
||||
GODOTCPP_ARCH "${ARCH_NAME}"
|
||||
GODOTCPP_PRECISION "${GODOTCPP_PRECISION}"
|
||||
GODOTCPP_SUFFIX "${GODOTCPP_SUFFIX}"
|
||||
|
||||
# Some IDE's respect this property to logically group targets
|
||||
FOLDER "godot-cpp"
|
||||
)
|
||||
|
||||
if( CMAKE_SYSTEM_NAME STREQUAL Android )
|
||||
android_generate()
|
||||
elseif ( CMAKE_SYSTEM_NAME STREQUAL iOS )
|
||||
ios_generate()
|
||||
elseif ( CMAKE_SYSTEM_NAME STREQUAL Linux )
|
||||
linux_generate()
|
||||
elseif ( CMAKE_SYSTEM_NAME STREQUAL Darwin )
|
||||
macos_generate()
|
||||
elseif ( CMAKE_SYSTEM_NAME STREQUAL Emscripten )
|
||||
web_generate()
|
||||
elseif ( CMAKE_SYSTEM_NAME STREQUAL Windows )
|
||||
windows_generate()
|
||||
endif ()
|
||||
|
||||
endforeach ()
|
||||
|
||||
# Added for backwards compatibility with prior cmake solution so that builds dont immediately break
|
||||
# from a missing target.
|
||||
add_library( godot::cpp ALIAS godot-cpp.template_debug )
|
||||
|
||||
endfunction()
|
||||
|
||||
21
cmake/ios.cmake
Normal file
21
cmake/ios.cmake
Normal file
@@ -0,0 +1,21 @@
|
||||
#[=======================================================================[.rst:
|
||||
Ios
|
||||
---
|
||||
|
||||
This file contains functions for options and configuration for targeting the
|
||||
Ios platform
|
||||
|
||||
]=======================================================================]
|
||||
function(ios_options)
|
||||
# iOS options
|
||||
endfunction()
|
||||
|
||||
function(ios_generate)
|
||||
target_compile_definitions(${TARGET_NAME}
|
||||
PUBLIC
|
||||
IOS_ENABLED
|
||||
UNIX_ENABLED
|
||||
)
|
||||
|
||||
common_compiler_flags()
|
||||
endfunction()
|
||||
21
cmake/linux.cmake
Normal file
21
cmake/linux.cmake
Normal file
@@ -0,0 +1,21 @@
|
||||
#[=======================================================================[.rst:
|
||||
Linux
|
||||
-----
|
||||
|
||||
This file contains functions for options and configuration for targeting the
|
||||
Linux platform
|
||||
|
||||
]=======================================================================]
|
||||
function( linux_options )
|
||||
# Linux Options
|
||||
endfunction()
|
||||
|
||||
function( linux_generate )
|
||||
target_compile_definitions( ${TARGET_NAME}
|
||||
PUBLIC
|
||||
LINUX_ENABLED
|
||||
UNIX_ENABLED
|
||||
)
|
||||
|
||||
common_compiler_flags()
|
||||
endfunction()
|
||||
46
cmake/macos.cmake
Normal file
46
cmake/macos.cmake
Normal file
@@ -0,0 +1,46 @@
|
||||
#[=======================================================================[.rst:
|
||||
MacOS
|
||||
-----
|
||||
|
||||
This file contains functions for options and configuration for targeting the
|
||||
MacOS platform
|
||||
|
||||
# To build universal binaries, ie targeting both x86_64 and arm64, use
|
||||
# the CMAKE_OSX_ARCHITECTURES variable prior to any project calls.
|
||||
# https://cmake.org/cmake/help/latest/variable/CMAKE_OSX_ARCHITECTURES.html
|
||||
|
||||
]=======================================================================]
|
||||
|
||||
# Find Requirements
|
||||
IF(APPLE)
|
||||
set( CMAKE_OSX_SYSROOT $ENV{SDKROOT} )
|
||||
find_library( COCOA_LIBRARY REQUIRED
|
||||
NAMES Cocoa
|
||||
PATHS ${CMAKE_OSX_SYSROOT}/System/Library
|
||||
PATH_SUFFIXES Frameworks
|
||||
NO_DEFAULT_PATH)
|
||||
ENDIF (APPLE)
|
||||
|
||||
function( macos_options )
|
||||
endfunction()
|
||||
|
||||
function( macos_generate )
|
||||
|
||||
target_compile_definitions(${TARGET_NAME}
|
||||
PUBLIC
|
||||
MACOS_ENABLED
|
||||
UNIX_ENABLED
|
||||
)
|
||||
|
||||
target_link_options( ${TARGET_NAME}
|
||||
PUBLIC
|
||||
-Wl,-undefined,dynamic_lookup
|
||||
)
|
||||
|
||||
target_link_libraries( ${TARGET_NAME}
|
||||
INTERFACE
|
||||
${COCOA_LIBRARY}
|
||||
)
|
||||
|
||||
common_compiler_flags()
|
||||
endfunction()
|
||||
42
cmake/web.cmake
Normal file
42
cmake/web.cmake
Normal file
@@ -0,0 +1,42 @@
|
||||
#[=======================================================================[.rst:
|
||||
Web
|
||||
---
|
||||
|
||||
This file contains functions for options and configuration for targeting the
|
||||
Web platform
|
||||
|
||||
]=======================================================================]
|
||||
|
||||
# Emscripten requires this hack for use of the SHARED option
|
||||
set( CMAKE_PROJECT_godot-cpp_INCLUDE cmake/emsdkHack.cmake )
|
||||
|
||||
function( web_options )
|
||||
# web options
|
||||
endfunction()
|
||||
|
||||
|
||||
function( web_generate )
|
||||
target_compile_definitions(${TARGET_NAME}
|
||||
PUBLIC
|
||||
WEB_ENABLED
|
||||
UNIX_ENABLED
|
||||
)
|
||||
|
||||
target_compile_options( ${TARGET_NAME}
|
||||
PUBLIC
|
||||
-sSIDE_MODULE
|
||||
-sSUPPORT_LONGJMP=wasm
|
||||
-fno-exceptions
|
||||
$<${THREADS_ENABLED}:-sUSE_PTHREADS=1>
|
||||
)
|
||||
|
||||
target_link_options( ${TARGET_NAME}
|
||||
INTERFACE
|
||||
-sWASM_BIGINT
|
||||
-sSUPPORT_LONGJMP=wasm
|
||||
-fvisibility=hidden
|
||||
-shared
|
||||
)
|
||||
|
||||
common_compiler_flags()
|
||||
endfunction()
|
||||
103
cmake/windows.cmake
Normal file
103
cmake/windows.cmake
Normal file
@@ -0,0 +1,103 @@
|
||||
#[=======================================================================[.rst:
|
||||
Windows
|
||||
-------
|
||||
This file contains functions for options and configuration for targeting the
|
||||
Windows platform
|
||||
|
||||
Because this file is included into the top level CMakelists.txt before the
|
||||
project directive, it means that
|
||||
|
||||
* ``CMAKE_CURRENT_SOURCE_DIR`` is the location of godot-cpp's CMakeLists.txt
|
||||
* ``CMAKE_SOURCE_DIR`` is the location where any prior ``project(...)``
|
||||
directive was
|
||||
|
||||
MSVC Runtime Selection
|
||||
----------------------
|
||||
|
||||
There are two main ways to set the msvc runtime library;
|
||||
Using ``target_compile_options()`` to add the flags
|
||||
or using the ``CMAKE_MSVC_RUNTIME_LIBRARY`` property_ abstraction, introduced
|
||||
in CMake version 3.15 with the policy CMP0091_ to remove the flags from
|
||||
``CMAKE_<LANG>_FLAGS_<CONFIG>``.
|
||||
|
||||
Default: ``CMAKE_MSVC_RUNTIME_LIBRARY="MultiThreaded$<$<CONFIG:Debug>:Debug>DLL"``
|
||||
|
||||
This initializes each target's ``MSVC_RUNTIME_LIBRARY`` property at the time of
|
||||
target creation.
|
||||
|
||||
it is stated in the msvc_ documentation that: "All modules passed to a given
|
||||
invocation of the linker must have been compiled with the same runtime library
|
||||
compiler option (/MD, /MT, /LD)."
|
||||
|
||||
This creates a conundrum for us, the ``CMAKE_MSVC_RUNTIME_LIBRARY`` needs to be
|
||||
correct at the time the target is created, but we have no control over the
|
||||
consumers CMake scripts, and the per-target ``MSVC_RUNTIME_LIBRARY`` property
|
||||
is not transient.
|
||||
|
||||
It has been raised that not using ``CMAKE_MSVC_RUNTIME_LIBRARY`` can also cause
|
||||
issues_ when a dependency( independent to godot-cpp ) that doesn't set any
|
||||
runtime flags, which relies purely on the ``CMAKE_MSVC_RUNTIME_LIBRARY``
|
||||
variable will very likely not have the correct msvc runtime flags set.
|
||||
|
||||
So we'll set ``CMAKE_MSVC_RUNTIME_LIBRARY`` as CACHE STRING so that it will be
|
||||
available for consumer target definitions, but also be able to be overridden if
|
||||
needed.
|
||||
|
||||
Additionally we message consumers notifying them and pointing to this
|
||||
documentation.
|
||||
|
||||
.. _CMP0091:https://cmake.org/cmake/help/latest/policy/CMP0091.html
|
||||
.. _property:https://cmake.org/cmake/help/latest/variable/CMAKE_MSVC_RUNTIME_LIBRARY.html
|
||||
.. https://discourse.cmake.org/t/mt-staticrelease-doesnt-match-value-md-dynamicrelease/5428/4
|
||||
.. _msvc: https://learn.microsoft.com/en-us/cpp/build/reference/md-mt-ld-use-run-time-library
|
||||
.. _issues: https://github.com/godotengine/godot-cpp/issues/1699
|
||||
|
||||
]=======================================================================]
|
||||
function( windows_options )
|
||||
option( GODOTCPP_USE_STATIC_CPP "Link MinGW/MSVC C++ runtime libraries statically" ON )
|
||||
option( GODOTCPP_DEBUG_CRT "Compile with MSVC's debug CRT (/MDd)" OFF )
|
||||
|
||||
message( STATUS "If not already cached, setting CMAKE_MSVC_RUNTIME_LIBRARY.\n"
|
||||
"\tFor more information please read godot-cpp/cmake/windows.cmake")
|
||||
|
||||
set( CMAKE_MSVC_RUNTIME_LIBRARY
|
||||
"MultiThreaded$<IF:$<BOOL:${GODOTCPP_DEBUG_CRT}>,DebugDLL,$<$<NOT:$<BOOL:${GODOTCPP_USE_STATIC_CPP}>>:DLL>>"
|
||||
CACHE STRING "Select the MSVC runtime library for use by compilers targeting the MSVC ABI.")
|
||||
endfunction()
|
||||
|
||||
|
||||
#[===========================[ Target Generation ]===========================]
|
||||
function( windows_generate )
|
||||
set( STATIC_CPP "$<BOOL:${GODOTCPP_USE_STATIC_CPP}>")
|
||||
|
||||
set_target_properties( ${TARGET_NAME}
|
||||
PROPERTIES
|
||||
PDB_OUTPUT_DIRECTORY "$<1:${CMAKE_SOURCE_DIR}/bin>"
|
||||
)
|
||||
|
||||
target_compile_definitions( ${TARGET_NAME}
|
||||
PUBLIC
|
||||
WINDOWS_ENABLED
|
||||
$<${IS_MSVC}:
|
||||
TYPED_METHOD_BIND
|
||||
NOMINMAX
|
||||
>
|
||||
)
|
||||
|
||||
target_link_options( ${TARGET_NAME}
|
||||
PUBLIC
|
||||
|
||||
$<${NOT_MSVC}:
|
||||
-Wl,--no-undefined
|
||||
$<${STATIC_CPP}:
|
||||
-static
|
||||
-static-libgcc
|
||||
-static-libstdc++
|
||||
>
|
||||
>
|
||||
|
||||
$<${IS_CLANG}:-lstdc++>
|
||||
)
|
||||
|
||||
common_compiler_flags()
|
||||
endfunction()
|
||||
57
doc/cmake.md
57
doc/cmake.md
@@ -1,57 +0,0 @@
|
||||
## CMake
|
||||
|
||||
### cmake arguments
|
||||
|
||||
`CMAKE_BUILD_TYPE`: Compilation target (Debug or Release defaults to Debug)
|
||||
|
||||
### godot-cpp cmake arguments
|
||||
- `GODOT_GDEXTENSION_DIR`: Path to the directory containing GDExtension interface header and API JSON file
|
||||
- `GODOT_SYSTEM_HEADERS`: Mark the header files as SYSTEM. This may be useful to suppress warnings in projects including this one.
|
||||
- `GODOT_WARNING_AS_ERROR`: Treat any warnings as errors
|
||||
- `GODOT_USE_HOT_RELOAD`: Build with hot reload support. Defaults to YES for Debug-builds and NO for Release-builds.
|
||||
- `GODOT_CUSTOM_API_FILE`: Path to a custom GDExtension API JSON file (takes precedence over `gdextension_dir`)
|
||||
- `GODOT_PRECISION`: Floating-point precision level ("single", "double")
|
||||
|
||||
### Android cmake arguments
|
||||
- `CMAKE_TOOLCHAIN_FILE`: The path to the android cmake toolchain ($ANDROID_NDK/build/cmake/android.toolchain.cmake)
|
||||
- `ANDROID_NDK`: The path to the android ndk root folder
|
||||
- `ANDROID_TOOLCHAIN_NAME`: The android toolchain (arm-linux-androideabi-4.9 or aarch64-linux-android-4.9 or x86-4.9 or x86_64-4.9)
|
||||
- `ANDROID_PLATFORM`: The android platform version (android-23)
|
||||
|
||||
- More info [here](https://godot.readthedocs.io/en/latest/development/compiling/compiling_for_android.html)
|
||||
|
||||
## Examples
|
||||
```shell
|
||||
Builds a debug version:
|
||||
cmake .
|
||||
cmake --build .
|
||||
```
|
||||
Builds a release version with clang
|
||||
|
||||
```shell
|
||||
CC=/usr/bin/clang CXX=/usr/bin/clang++ cmake -DCMAKE_BUILD_TYPE=Release -G "Unix Makefiles" .
|
||||
cmake --build .
|
||||
```
|
||||
Builds an android armeabi-v7a debug version:
|
||||
|
||||
``` shell
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake -DANDROID_NDK=$ANDROID_NDK \
|
||||
-DANDROID_TOOLCHAIN_NAME=arm-linux-androideabi-4.9 -DANDROID_PLATFORM=android-23 -DCMAKE_BUILD_TYPE=Debug .
|
||||
cmake --build .
|
||||
```
|
||||
|
||||
## Protip
|
||||
Generate the buildfiles in a sub directory to not clutter the root directory with build files:
|
||||
|
||||
```shell
|
||||
mkdir build && cd build && cmake -G "Unix Makefiles" .. && cmake --build .
|
||||
```
|
||||
|
||||
Ensure that you avoid exposing godot-cpp symbols - this might lead to hard to debug errors if you ever load multiple
|
||||
plugins using difference godot-cpp versions. Use visibility hidden whenever possible:
|
||||
```cmake
|
||||
set_target_properties(<all-my-plugin-related-targets> PROPERTIES CXX_VISIBILITY_PRESET hidden)
|
||||
```
|
||||
|
||||
## Todo
|
||||
Test build for Windows, Mac and mingw.
|
||||
377
doc/cmake.rst
Normal file
377
doc/cmake.rst
Normal file
@@ -0,0 +1,377 @@
|
||||
CMake
|
||||
=====
|
||||
|
||||
.. warning::
|
||||
|
||||
The CMake scripts do not have feature parity with the SCons ones at this
|
||||
stage and are still a work in progress. There are a number of people who
|
||||
have been working on alternative CMake solutions that are frequently
|
||||
referenced in the discord chats: Ivan's cmake-rewrite_ branch and
|
||||
Vorlac's godot-roguelite_ Project
|
||||
|
||||
.. _cmake-rewrite: https://github.com/IvanInventor/godot-cpp/tree/cmake-rewrite
|
||||
.. _godot-roguelite: https://github.com/vorlac/godot-roguelite
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
Compiling godot-cpp independently of an extension project is mainly for
|
||||
godot-cpp developers, package maintainers, and CI/CD. Look to the
|
||||
godot-cpp-template_ for a practical example on how to consume the godot-cpp
|
||||
library as part of a Godot extension.
|
||||
|
||||
Configuration examples are listed at the bottom of the page.
|
||||
|
||||
.. _godot-cpp-template: https://github.com/godotengine/godot-cpp-template
|
||||
|
||||
SCons Deviations
|
||||
----------------
|
||||
|
||||
Not everything from SCons can be perfectly representable in CMake, here are
|
||||
the notable differences.
|
||||
|
||||
- debug_symbols
|
||||
No longer has an explicit option, and is enabled via Debug-like CMake
|
||||
build configurations; Debug, RelWithDebInfo.
|
||||
|
||||
- dev_build
|
||||
Does not define NDEBUG when disabled, NDEBUG is set via Release-like
|
||||
CMake build configurations; Release, MinSizeRel.
|
||||
|
||||
Testing Integration
|
||||
-------------------
|
||||
When consuming a third party CMake project into yours, an unfortunate side
|
||||
effect is that the targets of the consumed project appear in the list of
|
||||
available targets, and are by default included in the ALL meta target
|
||||
created by most build systems. For this reason, all the targets specified
|
||||
in godot-cpp are marked with the ``EXCLUDE_FROM_ALL`` tag to prevent
|
||||
unnecessary compilation. The testing targets ``godot-cpp.test.<target>``
|
||||
are also guarded by ``GODOTCPP_ENABLE_TESTING`` which is off by default.
|
||||
|
||||
To configure and build the godot-cpp project to enable the integration
|
||||
testing targets the command will look something like:
|
||||
|
||||
.. code-block::
|
||||
|
||||
# Assuming our current directory is the godot-cpp source root
|
||||
mkdir cmake-build
|
||||
cd cmake-build
|
||||
cmake .. -DGODOTCPP_ENABLE_TESTING=YES
|
||||
cmake --build . --target godot-cpp.test.template_debug
|
||||
|
||||
Basic walkthrough
|
||||
-----------------
|
||||
|
||||
.. topic:: Clone the git repository
|
||||
|
||||
.. code-block::
|
||||
|
||||
git clone https://github.com/godotengine/godot-cpp.git
|
||||
Cloning into 'godot-cpp'...
|
||||
...
|
||||
cd godot-cpp
|
||||
|
||||
|
||||
.. topic:: Out-of-tree build directory
|
||||
|
||||
Create a build directory for CMake to put caches and build artifacts in and
|
||||
change directory to it. This is typically as a sub-directory of the project
|
||||
root but can be outside the source tree. This is so that generated files do
|
||||
not clutter up the source tree.
|
||||
|
||||
.. code-block::
|
||||
|
||||
mkdir cmake-build
|
||||
cd cmake-build
|
||||
|
||||
.. topic:: Configure the build
|
||||
|
||||
CMake doesn't build the code, it generates the files that another tool uses
|
||||
to build the code. To see the list of generators run ``cmake --help``. The
|
||||
first phase of which is running through the configuration scripts.
|
||||
|
||||
Configure and generate Ninja build files.
|
||||
|
||||
.. code-block::
|
||||
|
||||
cmake .. -G "Ninja"
|
||||
|
||||
To list the available options CMake use the ``-L[AH]`` option. ``A`` is for
|
||||
advanced, and ``H`` is for help strings.
|
||||
|
||||
.. code-block::
|
||||
|
||||
cmake .. -LH
|
||||
|
||||
Options are specified on the command line when configuring
|
||||
|
||||
.. code-block::
|
||||
|
||||
cmake .. -DGODOTCPP_USE_HOT_RELOAD:BOOL=ON \
|
||||
-DGODOTCPP_PRECISION:STRING=double \
|
||||
-DCMAKE_BUILD_TYPE:STRING=Debug
|
||||
|
||||
Review setting-build-variables_ and build-configurations_ for more information.
|
||||
|
||||
.. _setting-build-variables: https://cmake.org/cmake/help/latest/guide/user-interaction/index.html#setting-build-variables
|
||||
.. _build-configurations: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations
|
||||
|
||||
A non-exhaustive list of options:
|
||||
|
||||
.. code-block::
|
||||
|
||||
// Path to a custom GDExtension API JSON file (takes precedence over `GODOTCPP_GDEXTENSION_DIR`) ( /path/to/custom_api_file )
|
||||
`GODOTCPP_CUSTOM_API_FILE:FILEPATH=`
|
||||
|
||||
// Force disabling exception handling code (ON|OFF)
|
||||
GODOTCPP_DISABLE_EXCEPTIONS:BOOL=ON
|
||||
|
||||
// Path to a custom directory containing GDExtension interface header and API JSON file ( /path/to/gdextension_dir )
|
||||
GODOTCPP_GDEXTENSION_DIR:PATH=gdextension
|
||||
|
||||
// Generate a template version of the Node class's get_node. (ON|OFF)
|
||||
GODOTCPP_GENERATE_TEMPLATE_GET_NODE:BOOL=ON
|
||||
|
||||
// Set the floating-point precision level (single|double)
|
||||
GODOTCPP_PRECISION:STRING=single
|
||||
|
||||
// Symbols visibility on GNU platforms. Use 'auto' to apply the default value. (auto|visible|hidden)
|
||||
GODOTCPP_SYMBOL_VISIBILITY:STRING=hidden
|
||||
|
||||
// Expose headers as SYSTEM.
|
||||
GODOTCPP_SYSTEM_HEADERS:BOOL=ON
|
||||
|
||||
// Enable the extra accounting required to support hot reload. (ON|OFF)
|
||||
GODOTCPP_USE_HOT_RELOAD:BOOL=
|
||||
|
||||
// Treat warnings as errors
|
||||
GODOTCPP_WARNING_AS_ERROR:BOOL=OFF
|
||||
|
||||
|
||||
.. topic:: Compiling
|
||||
|
||||
A target and a configuration is required, as the default ``all`` target does
|
||||
not include anything and when using multi-config generators like ``Ninja
|
||||
Multi-Config``, ``Visual Studio *`` or ``Xcode`` the build configuration
|
||||
needs to be specified at build time. Build in Release mode unless you need
|
||||
debug symbols.
|
||||
|
||||
.. code-block::
|
||||
|
||||
cmake --build . -t template_debug --config Debug
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
Windows and MSVC - Release
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
So long as CMake is installed from the `CMake Downloads`_ page and in the PATH,
|
||||
and Microsoft Visual Studio is installed with c++ support, CMake will detect
|
||||
the MSVC compiler.
|
||||
|
||||
Remembering that Visual Studio is a Multi-Config Generator so the build type
|
||||
needs to be specified at build time.
|
||||
|
||||
.. _CMake downloads: https://cmake.org/download/
|
||||
|
||||
.. code-block::
|
||||
|
||||
# Assuming our current directory is the godot-cpp source root
|
||||
mkdir build-msvc
|
||||
cd build-msvc
|
||||
cmake .. -DGODOTCPP_ENABLE_TESTING=YES
|
||||
cmake --build . -t godot-cpp.test.template_debug --config Debug
|
||||
|
||||
|
||||
MSys2/clang64, "Ninja" - Debug
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Assumes the ming-w64-clang-x86_64-toolchain is installed
|
||||
|
||||
Remembering that Ninja is a Single-Config Generator so the build type
|
||||
needs to be specified at Configure time.
|
||||
|
||||
Using the msys2/clang64 shell
|
||||
|
||||
.. code-block::
|
||||
|
||||
# Assuming our current directory is the godot-cpp source root
|
||||
mkdir build-clang
|
||||
cd build-clang
|
||||
cmake .. -G"Ninja" -DGODOTCPP_ENABLE_TESTING=YES -DCMAKE_BUILD_TYPE=Debug
|
||||
cmake --build . -t godot-cpp.test.template_debug
|
||||
|
||||
MSys2/clang64, "Ninja Multi-Config" - dev_build, Debug Symbols
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Assumes the ming-w64-clang-x86_64-toolchain is installed
|
||||
|
||||
This time we are choosing the 'Ninja Multi-Config' generator, so the build
|
||||
type is specified at build time.
|
||||
|
||||
Using the msys2/clang64 shell
|
||||
|
||||
.. code-block::
|
||||
|
||||
# Assuming our current directory is the godot-cpp source root
|
||||
mkdir build-clang
|
||||
cd build-clang
|
||||
cmake .. -G"Ninja Multi-Config" -DGODOTCPP_ENABLE_TESTING=YES -DGODOTCPP_DEV_BUILD:BOOL=ON
|
||||
cmake --build . -t godot-cpp.test.template_debug --config Debug
|
||||
|
||||
Emscripten for web platform
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
I've only tested this on windows so far.
|
||||
|
||||
I cloned and installed the latest Emscripten tools to ``c:\emsdk``
|
||||
At the time of writing that was v3.1.69
|
||||
|
||||
I've been using ``C:\emsdk\emsdk.ps1 activate latest`` to enable the
|
||||
environment from powershell in the current shell.
|
||||
|
||||
The ``emcmake.bat`` utility adds the emscripten toolchain to the CMake command
|
||||
|
||||
.. code-block::
|
||||
|
||||
# Assuming our current directory is the godot-cpp source root
|
||||
C:\emsdk\emsdk.ps1 activate latest
|
||||
mkdir build-wasm32
|
||||
cd build-wasm32
|
||||
emcmake.bat cmake ../
|
||||
cmake --build . --target template_release
|
||||
|
||||
Android Cross Compile from Windows
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
There are two separate paths you can choose when configuring for android.
|
||||
|
||||
Use the ``CMAKE_ANDROID_*`` variables specified on the commandline or in your
|
||||
own toolchain file as listed in the cmake-toolchains_ documentation
|
||||
|
||||
.. _cmake-toolchains: https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling-for-android-with-the-ndk
|
||||
|
||||
Or use the toolchain and scripts provided by the Android SDK and make changes
|
||||
using the ``ANDROID_*`` variables listed there. Where ``<version>`` is whatever
|
||||
ndk version you have installed (tested with `23.2.8568313`) and ``<platform>``
|
||||
is for android sdk platform, (tested with ``android-29``)
|
||||
|
||||
.. warning::
|
||||
|
||||
The Android SDK website explicitly states that they do not support using
|
||||
the CMake built-in method, and recommends you stick with their toolchain
|
||||
files.
|
||||
|
||||
.. topic:: Using your own toolchain file as described in the CMake documentation
|
||||
|
||||
.. code-block::
|
||||
|
||||
# Assuming our current directory is the godot-cpp source root
|
||||
mkdir build-android
|
||||
cd build-android
|
||||
cmake .. --toolchain my_toolchain.cmake
|
||||
cmake --build . -t template_release
|
||||
|
||||
Doing the equivalent on just using the command line
|
||||
|
||||
.. code-block::
|
||||
|
||||
# Assuming our current directory is the godot-cpp source root
|
||||
mkdir build-android
|
||||
cd build-android
|
||||
cmake .. \
|
||||
-DCMAKE_SYSTEM_NAME=Android \
|
||||
-DCMAKE_SYSTEM_VERSION=<platform> \
|
||||
-DCMAKE_ANDROID_ARCH_ABI=<arch> \
|
||||
-DCMAKE_ANDROID_NDK=/path/to/android-ndk
|
||||
cmake --build . -t template_release
|
||||
|
||||
.. topic:: Using the toolchain file from the Android SDK
|
||||
|
||||
Defaults to minimum supported version( android-16 in my case) and armv7-a.
|
||||
|
||||
.. code-block::
|
||||
|
||||
# Assuming our current directory is the godot-cpp source root
|
||||
mkdir build-android
|
||||
cd build-android
|
||||
cmake .. --toolchain $ANDROID_HOME/ndk/<version>/build/cmake/android.toolchain.cmake
|
||||
cmake --build . -t template_release
|
||||
|
||||
Specify Android platform and ABI
|
||||
|
||||
.. code-block::
|
||||
|
||||
# Assuming our current directory is the godot-cpp source root
|
||||
mkdir build-android
|
||||
cd build-android
|
||||
cmake .. --toolchain $ANDROID_HOME/ndk/<version>/build/cmake/android.toolchain.cmake \
|
||||
-DANDROID_PLATFORM:STRING=android-29 \
|
||||
-DANDROID_ABI:STRING=armeabi-v7a
|
||||
cmake --build . -t template_release
|
||||
|
||||
|
||||
Toolchains
|
||||
----------
|
||||
This section attempts to list the host and target combinations that have been
|
||||
at tested.
|
||||
|
||||
Info on cross compiling triplets indicates that the naming is a little more
|
||||
freeform that expected, and tailored to its use case. Triplets tend to have the
|
||||
format ``<arch>[sub][-vendor][-OS][-env]``
|
||||
|
||||
* `osdev.org <https://wiki.osdev.org/Target_Triplet>`_
|
||||
* `stack overflow <https://stackoverflow.com/questions/13819857/does-a-list-of-all-known-target-triplets-in-use-exist>`_
|
||||
* `LLVM <https://llvm.org/doxygen/classllvm_1_1Triple.html>`_
|
||||
* `clang target triple <https://clang.llvm.org/docs/CrossCompilation.html#target-triple>`_
|
||||
* `vcpkg <https://learn.microsoft.com/en-us/vcpkg/concepts/triplets>`_
|
||||
* `wasm32-unknown-emscripten <https://blog.therocode.net/2020/10/a-guide-to-rust-sdl2-emscripten>`_
|
||||
|
||||
Linux Host
|
||||
~~~~~~~~~~
|
||||
|
||||
:Target: x86_64-linux
|
||||
|
||||
Macos Host
|
||||
~~~~~~~~~~
|
||||
|
||||
:System: Mac Mini
|
||||
:OS Name: Sequoia 15.0.1
|
||||
:Processor: Apple M2
|
||||
|
||||
Windows Host
|
||||
~~~~~~~~~~~~
|
||||
|
||||
:OS Name: Microsoft Windows 11 Home, 10.0.22631 N/A Build 22631
|
||||
:Processor: AMD Ryzen 7 6800HS Creator Edition
|
||||
|
||||
`Microsoft Visual Studio 17 2022 <https://visualstudio.microsoft.com/vs/>`_
|
||||
:Target: x86_64-w64
|
||||
|
||||
`LLVM <https://llvm.org/>`_
|
||||
:Target: x86_64-pc-windows-msvc
|
||||
|
||||
`AndroidSDK <https://developer.android.com/studio/#command-tools>`_
|
||||
armv7-none-linux-androideabi16
|
||||
|
||||
`Emscripten <https://emscripten.org/>`_
|
||||
:Compiler: Emscripten
|
||||
:Target: wasm32-unknown-emscripten
|
||||
|
||||
`MinGW-w64 <https://www.mingw-w64.org/>`_ based toolchains
|
||||
|
||||
`MSYS2 <https://www.msys2.org/>`_
|
||||
Necessary reading about MSYS2 `environments <https://www.msys2.org/docs/environments/>`_
|
||||
|
||||
ucrt64
|
||||
:Compiler: gcc version 14.2.0 (Rev1, Built by MSYS2 project)
|
||||
:Target: x86_64-w64-mingw32
|
||||
|
||||
clang64
|
||||
:Compiler: clang version 18.1.8
|
||||
:Target: x86_64-w64-windows-gnu
|
||||
|
||||
`LLVM-MinGW <https://github.com/mstorsjo/llvm-mingw/releases>`_
|
||||
|
||||
`MinGW-W64-builds <https://github.com/niXman/mingw-builds-binaries/releases>`_
|
||||
:Compiler: gcc
|
||||
:Target: x86_64-w64-mingw32-ucrt
|
||||
|
||||
`Jetbrains-CLion <https://www.jetbrains.com/clion/>`_
|
||||
:Target: x86_64-w64-mingw32-msvcrt
|
||||
55
doc_source_generator.py
Normal file
55
doc_source_generator.py
Normal file
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import glob
|
||||
import os
|
||||
import zlib
|
||||
|
||||
|
||||
def generate_doc_source(dst, source):
|
||||
g = open(dst, "w", encoding="utf-8")
|
||||
buf = ""
|
||||
docbegin = ""
|
||||
docend = ""
|
||||
for src in source:
|
||||
src_path = str(src)
|
||||
if not src_path.endswith(".xml"):
|
||||
continue
|
||||
with open(src_path, "r", encoding="utf-8") as f:
|
||||
content = f.read()
|
||||
buf += content
|
||||
|
||||
buf = (docbegin + buf + docend).encode("utf-8")
|
||||
decomp_size = len(buf)
|
||||
|
||||
# Use maximum zlib compression level to further reduce file size
|
||||
# (at the cost of initial build times).
|
||||
buf = zlib.compress(buf, zlib.Z_BEST_COMPRESSION)
|
||||
|
||||
g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
|
||||
g.write("\n")
|
||||
g.write("#include <godot_cpp/godot.hpp>\n")
|
||||
g.write("\n")
|
||||
|
||||
g.write('static const char *_doc_data_hash = "' + str(hash(buf)) + '";\n')
|
||||
g.write("static const int _doc_data_uncompressed_size = " + str(decomp_size) + ";\n")
|
||||
g.write("static const int _doc_data_compressed_size = " + str(len(buf)) + ";\n")
|
||||
g.write("static const unsigned char _doc_data_compressed[] = {\n")
|
||||
for i in range(len(buf)):
|
||||
g.write("\t" + str(buf[i]) + ",\n")
|
||||
g.write("};\n")
|
||||
g.write("\n")
|
||||
|
||||
g.write(
|
||||
"static godot::internal::DocDataRegistration _doc_data_registration(_doc_data_hash, _doc_data_uncompressed_size, _doc_data_compressed_size, _doc_data_compressed);\n"
|
||||
)
|
||||
g.write("\n")
|
||||
|
||||
g.close()
|
||||
|
||||
|
||||
def scons_generate_doc_source(target, source, env):
|
||||
generate_doc_source(str(target[0]), source)
|
||||
|
||||
|
||||
def generate_doc_source_from_directory(target, directory):
|
||||
generate_doc_source(target, glob.glob(os.path.join(directory, "*.xml")))
|
||||
File diff suppressed because it is too large
Load Diff
@@ -96,6 +96,7 @@ typedef enum {
|
||||
GDEXTENSION_VARIANT_TYPE_PACKED_VECTOR2_ARRAY,
|
||||
GDEXTENSION_VARIANT_TYPE_PACKED_VECTOR3_ARRAY,
|
||||
GDEXTENSION_VARIANT_TYPE_PACKED_COLOR_ARRAY,
|
||||
GDEXTENSION_VARIANT_TYPE_PACKED_VECTOR4_ARRAY,
|
||||
|
||||
GDEXTENSION_VARIANT_TYPE_VARIANT_MAX
|
||||
} GDExtensionVariantType;
|
||||
@@ -197,6 +198,7 @@ typedef struct {
|
||||
|
||||
typedef void (*GDExtensionVariantFromTypeConstructorFunc)(GDExtensionUninitializedVariantPtr, GDExtensionTypePtr);
|
||||
typedef void (*GDExtensionTypeFromVariantConstructorFunc)(GDExtensionUninitializedTypePtr, GDExtensionVariantPtr);
|
||||
typedef void *(*GDExtensionVariantGetInternalPtrFunc)(GDExtensionVariantPtr);
|
||||
typedef void (*GDExtensionPtrOperatorEvaluator)(GDExtensionConstTypePtr p_left, GDExtensionConstTypePtr p_right, GDExtensionTypePtr r_result);
|
||||
typedef void (*GDExtensionPtrBuiltInMethod)(GDExtensionTypePtr p_base, const GDExtensionConstTypePtr *p_args, GDExtensionTypePtr r_return, int p_argument_count);
|
||||
typedef void (*GDExtensionPtrConstructor)(GDExtensionUninitializedTypePtr p_base, const GDExtensionConstTypePtr *p_args);
|
||||
@@ -256,6 +258,7 @@ typedef struct {
|
||||
|
||||
typedef const GDExtensionPropertyInfo *(*GDExtensionClassGetPropertyList)(GDExtensionClassInstancePtr p_instance, uint32_t *r_count);
|
||||
typedef void (*GDExtensionClassFreePropertyList)(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list);
|
||||
typedef void (*GDExtensionClassFreePropertyList2)(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list, uint32_t p_count);
|
||||
typedef GDExtensionBool (*GDExtensionClassPropertyCanRevert)(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name);
|
||||
typedef GDExtensionBool (*GDExtensionClassPropertyGetRevert)(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret);
|
||||
typedef GDExtensionBool (*GDExtensionClassValidateProperty)(GDExtensionClassInstancePtr p_instance, GDExtensionPropertyInfo *p_property);
|
||||
@@ -266,10 +269,13 @@ typedef void (*GDExtensionClassReference)(GDExtensionClassInstancePtr p_instance
|
||||
typedef void (*GDExtensionClassUnreference)(GDExtensionClassInstancePtr p_instance);
|
||||
typedef void (*GDExtensionClassCallVirtual)(GDExtensionClassInstancePtr p_instance, const GDExtensionConstTypePtr *p_args, GDExtensionTypePtr r_ret);
|
||||
typedef GDExtensionObjectPtr (*GDExtensionClassCreateInstance)(void *p_class_userdata);
|
||||
typedef GDExtensionObjectPtr (*GDExtensionClassCreateInstance2)(void *p_class_userdata, GDExtensionBool p_notify_postinitialize);
|
||||
typedef void (*GDExtensionClassFreeInstance)(void *p_class_userdata, GDExtensionClassInstancePtr p_instance);
|
||||
typedef GDExtensionClassInstancePtr (*GDExtensionClassRecreateInstance)(void *p_class_userdata, GDExtensionObjectPtr p_object);
|
||||
typedef GDExtensionClassCallVirtual (*GDExtensionClassGetVirtual)(void *p_class_userdata, GDExtensionConstStringNamePtr p_name);
|
||||
typedef GDExtensionClassCallVirtual (*GDExtensionClassGetVirtual2)(void *p_class_userdata, GDExtensionConstStringNamePtr p_name, uint32_t p_hash);
|
||||
typedef void *(*GDExtensionClassGetVirtualCallData)(void *p_class_userdata, GDExtensionConstStringNamePtr p_name);
|
||||
typedef void *(*GDExtensionClassGetVirtualCallData2)(void *p_class_userdata, GDExtensionConstStringNamePtr p_name, uint32_t p_hash);
|
||||
typedef void (*GDExtensionClassCallVirtualWithData)(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, void *p_virtual_call_userdata, const GDExtensionConstTypePtr *p_args, GDExtensionTypePtr r_ret);
|
||||
|
||||
typedef struct {
|
||||
@@ -290,7 +296,7 @@ typedef struct {
|
||||
GDExtensionClassGetVirtual get_virtual_func; // Queries a virtual function by name and returns a callback to invoke the requested virtual function.
|
||||
GDExtensionClassGetRID get_rid_func;
|
||||
void *class_userdata; // Per-class user data, later accessible in instance bindings.
|
||||
} GDExtensionClassCreationInfo; // Deprecated. Use GDExtensionClassCreationInfo2 instead.
|
||||
} GDExtensionClassCreationInfo; // Deprecated. Use GDExtensionClassCreationInfo4 instead.
|
||||
|
||||
typedef struct {
|
||||
GDExtensionBool is_virtual;
|
||||
@@ -323,7 +329,75 @@ typedef struct {
|
||||
GDExtensionClassCallVirtualWithData call_virtual_with_data_func;
|
||||
GDExtensionClassGetRID get_rid_func;
|
||||
void *class_userdata; // Per-class user data, later accessible in instance bindings.
|
||||
} GDExtensionClassCreationInfo2;
|
||||
} GDExtensionClassCreationInfo2; // Deprecated. Use GDExtensionClassCreationInfo4 instead.
|
||||
|
||||
typedef struct {
|
||||
GDExtensionBool is_virtual;
|
||||
GDExtensionBool is_abstract;
|
||||
GDExtensionBool is_exposed;
|
||||
GDExtensionBool is_runtime;
|
||||
GDExtensionClassSet set_func;
|
||||
GDExtensionClassGet get_func;
|
||||
GDExtensionClassGetPropertyList get_property_list_func;
|
||||
GDExtensionClassFreePropertyList2 free_property_list_func;
|
||||
GDExtensionClassPropertyCanRevert property_can_revert_func;
|
||||
GDExtensionClassPropertyGetRevert property_get_revert_func;
|
||||
GDExtensionClassValidateProperty validate_property_func;
|
||||
GDExtensionClassNotification2 notification_func;
|
||||
GDExtensionClassToString to_string_func;
|
||||
GDExtensionClassReference reference_func;
|
||||
GDExtensionClassUnreference unreference_func;
|
||||
GDExtensionClassCreateInstance create_instance_func; // (Default) constructor; mandatory. If the class is not instantiable, consider making it virtual or abstract.
|
||||
GDExtensionClassFreeInstance free_instance_func; // Destructor; mandatory.
|
||||
GDExtensionClassRecreateInstance recreate_instance_func;
|
||||
// Queries a virtual function by name and returns a callback to invoke the requested virtual function.
|
||||
GDExtensionClassGetVirtual get_virtual_func;
|
||||
// Paired with `call_virtual_with_data_func`, this is an alternative to `get_virtual_func` for extensions that
|
||||
// need or benefit from extra data when calling virtual functions.
|
||||
// Returns user data that will be passed to `call_virtual_with_data_func`.
|
||||
// Returning `NULL` from this function signals to Godot that the virtual function is not overridden.
|
||||
// Data returned from this function should be managed by the extension and must be valid until the extension is deinitialized.
|
||||
// You should supply either `get_virtual_func`, or `get_virtual_call_data_func` with `call_virtual_with_data_func`.
|
||||
GDExtensionClassGetVirtualCallData get_virtual_call_data_func;
|
||||
// Used to call virtual functions when `get_virtual_call_data_func` is not null.
|
||||
GDExtensionClassCallVirtualWithData call_virtual_with_data_func;
|
||||
GDExtensionClassGetRID get_rid_func;
|
||||
void *class_userdata; // Per-class user data, later accessible in instance bindings.
|
||||
} GDExtensionClassCreationInfo3; // Deprecated. Use GDExtensionClassCreationInfo4 instead.
|
||||
|
||||
typedef struct {
|
||||
GDExtensionBool is_virtual;
|
||||
GDExtensionBool is_abstract;
|
||||
GDExtensionBool is_exposed;
|
||||
GDExtensionBool is_runtime;
|
||||
GDExtensionConstStringPtr icon_path;
|
||||
GDExtensionClassSet set_func;
|
||||
GDExtensionClassGet get_func;
|
||||
GDExtensionClassGetPropertyList get_property_list_func;
|
||||
GDExtensionClassFreePropertyList2 free_property_list_func;
|
||||
GDExtensionClassPropertyCanRevert property_can_revert_func;
|
||||
GDExtensionClassPropertyGetRevert property_get_revert_func;
|
||||
GDExtensionClassValidateProperty validate_property_func;
|
||||
GDExtensionClassNotification2 notification_func;
|
||||
GDExtensionClassToString to_string_func;
|
||||
GDExtensionClassReference reference_func;
|
||||
GDExtensionClassUnreference unreference_func;
|
||||
GDExtensionClassCreateInstance2 create_instance_func; // (Default) constructor; mandatory. If the class is not instantiable, consider making it virtual or abstract.
|
||||
GDExtensionClassFreeInstance free_instance_func; // Destructor; mandatory.
|
||||
GDExtensionClassRecreateInstance recreate_instance_func;
|
||||
// Queries a virtual function by name and returns a callback to invoke the requested virtual function.
|
||||
GDExtensionClassGetVirtual2 get_virtual_func;
|
||||
// Paired with `call_virtual_with_data_func`, this is an alternative to `get_virtual_func` for extensions that
|
||||
// need or benefit from extra data when calling virtual functions.
|
||||
// Returns user data that will be passed to `call_virtual_with_data_func`.
|
||||
// Returning `NULL` from this function signals to Godot that the virtual function is not overridden.
|
||||
// Data returned from this function should be managed by the extension and must be valid until the extension is deinitialized.
|
||||
// You should supply either `get_virtual_func`, or `get_virtual_call_data_func` with `call_virtual_with_data_func`.
|
||||
GDExtensionClassGetVirtualCallData2 get_virtual_call_data_func;
|
||||
// Used to call virtual functions when `get_virtual_call_data_func` is not null.
|
||||
GDExtensionClassCallVirtualWithData call_virtual_with_data_func;
|
||||
void *class_userdata; // Per-class user data, later accessible in instance bindings.
|
||||
} GDExtensionClassCreationInfo4;
|
||||
|
||||
typedef void *GDExtensionClassLibraryPtr;
|
||||
|
||||
@@ -350,7 +424,9 @@ typedef enum {
|
||||
GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_UINT32,
|
||||
GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_UINT64,
|
||||
GDEXTENSION_METHOD_ARGUMENT_METADATA_REAL_IS_FLOAT,
|
||||
GDEXTENSION_METHOD_ARGUMENT_METADATA_REAL_IS_DOUBLE
|
||||
GDEXTENSION_METHOD_ARGUMENT_METADATA_REAL_IS_DOUBLE,
|
||||
GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_CHAR16,
|
||||
GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_CHAR32,
|
||||
} GDExtensionClassMethodArgumentMetadata;
|
||||
|
||||
typedef void (*GDExtensionClassMethodCall)(void *method_userdata, GDExtensionClassInstancePtr p_instance, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error);
|
||||
@@ -364,13 +440,18 @@ typedef struct {
|
||||
GDExtensionClassMethodPtrCall ptrcall_func;
|
||||
uint32_t method_flags; // Bitfield of `GDExtensionClassMethodFlags`.
|
||||
|
||||
/* If `has_return_value` is false, `return_value_info` and `return_value_metadata` are ignored. */
|
||||
/* If `has_return_value` is false, `return_value_info` and `return_value_metadata` are ignored.
|
||||
*
|
||||
* @todo Consider dropping `has_return_value` and making the other two properties match `GDExtensionMethodInfo` and `GDExtensionClassVirtualMethod` for consistency in future version of this struct.
|
||||
*/
|
||||
GDExtensionBool has_return_value;
|
||||
GDExtensionPropertyInfo *return_value_info;
|
||||
GDExtensionClassMethodArgumentMetadata return_value_metadata;
|
||||
|
||||
/* Arguments: `arguments_info` and `arguments_metadata` are array of size `argument_count`.
|
||||
* Name and hint information for the argument can be omitted in release builds. Class name should always be present if it applies.
|
||||
*
|
||||
* @todo Consider renaming `arguments_info` to `arguments` for consistency in future version of this struct.
|
||||
*/
|
||||
uint32_t argument_count;
|
||||
GDExtensionPropertyInfo *arguments_info;
|
||||
@@ -381,6 +462,18 @@ typedef struct {
|
||||
GDExtensionVariantPtr *default_arguments;
|
||||
} GDExtensionClassMethodInfo;
|
||||
|
||||
typedef struct {
|
||||
GDExtensionStringNamePtr name;
|
||||
uint32_t method_flags; // Bitfield of `GDExtensionClassMethodFlags`.
|
||||
|
||||
GDExtensionPropertyInfo return_value;
|
||||
GDExtensionClassMethodArgumentMetadata return_value_metadata;
|
||||
|
||||
uint32_t argument_count;
|
||||
GDExtensionPropertyInfo *arguments;
|
||||
GDExtensionClassMethodArgumentMetadata *arguments_metadata;
|
||||
} GDExtensionClassVirtualMethodInfo;
|
||||
|
||||
typedef void (*GDExtensionCallableCustomCall)(void *callable_userdata, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error);
|
||||
typedef GDExtensionBool (*GDExtensionCallableCustomIsValid)(void *callable_userdata);
|
||||
typedef void (*GDExtensionCallableCustomFree)(void *callable_userdata);
|
||||
@@ -391,6 +484,8 @@ typedef GDExtensionBool (*GDExtensionCallableCustomLessThan)(void *callable_user
|
||||
|
||||
typedef void (*GDExtensionCallableCustomToString)(void *callable_userdata, GDExtensionBool *r_is_valid, GDExtensionStringPtr r_out);
|
||||
|
||||
typedef GDExtensionInt (*GDExtensionCallableCustomGetArgumentCount)(void *callable_userdata, GDExtensionBool *r_is_valid);
|
||||
|
||||
typedef struct {
|
||||
/* Only `call_func` and `token` are strictly required, however, `object_id` should be passed if its not a static method.
|
||||
*
|
||||
@@ -420,7 +515,40 @@ typedef struct {
|
||||
GDExtensionCallableCustomLessThan less_than_func;
|
||||
|
||||
GDExtensionCallableCustomToString to_string_func;
|
||||
} GDExtensionCallableCustomInfo;
|
||||
} GDExtensionCallableCustomInfo; // Deprecated. Use GDExtensionCallableCustomInfo2 instead.
|
||||
|
||||
typedef struct {
|
||||
/* Only `call_func` and `token` are strictly required, however, `object_id` should be passed if its not a static method.
|
||||
*
|
||||
* `token` should point to an address that uniquely identifies the GDExtension (for example, the
|
||||
* `GDExtensionClassLibraryPtr` passed to the entry symbol function.
|
||||
*
|
||||
* `hash_func`, `equal_func`, and `less_than_func` are optional. If not provided both `call_func` and
|
||||
* `callable_userdata` together are used as the identity of the callable for hashing and comparison purposes.
|
||||
*
|
||||
* The hash returned by `hash_func` is cached, `hash_func` will not be called more than once per callable.
|
||||
*
|
||||
* `is_valid_func` is necessary if the validity of the callable can change before destruction.
|
||||
*
|
||||
* `free_func` is necessary if `callable_userdata` needs to be cleaned up when the callable is freed.
|
||||
*/
|
||||
void *callable_userdata;
|
||||
void *token;
|
||||
|
||||
GDObjectInstanceID object_id;
|
||||
|
||||
GDExtensionCallableCustomCall call_func;
|
||||
GDExtensionCallableCustomIsValid is_valid_func;
|
||||
GDExtensionCallableCustomFree free_func;
|
||||
|
||||
GDExtensionCallableCustomHash hash_func;
|
||||
GDExtensionCallableCustomEqual equal_func;
|
||||
GDExtensionCallableCustomLessThan less_than_func;
|
||||
|
||||
GDExtensionCallableCustomToString to_string_func;
|
||||
|
||||
GDExtensionCallableCustomGetArgumentCount get_argument_count_func;
|
||||
} GDExtensionCallableCustomInfo2;
|
||||
|
||||
/* SCRIPT INSTANCE EXTENSION */
|
||||
|
||||
@@ -429,7 +557,8 @@ typedef void *GDExtensionScriptInstanceDataPtr; // Pointer to custom ScriptInsta
|
||||
typedef GDExtensionBool (*GDExtensionScriptInstanceSet)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionConstVariantPtr p_value);
|
||||
typedef GDExtensionBool (*GDExtensionScriptInstanceGet)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret);
|
||||
typedef const GDExtensionPropertyInfo *(*GDExtensionScriptInstanceGetPropertyList)(GDExtensionScriptInstanceDataPtr p_instance, uint32_t *r_count);
|
||||
typedef void (*GDExtensionScriptInstanceFreePropertyList)(GDExtensionScriptInstanceDataPtr p_instance, const GDExtensionPropertyInfo *p_list);
|
||||
typedef void (*GDExtensionScriptInstanceFreePropertyList)(GDExtensionScriptInstanceDataPtr p_instance, const GDExtensionPropertyInfo *p_list); // Deprecated. Use GDExtensionScriptInstanceFreePropertyList2 instead.
|
||||
typedef void (*GDExtensionScriptInstanceFreePropertyList2)(GDExtensionScriptInstanceDataPtr p_instance, const GDExtensionPropertyInfo *p_list, uint32_t p_count);
|
||||
typedef GDExtensionBool (*GDExtensionScriptInstanceGetClassCategory)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionPropertyInfo *p_class_category);
|
||||
|
||||
typedef GDExtensionVariantType (*GDExtensionScriptInstanceGetPropertyType)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionBool *r_is_valid);
|
||||
@@ -443,10 +572,13 @@ typedef void (*GDExtensionScriptInstancePropertyStateAdd)(GDExtensionConstString
|
||||
typedef void (*GDExtensionScriptInstanceGetPropertyState)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionScriptInstancePropertyStateAdd p_add_func, void *p_userdata);
|
||||
|
||||
typedef const GDExtensionMethodInfo *(*GDExtensionScriptInstanceGetMethodList)(GDExtensionScriptInstanceDataPtr p_instance, uint32_t *r_count);
|
||||
typedef void (*GDExtensionScriptInstanceFreeMethodList)(GDExtensionScriptInstanceDataPtr p_instance, const GDExtensionMethodInfo *p_list);
|
||||
typedef void (*GDExtensionScriptInstanceFreeMethodList)(GDExtensionScriptInstanceDataPtr p_instance, const GDExtensionMethodInfo *p_list); // Deprecated. Use GDExtensionScriptInstanceFreeMethodList2 instead.
|
||||
typedef void (*GDExtensionScriptInstanceFreeMethodList2)(GDExtensionScriptInstanceDataPtr p_instance, const GDExtensionMethodInfo *p_list, uint32_t p_count);
|
||||
|
||||
typedef GDExtensionBool (*GDExtensionScriptInstanceHasMethod)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name);
|
||||
|
||||
typedef GDExtensionInt (*GDExtensionScriptInstanceGetMethodArgumentCount)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionBool *r_is_valid);
|
||||
|
||||
typedef void (*GDExtensionScriptInstanceCall)(GDExtensionScriptInstanceDataPtr p_self, GDExtensionConstStringNamePtr p_method, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error);
|
||||
typedef void (*GDExtensionScriptInstanceNotification)(GDExtensionScriptInstanceDataPtr p_instance, int32_t p_what); // Deprecated. Use GDExtensionScriptInstanceNotification2 instead.
|
||||
typedef void (*GDExtensionScriptInstanceNotification2)(GDExtensionScriptInstanceDataPtr p_instance, int32_t p_what, GDExtensionBool p_reversed);
|
||||
@@ -503,7 +635,7 @@ typedef struct {
|
||||
|
||||
GDExtensionScriptInstanceFree free_func;
|
||||
|
||||
} GDExtensionScriptInstanceInfo; // Deprecated. Use GDExtensionScriptInstanceInfo2 instead.
|
||||
} GDExtensionScriptInstanceInfo; // Deprecated. Use GDExtensionScriptInstanceInfo3 instead.
|
||||
|
||||
typedef struct {
|
||||
GDExtensionScriptInstanceSet set_func;
|
||||
@@ -544,7 +676,50 @@ typedef struct {
|
||||
|
||||
GDExtensionScriptInstanceFree free_func;
|
||||
|
||||
} GDExtensionScriptInstanceInfo2;
|
||||
} GDExtensionScriptInstanceInfo2; // Deprecated. Use GDExtensionScriptInstanceInfo3 instead.
|
||||
|
||||
typedef struct {
|
||||
GDExtensionScriptInstanceSet set_func;
|
||||
GDExtensionScriptInstanceGet get_func;
|
||||
GDExtensionScriptInstanceGetPropertyList get_property_list_func;
|
||||
GDExtensionScriptInstanceFreePropertyList2 free_property_list_func;
|
||||
GDExtensionScriptInstanceGetClassCategory get_class_category_func; // Optional. Set to NULL for the default behavior.
|
||||
|
||||
GDExtensionScriptInstancePropertyCanRevert property_can_revert_func;
|
||||
GDExtensionScriptInstancePropertyGetRevert property_get_revert_func;
|
||||
|
||||
GDExtensionScriptInstanceGetOwner get_owner_func;
|
||||
GDExtensionScriptInstanceGetPropertyState get_property_state_func;
|
||||
|
||||
GDExtensionScriptInstanceGetMethodList get_method_list_func;
|
||||
GDExtensionScriptInstanceFreeMethodList2 free_method_list_func;
|
||||
GDExtensionScriptInstanceGetPropertyType get_property_type_func;
|
||||
GDExtensionScriptInstanceValidateProperty validate_property_func;
|
||||
|
||||
GDExtensionScriptInstanceHasMethod has_method_func;
|
||||
|
||||
GDExtensionScriptInstanceGetMethodArgumentCount get_method_argument_count_func;
|
||||
|
||||
GDExtensionScriptInstanceCall call_func;
|
||||
GDExtensionScriptInstanceNotification2 notification_func;
|
||||
|
||||
GDExtensionScriptInstanceToString to_string_func;
|
||||
|
||||
GDExtensionScriptInstanceRefCountIncremented refcount_incremented_func;
|
||||
GDExtensionScriptInstanceRefCountDecremented refcount_decremented_func;
|
||||
|
||||
GDExtensionScriptInstanceGetScript get_script_func;
|
||||
|
||||
GDExtensionScriptInstanceIsPlaceholder is_placeholder_func;
|
||||
|
||||
GDExtensionScriptInstanceSet set_fallback_func;
|
||||
GDExtensionScriptInstanceGet get_fallback_func;
|
||||
|
||||
GDExtensionScriptInstanceGetLanguage get_language_func;
|
||||
|
||||
GDExtensionScriptInstanceFree free_func;
|
||||
|
||||
} GDExtensionScriptInstanceInfo3;
|
||||
|
||||
/* INITIALIZATION */
|
||||
|
||||
@@ -670,7 +845,7 @@ typedef void (*GDExtensionInterfaceMemFree)(void *p_ptr);
|
||||
*
|
||||
* Logs an error to Godot's built-in debugger and to the OS terminal.
|
||||
*
|
||||
* @param p_description The code trigging the error.
|
||||
* @param p_description The code triggering the error.
|
||||
* @param p_function The function name where the error occurred.
|
||||
* @param p_file The file where the error occurred.
|
||||
* @param p_line The line where the error occurred.
|
||||
@@ -684,7 +859,7 @@ typedef void (*GDExtensionInterfacePrintError)(const char *p_description, const
|
||||
*
|
||||
* Logs an error with a message to Godot's built-in debugger and to the OS terminal.
|
||||
*
|
||||
* @param p_description The code trigging the error.
|
||||
* @param p_description The code triggering the error.
|
||||
* @param p_message The message to show along with the error.
|
||||
* @param p_function The function name where the error occurred.
|
||||
* @param p_file The file where the error occurred.
|
||||
@@ -699,7 +874,7 @@ typedef void (*GDExtensionInterfacePrintErrorWithMessage)(const char *p_descript
|
||||
*
|
||||
* Logs a warning to Godot's built-in debugger and to the OS terminal.
|
||||
*
|
||||
* @param p_description The code trigging the warning.
|
||||
* @param p_description The code triggering the warning.
|
||||
* @param p_function The function name where the warning occurred.
|
||||
* @param p_file The file where the warning occurred.
|
||||
* @param p_line The line where the warning occurred.
|
||||
@@ -713,7 +888,7 @@ typedef void (*GDExtensionInterfacePrintWarning)(const char *p_description, cons
|
||||
*
|
||||
* Logs a warning with a message to Godot's built-in debugger and to the OS terminal.
|
||||
*
|
||||
* @param p_description The code trigging the warning.
|
||||
* @param p_description The code triggering the warning.
|
||||
* @param p_message The message to show along with the warning.
|
||||
* @param p_function The function name where the warning occurred.
|
||||
* @param p_file The file where the warning occurred.
|
||||
@@ -728,7 +903,7 @@ typedef void (*GDExtensionInterfacePrintWarningWithMessage)(const char *p_descri
|
||||
*
|
||||
* Logs a script error to Godot's built-in debugger and to the OS terminal.
|
||||
*
|
||||
* @param p_description The code trigging the error.
|
||||
* @param p_description The code triggering the error.
|
||||
* @param p_function The function name where the error occurred.
|
||||
* @param p_file The file where the error occurred.
|
||||
* @param p_line The line where the error occurred.
|
||||
@@ -742,7 +917,7 @@ typedef void (*GDExtensionInterfacePrintScriptError)(const char *p_description,
|
||||
*
|
||||
* Logs a script error with a message to Godot's built-in debugger and to the OS terminal.
|
||||
*
|
||||
* @param p_description The code trigging the error.
|
||||
* @param p_description The code triggering the error.
|
||||
* @param p_message The message to show along with the error.
|
||||
* @param p_function The function name where the error occurred.
|
||||
* @param p_file The file where the error occurred.
|
||||
@@ -1136,6 +1311,21 @@ typedef GDExtensionBool (*GDExtensionInterfaceVariantHasMember)(GDExtensionVaria
|
||||
*/
|
||||
typedef GDExtensionBool (*GDExtensionInterfaceVariantHasKey)(GDExtensionConstVariantPtr p_self, GDExtensionConstVariantPtr p_key, GDExtensionBool *r_valid);
|
||||
|
||||
/**
|
||||
* @name variant_get_object_instance_id
|
||||
* @since 4.4
|
||||
*
|
||||
* Gets the object instance ID from a variant of type GDEXTENSION_VARIANT_TYPE_OBJECT.
|
||||
*
|
||||
* If the variant isn't of type GDEXTENSION_VARIANT_TYPE_OBJECT, then zero will be returned.
|
||||
* The instance ID will be returned even if the object is no longer valid - use `object_get_instance_by_id()` to check if the object is still valid.
|
||||
*
|
||||
* @param p_self A pointer to the Variant.
|
||||
*
|
||||
* @return The instance ID for the contained object.
|
||||
*/
|
||||
typedef GDObjectInstanceID (*GDExtensionInterfaceVariantGetObjectInstanceId)(GDExtensionConstVariantPtr p_self);
|
||||
|
||||
/**
|
||||
* @name variant_get_type_name
|
||||
* @since 4.1
|
||||
@@ -1197,6 +1387,23 @@ typedef GDExtensionVariantFromTypeConstructorFunc (*GDExtensionInterfaceGetVaria
|
||||
*/
|
||||
typedef GDExtensionTypeFromVariantConstructorFunc (*GDExtensionInterfaceGetVariantToTypeConstructor)(GDExtensionVariantType p_type);
|
||||
|
||||
/**
|
||||
* @name variant_get_ptr_internal_getter
|
||||
* @since 4.4
|
||||
*
|
||||
* Provides a function pointer for retrieving a pointer to a variant's internal value.
|
||||
* Access to a variant's internal value can be used to modify it in-place, or to retrieve its value without the overhead of variant conversion functions.
|
||||
* It is recommended to cache the getter for all variant types in a function table to avoid retrieval overhead upon use.
|
||||
*
|
||||
* @note Each function assumes the variant's type has already been determined and matches the function.
|
||||
* Invoking the function with a variant of a mismatched type has undefined behavior, and may lead to a segmentation fault.
|
||||
*
|
||||
* @param p_type The Variant type.
|
||||
*
|
||||
* @return A pointer to a type-specific function that returns a pointer to the internal value of a variant. Check the implementation of this function (gdextension_variant_get_ptr_internal_getter) for pointee type info of each variant type.
|
||||
*/
|
||||
typedef GDExtensionVariantGetInternalPtrFunc (*GDExtensionInterfaceGetVariantGetInternalPtrFunc)(GDExtensionVariantType p_type);
|
||||
|
||||
/**
|
||||
* @name variant_get_ptr_operator_evaluator
|
||||
* @since 4.1
|
||||
@@ -1447,6 +1654,7 @@ typedef void (*GDExtensionInterfaceStringNewWithLatin1CharsAndLen)(GDExtensionUn
|
||||
/**
|
||||
* @name string_new_with_utf8_chars_and_len
|
||||
* @since 4.1
|
||||
* @deprecated in Godot 4.3. Use `string_new_with_utf8_chars_and_len2` instead.
|
||||
*
|
||||
* Creates a String from a UTF-8 encoded C string with the given length.
|
||||
*
|
||||
@@ -1456,9 +1664,24 @@ typedef void (*GDExtensionInterfaceStringNewWithLatin1CharsAndLen)(GDExtensionUn
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceStringNewWithUtf8CharsAndLen)(GDExtensionUninitializedStringPtr r_dest, const char *p_contents, GDExtensionInt p_size);
|
||||
|
||||
/**
|
||||
* @name string_new_with_utf8_chars_and_len2
|
||||
* @since 4.3
|
||||
*
|
||||
* Creates a String from a UTF-8 encoded C string with the given length.
|
||||
*
|
||||
* @param r_dest A pointer to a Variant to hold the newly created String.
|
||||
* @param p_contents A pointer to a UTF-8 encoded C string.
|
||||
* @param p_size The number of bytes (not code units).
|
||||
*
|
||||
* @return Error code signifying if the operation successful.
|
||||
*/
|
||||
typedef GDExtensionInt (*GDExtensionInterfaceStringNewWithUtf8CharsAndLen2)(GDExtensionUninitializedStringPtr r_dest, const char *p_contents, GDExtensionInt p_size);
|
||||
|
||||
/**
|
||||
* @name string_new_with_utf16_chars_and_len
|
||||
* @since 4.1
|
||||
* @deprecated in Godot 4.3. Use `string_new_with_utf16_chars_and_len2` instead.
|
||||
*
|
||||
* Creates a String from a UTF-16 encoded C string with the given length.
|
||||
*
|
||||
@@ -1468,6 +1691,21 @@ typedef void (*GDExtensionInterfaceStringNewWithUtf8CharsAndLen)(GDExtensionUnin
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceStringNewWithUtf16CharsAndLen)(GDExtensionUninitializedStringPtr r_dest, const char16_t *p_contents, GDExtensionInt p_char_count);
|
||||
|
||||
/**
|
||||
* @name string_new_with_utf16_chars_and_len2
|
||||
* @since 4.3
|
||||
*
|
||||
* Creates a String from a UTF-16 encoded C string with the given length.
|
||||
*
|
||||
* @param r_dest A pointer to a Variant to hold the newly created String.
|
||||
* @param p_contents A pointer to a UTF-16 encoded C string.
|
||||
* @param p_size The number of characters (not bytes).
|
||||
* @param p_default_little_endian If true, UTF-16 use little endian.
|
||||
*
|
||||
* @return Error code signifying if the operation successful.
|
||||
*/
|
||||
typedef GDExtensionInt (*GDExtensionInterfaceStringNewWithUtf16CharsAndLen2)(GDExtensionUninitializedStringPtr r_dest, const char16_t *p_contents, GDExtensionInt p_char_count, GDExtensionBool p_default_little_endian);
|
||||
|
||||
/**
|
||||
* @name string_new_with_utf32_chars_and_len
|
||||
* @since 4.1
|
||||
@@ -1764,6 +2002,36 @@ typedef void (*GDExtensionInterfaceFileAccessStoreBuffer)(GDExtensionObjectPtr p
|
||||
*/
|
||||
typedef uint64_t (*GDExtensionInterfaceFileAccessGetBuffer)(GDExtensionConstObjectPtr p_instance, uint8_t *p_dst, uint64_t p_length);
|
||||
|
||||
/* INTERFACE: Image Utilities */
|
||||
|
||||
/**
|
||||
* @name image_ptrw
|
||||
* @since 4.3
|
||||
*
|
||||
* Returns writable pointer to internal Image buffer.
|
||||
*
|
||||
* @param p_instance A pointer to a Image object.
|
||||
*
|
||||
* @return Pointer to internal Image buffer.
|
||||
*
|
||||
* @see Image::ptrw()
|
||||
*/
|
||||
typedef uint8_t *(*GDExtensionInterfaceImagePtrw)(GDExtensionObjectPtr p_instance);
|
||||
|
||||
/**
|
||||
* @name image_ptr
|
||||
* @since 4.3
|
||||
*
|
||||
* Returns read only pointer to internal Image buffer.
|
||||
*
|
||||
* @param p_instance A pointer to a Image object.
|
||||
*
|
||||
* @return Pointer to internal Image buffer.
|
||||
*
|
||||
* @see Image::ptr()
|
||||
*/
|
||||
typedef const uint8_t *(*GDExtensionInterfaceImagePtr)(GDExtensionObjectPtr p_instance);
|
||||
|
||||
/* INTERFACE: WorkerThreadPool Utilities */
|
||||
|
||||
/**
|
||||
@@ -1829,32 +2097,6 @@ typedef uint8_t *(*GDExtensionInterfacePackedByteArrayOperatorIndex)(GDExtension
|
||||
*/
|
||||
typedef const uint8_t *(*GDExtensionInterfacePackedByteArrayOperatorIndexConst)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index);
|
||||
|
||||
/**
|
||||
* @name packed_color_array_operator_index
|
||||
* @since 4.1
|
||||
*
|
||||
* Gets a pointer to a color in a PackedColorArray.
|
||||
*
|
||||
* @param p_self A pointer to a PackedColorArray object.
|
||||
* @param p_index The index of the Color to get.
|
||||
*
|
||||
* @return A pointer to the requested Color.
|
||||
*/
|
||||
typedef GDExtensionTypePtr (*GDExtensionInterfacePackedColorArrayOperatorIndex)(GDExtensionTypePtr p_self, GDExtensionInt p_index);
|
||||
|
||||
/**
|
||||
* @name packed_color_array_operator_index_const
|
||||
* @since 4.1
|
||||
*
|
||||
* Gets a const pointer to a color in a PackedColorArray.
|
||||
*
|
||||
* @param p_self A const pointer to a const PackedColorArray object.
|
||||
* @param p_index The index of the Color to get.
|
||||
*
|
||||
* @return A const pointer to the requested Color.
|
||||
*/
|
||||
typedef GDExtensionTypePtr (*GDExtensionInterfacePackedColorArrayOperatorIndexConst)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index);
|
||||
|
||||
/**
|
||||
* @name packed_float32_array_operator_index
|
||||
* @since 4.1
|
||||
@@ -2037,6 +2279,58 @@ typedef GDExtensionTypePtr (*GDExtensionInterfacePackedVector3ArrayOperatorIndex
|
||||
*/
|
||||
typedef GDExtensionTypePtr (*GDExtensionInterfacePackedVector3ArrayOperatorIndexConst)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index);
|
||||
|
||||
/**
|
||||
* @name packed_vector4_array_operator_index
|
||||
* @since 4.3
|
||||
*
|
||||
* Gets a pointer to a Vector4 in a PackedVector4Array.
|
||||
*
|
||||
* @param p_self A pointer to a PackedVector4Array object.
|
||||
* @param p_index The index of the Vector4 to get.
|
||||
*
|
||||
* @return A pointer to the requested Vector4.
|
||||
*/
|
||||
typedef GDExtensionTypePtr (*GDExtensionInterfacePackedVector4ArrayOperatorIndex)(GDExtensionTypePtr p_self, GDExtensionInt p_index);
|
||||
|
||||
/**
|
||||
* @name packed_vector4_array_operator_index_const
|
||||
* @since 4.3
|
||||
*
|
||||
* Gets a const pointer to a Vector4 in a PackedVector4Array.
|
||||
*
|
||||
* @param p_self A const pointer to a PackedVector4Array object.
|
||||
* @param p_index The index of the Vector4 to get.
|
||||
*
|
||||
* @return A const pointer to the requested Vector4.
|
||||
*/
|
||||
typedef GDExtensionTypePtr (*GDExtensionInterfacePackedVector4ArrayOperatorIndexConst)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index);
|
||||
|
||||
/**
|
||||
* @name packed_color_array_operator_index
|
||||
* @since 4.1
|
||||
*
|
||||
* Gets a pointer to a color in a PackedColorArray.
|
||||
*
|
||||
* @param p_self A pointer to a PackedColorArray object.
|
||||
* @param p_index The index of the Color to get.
|
||||
*
|
||||
* @return A pointer to the requested Color.
|
||||
*/
|
||||
typedef GDExtensionTypePtr (*GDExtensionInterfacePackedColorArrayOperatorIndex)(GDExtensionTypePtr p_self, GDExtensionInt p_index);
|
||||
|
||||
/**
|
||||
* @name packed_color_array_operator_index_const
|
||||
* @since 4.1
|
||||
*
|
||||
* Gets a const pointer to a color in a PackedColorArray.
|
||||
*
|
||||
* @param p_self A const pointer to a PackedColorArray object.
|
||||
* @param p_index The index of the Color to get.
|
||||
*
|
||||
* @return A const pointer to the requested Color.
|
||||
*/
|
||||
typedef GDExtensionTypePtr (*GDExtensionInterfacePackedColorArrayOperatorIndexConst)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index);
|
||||
|
||||
/**
|
||||
* @name array_operator_index
|
||||
* @since 4.1
|
||||
@@ -2115,6 +2409,22 @@ typedef GDExtensionVariantPtr (*GDExtensionInterfaceDictionaryOperatorIndex)(GDE
|
||||
*/
|
||||
typedef GDExtensionVariantPtr (*GDExtensionInterfaceDictionaryOperatorIndexConst)(GDExtensionConstTypePtr p_self, GDExtensionConstVariantPtr p_key);
|
||||
|
||||
/**
|
||||
* @name dictionary_set_typed
|
||||
* @since 4.4
|
||||
*
|
||||
* Makes a Dictionary into a typed Dictionary.
|
||||
*
|
||||
* @param p_self A pointer to the Dictionary.
|
||||
* @param p_key_type The type of Variant the Dictionary key will store.
|
||||
* @param p_key_class_name A pointer to a StringName with the name of the object (if p_key_type is GDEXTENSION_VARIANT_TYPE_OBJECT).
|
||||
* @param p_key_script A pointer to a Script object (if p_key_type is GDEXTENSION_VARIANT_TYPE_OBJECT and the base class is extended by a script).
|
||||
* @param p_value_type The type of Variant the Dictionary value will store.
|
||||
* @param p_value_class_name A pointer to a StringName with the name of the object (if p_value_type is GDEXTENSION_VARIANT_TYPE_OBJECT).
|
||||
* @param p_value_script A pointer to a Script object (if p_value_type is GDEXTENSION_VARIANT_TYPE_OBJECT and the base class is extended by a script).
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceDictionarySetTyped)(GDExtensionTypePtr p_self, GDExtensionVariantType p_key_type, GDExtensionConstStringNamePtr p_key_class_name, GDExtensionConstVariantPtr p_key_script, GDExtensionVariantType p_value_type, GDExtensionConstStringNamePtr p_value_class_name, GDExtensionConstVariantPtr p_value_script);
|
||||
|
||||
/* INTERFACE: Object */
|
||||
|
||||
/**
|
||||
@@ -2223,6 +2533,9 @@ typedef void (*GDExtensionInterfaceObjectSetInstance)(GDExtensionObjectPtr p_o,
|
||||
*
|
||||
* Gets the class name of an Object.
|
||||
*
|
||||
* If the GDExtension wraps the Godot object in an abstraction specific to its class, this is the
|
||||
* function that should be used to determine which wrapper to use.
|
||||
*
|
||||
* @param p_object A pointer to the Object.
|
||||
* @param p_library A pointer the library received by the GDExtension's entry point function.
|
||||
* @param r_class_name A pointer to a String to receive the class name.
|
||||
@@ -2268,6 +2581,34 @@ typedef GDExtensionObjectPtr (*GDExtensionInterfaceObjectGetInstanceFromId)(GDOb
|
||||
*/
|
||||
typedef GDObjectInstanceID (*GDExtensionInterfaceObjectGetInstanceId)(GDExtensionConstObjectPtr p_object);
|
||||
|
||||
/**
|
||||
* @name object_has_script_method
|
||||
* @since 4.3
|
||||
*
|
||||
* Checks if this object has a script with the given method.
|
||||
*
|
||||
* @param p_object A pointer to the Object.
|
||||
* @param p_method A pointer to a StringName identifying the method.
|
||||
*
|
||||
* @returns true if the object has a script and that script has a method with the given name. Returns false if the object has no script.
|
||||
*/
|
||||
typedef GDExtensionBool (*GDExtensionInterfaceObjectHasScriptMethod)(GDExtensionConstObjectPtr p_object, GDExtensionConstStringNamePtr p_method);
|
||||
|
||||
/**
|
||||
* @name object_call_script_method
|
||||
* @since 4.3
|
||||
*
|
||||
* Call the given script method on this object.
|
||||
*
|
||||
* @param p_object A pointer to the Object.
|
||||
* @param p_method A pointer to a StringName identifying the method.
|
||||
* @param p_args A pointer to a C array of Variant.
|
||||
* @param p_argument_count The number of arguments.
|
||||
* @param r_return A pointer a Variant which will be assigned the return value.
|
||||
* @param r_error A pointer the structure which will hold error information.
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceObjectCallScriptMethod)(GDExtensionObjectPtr p_object, GDExtensionConstStringNamePtr p_method, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionUninitializedVariantPtr r_return, GDExtensionCallError *r_error);
|
||||
|
||||
/* INTERFACE: Reference */
|
||||
|
||||
/**
|
||||
@@ -2298,7 +2639,7 @@ typedef void (*GDExtensionInterfaceRefSetObject)(GDExtensionRefPtr p_ref, GDExte
|
||||
/**
|
||||
* @name script_instance_create
|
||||
* @since 4.1
|
||||
* @deprecated in Godot 4.2. Use `script_instance_create2` instead.
|
||||
* @deprecated in Godot 4.2. Use `script_instance_create3` instead.
|
||||
*
|
||||
* Creates a script instance that contains the given info and instance data.
|
||||
*
|
||||
@@ -2312,6 +2653,7 @@ typedef GDExtensionScriptInstancePtr (*GDExtensionInterfaceScriptInstanceCreate)
|
||||
/**
|
||||
* @name script_instance_create2
|
||||
* @since 4.2
|
||||
* @deprecated in Godot 4.3. Use `script_instance_create3` instead.
|
||||
*
|
||||
* Creates a script instance that contains the given info and instance data.
|
||||
*
|
||||
@@ -2322,6 +2664,19 @@ typedef GDExtensionScriptInstancePtr (*GDExtensionInterfaceScriptInstanceCreate)
|
||||
*/
|
||||
typedef GDExtensionScriptInstancePtr (*GDExtensionInterfaceScriptInstanceCreate2)(const GDExtensionScriptInstanceInfo2 *p_info, GDExtensionScriptInstanceDataPtr p_instance_data);
|
||||
|
||||
/**
|
||||
* @name script_instance_create3
|
||||
* @since 4.3
|
||||
*
|
||||
* Creates a script instance that contains the given info and instance data.
|
||||
*
|
||||
* @param p_info A pointer to a GDExtensionScriptInstanceInfo3 struct.
|
||||
* @param p_instance_data A pointer to a data representing the script instance in the GDExtension. This will be passed to all the function pointers on p_info.
|
||||
*
|
||||
* @return A pointer to a ScriptInstanceExtension object.
|
||||
*/
|
||||
typedef GDExtensionScriptInstancePtr (*GDExtensionInterfaceScriptInstanceCreate3)(const GDExtensionScriptInstanceInfo3 *p_info, GDExtensionScriptInstanceDataPtr p_instance_data);
|
||||
|
||||
/**
|
||||
* @name placeholder_script_instance_create
|
||||
* @since 4.2
|
||||
@@ -2371,6 +2726,7 @@ typedef GDExtensionScriptInstanceDataPtr (*GDExtensionInterfaceObjectGetScriptIn
|
||||
/**
|
||||
* @name callable_custom_create
|
||||
* @since 4.2
|
||||
* @deprecated in Godot 4.3. Use `callable_custom_create2` instead.
|
||||
*
|
||||
* Creates a custom Callable object from a function pointer.
|
||||
*
|
||||
@@ -2381,6 +2737,19 @@ typedef GDExtensionScriptInstanceDataPtr (*GDExtensionInterfaceObjectGetScriptIn
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceCallableCustomCreate)(GDExtensionUninitializedTypePtr r_callable, GDExtensionCallableCustomInfo *p_callable_custom_info);
|
||||
|
||||
/**
|
||||
* @name callable_custom_create2
|
||||
* @since 4.3
|
||||
*
|
||||
* Creates a custom Callable object from a function pointer.
|
||||
*
|
||||
* Provided struct can be safely freed once the function returns.
|
||||
*
|
||||
* @param r_callable A pointer that will receive the new Callable.
|
||||
* @param p_callable_custom_info The info required to construct a Callable.
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceCallableCustomCreate2)(GDExtensionUninitializedTypePtr r_callable, GDExtensionCallableCustomInfo2 *p_callable_custom_info);
|
||||
|
||||
/**
|
||||
* @name callable_custom_get_userdata
|
||||
* @since 4.2
|
||||
@@ -2399,6 +2768,7 @@ typedef void *(*GDExtensionInterfaceCallableCustomGetUserData)(GDExtensionConstT
|
||||
/**
|
||||
* @name classdb_construct_object
|
||||
* @since 4.1
|
||||
* @deprecated in Godot 4.4. Use `classdb_construct_object2` instead.
|
||||
*
|
||||
* Constructs an Object of the requested class.
|
||||
*
|
||||
@@ -2410,6 +2780,22 @@ typedef void *(*GDExtensionInterfaceCallableCustomGetUserData)(GDExtensionConstT
|
||||
*/
|
||||
typedef GDExtensionObjectPtr (*GDExtensionInterfaceClassdbConstructObject)(GDExtensionConstStringNamePtr p_classname);
|
||||
|
||||
/**
|
||||
* @name classdb_construct_object2
|
||||
* @since 4.4
|
||||
*
|
||||
* Constructs an Object of the requested class.
|
||||
*
|
||||
* The passed class must be a built-in godot class, or an already-registered extension class. In both cases, object_set_instance() should be called to fully initialize the object.
|
||||
*
|
||||
* "NOTIFICATION_POSTINITIALIZE" must be sent after construction.
|
||||
*
|
||||
* @param p_classname A pointer to a StringName with the class name.
|
||||
*
|
||||
* @return A pointer to the newly created Object.
|
||||
*/
|
||||
typedef GDExtensionObjectPtr (*GDExtensionInterfaceClassdbConstructObject2)(GDExtensionConstStringNamePtr p_classname);
|
||||
|
||||
/**
|
||||
* @name classdb_get_method_bind
|
||||
* @since 4.1
|
||||
@@ -2441,7 +2827,7 @@ typedef void *(*GDExtensionInterfaceClassdbGetClassTag)(GDExtensionConstStringNa
|
||||
/**
|
||||
* @name classdb_register_extension_class
|
||||
* @since 4.1
|
||||
* @deprecated in Godot 4.2. Use `classdb_register_extension_class2` instead.
|
||||
* @deprecated in Godot 4.2. Use `classdb_register_extension_class4` instead.
|
||||
*
|
||||
* Registers an extension class in the ClassDB.
|
||||
*
|
||||
@@ -2457,6 +2843,7 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass)(GDExtensionCla
|
||||
/**
|
||||
* @name classdb_register_extension_class2
|
||||
* @since 4.2
|
||||
* @deprecated in Godot 4.3. Use `classdb_register_extension_class4` instead.
|
||||
*
|
||||
* Registers an extension class in the ClassDB.
|
||||
*
|
||||
@@ -2469,6 +2856,37 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass)(GDExtensionCla
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass2)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo2 *p_extension_funcs);
|
||||
|
||||
/**
|
||||
* @name classdb_register_extension_class3
|
||||
* @since 4.3
|
||||
* @deprecated in Godot 4.4. Use `classdb_register_extension_class4` instead.
|
||||
*
|
||||
* Registers an extension class in the ClassDB.
|
||||
*
|
||||
* Provided struct can be safely freed once the function returns.
|
||||
*
|
||||
* @param p_library A pointer the library received by the GDExtension's entry point function.
|
||||
* @param p_class_name A pointer to a StringName with the class name.
|
||||
* @param p_parent_class_name A pointer to a StringName with the parent class name.
|
||||
* @param p_extension_funcs A pointer to a GDExtensionClassCreationInfo2 struct.
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass3)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo3 *p_extension_funcs);
|
||||
|
||||
/**
|
||||
* @name classdb_register_extension_class4
|
||||
* @since 4.4
|
||||
*
|
||||
* Registers an extension class in the ClassDB.
|
||||
*
|
||||
* Provided struct can be safely freed once the function returns.
|
||||
*
|
||||
* @param p_library A pointer the library received by the GDExtension's entry point function.
|
||||
* @param p_class_name A pointer to a StringName with the class name.
|
||||
* @param p_parent_class_name A pointer to a StringName with the parent class name.
|
||||
* @param p_extension_funcs A pointer to a GDExtensionClassCreationInfo2 struct.
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass4)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo4 *p_extension_funcs);
|
||||
|
||||
/**
|
||||
* @name classdb_register_extension_class_method
|
||||
* @since 4.1
|
||||
@@ -2483,18 +2901,36 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass2)(GDExtensionCl
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassMethod)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, const GDExtensionClassMethodInfo *p_method_info);
|
||||
|
||||
/**
|
||||
* @name classdb_register_extension_class_virtual_method
|
||||
* @since 4.3
|
||||
*
|
||||
* Registers a virtual method on an extension class in ClassDB, that can be implemented by scripts or other extensions.
|
||||
*
|
||||
* Provided struct can be safely freed once the function returns.
|
||||
*
|
||||
* @param p_library A pointer the library received by the GDExtension's entry point function.
|
||||
* @param p_class_name A pointer to a StringName with the class name.
|
||||
* @param p_method_info A pointer to a GDExtensionClassMethodInfo struct.
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassVirtualMethod)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, const GDExtensionClassVirtualMethodInfo *p_method_info);
|
||||
|
||||
/**
|
||||
* @name classdb_register_extension_class_integer_constant
|
||||
* @since 4.1
|
||||
*
|
||||
* Registers an integer constant on an extension class in the ClassDB.
|
||||
*
|
||||
* Note about registering bitfield values (if p_is_bitfield is true): even though p_constant_value is signed, language bindings are
|
||||
* advised to treat bitfields as uint64_t, since this is generally clearer and can prevent mistakes like using -1 for setting all bits.
|
||||
* Language APIs should thus provide an abstraction that registers bitfields (uint64_t) separately from regular constants (int64_t).
|
||||
*
|
||||
* @param p_library A pointer the library received by the GDExtension's entry point function.
|
||||
* @param p_class_name A pointer to a StringName with the class name.
|
||||
* @param p_enum_name A pointer to a StringName with the enum name.
|
||||
* @param p_constant_name A pointer to a StringName with the constant name.
|
||||
* @param p_constant_value The constant value.
|
||||
* @param p_is_bitfield Whether or not this is a bit field.
|
||||
* @param p_is_bitfield Whether or not this constant is part of a bitfield.
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_enum_name, GDExtensionConstStringNamePtr p_constant_name, GDExtensionInt p_constant_value, GDExtensionBool p_is_bitfield);
|
||||
|
||||
@@ -2617,6 +3053,31 @@ typedef void (*GDExtensionInterfaceEditorAddPlugin)(GDExtensionConstStringNamePt
|
||||
*/
|
||||
typedef void (*GDExtensionInterfaceEditorRemovePlugin)(GDExtensionConstStringNamePtr p_class_name);
|
||||
|
||||
/**
|
||||
* @name editor_help_load_xml_from_utf8_chars
|
||||
* @since 4.3
|
||||
*
|
||||
* Loads new XML-formatted documentation data in the editor.
|
||||
*
|
||||
* The provided pointer can be immediately freed once the function returns.
|
||||
*
|
||||
* @param p_data A pointer to a UTF-8 encoded C string (null terminated).
|
||||
*/
|
||||
typedef void (*GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8Chars)(const char *p_data);
|
||||
|
||||
/**
|
||||
* @name editor_help_load_xml_from_utf8_chars_and_len
|
||||
* @since 4.3
|
||||
*
|
||||
* Loads new XML-formatted documentation data in the editor.
|
||||
*
|
||||
* The provided pointer can be immediately freed once the function returns.
|
||||
*
|
||||
* @param p_data A pointer to a UTF-8 encoded C string.
|
||||
* @param p_size The number of bytes (not code units).
|
||||
*/
|
||||
typedef void (*GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8CharsAndLen)(const char *p_data, GDExtensionInt p_size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -265,8 +265,8 @@ struct PtrToArg<const Ref<T> &> {
|
||||
|
||||
template <typename T>
|
||||
struct GetTypeInfo<Ref<T>, typename EnableIf<TypeInherits<RefCounted, T>::value>::type> {
|
||||
static const GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_OBJECT;
|
||||
static const GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;
|
||||
static constexpr GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_OBJECT;
|
||||
static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;
|
||||
|
||||
static inline PropertyInfo get_class_info() {
|
||||
return make_property_info(Variant::Type::OBJECT, "", PROPERTY_HINT_RESOURCE_TYPE, T::get_class_static());
|
||||
@@ -275,8 +275,8 @@ struct GetTypeInfo<Ref<T>, typename EnableIf<TypeInherits<RefCounted, T>::value>
|
||||
|
||||
template <typename T>
|
||||
struct GetTypeInfo<const Ref<T> &, typename EnableIf<TypeInherits<RefCounted, T>::value>::type> {
|
||||
static const GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_OBJECT;
|
||||
static const GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;
|
||||
static constexpr GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_OBJECT;
|
||||
static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;
|
||||
|
||||
static inline PropertyInfo get_class_info() {
|
||||
return make_property_info(Variant::Type::OBJECT, "", PROPERTY_HINT_RESOURCE_TYPE, T::get_class_static());
|
||||
|
||||
@@ -36,33 +36,56 @@
|
||||
#include <godot_cpp/core/property_info.hpp>
|
||||
|
||||
#include <godot_cpp/templates/list.hpp>
|
||||
#include <godot_cpp/templates/vector.hpp>
|
||||
|
||||
#include <godot_cpp/godot.hpp>
|
||||
|
||||
#if defined(MACOS_ENABLED) && defined(HOT_RELOAD_ENABLED)
|
||||
#include <mutex>
|
||||
#define _GODOT_CPP_AVOID_THREAD_LOCAL
|
||||
#define _GODOT_CPP_THREAD_LOCAL
|
||||
#else
|
||||
#define _GODOT_CPP_THREAD_LOCAL thread_local
|
||||
#endif
|
||||
|
||||
namespace godot {
|
||||
|
||||
class ClassDB;
|
||||
|
||||
typedef void GodotObject;
|
||||
|
||||
template <typename T, std::enable_if_t<std::is_base_of<::godot::Wrapped, T>::value, bool> = true>
|
||||
_ALWAYS_INLINE_ void _pre_initialize();
|
||||
|
||||
// Base for all engine classes, to contain the pointer to the engine instance.
|
||||
class Wrapped {
|
||||
friend class GDExtensionBinding;
|
||||
friend class ClassDB;
|
||||
friend void postinitialize_handler(Wrapped *);
|
||||
|
||||
protected:
|
||||
#ifdef HOT_RELOAD_ENABLED
|
||||
struct RecreateInstance {
|
||||
GDExtensionClassInstancePtr wrapper;
|
||||
GDExtensionObjectPtr owner;
|
||||
RecreateInstance *next;
|
||||
};
|
||||
inline static RecreateInstance *recreate_instance = nullptr;
|
||||
template <typename T, std::enable_if_t<std::is_base_of<::godot::Wrapped, T>::value, bool>>
|
||||
friend _ALWAYS_INLINE_ void _pre_initialize();
|
||||
|
||||
#ifdef _GODOT_CPP_AVOID_THREAD_LOCAL
|
||||
static std::recursive_mutex _constructing_mutex;
|
||||
#endif
|
||||
|
||||
virtual const StringName *_get_extension_class_name() const; // This is needed to retrieve the class name before the godot object has its _extension and _extension_instance members assigned.
|
||||
virtual const GDExtensionInstanceBindingCallbacks *_get_bindings_callbacks() const = 0;
|
||||
_GODOT_CPP_THREAD_LOCAL static const StringName *_constructing_extension_class_name;
|
||||
_GODOT_CPP_THREAD_LOCAL static const GDExtensionInstanceBindingCallbacks *_constructing_class_binding_callbacks;
|
||||
|
||||
#ifdef HOT_RELOAD_ENABLED
|
||||
_GODOT_CPP_THREAD_LOCAL static GDExtensionObjectPtr _constructing_recreate_owner;
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
_ALWAYS_INLINE_ static void _set_construct_info() {
|
||||
_constructing_extension_class_name = T::_get_extension_class_name();
|
||||
_constructing_class_binding_callbacks = &T::_gde_binding_callbacks;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual bool _is_extension_class() const { return false; }
|
||||
static const StringName *_get_extension_class_name(); // This is needed to retrieve the class name before the godot object has its _extension and _extension_instance members assigned.
|
||||
|
||||
void _notification(int p_what) {}
|
||||
bool _set(const StringName &p_name, const Variant &p_property) { return false; }
|
||||
@@ -77,7 +100,7 @@ protected:
|
||||
static GDExtensionBool set_bind(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionConstVariantPtr p_value) { return false; }
|
||||
static GDExtensionBool get_bind(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret) { return false; }
|
||||
static const GDExtensionPropertyInfo *get_property_list_bind(GDExtensionClassInstancePtr p_instance, uint32_t *r_count) { return nullptr; }
|
||||
static void free_property_list_bind(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list) {}
|
||||
static void free_property_list_bind(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list, uint32_t p_count) {}
|
||||
static GDExtensionBool property_can_revert_bind(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name) { return false; }
|
||||
static GDExtensionBool property_get_revert_bind(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret) { return false; }
|
||||
static GDExtensionBool validate_property_bind(GDExtensionClassInstancePtr p_instance, GDExtensionPropertyInfo *p_property) { return false; }
|
||||
@@ -88,7 +111,6 @@ protected:
|
||||
::godot::List<::godot::PropertyInfo> plist_owned;
|
||||
|
||||
void _postinitialize();
|
||||
virtual void _notificationv(int32_t p_what, bool p_reversed = false) {}
|
||||
|
||||
Wrapped(const StringName p_godot_class);
|
||||
Wrapped(GodotObject *p_godot_object);
|
||||
@@ -108,6 +130,34 @@ public:
|
||||
GodotObject *_owner = nullptr;
|
||||
};
|
||||
|
||||
template <typename T, std::enable_if_t<std::is_base_of<::godot::Wrapped, T>::value, bool>>
|
||||
_ALWAYS_INLINE_ void _pre_initialize() {
|
||||
#ifdef _GODOT_CPP_AVOID_THREAD_LOCAL
|
||||
Wrapped::_constructing_mutex.lock();
|
||||
#endif
|
||||
Wrapped::_set_construct_info<T>();
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void snarray_add_str(Vector<StringName> &arr) {
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void snarray_add_str(Vector<StringName> &arr, const StringName &p_str) {
|
||||
arr.push_back(p_str);
|
||||
}
|
||||
|
||||
template <typename... P>
|
||||
_FORCE_INLINE_ void snarray_add_str(Vector<StringName> &arr, const StringName &p_str, P... p_args) {
|
||||
arr.push_back(p_str);
|
||||
snarray_add_str(arr, p_args...);
|
||||
}
|
||||
|
||||
template <typename... P>
|
||||
_FORCE_INLINE_ Vector<StringName> snarray(P... p_args) {
|
||||
Vector<StringName> arr;
|
||||
snarray_add_str(arr, p_args...);
|
||||
return arr;
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
GDExtensionPropertyInfo *create_c_property_list(const ::godot::List<::godot::PropertyInfo> &plist_cpp, uint32_t *r_size);
|
||||
@@ -140,15 +190,14 @@ struct EngineClassRegistration {
|
||||
private: \
|
||||
void operator=(const m_class & /*p_rval*/) {} \
|
||||
friend class ::godot::ClassDB; \
|
||||
friend class ::godot::Wrapped; \
|
||||
\
|
||||
protected: \
|
||||
virtual const ::godot::StringName *_get_extension_class_name() const override { \
|
||||
static ::godot::StringName string_name = get_class_static(); \
|
||||
return &string_name; \
|
||||
} \
|
||||
virtual bool _is_extension_class() const override { return true; } \
|
||||
\
|
||||
virtual const GDExtensionInstanceBindingCallbacks *_get_bindings_callbacks() const override { \
|
||||
return &_gde_binding_callbacks; \
|
||||
static const ::godot::StringName *_get_extension_class_name() { \
|
||||
const ::godot::StringName &string_name = get_class_static(); \
|
||||
return &string_name; \
|
||||
} \
|
||||
\
|
||||
static void (*_get_bind_methods())() { \
|
||||
@@ -210,7 +259,7 @@ public:
|
||||
} \
|
||||
\
|
||||
static const ::godot::StringName &get_class_static() { \
|
||||
static const ::godot::StringName string_name = ::godot::StringName(#m_class); \
|
||||
static const ::godot::StringName string_name = ::godot::StringName(U## #m_class); \
|
||||
return string_name; \
|
||||
} \
|
||||
\
|
||||
@@ -276,7 +325,7 @@ public:
|
||||
return ::godot::internal::create_c_property_list(plist_cpp, r_count); \
|
||||
} \
|
||||
\
|
||||
static void free_property_list_bind(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list) { \
|
||||
static void free_property_list_bind(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list, uint32_t /*p_count*/) { \
|
||||
if (p_instance) { \
|
||||
m_class *cls = reinterpret_cast<m_class *>(p_instance); \
|
||||
cls->plist_owned.clear(); \
|
||||
@@ -358,11 +407,6 @@ public:
|
||||
_gde_binding_reference_callback, \
|
||||
}; \
|
||||
\
|
||||
protected: \
|
||||
virtual void _notificationv(int32_t p_what, bool p_reversed = false) override { \
|
||||
m_class::notification_bind(this, p_what, p_reversed); \
|
||||
} \
|
||||
\
|
||||
private:
|
||||
|
||||
// Don't use this for your classes, use GDCLASS() instead.
|
||||
@@ -371,12 +415,9 @@ private:
|
||||
inline static ::godot::internal::EngineClassRegistration<m_class> _gde_engine_class_registration_helper; \
|
||||
void operator=(const m_class &p_rval) {} \
|
||||
friend class ::godot::ClassDB; \
|
||||
friend class ::godot::Wrapped; \
|
||||
\
|
||||
protected: \
|
||||
virtual const GDExtensionInstanceBindingCallbacks *_get_bindings_callbacks() const override { \
|
||||
return &_gde_binding_callbacks; \
|
||||
} \
|
||||
\
|
||||
m_class(const char *p_godot_class) : m_inherits(p_godot_class) {} \
|
||||
m_class(GodotObject *p_godot_object) : m_inherits(p_godot_object) {} \
|
||||
\
|
||||
@@ -464,4 +505,11 @@ private:
|
||||
// Don't use this for your classes, use GDCLASS() instead.
|
||||
#define GDEXTENSION_CLASS(m_class, m_inherits) GDEXTENSION_CLASS_ALIAS(m_class, m_class, m_inherits)
|
||||
|
||||
#define GDVIRTUAL_CALL(m_name, ...) _gdvirtual_##m_name##_call(__VA_ARGS__)
|
||||
#define GDVIRTUAL_CALL_PTR(m_obj, m_name, ...) m_obj->_gdvirtual_##m_name##_call(__VA_ARGS__)
|
||||
|
||||
#define GDVIRTUAL_BIND(m_name, ...) ::godot::ClassDB::add_virtual_method(get_class_static(), _gdvirtual_##m_name##_get_method_info(), ::godot::snarray(__VA_ARGS__));
|
||||
#define GDVIRTUAL_IS_OVERRIDDEN(m_name) _gdvirtual_##m_name##_overridden()
|
||||
#define GDVIRTUAL_IS_OVERRIDDEN_PTR(m_obj, m_name) m_obj->_gdvirtual_##m_name##_overridden()
|
||||
|
||||
#endif // GODOT_WRAPPED_HPP
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <godot_cpp/core/error_macros.hpp>
|
||||
#include <godot_cpp/core/method_bind.hpp>
|
||||
#include <godot_cpp/core/object.hpp>
|
||||
#include <godot_cpp/core/print_string.hpp>
|
||||
|
||||
#include <godot_cpp/classes/class_db_singleton.hpp>
|
||||
|
||||
@@ -87,12 +88,17 @@ class ClassDB {
|
||||
|
||||
public:
|
||||
struct ClassInfo {
|
||||
struct VirtualMethod {
|
||||
GDExtensionClassCallVirtual func;
|
||||
uint32_t hash;
|
||||
};
|
||||
|
||||
StringName name;
|
||||
StringName parent_name;
|
||||
GDExtensionInitializationLevel level = GDEXTENSION_INITIALIZATION_SCENE;
|
||||
std::unordered_map<StringName, MethodBind *> method_map;
|
||||
std::set<StringName> signal_names;
|
||||
std::unordered_map<StringName, GDExtensionClassCallVirtual> virtual_methods;
|
||||
std::unordered_map<StringName, VirtualMethod> virtual_methods;
|
||||
std::set<StringName> property_names;
|
||||
std::set<StringName> constant_names;
|
||||
// Pointer to the parent custom class, if any. Will be null if the parent class is a Godot class.
|
||||
@@ -113,12 +119,16 @@ private:
|
||||
static void bind_method_godot(const StringName &p_class_name, MethodBind *p_method);
|
||||
|
||||
template <typename T, bool is_abstract>
|
||||
static void _register_class(bool p_virtual = false, bool p_exposed = true);
|
||||
static void _register_class(bool p_virtual = false, bool p_exposed = true, bool p_runtime = false);
|
||||
|
||||
template <typename T>
|
||||
static GDExtensionObjectPtr _create_instance_func(void *data) {
|
||||
static GDExtensionObjectPtr _create_instance_func(void *data, GDExtensionBool p_notify_postinitialize) {
|
||||
if constexpr (!std::is_abstract_v<T>) {
|
||||
T *new_object = memnew(T);
|
||||
Wrapped::_set_construct_info<T>();
|
||||
T *new_object = new ("", "") T;
|
||||
if (p_notify_postinitialize) {
|
||||
new_object->_postinitialize();
|
||||
}
|
||||
return new_object->_owner;
|
||||
} else {
|
||||
return nullptr;
|
||||
@@ -129,9 +139,11 @@ private:
|
||||
static GDExtensionClassInstancePtr _recreate_instance_func(void *data, GDExtensionObjectPtr obj) {
|
||||
if constexpr (!std::is_abstract_v<T>) {
|
||||
#ifdef HOT_RELOAD_ENABLED
|
||||
#ifdef _GODOT_CPP_AVOID_THREAD_LOCAL
|
||||
std::lock_guard<std::recursive_mutex> lk(Wrapped::_constructing_mutex);
|
||||
#endif
|
||||
Wrapped::_constructing_recreate_owner = obj;
|
||||
T *new_instance = (T *)memalloc(sizeof(T));
|
||||
Wrapped::RecreateInstance recreate_data = { new_instance, obj, Wrapped::recreate_instance };
|
||||
Wrapped::recreate_instance = &recreate_data;
|
||||
memnew_placement(new_instance, T);
|
||||
return new_instance;
|
||||
#else
|
||||
@@ -149,6 +161,8 @@ public:
|
||||
static void register_abstract_class();
|
||||
template <typename T>
|
||||
static void register_internal_class();
|
||||
template <typename T>
|
||||
static void register_runtime_class();
|
||||
|
||||
_FORCE_INLINE_ static void _register_engine_class(const StringName &p_name, const GDExtensionInstanceBindingCallbacks *p_callbacks) {
|
||||
instance_binding_callbacks[p_name] = p_callbacks;
|
||||
@@ -183,11 +197,14 @@ public:
|
||||
static void add_property(const StringName &p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index = -1);
|
||||
static void add_signal(const StringName &p_class, const MethodInfo &p_signal);
|
||||
static void bind_integer_constant(const StringName &p_class_name, const StringName &p_enum_name, const StringName &p_constant_name, GDExtensionInt p_constant_value, bool p_is_bitfield = false);
|
||||
static void bind_virtual_method(const StringName &p_class, const StringName &p_method, GDExtensionClassCallVirtual p_call);
|
||||
// Binds an implementation of a virtual method defined in Godot.
|
||||
static void bind_virtual_method(const StringName &p_class, const StringName &p_method, GDExtensionClassCallVirtual p_call, uint32_t p_hash);
|
||||
// Add a new virtual method that can be implemented by scripts.
|
||||
static void add_virtual_method(const StringName &p_class, const MethodInfo &p_method, const Vector<StringName> &p_arg_names = Vector<StringName>());
|
||||
|
||||
static MethodBind *get_method(const StringName &p_class, const StringName &p_method);
|
||||
|
||||
static GDExtensionClassCallVirtual get_virtual_func(void *p_userdata, GDExtensionConstStringNamePtr p_name);
|
||||
static GDExtensionClassCallVirtual get_virtual_func(void *p_userdata, GDExtensionConstStringNamePtr p_name, uint32_t p_hash);
|
||||
static const GDExtensionInstanceBindingCallbacks *get_instance_binding_callbacks(const StringName &p_class);
|
||||
|
||||
static void initialize(GDExtensionInitializationLevel p_level);
|
||||
@@ -205,16 +222,16 @@ public:
|
||||
#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);
|
||||
|
||||
#define BIND_VIRTUAL_METHOD(m_class, m_method) \
|
||||
#define BIND_VIRTUAL_METHOD(m_class, m_method, m_hash) \
|
||||
{ \
|
||||
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); \
|
||||
}; \
|
||||
::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, m_hash); \
|
||||
}
|
||||
|
||||
template <typename T, bool is_abstract>
|
||||
void ClassDB::_register_class(bool p_virtual, bool p_exposed) {
|
||||
void ClassDB::_register_class(bool p_virtual, bool p_exposed, bool p_runtime) {
|
||||
static_assert(TypesAreSame<typename T::self_type, T>::value, "Class not declared properly, please use GDCLASS.");
|
||||
static_assert(!FunctionsAreSame<T::self_type::_bind_methods, T::parent_type::_bind_methods>::value, "Class must declare 'static void _bind_methods'.");
|
||||
static_assert(!std::is_abstract_v<T> || is_abstract, "Class is abstract, please use GDREGISTER_ABSTRACT_CLASS.");
|
||||
@@ -234,14 +251,16 @@ void ClassDB::_register_class(bool p_virtual, bool p_exposed) {
|
||||
class_register_order.push_back(cl.name);
|
||||
|
||||
// Register this class with Godot
|
||||
GDExtensionClassCreationInfo2 class_info = {
|
||||
GDExtensionClassCreationInfo4 class_info = {
|
||||
p_virtual, // GDExtensionBool is_virtual;
|
||||
is_abstract, // GDExtensionBool is_abstract;
|
||||
p_exposed, // GDExtensionBool is_exposed;
|
||||
p_runtime, // GDExtensionBool is_runtime;
|
||||
nullptr, // GDExtensionConstStringPtr icon_path;
|
||||
T::set_bind, // GDExtensionClassSet set_func;
|
||||
T::get_bind, // GDExtensionClassGet get_func;
|
||||
T::has_get_property_list() ? T::get_property_list_bind : nullptr, // GDExtensionClassGetPropertyList get_property_list_func;
|
||||
T::free_property_list_bind, // GDExtensionClassFreePropertyList free_property_list_func;
|
||||
T::free_property_list_bind, // GDExtensionClassFreePropertyList2 free_property_list_func;
|
||||
T::property_can_revert_bind, // GDExtensionClassPropertyCanRevert property_can_revert_func;
|
||||
T::property_get_revert_bind, // GDExtensionClassPropertyGetRevert property_get_revert_func;
|
||||
T::validate_property_bind, // GDExtensionClassValidateProperty validate_property_func;
|
||||
@@ -255,11 +274,10 @@ void ClassDB::_register_class(bool p_virtual, bool p_exposed) {
|
||||
&ClassDB::get_virtual_func, // GDExtensionClassGetVirtual get_virtual_func;
|
||||
nullptr, // GDExtensionClassGetVirtualCallData get_virtual_call_data_func;
|
||||
nullptr, // GDExtensionClassCallVirtualWithData call_virtual_func;
|
||||
nullptr, // GDExtensionClassGetRID get_rid;
|
||||
(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::gdextension_interface_classdb_register_extension_class4(internal::library, cl.name._native_ptr(), cl.parent_name._native_ptr(), &class_info);
|
||||
|
||||
// call bind_methods etc. to register all members of the class
|
||||
T::initialize_class();
|
||||
@@ -283,6 +301,11 @@ void ClassDB::register_internal_class() {
|
||||
ClassDB::_register_class<T, false>(false, false);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void ClassDB::register_runtime_class() {
|
||||
ClassDB::_register_class<T, false>(false, true, true);
|
||||
}
|
||||
|
||||
template <typename N, typename M, typename... VarArgs>
|
||||
MethodBind *ClassDB::bind_method(N p_method_name, M p_method, VarArgs... p_args) {
|
||||
Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported.
|
||||
@@ -342,6 +365,7 @@ MethodBind *ClassDB::bind_vararg_method(uint32_t p_flags, StringName p_name, M p
|
||||
#define GDREGISTER_VIRTUAL_CLASS(m_class) ::godot::ClassDB::register_class<m_class>(true);
|
||||
#define GDREGISTER_ABSTRACT_CLASS(m_class) ::godot::ClassDB::register_abstract_class<m_class>();
|
||||
#define GDREGISTER_INTERNAL_CLASS(m_class) ::godot::ClassDB::register_internal_class<m_class>();
|
||||
#define GDREGISTER_RUNTIME_CLASS(m_class) ::godot::ClassDB::register_runtime_class<m_class>();
|
||||
|
||||
} // namespace godot
|
||||
|
||||
|
||||
@@ -74,10 +74,6 @@ namespace godot {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef _NO_DISCARD_
|
||||
#define _NO_DISCARD_ [[nodiscard]]
|
||||
#endif
|
||||
|
||||
// Windows badly defines a lot of stuff we'll never use. Undefine it.
|
||||
#ifdef _WIN32
|
||||
#undef min // override standard definition
|
||||
|
||||
@@ -82,6 +82,9 @@ public:
|
||||
static void free_static(void *p_ptr, bool p_pad_align = false);
|
||||
};
|
||||
|
||||
template <typename T, std::enable_if_t<!std::is_base_of<::godot::Wrapped, T>::value, bool> = true>
|
||||
_ALWAYS_INLINE_ void _pre_initialize() {}
|
||||
|
||||
_ALWAYS_INLINE_ void postinitialize_handler(void *) {}
|
||||
|
||||
template <typename T>
|
||||
@@ -94,10 +97,10 @@ _ALWAYS_INLINE_ T *_post_initialize(T *p_obj) {
|
||||
#define memrealloc(m_mem, m_size) ::godot::Memory::realloc_static(m_mem, m_size)
|
||||
#define memfree(m_mem) ::godot::Memory::free_static(m_mem)
|
||||
|
||||
#define memnew(m_class) ::godot::_post_initialize(new ("", "") m_class)
|
||||
#define memnew(m_class) (::godot::_pre_initialize<std::remove_pointer_t<decltype(new ("", "") 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_placement(m_placement, m_class) ::godot::_post_initialize(new ("", m_placement, sizeof(m_class), "") m_class)
|
||||
#define memnew_allocator(m_class, m_allocator) (::godot::_pre_initialize<std::remove_pointer_t<decltype(new ("", "") m_class)>>(), ::godot::_post_initialize(new ("", m_allocator::alloc) m_class))
|
||||
#define memnew_placement(m_placement, m_class) (::godot::_pre_initialize<std::remove_pointer_t<decltype(new ("", "") m_class)>>(), ::godot::_post_initialize(new ("", m_placement, sizeof(m_class), "") m_class))
|
||||
|
||||
// Generic comparator used in Map, List, etc.
|
||||
template <typename T>
|
||||
|
||||
@@ -161,6 +161,7 @@ MAKE_PTRARG(PackedFloat64Array);
|
||||
MAKE_PTRARG(PackedStringArray);
|
||||
MAKE_PTRARG(PackedVector2Array);
|
||||
MAKE_PTRARG(PackedVector3Array);
|
||||
MAKE_PTRARG(PackedVector4Array);
|
||||
MAKE_PTRARG(PackedColorArray);
|
||||
MAKE_PTRARG_BY_REFERENCE(Variant);
|
||||
|
||||
|
||||
@@ -68,6 +68,8 @@ struct MethodInfo {
|
||||
int id = 0;
|
||||
std::vector<PropertyInfo> arguments;
|
||||
std::vector<Variant> default_arguments;
|
||||
GDExtensionClassMethodArgumentMetadata return_val_metadata;
|
||||
std::vector<GDExtensionClassMethodArgumentMetadata> arguments_metadata;
|
||||
|
||||
inline bool operator==(const MethodInfo &p_method) const { return id == p_method.id; }
|
||||
inline bool operator<(const MethodInfo &p_method) const { return id == p_method.id ? (name < p_method.name) : (id < p_method.id); }
|
||||
|
||||
73
include/godot_cpp/core/print_string.hpp
Normal file
73
include/godot_cpp/core/print_string.hpp
Normal file
@@ -0,0 +1,73 @@
|
||||
/**************************************************************************/
|
||||
/* print_string.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_PRINT_STRING_HPP
|
||||
#define GODOT_PRINT_STRING_HPP
|
||||
|
||||
#include <godot_cpp/variant/utility_functions.hpp>
|
||||
|
||||
namespace godot {
|
||||
inline void print_error(const Variant &p_variant) {
|
||||
UtilityFunctions::printerr(p_variant);
|
||||
}
|
||||
|
||||
inline void print_line(const Variant &p_variant) {
|
||||
UtilityFunctions::print(p_variant);
|
||||
}
|
||||
|
||||
inline void print_line_rich(const Variant &p_variant) {
|
||||
UtilityFunctions::print_rich(p_variant);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void print_error(const Variant &p_variant, Args... p_args) {
|
||||
UtilityFunctions::printerr(p_variant, p_args...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void print_line(const Variant &p_variant, Args... p_args) {
|
||||
UtilityFunctions::print(p_variant, p_args...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void print_line_rich(const Variant &p_variant, Args... p_args) {
|
||||
UtilityFunctions::print_rich(p_variant, p_args...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void print_verbose(const Variant &p_variant, Args... p_args) {
|
||||
UtilityFunctions::print_verbose(p_variant, p_args...);
|
||||
}
|
||||
|
||||
bool is_print_verbose_enabled();
|
||||
|
||||
} // namespace godot
|
||||
|
||||
#endif // GODOT_PRINT_STRING_HPP
|
||||
@@ -114,6 +114,17 @@ struct PropertyInfo {
|
||||
p_info->usage = usage;
|
||||
*(reinterpret_cast<StringName *>(p_info->class_name)) = class_name;
|
||||
}
|
||||
|
||||
GDExtensionPropertyInfo _to_gdextension() const {
|
||||
return {
|
||||
(GDExtensionVariantType)type,
|
||||
name._native_ptr(),
|
||||
class_name._native_ptr(),
|
||||
hint,
|
||||
hint_string._native_ptr(),
|
||||
usage,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace godot
|
||||
|
||||
@@ -148,8 +148,8 @@ MAKE_TYPE_INFO_WITH_META(uint32_t, GDEXTENSION_VARIANT_TYPE_INT, GDEXTENSION_MET
|
||||
MAKE_TYPE_INFO_WITH_META(int32_t, GDEXTENSION_VARIANT_TYPE_INT, GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT32)
|
||||
MAKE_TYPE_INFO_WITH_META(uint64_t, GDEXTENSION_VARIANT_TYPE_INT, GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_UINT64)
|
||||
MAKE_TYPE_INFO_WITH_META(int64_t, GDEXTENSION_VARIANT_TYPE_INT, GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT64)
|
||||
MAKE_TYPE_INFO(char16_t, GDEXTENSION_VARIANT_TYPE_INT)
|
||||
MAKE_TYPE_INFO(char32_t, GDEXTENSION_VARIANT_TYPE_INT)
|
||||
MAKE_TYPE_INFO_WITH_META(char16_t, GDEXTENSION_VARIANT_TYPE_INT, GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_CHAR16)
|
||||
MAKE_TYPE_INFO_WITH_META(char32_t, GDEXTENSION_VARIANT_TYPE_INT, GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_CHAR32)
|
||||
MAKE_TYPE_INFO_WITH_META(float, GDEXTENSION_VARIANT_TYPE_FLOAT, GDEXTENSION_METHOD_ARGUMENT_METADATA_REAL_IS_FLOAT)
|
||||
MAKE_TYPE_INFO_WITH_META(double, GDEXTENSION_VARIANT_TYPE_FLOAT, GDEXTENSION_METHOD_ARGUMENT_METADATA_REAL_IS_DOUBLE)
|
||||
|
||||
@@ -185,6 +185,7 @@ MAKE_TYPE_INFO(PackedFloat64Array, GDEXTENSION_VARIANT_TYPE_PACKED_FLOAT64_ARRAY
|
||||
MAKE_TYPE_INFO(PackedStringArray, GDEXTENSION_VARIANT_TYPE_PACKED_STRING_ARRAY)
|
||||
MAKE_TYPE_INFO(PackedVector2Array, GDEXTENSION_VARIANT_TYPE_PACKED_VECTOR2_ARRAY)
|
||||
MAKE_TYPE_INFO(PackedVector3Array, GDEXTENSION_VARIANT_TYPE_PACKED_VECTOR3_ARRAY)
|
||||
MAKE_TYPE_INFO(PackedVector4Array, GDEXTENSION_VARIANT_TYPE_PACKED_VECTOR4_ARRAY)
|
||||
MAKE_TYPE_INFO(PackedColorArray, GDEXTENSION_VARIANT_TYPE_PACKED_COLOR_ARRAY)
|
||||
|
||||
// For variant.
|
||||
@@ -208,8 +209,8 @@ struct GetTypeInfo<const Variant &> {
|
||||
|
||||
template <typename T>
|
||||
struct GetTypeInfo<T *, typename EnableIf<TypeInherits<Object, T>::value>::type> {
|
||||
static const GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_OBJECT;
|
||||
static const GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;
|
||||
static constexpr GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_OBJECT;
|
||||
static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;
|
||||
static inline PropertyInfo get_class_info() {
|
||||
return make_property_info(Variant::Type::OBJECT, "", PROPERTY_HINT_RESOURCE_TYPE, T::get_class_static());
|
||||
}
|
||||
@@ -217,8 +218,8 @@ struct GetTypeInfo<T *, typename EnableIf<TypeInherits<Object, T>::value>::type>
|
||||
|
||||
template <typename T>
|
||||
struct GetTypeInfo<const T *, typename EnableIf<TypeInherits<Object, T>::value>::type> {
|
||||
static const GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_OBJECT;
|
||||
static const GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;
|
||||
static constexpr GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_OBJECT;
|
||||
static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;
|
||||
static inline PropertyInfo get_class_info() {
|
||||
return make_property_info(Variant::Type::OBJECT, "", PROPERTY_HINT_RESOURCE_TYPE, T::get_class_static());
|
||||
}
|
||||
@@ -236,8 +237,8 @@ inline String enum_qualified_name_to_class_info_name(const String &p_qualified_n
|
||||
#define TEMPL_MAKE_ENUM_TYPE_INFO(m_enum, m_impl) \
|
||||
template <> \
|
||||
struct GetTypeInfo<m_impl> { \
|
||||
static const Variant::Type VARIANT_TYPE = Variant::INT; \
|
||||
static const GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE; \
|
||||
static constexpr Variant::Type VARIANT_TYPE = Variant::INT; \
|
||||
static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE; \
|
||||
static inline PropertyInfo get_class_info() { \
|
||||
return make_property_info(Variant::Type::INT, "", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_ENUM, \
|
||||
enum_qualified_name_to_class_info_name(#m_enum)); \
|
||||
@@ -274,8 +275,8 @@ public:
|
||||
#define TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, m_impl) \
|
||||
template <> \
|
||||
struct GetTypeInfo<m_impl> { \
|
||||
static const Variant::Type VARIANT_TYPE = Variant::INT; \
|
||||
static const GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE; \
|
||||
static constexpr Variant::Type VARIANT_TYPE = Variant::INT; \
|
||||
static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE; \
|
||||
static inline PropertyInfo get_class_info() { \
|
||||
return make_property_info(Variant::Type::INT, "", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_BITFIELD, \
|
||||
enum_qualified_name_to_class_info_name(#m_enum)); \
|
||||
@@ -283,8 +284,8 @@ public:
|
||||
}; \
|
||||
template <> \
|
||||
struct GetTypeInfo<BitField<m_impl>> { \
|
||||
static const Variant::Type VARIANT_TYPE = Variant::INT; \
|
||||
static const GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE; \
|
||||
static constexpr Variant::Type VARIANT_TYPE = Variant::INT; \
|
||||
static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE; \
|
||||
static inline PropertyInfo get_class_info() { \
|
||||
return make_property_info(Variant::Type::INT, "", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_BITFIELD, \
|
||||
enum_qualified_name_to_class_info_name(#m_enum)); \
|
||||
@@ -380,11 +381,14 @@ MAKE_TYPED_ARRAY_INFO(Rect2i, Variant::RECT2I)
|
||||
MAKE_TYPED_ARRAY_INFO(Vector3, Variant::VECTOR3)
|
||||
MAKE_TYPED_ARRAY_INFO(Vector3i, Variant::VECTOR3I)
|
||||
MAKE_TYPED_ARRAY_INFO(Transform2D, Variant::TRANSFORM2D)
|
||||
MAKE_TYPED_ARRAY_INFO(Vector4, Variant::VECTOR4)
|
||||
MAKE_TYPED_ARRAY_INFO(Vector4i, Variant::VECTOR4I)
|
||||
MAKE_TYPED_ARRAY_INFO(Plane, Variant::PLANE)
|
||||
MAKE_TYPED_ARRAY_INFO(Quaternion, Variant::QUATERNION)
|
||||
MAKE_TYPED_ARRAY_INFO(AABB, Variant::AABB)
|
||||
MAKE_TYPED_ARRAY_INFO(Basis, Variant::BASIS)
|
||||
MAKE_TYPED_ARRAY_INFO(Transform3D, Variant::TRANSFORM3D)
|
||||
MAKE_TYPED_ARRAY_INFO(Projection, Variant::PROJECTION)
|
||||
MAKE_TYPED_ARRAY_INFO(Color, Variant::COLOR)
|
||||
MAKE_TYPED_ARRAY_INFO(StringName, Variant::STRING_NAME)
|
||||
MAKE_TYPED_ARRAY_INFO(NodePath, Variant::NODE_PATH)
|
||||
@@ -401,7 +405,13 @@ MAKE_TYPED_ARRAY_INFO(PackedFloat64Array, Variant::PACKED_FLOAT64_ARRAY)
|
||||
MAKE_TYPED_ARRAY_INFO(PackedStringArray, Variant::PACKED_STRING_ARRAY)
|
||||
MAKE_TYPED_ARRAY_INFO(PackedVector2Array, Variant::PACKED_VECTOR2_ARRAY)
|
||||
MAKE_TYPED_ARRAY_INFO(PackedVector3Array, Variant::PACKED_VECTOR3_ARRAY)
|
||||
MAKE_TYPED_ARRAY_INFO(PackedVector4Array, Variant::PACKED_VECTOR4_ARRAY)
|
||||
MAKE_TYPED_ARRAY_INFO(PackedColorArray, Variant::PACKED_COLOR_ARRAY)
|
||||
/*
|
||||
MAKE_TYPED_ARRAY_INFO(IPAddress, Variant::STRING)
|
||||
*/
|
||||
|
||||
#undef MAKE_TYPED_ARRAY_INFO
|
||||
|
||||
#define CLASS_INFO(m_type) (GetTypeInfo<m_type *>::get_class_info())
|
||||
|
||||
|
||||
@@ -82,11 +82,13 @@ extern "C" GDExtensionInterfaceVariantGetType gdextension_interface_variant_get_
|
||||
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" GDExtensionInterfaceVariantGetObjectInstanceId gdextension_interface_variant_get_object_instance_id;
|
||||
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" GDExtensionInterfaceGetVariantGetInternalPtrFunc gdextension_interface_variant_get_ptr_internal_getter;
|
||||
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;
|
||||
@@ -108,7 +110,9 @@ extern "C" GDExtensionInterfaceStringNewWithUtf32Chars gdextension_interface_str
|
||||
extern "C" GDExtensionInterfaceStringNewWithWideChars gdextension_interface_string_new_with_wide_chars;
|
||||
extern "C" GDExtensionInterfaceStringNewWithLatin1CharsAndLen gdextension_interface_string_new_with_latin1_chars_and_len;
|
||||
extern "C" GDExtensionInterfaceStringNewWithUtf8CharsAndLen gdextension_interface_string_new_with_utf8_chars_and_len;
|
||||
extern "C" GDExtensionInterfaceStringNewWithUtf8CharsAndLen2 gdextension_interface_string_new_with_utf8_chars_and_len2;
|
||||
extern "C" GDExtensionInterfaceStringNewWithUtf16CharsAndLen gdextension_interface_string_new_with_utf16_chars_and_len;
|
||||
extern "C" GDExtensionInterfaceStringNewWithUtf16CharsAndLen2 gdextension_interface_string_new_with_utf16_chars_and_len2;
|
||||
extern "C" GDExtensionInterfaceStringNewWithUtf32CharsAndLen gdextension_interface_string_new_with_utf32_chars_and_len;
|
||||
extern "C" GDExtensionInterfaceStringNewWithWideCharsAndLen gdextension_interface_string_new_with_wide_chars_and_len;
|
||||
extern "C" GDExtensionInterfaceStringToLatin1Chars gdextension_interface_string_to_latin1_chars;
|
||||
@@ -148,12 +152,15 @@ extern "C" GDExtensionInterfacePackedVector2ArrayOperatorIndex gdextension_inter
|
||||
extern "C" GDExtensionInterfacePackedVector2ArrayOperatorIndexConst gdextension_interface_packed_vector2_array_operator_index_const;
|
||||
extern "C" GDExtensionInterfacePackedVector3ArrayOperatorIndex gdextension_interface_packed_vector3_array_operator_index;
|
||||
extern "C" GDExtensionInterfacePackedVector3ArrayOperatorIndexConst gdextension_interface_packed_vector3_array_operator_index_const;
|
||||
extern "C" GDExtensionInterfacePackedVector4ArrayOperatorIndex gdextension_interface_packed_vector4_array_operator_index;
|
||||
extern "C" GDExtensionInterfacePackedVector4ArrayOperatorIndexConst gdextension_interface_packed_vector4_array_operator_index_const;
|
||||
extern "C" GDExtensionInterfaceArrayOperatorIndex gdextension_interface_array_operator_index;
|
||||
extern "C" GDExtensionInterfaceArrayOperatorIndexConst gdextension_interface_array_operator_index_const;
|
||||
extern "C" GDExtensionInterfaceArrayRef gdextension_interface_array_ref;
|
||||
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" GDExtensionInterfaceDictionarySetTyped gdextension_interface_dictionary_set_typed;
|
||||
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;
|
||||
@@ -166,18 +173,21 @@ extern "C" GDExtensionInterfaceObjectGetClassName gdextension_interface_object_g
|
||||
extern "C" GDExtensionInterfaceObjectCastTo gdextension_interface_object_cast_to;
|
||||
extern "C" GDExtensionInterfaceObjectGetInstanceFromId gdextension_interface_object_get_instance_from_id;
|
||||
extern "C" GDExtensionInterfaceObjectGetInstanceId gdextension_interface_object_get_instance_id;
|
||||
extern "C" GDExtensionInterfaceCallableCustomCreate gdextension_interface_callable_custom_create;
|
||||
extern "C" GDExtensionInterfaceObjectHasScriptMethod gdextension_interface_object_has_script_method;
|
||||
extern "C" GDExtensionInterfaceObjectCallScriptMethod gdextension_interface_object_call_script_method;
|
||||
extern "C" GDExtensionInterfaceCallableCustomCreate2 gdextension_interface_callable_custom_create2;
|
||||
extern "C" 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" GDExtensionInterfaceScriptInstanceCreate3 gdextension_interface_script_instance_create3;
|
||||
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" GDExtensionInterfaceClassdbConstructObject2 gdextension_interface_classdb_construct_object2;
|
||||
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" GDExtensionInterfaceClassdbRegisterExtensionClass4 gdextension_interface_classdb_register_extension_class4;
|
||||
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassMethod gdextension_interface_classdb_register_extension_class_method;
|
||||
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassVirtualMethod gdextension_interface_classdb_register_extension_class_virtual_method;
|
||||
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant gdextension_interface_classdb_register_extension_class_integer_constant;
|
||||
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassProperty gdextension_interface_classdb_register_extension_class_property;
|
||||
extern "C" GDExtensionInterfaceClassdbRegisterExtensionClassPropertyIndexed gdextension_interface_classdb_register_extension_class_property_indexed;
|
||||
@@ -188,6 +198,15 @@ extern "C" GDExtensionInterfaceClassdbUnregisterExtensionClass gdextension_inter
|
||||
extern "C" GDExtensionInterfaceGetLibraryPath gdextension_interface_get_library_path;
|
||||
extern "C" GDExtensionInterfaceEditorAddPlugin gdextension_interface_editor_add_plugin;
|
||||
extern "C" GDExtensionInterfaceEditorRemovePlugin gdextension_interface_editor_remove_plugin;
|
||||
extern "C" GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8Chars gdextension_interface_editor_help_load_xml_from_utf8_chars;
|
||||
extern "C" GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8CharsAndLen gdextension_interface_editor_help_load_xml_from_utf8_chars_and_len;
|
||||
extern "C" GDExtensionInterfaceImagePtrw gdextension_interface_image_ptrw;
|
||||
extern "C" GDExtensionInterfaceImagePtr gdextension_interface_image_ptr;
|
||||
|
||||
class DocDataRegistration {
|
||||
public:
|
||||
DocDataRegistration(const char *p_hash, int p_uncompressed_size, int p_compressed_size, const unsigned char *p_data);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
|
||||
@@ -139,31 +139,6 @@ public:
|
||||
|
||||
typedef T ValueType;
|
||||
|
||||
struct Iterator {
|
||||
_FORCE_INLINE_ T &operator*() const {
|
||||
return E->get();
|
||||
}
|
||||
_FORCE_INLINE_ T *operator->() const { return &E->get(); }
|
||||
_FORCE_INLINE_ Iterator &operator++() {
|
||||
E = E->next();
|
||||
return *this;
|
||||
}
|
||||
_FORCE_INLINE_ Iterator &operator--() {
|
||||
E = E->prev();
|
||||
return *this;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ bool operator==(const Iterator &b) const { return E == b.E; }
|
||||
_FORCE_INLINE_ bool operator!=(const Iterator &b) const { return E != b.E; }
|
||||
|
||||
Iterator(Element *p_E) { E = p_E; }
|
||||
Iterator() {}
|
||||
Iterator(const Iterator &p_it) { E = p_it.E; }
|
||||
|
||||
private:
|
||||
Element *E = nullptr;
|
||||
};
|
||||
|
||||
struct ConstIterator {
|
||||
_FORCE_INLINE_ const T &operator*() const {
|
||||
return E->get();
|
||||
@@ -189,6 +164,35 @@ public:
|
||||
const Element *E = nullptr;
|
||||
};
|
||||
|
||||
struct Iterator {
|
||||
_FORCE_INLINE_ T &operator*() const {
|
||||
return E->get();
|
||||
}
|
||||
_FORCE_INLINE_ T *operator->() const { return &E->get(); }
|
||||
_FORCE_INLINE_ Iterator &operator++() {
|
||||
E = E->next();
|
||||
return *this;
|
||||
}
|
||||
_FORCE_INLINE_ Iterator &operator--() {
|
||||
E = E->prev();
|
||||
return *this;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ bool operator==(const Iterator &b) const { return E == b.E; }
|
||||
_FORCE_INLINE_ bool operator!=(const Iterator &b) const { return E != b.E; }
|
||||
|
||||
Iterator(Element *p_E) { E = p_E; }
|
||||
Iterator() {}
|
||||
Iterator(const Iterator &p_it) { E = p_it.E; }
|
||||
|
||||
operator ConstIterator() const {
|
||||
return ConstIterator(E);
|
||||
}
|
||||
|
||||
private:
|
||||
Element *E = nullptr;
|
||||
};
|
||||
|
||||
_FORCE_INLINE_ Iterator begin() {
|
||||
return Iterator(front());
|
||||
}
|
||||
@@ -519,7 +523,14 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
T &operator[](int p_index) {
|
||||
// Index operator, kept for compatibility.
|
||||
_FORCE_INLINE_ T &operator[](int p_index) {
|
||||
return get(p_index);
|
||||
}
|
||||
|
||||
// Random access to elements, use with care,
|
||||
// do not use for iteration.
|
||||
T &get(int p_index) {
|
||||
CRASH_BAD_INDEX(p_index, size());
|
||||
|
||||
Element *I = front();
|
||||
@@ -532,7 +543,14 @@ public:
|
||||
return I->get();
|
||||
}
|
||||
|
||||
const T &operator[](int p_index) const {
|
||||
// Index operator, kept for compatibility.
|
||||
_FORCE_INLINE_ const T &operator[](int p_index) const {
|
||||
return get(p_index);
|
||||
}
|
||||
|
||||
// Random access to elements, use with care,
|
||||
// do not use for iteration.
|
||||
const T &get(int p_index) const {
|
||||
CRASH_BAD_INDEX(p_index, size());
|
||||
|
||||
const Element *I = front();
|
||||
|
||||
@@ -257,6 +257,10 @@ public:
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool has(const T &p_val) const {
|
||||
return find(p_val) != -1;
|
||||
}
|
||||
|
||||
template <typename C>
|
||||
void sort_custom() {
|
||||
U len = count;
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace godot {
|
||||
|
||||
class Variant;
|
||||
|
||||
struct _NO_DISCARD_ AABB {
|
||||
struct [[nodiscard]] AABB {
|
||||
Vector3 position;
|
||||
Vector3 size;
|
||||
|
||||
@@ -103,7 +103,7 @@ struct _NO_DISCARD_ AABB {
|
||||
_FORCE_INLINE_ void expand_to(const Vector3 &p_vector); /** expand to contain a point if necessary */
|
||||
|
||||
_FORCE_INLINE_ AABB abs() const {
|
||||
return AABB(Vector3(position.x + MIN(size.x, (real_t)0), position.y + MIN(size.y, (real_t)0), position.z + MIN(size.z, (real_t)0)), size.abs());
|
||||
return AABB(position + size.minf(0), size.abs());
|
||||
}
|
||||
|
||||
Variant intersects_segment_bind(const Vector3 &p_from, const Vector3 &p_to) const;
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
namespace godot {
|
||||
|
||||
struct _NO_DISCARD_ Basis {
|
||||
struct [[nodiscard]] Basis {
|
||||
Vector3 rows[3] = {
|
||||
Vector3(1, 0, 0),
|
||||
Vector3(0, 1, 0),
|
||||
|
||||
@@ -41,6 +41,7 @@ class Object;
|
||||
class CallableCustomBase {
|
||||
public:
|
||||
virtual ObjectID get_object() const = 0;
|
||||
virtual int get_argument_count(bool &r_is_valid) const;
|
||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const = 0;
|
||||
virtual ~CallableCustomBase() {}
|
||||
};
|
||||
|
||||
@@ -73,6 +73,11 @@ public:
|
||||
return ObjectID(data.instance->get_instance_id());
|
||||
}
|
||||
|
||||
virtual int get_argument_count(bool &r_is_valid) const override {
|
||||
r_is_valid = true;
|
||||
return sizeof...(P);
|
||||
}
|
||||
|
||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const override {
|
||||
call_with_variant_args(data.instance, data.method, p_arguments, p_argcount, r_call_error);
|
||||
}
|
||||
@@ -110,6 +115,11 @@ public:
|
||||
return ObjectID(data.instance->get_instance_id());
|
||||
}
|
||||
|
||||
virtual int get_argument_count(bool &r_is_valid) const override {
|
||||
r_is_valid = true;
|
||||
return sizeof...(P);
|
||||
}
|
||||
|
||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const override {
|
||||
call_with_variant_args_ret(data.instance, data.method, p_arguments, p_argcount, r_return_value, r_call_error);
|
||||
}
|
||||
@@ -147,6 +157,11 @@ public:
|
||||
return ObjectID(data.instance->get_instance_id());
|
||||
}
|
||||
|
||||
virtual int get_argument_count(bool &r_is_valid) const override {
|
||||
r_is_valid = true;
|
||||
return sizeof...(P);
|
||||
}
|
||||
|
||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const override {
|
||||
call_with_variant_args_retc(data.instance, data.method, p_arguments, p_argcount, r_return_value, r_call_error);
|
||||
}
|
||||
@@ -182,6 +197,11 @@ public:
|
||||
return ObjectID();
|
||||
}
|
||||
|
||||
virtual int get_argument_count(bool &r_is_valid) const override {
|
||||
r_is_valid = true;
|
||||
return sizeof...(P);
|
||||
}
|
||||
|
||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const override {
|
||||
call_with_variant_args_static_ret(data.method, p_arguments, p_argcount, r_return_value, r_call_error);
|
||||
r_return_value = Variant();
|
||||
@@ -218,6 +238,11 @@ public:
|
||||
return ObjectID();
|
||||
}
|
||||
|
||||
virtual int get_argument_count(bool &r_is_valid) const override {
|
||||
r_is_valid = true;
|
||||
return sizeof...(P);
|
||||
}
|
||||
|
||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const override {
|
||||
call_with_variant_args_static_ret(data.method, p_arguments, p_argcount, r_return_value, r_call_error);
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace godot {
|
||||
|
||||
class String;
|
||||
|
||||
struct _NO_DISCARD_ Color {
|
||||
struct [[nodiscard]] Color {
|
||||
union {
|
||||
struct {
|
||||
float r;
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace godot {
|
||||
|
||||
class Variant;
|
||||
|
||||
struct _NO_DISCARD_ Plane {
|
||||
struct [[nodiscard]] Plane {
|
||||
Vector3 normal;
|
||||
real_t d = 0;
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ struct Rect2;
|
||||
struct Transform3D;
|
||||
struct Vector2;
|
||||
|
||||
struct _NO_DISCARD_ Projection {
|
||||
struct [[nodiscard]] Projection {
|
||||
enum Planes {
|
||||
PLANE_NEAR,
|
||||
PLANE_FAR,
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
namespace godot {
|
||||
|
||||
struct _NO_DISCARD_ Quaternion {
|
||||
struct [[nodiscard]] Quaternion {
|
||||
union {
|
||||
struct {
|
||||
real_t x;
|
||||
|
||||
@@ -40,7 +40,7 @@ class String;
|
||||
struct Rect2i;
|
||||
struct Transform2D;
|
||||
|
||||
struct _NO_DISCARD_ Rect2 {
|
||||
struct [[nodiscard]] Rect2 {
|
||||
Point2 position;
|
||||
Size2 size;
|
||||
|
||||
@@ -154,14 +154,12 @@ struct _NO_DISCARD_ Rect2 {
|
||||
return Rect2();
|
||||
}
|
||||
|
||||
new_rect.position.x = Math::max(p_rect.position.x, position.x);
|
||||
new_rect.position.y = Math::max(p_rect.position.y, position.y);
|
||||
new_rect.position = p_rect.position.max(position);
|
||||
|
||||
Point2 p_rect_end = p_rect.position + p_rect.size;
|
||||
Point2 end = position + size;
|
||||
|
||||
new_rect.size.x = Math::min(p_rect_end.x, end.x) - new_rect.position.x;
|
||||
new_rect.size.y = Math::min(p_rect_end.y, end.y) - new_rect.position.y;
|
||||
new_rect.size = p_rect_end.min(end) - new_rect.position;
|
||||
|
||||
return new_rect;
|
||||
}
|
||||
@@ -174,11 +172,9 @@ struct _NO_DISCARD_ Rect2 {
|
||||
#endif
|
||||
Rect2 new_rect;
|
||||
|
||||
new_rect.position.x = Math::min(p_rect.position.x, position.x);
|
||||
new_rect.position.y = Math::min(p_rect.position.y, position.y);
|
||||
new_rect.position = p_rect.position.min(position);
|
||||
|
||||
new_rect.size.x = Math::max(p_rect.position.x + p_rect.size.x, position.x + size.x);
|
||||
new_rect.size.y = Math::max(p_rect.position.y + p_rect.size.y, position.y + size.y);
|
||||
new_rect.size = (p_rect.position + p_rect.size).max(position + size);
|
||||
|
||||
new_rect.size = new_rect.size - new_rect.position; // Make relative again.
|
||||
|
||||
@@ -284,7 +280,7 @@ struct _NO_DISCARD_ Rect2 {
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Rect2 abs() const {
|
||||
return Rect2(Point2(position.x + Math::min(size.x, (real_t)0), position.y + Math::min(size.y, (real_t)0)), size.abs());
|
||||
return Rect2(position + size.minf(0), size.abs());
|
||||
}
|
||||
|
||||
Vector2 get_support(const Vector2 &p_normal) const {
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace godot {
|
||||
class String;
|
||||
struct Rect2;
|
||||
|
||||
struct _NO_DISCARD_ Rect2i {
|
||||
struct [[nodiscard]] Rect2i {
|
||||
Point2i position;
|
||||
Size2i size;
|
||||
|
||||
@@ -97,14 +97,12 @@ struct _NO_DISCARD_ Rect2i {
|
||||
return Rect2i();
|
||||
}
|
||||
|
||||
new_rect.position.x = Math::max(p_rect.position.x, position.x);
|
||||
new_rect.position.y = Math::max(p_rect.position.y, position.y);
|
||||
new_rect.position = p_rect.position.max(position);
|
||||
|
||||
Point2i p_rect_end = p_rect.position + p_rect.size;
|
||||
Point2i end = position + size;
|
||||
|
||||
new_rect.size.x = Math::min(p_rect_end.x, end.x) - new_rect.position.x;
|
||||
new_rect.size.y = Math::min(p_rect_end.y, end.y) - new_rect.position.y;
|
||||
new_rect.size = p_rect_end.min(end) - new_rect.position;
|
||||
|
||||
return new_rect;
|
||||
}
|
||||
@@ -117,11 +115,9 @@ struct _NO_DISCARD_ Rect2i {
|
||||
#endif
|
||||
Rect2i new_rect;
|
||||
|
||||
new_rect.position.x = Math::min(p_rect.position.x, position.x);
|
||||
new_rect.position.y = Math::min(p_rect.position.y, position.y);
|
||||
new_rect.position = p_rect.position.min(position);
|
||||
|
||||
new_rect.size.x = Math::max(p_rect.position.x + p_rect.size.x, position.x + size.x);
|
||||
new_rect.size.y = Math::max(p_rect.position.y + p_rect.size.y, position.y + size.y);
|
||||
new_rect.size = (p_rect.position + p_rect.size).max(position + size);
|
||||
|
||||
new_rect.size = new_rect.size - new_rect.position; // Make relative again.
|
||||
|
||||
@@ -219,7 +215,7 @@ struct _NO_DISCARD_ Rect2i {
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Rect2i abs() const {
|
||||
return Rect2i(Point2i(position.x + Math::min(size.x, 0), position.y + Math::min(size.y, 0)), size.abs());
|
||||
return Rect2i(position + size.mini(0), size.abs());
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void set_end(const Vector2i &p_end) {
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace godot {
|
||||
|
||||
class String;
|
||||
|
||||
struct _NO_DISCARD_ Transform2D {
|
||||
struct [[nodiscard]] Transform2D {
|
||||
// Warning #1: basis of Transform2D is stored differently from Basis. In terms of columns array, the basis matrix looks like "on paper":
|
||||
// M = (columns[0][0] columns[1][0])
|
||||
// (columns[0][1] columns[1][1])
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
namespace godot {
|
||||
|
||||
struct _NO_DISCARD_ Transform3D {
|
||||
struct [[nodiscard]] Transform3D {
|
||||
Basis basis;
|
||||
Vector3 origin;
|
||||
|
||||
|
||||
@@ -85,6 +85,8 @@ public:
|
||||
} \
|
||||
};
|
||||
|
||||
// All Variant::OBJECT types are intentionally omitted from this list because they are handled by
|
||||
// the unspecialized TypedArray definition.
|
||||
MAKE_TYPED_ARRAY(bool, Variant::BOOL)
|
||||
MAKE_TYPED_ARRAY(uint8_t, Variant::INT)
|
||||
MAKE_TYPED_ARRAY(int8_t, Variant::INT)
|
||||
@@ -104,11 +106,14 @@ MAKE_TYPED_ARRAY(Rect2i, Variant::RECT2I)
|
||||
MAKE_TYPED_ARRAY(Vector3, Variant::VECTOR3)
|
||||
MAKE_TYPED_ARRAY(Vector3i, Variant::VECTOR3I)
|
||||
MAKE_TYPED_ARRAY(Transform2D, Variant::TRANSFORM2D)
|
||||
MAKE_TYPED_ARRAY(Vector4, Variant::VECTOR4)
|
||||
MAKE_TYPED_ARRAY(Vector4i, Variant::VECTOR4I)
|
||||
MAKE_TYPED_ARRAY(Plane, Variant::PLANE)
|
||||
MAKE_TYPED_ARRAY(Quaternion, Variant::QUATERNION)
|
||||
MAKE_TYPED_ARRAY(AABB, Variant::AABB)
|
||||
MAKE_TYPED_ARRAY(Basis, Variant::BASIS)
|
||||
MAKE_TYPED_ARRAY(Transform3D, Variant::TRANSFORM3D)
|
||||
MAKE_TYPED_ARRAY(Projection, Variant::PROJECTION)
|
||||
MAKE_TYPED_ARRAY(Color, Variant::COLOR)
|
||||
MAKE_TYPED_ARRAY(StringName, Variant::STRING_NAME)
|
||||
MAKE_TYPED_ARRAY(NodePath, Variant::NODE_PATH)
|
||||
@@ -125,7 +130,12 @@ MAKE_TYPED_ARRAY(PackedFloat64Array, Variant::PACKED_FLOAT64_ARRAY)
|
||||
MAKE_TYPED_ARRAY(PackedStringArray, Variant::PACKED_STRING_ARRAY)
|
||||
MAKE_TYPED_ARRAY(PackedVector2Array, Variant::PACKED_VECTOR2_ARRAY)
|
||||
MAKE_TYPED_ARRAY(PackedVector3Array, Variant::PACKED_VECTOR3_ARRAY)
|
||||
MAKE_TYPED_ARRAY(PackedVector4Array, Variant::PACKED_VECTOR4_ARRAY)
|
||||
MAKE_TYPED_ARRAY(PackedColorArray, Variant::PACKED_COLOR_ARRAY)
|
||||
// If the IPAddress struct is added to godot-cpp, the following could also be added:
|
||||
//MAKE_TYPED_ARRAY(IPAddress, Variant::STRING)
|
||||
|
||||
#undef MAKE_TYPED_ARRAY
|
||||
|
||||
} // namespace godot
|
||||
|
||||
|
||||
439
include/godot_cpp/variant/typed_dictionary.hpp
Normal file
439
include/godot_cpp/variant/typed_dictionary.hpp
Normal file
@@ -0,0 +1,439 @@
|
||||
/**************************************************************************/
|
||||
/* typed_dictionary.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_TYPED_DICTIONARY_HPP
|
||||
#define GODOT_TYPED_DICTIONARY_HPP
|
||||
|
||||
#include <godot_cpp/core/type_info.hpp>
|
||||
#include <godot_cpp/variant/dictionary.hpp>
|
||||
#include <godot_cpp/variant/variant.hpp>
|
||||
|
||||
namespace godot {
|
||||
|
||||
template <typename K, typename V>
|
||||
class TypedDictionary : public Dictionary {
|
||||
public:
|
||||
_FORCE_INLINE_ void operator=(const Dictionary &p_dictionary) {
|
||||
ERR_FAIL_COND_MSG(!is_same_typed(p_dictionary), "Cannot assign a dictionary with a different element type.");
|
||||
Dictionary::operator=(p_dictionary);
|
||||
}
|
||||
_FORCE_INLINE_ TypedDictionary(const Variant &p_variant) :
|
||||
TypedDictionary(Dictionary(p_variant)) {
|
||||
}
|
||||
_FORCE_INLINE_ TypedDictionary(const Dictionary &p_dictionary) {
|
||||
set_typed(Variant::OBJECT, K::get_class_static(), Variant(), Variant::OBJECT, V::get_class_static(), Variant());
|
||||
if (is_same_typed(p_dictionary)) {
|
||||
Dictionary::operator=(p_dictionary);
|
||||
} else {
|
||||
assign(p_dictionary);
|
||||
}
|
||||
}
|
||||
_FORCE_INLINE_ TypedDictionary() {
|
||||
set_typed(Variant::OBJECT, K::get_class_static(), Variant(), Variant::OBJECT, V::get_class_static(), Variant());
|
||||
}
|
||||
};
|
||||
|
||||
//specialization for the rest of variant types
|
||||
|
||||
#define MAKE_TYPED_DICTIONARY_WITH_OBJECT(m_type, m_variant_type) \
|
||||
template <typename T> \
|
||||
class TypedDictionary<T, m_type> : public Dictionary { \
|
||||
public: \
|
||||
_FORCE_INLINE_ void operator=(const Dictionary &p_dictionary) { \
|
||||
ERR_FAIL_COND_MSG(!is_same_typed(p_dictionary), "Cannot assign an dictionary with a different element type."); \
|
||||
Dictionary::operator=(p_dictionary); \
|
||||
} \
|
||||
_FORCE_INLINE_ TypedDictionary(const Variant &p_variant) : \
|
||||
TypedDictionary(Dictionary(p_variant)) { \
|
||||
} \
|
||||
_FORCE_INLINE_ TypedDictionary(const Dictionary &p_dictionary) { \
|
||||
set_typed(Variant::OBJECT, T::get_class_static(), Variant(), m_variant_type, StringName(), Variant()); \
|
||||
if (is_same_typed(p_dictionary)) { \
|
||||
Dictionary::operator=(p_dictionary); \
|
||||
} else { \
|
||||
assign(p_dictionary); \
|
||||
} \
|
||||
} \
|
||||
_FORCE_INLINE_ TypedDictionary() { \
|
||||
set_typed(Variant::OBJECT, T::get_class_static(), Variant(), m_variant_type, StringName(), Variant()); \
|
||||
} \
|
||||
}; \
|
||||
template <typename T> \
|
||||
class TypedDictionary<m_type, T> : public Dictionary { \
|
||||
public: \
|
||||
_FORCE_INLINE_ void operator=(const Dictionary &p_dictionary) { \
|
||||
ERR_FAIL_COND_MSG(!is_same_typed(p_dictionary), "Cannot assign an dictionary with a different element type."); \
|
||||
Dictionary::operator=(p_dictionary); \
|
||||
} \
|
||||
_FORCE_INLINE_ TypedDictionary(const Variant &p_variant) : \
|
||||
TypedDictionary(Dictionary(p_variant)) { \
|
||||
} \
|
||||
_FORCE_INLINE_ TypedDictionary(const Dictionary &p_dictionary) { \
|
||||
set_typed(m_variant_type, StringName(), Variant(), Variant::OBJECT, T::get_class_static(), Variant()); \
|
||||
if (is_same_typed(p_dictionary)) { \
|
||||
Dictionary::operator=(p_dictionary); \
|
||||
} else { \
|
||||
assign(p_dictionary); \
|
||||
} \
|
||||
} \
|
||||
_FORCE_INLINE_ TypedDictionary() { \
|
||||
set_typed(m_variant_type, StringName(), Variant(), Variant::OBJECT, T::get_class_static(), Variant()); \
|
||||
} \
|
||||
};
|
||||
|
||||
#define MAKE_TYPED_DICTIONARY_EXPANDED(m_type_key, m_variant_type_key, m_type_value, m_variant_type_value) \
|
||||
template <> \
|
||||
class TypedDictionary<m_type_key, m_type_value> : public Dictionary { \
|
||||
public: \
|
||||
_FORCE_INLINE_ void operator=(const Dictionary &p_dictionary) { \
|
||||
ERR_FAIL_COND_MSG(!is_same_typed(p_dictionary), "Cannot assign an dictionary with a different element type."); \
|
||||
Dictionary::operator=(p_dictionary); \
|
||||
} \
|
||||
_FORCE_INLINE_ TypedDictionary(const Variant &p_variant) : \
|
||||
TypedDictionary(Dictionary(p_variant)) { \
|
||||
} \
|
||||
_FORCE_INLINE_ TypedDictionary(const Dictionary &p_dictionary) { \
|
||||
set_typed(m_variant_type_key, StringName(), Variant(), m_variant_type_value, StringName(), Variant()); \
|
||||
if (is_same_typed(p_dictionary)) { \
|
||||
Dictionary::operator=(p_dictionary); \
|
||||
} else { \
|
||||
assign(p_dictionary); \
|
||||
} \
|
||||
} \
|
||||
_FORCE_INLINE_ TypedDictionary() { \
|
||||
set_typed(m_variant_type_key, StringName(), Variant(), m_variant_type_value, StringName(), Variant()); \
|
||||
} \
|
||||
};
|
||||
|
||||
#define MAKE_TYPED_DICTIONARY_NIL(m_type, m_variant_type) \
|
||||
MAKE_TYPED_DICTIONARY_WITH_OBJECT(m_type, m_variant_type) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, bool, Variant::BOOL) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, uint8_t, Variant::INT) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, int8_t, Variant::INT) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, uint16_t, Variant::INT) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, int16_t, Variant::INT) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, uint32_t, Variant::INT) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, int32_t, Variant::INT) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, uint64_t, Variant::INT) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, int64_t, Variant::INT) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, float, Variant::FLOAT) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, double, Variant::FLOAT) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, String, Variant::STRING) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, Vector2, Variant::VECTOR2) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, Vector2i, Variant::VECTOR2I) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, Rect2, Variant::RECT2) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, Rect2i, Variant::RECT2I) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, Vector3, Variant::VECTOR3) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, Vector3i, Variant::VECTOR3I) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, Transform2D, Variant::TRANSFORM2D) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, Plane, Variant::PLANE) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, Quaternion, Variant::QUATERNION) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, AABB, Variant::AABB) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, Basis, Variant::BASIS) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, Transform3D, Variant::TRANSFORM3D) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, Color, Variant::COLOR) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, StringName, Variant::STRING_NAME) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, NodePath, Variant::NODE_PATH) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, RID, Variant::RID) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, Callable, Variant::CALLABLE) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, Signal, Variant::SIGNAL) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, Dictionary, Variant::DICTIONARY) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, Array, Variant::ARRAY) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, PackedByteArray, Variant::PACKED_BYTE_ARRAY) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, PackedInt32Array, Variant::PACKED_INT32_ARRAY) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, PackedInt64Array, Variant::PACKED_INT64_ARRAY) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, PackedFloat32Array, Variant::PACKED_FLOAT32_ARRAY) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, PackedFloat64Array, Variant::PACKED_FLOAT64_ARRAY) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, PackedStringArray, Variant::PACKED_STRING_ARRAY) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, PackedVector2Array, Variant::PACKED_VECTOR2_ARRAY) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, PackedVector3Array, Variant::PACKED_VECTOR3_ARRAY) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, PackedColorArray, Variant::PACKED_COLOR_ARRAY) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, PackedVector4Array, Variant::PACKED_VECTOR4_ARRAY) \
|
||||
/*MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, IPAddress, Variant::STRING)*/
|
||||
|
||||
#define MAKE_TYPED_DICTIONARY(m_type, m_variant_type) \
|
||||
MAKE_TYPED_DICTIONARY_EXPANDED(m_type, m_variant_type, Variant, Variant::NIL) \
|
||||
MAKE_TYPED_DICTIONARY_NIL(m_type, m_variant_type)
|
||||
|
||||
MAKE_TYPED_DICTIONARY_NIL(Variant, Variant::NIL)
|
||||
MAKE_TYPED_DICTIONARY(bool, Variant::BOOL)
|
||||
MAKE_TYPED_DICTIONARY(uint8_t, Variant::INT)
|
||||
MAKE_TYPED_DICTIONARY(int8_t, Variant::INT)
|
||||
MAKE_TYPED_DICTIONARY(uint16_t, Variant::INT)
|
||||
MAKE_TYPED_DICTIONARY(int16_t, Variant::INT)
|
||||
MAKE_TYPED_DICTIONARY(uint32_t, Variant::INT)
|
||||
MAKE_TYPED_DICTIONARY(int32_t, Variant::INT)
|
||||
MAKE_TYPED_DICTIONARY(uint64_t, Variant::INT)
|
||||
MAKE_TYPED_DICTIONARY(int64_t, Variant::INT)
|
||||
MAKE_TYPED_DICTIONARY(float, Variant::FLOAT)
|
||||
MAKE_TYPED_DICTIONARY(double, Variant::FLOAT)
|
||||
MAKE_TYPED_DICTIONARY(String, Variant::STRING)
|
||||
MAKE_TYPED_DICTIONARY(Vector2, Variant::VECTOR2)
|
||||
MAKE_TYPED_DICTIONARY(Vector2i, Variant::VECTOR2I)
|
||||
MAKE_TYPED_DICTIONARY(Rect2, Variant::RECT2)
|
||||
MAKE_TYPED_DICTIONARY(Rect2i, Variant::RECT2I)
|
||||
MAKE_TYPED_DICTIONARY(Vector3, Variant::VECTOR3)
|
||||
MAKE_TYPED_DICTIONARY(Vector3i, Variant::VECTOR3I)
|
||||
MAKE_TYPED_DICTIONARY(Transform2D, Variant::TRANSFORM2D)
|
||||
MAKE_TYPED_DICTIONARY(Plane, Variant::PLANE)
|
||||
MAKE_TYPED_DICTIONARY(Quaternion, Variant::QUATERNION)
|
||||
MAKE_TYPED_DICTIONARY(AABB, Variant::AABB)
|
||||
MAKE_TYPED_DICTIONARY(Basis, Variant::BASIS)
|
||||
MAKE_TYPED_DICTIONARY(Transform3D, Variant::TRANSFORM3D)
|
||||
MAKE_TYPED_DICTIONARY(Color, Variant::COLOR)
|
||||
MAKE_TYPED_DICTIONARY(StringName, Variant::STRING_NAME)
|
||||
MAKE_TYPED_DICTIONARY(NodePath, Variant::NODE_PATH)
|
||||
MAKE_TYPED_DICTIONARY(RID, Variant::RID)
|
||||
MAKE_TYPED_DICTIONARY(Callable, Variant::CALLABLE)
|
||||
MAKE_TYPED_DICTIONARY(Signal, Variant::SIGNAL)
|
||||
MAKE_TYPED_DICTIONARY(Dictionary, Variant::DICTIONARY)
|
||||
MAKE_TYPED_DICTIONARY(Array, Variant::ARRAY)
|
||||
MAKE_TYPED_DICTIONARY(PackedByteArray, Variant::PACKED_BYTE_ARRAY)
|
||||
MAKE_TYPED_DICTIONARY(PackedInt32Array, Variant::PACKED_INT32_ARRAY)
|
||||
MAKE_TYPED_DICTIONARY(PackedInt64Array, Variant::PACKED_INT64_ARRAY)
|
||||
MAKE_TYPED_DICTIONARY(PackedFloat32Array, Variant::PACKED_FLOAT32_ARRAY)
|
||||
MAKE_TYPED_DICTIONARY(PackedFloat64Array, Variant::PACKED_FLOAT64_ARRAY)
|
||||
MAKE_TYPED_DICTIONARY(PackedStringArray, Variant::PACKED_STRING_ARRAY)
|
||||
MAKE_TYPED_DICTIONARY(PackedVector2Array, Variant::PACKED_VECTOR2_ARRAY)
|
||||
MAKE_TYPED_DICTIONARY(PackedVector3Array, Variant::PACKED_VECTOR3_ARRAY)
|
||||
MAKE_TYPED_DICTIONARY(PackedColorArray, Variant::PACKED_COLOR_ARRAY)
|
||||
MAKE_TYPED_DICTIONARY(PackedVector4Array, Variant::PACKED_VECTOR4_ARRAY)
|
||||
/*
|
||||
MAKE_TYPED_DICTIONARY(IPAddress, Variant::STRING)
|
||||
*/
|
||||
|
||||
#undef MAKE_TYPED_DICTIONARY
|
||||
#undef MAKE_TYPED_DICTIONARY_NIL
|
||||
#undef MAKE_TYPED_DICTIONARY_EXPANDED
|
||||
#undef MAKE_TYPED_DICTIONARY_WITH_OBJECT
|
||||
|
||||
template <typename K, typename V>
|
||||
struct PtrToArg<TypedDictionary<K, V>> {
|
||||
_FORCE_INLINE_ static TypedDictionary<K, V> convert(const void *p_ptr) {
|
||||
return TypedDictionary<K, V>(*reinterpret_cast<const Dictionary *>(p_ptr));
|
||||
}
|
||||
typedef Dictionary EncodeT;
|
||||
_FORCE_INLINE_ static void encode(TypedDictionary<K, V> p_val, void *p_ptr) {
|
||||
*(Dictionary *)p_ptr = p_val;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename K, typename V>
|
||||
struct PtrToArg<const TypedDictionary<K, V> &> {
|
||||
typedef Dictionary EncodeT;
|
||||
_FORCE_INLINE_ static TypedDictionary<K, V>
|
||||
convert(const void *p_ptr) {
|
||||
return TypedDictionary<K, V>(*reinterpret_cast<const Dictionary *>(p_ptr));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename K, typename V>
|
||||
struct GetTypeInfo<TypedDictionary<K, V>> {
|
||||
static constexpr GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_DICTIONARY;
|
||||
static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;
|
||||
static inline PropertyInfo get_class_info() {
|
||||
return PropertyInfo(Variant::Type::DICTIONARY, String(), PROPERTY_HINT_DICTIONARY_TYPE, vformat("%s;%s", K::get_class_static(), V::get_class_static()));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename K, typename V>
|
||||
struct GetTypeInfo<const TypedDictionary<K, V> &> {
|
||||
static constexpr GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_DICTIONARY;
|
||||
static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE;
|
||||
static inline PropertyInfo get_class_info() {
|
||||
return PropertyInfo(Variant::Type::DICTIONARY, String(), PROPERTY_HINT_DICTIONARY_TYPE, vformat("%s;%s", K::get_class_static(), V::get_class_static()));
|
||||
}
|
||||
};
|
||||
|
||||
#define MAKE_TYPED_DICTIONARY_INFO_WITH_OBJECT(m_type, m_variant_type) \
|
||||
template <typename T> \
|
||||
struct GetTypeInfo<TypedDictionary<T, m_type>> { \
|
||||
static constexpr GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_DICTIONARY; \
|
||||
static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE; \
|
||||
static inline PropertyInfo get_class_info() { \
|
||||
return PropertyInfo(Variant::Type::DICTIONARY, String(), PROPERTY_HINT_DICTIONARY_TYPE, \
|
||||
vformat("%s;%s", T::get_class_static(), m_variant_type == Variant::Type::NIL ? "Variant" : Variant::get_type_name(m_variant_type).utf8().get_data())); \
|
||||
} \
|
||||
}; \
|
||||
template <typename T> \
|
||||
struct GetTypeInfo<const TypedDictionary<T, m_type> &> { \
|
||||
static constexpr GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_DICTIONARY; \
|
||||
static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE; \
|
||||
static inline PropertyInfo get_class_info() { \
|
||||
return PropertyInfo(Variant::Type::DICTIONARY, String(), PROPERTY_HINT_DICTIONARY_TYPE, \
|
||||
vformat("%s;%s", T::get_class_static(), m_variant_type == Variant::Type::NIL ? "Variant" : Variant::get_type_name(m_variant_type).utf8().get_data())); \
|
||||
} \
|
||||
}; \
|
||||
template <typename T> \
|
||||
struct GetTypeInfo<TypedDictionary<m_type, T>> { \
|
||||
static constexpr GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_DICTIONARY; \
|
||||
static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE; \
|
||||
static inline PropertyInfo get_class_info() { \
|
||||
return PropertyInfo(Variant::Type::DICTIONARY, String(), PROPERTY_HINT_DICTIONARY_TYPE, \
|
||||
vformat("%s;%s", m_variant_type == Variant::Type::NIL ? "Variant" : Variant::get_type_name(m_variant_type).utf8().get_data(), T::get_class_static())); \
|
||||
} \
|
||||
}; \
|
||||
template <typename T> \
|
||||
struct GetTypeInfo<const TypedDictionary<m_type, T> &> { \
|
||||
static constexpr GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_DICTIONARY; \
|
||||
static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE; \
|
||||
static inline PropertyInfo get_class_info() { \
|
||||
return PropertyInfo(Variant::Type::DICTIONARY, String(), PROPERTY_HINT_DICTIONARY_TYPE, \
|
||||
vformat("%s;%s", m_variant_type == Variant::Type::NIL ? "Variant" : Variant::get_type_name(m_variant_type).utf8().get_data(), T::get_class_static())); \
|
||||
} \
|
||||
};
|
||||
|
||||
#define MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type_key, m_variant_type_key, m_type_value, m_variant_type_value) \
|
||||
template <> \
|
||||
struct GetTypeInfo<TypedDictionary<m_type_key, m_type_value>> { \
|
||||
static constexpr GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_DICTIONARY; \
|
||||
static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE; \
|
||||
static inline PropertyInfo get_class_info() { \
|
||||
return PropertyInfo(Variant::Type::DICTIONARY, String(), PROPERTY_HINT_DICTIONARY_TYPE, \
|
||||
vformat("%s;%s", m_variant_type_key == Variant::Type::NIL ? "Variant" : Variant::get_type_name(m_variant_type_key).utf8().get_data(), \
|
||||
m_variant_type_value == Variant::Type::NIL ? "Variant" : Variant::get_type_name(m_variant_type_value).utf8().get_data())); \
|
||||
} \
|
||||
}; \
|
||||
template <> \
|
||||
struct GetTypeInfo<const TypedDictionary<m_type_key, m_type_value> &> { \
|
||||
static constexpr GDExtensionVariantType VARIANT_TYPE = GDEXTENSION_VARIANT_TYPE_DICTIONARY; \
|
||||
static constexpr GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE; \
|
||||
static inline PropertyInfo get_class_info() { \
|
||||
return PropertyInfo(Variant::Type::DICTIONARY, String(), PROPERTY_HINT_DICTIONARY_TYPE, \
|
||||
vformat("%s;%s", m_variant_type_key == Variant::Type::NIL ? "Variant" : Variant::get_type_name(m_variant_type_key).utf8().get_data(), \
|
||||
m_variant_type_value == Variant::Type::NIL ? "Variant" : Variant::get_type_name(m_variant_type_value).utf8().get_data())); \
|
||||
} \
|
||||
};
|
||||
|
||||
#define MAKE_TYPED_DICTIONARY_INFO_NIL(m_type, m_variant_type) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_WITH_OBJECT(m_type, m_variant_type) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, bool, Variant::BOOL) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, uint8_t, Variant::INT) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, int8_t, Variant::INT) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, uint16_t, Variant::INT) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, int16_t, Variant::INT) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, uint32_t, Variant::INT) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, int32_t, Variant::INT) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, uint64_t, Variant::INT) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, int64_t, Variant::INT) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, float, Variant::FLOAT) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, double, Variant::FLOAT) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, String, Variant::STRING) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Vector2, Variant::VECTOR2) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Vector2i, Variant::VECTOR2I) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Rect2, Variant::RECT2) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Rect2i, Variant::RECT2I) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Vector3, Variant::VECTOR3) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Vector3i, Variant::VECTOR3I) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Transform2D, Variant::TRANSFORM2D) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Plane, Variant::PLANE) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Quaternion, Variant::QUATERNION) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, AABB, Variant::AABB) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Basis, Variant::BASIS) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Transform3D, Variant::TRANSFORM3D) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Color, Variant::COLOR) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, StringName, Variant::STRING_NAME) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, NodePath, Variant::NODE_PATH) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, RID, Variant::RID) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Callable, Variant::CALLABLE) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Signal, Variant::SIGNAL) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Dictionary, Variant::DICTIONARY) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Array, Variant::ARRAY) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, PackedByteArray, Variant::PACKED_BYTE_ARRAY) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, PackedInt32Array, Variant::PACKED_INT32_ARRAY) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, PackedInt64Array, Variant::PACKED_INT64_ARRAY) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, PackedFloat32Array, Variant::PACKED_FLOAT32_ARRAY) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, PackedFloat64Array, Variant::PACKED_FLOAT64_ARRAY) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, PackedStringArray, Variant::PACKED_STRING_ARRAY) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, PackedVector2Array, Variant::PACKED_VECTOR2_ARRAY) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, PackedVector3Array, Variant::PACKED_VECTOR3_ARRAY) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, PackedVector4Array, Variant::PACKED_VECTOR4_ARRAY) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, PackedColorArray, Variant::PACKED_COLOR_ARRAY) \
|
||||
/* MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, IPAddress, Variant::STRING) */
|
||||
|
||||
#define MAKE_TYPED_DICTIONARY_INFO(m_type, m_variant_type) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_EXPANDED(m_type, m_variant_type, Variant, Variant::NIL) \
|
||||
MAKE_TYPED_DICTIONARY_INFO_NIL(m_type, m_variant_type)
|
||||
|
||||
MAKE_TYPED_DICTIONARY_INFO_NIL(Variant, Variant::NIL)
|
||||
MAKE_TYPED_DICTIONARY_INFO(bool, Variant::BOOL)
|
||||
MAKE_TYPED_DICTIONARY_INFO(uint8_t, Variant::INT)
|
||||
MAKE_TYPED_DICTIONARY_INFO(int8_t, Variant::INT)
|
||||
MAKE_TYPED_DICTIONARY_INFO(uint16_t, Variant::INT)
|
||||
MAKE_TYPED_DICTIONARY_INFO(int16_t, Variant::INT)
|
||||
MAKE_TYPED_DICTIONARY_INFO(uint32_t, Variant::INT)
|
||||
MAKE_TYPED_DICTIONARY_INFO(int32_t, Variant::INT)
|
||||
MAKE_TYPED_DICTIONARY_INFO(uint64_t, Variant::INT)
|
||||
MAKE_TYPED_DICTIONARY_INFO(int64_t, Variant::INT)
|
||||
MAKE_TYPED_DICTIONARY_INFO(float, Variant::FLOAT)
|
||||
MAKE_TYPED_DICTIONARY_INFO(double, Variant::FLOAT)
|
||||
MAKE_TYPED_DICTIONARY_INFO(String, Variant::STRING)
|
||||
MAKE_TYPED_DICTIONARY_INFO(Vector2, Variant::VECTOR2)
|
||||
MAKE_TYPED_DICTIONARY_INFO(Vector2i, Variant::VECTOR2I)
|
||||
MAKE_TYPED_DICTIONARY_INFO(Rect2, Variant::RECT2)
|
||||
MAKE_TYPED_DICTIONARY_INFO(Rect2i, Variant::RECT2I)
|
||||
MAKE_TYPED_DICTIONARY_INFO(Vector3, Variant::VECTOR3)
|
||||
MAKE_TYPED_DICTIONARY_INFO(Vector3i, Variant::VECTOR3I)
|
||||
MAKE_TYPED_DICTIONARY_INFO(Transform2D, Variant::TRANSFORM2D)
|
||||
MAKE_TYPED_DICTIONARY_INFO(Plane, Variant::PLANE)
|
||||
MAKE_TYPED_DICTIONARY_INFO(Quaternion, Variant::QUATERNION)
|
||||
MAKE_TYPED_DICTIONARY_INFO(AABB, Variant::AABB)
|
||||
MAKE_TYPED_DICTIONARY_INFO(Basis, Variant::BASIS)
|
||||
MAKE_TYPED_DICTIONARY_INFO(Transform3D, Variant::TRANSFORM3D)
|
||||
MAKE_TYPED_DICTIONARY_INFO(Color, Variant::COLOR)
|
||||
MAKE_TYPED_DICTIONARY_INFO(StringName, Variant::STRING_NAME)
|
||||
MAKE_TYPED_DICTIONARY_INFO(NodePath, Variant::NODE_PATH)
|
||||
MAKE_TYPED_DICTIONARY_INFO(RID, Variant::RID)
|
||||
MAKE_TYPED_DICTIONARY_INFO(Callable, Variant::CALLABLE)
|
||||
MAKE_TYPED_DICTIONARY_INFO(Signal, Variant::SIGNAL)
|
||||
MAKE_TYPED_DICTIONARY_INFO(Dictionary, Variant::DICTIONARY)
|
||||
MAKE_TYPED_DICTIONARY_INFO(Array, Variant::ARRAY)
|
||||
MAKE_TYPED_DICTIONARY_INFO(PackedByteArray, Variant::PACKED_BYTE_ARRAY)
|
||||
MAKE_TYPED_DICTIONARY_INFO(PackedInt32Array, Variant::PACKED_INT32_ARRAY)
|
||||
MAKE_TYPED_DICTIONARY_INFO(PackedInt64Array, Variant::PACKED_INT64_ARRAY)
|
||||
MAKE_TYPED_DICTIONARY_INFO(PackedFloat32Array, Variant::PACKED_FLOAT32_ARRAY)
|
||||
MAKE_TYPED_DICTIONARY_INFO(PackedFloat64Array, Variant::PACKED_FLOAT64_ARRAY)
|
||||
MAKE_TYPED_DICTIONARY_INFO(PackedStringArray, Variant::PACKED_STRING_ARRAY)
|
||||
MAKE_TYPED_DICTIONARY_INFO(PackedVector2Array, Variant::PACKED_VECTOR2_ARRAY)
|
||||
MAKE_TYPED_DICTIONARY_INFO(PackedVector3Array, Variant::PACKED_VECTOR3_ARRAY)
|
||||
MAKE_TYPED_DICTIONARY_INFO(PackedVector4Array, Variant::PACKED_VECTOR4_ARRAY)
|
||||
MAKE_TYPED_DICTIONARY_INFO(PackedColorArray, Variant::PACKED_COLOR_ARRAY)
|
||||
/*
|
||||
MAKE_TYPED_DICTIONARY_INFO(IPAddress, Variant::STRING)
|
||||
*/
|
||||
|
||||
#undef MAKE_TYPED_DICTIONARY_INFO
|
||||
#undef MAKE_TYPED_DICTIONARY_INFO_NIL
|
||||
#undef MAKE_TYPED_DICTIONARY_INFO_EXPANDED
|
||||
#undef MAKE_TYPED_DICTIONARY_INFO_WITH_OBJECT
|
||||
|
||||
} // namespace godot
|
||||
|
||||
#endif // GODOT_TYPED_DICTIONARY_HPP
|
||||
@@ -49,6 +49,7 @@ class Variant {
|
||||
|
||||
friend class GDExtensionBinding;
|
||||
friend class MethodBind;
|
||||
friend class VariantInternal;
|
||||
|
||||
static void init_bindings();
|
||||
|
||||
@@ -100,6 +101,7 @@ public:
|
||||
PACKED_VECTOR2_ARRAY,
|
||||
PACKED_VECTOR3_ARRAY,
|
||||
PACKED_COLOR_ARRAY,
|
||||
PACKED_VECTOR4_ARRAY,
|
||||
|
||||
VARIANT_MAX
|
||||
};
|
||||
@@ -212,6 +214,7 @@ public:
|
||||
Variant(const PackedVector2Array &v);
|
||||
Variant(const PackedVector3Array &v);
|
||||
Variant(const PackedColorArray &v);
|
||||
Variant(const PackedVector4Array &v);
|
||||
~Variant();
|
||||
|
||||
operator bool() const;
|
||||
@@ -260,6 +263,9 @@ public:
|
||||
operator PackedVector2Array() const;
|
||||
operator PackedVector3Array() const;
|
||||
operator PackedColorArray() const;
|
||||
operator PackedVector4Array() const;
|
||||
|
||||
Object *get_validated_object() const;
|
||||
|
||||
Variant &operator=(const Variant &other);
|
||||
Variant &operator=(Variant &&other);
|
||||
|
||||
509
include/godot_cpp/variant/variant_internal.hpp
Normal file
509
include/godot_cpp/variant/variant_internal.hpp
Normal file
@@ -0,0 +1,509 @@
|
||||
/**************************************************************************/
|
||||
/* variant_internal.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_VARIANT_INTERNAL_HPP
|
||||
#define GODOT_VARIANT_INTERNAL_HPP
|
||||
|
||||
#include <gdextension_interface.h>
|
||||
#include <godot_cpp/variant/variant.hpp>
|
||||
|
||||
namespace godot {
|
||||
// For use when you want to access the internal pointer of a Variant directly.
|
||||
// Use with caution. You need to be sure that the type is correct.
|
||||
|
||||
namespace internal {
|
||||
template <typename T>
|
||||
struct VariantInternalType {};
|
||||
|
||||
template <>
|
||||
struct VariantInternalType<bool> {
|
||||
static constexpr Variant::Type type = Variant::BOOL;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<int64_t> {
|
||||
static constexpr Variant::Type type = Variant::INT;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<double> {
|
||||
static constexpr Variant::Type type = Variant::FLOAT;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<String> {
|
||||
static constexpr Variant::Type type = Variant::STRING;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<Vector2> {
|
||||
static constexpr Variant::Type type = Variant::VECTOR2;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<Vector2i> {
|
||||
static constexpr Variant::Type type = Variant::VECTOR2I;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<Rect2> {
|
||||
static constexpr Variant::Type type = Variant::RECT2;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<Rect2i> {
|
||||
static constexpr Variant::Type type = Variant::RECT2I;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<Vector3> {
|
||||
static constexpr Variant::Type type = Variant::VECTOR3;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<Vector3i> {
|
||||
static constexpr Variant::Type type = Variant::VECTOR3I;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<Transform2D> {
|
||||
static constexpr Variant::Type type = Variant::TRANSFORM2D;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<Vector4> {
|
||||
static constexpr Variant::Type type = Variant::VECTOR4;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<Vector4i> {
|
||||
static constexpr Variant::Type type = Variant::VECTOR4I;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<Plane> {
|
||||
static constexpr Variant::Type type = Variant::PLANE;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<Quaternion> {
|
||||
static constexpr Variant::Type type = Variant::QUATERNION;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<AABB> {
|
||||
static constexpr Variant::Type type = Variant::AABB;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<Basis> {
|
||||
static constexpr Variant::Type type = Variant::BASIS;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<Transform3D> {
|
||||
static constexpr Variant::Type type = Variant::TRANSFORM3D;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<Projection> {
|
||||
static constexpr Variant::Type type = Variant::PROJECTION;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<Color> {
|
||||
static constexpr Variant::Type type = Variant::COLOR;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<StringName> {
|
||||
static constexpr Variant::Type type = Variant::STRING_NAME;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<NodePath> {
|
||||
static constexpr Variant::Type type = Variant::NODE_PATH;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<RID> {
|
||||
static constexpr Variant::Type type = Variant::RID;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<Object *> {
|
||||
static constexpr Variant::Type type = Variant::OBJECT;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<Callable> {
|
||||
static constexpr Variant::Type type = Variant::CALLABLE;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<Signal> {
|
||||
static constexpr Variant::Type type = Variant::SIGNAL;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<Dictionary> {
|
||||
static constexpr Variant::Type type = Variant::DICTIONARY;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<Array> {
|
||||
static constexpr Variant::Type type = Variant::ARRAY;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<PackedByteArray> {
|
||||
static constexpr Variant::Type type = Variant::PACKED_BYTE_ARRAY;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<PackedInt32Array> {
|
||||
static constexpr Variant::Type type = Variant::PACKED_INT32_ARRAY;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<PackedInt64Array> {
|
||||
static constexpr Variant::Type type = Variant::PACKED_INT64_ARRAY;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<PackedFloat32Array> {
|
||||
static constexpr Variant::Type type = Variant::PACKED_FLOAT32_ARRAY;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<PackedFloat64Array> {
|
||||
static constexpr Variant::Type type = Variant::PACKED_FLOAT64_ARRAY;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<PackedStringArray> {
|
||||
static constexpr Variant::Type type = Variant::PACKED_STRING_ARRAY;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<PackedVector2Array> {
|
||||
static constexpr Variant::Type type = Variant::PACKED_VECTOR2_ARRAY;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<PackedVector3Array> {
|
||||
static constexpr Variant::Type type = Variant::PACKED_VECTOR3_ARRAY;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<PackedColorArray> {
|
||||
static constexpr Variant::Type type = Variant::PACKED_COLOR_ARRAY;
|
||||
};
|
||||
template <>
|
||||
struct VariantInternalType<PackedVector4Array> {
|
||||
static constexpr Variant::Type type = Variant::PACKED_VECTOR4_ARRAY;
|
||||
};
|
||||
} //namespace internal
|
||||
|
||||
class VariantInternal {
|
||||
friend class Variant;
|
||||
|
||||
static GDExtensionVariantGetInternalPtrFunc get_internal_func[Variant::VARIANT_MAX];
|
||||
|
||||
static void init_bindings();
|
||||
|
||||
public:
|
||||
template <typename T>
|
||||
_FORCE_INLINE_ static T *get_internal_value(Variant *v) {
|
||||
return static_cast<T *>(get_internal_func[internal::VariantInternalType<T>::type](v));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
_FORCE_INLINE_ static const T *get_internal_value(const Variant *v) {
|
||||
return static_cast<const T *>(get_internal_func[internal::VariantInternalType<T>::type](const_cast<Variant *>(v)));
|
||||
}
|
||||
|
||||
// Atomic types.
|
||||
_FORCE_INLINE_ static bool *get_bool(Variant *v) { return get_internal_value<bool>(v); }
|
||||
_FORCE_INLINE_ static const bool *get_bool(const Variant *v) { return get_internal_value<bool>(v); }
|
||||
_FORCE_INLINE_ static int64_t *get_int(Variant *v) { return get_internal_value<int64_t>(v); }
|
||||
_FORCE_INLINE_ static const int64_t *get_int(const Variant *v) { return get_internal_value<int64_t>(v); }
|
||||
_FORCE_INLINE_ static double *get_float(Variant *v) { return get_internal_value<double>(v); }
|
||||
_FORCE_INLINE_ static const double *get_float(const Variant *v) { return get_internal_value<double>(v); }
|
||||
_FORCE_INLINE_ static String *get_string(Variant *v) { return get_internal_value<String>(v); }
|
||||
_FORCE_INLINE_ static const String *get_string(const Variant *v) { return get_internal_value<String>(v); }
|
||||
|
||||
// Math types.
|
||||
_FORCE_INLINE_ static Vector2 *get_vector2(Variant *v) { return get_internal_value<Vector2>(v); }
|
||||
_FORCE_INLINE_ static const Vector2 *get_vector2(const Variant *v) { return get_internal_value<Vector2>(v); }
|
||||
_FORCE_INLINE_ static Vector2i *get_vector2i(Variant *v) { return get_internal_value<Vector2i>(v); }
|
||||
_FORCE_INLINE_ static const Vector2i *get_vector2i(const Variant *v) { return get_internal_value<Vector2i>(v); }
|
||||
_FORCE_INLINE_ static Rect2 *get_rect2(Variant *v) { return get_internal_value<Rect2>(v); }
|
||||
_FORCE_INLINE_ static const Rect2 *get_rect2(const Variant *v) { return get_internal_value<Rect2>(v); }
|
||||
_FORCE_INLINE_ static Rect2i *get_rect2i(Variant *v) { return get_internal_value<Rect2i>(v); }
|
||||
_FORCE_INLINE_ static const Rect2i *get_rect2i(const Variant *v) { return get_internal_value<Rect2i>(v); }
|
||||
_FORCE_INLINE_ static Vector3 *get_vector3(Variant *v) { return get_internal_value<Vector3>(v); }
|
||||
_FORCE_INLINE_ static const Vector3 *get_vector3(const Variant *v) { return get_internal_value<Vector3>(v); }
|
||||
_FORCE_INLINE_ static Vector3i *get_vector3i(Variant *v) { return get_internal_value<Vector3i>(v); }
|
||||
_FORCE_INLINE_ static const Vector3i *get_vector3i(const Variant *v) { return get_internal_value<Vector3i>(v); }
|
||||
_FORCE_INLINE_ static Vector4 *get_vector4(Variant *v) { return get_internal_value<Vector4>(v); }
|
||||
_FORCE_INLINE_ static const Vector4 *get_vector4(const Variant *v) { return get_internal_value<Vector4>(v); }
|
||||
_FORCE_INLINE_ static Vector4i *get_vector4i(Variant *v) { return get_internal_value<Vector4i>(v); }
|
||||
_FORCE_INLINE_ static const Vector4i *get_vector4i(const Variant *v) { return get_internal_value<Vector4i>(v); }
|
||||
_FORCE_INLINE_ static Transform2D *get_transform2d(Variant *v) { return get_internal_value<Transform2D>(v); }
|
||||
_FORCE_INLINE_ static const Transform2D *get_transform2d(const Variant *v) { return get_internal_value<Transform2D>(v); }
|
||||
_FORCE_INLINE_ static Plane *get_plane(Variant *v) { return get_internal_value<Plane>(v); }
|
||||
_FORCE_INLINE_ static const Plane *get_plane(const Variant *v) { return get_internal_value<Plane>(v); }
|
||||
_FORCE_INLINE_ static Quaternion *get_quaternion(Variant *v) { return get_internal_value<Quaternion>(v); }
|
||||
_FORCE_INLINE_ static const Quaternion *get_quaternion(const Variant *v) { return get_internal_value<Quaternion>(v); }
|
||||
_FORCE_INLINE_ static AABB *get_aabb(Variant *v) { return get_internal_value<AABB>(v); }
|
||||
_FORCE_INLINE_ static const AABB *get_aabb(const Variant *v) { return get_internal_value<AABB>(v); }
|
||||
_FORCE_INLINE_ static Basis *get_basis(Variant *v) { return get_internal_value<Basis>(v); }
|
||||
_FORCE_INLINE_ static const Basis *get_basis(const Variant *v) { return get_internal_value<Basis>(v); }
|
||||
_FORCE_INLINE_ static Transform3D *get_transform(Variant *v) { return get_internal_value<Transform3D>(v); }
|
||||
_FORCE_INLINE_ static const Transform3D *get_transform(const Variant *v) { return get_internal_value<Transform3D>(v); }
|
||||
_FORCE_INLINE_ static Projection *get_projection(Variant *v) { return get_internal_value<Projection>(v); }
|
||||
_FORCE_INLINE_ static const Projection *get_projection(const Variant *v) { return get_internal_value<Projection>(v); }
|
||||
|
||||
// Misc types.
|
||||
_FORCE_INLINE_ static Color *get_color(Variant *v) { return get_internal_value<Color>(v); }
|
||||
_FORCE_INLINE_ static const Color *get_color(const Variant *v) { return get_internal_value<Color>(v); }
|
||||
_FORCE_INLINE_ static StringName *get_string_name(Variant *v) { return get_internal_value<StringName>(v); }
|
||||
_FORCE_INLINE_ static const StringName *get_string_name(const Variant *v) { return get_internal_value<StringName>(v); }
|
||||
_FORCE_INLINE_ static NodePath *get_node_path(Variant *v) { return get_internal_value<NodePath>(v); }
|
||||
_FORCE_INLINE_ static const NodePath *get_node_path(const Variant *v) { return get_internal_value<NodePath>(v); }
|
||||
_FORCE_INLINE_ static RID *get_rid(Variant *v) { return get_internal_value<RID>(v); }
|
||||
_FORCE_INLINE_ static const RID *get_rid(const Variant *v) { return get_internal_value<RID>(v); }
|
||||
_FORCE_INLINE_ static Callable *get_callable(Variant *v) { return get_internal_value<Callable>(v); }
|
||||
_FORCE_INLINE_ static const Callable *get_callable(const Variant *v) { return get_internal_value<Callable>(v); }
|
||||
_FORCE_INLINE_ static Signal *get_signal(Variant *v) { return get_internal_value<Signal>(v); }
|
||||
_FORCE_INLINE_ static const Signal *get_signal(const Variant *v) { return get_internal_value<Signal>(v); }
|
||||
_FORCE_INLINE_ static Dictionary *get_dictionary(Variant *v) { return get_internal_value<Dictionary>(v); }
|
||||
_FORCE_INLINE_ static const Dictionary *get_dictionary(const Variant *v) { return get_internal_value<Dictionary>(v); }
|
||||
_FORCE_INLINE_ static Array *get_array(Variant *v) { return get_internal_value<Array>(v); }
|
||||
_FORCE_INLINE_ static const Array *get_array(const Variant *v) { return get_internal_value<Array>(v); }
|
||||
|
||||
// Typed arrays.
|
||||
_FORCE_INLINE_ static PackedByteArray *get_byte_array(Variant *v) { return get_internal_value<PackedByteArray>(v); }
|
||||
_FORCE_INLINE_ static const PackedByteArray *get_byte_array(const Variant *v) { return get_internal_value<PackedByteArray>(v); }
|
||||
_FORCE_INLINE_ static PackedInt32Array *get_int32_array(Variant *v) { return get_internal_value<PackedInt32Array>(v); }
|
||||
_FORCE_INLINE_ static const PackedInt32Array *get_int32_array(const Variant *v) { return get_internal_value<PackedInt32Array>(v); }
|
||||
_FORCE_INLINE_ static PackedInt64Array *get_int64_array(Variant *v) { return get_internal_value<PackedInt64Array>(v); }
|
||||
_FORCE_INLINE_ static const PackedInt64Array *get_int64_array(const Variant *v) { return get_internal_value<PackedInt64Array>(v); }
|
||||
_FORCE_INLINE_ static PackedFloat32Array *get_float32_array(Variant *v) { return get_internal_value<PackedFloat32Array>(v); }
|
||||
_FORCE_INLINE_ static const PackedFloat32Array *get_float32_array(const Variant *v) { return get_internal_value<PackedFloat32Array>(v); }
|
||||
_FORCE_INLINE_ static PackedFloat64Array *get_float64_array(Variant *v) { return get_internal_value<PackedFloat64Array>(v); }
|
||||
_FORCE_INLINE_ static const PackedFloat64Array *get_float64_array(const Variant *v) { return get_internal_value<PackedFloat64Array>(v); }
|
||||
_FORCE_INLINE_ static PackedStringArray *get_string_array(Variant *v) { return get_internal_value<PackedStringArray>(v); }
|
||||
_FORCE_INLINE_ static const PackedStringArray *get_string_array(const Variant *v) { return get_internal_value<PackedStringArray>(v); }
|
||||
_FORCE_INLINE_ static PackedVector2Array *get_vector2_array(Variant *v) { return get_internal_value<PackedVector2Array>(v); }
|
||||
_FORCE_INLINE_ static const PackedVector2Array *get_vector2_array(const Variant *v) { return get_internal_value<PackedVector2Array>(v); }
|
||||
_FORCE_INLINE_ static PackedVector3Array *get_vector3_array(Variant *v) { return get_internal_value<PackedVector3Array>(v); }
|
||||
_FORCE_INLINE_ static const PackedVector3Array *get_vector3_array(const Variant *v) { return get_internal_value<PackedVector3Array>(v); }
|
||||
_FORCE_INLINE_ static PackedColorArray *get_color_array(Variant *v) { return get_internal_value<PackedColorArray>(v); }
|
||||
_FORCE_INLINE_ static const PackedColorArray *get_color_array(const Variant *v) { return get_internal_value<PackedColorArray>(v); }
|
||||
_FORCE_INLINE_ static PackedVector4Array *get_vector4_array(Variant *v) { return get_internal_value<PackedVector4Array>(v); }
|
||||
_FORCE_INLINE_ static const PackedVector4Array *get_vector4_array(const Variant *v) { return get_internal_value<PackedVector4Array>(v); }
|
||||
|
||||
_FORCE_INLINE_ static Object **get_object(Variant *v) { return get_internal_value<Object *>(v); }
|
||||
_FORCE_INLINE_ static const Object **get_object(const Variant *v) { return (const Object **)get_internal_value<Object *>(v); }
|
||||
|
||||
_FORCE_INLINE_ static void *get_opaque_pointer(Variant *v) {
|
||||
switch (v->get_type()) {
|
||||
case Variant::NIL:
|
||||
return nullptr;
|
||||
case Variant::BOOL:
|
||||
return get_bool(v);
|
||||
case Variant::INT:
|
||||
return get_int(v);
|
||||
case Variant::FLOAT:
|
||||
return get_float(v);
|
||||
case Variant::STRING:
|
||||
return get_string(v);
|
||||
case Variant::VECTOR2:
|
||||
return get_vector2(v);
|
||||
case Variant::VECTOR2I:
|
||||
return get_vector2i(v);
|
||||
case Variant::VECTOR3:
|
||||
return get_vector3(v);
|
||||
case Variant::VECTOR3I:
|
||||
return get_vector3i(v);
|
||||
case Variant::VECTOR4:
|
||||
return get_vector4(v);
|
||||
case Variant::VECTOR4I:
|
||||
return get_vector4i(v);
|
||||
case Variant::RECT2:
|
||||
return get_rect2(v);
|
||||
case Variant::RECT2I:
|
||||
return get_rect2i(v);
|
||||
case Variant::TRANSFORM3D:
|
||||
return get_transform(v);
|
||||
case Variant::PROJECTION:
|
||||
return get_projection(v);
|
||||
case Variant::TRANSFORM2D:
|
||||
return get_transform2d(v);
|
||||
case Variant::QUATERNION:
|
||||
return get_quaternion(v);
|
||||
case Variant::PLANE:
|
||||
return get_plane(v);
|
||||
case Variant::BASIS:
|
||||
return get_basis(v);
|
||||
case Variant::AABB:
|
||||
return get_aabb(v);
|
||||
case Variant::COLOR:
|
||||
return get_color(v);
|
||||
case Variant::STRING_NAME:
|
||||
return get_string_name(v);
|
||||
case Variant::NODE_PATH:
|
||||
return get_node_path(v);
|
||||
case Variant::RID:
|
||||
return get_rid(v);
|
||||
case Variant::CALLABLE:
|
||||
return get_callable(v);
|
||||
case Variant::SIGNAL:
|
||||
return get_signal(v);
|
||||
case Variant::DICTIONARY:
|
||||
return get_dictionary(v);
|
||||
case Variant::ARRAY:
|
||||
return get_array(v);
|
||||
case Variant::PACKED_BYTE_ARRAY:
|
||||
return get_byte_array(v);
|
||||
case Variant::PACKED_INT32_ARRAY:
|
||||
return get_int32_array(v);
|
||||
case Variant::PACKED_INT64_ARRAY:
|
||||
return get_int64_array(v);
|
||||
case Variant::PACKED_FLOAT32_ARRAY:
|
||||
return get_float32_array(v);
|
||||
case Variant::PACKED_FLOAT64_ARRAY:
|
||||
return get_float64_array(v);
|
||||
case Variant::PACKED_STRING_ARRAY:
|
||||
return get_string_array(v);
|
||||
case Variant::PACKED_VECTOR2_ARRAY:
|
||||
return get_vector2_array(v);
|
||||
case Variant::PACKED_VECTOR3_ARRAY:
|
||||
return get_vector3_array(v);
|
||||
case Variant::PACKED_COLOR_ARRAY:
|
||||
return get_color_array(v);
|
||||
case Variant::PACKED_VECTOR4_ARRAY:
|
||||
return get_vector4_array(v);
|
||||
case Variant::OBJECT:
|
||||
return get_object(v);
|
||||
case Variant::VARIANT_MAX:
|
||||
ERR_FAIL_V(nullptr);
|
||||
}
|
||||
ERR_FAIL_V(nullptr);
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ static const void *get_opaque_pointer(const Variant *v) {
|
||||
switch (v->get_type()) {
|
||||
case Variant::NIL:
|
||||
return nullptr;
|
||||
case Variant::BOOL:
|
||||
return get_bool(v);
|
||||
case Variant::INT:
|
||||
return get_int(v);
|
||||
case Variant::FLOAT:
|
||||
return get_float(v);
|
||||
case Variant::STRING:
|
||||
return get_string(v);
|
||||
case Variant::VECTOR2:
|
||||
return get_vector2(v);
|
||||
case Variant::VECTOR2I:
|
||||
return get_vector2i(v);
|
||||
case Variant::VECTOR3:
|
||||
return get_vector3(v);
|
||||
case Variant::VECTOR3I:
|
||||
return get_vector3i(v);
|
||||
case Variant::VECTOR4:
|
||||
return get_vector4(v);
|
||||
case Variant::VECTOR4I:
|
||||
return get_vector4i(v);
|
||||
case Variant::RECT2:
|
||||
return get_rect2(v);
|
||||
case Variant::RECT2I:
|
||||
return get_rect2i(v);
|
||||
case Variant::TRANSFORM3D:
|
||||
return get_transform(v);
|
||||
case Variant::PROJECTION:
|
||||
return get_projection(v);
|
||||
case Variant::TRANSFORM2D:
|
||||
return get_transform2d(v);
|
||||
case Variant::QUATERNION:
|
||||
return get_quaternion(v);
|
||||
case Variant::PLANE:
|
||||
return get_plane(v);
|
||||
case Variant::BASIS:
|
||||
return get_basis(v);
|
||||
case Variant::AABB:
|
||||
return get_aabb(v);
|
||||
case Variant::COLOR:
|
||||
return get_color(v);
|
||||
case Variant::STRING_NAME:
|
||||
return get_string_name(v);
|
||||
case Variant::NODE_PATH:
|
||||
return get_node_path(v);
|
||||
case Variant::RID:
|
||||
return get_rid(v);
|
||||
case Variant::CALLABLE:
|
||||
return get_callable(v);
|
||||
case Variant::SIGNAL:
|
||||
return get_signal(v);
|
||||
case Variant::DICTIONARY:
|
||||
return get_dictionary(v);
|
||||
case Variant::ARRAY:
|
||||
return get_array(v);
|
||||
case Variant::PACKED_BYTE_ARRAY:
|
||||
return get_byte_array(v);
|
||||
case Variant::PACKED_INT32_ARRAY:
|
||||
return get_int32_array(v);
|
||||
case Variant::PACKED_INT64_ARRAY:
|
||||
return get_int64_array(v);
|
||||
case Variant::PACKED_FLOAT32_ARRAY:
|
||||
return get_float32_array(v);
|
||||
case Variant::PACKED_FLOAT64_ARRAY:
|
||||
return get_float64_array(v);
|
||||
case Variant::PACKED_STRING_ARRAY:
|
||||
return get_string_array(v);
|
||||
case Variant::PACKED_VECTOR2_ARRAY:
|
||||
return get_vector2_array(v);
|
||||
case Variant::PACKED_VECTOR3_ARRAY:
|
||||
return get_vector3_array(v);
|
||||
case Variant::PACKED_COLOR_ARRAY:
|
||||
return get_color_array(v);
|
||||
case Variant::PACKED_VECTOR4_ARRAY:
|
||||
return get_vector4_array(v);
|
||||
case Variant::OBJECT:
|
||||
return get_object(v);
|
||||
case Variant::VARIANT_MAX:
|
||||
ERR_FAIL_V(nullptr);
|
||||
}
|
||||
ERR_FAIL_V(nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct VariantGetInternalPtr {
|
||||
static internal::VariantInternalType<T> *get_ptr(Variant *v) { return VariantInternal::get_internal_value<T>(v); }
|
||||
static const internal::VariantInternalType<T> *get_ptr(const Variant *v) { return VariantInternal::get_internal_value<T>(v); }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct can_set_variant_internal_value {
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct can_set_variant_internal_value<Object *> {
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct VariantInternalAccessor {
|
||||
static _FORCE_INLINE_ const T &get(const Variant *v) { return *VariantInternal::get_internal_value<T>(v); }
|
||||
|
||||
// Enable set() only for those types where we can set (all but Object *).
|
||||
template <typename U = T, typename = std::enable_if_t<can_set_variant_internal_value<U>::value>>
|
||||
static _FORCE_INLINE_ void set(Variant *v, const internal::VariantInternalType<U> &p_value) {
|
||||
*VariantInternal::get_internal_value<U>(v) = p_value;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, std::enable_if_t<can_set_variant_internal_value<T>::value>>
|
||||
struct VariantDefaultInitializer {
|
||||
static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_internal_value<T>(v) = T(); }
|
||||
};
|
||||
|
||||
} // namespace godot
|
||||
|
||||
#endif // GODOT_VARIANT_INTERNAL_HPP
|
||||
@@ -39,7 +39,7 @@ namespace godot {
|
||||
class String;
|
||||
struct Vector2i;
|
||||
|
||||
struct _NO_DISCARD_ Vector2 {
|
||||
struct [[nodiscard]] Vector2 {
|
||||
static const int AXIS_COUNT = 2;
|
||||
|
||||
enum Axis {
|
||||
@@ -91,10 +91,18 @@ struct _NO_DISCARD_ Vector2 {
|
||||
return Vector2(MIN(x, p_vector2.x), MIN(y, p_vector2.y));
|
||||
}
|
||||
|
||||
Vector2 minf(real_t p_scalar) const {
|
||||
return Vector2(MIN(x, p_scalar), MIN(y, p_scalar));
|
||||
}
|
||||
|
||||
Vector2 max(const Vector2 &p_vector2) const {
|
||||
return Vector2(MAX(x, p_vector2.x), MAX(y, p_vector2.y));
|
||||
}
|
||||
|
||||
Vector2 maxf(real_t p_scalar) const {
|
||||
return Vector2(MAX(x, p_scalar), MAX(y, p_scalar));
|
||||
}
|
||||
|
||||
real_t distance_to(const Vector2 &p_vector2) const;
|
||||
real_t distance_squared_to(const Vector2 &p_vector2) const;
|
||||
real_t angle_to(const Vector2 &p_vector2) const;
|
||||
@@ -169,7 +177,9 @@ struct _NO_DISCARD_ Vector2 {
|
||||
Vector2 ceil() const;
|
||||
Vector2 round() const;
|
||||
Vector2 snapped(const Vector2 &p_by) const;
|
||||
Vector2 snappedf(real_t p_by) const;
|
||||
Vector2 clamp(const Vector2 &p_min, const Vector2 &p_max) const;
|
||||
Vector2 clampf(real_t p_min, real_t p_max) const;
|
||||
real_t aspect() const { return width / height; }
|
||||
|
||||
operator String() const;
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace godot {
|
||||
class String;
|
||||
struct Vector2;
|
||||
|
||||
struct _NO_DISCARD_ Vector2i {
|
||||
struct [[nodiscard]] Vector2i {
|
||||
static const int AXIS_COUNT = 2;
|
||||
|
||||
enum Axis {
|
||||
@@ -83,10 +83,18 @@ struct _NO_DISCARD_ Vector2i {
|
||||
return Vector2i(MIN(x, p_vector2i.x), MIN(y, p_vector2i.y));
|
||||
}
|
||||
|
||||
Vector2i mini(int32_t p_scalar) const {
|
||||
return Vector2i(MIN(x, p_scalar), MIN(y, p_scalar));
|
||||
}
|
||||
|
||||
Vector2i max(const Vector2i &p_vector2i) const {
|
||||
return Vector2i(MAX(x, p_vector2i.x), MAX(y, p_vector2i.y));
|
||||
}
|
||||
|
||||
Vector2i maxi(int32_t p_scalar) const {
|
||||
return Vector2i(MAX(x, p_scalar), MAX(y, p_scalar));
|
||||
}
|
||||
|
||||
Vector2i operator+(const Vector2i &p_v) const;
|
||||
void operator+=(const Vector2i &p_v);
|
||||
Vector2i operator-(const Vector2i &p_v) const;
|
||||
@@ -117,10 +125,16 @@ struct _NO_DISCARD_ Vector2i {
|
||||
int64_t length_squared() const;
|
||||
double length() const;
|
||||
|
||||
int64_t distance_squared_to(const Vector2i &p_to) const;
|
||||
double distance_to(const Vector2i &p_to) const;
|
||||
|
||||
real_t aspect() const { return width / (real_t)height; }
|
||||
Vector2i sign() const { return Vector2i(SIGN(x), SIGN(y)); }
|
||||
Vector2i abs() const { return Vector2i(Math::abs(x), Math::abs(y)); }
|
||||
Vector2i snapped(const Vector2i &p_step) const;
|
||||
Vector2i snappedi(int32_t p_step) const;
|
||||
Vector2i clamp(const Vector2i &p_min, const Vector2i &p_max) const;
|
||||
Vector2i clampi(int32_t p_min, int32_t p_max) const;
|
||||
|
||||
operator String() const;
|
||||
operator Vector2() const;
|
||||
|
||||
@@ -41,7 +41,7 @@ struct Basis;
|
||||
struct Vector2;
|
||||
struct Vector3i;
|
||||
|
||||
struct _NO_DISCARD_ Vector3 {
|
||||
struct [[nodiscard]] Vector3 {
|
||||
static const int AXIS_COUNT = 3;
|
||||
|
||||
enum Axis {
|
||||
@@ -82,10 +82,18 @@ struct _NO_DISCARD_ Vector3 {
|
||||
return Vector3(MIN(x, p_vector3.x), MIN(y, p_vector3.y), MIN(z, p_vector3.z));
|
||||
}
|
||||
|
||||
Vector3 minf(real_t p_scalar) const {
|
||||
return Vector3(MIN(x, p_scalar), MIN(y, p_scalar), MIN(z, p_scalar));
|
||||
}
|
||||
|
||||
Vector3 max(const Vector3 &p_vector3) const {
|
||||
return Vector3(MAX(x, p_vector3.x), MAX(y, p_vector3.y), MAX(z, p_vector3.z));
|
||||
}
|
||||
|
||||
Vector3 maxf(real_t p_scalar) const {
|
||||
return Vector3(MAX(x, p_scalar), MAX(y, p_scalar), MAX(z, p_scalar));
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ real_t length() const;
|
||||
_FORCE_INLINE_ real_t length_squared() const;
|
||||
|
||||
@@ -98,7 +106,9 @@ struct _NO_DISCARD_ Vector3 {
|
||||
_FORCE_INLINE_ void zero();
|
||||
|
||||
void snap(const Vector3 p_val);
|
||||
void snapf(real_t p_val);
|
||||
Vector3 snapped(const Vector3 p_val) const;
|
||||
Vector3 snappedf(real_t p_val) const;
|
||||
|
||||
void rotate(const Vector3 &p_axis, const real_t p_angle);
|
||||
Vector3 rotated(const Vector3 &p_axis, const real_t p_angle) const;
|
||||
@@ -128,6 +138,7 @@ struct _NO_DISCARD_ Vector3 {
|
||||
_FORCE_INLINE_ Vector3 ceil() const;
|
||||
_FORCE_INLINE_ Vector3 round() const;
|
||||
Vector3 clamp(const Vector3 &p_min, const Vector3 &p_max) const;
|
||||
Vector3 clampf(real_t p_min, real_t p_max) const;
|
||||
|
||||
_FORCE_INLINE_ real_t distance_to(const Vector3 &p_to) const;
|
||||
_FORCE_INLINE_ real_t distance_squared_to(const Vector3 &p_to) const;
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace godot {
|
||||
class String;
|
||||
struct Vector3;
|
||||
|
||||
struct _NO_DISCARD_ Vector3i {
|
||||
struct [[nodiscard]] Vector3i {
|
||||
static const int AXIS_COUNT = 3;
|
||||
|
||||
enum Axis {
|
||||
@@ -75,18 +75,32 @@ struct _NO_DISCARD_ Vector3i {
|
||||
return Vector3i(MIN(x, p_vector3i.x), MIN(y, p_vector3i.y), MIN(z, p_vector3i.z));
|
||||
}
|
||||
|
||||
Vector3i mini(int32_t p_scalar) const {
|
||||
return Vector3i(MIN(x, p_scalar), MIN(y, p_scalar), MIN(z, p_scalar));
|
||||
}
|
||||
|
||||
Vector3i max(const Vector3i &p_vector3i) const {
|
||||
return Vector3i(MAX(x, p_vector3i.x), MAX(y, p_vector3i.y), MAX(z, p_vector3i.z));
|
||||
}
|
||||
|
||||
Vector3i maxi(int32_t p_scalar) const {
|
||||
return Vector3i(MAX(x, p_scalar), MAX(y, p_scalar), MAX(z, p_scalar));
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ int64_t length_squared() const;
|
||||
_FORCE_INLINE_ double length() const;
|
||||
|
||||
_FORCE_INLINE_ int64_t distance_squared_to(const Vector3i &p_to) const;
|
||||
_FORCE_INLINE_ double distance_to(const Vector3i &p_to) const;
|
||||
|
||||
_FORCE_INLINE_ void zero();
|
||||
|
||||
_FORCE_INLINE_ Vector3i abs() const;
|
||||
_FORCE_INLINE_ Vector3i sign() const;
|
||||
Vector3i snapped(const Vector3i &p_step) const;
|
||||
Vector3i snappedi(int32_t p_step) const;
|
||||
Vector3i clamp(const Vector3i &p_min, const Vector3i &p_max) const;
|
||||
Vector3i clampi(int32_t p_min, int32_t p_max) const;
|
||||
|
||||
/* Operators */
|
||||
|
||||
@@ -136,6 +150,14 @@ double Vector3i::length() const {
|
||||
return Math::sqrt((double)length_squared());
|
||||
}
|
||||
|
||||
int64_t Vector3i::distance_squared_to(const Vector3i &p_to) const {
|
||||
return (p_to - *this).length_squared();
|
||||
}
|
||||
|
||||
double Vector3i::distance_to(const Vector3i &p_to) const {
|
||||
return (p_to - *this).length();
|
||||
}
|
||||
|
||||
Vector3i Vector3i::abs() const {
|
||||
return Vector3i(Math::abs(x), Math::abs(y), Math::abs(z));
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace godot {
|
||||
|
||||
class String;
|
||||
|
||||
struct _NO_DISCARD_ Vector4 {
|
||||
struct [[nodiscard]] Vector4 {
|
||||
static const int AXIS_COUNT = 4;
|
||||
|
||||
enum Axis {
|
||||
@@ -75,10 +75,18 @@ struct _NO_DISCARD_ Vector4 {
|
||||
return Vector4(MIN(x, p_vector4.x), MIN(y, p_vector4.y), MIN(z, p_vector4.z), MIN(w, p_vector4.w));
|
||||
}
|
||||
|
||||
Vector4 minf(real_t p_scalar) const {
|
||||
return Vector4(MIN(x, p_scalar), MIN(y, p_scalar), MIN(z, p_scalar), MIN(w, p_scalar));
|
||||
}
|
||||
|
||||
Vector4 max(const Vector4 &p_vector4) const {
|
||||
return Vector4(MAX(x, p_vector4.x), MAX(y, p_vector4.y), MAX(z, p_vector4.z), MAX(w, p_vector4.w));
|
||||
}
|
||||
|
||||
Vector4 maxf(real_t p_scalar) const {
|
||||
return Vector4(MAX(x, p_scalar), MAX(y, p_scalar), MAX(z, p_scalar), MAX(w, p_scalar));
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ real_t length_squared() const;
|
||||
bool is_equal_approx(const Vector4 &p_vec4) const;
|
||||
bool is_zero_approx() const;
|
||||
@@ -104,8 +112,11 @@ struct _NO_DISCARD_ Vector4 {
|
||||
Vector4 posmod(const real_t p_mod) const;
|
||||
Vector4 posmodv(const Vector4 &p_modv) const;
|
||||
void snap(const Vector4 &p_step);
|
||||
void snapf(real_t p_step);
|
||||
Vector4 snapped(const Vector4 &p_step) const;
|
||||
Vector4 snappedf(real_t p_step) const;
|
||||
Vector4 clamp(const Vector4 &p_min, const Vector4 &p_max) const;
|
||||
Vector4 clampf(real_t p_min, real_t p_max) const;
|
||||
|
||||
Vector4 inverse() const;
|
||||
_FORCE_INLINE_ real_t dot(const Vector4 &p_vec4) const;
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace godot {
|
||||
class String;
|
||||
struct Vector4;
|
||||
|
||||
struct _NO_DISCARD_ Vector4i {
|
||||
struct [[nodiscard]] Vector4i {
|
||||
static const int AXIS_COUNT = 4;
|
||||
|
||||
enum Axis {
|
||||
@@ -77,18 +77,32 @@ struct _NO_DISCARD_ Vector4i {
|
||||
return Vector4i(MIN(x, p_vector4i.x), MIN(y, p_vector4i.y), MIN(z, p_vector4i.z), MIN(w, p_vector4i.w));
|
||||
}
|
||||
|
||||
Vector4i mini(int32_t p_scalar) const {
|
||||
return Vector4i(MIN(x, p_scalar), MIN(y, p_scalar), MIN(z, p_scalar), MIN(w, p_scalar));
|
||||
}
|
||||
|
||||
Vector4i max(const Vector4i &p_vector4i) const {
|
||||
return Vector4i(MAX(x, p_vector4i.x), MAX(y, p_vector4i.y), MAX(z, p_vector4i.z), MAX(w, p_vector4i.w));
|
||||
}
|
||||
|
||||
Vector4i maxi(int32_t p_scalar) const {
|
||||
return Vector4i(MAX(x, p_scalar), MAX(y, p_scalar), MAX(z, p_scalar), MAX(w, p_scalar));
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ int64_t length_squared() const;
|
||||
_FORCE_INLINE_ double length() const;
|
||||
|
||||
_FORCE_INLINE_ int64_t distance_squared_to(const Vector4i &p_to) const;
|
||||
_FORCE_INLINE_ double distance_to(const Vector4i &p_to) const;
|
||||
|
||||
_FORCE_INLINE_ void zero();
|
||||
|
||||
_FORCE_INLINE_ Vector4i abs() const;
|
||||
_FORCE_INLINE_ Vector4i sign() const;
|
||||
Vector4i snapped(const Vector4i &p_step) const;
|
||||
Vector4i snappedi(int32_t p_step) const;
|
||||
Vector4i clamp(const Vector4i &p_min, const Vector4i &p_max) const;
|
||||
Vector4i clampi(int32_t p_min, int32_t p_max) const;
|
||||
|
||||
/* Operators */
|
||||
|
||||
@@ -140,6 +154,14 @@ double Vector4i::length() const {
|
||||
return Math::sqrt((double)length_squared());
|
||||
}
|
||||
|
||||
int64_t Vector4i::distance_squared_to(const Vector4i &p_to) const {
|
||||
return (p_to - *this).length_squared();
|
||||
}
|
||||
|
||||
double Vector4i::distance_to(const Vector4i &p_to) const {
|
||||
return (p_to - *this).length();
|
||||
}
|
||||
|
||||
Vector4i Vector4i::abs() const {
|
||||
return Vector4i(Math::abs(x), Math::abs(y), Math::abs(z), Math::abs(w));
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
/**************************************************************************/
|
||||
|
||||
#include <godot_cpp/classes/file_access.hpp>
|
||||
#include <godot_cpp/classes/image.hpp>
|
||||
#include <godot_cpp/classes/worker_thread_pool.hpp>
|
||||
#include <godot_cpp/classes/xml_parser.hpp>
|
||||
|
||||
@@ -55,4 +56,12 @@ WorkerThreadPool::GroupID WorkerThreadPool::add_native_group_task(void (*p_func)
|
||||
return (GroupID)internal::gdextension_interface_worker_thread_pool_add_native_group_task(_owner, p_func, p_userdata, p_elements, p_tasks, p_high_priority, (GDExtensionConstStringPtr)&p_description);
|
||||
}
|
||||
|
||||
uint8_t *Image::ptrw() {
|
||||
return internal::gdextension_interface_image_ptrw(_owner);
|
||||
}
|
||||
|
||||
const uint8_t *Image::ptr() {
|
||||
return internal::gdextension_interface_image_ptr(_owner);
|
||||
}
|
||||
|
||||
} // namespace godot
|
||||
|
||||
@@ -40,42 +40,54 @@
|
||||
|
||||
namespace godot {
|
||||
|
||||
const StringName *Wrapped::_get_extension_class_name() const {
|
||||
#ifdef _GODOT_CPP_AVOID_THREAD_LOCAL
|
||||
std::recursive_mutex Wrapped::_constructing_mutex;
|
||||
#endif
|
||||
|
||||
_GODOT_CPP_THREAD_LOCAL const StringName *Wrapped::_constructing_extension_class_name = nullptr;
|
||||
_GODOT_CPP_THREAD_LOCAL const GDExtensionInstanceBindingCallbacks *Wrapped::_constructing_class_binding_callbacks = nullptr;
|
||||
|
||||
#ifdef HOT_RELOAD_ENABLED
|
||||
_GODOT_CPP_THREAD_LOCAL GDExtensionObjectPtr Wrapped::_constructing_recreate_owner = nullptr;
|
||||
#endif
|
||||
|
||||
const StringName *Wrapped::_get_extension_class_name() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Wrapped::_postinitialize() {
|
||||
const StringName *extension_class = _get_extension_class_name();
|
||||
if (extension_class) {
|
||||
godot::internal::gdextension_interface_object_set_instance(_owner, reinterpret_cast<GDExtensionConstStringNamePtr>(extension_class), this);
|
||||
}
|
||||
godot::internal::gdextension_interface_object_set_instance_binding(_owner, godot::internal::token, this, _get_bindings_callbacks());
|
||||
if (extension_class) {
|
||||
_notificationv(Object::NOTIFICATION_POSTINITIALIZE);
|
||||
#ifdef _GODOT_CPP_AVOID_THREAD_LOCAL
|
||||
Wrapped::_constructing_mutex.unlock();
|
||||
#endif
|
||||
|
||||
Object *obj = dynamic_cast<Object *>(this);
|
||||
if (obj) {
|
||||
obj->notification(Object::NOTIFICATION_POSTINITIALIZE);
|
||||
}
|
||||
}
|
||||
|
||||
Wrapped::Wrapped(const StringName p_godot_class) {
|
||||
#ifdef HOT_RELOAD_ENABLED
|
||||
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;
|
||||
}
|
||||
}
|
||||
if (unlikely(Wrapped::_constructing_recreate_owner)) {
|
||||
_owner = Wrapped::_constructing_recreate_owner;
|
||||
Wrapped::_constructing_recreate_owner = nullptr;
|
||||
} else
|
||||
#endif
|
||||
_owner = godot::internal::gdextension_interface_classdb_construct_object(reinterpret_cast<GDExtensionConstStringNamePtr>(p_godot_class._native_ptr()));
|
||||
{
|
||||
_owner = godot::internal::gdextension_interface_classdb_construct_object2(reinterpret_cast<GDExtensionConstStringNamePtr>(p_godot_class._native_ptr()));
|
||||
}
|
||||
|
||||
if (_constructing_extension_class_name) {
|
||||
godot::internal::gdextension_interface_object_set_instance(_owner, reinterpret_cast<GDExtensionConstStringNamePtr>(_constructing_extension_class_name), this);
|
||||
_constructing_extension_class_name = nullptr;
|
||||
}
|
||||
|
||||
if (likely(_constructing_class_binding_callbacks)) {
|
||||
godot::internal::gdextension_interface_object_set_instance_binding(_owner, godot::internal::token, this, _constructing_class_binding_callbacks);
|
||||
_constructing_class_binding_callbacks = nullptr;
|
||||
} else {
|
||||
CRASH_NOW_MSG("BUG: Godot Object created without binding callbacks. Did you forget to use memnew()?");
|
||||
}
|
||||
}
|
||||
|
||||
Wrapped::Wrapped(GodotObject *p_godot_object) {
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
#include <godot_cpp/core/error_macros.hpp>
|
||||
#include <godot_cpp/godot.hpp>
|
||||
#include <godot_cpp/templates/vector.hpp>
|
||||
|
||||
#include <godot_cpp/core/memory.hpp>
|
||||
|
||||
@@ -284,7 +285,7 @@ void ClassDB::bind_integer_constant(const StringName &p_class_name, const String
|
||||
// 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);
|
||||
}
|
||||
GDExtensionClassCallVirtual ClassDB::get_virtual_func(void *p_userdata, GDExtensionConstStringNamePtr p_name) {
|
||||
GDExtensionClassCallVirtual ClassDB::get_virtual_func(void *p_userdata, GDExtensionConstStringNamePtr p_name, uint32_t p_hash) {
|
||||
// This is called by Godot the first time it calls a virtual function, and it caches the result, per object instance.
|
||||
// Because of this, it can happen from different threads at once.
|
||||
// It should be ok not using any mutex as long as we only READ data.
|
||||
@@ -298,10 +299,10 @@ GDExtensionClassCallVirtual ClassDB::get_virtual_func(void *p_userdata, GDExtens
|
||||
|
||||
// Find method in current class, or any of its parent classes (Godot classes not included)
|
||||
while (type != nullptr) {
|
||||
std::unordered_map<StringName, GDExtensionClassCallVirtual>::const_iterator method_it = type->virtual_methods.find(*name);
|
||||
std::unordered_map<StringName, ClassInfo::VirtualMethod>::const_iterator method_it = type->virtual_methods.find(*name);
|
||||
|
||||
if (method_it != type->virtual_methods.end()) {
|
||||
return method_it->second;
|
||||
if (method_it != type->virtual_methods.end() && method_it->second.hash == p_hash) {
|
||||
return method_it->second.func;
|
||||
}
|
||||
|
||||
type = type->parent_ptr;
|
||||
@@ -327,7 +328,7 @@ const GDExtensionInstanceBindingCallbacks *ClassDB::get_instance_binding_callbac
|
||||
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, uint32_t p_hash) {
|
||||
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)));
|
||||
|
||||
@@ -336,7 +337,55 @@ void ClassDB::bind_virtual_method(const StringName &p_class, const StringName &p
|
||||
ERR_FAIL_COND_MSG(type.method_map.find(p_method) != type.method_map.end(), String("Method '{0}::{1}()' already registered as non-virtual.").format(Array::make(p_class, p_method)));
|
||||
ERR_FAIL_COND_MSG(type.virtual_methods.find(p_method) != type.virtual_methods.end(), String("Virtual '{0}::{1}()' method already registered.").format(Array::make(p_class, p_method)));
|
||||
|
||||
type.virtual_methods[p_method] = p_call;
|
||||
type.virtual_methods[p_method] = ClassInfo::VirtualMethod{
|
||||
p_call,
|
||||
p_hash,
|
||||
};
|
||||
}
|
||||
|
||||
void ClassDB::add_virtual_method(const StringName &p_class, const MethodInfo &p_method, const Vector<StringName> &p_arg_names) {
|
||||
std::unordered_map<StringName, ClassInfo>::iterator type_it = classes.find(p_class);
|
||||
ERR_FAIL_COND_MSG(type_it == classes.end(), String("Class '{0}' doesn't exist.").format(Array::make(p_class)));
|
||||
|
||||
GDExtensionClassVirtualMethodInfo mi;
|
||||
mi.name = (GDExtensionStringNamePtr)&p_method.name;
|
||||
mi.method_flags = p_method.flags;
|
||||
mi.return_value = p_method.return_val._to_gdextension();
|
||||
mi.return_value_metadata = p_method.return_val_metadata;
|
||||
mi.argument_count = p_method.arguments.size();
|
||||
if (mi.argument_count > 0) {
|
||||
mi.arguments = (GDExtensionPropertyInfo *)memalloc(sizeof(GDExtensionPropertyInfo) * mi.argument_count);
|
||||
mi.arguments_metadata = (GDExtensionClassMethodArgumentMetadata *)memalloc(sizeof(GDExtensionClassMethodArgumentMetadata) * mi.argument_count);
|
||||
if (mi.argument_count != p_method.arguments_metadata.size()) {
|
||||
WARN_PRINT("Mismatch argument metadata count for virtual method: " + String(p_class) + "::" + p_method.name);
|
||||
}
|
||||
for (uint32_t i = 0; i < mi.argument_count; i++) {
|
||||
mi.arguments[i] = p_method.arguments[i]._to_gdextension();
|
||||
if (i < p_method.arguments_metadata.size()) {
|
||||
mi.arguments_metadata[i] = p_method.arguments_metadata[i];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mi.arguments = nullptr;
|
||||
mi.arguments_metadata = nullptr;
|
||||
}
|
||||
|
||||
if (p_arg_names.size() != mi.argument_count) {
|
||||
WARN_PRINT("Mismatch argument name count for virtual method: " + String(p_class) + "::" + p_method.name);
|
||||
} else {
|
||||
for (int i = 0; i < p_arg_names.size(); i++) {
|
||||
mi.arguments[i].name = (GDExtensionStringNamePtr)&p_arg_names[i];
|
||||
}
|
||||
}
|
||||
|
||||
internal::gdextension_interface_classdb_register_extension_class_virtual_method(internal::library, &p_class, &mi);
|
||||
|
||||
if (mi.arguments) {
|
||||
memfree(mi.arguments);
|
||||
}
|
||||
if (mi.arguments_metadata) {
|
||||
memfree(mi.arguments_metadata);
|
||||
}
|
||||
}
|
||||
|
||||
void ClassDB::initialize_class(const ClassInfo &p_cl) {
|
||||
|
||||
39
src/core/print_string.cpp
Normal file
39
src/core/print_string.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
/**************************************************************************/
|
||||
/* print_string.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/core/print_string.hpp>
|
||||
|
||||
#include <godot_cpp/classes/os.hpp>
|
||||
|
||||
namespace godot {
|
||||
bool is_print_verbose_enabled() {
|
||||
return OS::get_singleton()->is_stdout_verbose();
|
||||
}
|
||||
} // namespace godot
|
||||
@@ -88,11 +88,13 @@ GDExtensionInterfaceVariantGetType gdextension_interface_variant_get_type = null
|
||||
GDExtensionInterfaceVariantHasMethod gdextension_interface_variant_has_method = nullptr;
|
||||
GDExtensionInterfaceVariantHasMember gdextension_interface_variant_has_member = nullptr;
|
||||
GDExtensionInterfaceVariantHasKey gdextension_interface_variant_has_key = nullptr;
|
||||
GDExtensionInterfaceVariantGetObjectInstanceId gdextension_interface_variant_get_object_instance_id = 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;
|
||||
GDExtensionInterfaceGetVariantGetInternalPtrFunc gdextension_interface_variant_get_ptr_internal_getter = 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;
|
||||
@@ -114,7 +116,9 @@ GDExtensionInterfaceStringNewWithUtf32Chars gdextension_interface_string_new_wit
|
||||
GDExtensionInterfaceStringNewWithWideChars gdextension_interface_string_new_with_wide_chars = nullptr;
|
||||
GDExtensionInterfaceStringNewWithLatin1CharsAndLen gdextension_interface_string_new_with_latin1_chars_and_len = nullptr;
|
||||
GDExtensionInterfaceStringNewWithUtf8CharsAndLen gdextension_interface_string_new_with_utf8_chars_and_len = nullptr;
|
||||
GDExtensionInterfaceStringNewWithUtf8CharsAndLen2 gdextension_interface_string_new_with_utf8_chars_and_len2 = nullptr;
|
||||
GDExtensionInterfaceStringNewWithUtf16CharsAndLen gdextension_interface_string_new_with_utf16_chars_and_len = nullptr;
|
||||
GDExtensionInterfaceStringNewWithUtf16CharsAndLen2 gdextension_interface_string_new_with_utf16_chars_and_len2 = nullptr;
|
||||
GDExtensionInterfaceStringNewWithUtf32CharsAndLen gdextension_interface_string_new_with_utf32_chars_and_len = nullptr;
|
||||
GDExtensionInterfaceStringNewWithWideCharsAndLen gdextension_interface_string_new_with_wide_chars_and_len = nullptr;
|
||||
GDExtensionInterfaceStringToLatin1Chars gdextension_interface_string_to_latin1_chars = nullptr;
|
||||
@@ -154,12 +158,15 @@ GDExtensionInterfacePackedVector2ArrayOperatorIndex gdextension_interface_packed
|
||||
GDExtensionInterfacePackedVector2ArrayOperatorIndexConst gdextension_interface_packed_vector2_array_operator_index_const = nullptr;
|
||||
GDExtensionInterfacePackedVector3ArrayOperatorIndex gdextension_interface_packed_vector3_array_operator_index = nullptr;
|
||||
GDExtensionInterfacePackedVector3ArrayOperatorIndexConst gdextension_interface_packed_vector3_array_operator_index_const = nullptr;
|
||||
GDExtensionInterfacePackedVector4ArrayOperatorIndex gdextension_interface_packed_vector4_array_operator_index = nullptr;
|
||||
GDExtensionInterfacePackedVector4ArrayOperatorIndexConst gdextension_interface_packed_vector4_array_operator_index_const = nullptr;
|
||||
GDExtensionInterfaceArrayOperatorIndex gdextension_interface_array_operator_index = nullptr;
|
||||
GDExtensionInterfaceArrayOperatorIndexConst gdextension_interface_array_operator_index_const = nullptr;
|
||||
GDExtensionInterfaceArrayRef gdextension_interface_array_ref = nullptr;
|
||||
GDExtensionInterfaceArraySetTyped gdextension_interface_array_set_typed = nullptr;
|
||||
GDExtensionInterfaceDictionaryOperatorIndex gdextension_interface_dictionary_operator_index = nullptr;
|
||||
GDExtensionInterfaceDictionaryOperatorIndexConst gdextension_interface_dictionary_operator_index_const = nullptr;
|
||||
GDExtensionInterfaceDictionarySetTyped gdextension_interface_dictionary_set_typed = nullptr;
|
||||
GDExtensionInterfaceObjectMethodBindCall gdextension_interface_object_method_bind_call = nullptr;
|
||||
GDExtensionInterfaceObjectMethodBindPtrcall gdextension_interface_object_method_bind_ptrcall = nullptr;
|
||||
GDExtensionInterfaceObjectDestroy gdextension_interface_object_destroy = nullptr;
|
||||
@@ -172,18 +179,21 @@ GDExtensionInterfaceObjectGetClassName gdextension_interface_object_get_class_na
|
||||
GDExtensionInterfaceObjectCastTo gdextension_interface_object_cast_to = nullptr;
|
||||
GDExtensionInterfaceObjectGetInstanceFromId gdextension_interface_object_get_instance_from_id = nullptr;
|
||||
GDExtensionInterfaceObjectGetInstanceId gdextension_interface_object_get_instance_id = nullptr;
|
||||
GDExtensionInterfaceCallableCustomCreate gdextension_interface_callable_custom_create = nullptr;
|
||||
GDExtensionInterfaceObjectHasScriptMethod gdextension_interface_object_has_script_method = nullptr;
|
||||
GDExtensionInterfaceObjectCallScriptMethod gdextension_interface_object_call_script_method = nullptr;
|
||||
GDExtensionInterfaceCallableCustomCreate2 gdextension_interface_callable_custom_create2 = 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;
|
||||
GDExtensionInterfaceScriptInstanceCreate3 gdextension_interface_script_instance_create3 = nullptr;
|
||||
GDExtensionInterfacePlaceHolderScriptInstanceCreate gdextension_interface_placeholder_script_instance_create = nullptr;
|
||||
GDExtensionInterfacePlaceHolderScriptInstanceUpdate gdextension_interface_placeholder_script_instance_update = nullptr;
|
||||
GDExtensionInterfaceClassdbConstructObject gdextension_interface_classdb_construct_object = nullptr;
|
||||
GDExtensionInterfaceClassdbConstructObject2 gdextension_interface_classdb_construct_object2 = 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;
|
||||
GDExtensionInterfaceClassdbRegisterExtensionClass4 gdextension_interface_classdb_register_extension_class4 = nullptr;
|
||||
GDExtensionInterfaceClassdbRegisterExtensionClassMethod gdextension_interface_classdb_register_extension_class_method = nullptr;
|
||||
GDExtensionInterfaceClassdbRegisterExtensionClassVirtualMethod gdextension_interface_classdb_register_extension_class_virtual_method = nullptr;
|
||||
GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant gdextension_interface_classdb_register_extension_class_integer_constant = nullptr;
|
||||
GDExtensionInterfaceClassdbRegisterExtensionClassProperty gdextension_interface_classdb_register_extension_class_property = nullptr;
|
||||
GDExtensionInterfaceClassdbRegisterExtensionClassPropertyIndexed gdextension_interface_classdb_register_extension_class_property_indexed = nullptr;
|
||||
@@ -194,6 +204,40 @@ GDExtensionInterfaceClassdbUnregisterExtensionClass gdextension_interface_classd
|
||||
GDExtensionInterfaceGetLibraryPath gdextension_interface_get_library_path = nullptr;
|
||||
GDExtensionInterfaceEditorAddPlugin gdextension_interface_editor_add_plugin = nullptr;
|
||||
GDExtensionInterfaceEditorRemovePlugin gdextension_interface_editor_remove_plugin = nullptr;
|
||||
GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8Chars gdextension_interface_editor_help_load_xml_from_utf8_chars = nullptr;
|
||||
GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8CharsAndLen gdextension_interface_editor_help_load_xml_from_utf8_chars_and_len = nullptr;
|
||||
GDExtensionInterfaceImagePtrw gdextension_interface_image_ptrw = nullptr;
|
||||
GDExtensionInterfaceImagePtr gdextension_interface_image_ptr = nullptr;
|
||||
|
||||
struct DocData {
|
||||
const char *hash = nullptr;
|
||||
int uncompressed_size = 0;
|
||||
int compressed_size = 0;
|
||||
const unsigned char *data = nullptr;
|
||||
|
||||
inline bool is_valid() const {
|
||||
return hash != nullptr && uncompressed_size > 0 && compressed_size > 0 && data != nullptr;
|
||||
}
|
||||
|
||||
void load_data() const;
|
||||
};
|
||||
|
||||
static DocData &get_doc_data() {
|
||||
static DocData doc_data;
|
||||
return doc_data;
|
||||
}
|
||||
|
||||
DocDataRegistration::DocDataRegistration(const char *p_hash, int p_uncompressed_size, int p_compressed_size, const unsigned char *p_data) {
|
||||
DocData &doc_data = get_doc_data();
|
||||
if (doc_data.is_valid()) {
|
||||
printf("ERROR: Attempting to register documentation data when we already have some - discarding.\n");
|
||||
return;
|
||||
}
|
||||
doc_data.hash = p_hash;
|
||||
doc_data.uncompressed_size = p_uncompressed_size;
|
||||
doc_data.compressed_size = p_compressed_size;
|
||||
doc_data.data = p_data;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
@@ -326,11 +370,13 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
|
||||
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_object_instance_id, GDExtensionInterfaceVariantGetObjectInstanceId);
|
||||
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_internal_getter, GDExtensionInterfaceGetVariantGetInternalPtrFunc);
|
||||
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);
|
||||
@@ -352,7 +398,9 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
|
||||
LOAD_PROC_ADDRESS(string_new_with_wide_chars, GDExtensionInterfaceStringNewWithWideChars);
|
||||
LOAD_PROC_ADDRESS(string_new_with_latin1_chars_and_len, GDExtensionInterfaceStringNewWithLatin1CharsAndLen);
|
||||
LOAD_PROC_ADDRESS(string_new_with_utf8_chars_and_len, GDExtensionInterfaceStringNewWithUtf8CharsAndLen);
|
||||
LOAD_PROC_ADDRESS(string_new_with_utf8_chars_and_len2, GDExtensionInterfaceStringNewWithUtf8CharsAndLen2);
|
||||
LOAD_PROC_ADDRESS(string_new_with_utf16_chars_and_len, GDExtensionInterfaceStringNewWithUtf16CharsAndLen);
|
||||
LOAD_PROC_ADDRESS(string_new_with_utf16_chars_and_len2, GDExtensionInterfaceStringNewWithUtf16CharsAndLen2);
|
||||
LOAD_PROC_ADDRESS(string_new_with_utf32_chars_and_len, GDExtensionInterfaceStringNewWithUtf32CharsAndLen);
|
||||
LOAD_PROC_ADDRESS(string_new_with_wide_chars_and_len, GDExtensionInterfaceStringNewWithWideCharsAndLen);
|
||||
LOAD_PROC_ADDRESS(string_to_latin1_chars, GDExtensionInterfaceStringToLatin1Chars);
|
||||
@@ -392,12 +440,15 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
|
||||
LOAD_PROC_ADDRESS(packed_vector2_array_operator_index_const, GDExtensionInterfacePackedVector2ArrayOperatorIndexConst);
|
||||
LOAD_PROC_ADDRESS(packed_vector3_array_operator_index, GDExtensionInterfacePackedVector3ArrayOperatorIndex);
|
||||
LOAD_PROC_ADDRESS(packed_vector3_array_operator_index_const, GDExtensionInterfacePackedVector3ArrayOperatorIndexConst);
|
||||
LOAD_PROC_ADDRESS(packed_vector4_array_operator_index, GDExtensionInterfacePackedVector4ArrayOperatorIndex);
|
||||
LOAD_PROC_ADDRESS(packed_vector4_array_operator_index_const, GDExtensionInterfacePackedVector4ArrayOperatorIndexConst);
|
||||
LOAD_PROC_ADDRESS(array_operator_index, GDExtensionInterfaceArrayOperatorIndex);
|
||||
LOAD_PROC_ADDRESS(array_operator_index_const, GDExtensionInterfaceArrayOperatorIndexConst);
|
||||
LOAD_PROC_ADDRESS(array_ref, GDExtensionInterfaceArrayRef);
|
||||
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(dictionary_set_typed, GDExtensionInterfaceDictionarySetTyped);
|
||||
LOAD_PROC_ADDRESS(object_method_bind_call, GDExtensionInterfaceObjectMethodBindCall);
|
||||
LOAD_PROC_ADDRESS(object_method_bind_ptrcall, GDExtensionInterfaceObjectMethodBindPtrcall);
|
||||
LOAD_PROC_ADDRESS(object_destroy, GDExtensionInterfaceObjectDestroy);
|
||||
@@ -410,18 +461,21 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
|
||||
LOAD_PROC_ADDRESS(object_cast_to, GDExtensionInterfaceObjectCastTo);
|
||||
LOAD_PROC_ADDRESS(object_get_instance_from_id, GDExtensionInterfaceObjectGetInstanceFromId);
|
||||
LOAD_PROC_ADDRESS(object_get_instance_id, GDExtensionInterfaceObjectGetInstanceId);
|
||||
LOAD_PROC_ADDRESS(callable_custom_create, GDExtensionInterfaceCallableCustomCreate);
|
||||
LOAD_PROC_ADDRESS(object_has_script_method, GDExtensionInterfaceObjectHasScriptMethod);
|
||||
LOAD_PROC_ADDRESS(object_call_script_method, GDExtensionInterfaceObjectCallScriptMethod);
|
||||
LOAD_PROC_ADDRESS(callable_custom_create2, GDExtensionInterfaceCallableCustomCreate2);
|
||||
LOAD_PROC_ADDRESS(callable_custom_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(script_instance_create3, GDExtensionInterfaceScriptInstanceCreate3);
|
||||
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_construct_object2, GDExtensionInterfaceClassdbConstructObject2);
|
||||
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_class4, GDExtensionInterfaceClassdbRegisterExtensionClass4);
|
||||
LOAD_PROC_ADDRESS(classdb_register_extension_class_method, GDExtensionInterfaceClassdbRegisterExtensionClassMethod);
|
||||
LOAD_PROC_ADDRESS(classdb_register_extension_class_virtual_method, GDExtensionInterfaceClassdbRegisterExtensionClassVirtualMethod);
|
||||
LOAD_PROC_ADDRESS(classdb_register_extension_class_integer_constant, GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant);
|
||||
LOAD_PROC_ADDRESS(classdb_register_extension_class_property, GDExtensionInterfaceClassdbRegisterExtensionClassProperty);
|
||||
LOAD_PROC_ADDRESS(classdb_register_extension_class_property_indexed, GDExtensionInterfaceClassdbRegisterExtensionClassPropertyIndexed);
|
||||
@@ -432,6 +486,10 @@ GDExtensionBool GDExtensionBinding::init(GDExtensionInterfaceGetProcAddress p_ge
|
||||
LOAD_PROC_ADDRESS(get_library_path, GDExtensionInterfaceGetLibraryPath);
|
||||
LOAD_PROC_ADDRESS(editor_add_plugin, GDExtensionInterfaceEditorAddPlugin);
|
||||
LOAD_PROC_ADDRESS(editor_remove_plugin, GDExtensionInterfaceEditorRemovePlugin);
|
||||
LOAD_PROC_ADDRESS(editor_help_load_xml_from_utf8_chars, GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8Chars);
|
||||
LOAD_PROC_ADDRESS(editor_help_load_xml_from_utf8_chars_and_len, GDExtensionsInterfaceEditorHelpLoadXmlFromUtf8CharsAndLen);
|
||||
LOAD_PROC_ADDRESS(image_ptrw, GDExtensionInterfaceImagePtrw);
|
||||
LOAD_PROC_ADDRESS(image_ptr, GDExtensionInterfaceImagePtr);
|
||||
|
||||
r_initialization->initialize = initialize_level;
|
||||
r_initialization->deinitialize = deinitialize_level;
|
||||
@@ -461,6 +519,13 @@ void GDExtensionBinding::initialize_level(void *p_userdata, GDExtensionInitializ
|
||||
ClassDB::initialize(p_level);
|
||||
}
|
||||
level_initialized[p_level]++;
|
||||
|
||||
if ((ModuleInitializationLevel)p_level == MODULE_INITIALIZATION_LEVEL_EDITOR) {
|
||||
const internal::DocData &doc_data = internal::get_doc_data();
|
||||
if (doc_data.is_valid()) {
|
||||
doc_data.load_data();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GDExtensionBinding::deinitialize_level(void *p_userdata, GDExtensionInitializationLevel p_level) {
|
||||
@@ -527,4 +592,15 @@ GDExtensionBool GDExtensionBinding::InitObject::init() const {
|
||||
return GDExtensionBinding::init(get_proc_address, library, init_data, initialization);
|
||||
}
|
||||
|
||||
void internal::DocData::load_data() const {
|
||||
PackedByteArray compressed;
|
||||
compressed.resize(compressed_size);
|
||||
memcpy(compressed.ptrw(), data, compressed_size);
|
||||
|
||||
// FileAccess::COMPRESSION_DEFLATE = 1
|
||||
PackedByteArray decompressed = compressed.decompress(uncompressed_size, 1);
|
||||
|
||||
internal::gdextension_interface_editor_help_load_xml_from_utf8_chars_and_len(reinterpret_cast<const char *>(decompressed.ptr()), uncompressed_size);
|
||||
}
|
||||
|
||||
} // namespace godot
|
||||
|
||||
@@ -35,6 +35,11 @@
|
||||
|
||||
namespace godot {
|
||||
|
||||
int CallableCustomBase::get_argument_count(bool &r_is_valid) const {
|
||||
r_is_valid = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void callable_custom_call(void *p_userdata, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error) {
|
||||
CallableCustom *callable_custom = (CallableCustom *)p_userdata;
|
||||
callable_custom->call((const Variant **)p_args, p_argument_count, *(Variant *)r_return, *r_error);
|
||||
@@ -84,13 +89,21 @@ static GDExtensionBool callable_custom_less_than_func(void *p_a, void *p_b) {
|
||||
return func_a(a, b);
|
||||
}
|
||||
|
||||
static GDExtensionInt custom_callable_get_argument_count_func(void *p_userdata, GDExtensionBool *r_is_valid) {
|
||||
CallableCustom *callable_custom = (CallableCustom *)p_userdata;
|
||||
bool valid = false;
|
||||
int ret = callable_custom->get_argument_count(valid);
|
||||
*r_is_valid = valid;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool CallableCustom::is_valid() const {
|
||||
// The same default implementation as in Godot.
|
||||
return ObjectDB::get_instance(get_object());
|
||||
}
|
||||
|
||||
Callable::Callable(CallableCustom *p_callable_custom) {
|
||||
GDExtensionCallableCustomInfo info = {};
|
||||
GDExtensionCallableCustomInfo2 info = {};
|
||||
info.callable_userdata = p_callable_custom;
|
||||
info.token = internal::token;
|
||||
info.object_id = p_callable_custom->get_object();
|
||||
@@ -101,8 +114,9 @@ Callable::Callable(CallableCustom *p_callable_custom) {
|
||||
info.equal_func = &callable_custom_equal_func;
|
||||
info.less_than_func = &callable_custom_less_than_func;
|
||||
info.to_string_func = &callable_custom_to_string;
|
||||
info.get_argument_count_func = &custom_callable_get_argument_count_func;
|
||||
|
||||
::godot::internal::gdextension_interface_callable_custom_create(_native_ptr(), &info);
|
||||
::godot::internal::gdextension_interface_callable_custom_create2(_native_ptr(), &info);
|
||||
}
|
||||
|
||||
CallableCustom *Callable::get_custom() const {
|
||||
|
||||
@@ -77,6 +77,14 @@ static GDExtensionBool custom_callable_mp_less_than_func(void *p_a, void *p_b) {
|
||||
return memcmp(a->get_comp_ptr(), b->get_comp_ptr(), a->get_comp_size() * 4) < 0;
|
||||
}
|
||||
|
||||
static GDExtensionInt custom_callable_mp_get_argument_count_func(void *p_userdata, GDExtensionBool *r_is_valid) {
|
||||
CallableCustomMethodPointerBase *callable_method_pointer = (CallableCustomMethodPointerBase *)p_userdata;
|
||||
bool valid = false;
|
||||
int ret = callable_method_pointer->get_argument_count(valid);
|
||||
*r_is_valid = valid;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CallableCustomMethodPointerBase::_setup(uint32_t *p_base_ptr, uint32_t p_ptr_size) {
|
||||
comp_ptr = p_base_ptr;
|
||||
comp_size = p_ptr_size / 4;
|
||||
@@ -93,7 +101,7 @@ void CallableCustomMethodPointerBase::_setup(uint32_t *p_base_ptr, uint32_t p_pt
|
||||
namespace internal {
|
||||
|
||||
Callable create_callable_from_ccmp(CallableCustomMethodPointerBase *p_callable_method_pointer) {
|
||||
GDExtensionCallableCustomInfo info = {};
|
||||
GDExtensionCallableCustomInfo2 info = {};
|
||||
info.callable_userdata = p_callable_method_pointer;
|
||||
info.token = internal::token;
|
||||
info.object_id = p_callable_method_pointer->get_object();
|
||||
@@ -103,9 +111,10 @@ Callable create_callable_from_ccmp(CallableCustomMethodPointerBase *p_callable_m
|
||||
info.hash_func = &custom_callable_mp_hash;
|
||||
info.equal_func = &custom_callable_mp_equal_func;
|
||||
info.less_than_func = &custom_callable_mp_less_than_func;
|
||||
info.get_argument_count_func = &custom_callable_mp_get_argument_count_func;
|
||||
|
||||
Callable callable;
|
||||
::godot::internal::gdextension_interface_callable_custom_create(callable._native_ptr(), &info);
|
||||
::godot::internal::gdextension_interface_callable_custom_create2(callable._native_ptr(), &info);
|
||||
return callable;
|
||||
}
|
||||
|
||||
|
||||
@@ -178,8 +178,8 @@ String String::utf8(const char *from, int64_t len) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
void String::parse_utf8(const char *from, int64_t len) {
|
||||
internal::gdextension_interface_string_new_with_utf8_chars_and_len(_native_ptr(), from, len);
|
||||
Error String::parse_utf8(const char *from, int64_t len) {
|
||||
return (Error)internal::gdextension_interface_string_new_with_utf8_chars_and_len2(_native_ptr(), from, len);
|
||||
}
|
||||
|
||||
String String::utf16(const char16_t *from, int64_t len) {
|
||||
@@ -188,8 +188,8 @@ String String::utf16(const char16_t *from, int64_t len) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
void String::parse_utf16(const char16_t *from, int64_t len) {
|
||||
internal::gdextension_interface_string_new_with_utf16_chars_and_len(_native_ptr(), from, len);
|
||||
Error String::parse_utf16(const char16_t *from, int64_t len, bool default_little_endian) {
|
||||
return (Error)internal::gdextension_interface_string_new_with_utf16_chars_and_len2(_native_ptr(), from, len, default_little_endian);
|
||||
}
|
||||
|
||||
String String::num_real(double p_num, bool p_trailing) {
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <godot_cpp/variant/packed_string_array.hpp>
|
||||
#include <godot_cpp/variant/packed_vector2_array.hpp>
|
||||
#include <godot_cpp/variant/packed_vector3_array.hpp>
|
||||
#include <godot_cpp/variant/packed_vector4_array.hpp>
|
||||
|
||||
namespace godot {
|
||||
|
||||
@@ -198,6 +199,24 @@ Vector3 *PackedVector3Array::ptrw() {
|
||||
return (Vector3 *)internal::gdextension_interface_packed_vector3_array_operator_index((GDExtensionTypePtr *)this, 0);
|
||||
}
|
||||
|
||||
const Vector4 &PackedVector4Array::operator[](int64_t p_index) const {
|
||||
const Vector4 *vec = (const Vector4 *)internal::gdextension_interface_packed_vector4_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
|
||||
return *vec;
|
||||
}
|
||||
|
||||
Vector4 &PackedVector4Array::operator[](int64_t p_index) {
|
||||
Vector4 *vec = (Vector4 *)internal::gdextension_interface_packed_vector4_array_operator_index((GDExtensionTypePtr *)this, p_index);
|
||||
return *vec;
|
||||
}
|
||||
|
||||
const Vector4 *PackedVector4Array::ptr() const {
|
||||
return (const Vector4 *)internal::gdextension_interface_packed_vector4_array_operator_index_const((GDExtensionTypePtr *)this, 0);
|
||||
}
|
||||
|
||||
Vector4 *PackedVector4Array::ptrw() {
|
||||
return (Vector4 *)internal::gdextension_interface_packed_vector4_array_operator_index((GDExtensionTypePtr *)this, 0);
|
||||
}
|
||||
|
||||
const Variant &Array::operator[](int64_t p_index) const {
|
||||
const Variant *var = (const Variant *)internal::gdextension_interface_array_operator_index_const((GDExtensionTypePtr *)this, p_index);
|
||||
return *var;
|
||||
@@ -227,4 +246,10 @@ Variant &Dictionary::operator[](const Variant &p_key) {
|
||||
return *var;
|
||||
}
|
||||
|
||||
void Dictionary::set_typed(uint32_t p_key_type, const StringName &p_key_class_name, const Variant &p_key_script, uint32_t p_value_type, const StringName &p_value_class_name, const Variant &p_value_script) {
|
||||
// p_key_type/p_value_type are not Variant::Type so that header doesn't depend on <variant.hpp>.
|
||||
internal::gdextension_interface_dictionary_set_typed((GDExtensionTypePtr *)this, (GDExtensionVariantType)p_key_type, (GDExtensionConstStringNamePtr)&p_key_class_name, (GDExtensionConstVariantPtr)&p_key_script,
|
||||
(GDExtensionVariantType)p_value_type, (GDExtensionConstStringNamePtr)&p_value_class_name, (GDExtensionConstVariantPtr)&p_value_script);
|
||||
}
|
||||
|
||||
} // namespace godot
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <godot_cpp/core/binder_common.hpp>
|
||||
#include <godot_cpp/core/class_db.hpp>
|
||||
#include <godot_cpp/core/defs.hpp>
|
||||
#include <godot_cpp/variant/variant_internal.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
@@ -49,6 +50,7 @@ void Variant::init_bindings() {
|
||||
from_type_constructor[i] = internal::gdextension_interface_get_variant_from_type_constructor((GDExtensionVariantType)i);
|
||||
to_type_constructor[i] = internal::gdextension_interface_get_variant_to_type_constructor((GDExtensionVariantType)i);
|
||||
}
|
||||
VariantInternal::init_bindings();
|
||||
|
||||
StringName::init_bindings();
|
||||
String::init_bindings();
|
||||
@@ -66,6 +68,7 @@ void Variant::init_bindings() {
|
||||
PackedStringArray::init_bindings();
|
||||
PackedVector2Array::init_bindings();
|
||||
PackedVector3Array::init_bindings();
|
||||
PackedVector4Array::init_bindings();
|
||||
PackedColorArray::init_bindings();
|
||||
}
|
||||
|
||||
@@ -248,6 +251,10 @@ Variant::Variant(const PackedColorArray &v) {
|
||||
from_type_constructor[PACKED_COLOR_ARRAY](_native_ptr(), v._native_ptr());
|
||||
}
|
||||
|
||||
Variant::Variant(const PackedVector4Array &v) {
|
||||
from_type_constructor[PACKED_VECTOR4_ARRAY](_native_ptr(), v._native_ptr());
|
||||
}
|
||||
|
||||
Variant::~Variant() {
|
||||
internal::gdextension_interface_variant_destroy(_native_ptr());
|
||||
}
|
||||
@@ -443,12 +450,7 @@ Variant::operator ObjectID() const {
|
||||
if (get_type() == Type::INT) {
|
||||
return ObjectID(operator uint64_t());
|
||||
} else if (get_type() == Type::OBJECT) {
|
||||
Object *obj = operator Object *();
|
||||
if (obj != nullptr) {
|
||||
return ObjectID(obj->get_instance_id());
|
||||
} else {
|
||||
return ObjectID();
|
||||
}
|
||||
return ObjectID(internal::gdextension_interface_variant_get_object_instance_id(_native_ptr()));
|
||||
} else {
|
||||
return ObjectID();
|
||||
}
|
||||
@@ -506,6 +508,14 @@ Variant::operator PackedColorArray() const {
|
||||
return PackedColorArray(this);
|
||||
}
|
||||
|
||||
Variant::operator PackedVector4Array() const {
|
||||
return PackedVector4Array(this);
|
||||
}
|
||||
|
||||
Object *Variant::get_validated_object() const {
|
||||
return ObjectDB::get_instance(operator ObjectID());
|
||||
}
|
||||
|
||||
Variant &Variant::operator=(const Variant &other) {
|
||||
clear();
|
||||
internal::gdextension_interface_variant_new_copy(_native_ptr(), other._native_ptr());
|
||||
|
||||
43
src/variant/variant_internal.cpp
Normal file
43
src/variant/variant_internal.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
/**************************************************************************/
|
||||
/* variant_internal.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/variant_internal.hpp>
|
||||
|
||||
namespace godot {
|
||||
|
||||
GDExtensionVariantGetInternalPtrFunc VariantInternal::get_internal_func[Variant::VARIANT_MAX]{};
|
||||
|
||||
void VariantInternal::init_bindings() {
|
||||
for (int i = 1; i < Variant::VARIANT_MAX; i++) {
|
||||
get_internal_func[i] = internal::gdextension_interface_variant_get_ptr_internal_getter((GDExtensionVariantType)i);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace godot
|
||||
@@ -137,12 +137,24 @@ Vector2 Vector2::clamp(const Vector2 &p_min, const Vector2 &p_max) const {
|
||||
CLAMP(y, p_min.y, p_max.y));
|
||||
}
|
||||
|
||||
Vector2 Vector2::clampf(real_t p_min, real_t p_max) const {
|
||||
return Vector2(
|
||||
CLAMP(x, p_min, p_max),
|
||||
CLAMP(y, p_min, p_max));
|
||||
}
|
||||
|
||||
Vector2 Vector2::snapped(const Vector2 &p_step) const {
|
||||
return Vector2(
|
||||
Math::snapped(x, p_step.x),
|
||||
Math::snapped(y, p_step.y));
|
||||
}
|
||||
|
||||
Vector2 Vector2::snappedf(real_t p_step) const {
|
||||
return Vector2(
|
||||
Math::snapped(x, p_step),
|
||||
Math::snapped(y, p_step));
|
||||
}
|
||||
|
||||
Vector2 Vector2::limit_length(const real_t p_len) const {
|
||||
const real_t l = length();
|
||||
Vector2 v = *this;
|
||||
|
||||
@@ -35,12 +35,30 @@
|
||||
|
||||
namespace godot {
|
||||
|
||||
Vector2i Vector2i::snapped(const Vector2i &p_step) const {
|
||||
return Vector2i(
|
||||
Math::snapped(x, p_step.x),
|
||||
Math::snapped(y, p_step.y));
|
||||
}
|
||||
|
||||
Vector2i Vector2i::snappedi(int32_t p_step) const {
|
||||
return Vector2i(
|
||||
Math::snapped(x, p_step),
|
||||
Math::snapped(y, p_step));
|
||||
}
|
||||
|
||||
Vector2i Vector2i::clamp(const Vector2i &p_min, const Vector2i &p_max) const {
|
||||
return Vector2i(
|
||||
CLAMP(x, p_min.x, p_max.x),
|
||||
CLAMP(y, p_min.y, p_max.y));
|
||||
}
|
||||
|
||||
Vector2i Vector2i::clampi(int32_t p_min, int32_t p_max) const {
|
||||
return Vector2i(
|
||||
CLAMP(x, p_min, p_max),
|
||||
CLAMP(y, p_min, p_max));
|
||||
}
|
||||
|
||||
int64_t Vector2i::length_squared() const {
|
||||
return x * (int64_t)x + y * (int64_t)y;
|
||||
}
|
||||
@@ -49,6 +67,14 @@ double Vector2i::length() const {
|
||||
return Math::sqrt((double)length_squared());
|
||||
}
|
||||
|
||||
int64_t Vector2i::distance_squared_to(const Vector2i &p_to) const {
|
||||
return (p_to - *this).length_squared();
|
||||
}
|
||||
|
||||
double Vector2i::distance_to(const Vector2i &p_to) const {
|
||||
return (p_to - *this).length();
|
||||
}
|
||||
|
||||
Vector2i Vector2i::operator+(const Vector2i &p_v) const {
|
||||
return Vector2i(x + p_v.x, y + p_v.y);
|
||||
}
|
||||
|
||||
@@ -54,18 +54,37 @@ Vector3 Vector3::clamp(const Vector3 &p_min, const Vector3 &p_max) const {
|
||||
CLAMP(z, p_min.z, p_max.z));
|
||||
}
|
||||
|
||||
Vector3 Vector3::clampf(real_t p_min, real_t p_max) const {
|
||||
return Vector3(
|
||||
CLAMP(x, p_min, p_max),
|
||||
CLAMP(y, p_min, p_max),
|
||||
CLAMP(z, p_min, p_max));
|
||||
}
|
||||
|
||||
void Vector3::snap(const Vector3 p_step) {
|
||||
x = Math::snapped(x, p_step.x);
|
||||
y = Math::snapped(y, p_step.y);
|
||||
z = Math::snapped(z, p_step.z);
|
||||
}
|
||||
|
||||
void Vector3::snapf(real_t p_step) {
|
||||
x = Math::snapped(x, p_step);
|
||||
y = Math::snapped(y, p_step);
|
||||
z = Math::snapped(z, p_step);
|
||||
}
|
||||
|
||||
Vector3 Vector3::snapped(const Vector3 p_step) const {
|
||||
Vector3 v = *this;
|
||||
v.snap(p_step);
|
||||
return v;
|
||||
}
|
||||
|
||||
Vector3 Vector3::snappedf(real_t p_step) const {
|
||||
Vector3 v = *this;
|
||||
v.snapf(p_step);
|
||||
return v;
|
||||
}
|
||||
|
||||
Vector3 Vector3::limit_length(const real_t p_len) const {
|
||||
const real_t l = length();
|
||||
Vector3 v = *this;
|
||||
|
||||
@@ -35,6 +35,20 @@
|
||||
|
||||
namespace godot {
|
||||
|
||||
Vector3i Vector3i::snapped(const Vector3i &p_step) const {
|
||||
return Vector3i(
|
||||
Math::snapped(x, p_step.x),
|
||||
Math::snapped(y, p_step.y),
|
||||
Math::snapped(z, p_step.z));
|
||||
}
|
||||
|
||||
Vector3i Vector3i::snappedi(int32_t p_step) const {
|
||||
return Vector3i(
|
||||
Math::snapped(x, p_step),
|
||||
Math::snapped(y, p_step),
|
||||
Math::snapped(z, p_step));
|
||||
}
|
||||
|
||||
Vector3i::Axis Vector3i::min_axis_index() const {
|
||||
return x < y ? (x < z ? Vector3i::AXIS_X : Vector3i::AXIS_Z) : (y < z ? Vector3i::AXIS_Y : Vector3i::AXIS_Z);
|
||||
}
|
||||
@@ -50,6 +64,13 @@ Vector3i Vector3i::clamp(const Vector3i &p_min, const Vector3i &p_max) const {
|
||||
CLAMP(z, p_min.z, p_max.z));
|
||||
}
|
||||
|
||||
Vector3i Vector3i::clampi(int32_t p_min, int32_t p_max) const {
|
||||
return Vector3i(
|
||||
CLAMP(x, p_min, p_max),
|
||||
CLAMP(y, p_min, p_max),
|
||||
CLAMP(z, p_min, p_max));
|
||||
}
|
||||
|
||||
Vector3i::operator String() const {
|
||||
return "(" + itos(x) + ", " + itos(y) + ", " + itos(z) + ")";
|
||||
}
|
||||
|
||||
@@ -173,12 +173,25 @@ void Vector4::snap(const Vector4 &p_step) {
|
||||
w = Math::snapped(w, p_step.w);
|
||||
}
|
||||
|
||||
void Vector4::snapf(real_t p_step) {
|
||||
x = Math::snapped(x, p_step);
|
||||
y = Math::snapped(y, p_step);
|
||||
z = Math::snapped(z, p_step);
|
||||
w = Math::snapped(w, p_step);
|
||||
}
|
||||
|
||||
Vector4 Vector4::snapped(const Vector4 &p_step) const {
|
||||
Vector4 v = *this;
|
||||
v.snap(p_step);
|
||||
return v;
|
||||
}
|
||||
|
||||
Vector4 Vector4::snappedf(real_t p_step) const {
|
||||
Vector4 v = *this;
|
||||
v.snapf(p_step);
|
||||
return v;
|
||||
}
|
||||
|
||||
Vector4 Vector4::inverse() const {
|
||||
return Vector4(1.0f / x, 1.0f / y, 1.0f / z, 1.0f / w);
|
||||
}
|
||||
@@ -191,6 +204,14 @@ Vector4 Vector4::clamp(const Vector4 &p_min, const Vector4 &p_max) const {
|
||||
CLAMP(w, p_min.w, p_max.w));
|
||||
}
|
||||
|
||||
Vector4 Vector4::clampf(real_t p_min, real_t p_max) const {
|
||||
return Vector4(
|
||||
CLAMP(x, p_min, p_max),
|
||||
CLAMP(y, p_min, p_max),
|
||||
CLAMP(z, p_min, p_max),
|
||||
CLAMP(w, p_min, p_max));
|
||||
}
|
||||
|
||||
Vector4::operator String() const {
|
||||
return "(" + String::num_real(x, false) + ", " + String::num_real(y, false) + ", " + String::num_real(z, false) + ", " + String::num_real(w, false) + ")";
|
||||
}
|
||||
|
||||
@@ -35,6 +35,22 @@
|
||||
|
||||
namespace godot {
|
||||
|
||||
Vector4i Vector4i::snapped(const Vector4i &p_step) const {
|
||||
return Vector4i(
|
||||
Math::snapped(x, p_step.x),
|
||||
Math::snapped(y, p_step.y),
|
||||
Math::snapped(z, p_step.z),
|
||||
Math::snapped(w, p_step.w));
|
||||
}
|
||||
|
||||
Vector4i Vector4i::snappedi(int32_t p_step) const {
|
||||
return Vector4i(
|
||||
Math::snapped(x, p_step),
|
||||
Math::snapped(y, p_step),
|
||||
Math::snapped(z, p_step),
|
||||
Math::snapped(w, p_step));
|
||||
}
|
||||
|
||||
Vector4i::Axis Vector4i::min_axis_index() const {
|
||||
uint32_t min_index = 0;
|
||||
int32_t min_value = x;
|
||||
@@ -67,6 +83,14 @@ Vector4i Vector4i::clamp(const Vector4i &p_min, const Vector4i &p_max) const {
|
||||
CLAMP(w, p_min.w, p_max.w));
|
||||
}
|
||||
|
||||
Vector4i Vector4i::clampi(int32_t p_min, int32_t p_max) const {
|
||||
return Vector4i(
|
||||
CLAMP(x, p_min, p_max),
|
||||
CLAMP(y, p_min, p_max),
|
||||
CLAMP(z, p_min, p_max),
|
||||
CLAMP(w, p_min, p_max));
|
||||
}
|
||||
|
||||
Vector4i::operator String() const {
|
||||
return "(" + itos(x) + ", " + itos(y) + ", " + itos(z) + ", " + itos(w) + ")";
|
||||
}
|
||||
|
||||
@@ -1,143 +1,81 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
project(godot-cpp-test)
|
||||
#[=======================================================================[.rst:
|
||||
Integration Testing
|
||||
-------------------
|
||||
|
||||
set(GODOT_GDEXTENSION_DIR ../gdextension/ CACHE STRING "Path to GDExtension interface header directory")
|
||||
set(CPP_BINDINGS_PATH ../ CACHE STRING "Path to C++ bindings")
|
||||
The Test target used to validate changes in the GitHub CI.
|
||||
]=======================================================================]
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
set(TARGET_PATH x11)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
set(TARGET_PATH win64)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
set(TARGET_PATH macos)
|
||||
else()
|
||||
message(FATAL_ERROR "Not implemented support for ${CMAKE_SYSTEM_NAME}")
|
||||
endif()
|
||||
message( STATUS "Testing Integration targets are enabled.")
|
||||
|
||||
# Change the output directory to the bin directory
|
||||
set(BUILD_PATH ${CMAKE_SOURCE_DIR}/bin/${TARGET_PATH})
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${BUILD_PATH}")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${BUILD_PATH}")
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${BUILD_PATH}")
|
||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG "${BUILD_PATH}")
|
||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE "${BUILD_PATH}")
|
||||
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${BUILD_PATH}")
|
||||
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${BUILD_PATH}")
|
||||
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${BUILD_PATH}")
|
||||
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${BUILD_PATH}")
|
||||
# Generate Doc Data
|
||||
file( GLOB_RECURSE DOC_XML
|
||||
LIST_DIRECTORIES NO
|
||||
CONFIGURE_DEPENDS
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/doc_classes/*.xml" )
|
||||
|
||||
# Set the c++ standard to c++17
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
foreach( TARGET_ALIAS template_debug template_release editor )
|
||||
set( TARGET_NAME "godot-cpp.test.${TARGET_ALIAS}" )
|
||||
|
||||
set(GODOT_COMPILE_FLAGS )
|
||||
set(GODOT_LINKER_FLAGS )
|
||||
add_library( ${TARGET_NAME} SHARED EXCLUDE_FROM_ALL )
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||
# using Visual Studio C++
|
||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /WX") # /GF /MP
|
||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /DTYPED_METHOD_BIND")
|
||||
target_sources( ${TARGET_NAME}
|
||||
PRIVATE
|
||||
src/example.cpp
|
||||
src/example.h
|
||||
src/register_types.cpp
|
||||
src/register_types.h
|
||||
src/tests.h
|
||||
)
|
||||
|
||||
if(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /MDd") # /Od /RTC1 /Zi
|
||||
else()
|
||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /MD /O2") # /Oy /GL /Gy
|
||||
STRING(REGEX REPLACE "/RTC(su|[1su])" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
string(REPLACE "/RTC1" "" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
|
||||
endif(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
# conditionally add doc data to compile output
|
||||
if( TARGET_ALIAS MATCHES "editor|template_debug" )
|
||||
target_doc_sources( ${TARGET_NAME} ${DOC_XML} )
|
||||
endif()
|
||||
|
||||
# Disable conversion warning, truncation, unreferenced var, signed mismatch
|
||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /wd4244 /wd4305 /wd4101 /wd4018 /wd4267")
|
||||
set( OUTPUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/project/bin/" )
|
||||
|
||||
add_definitions(-DNOMINMAX)
|
||||
# Link to godot-cpp target
|
||||
set( LINK_TARGET "godot-cpp::${TARGET_ALIAS}" )
|
||||
target_link_libraries( ${TARGET_NAME} PRIVATE ${LINK_TARGET} )
|
||||
|
||||
# Unkomment for warning level 4
|
||||
#if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
|
||||
# string(REGEX REPLACE "/W[0-4]" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
#endif()
|
||||
### Get useful properties from godot-cpp target
|
||||
get_target_property( GODOTCPP_SUFFIX ${LINK_TARGET} GODOTCPP_SUFFIX )
|
||||
get_target_property( OSX_ARCH ${LINK_TARGET} OSX_ARCHITECTURES )
|
||||
|
||||
else()
|
||||
set_target_properties( ${TARGET_NAME}
|
||||
PROPERTIES
|
||||
CXX_STANDARD 17
|
||||
CXX_EXTENSIONS OFF
|
||||
CXX_VISIBILITY_PRESET ${GODOTCPP_SYMBOL_VISIBILITY}
|
||||
|
||||
set(GODOT_LINKER_FLAGS "-static-libgcc -static-libstdc++ -Wl,-R,'$$ORIGIN'")
|
||||
POSITION_INDEPENDENT_CODE ON
|
||||
BUILD_RPATH_USE_ORIGIN ON
|
||||
|
||||
set(GODOT_COMPILE_FLAGS "-fPIC -g -Wwrite-strings")
|
||||
# Try to ensure only static libraries are selected to be linked to.
|
||||
LINK_SEARCH_START_STATIC ON
|
||||
LINK_SEARCH_END_STATIC ON
|
||||
|
||||
if(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -fno-omit-frame-pointer -O0")
|
||||
else()
|
||||
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -O3")
|
||||
endif(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
endif()
|
||||
# NOTE: Wrapping the output variables inside a generator expression
|
||||
# prevents msvc generator from adding addition Config Directories
|
||||
LIBRARY_OUTPUT_DIRECTORY "$<1:${OUTPUT_DIR}>"
|
||||
RUNTIME_OUTPUT_DIRECTORY "$<1:${OUTPUT_DIR}>"
|
||||
PDB_OUTPUT_DIRECTORY "$<1:${OUTPUT_DIR}>" #MSVC Only, ignored on other platforms
|
||||
|
||||
# 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()
|
||||
PREFIX "lib"
|
||||
OUTPUT_NAME "gdexample${GODOTCPP_SUFFIX}"
|
||||
|
||||
# Get Sources
|
||||
file(GLOB_RECURSE SOURCES src/*.c**)
|
||||
file(GLOB_RECURSE HEADERS include/*.h**)
|
||||
# Some IDE's respect this property to logically group targets
|
||||
FOLDER "godot-cpp"
|
||||
)
|
||||
|
||||
# Define our godot-cpp library
|
||||
add_library(${PROJECT_NAME} SHARED ${SOURCES} ${HEADERS})
|
||||
# CMAKE_SYSTEM_NAME refers to the target system
|
||||
if( CMAKE_SYSTEM_NAME STREQUAL Darwin )
|
||||
set_target_properties( ${TARGET_NAME}
|
||||
PROPERTIES
|
||||
SUFFIX ""
|
||||
OUTPUT_DIR "${OUTPUT_DIR}/libgdexample.macos.${TARGET_ALIAS}.framework"
|
||||
OSX_ARCHITECTURES "${OSX_ARCH}"
|
||||
)
|
||||
endif()
|
||||
|
||||
target_include_directories(${PROJECT_NAME} SYSTEM
|
||||
PRIVATE
|
||||
${CPP_BINDINGS_PATH}/include
|
||||
${CPP_BINDINGS_PATH}/gen/include
|
||||
${GODOT_GDEXTENSION_DIR}
|
||||
)
|
||||
|
||||
# Create the correct name (godot.os.build_type.system_bits)
|
||||
# Synchronized with godot-cpp's CMakeLists.txt
|
||||
|
||||
set(BITS 32)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(BITS 64)
|
||||
endif(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
|
||||
if(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
set(GODOT_CPP_BUILD_TYPE Debug)
|
||||
else()
|
||||
set(GODOT_CPP_BUILD_TYPE Release)
|
||||
endif()
|
||||
|
||||
string(TOLOWER ${CMAKE_SYSTEM_NAME} SYSTEM_NAME)
|
||||
string(TOLOWER ${GODOT_CPP_BUILD_TYPE} BUILD_TYPE)
|
||||
|
||||
if(ANDROID)
|
||||
# Added the android abi after system name
|
||||
set(SYSTEM_NAME ${SYSTEM_NAME}.${ANDROID_ABI})
|
||||
endif()
|
||||
|
||||
if(CMAKE_VERSION VERSION_GREATER "3.13")
|
||||
target_link_directories(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
${CPP_BINDINGS_PATH}/bin/
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
godot-cpp.${SYSTEM_NAME}.${BUILD_TYPE}$<$<NOT:$<PLATFORM_ID:Android>>:.${BITS}>
|
||||
)
|
||||
else()
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
${CPP_BINDINGS_PATH}/bin/libgodot-cpp.${SYSTEM_NAME}.${BUILD_TYPE}$<$<NOT:$<PLATFORM_ID:Android>>:.${BITS}>.a
|
||||
)
|
||||
endif()
|
||||
|
||||
# Add the compile flags
|
||||
set_property(TARGET ${PROJECT_NAME} APPEND_STRING PROPERTY COMPILE_FLAGS ${GODOT_COMPILE_FLAGS})
|
||||
set_property(TARGET ${PROJECT_NAME} APPEND_STRING PROPERTY LINK_FLAGS ${GODOT_LINKER_FLAGS})
|
||||
|
||||
set_property(TARGET ${PROJECT_NAME} PROPERTY OUTPUT_NAME "gdexample")
|
||||
endforeach()
|
||||
|
||||
@@ -14,6 +14,10 @@ env = SConscript("../SConstruct")
|
||||
env.Append(CPPPATH=["src/"])
|
||||
sources = Glob("src/*.cpp")
|
||||
|
||||
if env["target"] in ["editor", "template_debug"]:
|
||||
doc_data = env.GodotCPPDocData("src/gen/doc_data.gen.cpp", source=Glob("doc_classes/*.xml"))
|
||||
sources.append(doc_data)
|
||||
|
||||
if env["platform"] == "macos":
|
||||
library = env.SharedLibrary(
|
||||
"project/bin/libgdexample.{}.{}.framework/libgdexample.{}.{}".format(
|
||||
|
||||
25
test/doc_classes/Example.xml
Normal file
25
test/doc_classes/Example.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<class name="Example" inherits="Control" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/godotengine/godot/master/doc/class.xsd">
|
||||
<brief_description>
|
||||
A test control defined in GDExtension.
|
||||
</brief_description>
|
||||
<description>
|
||||
A control used for the automated GDExtension tests.
|
||||
</description>
|
||||
<tutorials>
|
||||
</tutorials>
|
||||
<methods>
|
||||
<method name="simple_func">
|
||||
<return type="void" />
|
||||
<description>
|
||||
Tests a simple function call.
|
||||
</description>
|
||||
</method>
|
||||
</methods>
|
||||
<members>
|
||||
</members>
|
||||
<signals>
|
||||
</signals>
|
||||
<constants>
|
||||
</constants>
|
||||
</class>
|
||||
5
test/project/example.gd
Normal file
5
test/project/example.gd
Normal file
@@ -0,0 +1,5 @@
|
||||
extends Example
|
||||
|
||||
func _do_something_virtual(p_name, p_value):
|
||||
custom_signal.emit(p_name, p_value)
|
||||
return "Implemented"
|
||||
@@ -9,12 +9,15 @@ class TestClass:
|
||||
func _ready():
|
||||
var example: Example = $Example
|
||||
|
||||
# Timing of set instance binding.
|
||||
assert_equal(example.is_object_binding_set_by_parent_constructor(), true)
|
||||
|
||||
# Signal.
|
||||
example.emit_custom_signal("Button", 42)
|
||||
assert_equal(custom_signal_emitted, ["Button", 42])
|
||||
|
||||
# To string.
|
||||
assert_equal(example.to_string(),'Example:[ GDExtension::Example <--> Instance ID:%s ]' % example.get_instance_id())
|
||||
assert_equal(example.to_string(),'[ 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())
|
||||
|
||||
@@ -78,10 +81,13 @@ func _ready():
|
||||
|
||||
# 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"})
|
||||
assert_equal(example.test_tarray(), [Vector2(1, 2), Vector2(2, 3)])
|
||||
var array: Array[int] = [1, 2, 3]
|
||||
assert_equal(example.test_tarray_arg(array), 6)
|
||||
assert_equal(example.test_dictionary(), { "hello": "world", "foo": "bar" })
|
||||
assert_equal(example.test_tdictionary(), { Vector2(1, 2): Vector2i(2, 3) })
|
||||
var dictionary: Dictionary[String, int] = { "1": 1, "2": 2, "3": 3 }
|
||||
assert_equal(example.test_tdictionary_arg(dictionary), 6)
|
||||
|
||||
example.callable_bind()
|
||||
assert_equal(custom_signal_emitted, ["bound", 11])
|
||||
@@ -102,6 +108,7 @@ func _ready():
|
||||
# mp_callable() with void method.
|
||||
var mp_callable: Callable = example.test_callable_mp()
|
||||
assert_equal(mp_callable.is_valid(), true)
|
||||
assert_equal(mp_callable.get_argument_count(), 3)
|
||||
mp_callable.call(example, "void", 36)
|
||||
assert_equal(custom_signal_emitted, ["unbound_method1: Example - void", 36])
|
||||
|
||||
@@ -117,14 +124,17 @@ func _ready():
|
||||
|
||||
# mp_callable() with return value.
|
||||
var mp_callable_ret: Callable = example.test_callable_mp_ret()
|
||||
assert_equal(mp_callable_ret.get_argument_count(), 3)
|
||||
assert_equal(mp_callable_ret.call(example, "test", 77), "unbound_method2: Example - test - 77")
|
||||
|
||||
# mp_callable() with const method and return value.
|
||||
var mp_callable_retc: Callable = example.test_callable_mp_retc()
|
||||
assert_equal(mp_callable_retc.get_argument_count(), 3)
|
||||
assert_equal(mp_callable_retc.call(example, "const", 101), "unbound_method3: Example - const - 101")
|
||||
|
||||
# mp_callable_static() with void method.
|
||||
var mp_callable_static: Callable = example.test_callable_mp_static()
|
||||
assert_equal(mp_callable_static.get_argument_count(), 3)
|
||||
mp_callable_static.call(example, "static", 83)
|
||||
assert_equal(custom_signal_emitted, ["unbound_static_method1: Example - static", 83])
|
||||
|
||||
@@ -140,6 +150,7 @@ func _ready():
|
||||
|
||||
# mp_callable_static() with return value.
|
||||
var mp_callable_static_ret: Callable = example.test_callable_mp_static_ret()
|
||||
assert_equal(mp_callable_static_ret.get_argument_count(), 3)
|
||||
assert_equal(mp_callable_static_ret.call(example, "static-ret", 84), "unbound_static_method2: Example - static-ret - 84")
|
||||
|
||||
# CallableCustom.
|
||||
@@ -150,6 +161,7 @@ func _ready():
|
||||
assert_equal(custom_callable.hash(), 27);
|
||||
assert_equal(custom_callable.get_object(), null);
|
||||
assert_equal(custom_callable.get_method(), "");
|
||||
assert_equal(custom_callable.get_argument_count(), 2)
|
||||
assert_equal(str(custom_callable), "<MyCallableCustom>");
|
||||
|
||||
# PackedArray iterators
|
||||
@@ -197,6 +209,12 @@ func _ready():
|
||||
assert_equal(example.test_variant_float_conversion(10.0), 10.0)
|
||||
assert_equal(example.test_variant_float_conversion(10), 10.0)
|
||||
|
||||
# Test checking if objects are valid.
|
||||
var object_of_questionable_validity = Object.new()
|
||||
assert_equal(example.test_object_is_valid(object_of_questionable_validity), true)
|
||||
object_of_questionable_validity.free()
|
||||
assert_equal(example.test_object_is_valid(object_of_questionable_validity), false)
|
||||
|
||||
# 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)
|
||||
@@ -246,9 +264,16 @@ func _ready():
|
||||
assert_equal(new_example_ref.was_post_initialized(), true)
|
||||
assert_equal(example.test_post_initialize(), true)
|
||||
|
||||
# Test a virtual method defined in GDExtension and implemented in script.
|
||||
assert_equal(example.test_virtual_implemented_in_script("Virtual", 939), "Implemented")
|
||||
assert_equal(custom_signal_emitted, ["Virtual", 939])
|
||||
|
||||
# Test that we can access an engine singleton.
|
||||
assert_equal(example.test_use_engine_singleton(), OS.get_name())
|
||||
|
||||
assert_equal(example.test_get_internal(1), 1)
|
||||
assert_equal(example.test_get_internal(true), -1)
|
||||
|
||||
# Test that notifications happen on both parent and child classes.
|
||||
var example_child = $ExampleChild
|
||||
assert_equal(example_child.get_value1(), 11)
|
||||
@@ -263,6 +288,10 @@ func _ready():
|
||||
assert_equal(library_path, ProjectSettings.globalize_path(library_path))
|
||||
assert_equal(FileAccess.file_exists(library_path), true)
|
||||
|
||||
# Test a class with a unicode name.
|
||||
var przykład = ExamplePrzykład.new()
|
||||
assert_equal(przykład.get_the_word(), "słowo to przykład")
|
||||
|
||||
exit_with_status()
|
||||
|
||||
func _on_Example_custom_signal(signal_name, value):
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://dmx2xuigcpvt4"]
|
||||
[gd_scene load_steps=3 format=3 uid="uid://dmx2xuigcpvt4"]
|
||||
|
||||
[ext_resource type="Script" path="res://main.gd" id="1_qesh5"]
|
||||
[ext_resource type="Script" path="res://example.gd" id="2_jju25"]
|
||||
|
||||
[node name="Node" type="Node"]
|
||||
script = ExtResource("1_qesh5")
|
||||
|
||||
[node name="Example" type="Example" parent="."]
|
||||
script = ExtResource("2_jju25")
|
||||
|
||||
[node name="ExampleMin" type="ExampleMin" parent="Example"]
|
||||
layout_mode = 0
|
||||
|
||||
@@ -12,7 +12,7 @@ config_version=5
|
||||
|
||||
config/name="GDExtension Test Project"
|
||||
run/main_scene="res://main.tscn"
|
||||
config/features=PackedStringArray("4.2")
|
||||
config/features=PackedStringArray("4.3")
|
||||
config/icon="res://icon.png"
|
||||
|
||||
[native_extensions]
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <godot_cpp/classes/multiplayer_api.hpp>
|
||||
#include <godot_cpp/classes/multiplayer_peer.hpp>
|
||||
#include <godot_cpp/classes/os.hpp>
|
||||
#include <godot_cpp/variant/typed_dictionary.hpp>
|
||||
#include <godot_cpp/variant/utility_functions.hpp>
|
||||
|
||||
using namespace godot;
|
||||
@@ -50,6 +51,11 @@ public:
|
||||
return ObjectID();
|
||||
}
|
||||
|
||||
virtual int get_argument_count(bool &r_is_valid) const {
|
||||
r_is_valid = true;
|
||||
return 2;
|
||||
}
|
||||
|
||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, GDExtensionCallError &r_call_error) const {
|
||||
r_return_value = "Hi";
|
||||
r_call_error.error = GDEXTENSION_CALL_OK;
|
||||
@@ -188,10 +194,14 @@ void Example::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("return_extended_ref"), &Example::return_extended_ref);
|
||||
ClassDB::bind_method(D_METHOD("extended_ref_checks", "ref"), &Example::extended_ref_checks);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("is_object_binding_set_by_parent_constructor"), &Example::is_object_binding_set_by_parent_constructor);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("test_array"), &Example::test_array);
|
||||
ClassDB::bind_method(D_METHOD("test_tarray_arg", "array"), &Example::test_tarray_arg);
|
||||
ClassDB::bind_method(D_METHOD("test_tarray"), &Example::test_tarray);
|
||||
ClassDB::bind_method(D_METHOD("test_dictionary"), &Example::test_dictionary);
|
||||
ClassDB::bind_method(D_METHOD("test_tdictionary_arg", "dictionary"), &Example::test_tdictionary_arg);
|
||||
ClassDB::bind_method(D_METHOD("test_tdictionary"), &Example::test_tdictionary);
|
||||
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_str_utility"), &Example::test_str_utility);
|
||||
@@ -208,6 +218,7 @@ void Example::_bind_methods() {
|
||||
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_object_is_valid", "variant"), &Example::test_object_is_valid);
|
||||
|
||||
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);
|
||||
@@ -233,6 +244,12 @@ void Example::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("callable_bind"), &Example::callable_bind);
|
||||
ClassDB::bind_method(D_METHOD("test_post_initialize"), &Example::test_post_initialize);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("test_get_internal", "a"), &Example::test_get_internal);
|
||||
|
||||
GDVIRTUAL_BIND(_do_something_virtual, "name", "value");
|
||||
ClassDB::bind_method(D_METHOD("test_virtual_implemented_in_script"), &Example::test_virtual_implemented_in_script);
|
||||
GDVIRTUAL_BIND(_do_something_virtual_with_control, "control");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("test_use_engine_singleton"), &Example::test_use_engine_singleton);
|
||||
|
||||
ClassDB::bind_static_method("Example", D_METHOD("test_static", "a", "b"), &Example::test_static);
|
||||
@@ -285,7 +302,17 @@ void Example::_bind_methods() {
|
||||
BIND_ENUM_CONSTANT(OUTSIDE_OF_CLASS);
|
||||
}
|
||||
|
||||
Example::Example() {
|
||||
bool Example::has_object_instance_binding() const {
|
||||
return internal::gdextension_interface_object_get_instance_binding(_owner, internal::token, nullptr);
|
||||
}
|
||||
|
||||
Example::Example() :
|
||||
object_instance_binding_set_by_parent_constructor(has_object_instance_binding()) {
|
||||
// Test conversion, to ensure users can use all parent class functions at this time.
|
||||
// It would crash if instance binding still not be initialized.
|
||||
Variant v = Variant(this);
|
||||
Object *o = (Object *)v;
|
||||
|
||||
//UtilityFunctions::print("Constructor.");
|
||||
}
|
||||
|
||||
@@ -365,6 +392,10 @@ void Example::emit_custom_signal(const String &name, int value) {
|
||||
emit_signal("custom_signal", name, value);
|
||||
}
|
||||
|
||||
bool Example::is_object_binding_set_by_parent_constructor() const {
|
||||
return object_instance_binding_set_by_parent_constructor;
|
||||
}
|
||||
|
||||
Array Example::test_array() const {
|
||||
Array arr;
|
||||
|
||||
@@ -526,6 +557,23 @@ Dictionary Example::test_dictionary() const {
|
||||
return dict;
|
||||
}
|
||||
|
||||
int Example::test_tdictionary_arg(const TypedDictionary<String, int64_t> &p_dictionary) {
|
||||
int sum = 0;
|
||||
TypedArray<int64_t> values = p_dictionary.values();
|
||||
for (int i = 0; i < p_dictionary.size(); i++) {
|
||||
sum += (int)values[i];
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
TypedDictionary<Vector2, Vector2i> Example::test_tdictionary() const {
|
||||
TypedDictionary<Vector2, Vector2i> dict;
|
||||
|
||||
dict[Vector2(1, 2)] = Vector2i(2, 3);
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
Example *Example::test_node_argument(Example *p_node) const {
|
||||
return p_node;
|
||||
}
|
||||
@@ -554,6 +602,10 @@ float Example::test_variant_float_conversion(const Variant &p_variant) const {
|
||||
return p_variant;
|
||||
}
|
||||
|
||||
bool Example::test_object_is_valid(const Variant &p_variant) const {
|
||||
return static_cast<bool>(p_variant.get_validated_object());
|
||||
}
|
||||
|
||||
void Example::test_add_child(Node *p_node) {
|
||||
add_child(p_node);
|
||||
}
|
||||
@@ -674,6 +726,14 @@ void ExampleChild::_notification(int p_what) {
|
||||
}
|
||||
}
|
||||
|
||||
String Example::test_virtual_implemented_in_script(const String &p_name, int p_value) {
|
||||
String ret;
|
||||
if (GDVIRTUAL_CALL(_do_something_virtual, p_name, p_value, ret)) {
|
||||
return ret;
|
||||
}
|
||||
return "Unimplemented";
|
||||
}
|
||||
|
||||
String Example::test_use_engine_singleton() const {
|
||||
return OS::get_singleton()->get_name();
|
||||
}
|
||||
@@ -683,3 +743,39 @@ String Example::test_library_path() {
|
||||
internal::gdextension_interface_get_library_path(internal::library, library_path._native_ptr());
|
||||
return library_path;
|
||||
}
|
||||
|
||||
int64_t Example::test_get_internal(const Variant &p_input) const {
|
||||
if (p_input.get_type() != Variant::INT) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return *VariantInternal::get_int(&p_input);
|
||||
}
|
||||
|
||||
void ExampleRuntime::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_prop_value", "value"), &ExampleRuntime::set_prop_value);
|
||||
ClassDB::bind_method(D_METHOD("get_prop_value"), &ExampleRuntime::get_prop_value);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "prop_value"), "set_prop_value", "get_prop_value");
|
||||
}
|
||||
|
||||
void ExampleRuntime::set_prop_value(int p_prop_value) {
|
||||
prop_value = p_prop_value;
|
||||
}
|
||||
|
||||
int ExampleRuntime::get_prop_value() const {
|
||||
return prop_value;
|
||||
}
|
||||
|
||||
ExampleRuntime::ExampleRuntime() {
|
||||
}
|
||||
|
||||
ExampleRuntime::~ExampleRuntime() {
|
||||
}
|
||||
|
||||
void ExamplePrzykład::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_the_word"), &ExamplePrzykład::get_the_word);
|
||||
}
|
||||
|
||||
String ExamplePrzykład::get_the_word() const {
|
||||
return U"słowo to przykład";
|
||||
}
|
||||
|
||||
@@ -21,9 +21,12 @@
|
||||
#include <godot_cpp/classes/tile_map.hpp>
|
||||
#include <godot_cpp/classes/tile_set.hpp>
|
||||
#include <godot_cpp/classes/viewport.hpp>
|
||||
#include <godot_cpp/variant/typed_dictionary.hpp>
|
||||
#include <godot_cpp/variant/variant.hpp>
|
||||
#include <godot_cpp/variant/variant_internal.hpp>
|
||||
|
||||
#include <godot_cpp/core/binder_common.hpp>
|
||||
#include <godot_cpp/core/gdvirtual.gen.inc>
|
||||
|
||||
using namespace godot;
|
||||
|
||||
@@ -81,6 +84,9 @@ private:
|
||||
Vector2 dprop[3];
|
||||
int last_rpc_arg = 0;
|
||||
|
||||
const bool object_instance_binding_set_by_parent_constructor;
|
||||
bool has_object_instance_binding() const;
|
||||
|
||||
public:
|
||||
// Constants.
|
||||
enum Constants {
|
||||
@@ -119,10 +125,14 @@ public:
|
||||
void emit_custom_signal(const String &name, int value);
|
||||
int def_args(int p_a = 100, int p_b = 200);
|
||||
|
||||
bool is_object_binding_set_by_parent_constructor() const;
|
||||
|
||||
Array test_array() const;
|
||||
int test_tarray_arg(const TypedArray<int64_t> &p_array);
|
||||
TypedArray<Vector2> test_tarray() const;
|
||||
Dictionary test_dictionary() const;
|
||||
int test_tdictionary_arg(const TypedDictionary<String, int64_t> &p_dictionary);
|
||||
TypedDictionary<Vector2, Vector2i> test_tdictionary() const;
|
||||
Example *test_node_argument(Example *p_node) const;
|
||||
String test_string_ops() const;
|
||||
String test_str_utility() const;
|
||||
@@ -139,6 +149,7 @@ public:
|
||||
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;
|
||||
bool test_object_is_valid(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;
|
||||
@@ -176,6 +187,8 @@ public:
|
||||
|
||||
bool test_post_initialize() const;
|
||||
|
||||
int64_t test_get_internal(const Variant &p_input) const;
|
||||
|
||||
// Static method.
|
||||
static int test_static(int p_a, int p_b);
|
||||
static void test_static2();
|
||||
@@ -184,6 +197,10 @@ public:
|
||||
virtual bool _has_point(const Vector2 &point) const override;
|
||||
virtual void _input(const Ref<InputEvent> &event) override;
|
||||
|
||||
GDVIRTUAL2R(String, _do_something_virtual, String, int);
|
||||
String test_virtual_implemented_in_script(const String &p_name, int p_value);
|
||||
GDVIRTUAL1(_do_something_virtual_with_control, Control *);
|
||||
|
||||
String test_use_engine_singleton() const;
|
||||
|
||||
static String test_library_path();
|
||||
@@ -247,4 +264,30 @@ protected:
|
||||
void _notification(int p_what);
|
||||
};
|
||||
|
||||
class ExampleRuntime : public Node {
|
||||
GDCLASS(ExampleRuntime, Node);
|
||||
|
||||
int prop_value = 12;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
void set_prop_value(int p_prop_value);
|
||||
int get_prop_value() const;
|
||||
|
||||
ExampleRuntime();
|
||||
~ExampleRuntime();
|
||||
};
|
||||
|
||||
class ExamplePrzykład : public RefCounted {
|
||||
GDCLASS(ExamplePrzykład, RefCounted);
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
String get_the_word() const;
|
||||
};
|
||||
|
||||
#endif // EXAMPLE_CLASS_H
|
||||
|
||||
@@ -29,6 +29,8 @@ void initialize_example_module(ModuleInitializationLevel p_level) {
|
||||
GDREGISTER_CLASS(ExampleConcrete);
|
||||
GDREGISTER_CLASS(ExampleBase);
|
||||
GDREGISTER_CLASS(ExampleChild);
|
||||
GDREGISTER_RUNTIME_CLASS(ExampleRuntime);
|
||||
GDREGISTER_CLASS(ExamplePrzykład);
|
||||
}
|
||||
|
||||
void uninitialize_example_module(ModuleInitializationLevel p_level) {
|
||||
|
||||
@@ -12,6 +12,7 @@ from SCons.Variables.BoolVariable import _text2bool
|
||||
|
||||
from binding_generator import _generate_bindings, _get_file_list, get_file_list
|
||||
from build_profile import generate_trimmed_api
|
||||
from doc_source_generator import scons_generate_doc_source
|
||||
|
||||
|
||||
def add_sources(sources, dir, extension):
|
||||
@@ -508,7 +509,8 @@ def generate(env):
|
||||
# Builders
|
||||
env.Append(
|
||||
BUILDERS={
|
||||
"GodotCPPBindings": Builder(action=Action(scons_generate_bindings, "$GENCOMSTR"), emitter=scons_emit_files)
|
||||
"GodotCPPBindings": Builder(action=Action(scons_generate_bindings, "$GENCOMSTR"), emitter=scons_emit_files),
|
||||
"GodotCPPDocData": Builder(action=scons_generate_doc_source),
|
||||
}
|
||||
)
|
||||
env.AddMethod(_godot_cpp, "GodotCPP")
|
||||
|
||||
@@ -42,6 +42,10 @@ def generate(env):
|
||||
env.Append(CCFLAGS=["-sSIDE_MODULE=1"])
|
||||
env.Append(LINKFLAGS=["-sSIDE_MODULE=1"])
|
||||
|
||||
# Enable WebAssembly BigInt <-> i64 conversion.
|
||||
# This must match the flag used to build Godot (true in official builds since 4.3)
|
||||
env.Append(LINKFLAGS=["-sWASM_BIGINT"])
|
||||
|
||||
# Force wasm longjmp mode.
|
||||
env.Append(CCFLAGS=["-sSUPPORT_LONGJMP='wasm'"])
|
||||
env.Append(LINKFLAGS=["-sSUPPORT_LONGJMP='wasm'"])
|
||||
|
||||
@@ -78,6 +78,7 @@ def options(opts):
|
||||
opts.Add(BoolVariable("use_mingw", "Use the MinGW compiler instead of MSVC - only effective on Windows", False))
|
||||
opts.Add(BoolVariable("use_static_cpp", "Link MinGW/MSVC C++ runtime libraries statically", True))
|
||||
opts.Add(BoolVariable("silence_msvc", "Silence MSVC's cl/link stdout bloat, redirecting errors to stderr.", True))
|
||||
opts.Add(BoolVariable("debug_crt", "Compile with MSVC's debug CRT (/MDd)", False))
|
||||
opts.Add(BoolVariable("use_llvm", "Use the LLVM compiler (MVSC or MinGW depending on the use_mingw flag)", False))
|
||||
opts.Add("mingw_prefix", "MinGW prefix", mingw)
|
||||
|
||||
@@ -117,10 +118,14 @@ def generate(env):
|
||||
env["CC"] = "clang-cl"
|
||||
env["CXX"] = "clang-cl"
|
||||
|
||||
if env["use_static_cpp"]:
|
||||
env.Append(CCFLAGS=["/MT"])
|
||||
if env["debug_crt"]:
|
||||
# Always use dynamic runtime, static debug CRT breaks thread_local.
|
||||
env.AppendUnique(CCFLAGS=["/MDd"])
|
||||
else:
|
||||
env.Append(CCFLAGS=["/MD"])
|
||||
if env["use_static_cpp"]:
|
||||
env.AppendUnique(CCFLAGS=["/MT"])
|
||||
else:
|
||||
env.AppendUnique(CCFLAGS=["/MD"])
|
||||
|
||||
if env["silence_msvc"] and not env.GetOption("clean"):
|
||||
silence_msvc(env)
|
||||
|
||||
Reference in New Issue
Block a user