From fa0284371937d18e86740d71726686ac630feae6 Mon Sep 17 00:00:00 2001 From: Ijtihed Kilani Date: Wed, 24 Jun 2026 07:53:13 +0300 Subject: [PATCH] Add `SceneTree::get_singleton()` --- binding_generator.py | 3 +++ src/classes/low_level.cpp | 8 ++++++++ test/project/main.gd | 3 +++ test/src/example.cpp | 7 +++++++ test/src/example.h | 1 + 5 files changed, 22 insertions(+) diff --git a/binding_generator.py b/binding_generator.py index 1a401a3b8..1be3624e7 100644 --- a/binding_generator.py +++ b/binding_generator.py @@ -1953,6 +1953,9 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us "\tGroupID add_native_group_task(void (*p_func)(void *, uint32_t), void *p_userdata, int p_elements, int p_tasks = -1, bool p_high_priority = false, const String &p_description = String());" ) + if class_name == "SceneTree": + result.append("\tstatic SceneTree *get_singleton();") + if class_name == "Object": result.append("\ttemplate ") result.append("\tstatic T *cast_to(Object *p_object);") diff --git a/src/classes/low_level.cpp b/src/classes/low_level.cpp index a1e625e29..78e077f97 100644 --- a/src/classes/low_level.cpp +++ b/src/classes/low_level.cpp @@ -28,11 +28,15 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ +#include #include #include +#include #include #include +#include + #include namespace godot { @@ -64,4 +68,8 @@ const uint8_t *Image::ptr() { return ::godot::gdextension_interface::image_ptr(_owner); } +SceneTree *SceneTree::get_singleton() { + return Object::cast_to(Engine::get_singleton()->get_main_loop()); +} + } // namespace godot diff --git a/test/project/main.gd b/test/project/main.gd index 52d7c0f13..d002bccc5 100644 --- a/test/project/main.gd +++ b/test/project/main.gd @@ -279,6 +279,9 @@ func _ready(): # Test that we can access an engine singleton. assert_equal(example.test_use_engine_singleton(), OS.get_name()) + # Test that we can access the SceneTree singleton. + assert_equal(example.test_use_scene_tree_singleton(), true) + if godot_target_version["minor"] >= 4: assert_equal(example.test_get_internal(1), 1) assert_equal(example.test_get_internal(true), -1) diff --git a/test/src/example.cpp b/test/src/example.cpp index 43f781c4e..0f42bf176 100644 --- a/test/src/example.cpp +++ b/test/src/example.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include using namespace godot; @@ -266,6 +267,7 @@ void Example::_bind_methods() { 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_scene_tree_singleton"), &Example::test_use_scene_tree_singleton); ClassDB::bind_method(D_METHOD("test_get_internal_class"), &Example::test_get_internal_class); @@ -759,6 +761,11 @@ String Example::test_use_engine_singleton() const { return OS::get_singleton()->get_name(); } +bool Example::test_use_scene_tree_singleton() const { + SceneTree *scene_tree = SceneTree::get_singleton(); + return scene_tree != nullptr && scene_tree == get_tree(); +} + String Example::test_library_path() { String library_path; ::godot::gdextension_interface::get_library_path(::godot::gdextension_interface::library, library_path._native_ptr()); diff --git a/test/src/example.h b/test/src/example.h index d75abbd8f..82361fe7d 100644 --- a/test/src/example.h +++ b/test/src/example.h @@ -214,6 +214,7 @@ class Example : public Control { GDVIRTUAL1(_do_something_virtual_with_control, Control *); String test_use_engine_singleton() const; + bool test_use_scene_tree_singleton() const; static String test_library_path();