Browse Source

some Ref WIP, memory leaks and invalid returns

Karroffel 8 years ago
parent
commit
38f1ee741d
3 changed files with 70 additions and 21 deletions
  1. 45 16
      binding_generator.py
  2. 1 0
      include/core/Godot.hpp
  3. 24 5
      include/core/Ref.hpp

+ 45 - 16
binding_generator.py

@@ -4,8 +4,11 @@ import json
 
 
 # comment.
 # comment.
 
 
+classes = []
+
 def generate_bindings(path):
 def generate_bindings(path):
     
     
+    global classes
     classes = json.load(open(path))
     classes = json.load(open(path))
     
     
     icalls = set()
     icalls = set()
@@ -31,8 +34,23 @@ def generate_bindings(path):
     icall_source_file = open("src/__icalls.cpp", "w+")
     icall_source_file = open("src/__icalls.cpp", "w+")
     icall_source_file.write(generate_icall_implementation(icalls))
     icall_source_file.write(generate_icall_implementation(icalls))
 
 
-        
-        
+
+def is_reference_type(t):
+    for c in classes:
+        if c['name'] != t:
+            continue
+        if c['is_reference']:
+            return True
+    return False
+
+def make_gdnative_type(t):
+    if is_class_type(t):
+        if is_reference_type(t):
+            return "Ref<" + strip_name(t) + "> "
+        else:
+            return strip_name(t) + " *"
+    else:
+        return strip_name(t) + " "
 
 
 def generate_class_header(used_classes, c):
 def generate_class_header(used_classes, c):
 
 
@@ -59,6 +77,7 @@ def generate_class_header(used_classes, c):
     
     
     
     
     source.append("#include <CoreTypes.hpp>")
     source.append("#include <CoreTypes.hpp>")
+    source.append("#include <Ref.hpp>")
     
     
     if c["base_class"] != "":
     if c["base_class"] != "":
         source.append("#include <" + strip_name(c["base_class"]) + ".hpp>")
         source.append("#include <" + strip_name(c["base_class"]) + ".hpp>")
@@ -104,15 +123,14 @@ def generate_class_header(used_classes, c):
         method_signature = ""
         method_signature = ""
         
         
         method_signature += "static " if c["singleton"] else ""
         method_signature += "static " if c["singleton"] else ""
-        method_signature += strip_name(method["return_type"])
-        method_signature += " *" if is_class_type(method["return_type"]) else " "
+        method_signature += make_gdnative_type(method["return_type"])
         method_signature += escape_cpp(method["name"]) + "("
         method_signature += escape_cpp(method["name"]) + "("
-        
-        
+            
+            
         has_default_argument = False
         has_default_argument = False
         
         
         for i, argument in enumerate(method["arguments"]):
         for i, argument in enumerate(method["arguments"]):
-            method_signature += "const " + argument["type"] + (" *" if is_class_type(argument["type"]) else " ")
+            method_signature += "const " + make_gdnative_type(argument["type"])
             method_signature += escape_cpp(argument["name"])
             method_signature += escape_cpp(argument["name"])
             
             
             
             
@@ -196,6 +214,7 @@ def generate_class_implementation(icalls, used_classes, c):
     source.append("")
     source.append("")
     
     
     source.append("#include <CoreTypes.hpp>")
     source.append("#include <CoreTypes.hpp>")
+    source.append("#include <Ref.hpp>")
     
     
     source.append("#include <Godot.hpp>")
     source.append("#include <Godot.hpp>")
     source.append("")
     source.append("")
@@ -252,12 +271,11 @@ def generate_class_implementation(icalls, used_classes, c):
     for method in c["methods"]:
     for method in c["methods"]:
         method_signature = ""
         method_signature = ""
         
         
-        method_signature += strip_name(method["return_type"])
-        method_signature += " *" if is_class_type(method["return_type"]) else " "
+        method_signature += make_gdnative_type(method["return_type"])
         method_signature += strip_name(c["name"]) + "::" + escape_cpp(method["name"]) + "("
         method_signature += strip_name(c["name"]) + "::" + escape_cpp(method["name"]) + "("
         
         
         for i, argument in enumerate(method["arguments"]):
         for i, argument in enumerate(method["arguments"]):
-            method_signature += "const " + argument["type"] + (" *" if is_class_type(argument["type"]) else " ")
+            method_signature += "const " + make_gdnative_type(argument["type"])
             method_signature += escape_cpp(argument["name"])
             method_signature += escape_cpp(argument["name"])
             
             
             if i != len(method["arguments"]) - 1:
             if i != len(method["arguments"]) - 1:
@@ -286,7 +304,13 @@ def generate_class_implementation(icalls, used_classes, c):
         return_statement = ""
         return_statement = ""
         
         
         if method["return_type"] != "void":
         if method["return_type"] != "void":
