Browse Source

Add a instance callback for extensions

This sends the Godot object instance back to the extension so they can
keep a pointer for function calls.

Incidentally fix argument order on instance bindings callback for free()
George Marques 4 years ago
parent
commit
626c0b6905
4 changed files with 8 additions and 5 deletions
  1. 4 2
      core/object/class_db.cpp
  2. 1 1
      core/object/class_db.h
  3. 2 2
      core/object/object.cpp
  4. 1 0
      core/object/object.h

+ 4 - 2
core/object/class_db.cpp

@@ -505,11 +505,12 @@ thread_local bool initializing_with_extension = false;
 thread_local ObjectNativeExtension *initializing_extension = nullptr;
 thread_local GDExtensionClassInstancePtr initializing_extension_instance = nullptr;
 
-void ClassDB::instance_get_native_extension_data(ObjectNativeExtension **r_extension, GDExtensionClassInstancePtr *r_extension_instance) {
+void ClassDB::instance_get_native_extension_data(ObjectNativeExtension **r_extension, GDExtensionClassInstancePtr *r_extension_instance, Object *p_base) {
 	if (initializing_with_extension) {
 		*r_extension = initializing_extension;
 		*r_extension_instance = initializing_extension_instance;
 		initializing_with_extension = false;
+		initializing_extension->set_object_instance(*r_extension_instance, p_base);
 	} else {
 		*r_extension = nullptr;
 		*r_extension_instance = nullptr;
@@ -1592,7 +1593,7 @@ void ClassDB::register_extension_class(ObjectNativeExtension *p_extension) {
 	GLOBAL_LOCK_FUNCTION;
 
 	ERR_FAIL_COND_MSG(classes.has(p_extension->class_name), "Class already registered: " + String(p_extension->class_name));
-	ERR_FAIL_COND_MSG(classes.has(p_extension->parent_class_name), "Parent class name for extension class not found: " + String(p_extension->parent_class_name));
+	ERR_FAIL_COND_MSG(!classes.has(p_extension->parent_class_name), "Parent class name for extension class not found: " + String(p_extension->parent_class_name));
 
 	ClassInfo *parent = classes.getptr(p_extension->parent_class_name);
 
@@ -1604,6 +1605,7 @@ void ClassDB::register_extension_class(ObjectNativeExtension *p_extension) {
 	c.inherits = parent->name;
 	c.class_ptr = parent->class_ptr;
 	c.inherits_ptr = parent;
+	c.exposed = true;
 
 	classes[p_extension->class_name] = c;
 }

+ 1 - 1
core/object/class_db.h

@@ -233,7 +233,7 @@ public:
 	static bool is_parent_class(const StringName &p_class, const StringName &p_inherits);
 	static bool can_instantiate(const StringName &p_class);
 	static Object *instantiate(const StringName &p_class);
-	static void instance_get_native_extension_data(ObjectNativeExtension **r_extension, GDExtensionClassInstancePtr *r_extension_instance);
+	static void instance_get_native_extension_data(ObjectNativeExtension **r_extension, GDExtensionClassInstancePtr *r_extension_instance, Object *p_base);
 
 	static APIType get_api_type(const StringName &p_class);
 

+ 2 - 2
core/object/object.cpp

@@ -1815,7 +1815,7 @@ void Object::_construct_object(bool p_reference) {
 	type_is_reference = p_reference;
 	_instance_id = ObjectDB::add_instance(this);
 
-	ClassDB::instance_get_native_extension_data(&_extension, &_extension_instance);
+	ClassDB::instance_get_native_extension_data(&_extension, &_extension_instance, this);
 
 #ifdef DEBUG_ENABLED
 	_lock_index.init(1);
@@ -1876,7 +1876,7 @@ Object::~Object() {
 	if (_instance_bindings != nullptr) {
 		for (uint32_t i = 0; i < _instance_binding_count; i++) {
 			if (_instance_bindings[i].free_callback) {
-				_instance_bindings[i].free_callback(_instance_bindings[i].token, _instance_bindings[i].binding, this);
+				_instance_bindings[i].free_callback(_instance_bindings[i].token, this, _instance_bindings[i].binding);
 			}
 		}
 		memfree(_instance_bindings);

+ 1 - 0
core/object/object.h

@@ -272,6 +272,7 @@ struct ObjectNativeExtension {
 
 	GDNativeExtensionClassCreateInstance create_instance;
 	GDNativeExtensionClassFreeInstance free_instance;
+	GDNativeExtensionClassObjectInstance set_object_instance;
 	GDNativeExtensionClassGetVirtual get_virtual;
 };