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,78 +29,38 @@ 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}
10353
10454pub fn make_core_central_code ( api : & ExtensionApi , ctx : & mut Context ) -> TokenStream {
10555 let VariantEnums {
10656 variant_ty_enumerators_pascal,
57+ variant_ty_enumerators_shout,
10758 variant_ty_enumerators_rust,
10859 ..
10960 } = make_variant_enums ( api, ctx) ;
11061
11162 let global_enum_defs = make_global_enums ( api) ;
63+ let variant_type_traits = make_variant_type_enum ( api, false ) . 0 ;
11264
11365 // TODO impl Clone, Debug, PartialEq, PartialOrd, Hash for VariantDispatch
11466 // 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
11870 use crate :: engine:: Object ;
11971 use crate :: obj:: Gd ;
12072
73+ // Remaining trait impls for sys::VariantType (traits only defined in godot-core).
74+ #variant_type_traits
75+
12176 #[ allow( dead_code) ]
12277 pub enum VariantDispatch {
12378 Nil ,
@@ -129,11 +84,14 @@ pub fn make_core_central_code(api: &ExtensionApi, ctx: &mut Context) -> TokenStr
12984 impl VariantDispatch {
13085 pub fn from_variant( variant: & Variant ) -> Self {
13186 match variant. get_type( ) {
132- VariantType :: Nil => Self :: Nil ,
87+ VariantType :: NIL => Self :: Nil ,
13388 #(
134- VariantType :: #variant_ty_enumerators_pascal
89+ VariantType :: #variant_ty_enumerators_shout
13590 => Self :: #variant_ty_enumerators_pascal( variant. to:: <#variant_ty_enumerators_rust>( ) ) ,
13691 ) *
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( ) ) ,
13795 }
13896 }
13997 }
@@ -167,20 +125,8 @@ pub fn make_core_central_code(api: &ExtensionApi, ctx: &mut Context) -> TokenStr
167125
168126struct VariantEnums {
169127 variant_ty_enumerators_pascal : Vec < Ident > ,
128+ variant_ty_enumerators_shout : Vec < Ident > ,
170129 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 ( )
184130}
185131
186132fn make_opaque_types ( api : & ExtensionApi ) -> [ Vec < TokenStream > ; 2 ] {
@@ -208,49 +154,30 @@ fn make_opaque_type(godot_original_name: &str, size: usize) -> TokenStream {
208154}
209155
210156fn make_variant_enums ( api : & ExtensionApi , ctx : & mut Context ) -> VariantEnums {
211- let variant_operators = collect_variant_operators ( api) ;
212-
213157 // Generate builtin methods, now with info for all types available.
214158 // Separate vectors because that makes usage in quote! easier.
215159 let len = api. builtins . len ( ) ;
216160
217161 let mut result = VariantEnums {
218162 variant_ty_enumerators_pascal : Vec :: with_capacity ( len) ,
163+ variant_ty_enumerators_shout : Vec :: with_capacity ( len) ,
219164 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 ( ) ,
223165 } ;
224166
225167 // Note: NIL is not part of this iteration, it will be added manually.
226168 for builtin in api. builtins . iter ( ) {
227169 let original_name = builtin. godot_original_name ( ) ;
170+ let shout_case = builtin. godot_shout_name ( ) ;
228171 let rust_ty = conv:: to_rust_type ( original_name, None , ctx) ;
229172 let pascal_case = conv:: to_pascal_case ( original_name) ;
230- let ord = builtin. unsuffixed_ord_lit ( ) ;
231173
232174 result
233175 . variant_ty_enumerators_pascal
234176 . push ( ident ( & pascal_case) ) ;
177+ result. variant_ty_enumerators_shout . push ( ident ( shout_case) ) ;
235178 result
236179 . variant_ty_enumerators_rust
237180 . 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 ( ) ) ;
254181 }
255182
256183 result
@@ -260,8 +187,8 @@ fn make_global_enums(api: &ExtensionApi) -> Vec<TokenStream> {
260187 let mut global_enum_defs = vec ! [ ] ;
261188
262189 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" {
265192 continue ;
266193 }
267194
@@ -271,3 +198,20 @@ fn make_global_enums(api: &ExtensionApi) -> Vec<TokenStream> {
271198
272199 global_enum_defs
273200}
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