From 8a791858802577a1bc06c6ad36b2da96d2ba13cb Mon Sep 17 00:00:00 2001 From: Shane Celis Date: Tue, 23 Jul 2024 08:29:15 -0400 Subject: [PATCH] feature: Derive Hash for KeyboardInput. (#14263) # Objective Derive `Hash` for `KeyboardInput`. ## Problem I was [writing code](https://github.com/joshka/bevy_ratatui/pull/13) to take `crossterm` events and republish them as bevy input events. One scenario requires I check if the same key press was happening repeatedly; in a regular terminal we don't get key released events, so I was simulating them. I was surprised to find that I couldn't put `KeyboardInput` into a `HashSet`. ## Work Around My work around was to add a new type that implemented Hash. ```rust #[derive(Deref, DerefMut, PartialEq, Eq)] struct KeyInput(KeyboardInput); impl Hash for KeyInput { fn hash(&self, state: &mut H) where H: Hasher, { self.key_code.hash(state); self.logical_key.hash(state); self.state.hash(state); self.window.hash(state); } } ``` ## Solution A better solution since all members of `KeyboardInput` implement `Hash` is to have it derive `Hash` as well. ## Testing My newtype solution works for its purpose. --------- Co-authored-by: Alice Cecile Co-authored-by: Josh McKinney Co-authored-by: BD103 <59022059+BD103@users.noreply.github.com> --- crates/bevy_input/src/keyboard.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/crates/bevy_input/src/keyboard.rs b/crates/bevy_input/src/keyboard.rs index 23f07807cd..37d58bd476 100644 --- a/crates/bevy_input/src/keyboard.rs +++ b/crates/bevy_input/src/keyboard.rs @@ -88,8 +88,12 @@ use bevy_reflect::{ReflectDeserialize, ReflectSerialize}; /// /// The event is consumed inside of the [`keyboard_input_system`] /// to update the [`ButtonInput`](ButtonInput) resource. -#[derive(Event, Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "bevy_reflect", derive(Reflect), reflect(Debug, PartialEq))] +#[derive(Event, Debug, Clone, PartialEq, Eq, Hash)] +#[cfg_attr( + feature = "bevy_reflect", + derive(Reflect), + reflect(Debug, PartialEq, Hash) +)] #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr( all(feature = "serialize", feature = "bevy_reflect"),