Browse Source

Merge pull request #34688 from sheepandshepherd/gdnative_class_ptr

Expose is_class_ptr to GDNative for dynamic casts
Rémi Verschelde 5 years ago
parent
commit
9d3424f61d

+ 4 - 0
core/class_db.h

@@ -114,6 +114,7 @@ public:
 
 		APIType api;
 		ClassInfo *inherits_ptr;
+		void *class_ptr;
 		HashMap<StringName, MethodBind *> method_map;
 		HashMap<StringName, int> constant_map;
 		HashMap<StringName, List<StringName> > enum_map;
@@ -177,6 +178,7 @@ public:
 		ERR_FAIL_COND(!t);
 		t->creation_func = &creator<T>;
 		t->exposed = true;
+		t->class_ptr = T::get_class_ptr_static();
 		T::register_custom_data_to_otdb();
 	}
 
@@ -188,6 +190,7 @@ public:
 		ClassInfo *t = classes.getptr(T::get_class_static());
 		ERR_FAIL_COND(!t);
 		t->exposed = true;
+		t->class_ptr = T::get_class_ptr_static();
 		//nothing
 	}
 
@@ -206,6 +209,7 @@ public:
 		ERR_FAIL_COND(!t);
 		t->creation_func = &_create_ptr_func<T>;
 		t->exposed = true;
+		t->class_ptr = T::get_class_ptr_static();
 		T::register_custom_data_to_otdb();
 	}
 

+ 13 - 0
modules/gdnative/gdnative/gdnative.cpp

@@ -170,6 +170,19 @@ bool GDAPI godot_is_instance_valid(const godot_object *p_object) {
 	return ObjectDB::instance_validate((Object *)p_object);
 }
 
+void *godot_get_class_tag(const godot_string_name *p_class) {
+	StringName class_name = *(StringName *)p_class;
+	ClassDB::ClassInfo *class_info = ClassDB::classes.getptr(class_name);
+	return class_info ? class_info->class_ptr : NULL;
+}
+
+godot_object *godot_object_cast_to(const godot_object *p_object, void *p_class_tag) {
+	if (!p_object) return NULL;
+	Object *o = (Object *)p_object;
+
+	return o->is_class_ptr(p_class_tag) ? (godot_object *)o : NULL;
+}
+
 #ifdef __cplusplus
 }
 #endif

+ 15 - 0
modules/gdnative/gdnative_api.json

@@ -140,6 +140,21 @@
             "arguments": [
               ["const godot_pool_color_array *", "p_self"]
             ]
+          },
+          {
+            "name": "godot_get_class_tag",
+            "return_type": "void *",
+            "arguments": [
+              ["const godot_string_name *", "p_class"]
+            ]
+          },
+          {
+            "name": "godot_object_cast_to",
+            "return_type": "godot_object *",
+            "arguments": [
+              ["const godot_object *", "p_object"],
+              ["void *", "p_class_tag"]
+            ]
           }
         ]
       },

+ 4 - 0
modules/gdnative/include/gdnative/gdnative.h

@@ -286,6 +286,10 @@ void GDAPI godot_print(const godot_string *p_message);
 
 bool GDAPI godot_is_instance_valid(const godot_object *p_object);
 
+//tags used for safe dynamic casting
+void GDAPI *godot_get_class_tag(const godot_string_name *p_class);
+godot_object GDAPI *godot_object_cast_to(const godot_object *p_object, void *p_class_tag);
+
 #ifdef __cplusplus
 }
 #endif