Now the Engine has methods to store globals (custom singletons). They are mostly meant for classes like EditorInterface, SpatialEditor, and plugin scripts that need a singleton for in-editor use. In essence it provides easy and side effect less access for classes that might not be present on every run. (For example gdscript recognizes normal singletons as keywords, but not these.)

This commit is contained in:
Relintai 2022-08-23 13:13:39 +02:00
parent d41239d425
commit 4f9dd569b8
5 changed files with 108 additions and 1 deletions

View File

@ -3155,6 +3155,22 @@ bool _Engine::is_editor_hint() const {
return Engine::get_singleton()->is_editor_hint();
}
void _Engine::add_global(const String &p_name, const Variant &p_global) {
return Engine::get_singleton()->add_global(p_name, p_global);
}
Variant _Engine::get_global(const String &p_name) {
return Engine::get_singleton()->get_global(p_name);
}
void _Engine::remove_global(const String &p_name) {
return Engine::get_singleton()->remove_global(p_name);
}
bool _Engine::has_global(const String &p_name) {
return Engine::get_singleton()->has_global(p_name);
}
Dictionary _Engine::get_globals() {
return Engine::get_singleton()->get_globals();
}
void _Engine::set_print_error_messages(bool p_enabled) {
Engine::get_singleton()->set_print_error_messages(p_enabled);
}
@ -3197,6 +3213,12 @@ void _Engine::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_editor_hint", "enabled"), &_Engine::set_editor_hint);
ClassDB::bind_method(D_METHOD("is_editor_hint"), &_Engine::is_editor_hint);
ClassDB::bind_method(D_METHOD("add_global", "name", "global"), &_Engine::add_global);
ClassDB::bind_method(D_METHOD("get_global", "name"), &_Engine::get_global);
ClassDB::bind_method(D_METHOD("remove_global", "name"), &_Engine::remove_global);
ClassDB::bind_method(D_METHOD("has_global", "name"), &_Engine::has_global);
ClassDB::bind_method(D_METHOD("get_globals"), &_Engine::get_globals);
ClassDB::bind_method(D_METHOD("set_print_error_messages", "enabled"), &_Engine::set_print_error_messages);
ClassDB::bind_method(D_METHOD("is_printing_error_messages"), &_Engine::is_printing_error_messages);

View File

@ -825,6 +825,12 @@ public:
void set_editor_hint(bool p_enabled);
bool is_editor_hint() const;
void add_global(const String &p_name, const Variant &p_global);
Variant get_global(const String &p_name);
void remove_global(const String &p_name);
bool has_global(const String &p_name);
Dictionary get_globals();
void set_print_error_messages(bool p_enabled);
bool is_printing_error_messages() const;

View File

@ -86,6 +86,38 @@ void Engine::set_portals_active(bool p_active) {
_portals_active = p_active;
}
void Engine::add_global(const String &p_name, const Variant &p_global) {
ERR_FAIL_COND(_globals.has(p_name));
_globals.set(p_name, p_global);
}
Variant Engine::get_global(const String &p_name) {
ERR_FAIL_COND_V(!_globals.has(p_name), Variant());
return _globals[p_name];
}
void Engine::remove_global(const String &p_name) {
ERR_FAIL_COND(!_globals.has(p_name));
_globals.erase(p_name);
}
bool Engine::has_global(const String &p_name) {
return _globals.has(p_name);
}
Dictionary Engine::get_globals() {
Dictionary dict;
const String *k = NULL;
while ((k = _globals.next(k))) {
String key = *k;
dict[key] = _globals[key];
}
return dict;
}
Dictionary Engine::get_version_info() const {
Dictionary dict;
dict["major"] = VERSION_MAJOR;

View File

@ -30,6 +30,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "core/containers/hash_map.h"
#include "core/containers/list.h"
#include "core/containers/vector.h"
#include "core/os/main_loop.h"
@ -97,6 +98,12 @@ public:
}
#endif
void add_global(const String &p_name, const Variant &p_global);
Variant get_global(const String &p_name);
void remove_global(const String &p_name);
bool has_global(const String &p_name);
Dictionary get_globals();
Dictionary get_version_info() const;
Dictionary get_author_info() const;
Array get_copyright_info() const;
@ -134,6 +141,8 @@ private:
bool editor_hint;
HashMap<String, Variant> _globals;
static Engine *singleton;
};

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Engine" inherits="Object" version="3.7">
<class name="Engine" inherits="Object" version="3.8">
<brief_description>
Access to engine properties.
</brief_description>
@ -9,6 +9,17 @@
<tutorials>
</tutorials>
<methods>
<method name="add_global">
<return type="void" />
<argument index="0" name="name" type="String" />
<argument index="1" name="global" type="Variant" />
<description>
Adds a class for easy global access.
These should be used by engine side singletons that cannot be expected to be always present, like the SpatialEditor, the EditorInterface, and plugins so they don't have to create autoloads when they need a singleton for in-editor use.
In your game / app projects use autoloads instead.
Classes that are added are not turned into tokens by scripting languages like with normal singletons (Engine, RenderingServer etc.).
</description>
</method>
<method name="get_author_info" qualifiers="const">
<return type="Dictionary" />
<description>
@ -46,6 +57,19 @@
Returns the frames per second of the running game.
</description>
</method>
<method name="get_global">
<return type="Variant" />
<argument index="0" name="name" type="String" />
<description>
Returns a global using it's name.
</description>
</method>
<method name="get_globals">
<return type="Dictionary" />
<description>
Returns all globals as a dictionary.
</description>
</method>
<method name="get_idle_frames" qualifiers="const">
<return type="int" />
<description>
@ -123,6 +147,13 @@
[/codeblock]
</description>
</method>
<method name="has_global">
<return type="bool" />
<argument index="0" name="name" type="String" />
<description>
Returns whenter a global existss or not.
</description>
</method>
<method name="has_singleton" qualifiers="const">
<return type="bool" />
<argument index="0" name="name" type="String" />
@ -136,6 +167,13 @@
Returns [code]true[/code] if the game is inside the fixed process and physics phase of the game loop.
</description>
</method>
<method name="remove_global">
<return type="void" />
<argument index="0" name="name" type="String" />
<description>
Removes a global using it's name.
</description>
</method>
</methods>
<members>
<member name="editor_hint" type="bool" setter="set_editor_hint" getter="is_editor_hint" default="true">