fix cast_to

pull/155/head
karroffel 2018-04-06 01:39:35 +02:00
parent b3d705c898
commit d420613bd2
3 changed files with 25 additions and 15 deletions

View File

@ -495,7 +495,19 @@ void register_signal(String name, Args... varargs)
template<class T> template<class T>
T *Object::cast_to(const Object *obj) T *Object::cast_to(const Object *obj)
{ {
if (godot::_TagDB::is_type_compatible(T::___get_type_tag(), obj->_type_tag)) { const void *have_tag = godot::nativescript_1_1_api->godot_nativescript_get_type_tag(obj->_owner);
if (have_tag) {
if (!godot::_TagDB::is_type_known(have_tag)) {
have_tag = nullptr;
}
}
if (!have_tag) {
have_tag = obj->_type_tag;
}
if (godot::_TagDB::is_type_compatible(T::___get_type_tag(), have_tag)) {
return (T::___CLASS_IS_SCRIPT) ? godot::as<T>(obj) : (T *) obj; return (T::___CLASS_IS_SCRIPT) ? godot::as<T>(obj) : (T *) obj;
} else { } else {
return nullptr; return nullptr;

View File

@ -6,8 +6,8 @@ namespace godot {
namespace _TagDB { namespace _TagDB {
void register_type(const void *type_tag, const void *base_type_tag); void register_type(const void *type_tag, const void *base_type_tag);
bool is_type_known(const void *type_tag);
void register_global_type(const char *name, const void *type_tag, const void *base_type_tag); void register_global_type(const char *name, const void *type_tag, const void *base_type_tag);
bool is_type_compatible(const void *type_tag, const void *base_type_tag); bool is_type_compatible(const void *type_tag, const void *base_type_tag);
} }

View File

@ -15,6 +15,11 @@ void register_type(const void *type_tag, const void *base_type_tag)
parent_to[type_tag] = base_type_tag; parent_to[type_tag] = base_type_tag;
} }
bool is_type_known(const void *type_tag)
{
return parent_to.find(type_tag) != parent_to.end();
}
void register_global_type(const char *name, const void *type_tag, const void *base_type_tag) void register_global_type(const char *name, const void *type_tag, const void *base_type_tag)
{ {
@ -23,25 +28,18 @@ void register_global_type(const char *name, const void *type_tag, const void *ba
register_type(type_tag, base_type_tag); register_type(type_tag, base_type_tag);
} }
bool is_type_compatible(const void *type_tag, const void *base_type_tag) bool is_type_compatible(const void *ask_tag, const void *have_tag)
{ {
if (type_tag == nullptr || base_type_tag == nullptr)
if (have_tag == nullptr)
return false; return false;
if (type_tag == base_type_tag) const void *tag = have_tag;
while (tag != nullptr) {
if (tag == ask_tag)
return true; return true;
const void *tag = type_tag;
while (true) {
if (tag == base_type_tag) {
return true;
}
if (tag == nullptr) {
return false;
}
tag = parent_to[tag]; tag = parent_to[tag];
} }