Skip to content

Commit 27a7acc

Browse files
committed
Add SceneTree::get_singleton()
1 parent 1d713bd commit 27a7acc

6 files changed

Lines changed: 33 additions & 0 deletions

File tree

binding_generator.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1953,6 +1953,9 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
19531953
"\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());"
19541954
)
19551955

1956+
if class_name == "SceneTree":
1957+
result.append("\tstatic SceneTree *get_singleton();")
1958+
19561959
if class_name == "Object":
19571960
result.append("\ttemplate <typename T>")
19581961
result.append("\tstatic T *cast_to(Object *p_object);")

src/classes/low_level.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,17 @@
3535

3636
#include <godot_cpp/godot.hpp>
3737

38+
// Unlike the classes above, `Engine` and `SceneTree` aren't always generated, since they may be left out of a build profile.
39+
// Only define `SceneTree::get_singleton()` when both of them are available, so that build profiles don't have to include them.
40+
#if __has_include(<godot_cpp/classes/engine.hpp>) && __has_include(<godot_cpp/classes/scene_tree.hpp>)
41+
#define GODOT_CPP_SCENE_TREE_SINGLETON
42+
43+
#include <godot_cpp/classes/engine.hpp>
44+
#include <godot_cpp/classes/scene_tree.hpp>
45+
46+
#include <godot_cpp/core/object.hpp>
47+
#endif
48+
3849
namespace godot {
3950
Error XMLParser::_open_buffer(const uint8_t *p_buffer, size_t p_size) {
4051
return (Error)::godot::gdextension_interface::xml_parser_open_buffer(_owner, p_buffer, p_size);
@@ -64,4 +75,10 @@ const uint8_t *Image::ptr() {
6475
return ::godot::gdextension_interface::image_ptr(_owner);
6576
}
6677

78+
#ifdef GODOT_CPP_SCENE_TREE_SINGLETON
79+
SceneTree *SceneTree::get_singleton() {
80+
return Object::cast_to<SceneTree>(Engine::get_singleton()->get_main_loop());
81+
}
82+
#endif
83+
6784
} // namespace godot

test/build_profile.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
{
22
"enabled_classes": [
33
"Control",
4+
"Engine",
45
"InputEventKey",
56
"Label",
67
"MultiplayerAPI",
78
"MultiplayerPeer",
89
"OS",
10+
"SceneTree",
911
"TileMap",
1012
"TileSet",
1113
"Tween",

test/project/main.gd

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,9 @@ func _ready():
279279
# Test that we can access an engine singleton.
280280
assert_equal(example.test_use_engine_singleton(), OS.get_name())
281281

282+
# Test that we can access the SceneTree singleton.
283+
assert_equal(example.test_use_scene_tree_singleton(), true)
284+
282285
if godot_target_version["minor"] >= 4:
283286
assert_equal(example.test_get_internal(1), 1)
284287
assert_equal(example.test_get_internal(true), -1)

test/src/example.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <godot_cpp/classes/multiplayer_api.hpp>
1313
#include <godot_cpp/classes/multiplayer_peer.hpp>
1414
#include <godot_cpp/classes/os.hpp>
15+
#include <godot_cpp/classes/scene_tree.hpp>
1516
#include <godot_cpp/variant/utility_functions.hpp>
1617

1718
using namespace godot;
@@ -266,6 +267,7 @@ void Example::_bind_methods() {
266267
GDVIRTUAL_BIND(_do_something_virtual_with_control, "control");
267268

268269
ClassDB::bind_method(D_METHOD("test_use_engine_singleton"), &Example::test_use_engine_singleton);
270+
ClassDB::bind_method(D_METHOD("test_use_scene_tree_singleton"), &Example::test_use_scene_tree_singleton);
269271

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

@@ -759,6 +761,11 @@ String Example::test_use_engine_singleton() const {
759761
return OS::get_singleton()->get_name();
760762
}
761763

764+
bool Example::test_use_scene_tree_singleton() const {
765+
SceneTree *scene_tree = SceneTree::get_singleton();
766+
return scene_tree != nullptr && scene_tree == get_tree();
767+
}
768+
762769
String Example::test_library_path() {
763770
String library_path;
764771
::godot::gdextension_interface::get_library_path(::godot::gdextension_interface::library, library_path._native_ptr());

test/src/example.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ class Example : public Control {
214214
GDVIRTUAL1(_do_something_virtual_with_control, Control *);
215215

216216
String test_use_engine_singleton() const;
217+
bool test_use_scene_tree_singleton() const;
217218

218219
static String test_library_path();
219220

0 commit comments

Comments
 (0)