C#: Add 'Singleton' property to singleton wrapper class

This property returns an instance of the singleton.
The purpose of this is to allow using methods from the base class like 'Connect'.
Since all Godot singletons inherit Object, the type of the returned instance is Godot.Object.
This commit is contained in:
Ignacio Etcheverry 2019-02-19 22:36:27 +01:00
parent aa5b99821b
commit 9421da57ad
4 changed files with 24 additions and 2 deletions

View file

@ -97,7 +97,7 @@
#define C_METHOD_MONOARRAY_TO(m_type) C_NS_MONOMARSHAL "::mono_array_to_" #m_type
#define C_METHOD_MONOARRAY_FROM(m_type) C_NS_MONOMARSHAL "::" #m_type "_to_mono_array"
#define BINDINGS_GENERATOR_VERSION UINT32_C(6)
#define BINDINGS_GENERATOR_VERSION UINT32_C(7)
const char *BindingsGenerator::TypeInterface::DEFAULT_VARARG_C_IN = "\t%0 %1_in = %1;\n";
@ -854,6 +854,12 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
if (itype.is_singleton) {
// Add the type name and the singleton pointer as static fields
output.push_back(MEMBER_BEGIN "private static Godot.Object singleton;\n");
output.push_back(MEMBER_BEGIN "public static Godot.Object Singleton\n" INDENT2 "{\n" INDENT3
"get\n" INDENT3 "{\n" INDENT4 "if (singleton == null)\n" INDENT5
"singleton = Engine.GetSingleton(" BINDINGS_NATIVE_NAME_FIELD ");\n" INDENT4
"return singleton;\n" INDENT3 "}\n" INDENT2 "}\n");
output.push_back(MEMBER_BEGIN "private const string " BINDINGS_NATIVE_NAME_FIELD " = \"");
output.push_back(itype.name);
output.push_back("\";\n");

View file

@ -59,8 +59,16 @@ MonoType *GDMonoClass::get_mono_type() {
return get_mono_type(mono_class);
}
bool GDMonoClass::is_assignable_from(GDMonoClass *p_from) const {
uint32_t GDMonoClass::get_flags() const {
return mono_class_get_flags(mono_class);
}
bool GDMonoClass::is_static() const {
uint32_t static_class_flags = MONO_TYPE_ATTR_ABSTRACT | MONO_TYPE_ATTR_SEALED;
return (get_flags() & static_class_flags) == static_class_flags;
}
bool GDMonoClass::is_assignable_from(GDMonoClass *p_from) const {
return mono_class_is_assignable_from(mono_class, p_from->mono_class);
}

View file

@ -109,6 +109,9 @@ public:
String get_full_name() const;
MonoType *get_mono_type();
uint32_t get_flags() const;
bool is_static() const;
bool is_assignable_from(GDMonoClass *p_from) const;
_FORCE_INLINE_ StringName get_namespace() const { return namespace_name; }

View file

@ -374,6 +374,11 @@ GDMonoClass *type_get_proxy_class(const StringName &p_type) {
GDMonoClass *klass = GDMono::get_singleton()->get_core_api_assembly()->get_class(BINDINGS_NAMESPACE, class_name);
if (klass && klass->is_static()) {
// A static class means this is a Godot singleton class. If an instance is needed we use Godot.Object.
return mono_cache.class_GodotObject;
}
#ifdef TOOLS_ENABLED
if (!klass) {
return GDMono::get_singleton()->get_editor_api_assembly()->get_class(BINDINGS_NAMESPACE, class_name);