Skip to content

Commit

Permalink
Revert "Merge pull request godot-rust#524 from Lemiczek/bitflags_u64_…
Browse files Browse the repository at this point in the history
…type"

This reverts commit ef8b2b4, reversing
changes made to 7dee976.
  • Loading branch information
TCROC committed Dec 6, 2023
1 parent 83feabc commit a188893
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 137 deletions.
6 changes: 0 additions & 6 deletions godot-codegen/src/codegen_special_cases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,6 @@ fn is_type_excluded(ty: &str, ctx: &mut Context) -> bool {
None => false,
Some(class) => is_class_excluded(class.as_str()),
},
RustTy::EngineBitfield {
surrounding_class, ..
} => match surrounding_class.as_ref() {
None => false,
Some(class) => is_class_excluded(class.as_str()),
},
RustTy::EngineClass { inner_class, .. } => is_class_excluded(&inner_class.to_string()),
}
}
Expand Down
9 changes: 0 additions & 9 deletions godot-codegen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,14 +185,6 @@ enum RustTy {
surrounding_class: Option<String>,
},

/// `module::Bitfield`
EngineBitfield {
tokens: TokenStream,
/// `None` for globals
#[allow(dead_code)] // only read in minimal config
surrounding_class: Option<String>,
},

/// `Gd<Node>`
EngineClass {
/// Tokens with full `Gd<T>`
Expand Down Expand Up @@ -227,7 +219,6 @@ impl ToTokens for RustTy {
} => quote! { *mut #inner }.to_tokens(tokens),
RustTy::EngineArray { tokens: path, .. } => path.to_tokens(tokens),
RustTy::EngineEnum { tokens: path, .. } => path.to_tokens(tokens),
RustTy::EngineBitfield { tokens: path, .. } => path.to_tokens(tokens),
RustTy::EngineClass { tokens: path, .. } => path.to_tokens(tokens),
}
}
Expand Down
164 changes: 60 additions & 104 deletions godot-codegen/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,37 +241,8 @@ pub fn make_enum_definition(enum_: &Enum) -> TokenStream {
unique_ords.sort();
unique_ords.dedup();

let mut derives = vec!["Copy", "Clone", "Eq", "PartialEq", "Hash", "Debug"];

if enum_.is_bitfield {
derives.push("Default");
}

let derives = derives.into_iter().map(ident);

let index_enum_impl = if enum_.is_bitfield {
// Bitfields don't implement IndexEnum.
TokenStream::new()
} else {
// Enums implement IndexEnum only if they are "index-like" (see docs).
if let Some(enum_max) = try_count_index_enum(enum_) {
quote! {
impl crate::obj::IndexEnum for #enum_name {
const ENUMERATOR_COUNT: usize = #enum_max;
}
}
} else {
TokenStream::new()
}
};

let bitfield_ops;
let self_as_trait;
let engine_impl;
let enum_ord_type;

