Skip to content

Commit

Permalink
Support tuple structs in AnimatedField (#16747)
Browse files Browse the repository at this point in the history
# Objective

Partially fixes #16736.

## Solution

`AnimatedField::new_unchecked` now supports tuple struct fields.
`animated_field!` is unchanged.

## Testing

Added a test to make sure common and simple uses of
`AnimatedField::new_unchecked` with tuple structs don't panic.

---------

Co-authored-by: yonzebu <[email protected]>
  • Loading branch information
yonzebu and yonzebu authored Dec 11, 2024
1 parent 5f1e114 commit 2994e53
Showing 1 changed file with 34 additions and 8 deletions.
42 changes: 34 additions & 8 deletions crates/bevy_animation/src/animation_curves.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,18 +243,26 @@ where

impl<C: Typed, P, F: Fn(&mut C) -> &mut P + 'static> AnimatedField<C, P, F> {
/// Creates a new instance of [`AnimatedField`]. This operates under the assumption that
/// `C` is a reflect-able struct with named fields, and that `field_name` is a valid field on that struct.
/// `C` is a reflect-able struct, and that `field_name` is a valid field on that struct.
///
/// # Panics
/// If the type of `C` is not a struct with named fields or if the `field_name` does not exist.
/// If the type of `C` is not a struct or if the `field_name` does not exist.
pub fn new_unchecked(field_name: &str, func: F) -> Self {
let TypeInfo::Struct(struct_info) = C::type_info() else {
let field_index;
if let TypeInfo::Struct(struct_info) = C::type_info() {
field_index = struct_info
.index_of(field_name)
.expect("Field name should exist");
} else if let TypeInfo::TupleStruct(struct_info) = C::type_info() {
field_index = field_name
.parse()
.expect("Field name should be a valid tuple index");
if field_index >= struct_info.field_len() {
panic!("Field name should be a valid tuple index");
}
} else {
panic!("Only structs are supported in `AnimatedField::new_unchecked`")
};

let field_index = struct_info
.index_of(field_name)
.expect("Field name should exist");
}

Self {
func,
Expand Down Expand Up @@ -984,3 +992,21 @@ macro_rules! animated_field {
})
};
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_animated_field_tuple_struct_simple_uses() {
#[derive(Clone, Debug, Component, Reflect)]
struct A(f32);
let _ = AnimatedField::new_unchecked("0", |a: &mut A| &mut a.0);

#[derive(Clone, Debug, Component, Reflect)]
struct B(f32, f64, f32);
let _ = AnimatedField::new_unchecked("0", |b: &mut B| &mut b.0);
let _ = AnimatedField::new_unchecked("1", |b: &mut B| &mut b.1);
let _ = AnimatedField::new_unchecked("2", |b: &mut B| &mut b.2);
}
}

0 comments on commit 2994e53

Please sign in to comment.