-            return_statement += "return " + ("(" + strip_name(method["return_type"]) + " *) " if is_class_type(method["return_type"]) else "")
+            if is_class_type(method["return_type"]):
+                if is_reference_type(method["return_type"]):
+                    return_statement += "return Ref<" + strip_name(method["return_type"]) + ">(";
+                else:
+                    return_statement += "return " + ("(" + strip_name(method["return_type"]) + " *) " if is_class_type(method["return_type"]) else "")
+            else:
+                return_statement += "return "
         
         
         def get_icall_type_name(name):
         def get_icall_type_name(name):
             if is_class_type(name):
             if is_class_type(name):
@@ -295,7 +319,7 @@ def generate_class_implementation(icalls, used_classes, c):
         
         
         
         
         
         
-        if method["is_virtual"] or method["has_varargs"]:
+        if method["has_varargs"]:
 
 
             if len(method["arguments"]) != 0:
             if len(method["arguments"]) != 0:
                 source.append("\tVariant __given_args[" + str(len(method["arguments"])) + "];")
                 source.append("\tVariant __given_args[" + str(len(method["arguments"])) + "];")
@@ -347,8 +371,13 @@ def generate_class_implementation(icalls, used_classes, c):
             if method["return_type"] != "void":
             if method["return_type"] != "void":
                 cast = ""
                 cast = ""
                 if is_class_type(method["return_type"]):
                 if is_class_type(method["return_type"]):
-                    cast += "(" + strip_name(method["return_type"]) + " *) (Object *) "
-                source.append("\treturn " + cast + "__result;")
+                    if is_reference_type(method["return_type"]):
+                        cast += "Ref<" + stip_name(method["return_type"]) + ">(__result);"
+                    else:
+                        cast += "(" + strip_name(method["return_type"]) + " *) (Object *) __result;"
+                else:
+                    cast += "__result;"
+                source.append("\treturn " + cast)
             
             
             
             
             
             
@@ -369,11 +398,11 @@ def generate_class_implementation(icalls, used_classes, c):
             return_statement += icall_name + "(mb, (godot_object *) " + core_object_name
             return_statement += icall_name + "(mb, (godot_object *) " + core_object_name
             
             
             for arg in method["arguments"]:
             for arg in method["arguments"]:
-                return_statement += ", " + escape_cpp(arg["name"])
+                return_statement += ", " + escape_cpp(arg["name"]) + (".ptr()" if is_reference_type(arg["type"]) else "")
                 
                 
             return_statement += ")"
             return_statement += ")"
             
             
-            source.append("\t" + return_statement + ";")
+            source.append("\t" + return_statement + (")" if is_reference_type(method["return_type"]) else "") + ";")
         
         
         source.append("}")
         source.append("}")
         source.append("")
         source.append("")

+ 1 - 0
include/core/Godot.hpp

@@ -9,6 +9,7 @@
 
 
 #include <CoreTypes.hpp>
 #include <CoreTypes.hpp>
 #include <Variant.hpp>
 #include <Variant.hpp>
+#include <Ref.hpp>
 
 
 #include <Object.hpp>
 #include <Object.hpp>
 
 

+ 24 - 5
include/core/Ref.hpp

@@ -84,10 +84,17 @@ public:
 	{
 	{
 		ref(from);
 		ref(from);
 	}
 	}
+
+	template<class T_Other>
+	void operator=(const Ref<T_Other> &from)
+	{
+		Ref<T> n((T *) from.ptr());
+		ref(n);
+	}
 	
 	
 	void operator=(const Variant &variant)
 	void operator=(const Variant &variant)
 	{
 	{
-		T *r = variant;
+		T *r = (T *) (Object *) variant;
 		if (!r) {
 		if (!r) {
 			unref();
 			unref();
 			return;
 			return;
@@ -101,17 +108,26 @@ public:
 	
 	
 	operator Variant() const
 	operator Variant() const
 	{
 	{
-		ref();
-		return Variant((Object *) this);
+		if (reference) reference->reference();
+		return Variant((Object *) reference);
 	}
 	}
 	
 	
+	template<class T_Other>
+	Ref(const Ref<T_Other> &from)
+	{
+		if (from.ptr())
+			ref_pointer((T *) from.ptr());
+		else
+			reference = nullptr;
+	}
 	
 	
 	Ref(const Ref &from)
 	Ref(const Ref &from)
 	{
 	{
 		reference = nullptr;
 		reference = nullptr;
 		ref(from);
 		ref(from);
 	}
 	}
-	
+
+
 	Ref(T *r)
 	Ref(T *r)
 	{
 	{
 		if (r)
 		if (r)
@@ -120,10 +136,13 @@ public:
 			reference = nullptr;
 			reference = nullptr;
 	}
 	}
 	
 	
+	template<class T_Other>
+	Ref(T_Other *r) : Ref((T *) r) {}
+
 	Ref(const Variant &variant)
 	Ref(const Variant &variant)
 	{
 	{
 		reference = nullptr;
 		reference = nullptr;
-		T *r = variant;
+		T *r = (T *) (Object *) variant;
 		if (!r) {
 		if (!r) {
 			unref();
 			unref();
 			return;
 			return;