summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/extension/gdextension.cpp1
-rw-r--r--core/extension/gdextension_interface.cpp14
-rw-r--r--core/extension/gdextension_interface.h13
-rw-r--r--core/object/object.cpp2
-rw-r--r--core/object/object.h14
5 files changed, 43 insertions, 1 deletions
diff --git a/core/extension/gdextension.cpp b/core/extension/gdextension.cpp
index 942ec95678..a9be7f2e9b 100644
--- a/core/extension/gdextension.cpp
+++ b/core/extension/gdextension.cpp
@@ -314,6 +314,7 @@ void GDExtension::_register_extension_class(GDExtensionClassLibraryPtr p_library
parent_extension->gdextension.children.push_back(&extension->gdextension);
}
+ extension->gdextension.library = self;
extension->gdextension.parent_class_name = parent_class_name;
extension->gdextension.class_name = class_name;
extension->gdextension.editor_class = self->level_initialized == INITIALIZATION_LEVEL_EDITOR;
diff --git a/core/extension/gdextension_interface.cpp b/core/extension/gdextension_interface.cpp
index c661bfa8c7..12ef1772e3 100644
--- a/core/extension/gdextension_interface.cpp
+++ b/core/extension/gdextension_interface.cpp
@@ -992,6 +992,19 @@ static GDExtensionObjectPtr gdextension_object_get_instance_from_id(GDObjectInst
return (GDExtensionObjectPtr)ObjectDB::get_instance(ObjectID(p_instance_id));
}
+static GDExtensionBool gdextension_object_get_class_name(GDExtensionConstObjectPtr p_object, GDExtensionClassLibraryPtr p_library, GDExtensionUninitializedStringNamePtr r_class_name) {
+ if (!p_object) {
+ return false;
+ }
+ const Object *o = (const Object *)p_object;
+
+ memnew_placement(r_class_name, StringName);
+ StringName *class_name = reinterpret_cast<StringName *>(r_class_name);
+ *class_name = o->get_class_name_for_extension((GDExtension *)p_library);
+
+ return true;
+}
+
static GDExtensionObjectPtr gdextension_object_cast_to(GDExtensionConstObjectPtr p_object, void *p_class_tag) {
if (!p_object) {
return nullptr;
@@ -1176,6 +1189,7 @@ void gdextension_setup_interface() {
REGISTER_INTERFACE_FUNC(object_get_instance_binding);
REGISTER_INTERFACE_FUNC(object_set_instance_binding);
REGISTER_INTERFACE_FUNC(object_set_instance);
+ REGISTER_INTERFACE_FUNC(object_get_class_name);
REGISTER_INTERFACE_FUNC(object_cast_to);
REGISTER_INTERFACE_FUNC(object_get_instance_from_id);
REGISTER_INTERFACE_FUNC(object_get_instance_id);
diff --git a/core/extension/gdextension_interface.h b/core/extension/gdextension_interface.h
index 4e4f300f5d..a5ea3918df 100644
--- a/core/extension/gdextension_interface.h
+++ b/core/extension/gdextension_interface.h
@@ -1902,6 +1902,19 @@ typedef void (*GDExtensionInterfaceObjectSetInstanceBinding)(GDExtensionObjectPt
typedef void (*GDExtensionInterfaceObjectSetInstance)(GDExtensionObjectPtr p_o, GDExtensionConstStringNamePtr p_classname, GDExtensionClassInstancePtr p_instance); /* p_classname should be a registered extension class and should extend the p_o object's class. */
/**
+ * @name object_get_class_name
+ *
+ * Gets the class name of an Object.
+ *
+ * @param p_object A pointer to the Object.
+ * @param p_library A pointer the library received by the GDExtension's entry point function.
+ * @param r_class_name A pointer to a String to receive the class name.
+ *
+ * @return true if successful in getting the class name; otherwise false.
+ */
+typedef GDExtensionBool (*GDExtensionInterfaceObjectGetClassName)(GDExtensionConstObjectPtr p_object, GDExtensionClassLibraryPtr p_library, GDExtensionUninitializedStringNamePtr r_class_name);
+
+/**
* @name object_cast_to
*
* Casts an Object to a different type.
diff --git a/core/object/object.cpp b/core/object/object.cpp
index 5a34328ec4..18e7f65a97 100644
--- a/core/object/object.cpp
+++ b/core/object/object.cpp
@@ -1739,7 +1739,7 @@ void *Object::get_instance_binding(void *p_token, const GDExtensionInstanceBindi
break;
}
}
- if (unlikely(!binding)) {
+ if (unlikely(!binding && p_callbacks)) {
uint32_t current_size = next_power_of_2(_instance_binding_count);
uint32_t new_size = next_power_of_2(_instance_binding_count + 1);
diff --git a/core/object/object.h b/core/object/object.h
index c4d287a71c..6f626b0ed0 100644
--- a/core/object/object.h
+++ b/core/object/object.h
@@ -304,8 +304,10 @@ struct MethodInfo {
// API used to extend in GDExtension and other C compatible compiled languages.
class MethodBind;
+class GDExtension;
struct ObjectGDExtension {
+ GDExtension *library = nullptr;
ObjectGDExtension *parent = nullptr;
List<ObjectGDExtension *> children;
StringName parent_class_name;
@@ -798,6 +800,18 @@ public:
return *_class_name_ptr;
}
+ _FORCE_INLINE_ const StringName &get_class_name_for_extension(const GDExtension *p_library) const {
+ // Only return the class name per the extension if it matches the given p_library.
+ if (_extension && _extension->library == p_library) {
+ return _extension->class_name;
+ }
+ // Otherwise, return the name of the built-in class.
+ if (unlikely(!_class_name_ptr)) {
+ return *_get_class_namev();
+ }
+ return *_class_name_ptr;
+ }
+
/* IAPI */
void set(const StringName &p_name, const Variant &p_value, bool *r_valid = nullptr);