diff --git a/SConstruct b/SConstruct index bc1a3c0e..be557b8e 100644 --- a/SConstruct +++ b/SConstruct @@ -28,7 +28,7 @@ if target_platform == 'linux': if ARGUMENTS.get('use_llvm', 'no') == 'yes': 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\'' ]) if target == 'debug': diff --git a/binding_generator.py b/binding_generator.py index 61610ca0..5b9f7b8b 100644 --- a/binding_generator.py +++ b/binding_generator.py @@ -139,9 +139,6 @@ def generate_class_header(used_classes, c): source.append("public:") source.append("") - source.append("\tstatic void *___get_type_tag();") - source.append("\tstatic void *___get_base_type_tag();") - if c["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("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"]: source.append("" + class_name + " *" + class_name + "::_singleton = NULL;") source.append("") @@ -669,7 +651,8 @@ def generate_type_registry(classes): source = [] source.append("#include \"TagDB.hpp\"") - source.append("") + source.append("#include ") + source.append("\n") for c in classes: source.append("#include <" + strip_name(c["name"]) + ".hpp>") @@ -684,7 +667,16 @@ def generate_type_registry(classes): for c in classes: 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("}") @@ -751,6 +743,8 @@ def get_used_classes(c): def strip_name(name): + if len(name) == 0: + return name if name[0] == '_': return name[1:] return name diff --git a/include/core/Godot.hpp b/include/core/Godot.hpp index c7adf2f9..e336c8e9 100644 --- a/include/core/Godot.hpp +++ b/include/core/Godot.hpp @@ -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_object *) godot::gdnlib)); script->set_class_name(#Name); Name *instance = godot::as(script->new_()); return instance; } \ 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(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: #define GODOT_SUBCLASS(Name, Base) \ @@ -87,7 +85,7 @@ void *_godot_class_instance_func(godot_object *p, void *method_data) { T *d = new T(); d->_owner = p; - d->_type_tag = T::___get_type_tag(); + d->_type_tag = typeid(T).hash_code(); d->_init(); return d; } @@ -109,10 +107,10 @@ void register_class() godot_instance_destroy_func destroy = {}; destroy.destroy_func = _godot_class_destroy_func; - _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_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(); } @@ -495,11 +493,11 @@ void register_signal(String name, Args... varargs) template 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 (!godot::_TagDB::is_type_known(have_tag)) { - have_tag = nullptr; + if (!godot::_TagDB::is_type_known((size_t) have_tag)) { + have_tag = 0; } } @@ -507,7 +505,7 @@ T *Object::cast_to(const Object *obj) 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(obj) : (T *) obj; } else { return nullptr; diff --git a/include/core/TagDB.hpp b/include/core/TagDB.hpp index d76c029c..449cb3a6 100644 --- a/include/core/TagDB.hpp +++ b/include/core/TagDB.hpp @@ -1,14 +1,16 @@ #ifndef TAGDB_HPP #define TAGDB_HPP +#include + namespace godot { namespace _TagDB { -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); -bool is_type_compatible(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(size_t type_tag); +void register_global_type(const char *name, size_t type_tag, size_t base_type_tag); +bool is_type_compatible(size_t type_tag, size_t base_type_tag); } diff --git a/include/core/Wrapped.hpp b/include/core/Wrapped.hpp index bc446e72..ce6a6de6 100644 --- a/include/core/Wrapped.hpp +++ b/include/core/Wrapped.hpp @@ -8,7 +8,7 @@ namespace godot { class _Wrapped { public: godot_object *_owner; - const void *_type_tag; + size_t _type_tag; }; } diff --git a/src/core/GodotGlobal.cpp b/src/core/GodotGlobal.cpp index 980aa5d9..37a8bf58 100644 --- a/src/core/GodotGlobal.cpp +++ b/src/core/GodotGlobal.cpp @@ -11,7 +11,7 @@ static GDCALLINGCONV void *wrapper_create(void *data, const void *type_tag, godo if (!wrapper_memory) return NULL; wrapper_memory->_owner = instance; - wrapper_memory->_type_tag = type_tag; + wrapper_memory->_type_tag = (size_t) type_tag; return (void *) wrapper_memory; } diff --git a/src/core/TagDB.cpp b/src/core/TagDB.cpp index e47c9967..0e7fb8f2 100644 --- a/src/core/TagDB.cpp +++ b/src/core/TagDB.cpp @@ -8,35 +8,38 @@ namespace godot { namespace _TagDB { -std::unordered_map parent_to; +std::unordered_map 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; } -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(); } -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); } -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; - const void *tag = have_tag; + size_t tag = have_tag; - while (tag != nullptr) { + while (tag != 0) { if (tag == ask_tag) return true;