Open KirillGrigoriev opened 1 year ago
Singleton's in the engine and GDExtension aren't like "autoload singletons", they are something totally different.
Some examples of engine singletons include Time
, Input
, ResourceLoader
, etc. Since GDExtensions are meant to work like engine modules, that means GDExtension singletons are the same kind of thing.
Presently, if you want to make an autoload singleton using a GDExtension class, you'll need to make a scene where your GDExtension node is the root of the scene. Then add that scene as an autoload singleton in the editor, same as you would add any scene.
I hope that helps!
Thanks for reply. But, I need something that can hold data and interact with game world regardless of loaded scene. In other words: I need to create GDScript autoload singleton in GDExtension. It's like to lose inventory when load another level, for example. Now, I'm use autoload GDScript as wrapper, wrapper act exactly like I need, but I'm sure it shouldn't work like this. There are should be a way to create something like this in GDExtension without wrappers, if not in current version, but in future version of engine.
Now, I'm use autoload GDScript as wrapper, wrapper act exactly like I need, but I'm sure it shouldn't work like this.
You don't need to use GDScript. You can make scenes into autoload singletons too, not just GDScripts. So, if you make a scene that has your GDExtension node as the root of the scene, and then make that scene into an autoload singleton (via the usual dialog in the editor), it should work without needing to involve GDScript at all.
Oh, I got your idea. Create scene that extends from my singleton GDExtension class, save it, and add file to Autoload section. But, now somehow methods from my extension that depends on this class called before singleton created. Methods like (for example):
Bar::~Bar() { foo->m_bars.erase(std::remove(vec.begin(), vec.end(), this), vec.end()); }
Bar::Bar() { foo->m_bars.push_back(this); }
For some reason called both constructors and destructors at engine start. Singleton in extension referred by pointer that I set from singleton's constructor. Like:
Foo::Foo() : Node() { foo = this; }
Engine just crushed on start with null pointer exception. To sure about it, I just comment places like this, and engine started, but obviously extension initialized wrongly. Maybe, autoloads loads after creating scene and all nodes, or maybe autoloads don't loads at editor time, this I'm not sure about it. Also, seems like now scene is wrapper, with two scene loaded at same time engine starts and closes slower, I can see this lags, it's not important for me, but seems better use GDScript as wrapper and we still have a wrapper. I'm actually happy with GDScript wrapper, but I would happy engine I like become better in this part.
If you're still doing Engine::get_singleton()->register_singleton("GlobalFoo", foo);
I think you should probably remove that. I don't think you don't want an engine-level singleton at all, you just want the project-level autoload singleton.
However, regarding this in particular:
For some reason called both constructors and destructors at engine start.
All engine classes (which includes GDExtension classes but also the ones built into the engine) are created and destroyed once during startup, so that the ClassDB
can read some information from them. For this reason, you shouldn't do anything that creates important resources in a class constructor.
Usually, doing something like:
Foo::Foo() : Node() { foo = this; }
... is fine. I do this in the engine-level singletons in my GDExtensions. :-)
But, I don't think you really want an engine-level singleton, so I wouldn't do this in your case. Your singleton is an autoload singleton, which means you access it by grabbing it from the scene tree (ie get_tree()->get_node("/root/MyAutoloadName")
).
Oh, I got it. Seems like engine-level singleton have better performance, I think, it's important for games, but I need more testing. Anyway, big thanks for advice and spended time. )
Godot version
v4.1.2.stable.official [399c9dc39]
System information
Godot v4.1.2.stable - Windows 10.0.19045 - Vulkan (Mobile) - dedicated NVIDIA GeForce GTX 650 (NVIDIA; 30.0.14.7430) - 13th Gen Intel(R) Core(TM) i5-13400 (16 Threads)
Issue description
Singleton created by memnew in GDExtension and registered by Engine::get_singleton()->register_singleton don't receive any events, any of virtual methods won't called, also don't shown in Node Tree Viewer, near "root" node, but all other functions seems work, singleton available from any GDScript.
Steps to reproduce
Minimal reproduction project
Foo.cpp:
test_scene.gd:
Output: