From 3056c4bd5acc4b5eda71303bf349e0d4f94a89c8 Mon Sep 17 00:00:00 2001 From: sheepandshepherd Date: Mon, 21 Oct 2019 17:44:56 +0200 Subject: [PATCH] Expose cast_to to GDNative for dynamic casts --- core/class_db.h | 4 ++++ modules/gdnative/gdnative/gdnative.cpp | 13 +++++++++++++ modules/gdnative/gdnative_api.json | 15 +++++++++++++++ modules/gdnative/include/gdnative/gdnative.h | 4 ++++ 4 files changed, 36 insertions(+) diff --git a/core/class_db.h b/core/class_db.h index 4129a741474..54f3e9e1072 100644 --- a/core/class_db.h +++ b/core/class_db.h @@ -114,6 +114,7 @@ public: APIType api; ClassInfo *inherits_ptr; + void *class_ptr; HashMap method_map; HashMap constant_map; HashMap > enum_map; @@ -177,6 +178,7 @@ public: ERR_FAIL_COND(!t); t->creation_func = &creator; 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->exposed = true; + t->class_ptr = T::get_class_ptr_static(); T::register_custom_data_to_otdb(); } diff --git a/modules/gdnative/gdnative/gdnative.cpp b/modules/gdnative/gdnative/gdnative.cpp index 174ef14ec23..6ef1f2f4b95 100644 --- a/modules/gdnative/gdnative/gdnative.cpp +++ b/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 diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json index 9e5295a9369..7e2ca49f8d3 100644 --- a/modules/gdnative/gdnative_api.json +++ b/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"] + ] } ] }, diff --git a/modules/gdnative/include/gdnative/gdnative.h b/modules/gdnative/include/gdnative/gdnative.h index 5a6333e814d..2fe59b8a73e 100644 --- a/modules/gdnative/include/gdnative/gdnative.h +++ b/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