Browse Source

Allow GDExtension to register unexposed class.

Daylily-Zeleen 2 years ago
parent
commit
41ffe5461f

+ 2 - 0
core/extension/gdextension.cpp

@@ -286,6 +286,7 @@ void GDExtension::_register_extension_class(GDExtensionClassLibraryPtr p_library
 	const GDExtensionClassCreationInfo2 class_info2 = {
 		p_extension_funcs->is_virtual, // GDExtensionBool is_virtual;
 		p_extension_funcs->is_abstract, // GDExtensionBool is_abstract;
+		true, // GDExtensionBool is_exposed;
 		p_extension_funcs->set_func, // GDExtensionClassSet set_func;
 		p_extension_funcs->get_func, // GDExtensionClassGet get_func;
 		p_extension_funcs->get_property_list_func, // GDExtensionClassGetPropertyList get_property_list_func;
@@ -352,6 +353,7 @@ void GDExtension::_register_extension_class_internal(GDExtensionClassLibraryPtr
 	extension->gdextension.editor_class = self->level_initialized == INITIALIZATION_LEVEL_EDITOR;
 	extension->gdextension.is_virtual = p_extension_funcs->is_virtual;
 	extension->gdextension.is_abstract = p_extension_funcs->is_abstract;
+	extension->gdextension.is_exposed = p_extension_funcs->is_exposed;
 	extension->gdextension.set = p_extension_funcs->set_func;
 	extension->gdextension.get = p_extension_funcs->get_func;
 	extension->gdextension.get_property_list = p_extension_funcs->get_property_list_func;

+ 1 - 0
core/extension/gdextension_interface.h

@@ -291,6 +291,7 @@ typedef struct {
 typedef struct {
 	GDExtensionBool is_virtual;
 	GDExtensionBool is_abstract;
+	GDExtensionBool is_exposed;
 	GDExtensionClassSet set_func;
 	GDExtensionClassGet get_func;
 	GDExtensionClassGetPropertyList get_property_list_func;

+ 8 - 1
core/object/class_db.cpp

@@ -1674,7 +1674,14 @@ void ClassDB::register_extension_class(ObjectGDExtension *p_extension) {
 	c.inherits = parent->name;
 	c.class_ptr = parent->class_ptr;
 	c.inherits_ptr = parent;
-	c.exposed = true;
+	c.exposed = p_extension->is_exposed;
+	if (c.exposed) {
+		// The parent classes should be exposed if it has an exposed child class.
+		while (parent && !parent->exposed) {
+			parent->exposed = true;
+			parent = classes.getptr(parent->name);
+		}
+	}
 
 	classes[p_extension->class_name] = c;
 }

+ 19 - 0
core/object/class_db.h

@@ -212,6 +212,21 @@ public:
 		//nothing
 	}
 
+	template <class T>
+	static void register_internal_class() {
+		GLOBAL_LOCK_FUNCTION;
+		static_assert(TypesAreSame<typename T::self_type, T>::value, "Class not declared properly, please use GDCLASS.");
+		T::initialize_class();
+		ClassInfo *t = classes.getptr(T::get_class_static());
+		ERR_FAIL_COND(!t);
+		t->creation_func = &creator<T>;
+		t->exposed = false;
+		t->is_virtual = false;
+		t->class_ptr = T::get_class_ptr_static();
+		t->api = current_api;
+		T::register_custom_data_to_otdb();
+	}
+
 	static void register_extension_class(ObjectGDExtension *p_extension);
 	static void unregister_extension_class(const StringName &p_class);
 
@@ -483,6 +498,10 @@ _FORCE_INLINE_ Vector<Error> errarray(P... p_args) {
 	if (m_class::_class_is_enabled) {                  \
 		::ClassDB::register_abstract_class<m_class>(); \
 	}
+#define GDREGISTER_INTERNAL_CLASS(m_class)             \
+	if (m_class::_class_is_enabled) {                  \
+		::ClassDB::register_internal_class<m_class>(); \
+	}
 
 #define GDREGISTER_NATIVE_STRUCT(m_class, m_code) ClassDB::register_native_struct(#m_class, m_code, sizeof(m_class))
 

+ 1 - 0
core/object/object.h

@@ -315,6 +315,7 @@ struct ObjectGDExtension {
 	bool editor_class = false;
 	bool is_virtual = false;
 	bool is_abstract = false;
+	bool is_exposed = true;
 	GDExtensionClassSet set;
 	GDExtensionClassGet get;
 	GDExtensionClassGetPropertyList get_property_list;

+ 4 - 0
editor/create_dialog.cpp

@@ -135,6 +135,10 @@ bool CreateDialog::_should_hide_type(const String &p_type) const {
 			return true; // Wrong inheritance.
 		}
 
+		if (!ClassDB::is_class_exposed(p_type)) {
+			return true; // Unexposed types.
+		}
+
 		for (const StringName &E : type_blacklist) {
 			if (ClassDB::is_parent_class(p_type, E)) {
 				return true; // Parent type is blacklisted.