summaryrefslogtreecommitdiff
path: root/src/script_to_header.py
diff options
context:
space:
mode:
authorAnson Bridges <bridges.anson@gmail.com>2022-09-15 16:43:08 -0400
committerAnson Bridges <bridges.anson@gmail.com>2022-09-15 16:43:08 -0400
commit7a52122ef736a9525f98c37d3e56c4c3095b61e5 (patch)
tree4eda6ebf8ed300bb32559a1cdbe8c4015f3f77d6 /src/script_to_header.py
parentaad319ddb5be108e9ca81d407bd90c843bae502d (diff)
Script for converting properly formatted .gd to a c++ template
Diffstat (limited to 'src/script_to_header.py')
-rw-r--r--src/script_to_header.py127
1 files changed, 127 insertions, 0 deletions
diff --git a/src/script_to_header.py b/src/script_to_header.py
new file mode 100644
index 0000000..452a09d
--- /dev/null
+++ b/src/script_to_header.py
@@ -0,0 +1,127 @@
+import sys
+from os.path import exists
+
+RPC_DICT = {"remote" : "GODOT_METHOD_RPC_MODE_REMOTE", "remotesync" : "GODOT_METHOD_RPC_MODE_REMOTESYNC", \
+ "master" : "GODOT_METHOD_RPC_MODE_MASTER", "mastersync" : "GODOT_METHOD_RPC_MODE_MASTERSYNC", \
+ "puppet" : "GODOT_METHOD_RPC_MODE_PUPPET", "puppetsync" : "GODOT_METHOD_RPC_MODE_PUPPETSYNC"}
+
+def script_to_gdn(filename):
+ if not exists(filename) or not filename.endswith(".gd"):
+ return
+ class_name = filename[:-3]
+ new_file_base = class_name.lower()
+ header_name = class_name.upper() + "_H"
+ base_class_name = "Node"
+ class_vars = [] # {export bool, onready bool, type str, varname str, initialvalue}
+ funcs = [] # {net type, return type, name, [args], [content]} args = [name, type], content = func content lines list
+
+ script = open(filename, "r")
+ template_h = open("gdn_header_template", "r")
+ template_c = open("gdn_src_template", "r")
+
+ header_file_text = template_h.read(); template_h.close();
+ src_file_text = template_c.read(); template_c.close();
+
+ lines = script.readlines()
+ for I in range(len(lines)):
+ line = lines[I]
+ if line.startswith("extends"):
+ base_class_name = line.split(" ")[-1].strip();
+
+ if line.startswith("var") or line.startswith("export var") or line.startswith("const") or line.startswith("onready var"):
+ class_vars.append( [ line.startswith("export"), line.startswith("onready"), line.split(":")[1].split('=')[0].strip(), line.split(":")[0].split(" ")[-1], "" if "=" not in line else line.split("=")[-1].strip() ])
+
+ if line.startswith("func") or line.startswith("remote") or line.startswith("master") or line.startswith("puppet"):
+ functype = line[0:line.index(" ")]
+
+ args = line[line.index("(")+1 : line.index(")")].split(",")
+ for i, arg in enumerate(args):
+ if arg == "":
+ args = []
+ break
+ args[i] = [arg.split(":")[0].strip(), arg.split(":")[1].strip()]
+
+ returntype = "void"
+ if "->" in line:
+ returntype = line[line.index("->"+1),line.index(":").strip()]
+
+ funcname = line[ line[0:line.index("(")].rindex(" ") : int(line.index("(")) ].strip()
+
+ content = []
+ I+=1
+ line = lines[I]
+ while line.startswith('\t'):
+ content.append(line)
+ I+=1
+ if I != len(lines):
+ line = lines[I]
+ else:
+ line = "EOF"
+ I-=1
+
+ funcs.append( [functype, returntype, funcname, args, content] )
+ script.close()
+
+ header_file_text = header_file_text.replace("{HEADER_NAME}", header_name).replace("{BASE_CLASS_NAME}", base_class_name).replace("{CLASS_NAME}", class_name)
+
+ var_text = ""
+ for var in class_vars:
+ var_text += '\t' + var[2] + " " + var[3] + ";\n" # type varname;
+ header_file_text = header_file_text.replace("{VARS}", var_text)
+
+ func_text = ""
+ for func in funcs:
+ func_text += '\t' + func[1] + " " + func[2] + "(" # type functionname(
+ for i,arg in enumerate(func[3]):
+ func_text += arg[1] + " " + arg[0]
+ if i != len(func[3])-1:
+ func_text += ", "
+ func_text += ");\n"
+ header_file_text = header_file_text.replace("{FUNCS}", func_text)
+ #print(header_file_text)
+ with open(new_file_base+".h", "w") as f:
+ f.write(header_file_text)
+
+ #SOURCE CODE:
+ src_file_text = src_file_text.replace("{CLASS_NAME}", class_name).replace("{NEW_FILE_BASE}",new_file_base)
+
+ reg_vars = ""
+ vars_init = ""
+ vars_ready = ""
+ for var in class_vars:
+ if var[0]: #export
+ reg_vars += "\tregister_property<"+class_name+", "+var[2]+">(\""+var[3]+"\", &"+class_name+"::"+var[3]+", "+var[2]+"("+var[4]+"));\n"
+ elif var[1]: #onready
+ vars_ready += "\t"+var[3]+" = "+var[4]+";\n"
+ else:
+ vars_init += "\t"+var[3]+" = "+var[4]+";\n"
+ reg_vars = reg_vars[:-1]
+ reg_methods = ""
+ src_func_text = ""
+ for func in funcs:
+ reg_methods += "\tregister_method(\"" + func[2]+"\", &"+class_name+"::"+func[2]
+ if func[0] != "func":
+ reg_methods += ", " + RPC_DICT[func[0]]
+ reg_methods += ");\n"
+
+ src_func_text += func[1] + " " + class_name + "::" + func[2] + "(" #returntype ClassName::functionname(
+ for i,arg in enumerate(func[3]):
+ src_func_text += arg[1] + " " + arg[0]
+ if i != len(func[3])-1:
+ src_func_text += ", "
+ src_func_text += ") {\n"
+ if func[2] == "_ready":
+ src_func_text += vars_ready
+ src_func_text += "//" + "//".join(func[4]) #join content (commented out)
+ src_func_text += "}\n\n"
+
+ src_file_text = src_file_text.replace("{INIT_VARS}", vars_init).replace("{REGISTER_METHODS}",reg_methods).replace("{REGISTER_VARS}", reg_vars).replace("{FULL_FUNCS}", src_func_text)
+
+ with open(new_file_base+".cpp", "w") as f:
+ f.write(src_file_text)
+
+if __name__ == "__main__":
+ n = len(sys.argv)
+ if n != 2:
+ quit()
+ script_to_gdn(sys.argv[1])