Skip to content

Commit 7d9e864

Browse files
implement Reflect for Input<T>, some misc improvements to reflect value derive (bevyengine#5676)
# Objective - I'm currently working on being able to call methods on reflect types (https://github.com/jakobhellermann/bevy_reflect_fns) - for that, I'd like to add methods to the `Input<KeyCode>` resource (which I'm doing by registering type data) - implementing `Reflect` is currently a requirement for having type data in the `TypeRegistry` ## Solution - derive `Reflect` for `KeyCode` and `Input` - uses `#[reflect_value]` for `Input`, since it's fields aren't supposed to be observable - using reflect_value would need `Clone` bounds on `T`, but since all the methods (`.pressed` etc) already require `T: Copy`, I unified everything to requiring `Copy` - add `Send + Sync + 'static` bounds, also required by reflect derive ## Unrelated improvements I can extract into a separate PR if needed. - the `Reflect` derive would previously ignore `#[reflect_value]` and only accept `#[reflect_value()]` which was a bit confusing - the generated code used `val.clone()` on a reference, which is fine if `val` impls `Clone`, but otherwise also compiles with a worse error message. Change to `std::clone::Clone::clone(val)` instead which gives a neat `T does not implement Clone` error
1 parent 7a92555 commit 7d9e864

File tree

4 files changed

+21
-17
lines changed

4 files changed

+21
-17
lines changed

crates/bevy_input/src/input.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use bevy_ecs::system::Resource;
2+
use bevy_reflect::Reflect;
23
use bevy_utils::HashSet;
34
use std::hash::Hash;
45

@@ -33,8 +34,9 @@ use bevy_ecs::schedule::State;
3334
/// * Call the [`Input::press`] method for each press event.
3435
/// * Call the [`Input::release`] method for each release event.
3536
/// * Call the [`Input::clear`] method at each frame start, before processing events.
36-
#[derive(Debug, Clone, Resource)]
37-
pub struct Input<T: Eq + Hash> {
37+
#[derive(Debug, Clone, Resource, Reflect)]
38+
#[reflect_value]
39+
pub struct Input<T: Copy + Eq + Hash + Send + Sync + 'static> {
3840
/// A collection of every button that is currently being pressed.
3941
pressed: HashSet<T>,
4042
/// A collection of every button that has just been pressed.
@@ -43,7 +45,7 @@ pub struct Input<T: Eq + Hash> {
4345
just_released: HashSet<T>,
4446
}
4547

46-
impl<T: Eq + Hash> Default for Input<T> {
48+
impl<T: Copy + Eq + Hash + Send + Sync + 'static> Default for Input<T> {
4749
fn default() -> Self {
4850
Self {
4951
pressed: Default::default(),
@@ -55,7 +57,7 @@ impl<T: Eq + Hash> Default for Input<T> {
5557

5658
impl<T> Input<T>
5759
where
58-
T: Copy + Eq + Hash,
60+
T: Copy + Eq + Hash + Send + Sync + 'static,
5961
{
6062
/// Registers a press for the given `input`.
6163
pub fn press(&mut self, input: T) {

crates/bevy_input/src/keyboard.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::{ButtonState, Input};
22
use bevy_ecs::{event::EventReader, system::ResMut};
3+
use bevy_reflect::{FromReflect, Reflect};
34

45
/// A keyboard input event.
56
///
@@ -60,8 +61,9 @@ pub fn keyboard_input_system(
6061
/// ## Updating
6162
///
6263
/// The resource is updated inside of the [`keyboard_input_system`](crate::keyboard::keyboard_input_system).
63-
#[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy)]
64+
#[derive(Reflect, FromReflect, Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy)]
6465
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
66+
#[reflect(Hash, PartialEq)]
6567
#[repr(u32)]
6668
pub enum KeyCode {
6769
/// The `1` key over the letters.
@@ -422,6 +424,7 @@ pub enum KeyCode {
422424
/// ## Updating
423425
///
424426
/// The resource is updated inside of the [`keyboard_input_system`](crate::keyboard::keyboard_input_system).
425-
#[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy)]
427+
#[derive(Reflect, FromReflect, Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy)]
428+
#[reflect(Hash, PartialEq)]
426429
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
427430
pub struct ScanCode(pub u32);

crates/bevy_reflect/bevy_reflect_derive/src/derive_data.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -111,19 +111,18 @@ impl<'a> ReflectDerive<'a> {
111111
let mut force_reflect_value = false;
112112

113113
for attribute in input.attrs.iter().filter_map(|attr| attr.parse_meta().ok()) {
114-
let meta_list = if let Meta::List(meta_list) = attribute {
115-
meta_list
116-
} else {
117-
continue;
118-
};
119-
120-
if let Some(ident) = meta_list.path.get_ident() {
121-
if ident == REFLECT_ATTRIBUTE_NAME {
114+
match attribute {
115+
Meta::List(meta_list) if meta_list.path.is_ident(REFLECT_ATTRIBUTE_NAME) => {
122116
traits = ReflectTraits::from_nested_metas(&meta_list.nested);
123-
} else if ident == REFLECT_VALUE_ATTRIBUTE_NAME {
117+
}
118+
Meta::List(meta_list) if meta_list.path.is_ident(REFLECT_VALUE_ATTRIBUTE_NAME) => {
124119
force_reflect_value = true;
125120
traits = ReflectTraits::from_nested_metas(&meta_list.nested);
126121
}
122+
Meta::Path(path) if path.is_ident(REFLECT_VALUE_ATTRIBUTE_NAME) => {
123+
force_reflect_value = true;
124+
}
125+
_ => continue,
127126
}
128127
}
129128

crates/bevy_reflect/bevy_reflect_derive/src/impls/values.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,14 @@ pub(crate) fn impl_value(meta: &ReflectMeta) -> TokenStream {
6868

6969
#[inline]
7070
fn clone_value(&self) -> Box<dyn #bevy_reflect_path::Reflect> {
71-
Box::new(self.clone())
71+
Box::new(std::clone::Clone::clone(self))
7272
}
7373

7474
#[inline]
7575
fn apply(&mut self, value: &dyn #bevy_reflect_path::Reflect) {
7676
let value = value.as_any();
7777
if let Some(value) = value.downcast_ref::<Self>() {
78-
*self = value.clone();
78+
*self = std::clone::Clone::clone(value);
7979
} else {
8080
panic!("Value is not {}.", std::any::type_name::<Self>());
8181
}

0 commit comments

Comments
 (0)