summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc <marc.gilleron@gmail.com>2020-08-23 20:28:44 +0100
committerGitHub <noreply@github.com>2020-08-23 20:28:44 +0100
commit824f4ef481809fdeed0e6afe09f8b856d71f3b54 (patch)
tree1808c43d417eec39f62445ce8b64def73fca1bf6
parent6c2e94710aca45dea0c82714908bd4987e0c7afb (diff)
parenta2ebc8bbec0cdc80b2539786f64078930830d464 (diff)
downloadredot-cpp-824f4ef481809fdeed0e6afe09f8b856d71f3b54.tar.gz
Merge pull request #416 from DuncanSparks/template_get_node
Add option to generate template version of Node::get_node
-rw-r--r--SConstruct7
-rw-r--r--binding_generator.py42
2 files changed, 39 insertions, 10 deletions
diff --git a/SConstruct b/SConstruct
index 881b44d..b63ee57 100644
--- a/SConstruct
+++ b/SConstruct
@@ -144,6 +144,11 @@ opts.Add(
'Path to your Android NDK installation. By default, uses ANDROID_NDK_ROOT from your defined environment variables.',
os.environ.get("ANDROID_NDK_ROOT", None)
)
+opts.Add(BoolVariable(
+ 'generate_template_get_node',
+ "Generate a template version of the Node class's get_node.",
+ True
+))
env = Environment(ENV = os.environ)
opts.Update(env)
@@ -362,7 +367,7 @@ if env['generate_bindings']:
# Actually create the bindings here
import binding_generator
- binding_generator.generate_bindings(json_api_file)
+ binding_generator.generate_bindings(json_api_file, env['generate_template_get_node'])
# Sources to compile
sources = []
diff --git a/binding_generator.py b/binding_generator.py
index 2f17592..991e25b 100644
--- a/binding_generator.py
+++ b/binding_generator.py
@@ -4,9 +4,16 @@ import json
# comment.
+# Convenience function for using template get_node
+def correct_method_name(method_list):
+ for method in method_list:
+ if method["name"] == "get_node":
+ method["name"] = "get_node_internal"
+
+
classes = []
-def generate_bindings(path):
+def generate_bindings(path, use_template_get_node):
global classes
classes = json.load(open(path))
@@ -16,10 +23,12 @@ def generate_bindings(path):
for c in classes:
# print c['name']
used_classes = get_used_classes(c)
+ if use_template_get_node and c["name"] == "Node":
+ correct_method_name(c["methods"])
- header = generate_class_header(used_classes, c)
+ header = generate_class_header(used_classes, c, use_template_get_node)
- impl = generate_class_implementation(icalls, used_classes, c)
+ impl = generate_class_implementation(icalls, used_classes, c, use_template_get_node)
header_file = open("include/gen/" + strip_name(c["name"]) + ".hpp", "w+")
header_file.write(header)
@@ -62,7 +71,7 @@ def make_gdnative_type(t, ref_allowed):
return strip_name(t) + " "
-def generate_class_header(used_classes, c):
+def generate_class_header(used_classes, c, use_template_get_node):
source = []
source.append("#ifndef GODOT_CPP_" + strip_name(c["name"]).upper() + "_HPP")
@@ -207,7 +216,6 @@ def generate_class_header(used_classes, c):
source.append("")
for method in c["methods"]:
-
method_signature = ""
# TODO decide what to do about virtual methods
@@ -285,10 +293,26 @@ def generate_class_header(used_classes, c):
source.append("\t" + method_signature + ";")
source.append(vararg_templates)
- source.append("};")
- source.append("")
+ if use_template_get_node and class_name == "Node":
+ # Extra definition for template get_node that calls the renamed get_node_internal; has a default template parameter for backwards compatibility.
+ source.append("\ttemplate <class T = Node>")
+ source.append("\tT *get_node(const NodePath path) const {")
+ source.append("\t\treturn Object::cast_to<T>(get_node_internal(path));")
+ source.append("\t}")
+ source.append("};")
+ source.append("")
+
+ # ...And a specialized version so we don't unnecessarily cast when using the default.
+ source.append("template <>")
+ source.append("inline Node *Node::get_node<Node>(const NodePath path) const {")
+ source.append("\treturn get_node_internal(path);")
+ source.append("}")
+ source.append("")
+ else:
+ source.append("};")
+ source.append("")
source.append("}")
source.append("")
@@ -302,7 +326,7 @@ def generate_class_header(used_classes, c):
-def generate_class_implementation(icalls, used_classes, c):
+def generate_class_implementation(icalls, used_classes, c, use_template_get_node):
class_name = strip_name(c["name"])
ref_allowed = class_name != "Object" and class_name != "Reference"
@@ -365,7 +389,7 @@ def generate_class_implementation(icalls, used_classes, c):
source.append("void " + class_name + "::___init_method_bindings() {")
for method in c["methods"]:
- source.append("\t___mb.mb_" + method["name"] + " = godot::api->godot_method_bind_get_method(\"" + c["name"] + "\", \"" + method["name"] + "\");")
+ source.append("\t___mb.mb_" + method["name"] + " = godot::api->godot_method_bind_get_method(\"" + c["name"] + "\", \"" + ("get_node" if use_template_get_node and method["name"] == "get_node_internal" else method["name"]) + "\");")
source.append("\tgodot_string_name class_name;")
source.append("\tgodot::api->godot_string_name_new_data(&class_name, \"" + c["name"] + "\");")