Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions godot-codegen/src/generator/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,18 @@ pub fn make_enum_definition_with(
let index_enum_impl = make_enum_index_impl(enum_);
let bitwise_impls = make_enum_bitwise_operators(enum_, enum_bitmask.as_ref());

let special_default_impl = if let Some(override_default) = enum_.override_default.as_ref() {
quote! {
impl Default for #name {
fn default() -> Self {
#override_default
}
}
}
} else {
TokenStream::new()
};

let var_trait_set = if enum_.is_exhaustive {
quote! {
fn var_set(field: &mut Self, value: Self::Via) {
Expand Down Expand Up @@ -144,6 +156,7 @@ pub fn make_enum_definition_with(
#engine_trait_impl
#index_enum_impl
#bitwise_impls
#special_default_impl

impl crate::meta::GodotConvert for #name {
type Via = #ord_type;
Expand Down
3 changes: 2 additions & 1 deletion godot-codegen/src/models/domain/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub struct Enum {
pub godot_name: String,
pub surrounding_class: Option<TyName>,
pub is_bitfield: bool,
pub override_default: Option<TokenStream>,
pub is_private: bool,
pub is_exhaustive: bool,
pub enumerators: Vec<Enumerator>,
Expand All @@ -33,7 +34,7 @@ impl Enum {
// Debug is implemented manually, using enumerator name. This can be derived once we use proper enums.
let mut derives = vec!["Copy", "Clone", "Eq", "PartialEq", "Hash"];

if self.is_bitfield {
if self.is_bitfield && self.override_default.is_none() {
derives.push("Default");
}

Expand Down
3 changes: 3 additions & 0 deletions godot-codegen/src/models/domain_mapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,8 @@ impl Enum {
.unwrap_or(json_is_bitfield);
let is_private = special_cases::is_enum_private(surrounding_class, &godot_name);
let is_exhaustive = special_cases::is_enum_exhaustive(surrounding_class, &godot_name);
let override_default =
special_cases::does_enum_have_special_default(surrounding_class, &godot_name);

let rust_enum_name = conv::make_enum_name_str(&godot_name);
let rust_enumerator_names = {
Expand Down Expand Up @@ -800,6 +802,7 @@ impl Enum {
godot_name,
surrounding_class: surrounding_class.cloned(),
is_bitfield,
override_default,
is_private,
is_exhaustive,
enumerators,
Expand Down
21 changes: 21 additions & 0 deletions godot-codegen/src/special_cases/special_cases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1361,6 +1361,27 @@ pub fn is_enum_bitfield(class_name: Option<&TyName>, enum_name: &str) -> Option<
}
}

/// For types where a [`Default`](Default) is helpful, but the default value should
/// be something other than what would be returned by a `#[derive(Default)]` implementation.
///
/// An example of this is `DuplicateFlags`, where the default flags to `duplicate` are non-zero,
/// so if one wants to use "all flags except one" in `duplicate_ex`, the most natural way to do
/// so would be to pass `DuplicateFlags::default() & !DuplicateFlags::USE_INSTATANTIATION` to `flags`.
///
/// * `Some(TokenStream)` -> function body which will be psted into the `Default::default` implementation.
/// * `None` -> no special default, i.e. if a Default is generated it will be with an automatic derive.
#[rustfmt::skip]
pub fn does_enum_have_special_default(class_name: Option<&TyName>, enum_name: &str) -> Option<TokenStream> {
let class_name = class_name.map(|c| c.godot_ty.as_str());
match (class_name, enum_name) {
(Some("Node"), "DuplicateFlags") => Some(quote! {
Self::SIGNALS | Self::GROUPS | Self::SCRIPTS | Self::USE_INSTANTIATION
}),

_ => None
}
}

/// Whether an enum can be combined with another enum (return value) for bitmasking purposes.
///
/// If multiple masks are ever necessary, this can be extended to return a slice instead of Option.
Expand Down
Loading