Started a Cobor Virtual Machine implementation for running the code.
This commit is contained in:
25
cobor_vm_extension/godot-cpp/test/.gitignore
vendored
Normal file
25
cobor_vm_extension/godot-cpp/test/.gitignore
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# Generated directories with binaries
|
||||
build
|
||||
bin
|
||||
|
||||
# Godot 4+ specific ignores
|
||||
.godot/
|
||||
|
||||
# Godot-specific ignores
|
||||
.import/
|
||||
export.cfg
|
||||
export_presets.cfg
|
||||
# Dummy HTML5 export presets file for continuous integration
|
||||
!.github/dist/export_presets.cfg
|
||||
|
||||
# Imported translations (automatically generated from CSV files)
|
||||
*.translation
|
||||
|
||||
# Mono-specific ignores
|
||||
.mono/
|
||||
data_*/
|
||||
mono_crash.*.json
|
||||
|
||||
# System/tool-specific ignores
|
||||
.directory
|
||||
*~
|
||||
69
cobor_vm_extension/godot-cpp/test/CMakeLists.txt
Normal file
69
cobor_vm_extension/godot-cpp/test/CMakeLists.txt
Normal file
@@ -0,0 +1,69 @@
|
||||
#[=======================================================================[.rst:
|
||||
Integration Testing
|
||||
-------------------
|
||||
|
||||
The Test target used to validate changes in the GitHub CI.
|
||||
]=======================================================================]
|
||||
|
||||
message(STATUS "Testing Integration targets are enabled.")
|
||||
|
||||
set(TARGET_NAME "godot-cpp-test")
|
||||
|
||||
add_library(${TARGET_NAME} SHARED EXCLUDE_FROM_ALL)
|
||||
|
||||
target_sources(
|
||||
${TARGET_NAME}
|
||||
PRIVATE src/example.cpp src/example.h src/register_types.cpp src/register_types.h src/tests.h
|
||||
)
|
||||
|
||||
# conditionally add doc data to compile output
|
||||
if(GODOTCPP_TARGET MATCHES "editor|template_debug")
|
||||
file(GLOB_RECURSE DOC_XML LIST_DIRECTORIES NO CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/doc_classes/*.xml")
|
||||
target_doc_sources( ${TARGET_NAME} ${DOC_XML} )
|
||||
endif()
|
||||
|
||||
set(OUTPUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/project/bin/")
|
||||
|
||||
# Link to godot-cpp target
|
||||
target_link_libraries(${TARGET_NAME} PRIVATE godot-cpp)
|
||||
|
||||
### Get useful properties from godot-cpp target
|
||||
get_target_property(GODOTCPP_SUFFIX godot-cpp GODOTCPP_SUFFIX)
|
||||
|
||||
# gersemi: off
|
||||
set_target_properties(
|
||||
${TARGET_NAME}
|
||||
PROPERTIES
|
||||
CXX_STANDARD 17
|
||||
CXX_EXTENSIONS OFF
|
||||
CXX_VISIBILITY_PRESET ${GODOTCPP_SYMBOL_VISIBILITY}
|
||||
|
||||
POSITION_INDEPENDENT_CODE ON
|
||||
BUILD_RPATH_USE_ORIGIN ON
|
||||
|
||||
# Try to ensure only static libraries are selected to be linked to.
|
||||
LINK_SEARCH_START_STATIC ON
|
||||
LINK_SEARCH_END_STATIC ON
|
||||
|
||||
# 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
|
||||
|
||||
PREFIX "lib"
|
||||
OUTPUT_NAME "gdexample${GODOTCPP_SUFFIX}"
|
||||
# TODO rename the file for both CMake and SCons
|
||||
|
||||
# Some IDE's respect this property to logically group targets
|
||||
FOLDER "godot-cpp"
|
||||
)
|
||||
# gersemi: on
|
||||
|
||||
# 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.${GODOTCPP_TARGET}.framework"
|
||||
)
|
||||
endif()
|
||||
31
cobor_vm_extension/godot-cpp/test/README.md
Normal file
31
cobor_vm_extension/godot-cpp/test/README.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# godot-cpp integration test
|
||||
|
||||
This project is used to perform integration testing of the godot-cpp
|
||||
extension, to validate PRs and implemented APIs.
|
||||
|
||||
## License
|
||||
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
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 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.
|
||||
|
||||
For more information, please refer to <https://unlicense.org/>
|
||||
46
cobor_vm_extension/godot-cpp/test/SConstruct
Normal file
46
cobor_vm_extension/godot-cpp/test/SConstruct
Normal file
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
env = SConscript("../SConstruct")
|
||||
|
||||
# For the reference:
|
||||
# - CCFLAGS are compilation flags shared between C and C++
|
||||
# - CFLAGS are for C-specific compilation flags
|
||||
# - CXXFLAGS are for C++-specific compilation flags
|
||||
# - CPPFLAGS are for pre-processor flags
|
||||
# - CPPDEFINES are for pre-processor defines
|
||||
# - LINKFLAGS are for linking flags
|
||||
|
||||
# tweak this if you want to use different folders, or more folders, to store your source code in.
|
||||
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(
|
||||
env["platform"], env["target"], env["platform"], env["target"]
|
||||
),
|
||||
source=sources,
|
||||
)
|
||||
elif env["platform"] == "ios":
|
||||
if env["ios_simulator"]:
|
||||
library = env.StaticLibrary(
|
||||
"project/bin/libgdexample.{}.{}.simulator.a".format(env["platform"], env["target"]),
|
||||
source=sources,
|
||||
)
|
||||
else:
|
||||
library = env.StaticLibrary(
|
||||
"project/bin/libgdexample.{}.{}.a".format(env["platform"], env["target"]),
|
||||
source=sources,
|
||||
)
|
||||
else:
|
||||
library = env.SharedLibrary(
|
||||
"project/bin/libgdexample{}{}".format(env["suffix"], env["SHLIBSUFFIX"]),
|
||||
source=sources,
|
||||
)
|
||||
|
||||
env.NoCache(library)
|
||||
Default(library)
|
||||
13
cobor_vm_extension/godot-cpp/test/build_profile.json
Normal file
13
cobor_vm_extension/godot-cpp/test/build_profile.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"enabled_classes": [
|
||||
"Control",
|
||||
"InputEventKey",
|
||||
"Label",
|
||||
"MultiplayerAPI",
|
||||
"MultiplayerPeer",
|
||||
"OS",
|
||||
"TileMap",
|
||||
"TileSet",
|
||||
"Viewport"
|
||||
]
|
||||
}
|
||||
25
cobor_vm_extension/godot-cpp/test/doc_classes/Example.xml
Normal file
25
cobor_vm_extension/godot-cpp/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>
|
||||
7
cobor_vm_extension/godot-cpp/test/generate_xcframework.sh
Executable file
7
cobor_vm_extension/godot-cpp/test/generate_xcframework.sh
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
scons arch=universal ios_simulator=yes platform=ios target=$1 $2
|
||||
scons arch=arm64 ios_simulator=no platform=ios target=$1 $2
|
||||
|
||||
xcodebuild -create-xcframework -library ./project/bin/libgdexample.ios.$1.a -library ./project/bin/libgdexample.ios.$1.simulator.a -output ./project/bin/libgdexample.ios.$1.xcframework
|
||||
xcodebuild -create-xcframework -library ../bin/libgodot-cpp.ios.$1.arm64.a -library ../bin/libgodot-cpp.ios.$1.universal.simulator.a -output ./project/bin/libgodot-cpp.ios.$1.xcframework
|
||||
@@ -0,0 +1,7 @@
|
||||
[gd_resource type="Environment" load_steps=2 format=3 uid="uid://dtd3q2x2ulcsi"]
|
||||
|
||||
[sub_resource type="Sky" id="1"]
|
||||
|
||||
[resource]
|
||||
background_mode = 2
|
||||
sky = SubResource("1")
|
||||
5
cobor_vm_extension/godot-cpp/test/project/example.gd
Normal file
5
cobor_vm_extension/godot-cpp/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"
|
||||
@@ -0,0 +1,43 @@
|
||||
[configuration]
|
||||
|
||||
entry_symbol = "example_library_init"
|
||||
compatibility_minimum = "4.1"
|
||||
|
||||
[libraries]
|
||||
|
||||
macos.debug = "res://bin/libgdexample.macos.template_debug.framework"
|
||||
macos.release = "res://bin/libgdexample.macos.template_release.framework"
|
||||
windows.debug.x86_32 = "res://bin/libgdexample.windows.template_debug.x86_32.dll"
|
||||
windows.release.x86_32 = "res://bin/libgdexample.windows.template_release.x86_32.dll"
|
||||
windows.debug.x86_64 = "res://bin/libgdexample.windows.template_debug.x86_64.dll"
|
||||
windows.release.x86_64 = "res://bin/libgdexample.windows.template_release.x86_64.dll"
|
||||
windows.debug.arm64 = "res://bin/libgdexample.windows.template_debug.arm64.dll"
|
||||
windows.release.arm64 = "res://bin/libgdexample.windows.template_release.arm64.dll"
|
||||
linux.debug.x86_32 = "res://bin/libgdexample.linux.template_debug.x86_32.so"
|
||||
linux.release.x86_32 = "res://bin/libgdexample.linux.template_release.x86_32.so"
|
||||
linux.debug.x86_64 = "res://bin/libgdexample.linux.template_debug.x86_64.so"
|
||||
linux.release.x86_64 = "res://bin/libgdexample.linux.template_release.x86_64.so"
|
||||
linux.debug.arm32 = "res://bin/libgdexample.linux.template_debug.arm32.so"
|
||||
linux.release.arm32 = "res://bin/libgdexample.linux.template_release.arm32.so"
|
||||
linux.debug.arm64 = "res://bin/libgdexample.linux.template_debug.arm64.so"
|
||||
linux.release.arm64 = "res://bin/libgdexample.linux.template_release.arm64.so"
|
||||
linux.debug.rv64 = "res://bin/libgdexample.linux.template_debug.rv64.so"
|
||||
linux.release.rv64 = "res://bin/libgdexample.linux.template_release.rv64.so"
|
||||
android.debug.x86_64 = "res://bin/libgdexample.android.template_debug.x86_64.so"
|
||||
android.release.x86_64 = "res://bin/libgdexample.android.template_release.x86_64.so"
|
||||
android.debug.arm64 = "res://bin/libgdexample.android.template_debug.arm64.so"
|
||||
android.release.arm64 = "res://bin/libgdexample.android.template_release.arm64.so"
|
||||
ios.debug = "res://bin/libgdexample.ios.template_debug.xcframework"
|
||||
ios.release = "res://bin/libgdexample.ios.template_release.xcframework"
|
||||
web.debug.threads.wasm32 = "res://bin/libgdexample.web.template_debug.wasm32.wasm"
|
||||
web.release.threads.wasm32 = "res://bin/libgdexample.web.template_release.wasm32.wasm"
|
||||
web.debug.wasm32 = "res://bin/libgdexample.web.template_debug.wasm32.nothreads.wasm"
|
||||
web.release.wasm32 = "res://bin/libgdexample.web.template_release.wasm32.nothreads.wasm"
|
||||
|
||||
[dependencies]
|
||||
ios.debug = {
|
||||
"res://bin/libgodot-cpp.ios.template_debug.xcframework": ""
|
||||
}
|
||||
ios.release = {
|
||||
"res://bin/libgodot-cpp.ios.template_release.xcframework": ""
|
||||
}
|
||||
BIN
cobor_vm_extension/godot-cpp/test/project/icon.png
Normal file
BIN
cobor_vm_extension/godot-cpp/test/project/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.2 KiB |
34
cobor_vm_extension/godot-cpp/test/project/icon.png.import
Normal file
34
cobor_vm_extension/godot-cpp/test/project/icon.png.import
Normal file
@@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cswr8vy4lt7dt"
|
||||
path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://icon.png"
|
||||
dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
298
cobor_vm_extension/godot-cpp/test/project/main.gd
Normal file
298
cobor_vm_extension/godot-cpp/test/project/main.gd
Normal file
@@ -0,0 +1,298 @@
|
||||
extends "res://test_base.gd"
|
||||
|
||||
var custom_signal_emitted = null
|
||||
|
||||
class TestClass:
|
||||
func test(p_msg: String) -> String:
|
||||
return p_msg + " world"
|
||||
|
||||
func _ready():
|
||||
var example: Example = $Example
|
||||
|
||||
# Timing of set instance binding.
|
||||
assert_equal(example.is_object_binding_set_by_parent_constructor(), true)
|
||||
|
||||
# Signal.
|
||||
example.emit_custom_signal("Button", 42)
|
||||
assert_equal(custom_signal_emitted, ["Button", 42])
|
||||
|
||||
# To string.
|
||||
assert_equal(example.to_string(),'[ GDExtension::Example <--> Instance ID:%s ]' % example.get_instance_id())
|
||||
# It appears there's a bug with instance ids :-(
|
||||
#assert_equal($Example/ExampleMin.to_string(), 'ExampleMin:[Wrapped:%s]' % $Example/ExampleMin.get_instance_id())
|
||||
|
||||
# Call static methods.
|
||||
assert_equal(Example.test_static(9, 100), 109);
|
||||
# It's void and static, so all we know is that it didn't crash.
|
||||
Example.test_static2()
|
||||
|
||||
# Property list.
|
||||
example.property_from_list = Vector3(100, 200, 300)
|
||||
assert_equal(example.property_from_list, Vector3(100, 200, 300))
|
||||
var prop_list = example.get_property_list()
|
||||
for prop_info in prop_list:
|
||||
if prop_info['name'] == 'mouse_filter':
|
||||
assert_equal(prop_info['usage'], PROPERTY_USAGE_NO_EDITOR)
|
||||
|
||||
# Call simple methods.
|
||||
example.simple_func()
|
||||
assert_equal(custom_signal_emitted, ['simple_func', 3])
|
||||
example.simple_const_func()
|
||||
assert_equal(custom_signal_emitted, ['simple_const_func', 4])
|
||||
|
||||
# Pass custom reference.
|
||||
assert_equal(example.custom_ref_func(null), -1)
|
||||
var ref1 = ExampleRef.new()
|
||||
ref1.id = 27
|
||||
assert_equal(example.custom_ref_func(ref1), 27)
|
||||
ref1.id += 1;
|
||||
assert_equal(example.custom_const_ref_func(ref1), 28)
|
||||
|
||||
# Pass core reference.
|
||||
assert_equal(example.image_ref_func(null), "invalid")
|
||||
assert_equal(example.image_const_ref_func(null), "invalid")
|
||||
var image = Image.new()
|
||||
assert_equal(example.image_ref_func(image), "valid")
|
||||
assert_equal(example.image_const_ref_func(image), "valid")
|
||||
|
||||
# Return values.
|
||||
assert_equal(example.return_something("some string"), "some string42")
|
||||
assert_equal(example.return_something_const(), get_viewport())
|
||||
var null_ref = example.return_empty_ref()
|
||||
assert_equal(null_ref, null)
|
||||
var ret_ref = example.return_extended_ref()
|
||||
assert_not_equal(ret_ref.get_instance_id(), 0)
|
||||
assert_equal(ret_ref.get_id(), 0)
|
||||
assert_equal(example.get_v4(), Vector4(1.2, 3.4, 5.6, 7.8))
|
||||
assert_equal(example.test_node_argument(example), example)
|
||||
|
||||
# VarArg method calls.
|
||||
var var_ref = ExampleRef.new()
|
||||
assert_not_equal(example.extended_ref_checks(var_ref).get_instance_id(), var_ref.get_instance_id())
|
||||
assert_equal(example.varargs_func("some", "arguments", "to", "test"), 4)
|
||||
assert_equal(example.varargs_func_nv("some", "arguments", "to", "test"), 46)
|
||||
example.varargs_func_void("some", "arguments", "to", "test")
|
||||
assert_equal(custom_signal_emitted, ["varargs_func_void", 5])
|
||||
|
||||
# Method calls with default values.
|
||||
assert_equal(example.def_args(), 300)
|
||||
assert_equal(example.def_args(50), 250)
|
||||
assert_equal(example.def_args(50, 100), 150)
|
||||
|
||||
# Array and Dictionary
|
||||
assert_equal(example.test_array(), [1, 2])
|
||||
assert_equal(example.test_tarray(), [Vector2(1, 2), Vector2(2, 3)])
|
||||
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])
|
||||
|
||||
# String += operator
|
||||
assert_equal(example.test_string_ops(), "ABCĎE")
|
||||
|
||||
# UtilityFunctions::str()
|
||||
assert_equal(example.test_str_utility(), "Hello, World! The answer is 42")
|
||||
|
||||
# Test converting string to char* and doing comparison.
|
||||
assert_equal(example.test_string_is_forty_two("blah"), false)
|
||||
assert_equal(example.test_string_is_forty_two("forty two"), true)
|
||||
|
||||
# String::resize().
|
||||
assert_equal(example.test_string_resize("What"), "What!?")
|
||||
|
||||
# mp_callable() with void method.
|
||||
var mp_callable: Callable = example.test_callable_mp()
|
||||
assert_equal(mp_callable.is_valid(), true)
|
||||
assert_equal(mp_callable.get_argument_count(), 3)
|
||||
mp_callable.call(example, "void", 36)
|
||||
assert_equal(custom_signal_emitted, ["unbound_method1: Example - void", 36])
|
||||
|
||||
# Check that it works with is_connected().
|
||||
assert_equal(example.renamed.is_connected(mp_callable), false)
|
||||
example.renamed.connect(mp_callable)
|
||||
assert_equal(example.renamed.is_connected(mp_callable), true)
|
||||
# Make sure a new object is still treated as equivalent.
|
||||
assert_equal(example.renamed.is_connected(example.test_callable_mp()), true)
|
||||
assert_equal(mp_callable.hash(), example.test_callable_mp().hash())
|
||||
example.renamed.disconnect(mp_callable)
|
||||
assert_equal(example.renamed.is_connected(mp_callable), false)
|
||||
|
||||
# mp_callable() with return value.
|
||||
var mp_callable_ret: Callable = example.test_callable_mp_ret()
|
||||
assert_equal(mp_callable_ret.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])
|
||||
|
||||
# Check that it works with is_connected().
|
||||
assert_equal(example.renamed.is_connected(mp_callable_static), false)
|
||||
example.renamed.connect(mp_callable_static)
|
||||
assert_equal(example.renamed.is_connected(mp_callable_static), true)
|
||||
# Make sure a new object is still treated as equivalent.
|
||||
assert_equal(example.renamed.is_connected(example.test_callable_mp_static()), true)
|
||||
assert_equal(mp_callable_static.hash(), example.test_callable_mp_static().hash())
|
||||
example.renamed.disconnect(mp_callable_static)
|
||||
assert_equal(example.renamed.is_connected(mp_callable_static), false)
|
||||
|
||||
# mp_callable_static() with return value.
|
||||
var mp_callable_static_ret: Callable = example.test_callable_mp_static_ret()
|
||||
assert_equal(mp_callable_static_ret.get_argument_count(), 3)
|
||||
assert_equal(mp_callable_static_ret.call(example, "static-ret", 84), "unbound_static_method2: Example - static-ret - 84")
|
||||
|
||||
# CallableCustom.
|
||||
var custom_callable: Callable = example.test_custom_callable();
|
||||
assert_equal(custom_callable.is_custom(), true);
|
||||
assert_equal(custom_callable.is_valid(), true);
|
||||
assert_equal(custom_callable.call(), "Hi")
|
||||
assert_equal(custom_callable.hash(), 27);
|
||||
assert_equal(custom_callable.get_object(), null);
|
||||
assert_equal(custom_callable.get_method(), "");
|
||||
assert_equal(custom_callable.get_argument_count(), 2)
|
||||
assert_equal(str(custom_callable), "<MyCallableCustom>");
|
||||
|
||||
# PackedArray iterators
|
||||
assert_equal(example.test_vector_ops(), 105)
|
||||
assert_equal(example.test_vector_init_list(), 105)
|
||||
|
||||
# Properties.
|
||||
assert_equal(example.group_subgroup_custom_position, Vector2(0, 0))
|
||||
example.group_subgroup_custom_position = Vector2(50, 50)
|
||||
assert_equal(example.group_subgroup_custom_position, Vector2(50, 50))
|
||||
|
||||
# Test Object::cast_to<>() and that correct wrappers are being used.
|
||||
var control = Control.new()
|
||||
var sprite = Sprite2D.new()
|
||||
var example_ref = ExampleRef.new()
|
||||
|
||||
assert_equal(example.test_object_cast_to_node(control), true)
|
||||
assert_equal(example.test_object_cast_to_control(control), true)
|
||||
assert_equal(example.test_object_cast_to_example(control), false)
|
||||
|
||||
assert_equal(example.test_object_cast_to_node(example), true)
|
||||
assert_equal(example.test_object_cast_to_control(example), true)
|
||||
assert_equal(example.test_object_cast_to_example(example), true)
|
||||
|
||||
assert_equal(example.test_object_cast_to_node(sprite), true)
|
||||
assert_equal(example.test_object_cast_to_control(sprite), false)
|
||||
assert_equal(example.test_object_cast_to_example(sprite), false)
|
||||
|
||||
assert_equal(example.test_object_cast_to_node(example_ref), false)
|
||||
assert_equal(example.test_object_cast_to_control(example_ref), false)
|
||||
assert_equal(example.test_object_cast_to_example(example_ref), false)
|
||||
|
||||
control.queue_free()
|
||||
sprite.queue_free()
|
||||
|
||||
# Test that passing null for objects works as expected too.
|
||||
var example_null : Example = null
|
||||
assert_equal(example.test_object_cast_to_node(example_null), false)
|
||||
|
||||
# Test conversions to and from Variant.
|
||||
assert_equal(example.test_variant_vector2i_conversion(Vector2i(1, 1)), Vector2i(1, 1))
|
||||
assert_equal(example.test_variant_vector2i_conversion(Vector2(1.0, 1.0)), Vector2i(1, 1))
|
||||
assert_equal(example.test_variant_int_conversion(10), 10)
|
||||
assert_equal(example.test_variant_int_conversion(10.0), 10)
|
||||
assert_equal(example.test_variant_float_conversion(10.0), 10.0)
|
||||
assert_equal(example.test_variant_float_conversion(10), 10.0)
|
||||
|
||||
# Test 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)
|
||||
assert_equal(new_node.get_parent(), example)
|
||||
|
||||
var new_tileset = TileSet.new()
|
||||
var new_tilemap = TileMap.new()
|
||||
example.test_set_tileset(new_tilemap, new_tileset)
|
||||
assert_equal(new_tilemap.tile_set, new_tileset)
|
||||
new_tilemap.queue_free()
|
||||
|
||||
# Test variant call.
|
||||
var test_obj = TestClass.new()
|
||||
assert_equal(example.test_variant_call(test_obj), "hello world")
|
||||
|
||||
# Constants.
|
||||
assert_equal(Example.FIRST, 0)
|
||||
assert_equal(Example.ANSWER_TO_EVERYTHING, 42)
|
||||
assert_equal(Example.CONSTANT_WITHOUT_ENUM, 314)
|
||||
|
||||
# BitFields.
|
||||
assert_equal(Example.FLAG_ONE, 1)
|
||||
assert_equal(Example.FLAG_TWO, 2)
|
||||
assert_equal(example.test_bitfield(0), 0)
|
||||
assert_equal(example.test_bitfield(Example.FLAG_ONE | Example.FLAG_TWO), 3)
|
||||
|
||||
# Test variant iterator.
|
||||
assert_equal(example.test_variant_iterator([10, 20, 30]), [15, 25, 35])
|
||||
assert_equal(example.test_variant_iterator(null), "iter_init: not valid")
|
||||
|
||||
# RPCs.
|
||||
assert_equal(example.return_last_rpc_arg(), 0)
|
||||
example.test_rpc(42)
|
||||
assert_equal(example.return_last_rpc_arg(), 42)
|
||||
example.test_send_rpc(100)
|
||||
assert_equal(example.return_last_rpc_arg(), 100)
|
||||
|
||||
# Virtual method.
|
||||
var event = InputEventKey.new()
|
||||
event.key_label = KEY_H
|
||||
event.unicode = 72
|
||||
get_viewport().push_input(event)
|
||||
assert_equal(custom_signal_emitted, ["_input: H", 72])
|
||||
|
||||
# Check NOTIFICATION_POST_INITIALIZED, both when created from GDScript and godot-cpp.
|
||||
var new_example_ref = ExampleRef.new()
|
||||
assert_equal(new_example_ref.was_post_initialized(), true)
|
||||
assert_equal(example.test_post_initialize(), true)
|
||||
|
||||
# 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)
|
||||
assert_equal(example_child.get_value2(), 33)
|
||||
example_child.notification(NOTIFICATION_ENTER_TREE, true)
|
||||
assert_equal(example_child.get_value1(), 11)
|
||||
assert_equal(example_child.get_value2(), 22)
|
||||
|
||||
# Test that the extension's library path is absolute and valid.
|
||||
var library_path = Example.test_library_path()
|
||||
assert_equal(library_path.begins_with("res://"), false)
|
||||
assert_equal(library_path, ProjectSettings.globalize_path(library_path))
|
||||
assert_equal(FileAccess.file_exists(library_path), true)
|
||||
|
||||
# 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):
|
||||
custom_signal_emitted = [signal_name, value]
|
||||
29
cobor_vm_extension/godot-cpp/test/project/main.tscn
Normal file
29
cobor_vm_extension/godot-cpp/test/project/main.tscn
Normal file
@@ -0,0 +1,29 @@
|
||||
[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
|
||||
|
||||
[node name="Label" type="Label" parent="Example"]
|
||||
layout_mode = 0
|
||||
offset_left = 194.0
|
||||
offset_top = -2.0
|
||||
offset_right = 234.0
|
||||
offset_bottom = 21.0
|
||||
|
||||
[node name="Button" type="Button" parent="."]
|
||||
offset_right = 79.0
|
||||
offset_bottom = 29.0
|
||||
text = "Click me!"
|
||||
|
||||
[node name="ExampleChild" type="ExampleChild" parent="."]
|
||||
|
||||
[connection signal="custom_signal" from="Example" to="." method="_on_Example_custom_signal"]
|
||||
25
cobor_vm_extension/godot-cpp/test/project/project.godot
Normal file
25
cobor_vm_extension/godot-cpp/test/project/project.godot
Normal file
@@ -0,0 +1,25 @@
|
||||
; Engine configuration file.
|
||||
; It's best edited using the editor UI and not directly,
|
||||
; since the parameters that go here are not all obvious.
|
||||
;
|
||||
; Format:
|
||||
; [section] ; section goes between []
|
||||
; param=value ; assign values to parameters
|
||||
|
||||
config_version=5
|
||||
|
||||
[application]
|
||||
|
||||
config/name="GDExtension Test Project"
|
||||
run/main_scene="res://main.tscn"
|
||||
config/features=PackedStringArray("4.3")
|
||||
config/icon="res://icon.png"
|
||||
|
||||
[native_extensions]
|
||||
|
||||
paths=["res://example.gdextension"]
|
||||
|
||||
[rendering]
|
||||
|
||||
textures/vram_compression/import_etc2_astc=true
|
||||
environment/defaults/default_environment="res://default_env.tres"
|
||||
59
cobor_vm_extension/godot-cpp/test/project/test_base.gd
Normal file
59
cobor_vm_extension/godot-cpp/test/project/test_base.gd
Normal file
@@ -0,0 +1,59 @@
|
||||
extends Node
|
||||
|
||||
var test_passes := 0
|
||||
var test_failures := 0
|
||||
|
||||
func __get_stack_frame():
|
||||
var me = get_script()
|
||||
for s in get_stack():
|
||||
if s.source == me.resource_path:
|
||||
return s
|
||||
return null
|
||||
|
||||
func __assert_pass():
|
||||
test_passes += 1
|
||||
|
||||
func __assert_fail():
|
||||
test_failures += 1
|
||||
var s = __get_stack_frame()
|
||||
if s != null:
|
||||
print_rich ("[color=red] == FAILURE: In function %s() from '%s' on line %s[/color]" % [s.function, s.source, s.line])
|
||||
else:
|
||||
print_rich ("[color=red] == FAILURE (run with --debug to get more information!) ==[/color]")
|
||||
|
||||
func assert_equal(actual, expected):
|
||||
if actual == expected:
|
||||
__assert_pass()
|
||||
else:
|
||||
__assert_fail()
|
||||
print (" |-> Expected '%s' but got '%s'" % [expected, actual])
|
||||
|
||||
func assert_true(v):
|
||||
assert_equal(v, true)
|
||||
|
||||
func assert_false(v):
|
||||
assert_equal(v, false)
|
||||
|
||||
func assert_not_equal(actual, expected):
|
||||
if actual != expected:
|
||||
__assert_pass()
|
||||
else:
|
||||
__assert_fail()
|
||||
print (" |-> Expected '%s' NOT to equal '%s'" % [expected, actual])
|
||||
|
||||
func exit_with_status() -> void:
|
||||
var success: bool = (test_failures == 0)
|
||||
print ("")
|
||||
print_rich ("[color=%s] ==== TESTS FINISHED ==== [/color]" % ("green" if success else "red"))
|
||||
print ("")
|
||||
print_rich (" PASSES: [color=green]%s[/color]" % test_passes)
|
||||
print_rich (" FAILURES: [color=red]%s[/color]" % test_failures)
|
||||
print ("")
|
||||
|
||||
if success:
|
||||
print_rich("[color=green] ******** PASSED ******** [/color]")
|
||||
else:
|
||||
print_rich("[color=red] ******** FAILED ********[/color]")
|
||||
print("")
|
||||
|
||||
get_tree().quit(0 if success else 1)
|
||||
24
cobor_vm_extension/godot-cpp/test/run-tests.sh
Executable file
24
cobor_vm_extension/godot-cpp/test/run-tests.sh
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
|
||||
GODOT=${GODOT:-godot}
|
||||
|
||||
END_STRING="==== TESTS FINISHED ===="
|
||||
FAILURE_STRING="******** FAILED ********"
|
||||
|
||||
OUTPUT=$($GODOT --path project --debug --headless --quit)
|
||||
ERRCODE=$?
|
||||
|
||||
echo "$OUTPUT"
|
||||
echo
|
||||
|
||||
if ! echo "$OUTPUT" | grep -e "$END_STRING" >/dev/null; then
|
||||
echo "ERROR: Tests failed to complete"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if echo "$OUTPUT" | grep -e "$FAILURE_STRING" >/dev/null; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Success!
|
||||
exit 0
|
||||
781
cobor_vm_extension/godot-cpp/test/src/example.cpp
Normal file
781
cobor_vm_extension/godot-cpp/test/src/example.cpp
Normal file
@@ -0,0 +1,781 @@
|
||||
/* godot-cpp integration testing project.
|
||||
*
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*/
|
||||
|
||||
#include "example.h"
|
||||
|
||||
#include <godot_cpp/core/class_db.hpp>
|
||||
|
||||
#include <godot_cpp/classes/global_constants.hpp>
|
||||
#include <godot_cpp/classes/label.hpp>
|
||||
#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;
|
||||
|
||||
class MyCallableCustom : public CallableCustom {
|
||||
public:
|
||||
virtual uint32_t hash() const {
|
||||
return 27;
|
||||
}
|
||||
|
||||
virtual String get_as_text() const {
|
||||
return "<MyCallableCustom>";
|
||||
}
|
||||
|
||||
static bool compare_equal_func(const CallableCustom *p_a, const CallableCustom *p_b) {
|
||||
return p_a == p_b;
|
||||
}
|
||||
|
||||
virtual CompareEqualFunc get_compare_equal_func() const {
|
||||
return &MyCallableCustom::compare_equal_func;
|
||||
}
|
||||
|
||||
static bool compare_less_func(const CallableCustom *p_a, const CallableCustom *p_b) {
|
||||
return (void *)p_a < (void *)p_b;
|
||||
}
|
||||
|
||||
virtual CompareLessFunc get_compare_less_func() const {
|
||||
return &MyCallableCustom::compare_less_func;
|
||||
}
|
||||
|
||||
bool is_valid() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual ObjectID get_object() const {
|
||||
return ObjectID();
|
||||
}
|
||||
|
||||
virtual 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;
|
||||
}
|
||||
};
|
||||
|
||||
void ExampleRef::set_id(int p_id) {
|
||||
id = p_id;
|
||||
}
|
||||
|
||||
int ExampleRef::get_id() const {
|
||||
return id;
|
||||
}
|
||||
|
||||
void ExampleRef::_notification(int p_what) {
|
||||
if (p_what == NOTIFICATION_POSTINITIALIZE) {
|
||||
post_initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ExampleRef::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_id", "id"), &ExampleRef::set_id);
|
||||
ClassDB::bind_method(D_METHOD("get_id"), &ExampleRef::get_id);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("was_post_initialized"), &ExampleRef::was_post_initialized);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "id"), "set_id", "get_id");
|
||||
}
|
||||
|
||||
ExampleRef::ExampleRef() {
|
||||
id = 0;
|
||||
}
|
||||
|
||||
ExampleRef::~ExampleRef() {
|
||||
}
|
||||
|
||||
int Example::test_static(int p_a, int p_b) {
|
||||
return p_a + p_b;
|
||||
}
|
||||
|
||||
void Example::test_static2() {
|
||||
//UtilityFunctions::print(" void static");
|
||||
}
|
||||
|
||||
int Example::def_args(int p_a, int p_b) {
|
||||
return p_a + p_b;
|
||||
}
|
||||
|
||||
void Example::_notification(int p_what) {
|
||||
if (p_what == NOTIFICATION_READY) {
|
||||
Dictionary opts;
|
||||
opts["rpc_mode"] = MultiplayerAPI::RPC_MODE_AUTHORITY;
|
||||
opts["transfer_mode"] = MultiplayerPeer::TRANSFER_MODE_RELIABLE;
|
||||
opts["call_local"] = true;
|
||||
opts["channel"] = 0;
|
||||
rpc_config("test_rpc", opts);
|
||||
}
|
||||
//UtilityFunctions::print("Notification: ", String::num(p_what));
|
||||
}
|
||||
|
||||
bool Example::_set(const StringName &p_name, const Variant &p_value) {
|
||||
String name = p_name;
|
||||
if (name.begins_with("dproperty")) {
|
||||
int64_t index = name.get_slicec('_', 1).to_int();
|
||||
dprop[index] = p_value;
|
||||
return true;
|
||||
}
|
||||
if (name == "property_from_list") {
|
||||
property_from_list = p_value;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Example::_get(const StringName &p_name, Variant &r_ret) const {
|
||||
String name = p_name;
|
||||
if (name.begins_with("dproperty")) {
|
||||
int64_t index = name.get_slicec('_', 1).to_int();
|
||||
r_ret = dprop[index];
|
||||
return true;
|
||||
}
|
||||
if (name == "property_from_list") {
|
||||
r_ret = property_from_list;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
String Example::_to_string() const {
|
||||
return "[ GDExtension::Example <--> Instance ID:" + uitos(get_instance_id()) + " ]";
|
||||
}
|
||||
|
||||
void Example::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||
p_list->push_back(PropertyInfo(Variant::VECTOR3, "property_from_list"));
|
||||
for (int i = 0; i < 3; i++) {
|
||||
p_list->push_back(PropertyInfo(Variant::VECTOR2, "dproperty_" + itos(i)));
|
||||
}
|
||||
}
|
||||
|
||||
bool Example::_property_can_revert(const StringName &p_name) const {
|
||||
if (p_name == StringName("property_from_list") && property_from_list != Vector3(42, 42, 42)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
bool Example::_property_get_revert(const StringName &p_name, Variant &r_property) const {
|
||||
if (p_name == StringName("property_from_list")) {
|
||||
r_property = Vector3(42, 42, 42);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
void Example::_validate_property(PropertyInfo &p_property) const {
|
||||
String name = p_property.name;
|
||||
// Test hiding the "mouse_filter" property from the editor.
|
||||
if (name == "mouse_filter") {
|
||||
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
|
||||
}
|
||||
}
|
||||
|
||||
void Example::_bind_methods() {
|
||||
// Methods.
|
||||
ClassDB::bind_method(D_METHOD("simple_func"), &Example::simple_func);
|
||||
ClassDB::bind_method(D_METHOD("simple_const_func"), &Example::simple_const_func);
|
||||
ClassDB::bind_method(D_METHOD("custom_ref_func", "ref"), &Example::custom_ref_func);
|
||||
ClassDB::bind_method(D_METHOD("custom_const_ref_func", "ref"), &Example::custom_const_ref_func);
|
||||
ClassDB::bind_method(D_METHOD("image_ref_func", "image"), &Example::image_ref_func);
|
||||
ClassDB::bind_method(D_METHOD("image_const_ref_func", "image"), &Example::image_const_ref_func);
|
||||
ClassDB::bind_method(D_METHOD("return_something"), &Example::return_something);
|
||||
ClassDB::bind_method(D_METHOD("return_something_const"), &Example::return_something_const);
|
||||
ClassDB::bind_method(D_METHOD("return_empty_ref"), &Example::return_empty_ref);
|
||||
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);
|
||||
ClassDB::bind_method(D_METHOD("test_string_is_forty_two"), &Example::test_string_is_forty_two);
|
||||
ClassDB::bind_method(D_METHOD("test_string_resize"), &Example::test_string_resize);
|
||||
ClassDB::bind_method(D_METHOD("test_typed_array_of_packed"), &Example::test_typed_array_of_packed);
|
||||
ClassDB::bind_method(D_METHOD("test_vector_ops"), &Example::test_vector_ops);
|
||||
ClassDB::bind_method(D_METHOD("test_vector_init_list"), &Example::test_vector_init_list);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("test_object_cast_to_node", "object"), &Example::test_object_cast_to_node);
|
||||
ClassDB::bind_method(D_METHOD("test_object_cast_to_control", "object"), &Example::test_object_cast_to_control);
|
||||
ClassDB::bind_method(D_METHOD("test_object_cast_to_example", "object"), &Example::test_object_cast_to_example);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("test_variant_vector2i_conversion", "variant"), &Example::test_variant_vector2i_conversion);
|
||||
ClassDB::bind_method(D_METHOD("test_variant_int_conversion", "variant"), &Example::test_variant_int_conversion);
|
||||
ClassDB::bind_method(D_METHOD("test_variant_float_conversion", "variant"), &Example::test_variant_float_conversion);
|
||||
ClassDB::bind_method(D_METHOD("test_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);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("test_variant_call", "variant"), &Example::test_variant_call);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("test_callable_mp"), &Example::test_callable_mp);
|
||||
ClassDB::bind_method(D_METHOD("test_callable_mp_ret"), &Example::test_callable_mp_ret);
|
||||
ClassDB::bind_method(D_METHOD("test_callable_mp_retc"), &Example::test_callable_mp_retc);
|
||||
ClassDB::bind_method(D_METHOD("test_callable_mp_static"), &Example::test_callable_mp_static);
|
||||
ClassDB::bind_method(D_METHOD("test_callable_mp_static_ret"), &Example::test_callable_mp_static_ret);
|
||||
ClassDB::bind_method(D_METHOD("test_custom_callable"), &Example::test_custom_callable);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("test_bitfield", "flags"), &Example::test_bitfield);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("test_variant_iterator", "input"), &Example::test_variant_iterator);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("test_rpc", "value"), &Example::test_rpc);
|
||||
ClassDB::bind_method(D_METHOD("test_send_rpc", "value"), &Example::test_send_rpc);
|
||||
ClassDB::bind_method(D_METHOD("return_last_rpc_arg"), &Example::return_last_rpc_arg);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("def_args", "a", "b"), &Example::def_args, DEFVAL(100), DEFVAL(200));
|
||||
ClassDB::bind_method(D_METHOD("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);
|
||||
ClassDB::bind_static_method("Example", D_METHOD("test_static2"), &Example::test_static2);
|
||||
|
||||
ClassDB::bind_static_method("Example", D_METHOD("test_library_path"), &Example::test_library_path);
|
||||
|
||||
{
|
||||
MethodInfo mi;
|
||||
mi.arguments.push_back(PropertyInfo(Variant::STRING, "some_argument"));
|
||||
mi.name = "varargs_func";
|
||||
ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "varargs_func", &Example::varargs_func, mi);
|
||||
}
|
||||
|
||||
{
|
||||
MethodInfo mi;
|
||||
mi.arguments.push_back(PropertyInfo(Variant::STRING, "some_argument"));
|
||||
mi.name = "varargs_func_nv";
|
||||
ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "varargs_func_nv", &Example::varargs_func_nv, mi);
|
||||
}
|
||||
|
||||
{
|
||||
MethodInfo mi;
|
||||
mi.arguments.push_back(PropertyInfo(Variant::STRING, "some_argument"));
|
||||
mi.name = "varargs_func_void";
|
||||
ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "varargs_func_void", &Example::varargs_func_void, mi);
|
||||
}
|
||||
|
||||
// Properties.
|
||||
ADD_GROUP("Test group", "group_");
|
||||
ADD_SUBGROUP("Test subgroup", "group_subgroup_");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_custom_position"), &Example::get_custom_position);
|
||||
ClassDB::bind_method(D_METHOD("get_v4"), &Example::get_v4);
|
||||
ClassDB::bind_method(D_METHOD("set_custom_position", "position"), &Example::set_custom_position);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "group_subgroup_custom_position"), "set_custom_position", "get_custom_position");
|
||||
|
||||
// Signals.
|
||||
ADD_SIGNAL(MethodInfo("custom_signal", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::INT, "value")));
|
||||
ClassDB::bind_method(D_METHOD("emit_custom_signal", "name", "value"), &Example::emit_custom_signal);
|
||||
|
||||
// Constants.
|
||||
BIND_ENUM_CONSTANT(FIRST);
|
||||
BIND_ENUM_CONSTANT(ANSWER_TO_EVERYTHING);
|
||||
|
||||
BIND_BITFIELD_FLAG(FLAG_ONE);
|
||||
BIND_BITFIELD_FLAG(FLAG_TWO);
|
||||
|
||||
BIND_CONSTANT(CONSTANT_WITHOUT_ENUM);
|
||||
BIND_ENUM_CONSTANT(OUTSIDE_OF_CLASS);
|
||||
}
|
||||
|
||||
bool Example::has_object_instance_binding() const {
|
||||
return internal::gdextension_interface_object_get_instance_binding(_owner, internal::token, nullptr);
|
||||
}
|
||||
|
||||
Example::Example() :
|
||||
object_instance_binding_set_by_parent_constructor(has_object_instance_binding()) {
|
||||
// Test conversion, to ensure users can use all parent class functions at this time.
|
||||
// It would crash if instance binding still not be initialized.
|
||||
Variant v = Variant(this);
|
||||
Object *o = (Object *)v;
|
||||
|
||||
//UtilityFunctions::print("Constructor.");
|
||||
}
|
||||
|
||||
Example::~Example() {
|
||||
//UtilityFunctions::print("Destructor.");
|
||||
}
|
||||
|
||||
// Methods.
|
||||
void Example::simple_func() {
|
||||
emit_custom_signal("simple_func", 3);
|
||||
}
|
||||
|
||||
void Example::simple_const_func() const {
|
||||
((Example *)this)->emit_custom_signal("simple_const_func", 4);
|
||||
}
|
||||
|
||||
int Example::custom_ref_func(Ref<ExampleRef> p_ref) {
|
||||
return p_ref.is_valid() ? p_ref->get_id() : -1;
|
||||
}
|
||||
|
||||
int Example::custom_const_ref_func(const Ref<ExampleRef> &p_ref) {
|
||||
return p_ref.is_valid() ? p_ref->get_id() : -1;
|
||||
}
|
||||
|
||||
String Example::image_ref_func(Ref<Image> p_image) {
|
||||
return p_image.is_valid() ? String("valid") : String("invalid");
|
||||
}
|
||||
|
||||
String Example::image_const_ref_func(const Ref<Image> &p_image) {
|
||||
return p_image.is_valid() ? String("valid") : String("invalid");
|
||||
}
|
||||
|
||||
String Example::return_something(const String &base) {
|
||||
return base + String("42");
|
||||
}
|
||||
|
||||
Viewport *Example::return_something_const() const {
|
||||
if (is_inside_tree()) {
|
||||
Viewport *result = get_viewport();
|
||||
return result;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Ref<ExampleRef> Example::return_empty_ref() const {
|
||||
Ref<ExampleRef> ref;
|
||||
return ref;
|
||||
}
|
||||
|
||||
ExampleRef *Example::return_extended_ref() const {
|
||||
// You can instance and return a refcounted object like this, but keep in mind that refcounting starts with the returned object
|
||||
// and it will be destroyed when all references are destroyed. If you store this pointer you run the risk of having a pointer
|
||||
// to a destroyed object.
|
||||
return memnew(ExampleRef());
|
||||
}
|
||||
|
||||
Ref<ExampleRef> Example::extended_ref_checks(Ref<ExampleRef> p_ref) const {
|
||||
// This is therefore the preferred way of instancing and returning a refcounted object:
|
||||
Ref<ExampleRef> ref;
|
||||
ref.instantiate();
|
||||
return ref;
|
||||
}
|
||||
|
||||
Variant Example::varargs_func(const Variant **args, GDExtensionInt arg_count, GDExtensionCallError &error) {
|
||||
return arg_count;
|
||||
}
|
||||
|
||||
int Example::varargs_func_nv(const Variant **args, GDExtensionInt arg_count, GDExtensionCallError &error) {
|
||||
return 42 + arg_count;
|
||||
}
|
||||
|
||||
void Example::varargs_func_void(const Variant **args, GDExtensionInt arg_count, GDExtensionCallError &error) {
|
||||
emit_custom_signal("varargs_func_void", arg_count + 1);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
arr.resize(2);
|
||||
arr[0] = Variant(1);
|
||||
arr[1] = Variant(2);
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
String Example::test_string_ops() const {
|
||||
String s = String("A");
|
||||
s += "B";
|
||||
s += "C";
|
||||
s += char32_t(0x010E);
|
||||
s = s + "E";
|
||||
return s;
|
||||
}
|
||||
|
||||
String Example::test_str_utility() const {
|
||||
return UtilityFunctions::str("Hello, ", "World", "! The answer is ", 42);
|
||||
}
|
||||
|
||||
bool Example::test_string_is_forty_two(const String &p_string) const {
|
||||
return strcmp(p_string.utf8().ptr(), "forty two") == 0;
|
||||
}
|
||||
|
||||
String Example::test_string_resize(String p_string) const {
|
||||
int orig_len = p_string.length();
|
||||
p_string.resize(orig_len + 3);
|
||||
char32_t *data = p_string.ptrw();
|
||||
data[orig_len + 0] = '!';
|
||||
data[orig_len + 1] = '?';
|
||||
data[orig_len + 2] = '\0';
|
||||
return p_string;
|
||||
}
|
||||
|
||||
TypedArray<PackedInt32Array> Example::test_typed_array_of_packed() const {
|
||||
TypedArray<PackedInt32Array> arr;
|
||||
PackedInt32Array packed_arr1;
|
||||
packed_arr1.push_back(1);
|
||||
packed_arr1.push_back(2);
|
||||
arr.push_back(packed_arr1);
|
||||
PackedInt32Array packed_arr2;
|
||||
packed_arr2.push_back(3);
|
||||
packed_arr2.push_back(4);
|
||||
arr.push_back(packed_arr2);
|
||||
return arr;
|
||||
}
|
||||
|
||||
int Example::test_vector_ops() const {
|
||||
PackedInt32Array arr;
|
||||
arr.push_back(10);
|
||||
arr.push_back(20);
|
||||
arr.push_back(30);
|
||||
arr.push_back(45);
|
||||
int ret = 0;
|
||||
for (const int32_t &E : arr) {
|
||||
ret += E;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Example::test_vector_init_list() const {
|
||||
PackedInt32Array arr = { 10, 20, 30, 45 };
|
||||
int ret = 0;
|
||||
for (const int32_t &E : arr) {
|
||||
ret += E;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
Callable Example::test_callable_mp() {
|
||||
return callable_mp(this, &Example::unbound_method1);
|
||||
}
|
||||
|
||||
Callable Example::test_callable_mp_ret() {
|
||||
return callable_mp(this, &Example::unbound_method2);
|
||||
}
|
||||
|
||||
Callable Example::test_callable_mp_retc() const {
|
||||
return callable_mp(this, &Example::unbound_method3);
|
||||
}
|
||||
|
||||
Callable Example::test_callable_mp_static() const {
|
||||
return callable_mp_static(&Example::unbound_static_method1);
|
||||
}
|
||||
|
||||
Callable Example::test_callable_mp_static_ret() const {
|
||||
return callable_mp_static(&Example::unbound_static_method2);
|
||||
}
|
||||
|
||||
Callable Example::test_custom_callable() const {
|
||||
return Callable(memnew(MyCallableCustom));
|
||||
}
|
||||
|
||||
void Example::unbound_method1(Object *p_object, String p_string, int p_int) {
|
||||
String test = "unbound_method1: ";
|
||||
test += p_object->get_class();
|
||||
test += " - " + p_string;
|
||||
emit_custom_signal(test, p_int);
|
||||
}
|
||||
|
||||
String Example::unbound_method2(Object *p_object, String p_string, int p_int) {
|
||||
String test = "unbound_method2: ";
|
||||
test += p_object->get_class();
|
||||
test += " - " + p_string;
|
||||
test += " - " + itos(p_int);
|
||||
return test;
|
||||
}
|
||||
|
||||
String Example::unbound_method3(Object *p_object, String p_string, int p_int) const {
|
||||
String test = "unbound_method3: ";
|
||||
test += p_object->get_class();
|
||||
test += " - " + p_string;
|
||||
test += " - " + itos(p_int);
|
||||
return test;
|
||||
}
|
||||
|
||||
void Example::unbound_static_method1(Example *p_object, String p_string, int p_int) {
|
||||
String test = "unbound_static_method1: ";
|
||||
test += p_object->get_class();
|
||||
test += " - " + p_string;
|
||||
p_object->emit_custom_signal(test, p_int);
|
||||
}
|
||||
|
||||
String Example::unbound_static_method2(Object *p_object, String p_string, int p_int) {
|
||||
String test = "unbound_static_method2: ";
|
||||
test += p_object->get_class();
|
||||
test += " - " + p_string;
|
||||
test += " - " + itos(p_int);
|
||||
return test;
|
||||
}
|
||||
|
||||
int Example::test_tarray_arg(const TypedArray<int64_t> &p_array) {
|
||||
int sum = 0;
|
||||
for (int i = 0; i < p_array.size(); i++) {
|
||||
sum += (int)p_array[i];
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
TypedArray<Vector2> Example::test_tarray() const {
|
||||
TypedArray<Vector2> arr;
|
||||
|
||||
arr.resize(2);
|
||||
arr[0] = Vector2(1, 2);
|
||||
arr[1] = Vector2(2, 3);
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
Dictionary Example::test_dictionary() const {
|
||||
Dictionary dict;
|
||||
|
||||
dict["hello"] = "world";
|
||||
dict["foo"] = "bar";
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
bool Example::test_object_cast_to_node(Object *p_object) const {
|
||||
return Object::cast_to<Node>(p_object) != nullptr;
|
||||
}
|
||||
|
||||
bool Example::test_object_cast_to_control(Object *p_object) const {
|
||||
return Object::cast_to<Control>(p_object) != nullptr;
|
||||
}
|
||||
|
||||
bool Example::test_object_cast_to_example(Object *p_object) const {
|
||||
return Object::cast_to<Example>(p_object) != nullptr;
|
||||
}
|
||||
|
||||
Vector2i Example::test_variant_vector2i_conversion(const Variant &p_variant) const {
|
||||
return p_variant;
|
||||
}
|
||||
|
||||
int Example::test_variant_int_conversion(const Variant &p_variant) const {
|
||||
return p_variant;
|
||||
}
|
||||
|
||||
float Example::test_variant_float_conversion(const Variant &p_variant) const {
|
||||
return p_variant;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void Example::test_set_tileset(TileMap *p_tilemap, const Ref<TileSet> &p_tileset) const {
|
||||
p_tilemap->set_tileset(p_tileset);
|
||||
}
|
||||
|
||||
Variant Example::test_variant_call(Variant p_variant) {
|
||||
return p_variant.call("test", "hello");
|
||||
}
|
||||
|
||||
BitField<Example::Flags> Example::test_bitfield(BitField<Flags> flags) {
|
||||
return flags;
|
||||
}
|
||||
|
||||
Variant Example::test_variant_iterator(const Variant &p_input) {
|
||||
Array output;
|
||||
|
||||
Variant iter;
|
||||
|
||||
bool is_init_valid = true;
|
||||
if (!p_input.iter_init(iter, is_init_valid)) {
|
||||
if (!is_init_valid) {
|
||||
return "iter_init: not valid";
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
bool is_iter_next_valid = true;
|
||||
bool is_iter_get_valid = true;
|
||||
do {
|
||||
if (!is_iter_next_valid) {
|
||||
return "iter_next: not valid";
|
||||
}
|
||||
|
||||
Variant value = p_input.iter_get(iter, is_iter_get_valid);
|
||||
if (!is_iter_get_valid) {
|
||||
return "iter_get: not valid";
|
||||
}
|
||||
output.push_back(((int)value) + 5);
|
||||
|
||||
} while (p_input.iter_next(iter, is_iter_next_valid));
|
||||
|
||||
if (!is_iter_next_valid) {
|
||||
return "iter_next: not valid";
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
void Example::test_rpc(int p_value) {
|
||||
last_rpc_arg = p_value;
|
||||
}
|
||||
|
||||
void Example::test_send_rpc(int p_value) {
|
||||
rpc("test_rpc", p_value);
|
||||
}
|
||||
|
||||
int Example::return_last_rpc_arg() {
|
||||
return last_rpc_arg;
|
||||
}
|
||||
|
||||
void Example::callable_bind() {
|
||||
Callable c = Callable(this, "emit_custom_signal").bind("bound", 11);
|
||||
c.call();
|
||||
}
|
||||
|
||||
// Properties.
|
||||
void Example::set_custom_position(const Vector2 &pos) {
|
||||
custom_position = pos;
|
||||
}
|
||||
|
||||
Vector2 Example::get_custom_position() const {
|
||||
return custom_position;
|
||||
}
|
||||
|
||||
Vector4 Example::get_v4() const {
|
||||
return Vector4(1.2, 3.4, 5.6, 7.8);
|
||||
}
|
||||
|
||||
bool Example::test_post_initialize() const {
|
||||
Ref<ExampleRef> new_example_ref;
|
||||
new_example_ref.instantiate();
|
||||
return new_example_ref->was_post_initialized();
|
||||
}
|
||||
|
||||
// Virtual function override.
|
||||
bool Example::_has_point(const Vector2 &point) const {
|
||||
Label *label = get_node<Label>("Label");
|
||||
label->set_text("Got point: " + Variant(point).stringify());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Example::_input(const Ref<InputEvent> &event) {
|
||||
const InputEventKey *key_event = Object::cast_to<const InputEventKey>(*event);
|
||||
if (key_event) {
|
||||
emit_custom_signal(String("_input: ") + key_event->get_key_label(), key_event->get_unicode());
|
||||
}
|
||||
}
|
||||
|
||||
void ExampleBase::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_value1"), &ExampleBase::get_value1);
|
||||
ClassDB::bind_method(D_METHOD("get_value2"), &ExampleBase::get_value2);
|
||||
}
|
||||
|
||||
void ExampleBase::_notification(int p_what) {
|
||||
if (p_what == NOTIFICATION_ENTER_TREE) {
|
||||
value1 = 11;
|
||||
value2 = 22;
|
||||
}
|
||||
}
|
||||
|
||||
void ExampleChild::_notification(int p_what) {
|
||||
if (p_what == NOTIFICATION_ENTER_TREE) {
|
||||
value2 = 33;
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
String Example::test_library_path() {
|
||||
String 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";
|
||||
}
|
||||
293
cobor_vm_extension/godot-cpp/test/src/example.h
Normal file
293
cobor_vm_extension/godot-cpp/test/src/example.h
Normal file
@@ -0,0 +1,293 @@
|
||||
/* godot-cpp integration testing project.
|
||||
*
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*/
|
||||
|
||||
#ifndef EXAMPLE_CLASS_H
|
||||
#define EXAMPLE_CLASS_H
|
||||
|
||||
// We don't need windows.h in this example plugin but many others do, and it can
|
||||
// lead to annoying situations due to the ton of macros it defines.
|
||||
// So we include it and make sure CI warns us if we use something that conflicts
|
||||
// with a Windows define.
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <godot_cpp/classes/control.hpp>
|
||||
#include <godot_cpp/classes/global_constants.hpp>
|
||||
#include <godot_cpp/classes/image.hpp>
|
||||
#include <godot_cpp/classes/input_event_key.hpp>
|
||||
#include <godot_cpp/classes/tile_map.hpp>
|
||||
#include <godot_cpp/classes/tile_set.hpp>
|
||||
#include <godot_cpp/classes/viewport.hpp>
|
||||
#include <godot_cpp/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;
|
||||
|
||||
class ExampleRef : public RefCounted {
|
||||
GDCLASS(ExampleRef, RefCounted);
|
||||
|
||||
private:
|
||||
static int instance_count;
|
||||
static int last_id;
|
||||
|
||||
int id;
|
||||
bool post_initialized = false;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
void _notification(int p_what);
|
||||
|
||||
public:
|
||||
ExampleRef();
|
||||
~ExampleRef();
|
||||
|
||||
void set_id(int p_id);
|
||||
int get_id() const;
|
||||
|
||||
bool was_post_initialized() const { return post_initialized; }
|
||||
};
|
||||
|
||||
class ExampleMin : public Control {
|
||||
GDCLASS(ExampleMin, Control);
|
||||
|
||||
protected:
|
||||
static void _bind_methods(){};
|
||||
};
|
||||
|
||||
class Example : public Control {
|
||||
GDCLASS(Example, Control);
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
void _notification(int p_what);
|
||||
bool _set(const StringName &p_name, const Variant &p_value);
|
||||
bool _get(const StringName &p_name, Variant &r_ret) const;
|
||||
void _get_property_list(List<PropertyInfo> *p_list) const;
|
||||
bool _property_can_revert(const StringName &p_name) const;
|
||||
bool _property_get_revert(const StringName &p_name, Variant &r_property) const;
|
||||
void _validate_property(PropertyInfo &p_property) const;
|
||||
|
||||
String _to_string() const;
|
||||
|
||||
private:
|
||||
Vector2 custom_position;
|
||||
Vector3 property_from_list;
|
||||
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 {
|
||||
FIRST,
|
||||
ANSWER_TO_EVERYTHING = 42,
|
||||
};
|
||||
|
||||
enum Flags {
|
||||
FLAG_ONE = 1,
|
||||
FLAG_TWO = 2,
|
||||
};
|
||||
|
||||
enum {
|
||||
CONSTANT_WITHOUT_ENUM = 314,
|
||||
};
|
||||
|
||||
Example();
|
||||
~Example();
|
||||
|
||||
// Functions.
|
||||
void simple_func();
|
||||
void simple_const_func() const;
|
||||
int custom_ref_func(Ref<ExampleRef> p_ref);
|
||||
int custom_const_ref_func(const Ref<ExampleRef> &p_ref);
|
||||
String image_ref_func(Ref<Image> p_image);
|
||||
String image_const_ref_func(const Ref<Image> &p_image);
|
||||
String return_something(const String &base);
|
||||
Viewport *return_something_const() const;
|
||||
Ref<ExampleRef> return_ref() const;
|
||||
Ref<ExampleRef> return_empty_ref() const;
|
||||
ExampleRef *return_extended_ref() const;
|
||||
Ref<ExampleRef> extended_ref_checks(Ref<ExampleRef> p_ref) const;
|
||||
Variant varargs_func(const Variant **args, GDExtensionInt arg_count, GDExtensionCallError &error);
|
||||
int varargs_func_nv(const Variant **args, GDExtensionInt arg_count, GDExtensionCallError &error);
|
||||
void varargs_func_void(const Variant **args, GDExtensionInt arg_count, GDExtensionCallError &error);
|
||||
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;
|
||||
bool test_string_is_forty_two(const String &p_str) const;
|
||||
String test_string_resize(String p_original) const;
|
||||
TypedArray<PackedInt32Array> test_typed_array_of_packed() const;
|
||||
int test_vector_ops() const;
|
||||
int test_vector_init_list() const;
|
||||
|
||||
bool test_object_cast_to_node(Object *p_object) const;
|
||||
bool test_object_cast_to_control(Object *p_object) const;
|
||||
bool test_object_cast_to_example(Object *p_object) const;
|
||||
|
||||
Vector2i test_variant_vector2i_conversion(const Variant &p_variant) const;
|
||||
int test_variant_int_conversion(const Variant &p_variant) const;
|
||||
float test_variant_float_conversion(const Variant &p_variant) const;
|
||||
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;
|
||||
|
||||
Variant test_variant_call(Variant p_variant);
|
||||
|
||||
Callable test_callable_mp();
|
||||
Callable test_callable_mp_ret();
|
||||
Callable test_callable_mp_retc() const;
|
||||
Callable test_callable_mp_static() const;
|
||||
Callable test_callable_mp_static_ret() const;
|
||||
Callable test_custom_callable() const;
|
||||
|
||||
void unbound_method1(Object *p_object, String p_string, int p_int);
|
||||
String unbound_method2(Object *p_object, String p_string, int p_int);
|
||||
String unbound_method3(Object *p_object, String p_string, int p_int) const;
|
||||
static void unbound_static_method1(Example *p_object, String p_string, int p_int);
|
||||
static String unbound_static_method2(Object *p_object, String p_string, int p_int);
|
||||
|
||||
BitField<Flags> test_bitfield(BitField<Flags> flags);
|
||||
|
||||
Variant test_variant_iterator(const Variant &p_input);
|
||||
|
||||
// RPC
|
||||
void test_rpc(int p_value);
|
||||
void test_send_rpc(int p_value);
|
||||
int return_last_rpc_arg();
|
||||
|
||||
void callable_bind();
|
||||
|
||||
// Property.
|
||||
void set_custom_position(const Vector2 &pos);
|
||||
Vector2 get_custom_position() const;
|
||||
Vector4 get_v4() const;
|
||||
|
||||
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();
|
||||
|
||||
// Virtual function override (no need to bind manually).
|
||||
virtual bool _has_point(const Vector2 &point) const override;
|
||||
virtual void _input(const Ref<InputEvent> &event) override;
|
||||
|
||||
GDVIRTUAL2R(String, _do_something_virtual, String, int);
|
||||
String test_virtual_implemented_in_script(const String &p_name, int p_value);
|
||||
GDVIRTUAL1(_do_something_virtual_with_control, Control *);
|
||||
|
||||
String test_use_engine_singleton() const;
|
||||
|
||||
static String test_library_path();
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(Example::Constants);
|
||||
VARIANT_BITFIELD_CAST(Example::Flags);
|
||||
|
||||
enum EnumWithoutClass {
|
||||
OUTSIDE_OF_CLASS = 512
|
||||
};
|
||||
VARIANT_ENUM_CAST(EnumWithoutClass);
|
||||
|
||||
class ExampleVirtual : public Object {
|
||||
GDCLASS(ExampleVirtual, Object);
|
||||
|
||||
protected:
|
||||
static void _bind_methods() {}
|
||||
};
|
||||
|
||||
class ExampleAbstractBase : public Object {
|
||||
GDCLASS(ExampleAbstractBase, Object);
|
||||
|
||||
protected:
|
||||
static void _bind_methods() {}
|
||||
|
||||
virtual int test_function() = 0;
|
||||
};
|
||||
|
||||
class ExampleConcrete : public ExampleAbstractBase {
|
||||
GDCLASS(ExampleConcrete, ExampleAbstractBase);
|
||||
|
||||
protected:
|
||||
static void _bind_methods() {}
|
||||
|
||||
virtual int test_function() override { return 25; }
|
||||
};
|
||||
|
||||
class ExampleBase : public Node {
|
||||
GDCLASS(ExampleBase, Node);
|
||||
|
||||
protected:
|
||||
int value1 = 0;
|
||||
int value2 = 0;
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
void _notification(int p_what);
|
||||
|
||||
public:
|
||||
int get_value1() { return value1; }
|
||||
int get_value2() { return value2; }
|
||||
};
|
||||
|
||||
class ExampleChild : public ExampleBase {
|
||||
GDCLASS(ExampleChild, ExampleBase);
|
||||
|
||||
protected:
|
||||
static void _bind_methods() {}
|
||||
|
||||
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
|
||||
53
cobor_vm_extension/godot-cpp/test/src/register_types.cpp
Normal file
53
cobor_vm_extension/godot-cpp/test/src/register_types.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
/* godot-cpp integration testing project.
|
||||
*
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*/
|
||||
|
||||
#include "register_types.h"
|
||||
|
||||
#include <gdextension_interface.h>
|
||||
|
||||
#include <godot_cpp/core/class_db.hpp>
|
||||
#include <godot_cpp/core/defs.hpp>
|
||||
#include <godot_cpp/godot.hpp>
|
||||
|
||||
#include "example.h"
|
||||
#include "tests.h"
|
||||
|
||||
using namespace godot;
|
||||
|
||||
void initialize_example_module(ModuleInitializationLevel p_level) {
|
||||
if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
|
||||
return;
|
||||
}
|
||||
|
||||
GDREGISTER_CLASS(ExampleRef);
|
||||
GDREGISTER_CLASS(ExampleMin);
|
||||
GDREGISTER_CLASS(Example);
|
||||
GDREGISTER_VIRTUAL_CLASS(ExampleVirtual);
|
||||
GDREGISTER_ABSTRACT_CLASS(ExampleAbstractBase);
|
||||
GDREGISTER_CLASS(ExampleConcrete);
|
||||
GDREGISTER_CLASS(ExampleBase);
|
||||
GDREGISTER_CLASS(ExampleChild);
|
||||
GDREGISTER_RUNTIME_CLASS(ExampleRuntime);
|
||||
GDREGISTER_CLASS(ExamplePrzykład);
|
||||
}
|
||||
|
||||
void uninitialize_example_module(ModuleInitializationLevel p_level) {
|
||||
if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
// Initialization.
|
||||
GDExtensionBool GDE_EXPORT example_library_init(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) {
|
||||
godot::GDExtensionBinding::InitObject init_obj(p_get_proc_address, p_library, r_initialization);
|
||||
|
||||
init_obj.register_initializer(initialize_example_module);
|
||||
init_obj.register_terminator(uninitialize_example_module);
|
||||
init_obj.set_minimum_library_initialization_level(MODULE_INITIALIZATION_LEVEL_SCENE);
|
||||
|
||||
return init_obj.init();
|
||||
}
|
||||
}
|
||||
16
cobor_vm_extension/godot-cpp/test/src/register_types.h
Normal file
16
cobor_vm_extension/godot-cpp/test/src/register_types.h
Normal file
@@ -0,0 +1,16 @@
|
||||
/* godot-cpp integration testing project.
|
||||
*
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*/
|
||||
|
||||
#ifndef EXAMPLE_REGISTER_TYPES_H
|
||||
#define EXAMPLE_REGISTER_TYPES_H
|
||||
|
||||
#include <godot_cpp/core/class_db.hpp>
|
||||
|
||||
using namespace godot;
|
||||
|
||||
void initialize_example_module(ModuleInitializationLevel p_level);
|
||||
void uninitialize_example_module(ModuleInitializationLevel p_level);
|
||||
|
||||
#endif // EXAMPLE_REGISTER_TYPES_H
|
||||
29
cobor_vm_extension/godot-cpp/test/src/tests.h
Normal file
29
cobor_vm_extension/godot-cpp/test/src/tests.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/* godot-cpp integration testing project.
|
||||
*
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*/
|
||||
|
||||
#ifndef TESTS_H
|
||||
#define TESTS_H
|
||||
|
||||
#include <godot_cpp/templates/cowdata.hpp>
|
||||
#include <godot_cpp/templates/hash_map.hpp>
|
||||
#include <godot_cpp/templates/hash_set.hpp>
|
||||
#include <godot_cpp/templates/hashfuncs.hpp>
|
||||
#include <godot_cpp/templates/list.hpp>
|
||||
#include <godot_cpp/templates/local_vector.hpp>
|
||||
#include <godot_cpp/templates/pair.hpp>
|
||||
#include <godot_cpp/templates/rb_map.hpp>
|
||||
#include <godot_cpp/templates/rb_set.hpp>
|
||||
#include <godot_cpp/templates/rid_owner.hpp>
|
||||
#include <godot_cpp/templates/safe_refcount.hpp>
|
||||
#include <godot_cpp/templates/search_array.hpp>
|
||||
#include <godot_cpp/templates/self_list.hpp>
|
||||
#include <godot_cpp/templates/sort_array.hpp>
|
||||
#include <godot_cpp/templates/spin_lock.hpp>
|
||||
#include <godot_cpp/templates/thread_work_pool.hpp>
|
||||
#include <godot_cpp/templates/vector.hpp>
|
||||
#include <godot_cpp/templates/vmap.hpp>
|
||||
#include <godot_cpp/templates/vset.hpp>
|
||||
|
||||
#endif // TESTS_H
|
||||
Reference in New Issue
Block a user