Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions binding_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -2062,6 +2062,7 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
result = []

class_name = class_api["name"]
inherits = class_api["inherits"] if "inherits" in class_api else "Wrapped"
snake_class_name = camel_to_snake(class_name)
is_singleton = class_name in singletons

Expand Down Expand Up @@ -2101,27 +2102,37 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
result.append("#ifdef DEBUG_ENABLED")
result.append("\t\tERR_FAIL_NULL_V(singleton_obj, nullptr);")
result.append("#endif // DEBUG_ENABLED")
# This will lead to the constructor which will set `singleton`.
result.append(
f"\t\tsingleton = reinterpret_cast<{class_name} *>(::godot::gdextension_interface::object_get_instance_binding(singleton_obj, ::godot::gdextension_interface::token, &{class_name}::_gde_binding_callbacks));"
f"\t\t::godot::gdextension_interface::object_get_instance_binding(singleton_obj, ::godot::gdextension_interface::token, &{class_name}::_gde_binding_callbacks);"
)
result.append("#ifdef DEBUG_ENABLED")
result.append("\t\tERR_FAIL_NULL_V(singleton, nullptr);")
result.append("#endif // DEBUG_ENABLED")
result.append("\t\tif (likely(singleton)) {")
result.append(f"\t\t\tClassDB::_register_engine_singleton({class_name}::get_class_static(), singleton);")
result.append("\t\t}")
result.append("\t}")
result.append("\treturn singleton;")
result.append("}")
result.append("")

result.append(f"{class_name}::{class_name}(GodotObject *p_godot_object) : {inherits}(p_godot_object) {{")
result.append("\tif (singleton == nullptr) {")
result.append("\t\tsingleton = this;")
result.append(f"\t\tClassDB::_register_engine_singleton({class_name}::get_class_static(), singleton);")
result.append("\t}")
result.append("}")
result.append("")

result.append(f"{class_name}::~{class_name}() {{")
result.append("\tif (singleton == this) {")
result.append(f"\t\tClassDB::_unregister_engine_singleton({class_name}::get_class_static());")
result.append("\t\tsingleton = nullptr;")
result.append("\t}")
result.append("}")
result.append("")
else:
result.append(f"{class_name}::{class_name}(GodotObject *p_godot_object) : {inherits}(p_godot_object) {{")
result.append("}")
result.append("")

if "methods" in class_api:
for method in class_api["methods"]:
Expand Down
2 changes: 1 addition & 1 deletion include/godot_cpp/classes/wrapped.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ private:
\
protected: \
m_class(const char *p_godot_class) : m_inherits(p_godot_class) {} \
m_class(GodotObject *p_godot_object) : m_inherits(p_godot_object) {} \
m_class(GodotObject *p_godot_object); \
\
static void _bind_methods() {} \
\
Expand Down
4 changes: 3 additions & 1 deletion test/build_profile.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"enabled_classes": [
"Control",
"Engine",
"InputEventKey",
"Label",
"MultiplayerAPI",
Expand All @@ -9,6 +10,7 @@
"TileMap",
"TileSet",
"Tween",
"Viewport"
"Viewport",
"XRServer"
]
}
5 changes: 3 additions & 2 deletions test/project/main.gd
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,9 @@ func _ready():
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())
# Test that we can access an engine singletons.
assert_equal(example.test_use_engine_singleton1(), OS.get_name())
assert_equal(example.test_use_engine_singleton2(), true)

if godot_target_version["minor"] >= 4:
assert_equal(example.test_get_internal(1), 1)
Expand Down
12 changes: 10 additions & 2 deletions test/src/example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@

#include <godot_cpp/core/class_db.hpp>

#include <godot_cpp/classes/engine.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/classes/xr_server.hpp>
#include <godot_cpp/variant/utility_functions.hpp>

using namespace godot;
Expand Down Expand Up @@ -265,7 +267,8 @@ void Example::_bind_methods() {
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_method(D_METHOD("test_use_engine_singleton1"), &Example::test_use_engine_singleton1);
ClassDB::bind_method(D_METHOD("test_use_engine_singleton2"), &Example::test_use_engine_singleton2);

ClassDB::bind_method(D_METHOD("test_get_internal_class"), &Example::test_get_internal_class);

Expand Down Expand Up @@ -758,10 +761,15 @@ String Example::test_virtual_implemented_in_script(const String &p_name, int p_v
return "Unimplemented";
}

String Example::test_use_engine_singleton() const {
String Example::test_use_engine_singleton1() const {
return OS::get_singleton()->get_name();
}

bool Example::test_use_engine_singleton2() const {
XRServer *xr_server = Object::cast_to<XRServer>(Engine::get_singleton()->get_singleton("XRServer"));
return xr_server != nullptr;
}

String Example::test_library_path() {
String library_path;
::godot::gdextension_interface::get_library_path(::godot::gdextension_interface::library, library_path._native_ptr());
Expand Down
3 changes: 2 additions & 1 deletion test/src/example.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,8 @@ class Example : public Control {
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;
String test_use_engine_singleton1() const;
bool test_use_engine_singleton2() const;

static String test_library_path();

Expand Down
Loading