use typeid() for type tags now
parent
1a2afca8af
commit
38da87fc0b
|
@ -28,7 +28,7 @@ if target_platform == 'linux':
|
||||||
if ARGUMENTS.get('use_llvm', 'no') == 'yes':
|
if ARGUMENTS.get('use_llvm', 'no') == 'yes':
|
||||||
env['CXX'] = 'clang++'
|
env['CXX'] = 'clang++'
|
||||||
|
|
||||||
env.Append(CCFLAGS = [ '-fPIC', '-g', '-std=c++14', '-Wwrite-strings' ])
|
env.Append(CCFLAGS = [ '-fPIC', '-g', '-Og', '-std=c++14', '-Wwrite-strings' ])
|
||||||
env.Append(LINKFLAGS = [ '-Wl,-R,\'$$ORIGIN\'' ])
|
env.Append(LINKFLAGS = [ '-Wl,-R,\'$$ORIGIN\'' ])
|
||||||
|
|
||||||
if target == 'debug':
|
if target == 'debug':
|
||||||
|
|
|
@ -139,9 +139,6 @@ def generate_class_header(used_classes, c):
|
||||||
source.append("public:")
|
source.append("public:")
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
source.append("\tstatic void *___get_type_tag();")
|
|
||||||
source.append("\tstatic void *___get_base_type_tag();")
|
|
||||||
|
|
||||||
|
|
||||||
if c["singleton"]:
|
if c["singleton"]:
|
||||||
source.append("\tstatic inline " + class_name + " *get_singleton()")
|
source.append("\tstatic inline " + class_name + " *get_singleton()")
|
||||||
|
@ -325,21 +322,6 @@ def generate_class_implementation(icalls, used_classes, c):
|
||||||
source.append("")
|
source.append("")
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
source.append("void *" + class_name + "::___get_type_tag()")
|
|
||||||
source.append("{")
|
|
||||||
source.append("\treturn (void *) &" + class_name + "::___get_type_tag;")
|
|
||||||
source.append("}")
|
|
||||||
source.append("")
|
|
||||||
|
|
||||||
source.append("void *" + class_name + "::___get_base_type_tag()")
|
|
||||||
source.append("{")
|
|
||||||
if c["base_class"] != "":
|
|
||||||
source.append("\treturn (void *) &" + strip_name(c["base_class"]) + "::___get_type_tag;")
|
|
||||||
else:
|
|
||||||
source.append("\treturn (void *) nullptr;")
|
|
||||||
source.append("}")
|
|
||||||
source.append("")
|
|
||||||
|
|
||||||
if c["singleton"]:
|
if c["singleton"]:
|
||||||
source.append("" + class_name + " *" + class_name + "::_singleton = NULL;")
|
source.append("" + class_name + " *" + class_name + "::_singleton = NULL;")
|
||||||
source.append("")
|
source.append("")
|
||||||
|
@ -669,7 +651,8 @@ def generate_type_registry(classes):
|
||||||
source = []
|
source = []
|
||||||
|
|
||||||
source.append("#include \"TagDB.hpp\"")
|
source.append("#include \"TagDB.hpp\"")
|
||||||
source.append("")
|
source.append("#include <typeinfo>")
|
||||||
|
source.append("\n")
|
||||||
|
|
||||||
for c in classes:
|
for c in classes:
|
||||||
source.append("#include <" + strip_name(c["name"]) + ".hpp>")
|
source.append("#include <" + strip_name(c["name"]) + ".hpp>")
|
||||||
|
@ -684,7 +667,16 @@ def generate_type_registry(classes):
|
||||||
|
|
||||||
for c in classes:
|
for c in classes:
|
||||||
class_name = strip_name(c["name"])
|
class_name = strip_name(c["name"])
|
||||||
source.append("\tgodot::_TagDB::register_global_type(\"" + class_name + "\", " + class_name + "::___get_type_tag(), " + class_name + "::___get_base_type_tag());")
|
base_class_name = strip_name(c["base_class"])
|
||||||
|
|
||||||
|
class_type_hash = "typeid(" + class_name + ").hash_code()"
|
||||||
|
|
||||||
|
base_class_type_hash = "typeid(" + base_class_name + ").hash_code()"
|
||||||
|
|
||||||
|
if base_class_name == "":
|
||||||
|
base_class_type_hash = "0"
|
||||||
|
|
||||||
|
source.append("\tgodot::_TagDB::register_global_type(\"" + class_name + "\", " + class_type_hash + ", " + base_class_type_hash + ");")
|
||||||
|
|
||||||
source.append("}")
|
source.append("}")
|
||||||
|
|
||||||
|
@ -751,6 +743,8 @@ def get_used_classes(c):
|
||||||
|
|
||||||
|
|
||||||
def strip_name(name):
|
def strip_name(name):
|
||||||
|
if len(name) == 0:
|
||||||
|
return name
|
||||||
if name[0] == '_':
|
if name[0] == '_':
|
||||||
return name[1:]
|
return name[1:]
|
||||||
return name
|
return name
|
||||||
|
|
|
@ -42,8 +42,6 @@ T *get_wrapper(godot_object *obj)
|
||||||
inline static Name *_new() { godot::NativeScript *script = godot::NativeScript::_new(); script->set_library(godot::get_wrapper<godot::GDNativeLibrary>((godot_object *) godot::gdnlib)); script->set_class_name(#Name); Name *instance = godot::as<Name>(script->new_()); return instance; } \
|
inline static Name *_new() { godot::NativeScript *script = godot::NativeScript::_new(); script->set_library(godot::get_wrapper<godot::GDNativeLibrary>((godot_object *) godot::gdnlib)); script->set_class_name(#Name); Name *instance = godot::as<Name>(script->new_()); return instance; } \
|
||||||
inline static const char *___get_base_type_name() { return Base::___get_class_name(); } \
|
inline static const char *___get_base_type_name() { return Base::___get_class_name(); } \
|
||||||
inline static Object *___get_from_variant(godot::Variant a) { return (godot::Object *) godot::as<Name>(godot::Object::___get_from_variant(a)); } \
|
inline static Object *___get_from_variant(godot::Variant a) { return (godot::Object *) godot::as<Name>(godot::Object::___get_from_variant(a)); } \
|
||||||
inline static void *___get_type_tag() { return (void *) &Name::___get_type_tag; } \
|
|
||||||
inline static void *___get_base_type_tag() { return (void *) &Base::___get_type_tag; } \
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
#define GODOT_SUBCLASS(Name, Base) \
|
#define GODOT_SUBCLASS(Name, Base) \
|
||||||
|
@ -87,7 +85,7 @@ void *_godot_class_instance_func(godot_object *p, void *method_data)
|
||||||
{
|
{
|
||||||
T *d = new T();
|
T *d = new T();
|
||||||
d->_owner = p;
|
d->_owner = p;
|
||||||
d->_type_tag = T::___get_type_tag();
|
d->_type_tag = typeid(T).hash_code();
|
||||||
d->_init();
|
d->_init();
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
@ -109,10 +107,10 @@ void register_class()
|
||||||
godot_instance_destroy_func destroy = {};
|
godot_instance_destroy_func destroy = {};
|
||||||
destroy.destroy_func = _godot_class_destroy_func<T>;
|
destroy.destroy_func = _godot_class_destroy_func<T>;
|
||||||
|
|
||||||
_TagDB::register_type(T::___get_type_tag(), T::___get_base_type_tag());
|
_TagDB::register_type(typeid(T).hash_code(), typeid(T).hash_code());
|
||||||
|
|
||||||
godot::nativescript_api->godot_nativescript_register_class(godot::_RegisterState::nativescript_handle, T::___get_type_name(), T::___get_base_type_name(), create, destroy);
|
godot::nativescript_api->godot_nativescript_register_class(godot::_RegisterState::nativescript_handle, T::___get_type_name(), T::___get_base_type_name(), create, destroy);
|
||||||
godot::nativescript_1_1_api->godot_nativescript_set_type_tag(godot::_RegisterState::nativescript_handle, T::___get_type_name(), T::___get_type_tag());
|
godot::nativescript_1_1_api->godot_nativescript_set_type_tag(godot::_RegisterState::nativescript_handle, T::___get_type_name(), (const void *) typeid(T).hash_code());
|
||||||
T::_register_methods();
|
T::_register_methods();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -495,11 +493,11 @@ 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)
|
||||||
{
|
{
|
||||||
const void *have_tag = godot::nativescript_1_1_api->godot_nativescript_get_type_tag(obj->_owner);
|
size_t have_tag = (size_t) godot::nativescript_1_1_api->godot_nativescript_get_type_tag(obj->_owner);
|
||||||
|
|
||||||
if (have_tag) {
|
if (have_tag) {
|
||||||
if (!godot::_TagDB::is_type_known(have_tag)) {
|
if (!godot::_TagDB::is_type_known((size_t) have_tag)) {
|
||||||
have_tag = nullptr;
|
have_tag = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -507,7 +505,7 @@ T *Object::cast_to(const Object *obj)
|
||||||
have_tag = obj->_type_tag;
|
have_tag = obj->_type_tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (godot::_TagDB::is_type_compatible(T::___get_type_tag(), have_tag)) {
|
if (godot::_TagDB::is_type_compatible(typeid(T).hash_code(), 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;
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
#ifndef TAGDB_HPP
|
#ifndef TAGDB_HPP
|
||||||
#define TAGDB_HPP
|
#define TAGDB_HPP
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
namespace godot {
|
namespace godot {
|
||||||
|
|
||||||
namespace _TagDB {
|
namespace _TagDB {
|
||||||
|
|
||||||
void register_type(const void *type_tag, const void *base_type_tag);
|
void register_type(size_t type_tag, size_t base_type_tag);
|
||||||
bool is_type_known(const void *type_tag);
|
bool is_type_known(size_t 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, size_t type_tag, size_t base_type_tag);
|
||||||
bool is_type_compatible(const void *type_tag, const void *base_type_tag);
|
bool is_type_compatible(size_t type_tag, size_t base_type_tag);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace godot {
|
||||||
class _Wrapped {
|
class _Wrapped {
|
||||||
public:
|
public:
|
||||||
godot_object *_owner;
|
godot_object *_owner;
|
||||||
const void *_type_tag;
|
size_t _type_tag;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ static GDCALLINGCONV void *wrapper_create(void *data, const void *type_tag, godo
|
||||||
if (!wrapper_memory)
|
if (!wrapper_memory)
|
||||||
return NULL;
|
return NULL;
|
||||||
wrapper_memory->_owner = instance;
|
wrapper_memory->_owner = instance;
|
||||||
wrapper_memory->_type_tag = type_tag;
|
wrapper_memory->_type_tag = (size_t) type_tag;
|
||||||
|
|
||||||
return (void *) wrapper_memory;
|
return (void *) wrapper_memory;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,35 +8,38 @@ namespace godot {
|
||||||
|
|
||||||
namespace _TagDB {
|
namespace _TagDB {
|
||||||
|
|
||||||
std::unordered_map<const void *, const void *> parent_to;
|
std::unordered_map<size_t, size_t> parent_to;
|
||||||
|
|
||||||
void register_type(const void *type_tag, const void *base_type_tag)
|
void register_type(size_t type_tag, size_t base_type_tag)
|
||||||
{
|
{
|
||||||
|
if (type_tag == base_type_tag) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
parent_to[type_tag] = base_type_tag;
|
parent_to[type_tag] = base_type_tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_type_known(const void *type_tag)
|
bool is_type_known(size_t type_tag)
|
||||||
{
|
{
|
||||||
return parent_to.find(type_tag) != parent_to.end();
|
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, size_t type_tag, size_t base_type_tag)
|
||||||
{
|
{
|
||||||
|
|
||||||
godot::nativescript_1_1_api->godot_nativescript_set_global_type_tag(godot::_RegisterState::language_index, name, type_tag);
|
godot::nativescript_1_1_api->godot_nativescript_set_global_type_tag(godot::_RegisterState::language_index, name, (const void *) type_tag);
|
||||||
|
|
||||||
register_type(type_tag, base_type_tag);
|
register_type(type_tag, base_type_tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_type_compatible(const void *ask_tag, const void *have_tag)
|
bool is_type_compatible(size_t ask_tag, size_t have_tag)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (have_tag == nullptr)
|
if (have_tag == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const void *tag = have_tag;
|
size_t tag = have_tag;
|
||||||
|
|
||||||
while (tag != nullptr) {
|
while (tag != 0) {
|
||||||
if (tag == ask_tag)
|
if (tag == ask_tag)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue