8
8
use crate :: context:: Context ;
9
9
use crate :: conv;
10
10
use crate :: generator:: { enums, gdext_build_struct} ;
11
- use crate :: models:: domain:: { Enumerator , ExtensionApi } ;
11
+ use crate :: models:: domain:: ExtensionApi ;
12
12
use crate :: util:: ident;
13
- use proc_macro2:: { Ident , Literal , TokenStream } ;
13
+ use proc_macro2:: { Ident , TokenStream } ;
14
14
use quote:: { format_ident, quote, ToTokens } ;
15
15
16
- pub fn make_sys_central_code ( api : & ExtensionApi , ctx : & mut Context ) -> TokenStream {
17
- let VariantEnums {
18
- variant_ty_enumerators_pascal,
19
- variant_ty_enumerators_ord,
20
- variant_op_enumerators_pascal,
21
- variant_op_enumerators_ord,
22
- ..
23
- } = make_variant_enums ( api, ctx) ;
24
-
16
+ pub fn make_sys_central_code ( api : & ExtensionApi ) -> TokenStream {
25
17
let build_config_struct = gdext_build_struct:: make_gdext_build_struct ( & api. godot_version ) ;
18
+ let ( variant_type_enum, variant_type_deprecated_enumerators) =
19
+ make_variant_type_enum ( api, true ) ;
26
20
let [ opaque_32bit, opaque_64bit] = make_opaque_types ( api) ;
27
21
28
22
quote ! {
29
- use crate :: { GDExtensionVariantOperator , GDExtensionVariantType } ;
30
-
31
23
#[ cfg( target_pointer_width = "32" ) ]
32
24
pub mod types {
33
25
#( #opaque_32bit) *
@@ -37,78 +29,38 @@ pub fn make_sys_central_code(api: &ExtensionApi, ctx: &mut Context) -> TokenStre
37
29
#( #opaque_64bit) *
38
30
}
39
31
40
-
41
32
// ----------------------------------------------------------------------------------------------------------------------------------------------
42
33
43
34
#build_config_struct
44
-
45
- // ----------------------------------------------------------------------------------------------------------------------------------------------
46
-
47
- #[ derive( Copy , Clone , Eq , PartialEq , Ord , PartialOrd , Hash , Debug ) ]
48
- #[ repr( i32 ) ]
49
- pub enum VariantType {
50
- Nil = 0 ,
51
- #(
52
- #variant_ty_enumerators_pascal = #variant_ty_enumerators_ord,
53
- ) *
54
- }
35
+ #variant_type_enum
55
36
56
37
impl VariantType {
38
+ // This will need refactoring if VariantType is changed to a real enum.
57
39
#[ doc( hidden) ]
58
- pub fn from_sys( enumerator: GDExtensionVariantType ) -> Self {
59
- // Annoying, but only stable alternative is transmute(), which dictates enum size.
60
- match enumerator {
61
- 0 => Self :: Nil ,
62
- #(
63
- #variant_ty_enumerators_ord => Self :: #variant_ty_enumerators_pascal,
64
- ) *
65
- _ => unreachable!( "invalid variant type {}" , enumerator)
66
- }
40
+ pub fn from_sys( enumerator: crate :: GDExtensionVariantType ) -> Self {
41
+ Self { ord: enumerator as i32 }
67
42
}
68
43
69
44
#[ doc( hidden) ]
70
- pub fn sys( self ) -> GDExtensionVariantType {
71
- self as _
45
+ pub fn sys( self ) -> crate :: GDExtensionVariantType {
46
+ self . ord as _
72
47
}
73
- }
74
48
75
- // ----------------------------------------------------------------------------------------------------------------------------------------------
76
-
77
- #[ derive( Copy , Clone , Eq , PartialEq , Ord , PartialOrd , Hash , Debug ) ]
78
- #[ repr( i32 ) ]
79
- pub enum VariantOperator {
80
- #(
81
- #variant_op_enumerators_pascal = #variant_op_enumerators_ord,
82
- ) *
83
- }
84
-
85
- impl VariantOperator {
86
- #[ doc( hidden) ]
87
- pub fn from_sys( enumerator: GDExtensionVariantOperator ) -> Self {
88
- match enumerator {
89
- #(
90
- #variant_op_enumerators_ord => Self :: #variant_op_enumerators_pascal,
91
- ) *
92
- _ => unreachable!( "invalid variant operator {}" , enumerator)
93
- }
94
- }
95
-
96
- #[ doc( hidden) ]
97
- pub fn sys( self ) -> GDExtensionVariantOperator {
98
- self as _
99
- }
49
+ #variant_type_deprecated_enumerators
100
50
}
101
51
}
102
52
}
103
53
104
54
pub fn make_core_central_code ( api : & ExtensionApi , ctx : & mut Context ) -> TokenStream {
105
55
let VariantEnums {
106
56
variant_ty_enumerators_pascal,
57
+ variant_ty_enumerators_shout,
107
58
variant_ty_enumerators_rust,
108
59
..
109
60
} = make_variant_enums ( api, ctx) ;
110
61
111
62
let global_enum_defs = make_global_enums ( api) ;
63
+ let variant_type_traits = make_variant_type_enum ( api, false ) . 0 ;
112
64
113
65
// TODO impl Clone, Debug, PartialEq, PartialOrd, Hash for VariantDispatch
114
66
// TODO could use try_to().unwrap_unchecked(), since type is already verified. Also directly overload from_variant().
@@ -118,6 +70,9 @@ pub fn make_core_central_code(api: &ExtensionApi, ctx: &mut Context) -> TokenStr
118
70
use crate :: engine:: Object ;
119
71
use crate :: obj:: Gd ;
120
72
73
+ // Remaining trait impls for sys::VariantType (traits only defined in godot-core).
74
+ #variant_type_traits
75
+
121
76
#[ allow( dead_code) ]
122
77
pub enum VariantDispatch {
123
78
Nil ,
@@ -129,11 +84,14 @@ pub fn make_core_central_code(api: &ExtensionApi, ctx: &mut Context) -> TokenStr
129
84
impl VariantDispatch {
130
85
pub fn from_variant( variant: & Variant ) -> Self {
131
86
match variant. get_type( ) {
132
- VariantType :: Nil => Self :: Nil ,
87
+ VariantType :: NIL => Self :: Nil ,
133
88
#(
134
- VariantType :: #variant_ty_enumerators_pascal
89
+ VariantType :: #variant_ty_enumerators_shout
135
90
=> Self :: #variant_ty_enumerators_pascal( variant. to:: <#variant_ty_enumerators_rust>( ) ) ,
136
91
) *
92
+
93
+ // Panic can be removed as soon as VariantType is a proper, non-exhaustive enum.
94
+ _ => panic!( "Variant type not supported: {:?}" , variant. get_type( ) ) ,
137
95
}
138
96
}
139
97
}
@@ -167,20 +125,8 @@ pub fn make_core_central_code(api: &ExtensionApi, ctx: &mut Context) -> TokenStr
167
125
168
126
struct VariantEnums {
169
127
variant_ty_enumerators_pascal : Vec < Ident > ,
128
+ variant_ty_enumerators_shout : Vec < Ident > ,
170
129
variant_ty_enumerators_rust : Vec < TokenStream > ,
171
- variant_ty_enumerators_ord : Vec < Literal > ,
172
- variant_op_enumerators_pascal : Vec < Ident > ,
173
- variant_op_enumerators_ord : Vec < Literal > ,
174
- }
175
-
176
- fn collect_variant_operators ( api : & ExtensionApi ) -> Vec < & Enumerator > {
177
- let variant_operator_enum = api
178
- . global_enums
179
- . iter ( )
180
- . find ( |e| & e. name == "VariantOperator" ) // in JSON: "Variant.Operator"
181
- . expect ( "missing enum for VariantOperator in JSON" ) ;
182
-
183
- variant_operator_enum. enumerators . iter ( ) . collect ( )
184
130
}
185
131
186
132
fn make_opaque_types ( api : & ExtensionApi ) -> [ Vec < TokenStream > ; 2 ] {
@@ -208,49 +154,30 @@ fn make_opaque_type(godot_original_name: &str, size: usize) -> TokenStream {
208
154
}
209
155
210
156
fn make_variant_enums ( api : & ExtensionApi , ctx : & mut Context ) -> VariantEnums {
211
- let variant_operators = collect_variant_operators ( api) ;
212
-
213
157
// Generate builtin methods, now with info for all types available.
214
158
// Separate vectors because that makes usage in quote! easier.
215
159
let len = api. builtins . len ( ) ;
216
160
217
161
let mut result = VariantEnums {
218
162
variant_ty_enumerators_pascal : Vec :: with_capacity ( len) ,
163
+ variant_ty_enumerators_shout : Vec :: with_capacity ( len) ,
219
164
variant_ty_enumerators_rust : Vec :: with_capacity ( len) ,
220
- variant_ty_enumerators_ord : Vec :: with_capacity ( len) ,
221
- variant_op_enumerators_pascal : Vec :: new ( ) ,
222
- variant_op_enumerators_ord : Vec :: new ( ) ,
223
165
} ;
224
166
225
167
// Note: NIL is not part of this iteration, it will be added manually.
226
168
for builtin in api. builtins . iter ( ) {
227
169
let original_name = builtin. godot_original_name ( ) ;
170
+ let shout_case = builtin. godot_shout_name ( ) ;
228
171
let rust_ty = conv:: to_rust_type ( original_name, None , ctx) ;
229
172
let pascal_case = conv:: to_pascal_case ( original_name) ;
230
- let ord = builtin. unsuffixed_ord_lit ( ) ;
231
173
232
174
result
233
175
. variant_ty_enumerators_pascal
234
176
. push ( ident ( & pascal_case) ) ;
177
+ result. variant_ty_enumerators_shout . push ( ident ( shout_case) ) ;
235
178
result
236
179
. variant_ty_enumerators_rust
237
180
. push ( rust_ty. to_token_stream ( ) ) ;
238
- result. variant_ty_enumerators_ord . push ( ord) ;
239
- }
240
-
241
- for op in variant_operators {
242
- let pascal_name = conv:: to_pascal_case ( & op. name . to_string ( ) ) ;
243
-
244
- let enumerator_name = if pascal_name == "Module" {
245
- ident ( "Modulo" )
246
- } else {
247
- ident ( & pascal_name)
248
- } ;
249
-
250
- result. variant_op_enumerators_pascal . push ( enumerator_name) ;
251
- result
252
- . variant_op_enumerators_ord
253
- . push ( op. value . unsuffixed_lit ( ) ) ;
254
181
}
255
182
256
183
result
@@ -260,8 +187,8 @@ fn make_global_enums(api: &ExtensionApi) -> Vec<TokenStream> {
260
187
let mut global_enum_defs = vec ! [ ] ;
261
188
262
189
for enum_ in api. global_enums . iter ( ) {
263
- // Skip those enums which are already manually handled .
264
- if enum_. name == "VariantType" || enum_ . name == "VariantOperator" {
190
+ // Skip VariantType, which is already defined in godot-ffi .
191
+ if enum_. name == "VariantType" {
265
192
continue ;
266
193
}
267
194
@@ -271,3 +198,20 @@ fn make_global_enums(api: &ExtensionApi) -> Vec<TokenStream> {
271
198
272
199
global_enum_defs
273
200
}
201
+
202
+ fn make_variant_type_enum ( api : & ExtensionApi , is_definition : bool ) -> ( TokenStream , TokenStream ) {
203
+ let variant_type_enum = api
204
+ . global_enums
205
+ . iter ( )
206
+ . find ( |e| e. name == "VariantType" )
207
+ . expect ( "missing VariantType enum in API JSON" ) ;
208
+
209
+ let define_enum = is_definition;
210
+ let define_traits = !is_definition;
211
+
212
+ let enum_definition =
213
+ enums:: make_enum_definition_with ( variant_type_enum, define_enum, define_traits) ;
214
+ let deprecated_enumerators = enums:: make_deprecated_enumerators ( variant_type_enum) ;
215
+
216
+ ( enum_definition, deprecated_enumerators)
217
+ }
0 commit comments