if enum_.is_bitfield {
bitfield_ops = quote! {
let bitfield_ops = if enum_.is_bitfield {
let tokens = quote! {
// impl #enum_name {
// pub const UNSET: Self = Self { ord: 0 };
// }
Expand All @@ -283,85 +254,97 @@ pub fn make_enum_definition(enum_: &Enum) -> TokenStream {
}
}
};
enum_ord_type = quote! { u64 };
self_as_trait = quote! { <Self as crate::obj::EngineBitfield> };
engine_impl = quote! {
impl crate::obj::EngineBitfield for #enum_name {
fn try_from_ord(ord: u64) -> Option<Self> {
Some(Self { ord })
}

fn ord(self) -> u64 {
self.ord
}
Some(tokens)
} else {
None
};

let try_from_ord = if enum_.is_bitfield {
quote! {
fn try_from_ord(ord: i32) -> Option<Self> {
Some(Self { ord })
}
};
}
} else {
bitfield_ops = TokenStream::new();
enum_ord_type = quote! { i32 };
self_as_trait = quote! { <Self as crate::obj::EngineEnum> };
engine_impl = quote! {
impl crate::obj::EngineEnum for #enum_name {
// fn try_from_ord(ord: i32) -> Option<Self> {
// match ord {
// #(
// #matches
// )*
// _ => None,
// }
// }

fn try_from_ord(ord: i32) -> Option<Self> {
match ord {
#( ord @ #unique_ords )|* => Some(Self { ord }),
_ => None,
}
quote! {
fn try_from_ord(ord: i32) -> Option<Self> {
match ord {
#( ord @ #unique_ords )|* => Some(Self { ord }),
_ => None,
}
}
}
};

fn ord(self) -> i32 {
self.ord
}
let mut derives = vec!["Copy", "Clone", "Eq", "PartialEq", "Debug", "Hash"];

if enum_.is_bitfield {
derives.push("Default");
}

let index_enum_impl = if let Some(enum_max) = try_count_index_enum(enum_) {
quote! {
impl crate::obj::IndexEnum for #enum_name {
const ENUMERATOR_COUNT: usize = #enum_max;
}
};
}
} else {
TokenStream::new()
};

let derives = derives.into_iter().map(ident);

// Enumerator ordinal stored as i32, since that's enough to hold all current values and the default repr in C++.
// Public interface is i64 though, for consistency (and possibly forward compatibility?).
// Bitfield ordinals are stored as u64. See also: https://github.com/godotengine/godot-cpp/pull/1320
// TODO maybe generalize GodotFfi over EngineEnum trait
quote! {
#[repr(transparent)]
#[derive(#( #derives ),*)]
pub struct #enum_name {
ord: #enum_ord_type
ord: i32
}
impl #enum_name {
#(
#enumerators
)*
}
impl crate::obj::EngineEnum for #enum_name {
// fn try_from_ord(ord: i32) -> Option<Self> {
// match ord {
// #(
// #matches
// )*
// _ => None,
// }
// }

#engine_impl

#bitfield_ops
#try_from_ord

fn ord(self) -> i32 {
self.ord
}
}
#index_enum_impl

impl crate::builtin::meta::GodotConvert for #enum_name {
type Via = #enum_ord_type;
type Via = i32;
}

impl crate::builtin::meta::ToGodot for #enum_name {
fn to_godot(&self) -> Self::Via {
#self_as_trait::ord(*self)
<Self as crate::obj::EngineEnum>::ord(*self)
}
}

impl crate::builtin::meta::FromGodot for #enum_name {
fn try_from_godot(via: Self::Via) -> std::result::Result<Self, crate::builtin::meta::ConvertError> {
#self_as_trait::try_from_ord(via)
<Self as crate::obj::EngineEnum>::try_from_ord(via)
.ok_or_else(|| crate::builtin::meta::FromGodotError::InvalidEnum.into_error(via))
}
}

#bitfield_ops
}
}

Expand Down Expand Up @@ -687,28 +670,11 @@ fn to_rust_type_uncached(full_ty: &GodotTy, ctx: &mut Context) -> RustTy {
};
}

