Skip to content

Commit 0aa0072

Browse files
authored
Merge pull request #726 from godot-rust/qol/variant-constants
Treat `VariantType` and `VariantOperator` like regular engine enums
2 parents 89f5052 + 0d6541e commit 0aa0072

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+385
-302
lines changed

godot-codegen/src/generator/central_files.rs

Lines changed: 45 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,18 @@
88
use crate::context::Context;
99
use crate::conv;
1010
use crate::generator::{enums, gdext_build_struct};
11-
use crate::models::domain::{Enumerator, ExtensionApi};
11+
use crate::models::domain::ExtensionApi;
1212
use crate::util::ident;
13-
use proc_macro2::{Ident, Literal, TokenStream};
13+
use proc_macro2::{Ident, TokenStream};
1414
use 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

10454
pub 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

168126
struct 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

186132
fn 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

210156
fn 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

Comments
 (0)