diff options
| -rw-r--r-- | core/config/engine.cpp | 30 | ||||
| -rw-r--r-- | core/config/engine.h | 7 | ||||
| -rw-r--r-- | core/core_bind.cpp | 35 | ||||
| -rw-r--r-- | core/core_bind.h | 7 | ||||
| -rw-r--r-- | doc/classes/Engine.xml | 22 | 
5 files changed, 90 insertions, 11 deletions
diff --git a/core/config/engine.cpp b/core/config/engine.cpp index 495670bc88..d8fbb50a75 100644 --- a/core/config/engine.cpp +++ b/core/config/engine.cpp @@ -199,17 +199,41 @@ bool Engine::is_printing_error_messages() const {  }  void Engine::add_singleton(const Singleton &p_singleton) { +	ERR_FAIL_COND_MSG(singleton_ptrs.has(p_singleton.name), "Can't register singleton that already exists: " + String(p_singleton.name));  	singletons.push_back(p_singleton);  	singleton_ptrs[p_singleton.name] = p_singleton.ptr;  } -Object *Engine::get_singleton_object(const String &p_name) const { +Object *Engine::get_singleton_object(const StringName &p_name) const {  	const Map<StringName, Object *>::Element *E = singleton_ptrs.find(p_name); -	ERR_FAIL_COND_V_MSG(!E, nullptr, "Failed to retrieve non-existent singleton '" + p_name + "'."); +	ERR_FAIL_COND_V_MSG(!E, nullptr, "Failed to retrieve non-existent singleton '" + String(p_name) + "'.");  	return E->get();  } -bool Engine::has_singleton(const String &p_name) const { +bool Engine::is_singleton_user_created(const StringName &p_name) const { +	ERR_FAIL_COND_V(!singleton_ptrs.has(p_name), false); + +	for (const Singleton &E : singletons) { +		if (E.name == p_name && E.user_created) { +			return true; +		} +	} + +	return false; +} +void Engine::remove_singleton(const StringName &p_name) { +	ERR_FAIL_COND(!singleton_ptrs.has(p_name)); + +	for (List<Singleton>::Element *E = singletons.front(); E; E = E->next()) { +		if (E->get().name == p_name) { +			singletons.erase(E); +			singleton_ptrs.erase(p_name); +			return; +		} +	} +} + +bool Engine::has_singleton(const StringName &p_name) const {  	return singleton_ptrs.has(p_name);  } diff --git a/core/config/engine.h b/core/config/engine.h index e6b5df2d5a..ae33acede2 100644 --- a/core/config/engine.h +++ b/core/config/engine.h @@ -42,6 +42,7 @@ public:  		StringName name;  		Object *ptr;  		StringName class_name; //used for binding generation hinting +		bool user_created = false;  		Singleton(const StringName &p_name = StringName(), Object *p_ptr = nullptr, const StringName &p_class_name = StringName());  	}; @@ -109,8 +110,10 @@ public:  	void add_singleton(const Singleton &p_singleton);  	void get_singletons(List<Singleton> *p_singletons); -	bool has_singleton(const String &p_name) const; -	Object *get_singleton_object(const String &p_name) const; +	bool has_singleton(const StringName &p_name) const; +	Object *get_singleton_object(const StringName &p_name) const; +	void remove_singleton(const StringName &p_name); +	bool is_singleton_user_created(const StringName &p_name) const;  #ifdef TOOLS_ENABLED  	_FORCE_INLINE_ void set_editor_hint(bool p_enabled) { editor_hint = p_enabled; } diff --git a/core/core_bind.cpp b/core/core_bind.cpp index efb4b84716..83a3b80803 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -2165,14 +2165,41 @@ bool Engine::is_in_physics_frame() const {  	return ::Engine::get_singleton()->is_in_physics_frame();  } -bool Engine::has_singleton(const String &p_name) const { +bool Engine::has_singleton(const StringName &p_name) const {  	return ::Engine::get_singleton()->has_singleton(p_name);  } -Object *Engine::get_singleton_object(const String &p_name) const { +Object *Engine::get_singleton_object(const StringName &p_name) const {  	return ::Engine::get_singleton()->get_singleton_object(p_name);  } +void Engine::register_singleton(const StringName &p_name, Object *p_object) { +	ERR_FAIL_COND_MSG(has_singleton(p_name), "Singleton already registered: " + String(p_name)); +	ERR_FAIL_COND_MSG(p_name.operator String().is_valid_identifier(), "Singleton name is not a valid identifier: " + String(p_name)); +	::Engine::Singleton s; +	s.class_name = p_name; +	s.name = p_name; +	s.ptr = p_object; +	s.user_created = true; +	::Engine::get_singleton()->add_singleton(s); +	; +} +void Engine::unregister_singleton(const StringName &p_name) { +	ERR_FAIL_COND_MSG(!has_singleton(p_name), "Attempt to remove unregisteres singleton: " + String(p_name)); +	ERR_FAIL_COND_MSG(!::Engine::get_singleton()->is_singleton_user_created(p_name), "Attempt to remove non-user created singleton: " + String(p_name)); +	::Engine::get_singleton()->remove_singleton(p_name); +} + +Vector<String> Engine::get_singleton_list() const { +	List<::Engine::Singleton> singletons; +	::Engine::get_singleton()->get_singletons(&singletons); +	Vector<String> ret; +	for (List<::Engine::Singleton>::Element *E = singletons.front(); E; E = E->next()) { +		ret.push_back(E->get().name); +	} +	return ret; +} +  void Engine::set_editor_hint(bool p_enabled) {  	::Engine::get_singleton()->set_editor_hint(p_enabled);  } @@ -2220,6 +2247,10 @@ void Engine::_bind_methods() {  	ClassDB::bind_method(D_METHOD("has_singleton", "name"), &Engine::has_singleton);  	ClassDB::bind_method(D_METHOD("get_singleton", "name"), &Engine::get_singleton_object); +	ClassDB::bind_method(D_METHOD("register_singleton", "name", "instance"), &Engine::register_singleton); +	ClassDB::bind_method(D_METHOD("unregister_singleton", "name"), &Engine::unregister_singleton); +	ClassDB::bind_method(D_METHOD("get_singleton_list"), &Engine::get_singleton_list); +  	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); diff --git a/core/core_bind.h b/core/core_bind.h index 1dbe49f418..a6fac63edd 100644 --- a/core/core_bind.h +++ b/core/core_bind.h @@ -639,8 +639,11 @@ public:  	bool is_in_physics_frame() const; -	bool has_singleton(const String &p_name) const; -	Object *get_singleton_object(const String &p_name) const; +	bool has_singleton(const StringName &p_name) const; +	Object *get_singleton_object(const StringName &p_name) const; +	void register_singleton(const StringName &p_name, Object *p_object); +	void unregister_singleton(const StringName &p_name); +	Vector<String> get_singleton_list() const;  	void set_editor_hint(bool p_enabled);  	bool is_editor_hint() const; diff --git a/doc/classes/Engine.xml b/doc/classes/Engine.xml index 886a18900e..8b399f64c9 100644 --- a/doc/classes/Engine.xml +++ b/doc/classes/Engine.xml @@ -84,11 +84,16 @@  		</method>  		<method name="get_singleton" qualifiers="const">  			<return type="Object" /> -			<argument index="0" name="name" type="String" /> +			<argument index="0" name="name" type="StringName" />  			<description>  				Returns a global singleton with given [code]name[/code]. Often used for plugins, e.g. GodotPayments.  			</description>  		</method> +		<method name="get_singleton_list" qualifiers="const"> +			<return type="PackedStringArray" /> +			<description> +			</description> +		</method>  		<method name="get_version_info" qualifiers="const">  			<return type="Dictionary" />  			<description> @@ -125,7 +130,7 @@  		</method>  		<method name="has_singleton" qualifiers="const">  			<return type="bool" /> -			<argument index="0" name="name" type="String" /> +			<argument index="0" name="name" type="StringName" />  			<description>  				Returns [code]true[/code] if a singleton with given [code]name[/code] exists in global scope.  			</description> @@ -136,6 +141,19 @@  				Returns [code]true[/code] if the game is inside the fixed process and physics phase of the game loop.  			</description>  		</method> +		<method name="register_singleton"> +			<return type="void" /> +			<argument index="0" name="name" type="StringName" /> +			<argument index="1" name="instance" type="Object" /> +			<description> +			</description> +		</method> +		<method name="unregister_singleton"> +			<return type="void" /> +			<argument index="0" name="name" type="StringName" /> +			<description> +			</description> +		</method>  	</methods>  	<members>  		<member name="editor_hint" type="bool" setter="set_editor_hint" getter="is_editor_hint" default="true">  |