1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
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])
|