Browse Source

use typeid() for type tags now

karroffel 7 years ago
parent
commit
38da87fc0b
7 changed files with 42 additions and 45 deletions
  1. 1 1
      SConstruct
  2. 14 20
      binding_generator.py
  3. 7 9
      include/core/Godot.hpp
  4. 6 4
      include/core/TagDB.hpp
  5. 1 1
      include/core/Wrapped.hpp
  6. 1 1
      src/core/GodotGlobal.cpp
  7. 12 9
      src/core/TagDB.cpp

+ 1 - 1
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':

+ 14 - 20
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 <typeinfo>")
+    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

+ 7 - 9
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::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 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:
 
 #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<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_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<class T>
 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<T>(obj) : (T *) obj;
 	} else {
 		return nullptr;

+ 6 - 4
include/core/TagDB.hpp

@@ -1,14 +1,16 @@
 #ifndef TAGDB_HPP
 #define TAGDB_HPP
 
+#include <stddef.h>
+
 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);
 
 }
 

+ 1 - 1
include/core/Wrapped.hpp

@@ -8,7 +8,7 @@ namespace godot {
 class _Wrapped {
 public:
 	godot_object *_owner;
-	const void *_type_tag;
+	size_t _type_tag;
 };
 
 }

+ 1 - 1
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;
 }

+ 12 - 9
src/core/TagDB.cpp

@@ -8,35 +8,38 @@ namespace godot {
 
 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;
 }
 
-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;