88use crate :: context:: Context ;
99use crate :: conv;
1010use crate :: generator:: { enums, gdext_build_struct} ;
11- use crate :: models:: domain:: { Enumerator , ExtensionApi } ;
11+ use crate :: models:: domain:: ExtensionApi ;
1212use crate :: util:: ident;
13- use proc_macro2:: { Ident , Literal , TokenStream } ;
13+ use proc_macro2:: { Ident , TokenStream } ;
1414use quote:: { format_ident, quote, ToTokens } ;
1515
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 {
2517 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 ) ;
2620 let [ opaque_32bit, opaque_64bit] = make_opaque_types ( api) ;
2721
2822 quote ! {
29- use crate :: { GDExtensionVariantOperator , GDExtensionVariantType } ;
30-
3123 #[ cfg( target_pointer_width = "32" ) ]
3224 pub mod types {
3325 #( #opaque_32bit) *
@@ -37,66 +29,24 @@ pub fn make_sys_central_code(api: &ExtensionApi, ctx: &mut Context) -> TokenStre
3729 #( #opaque_64bit) *
3830 }
3931
40-
4132 // ----------------------------------------------------------------------------------------------------------------------------------------------
4233
4334 #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
5536
5637 impl VariantType {
38+ // This will need refactoring if VariantType is changed to a real enum.
5739 #[ 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 }
6742 }
6843
6944 #[ doc( hidden) ]
70- pub fn sys( self ) -> GDExtensionVariantType {
71- self as _
45+ pub fn sys( self ) -> crate :: GDExtensionVariantType {
46+ self . ord as _
7247 }
73- }
7448
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
10050 }
10151 }
10252}
@@ -109,6 +59,7 @@ pub fn make_core_central_code(api: &ExtensionApi, ctx: &mut Context) -> TokenStr
10959 } = make_variant_enums ( api, ctx) ;
11060
11161 let global_enum_defs = make_global_enums ( api) ;
62+ let variant_type_traits = make_variant_type_enum ( api, false ) . 0 ;
11263
11364 // TODO impl Clone, Debug, PartialEq, PartialOrd, Hash for VariantDispatch
11465 // TODO could use try_to().unwrap_unchecked(), since type is already verified. Also directly overload from_variant().
@@ -118,6 +69,9 @@ pub fn make_core_central_code(api: &ExtensionApi, ctx: &mut Context) -> TokenStr
11869 use crate :: engine:: Object ;
11970 use crate :: obj:: Gd ;
12071
72+ // Remaining trait impls for sys::VariantType (traits only defined in godot-core).
73+ #variant_type_traits
74+
12175 #[ allow( dead_code) ]
12276 pub enum VariantDispatch {
12377 Nil ,
@@ -134,6 +88,9 @@ pub fn make_core_central_code(api: &ExtensionApi, ctx: &mut Context) -> TokenStr
13488 VariantType :: #variant_ty_enumerators_pascal
13589 => Self :: #variant_ty_enumerators_pascal( variant. to:: <#variant_ty_enumerators_rust>( ) ) ,
13690 ) *
91+
92+ // Panic can be removed as soon as VariantType is a proper, non-exhaustive enum.
93+ _ => panic!( "Variant type not supported: {:?}" , variant. get_type( ) ) ,
13794 }
13895 }
13996 }
@@ -168,19 +125,6 @@ pub fn make_core_central_code(api: &ExtensionApi, ctx: &mut Context) -> TokenStr
168125struct VariantEnums {
169126 variant_ty_enumerators_pascal : Vec < Ident > ,
170127 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 ( )
184128}
185129
186130fn make_opaque_types ( api : & ExtensionApi ) -> [ Vec < TokenStream > ; 2 ] {
@@ -208,49 +152,27 @@ fn make_opaque_type(godot_original_name: &str, size: usize) -> TokenStream {
208152}
209153
210154fn make_variant_enums ( api : & ExtensionApi , ctx : & mut Context ) -> VariantEnums {
211- let variant_operators = collect_variant_operators ( api) ;
212-
213155 // Generate builtin methods, now with info for all types available.
214156 // Separate vectors because that makes usage in quote! easier.
215157 let len = api. builtins . len ( ) ;
216158
217159 let mut result = VariantEnums {
218160 variant_ty_enumerators_pascal : Vec :: with_capacity ( len) ,
219161 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 ( ) ,
223162 } ;
224163
225164 // Note: NIL is not part of this iteration, it will be added manually.
226165 for builtin in api. builtins . iter ( ) {
227166 let original_name = builtin. godot_original_name ( ) ;
228167 let rust_ty = conv:: to_rust_type ( original_name, None , ctx) ;
229168 let pascal_case = conv:: to_pascal_case ( original_name) ;
230- let ord = builtin. unsuffixed_ord_lit ( ) ;
231169
232170 result
233171 . variant_ty_enumerators_pascal
234172 . push ( ident ( & pascal_case) ) ;
235173 result
236174 . variant_ty_enumerators_rust
237175 . 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 ( ) ) ;
254176 }
255177
256178 result
@@ -260,8 +182,8 @@ fn make_global_enums(api: &ExtensionApi) -> Vec<TokenStream> {
260182 let mut global_enum_defs = vec ! [ ] ;
261183
262184 for enum_ in api. global_enums . iter ( ) {
263- // Skip those enums which are already manually handled .
264- if enum_. name == "VariantType" || enum_ . name == "VariantOperator" {
185+ // Skip VariantType, which is already defined in godot-ffi .
186+ if enum_. name == "VariantType" {
265187 continue ;
266188 }
267189
@@ -271,3 +193,20 @@ fn make_global_enums(api: &ExtensionApi) -> Vec<TokenStream> {
271193
272194 global_enum_defs
273195}
196+
197+ fn make_variant_type_enum ( api : & ExtensionApi , is_definition : bool ) -> ( TokenStream , TokenStream ) {
198+ let variant_type_enum = api
199+ . global_enums
200+ . iter ( )
201+ . find ( |e| e. name == "VariantType" )
202+ . expect ( "missing VariantType enum in API JSON" ) ;
203+
204+ let define_enum = is_definition;
205+ let define_traits = !is_definition;
206+
207+ let enum_definition =
208+ enums:: make_enum_definition_with ( variant_type_enum, define_enum, define_traits) ;
209+ let deprecated_enumerators = enums:: make_deprecated_enumerators ( variant_type_enum) ;
210+
211+ ( enum_definition, deprecated_enumerators)
212+ }
0 commit comments