@@ -26,6 +26,7 @@ pub fn Generator.new(api_dump string) Generator {
2626pub fn (mut g Generator) run () ! {
2727 g.setup ()
2828
29+ g.gen_gdext ()!
2930 g.gen_functions ()!
3031 g.gen_enums ()!
3132 g.gen_builtin_classes ()!
@@ -68,27 +69,111 @@ fn (mut g Generator) setup() {
6869 }
6970}
7071
71- fn (g &Generator) gen_enums () ! {
72+ fn (g &Generator) gen_gdext () ! {
7273 mut buf := strings.new_builder (1024 )
73- buf.writeln ('module gd' )
74+ buf.writeln ('
75+ |module gdext
76+ |
77+ |import gd
78+ ' .strip_margin ().trim ('\n ' ))
7479
75- for enm in g.api.global_enums {
76- name := convert_type (enm.name)
77- buf.writeln ('' )
78- buf.writeln ('pub enum ${name} as i64 {' )
79- mut bits := []i64 {cap: enm.values.len}
80+ // call_func
81+ buf.writeln ('
82+ |// TODO: see if we can leverage the passed-in FunctionData
83+ |fn call_func[T](user_data voidptr, instance gd.GDExtensionClassInstancePtr, args &&gd.Variant, arg_count gd.GDExtensionInt, ret &gd.Variant, err &gd.GDExtensionCallError) {
84+ | mut inst := unsafe { &T(instance) }
85+ | method_data := unsafe { &FunctionData(user_data) }
86+ | // HACK: there is no way this nested `\$ for` is actually necessary...
87+ | \$ for method in T.methods {
88+ | if method.name == method_data.name {
89+ | mut params := []voidptr{}
90+ | // handle params
91+ | // TODO: leverage `gd.ToVariant` and `gd.FromVariant` interfaces
92+ | mut p := 0
93+ | \$ for param in method.params {
94+ | prm := unsafe { &args[p] }
95+ | \$ if param.typ is &bool {
96+ | value := prm.to_bool()
97+ | params << &value
98+ | } \$ else \$ if param.typ is &string {
99+ | value := prm.to_string()
100+ | params << &value
101+ | } \$ else \$ if param.typ is &int {
102+ | value := prm.to_int()
103+ | params << &value
104+ | } \$ else \$ if param.typ is &i64 {
105+ | value := gd.i64_from_variant(prm)
106+ | params << &value
107+ | } \$ else \$ if param.typ is &f64 {
108+ | value := gd.f64_from_variant(prm)
109+ | params << &value
110+ ' .strip_margin ().trim_right ('\n ' ))
80111
81- for val in enm.values {
82- if val.value ! in bits {
83- bits << val.value
84- buf.writeln ('\t ${val.name.to_lower()} = ${val.value} ' )
85- }
112+ for class in g.api.builtin_classes {
113+ if class.name.is_lower () {
114+ continue
86115 }
116+ class_name := convert_type (class.name, ns: 'gd' )
117+ buf.writeln ('
118+ | } \$ else \$ if param.typ is ${class_name} || param.typ is &${class_name} {
119+ | mut value := ${class_name} {}
120+ | value.from_variant(prm)
121+ | params << &value
122+ ' .strip_margin ().trim ('\n ' ))
123+ }
87124
88- buf.writeln ('}' )
125+ for class in g.api.classes {
126+ class_name := convert_type (class.name, ns: 'gd' )
127+ buf.writeln ('
128+ | } \$ else \$ if param.typ is ${class_name} || param.typ is &${class_name} {
129+ | mut value := ${class_name} {}
130+ | value.from_variant(prm)
131+ | params << &value
132+ ' .strip_margin ().trim ('\n ' ))
89133 }
90134
91- mut f := os.create ('src/__enums.v' )!
135+ buf.writeln ("
136+ | } \$ else {
137+ | params << &prm
138+ | }
139+ | p += 1
140+ | }
141+ | if p != arg_count {
142+ | panic('call_func: argument count mismatch')
143+ | }
144+ | // handle return value
145+ | \$ if method.return_type is bool {
146+ | result := inst.\$ method(...params)
147+ | ret.from_bool(result)
148+ | } \$ else \$ if method.return_type is string {
149+ | result := inst.\$ method(...params)
150+ | str := String.new(result)
151+ | variant := str.to_variant()
152+ | ret.from_variant(variant)
153+ | } \$ else \$ if method.return_type is int {
154+ | result := inst.\$ method(...params)
155+ | ret.from_int(result)
156+ | } \$ else \$ if method.return_type is i64 {
157+ | result := inst.\$ method(...params)
158+ | ret.from_variant(gd.i64_to_variant(result))
159+ | } \$ else \$ if method.return_type is f64 {
160+ | result := inst.\$ method(...params)
161+ | ret.from_variant(gd.f64_to_variant(result))
162+ | } \$ else \$ if method.return_type is gd.ToVariant {
163+ | result := inst.\$ method(...params)
164+ | variant := result.to_variant()
165+ | ret.from_variant(variant)
166+ | } \$ else {
167+ | // TODO: \$ if method.return_type == 1
168+ | // void
169+ | inst.\$ method(...params)
170+ | }
171+ | }
172+ | }
173+ |}
174+ " .strip_margin ().trim ('\n ' ))
175+
176+ mut f := os.create ('gdext/__functions.v' )!
92177 defer { f.close () }
93178 f.write (buf)!
94179}
@@ -192,101 +277,32 @@ fn (g &Generator) gen_functions() ! {
192277 buf.writeln ('}' )
193278 }
194279
195- // call_func
196- buf.writeln ('
197- |// TODO: see if we can leverage the passed-in FunctionData
198- |fn call_func[T](user_data voidptr, instance GDExtensionClassInstancePtr, args &&Variant, arg_count GDExtensionInt, ret &Variant, err &GDExtensionCallError) {
199- | mut inst := unsafe { &T(instance) }
200- | method_data := unsafe { &FunctionData(user_data) }
201- | // HACK: there is no way this nested `\$ for` is actually necessary...
202- | \$ for method in T.methods {
203- | if method.name == method_data.name {
204- | mut params := []voidptr{}
205- | // handle params
206- | // TODO: leverage `ToVariant` and `FromVariant` interfaces
207- | mut p := 0
208- | \$ for param in method.params {
209- | prm := unsafe { &args[p] }
210- | \$ if param.typ is &bool {
211- | value := prm.to_bool()
212- | params << &value
213- | } \$ else \$ if param.typ is &string {
214- | value := prm.to_string()
215- | params << &value
216- | } \$ else \$ if param.typ is &int {
217- | value := prm.to_int()
218- | params << &value
219- | } \$ else \$ if param.typ is &i64 {
220- | value := i64_from_variant(prm)
221- | params << &value
222- | } \$ else \$ if param.typ is &f64 {
223- | value := f64_from_variant(prm)
224- | params << &value
225- ' .strip_margin ().trim_right ('\n ' ))
280+ mut f := os.create ('src/__functions.v' )!
281+ defer { f.close () }
282+ f.write (buf)!
283+ }
226284
227- for class in g.api.builtin_classes {
228- if class.name.is_lower () {
229- continue
285+ fn (g &Generator) gen_enums () ! {
286+ mut buf := strings.new_builder (1024 )
287+ buf.writeln ('module gd' )
288+
289+ for enm in g.api.global_enums {
290+ name := convert_type (enm.name)
291+ buf.writeln ('' )
292+ buf.writeln ('pub enum ${name} as i64 {' )
293+ mut bits := []i64 {cap: enm.values.len}
294+
295+ for val in enm.values {
296+ if val.value ! in bits {
297+ bits << val.value
298+ buf.writeln ('\t ${val.name.to_lower()} = ${val.value} ' )
299+ }
230300 }
231- buf.writeln ('
232- | } \$ else \$ if param.typ is ${class.name} || param.typ is &${class.name} {
233- | mut value := ${class.name} {}
234- | value.from_variant(prm)
235- | params << &value
236- ' .strip_margin ().trim ('\n ' ))
237- }
238301
239- for class in g.api.classes {
240- buf.writeln ('
241- | } \$ else \$ if param.typ is ${class.name} || param.typ is &${class.name} {
242- | mut value := ${class.name} {}
243- | value.from_variant(prm)
244- | params << &value
245- ' .strip_margin ().trim ('\n ' ))
302+ buf.writeln ('}' )
246303 }
247304
248- buf.writeln ("
249- | } \$ else {
250- | params << &prm
251- | }
252- | p += 1
253- | }
254- | if p != arg_count {
255- | panic('call_func: argument count mismatch')
256- | }
257- | // handle return value
258- | \$ if method.return_type is bool {
259- | result := inst.\$ method(...params)
260- | ret.from_bool(result)
261- | } \$ else \$ if method.return_type is string {
262- | result := inst.\$ method(...params)
263- | str := String.new(result)
264- | variant := str.to_variant()
265- | ret.from_variant(variant)
266- | } \$ else \$ if method.return_type is int {
267- | result := inst.\$ method(...params)
268- | ret.from_int(result)
269- | } \$ else \$ if method.return_type is i64 {
270- | result := inst.\$ method(...params)
271- | ret.from_variant(i64_to_variant(result))
272- | } \$ else \$ if method.return_type is f64 {
273- | result := inst.\$ method(...params)
274- | ret.from_variant(f64_to_variant(result))
275- | } \$ else \$ if method.return_type is ToVariant {
276- | result := inst.\$ method(...params)
277- | variant := result.to_variant()
278- | ret.from_variant(variant)
279- | } \$ else {
280- | // TODO: \$ if method.return_type == 1
281- | // void
282- | inst.\$ method(...params)
283- | }
284- | }
285- | }
286- |}
287- " .strip_margin ().trim ('\n ' ))
288-
289- mut f := os.create ('src/__functions.v' )!
305+ mut f := os.create ('src/__enums.v' )!
290306 defer { f.close () }
291307 f.write (buf)!
292308}
@@ -705,7 +721,7 @@ fn (g &Generator) gen_classes() ! {
705721
706722 // struct
707723 buf.writeln ('' )
708- buf.writeln ('@[noinit]' )
724+ // buf.writeln('@[noinit]')
709725 buf.writeln ('pub struct ${class.name} {' )
710726 if class.inherits == '' {
711727 buf.writeln ('pub mut:' )
@@ -1062,7 +1078,11 @@ fn (g &Generator) class_to_variant_type(class_name string) string {
10621078
10631079fn (g &Generator) gen_virtual_methods () ! {
10641080 mut buf := strings.new_builder (1024 )
1065- buf.writeln ('module gd' )
1081+ buf.writeln ('
1082+ |module gdext
1083+ |
1084+ |import gd
1085+ ' .strip_margin ().trim ('\n ' ))
10661086
10671087 // methods
10681088 for class in g.api.classes {
@@ -1075,11 +1095,13 @@ fn (g &Generator) gen_virtual_methods() ! {
10751095 virt_name := '${convert_name(method.name[1..])} _'
10761096
10771097 buf.writeln ('' )
1078- buf.writeln ('fn ${convert_type(class.name).to_lower()} _${convert_name(method.name)} [T] (inst GDExtensionClassInstancePtr, args &GDExtensionConstTypePtr, ret GDExtensionTypePtr) {' )
1079- buf.writeln ('\t mut v_inst := &${name} (unsafe{&T(inst)})' )
1098+ buf.writeln ('fn ${convert_type(class.name).to_lower()} _${convert_name(method.name)} [T] (inst gd. GDExtensionClassInstancePtr, args &gd. GDExtensionConstTypePtr, ret gd. GDExtensionTypePtr) {' )
1099+ buf.writeln ('\t mut v_inst := &gd. ${name} (unsafe{&T(inst)})' )
10801100
10811101 for i, arg in method.arguments {
1082- buf.writeln ('\t ${convert_name(arg.name)} := unsafe{&${convert_type(arg.type)} (args[${i} ])}' )
1102+ buf.writeln ('\t ${convert_name(arg.name)} := unsafe{&${convert_type(arg.type,
1103+ ns: ' gd'
1104+ )}(args[${i} ])}' )
10831105 }
10841106
10851107 buf.write_string ('\t ' )
@@ -1113,13 +1135,13 @@ fn (g &Generator) gen_virtual_methods() ! {
11131135
11141136 // HACK: force function generation
11151137 buf.writeln ('
1116- | \$ if T is ${name} {
1138+ | \$ if T is gd. ${name} {
11171139 | // HACK: force function generation
11181140 | if false { unsafe { ${full_name} [T](nil, nil, nil) } }
11191141 | func := ${full_name} [T]
11201142 | ivar := i64(func)
1121- | var := i64_to_variant(ivar)
1122- | sn := StringName.new("${method.name} ")
1143+ | var := gd. i64_to_variant(ivar)
1144+ | sn := gd. StringName.new("${method.name} ")
11231145 | defer { sn.deinit() }
11241146 | ci.virtual_methods.index_set_named(sn, var) or {panic(err)}
11251147 | }
@@ -1128,7 +1150,7 @@ fn (g &Generator) gen_virtual_methods() ! {
11281150 }
11291151 buf.writeln ('}' )
11301152
1131- mut f := os.create ('src /__virtual.v' )!
1153+ mut f := os.create ('gdext /__virtual.v' )!
11321154 defer { f.close () }
11331155 f.write (buf)!
11341156}
0 commit comments