Browse Source

Merge pull request #108 from danielytics/variadic-functions

Adds variadic template functions for register_signal and emit_signal
Thomas Herzog 7 years ago
parent
commit
779568c67c
6 changed files with 64 additions and 3 deletions
  1. 1 0
      README.md
  2. 11 3
      binding_generator.py
  3. 6 0
      include/core/Array.hpp
  4. 36 0
      include/core/Defs.hpp
  5. 5 0
      include/core/Dictionary.hpp
  6. 5 0
      include/core/Godot.hpp

+ 1 - 0
README.md

@@ -78,6 +78,7 @@ public:
 
            /** For registering signal **/
            // register_signal<SimpleClass>("signal_name");
+           // register_signal<SimpleClass>("signal_name", "string_argument", GODOT_VARIANT_TYPE_STRING)
         }
 	
 	String _name;

+ 11 - 3
binding_generator.py

@@ -115,6 +115,7 @@ def generate_class_header(used_classes, c):
     
     source.append("")
     
+    vararg_templates = ""
     
     # generate the class definition here
     source.append("class " + class_name + ("" if c["base_class"] == "" else (" : public " + strip_name(c["base_class"])) ) + " {")
@@ -157,14 +158,18 @@ def generate_class_header(used_classes, c):
         
         method_signature += "static " if c["singleton"] else ""
         method_signature += make_gdnative_type(method["return_type"])
-        method_signature += escape_cpp(method["name"]) + "("
+        method_name = escape_cpp(method["name"])
+        method_signature +=  method_name + "("
             
             
         has_default_argument = False
+        method_arguments = ""
         
         for i, argument in enumerate(method["arguments"]):
             method_signature += "const " + make_gdnative_type(argument["type"])
-            method_signature += escape_cpp(argument["name"])
+            argument_name = escape_cpp(argument["name"])
+            method_signature += argument_name
+            method_arguments += argument_name
             
             
             # default arguments
@@ -210,10 +215,13 @@ def generate_class_header(used_classes, c):
             
             if i != len(method["arguments"]) - 1:
                 method_signature += ", "
+                method_arguments += ","
                 
         if method["has_varargs"]:
             if len(method["arguments"]) > 0:
                 method_signature += ", "
+                method_arguments += ", "
+            vararg_templates += "\ttemplate <class... Args> " + method_signature + "Args... args){\n\t\treturn " + method_name + "(" + method_arguments + "Array::make(args...));\n\t}\n"""
             method_signature += "const Array& __var_args = Array()"
             
         method_signature += ")" + (" const" if method["is_const"] and not c["singleton"] else "")
@@ -221,7 +229,7 @@ def generate_class_header(used_classes, c):
 
         source.append("\t" + method_signature + ";")
     
-    
+    source.append(vararg_templates)
     source.append("};")
     source.append("")
     

+ 6 - 0
include/core/Array.hpp

@@ -3,6 +3,7 @@
 
 #include <gdnative/array.h>
 
+#include "Defs.hpp"
 #include "String.hpp"
 
 namespace godot {
@@ -39,6 +40,11 @@ public:
 
 	Array(const PoolColorArray& a);
 
+	template <class... Args>
+	static Array make(Args... args) {
+		return helpers::append_all(Array(), args...);
+	}
+
 	Variant& operator [](const int idx);
 
 	Variant operator [](const int idx) const;

+ 36 - 0
include/core/Defs.hpp

@@ -58,6 +58,42 @@ enum Error {
 	ERR_WTF = ERR_OMFG_THIS_IS_VERY_VERY_BAD ///< short version of the above
 };
 
+	namespace helpers {
+		template <typename T, typename ValueT>
+		T append_all (T appendable, ValueT value) {
+			appendable.append(value);
+			return appendable;
+		}
+
+		template <typename T, typename ValueT, typename... Args>
+		T append_all (T appendable, ValueT value, Args... args) {
+			appendable.append(value);
+			return append_all(appendable, args...);
+		}
+
+		template <typename T>
+		T append_all (T appendable) {
+			return appendable;
+		}
+
+		template <typename KV, typename KeyT, typename ValueT>
+		KV add_all (KV kv, KeyT key, ValueT value) {
+			kv[key] = value;
+			return kv;
+		}
+
+		template <typename KV, typename KeyT, typename ValueT, typename... Args>
+		KV add_all (KV kv, KeyT key, ValueT value, Args... args) {
+			kv[key] = value;
+			return add_all(kv, args...);
+		}
+
+		template <typename KV>
+		KV add_all (KV kv) {
+			return kv;
+		}
+	}
+
 }
 
 #include <stdio.h>

+ 5 - 0
include/core/Dictionary.hpp

@@ -16,6 +16,11 @@ public:
 	Dictionary(const Dictionary & other);
 	Dictionary & operator=(const Dictionary & other);
 
+	template <class... Args>
+	static Dictionary make(Args... args) {
+		return helpers::add_all(Dictionary(), args...);
+	}
+
 	void clear();
 
 	bool empty() const;

+ 5 - 0
include/core/Godot.hpp

@@ -484,6 +484,11 @@ void register_signal(String name, Dictionary args = Dictionary())
 	}
 }
 
+template<class T, class... Args>
+void register_signal(String name, Args... varargs)
+{
+	register_signal<T>(name, Dictionary::make(varargs...));
+}
 
 }