if let Some(bitfield) = ty.strip_prefix("bitfield::") {
return if let Some((class, enum_)) = bitfield.split_once('.') {
// Class-local bitfield.
let module = ModName::from_godot(class);
let bitfield_ty = make_enum_name(enum_);

RustTy::EngineBitfield {
tokens: quote! { crate::engine::#module::#bitfield_ty},
surrounding_class: Some(class.to_string()),
}
} else {
// Global bitfield.
let bitfield_ty = make_enum_name(bitfield);

RustTy::EngineBitfield {
tokens: quote! { crate::engine::global::#bitfield_ty },
surrounding_class: None,
}
};
}
let qualified_enum = ty
.strip_prefix("enum::")
.or_else(|| ty.strip_prefix("bitfield::"));

if let Some(qualified_enum) = ty.strip_prefix("enum::") {
if let Some(qualified_enum) = qualified_enum {
return if let Some((class, enum_)) = qualified_enum.split_once('.') {
// Class-local enum
let module = ModName::from_godot(class);
Expand Down Expand Up @@ -833,7 +799,6 @@ fn to_rust_expr_inner(expr: &str, ty: &RustTy, is_inner: bool) -> TokenStream {
if let Ok(num) = expr.parse::<i64>() {
let lit = Literal::i64_unsuffixed(num);
return match ty {
RustTy::EngineBitfield { .. } => quote! { crate::obj::EngineBitfield::from_ord(#lit) },
RustTy::EngineEnum { .. } => quote! { crate::obj::EngineEnum::from_ord(#lit) },
RustTy::BuiltinIdent(ident) if ident == "Variant" => quote! { Variant::from(#lit) },
RustTy::BuiltinIdent(ident)
Expand Down Expand Up @@ -983,12 +948,6 @@ fn gdscript_to_rust_expr() {
};
let ty_enum = Some(&ty_enum);

let ty_bitfield = RustTy::EngineBitfield {
tokens: quote! { SomeEnum },
surrounding_class: None,
};
let ty_bitfield = Some(&ty_bitfield);

let ty_variant = RustTy::BuiltinIdent(ident("Variant"));
let ty_variant = Some(&ty_variant);

Expand Down Expand Up @@ -1038,9 +997,6 @@ fn gdscript_to_rust_expr() {
// enum (from int)
("7", ty_enum, quote! { crate::obj::EngineEnum::from_ord(7) }),

// bitfield (from int)
("7", ty_bitfield, quote! { crate::obj::EngineBitfield::from_ord(7) }),

// Variant (from int)
("8", ty_variant, quote! { Variant::from(8) }),

Expand Down
1 change: 0 additions & 1 deletion godot-core/src/builtin/meta/godot_convert/convert_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,6 @@ pub(crate) enum FromGodotError {
expected: array_inner::TypeInfo,
got: array_inner::TypeInfo,
},
/// InvalidEnum is also used by bitfields.
InvalidEnum,
ZeroInstanceId,
}
Expand Down
2 changes: 0 additions & 2 deletions godot-core/src/builtin/meta/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,6 @@ pub struct PropertyInfo {
impl PropertyInfo {
/// Converts to the FFI type. Keep this object allocated while using that!
pub fn property_sys(&self) -> sys::GDExtensionPropertyInfo {
use crate::obj::EngineBitfield as _;
use crate::obj::EngineEnum as _;

sys::GDExtensionPropertyInfo {
Expand All @@ -262,7 +261,6 @@ impl PropertyInfo {
}

pub fn empty_sys() -> sys::GDExtensionPropertyInfo {
use crate::obj::EngineBitfield as _;
use crate::obj::EngineEnum as _;

sys::GDExtensionPropertyInfo {
Expand Down
2 changes: 1 addition & 1 deletion godot-core/src/builtin/meta/registration/method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ impl ClassMethodInfo {
}

pub fn register_extension_class_method(&self) {
use crate::obj::EngineBitfield as _;
use crate::obj::EngineEnum as _;

let (return_value_info, return_value_metadata) = match &self.return_value {
Some(info) => (Some(&info.info), info.metadata),
Expand Down
13 changes: 0 additions & 13 deletions godot-core/src/obj/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,19 +182,6 @@ pub trait EngineEnum: Copy {
}
}

/// Auto-implemented for all engine-provided bitfields.
pub trait EngineBitfield: Copy {
fn try_from_ord(ord: u64) -> Option<Self>;

/// Ordinal value of the bit flag, as specified in Godot.
fn ord(self) -> u64;

fn from_ord(ord: u64) -> Self {
Self::try_from_ord(ord)
.unwrap_or_else(|| panic!("ordinal {ord} does not map to any valid bit flag"))
}
}

/// Trait for enums that can be used as indices in arrays.
///
/// The conditions for a Godot enum to be "index-like" are:
Expand Down
1 change: 0 additions & 1 deletion godot/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,6 @@ pub mod prelude {

// Make trait methods available
pub use super::engine::NodeExt as _;
pub use super::obj::EngineBitfield as _;
pub use super::obj::EngineEnum as _;
pub use super::obj::UserClass as _; // new_gd(), alloc_gd()
pub use super::obj::WithBaseField as _; // to_gd()
Expand Down

0 comments on commit a188893

Please sign in to comment.