From 948fa9eec2d3098e45af4f7dcb4b31378cd6d0ff Mon Sep 17 00:00:00 2001 From: Mateusz Wachowiak Date: Sun, 10 Dec 2023 20:31:15 +0100 Subject: [PATCH 1/7] Add `clear_just_pressed` in `Touches` and test for that function --- crates/bevy_input/src/touch.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/crates/bevy_input/src/touch.rs b/crates/bevy_input/src/touch.rs index 253c64d03657b..845c11b859ad4 100644 --- a/crates/bevy_input/src/touch.rs +++ b/crates/bevy_input/src/touch.rs @@ -260,6 +260,13 @@ impl Touches { self.just_pressed.contains_key(&id) } + /// Clears the `just_pressed` state of the touch input and returns `true` if the touch input has just been pressed. + /// + /// Future calls to [`Touches::just_pressed`] for the given touch input will return false until a new press event occurs. + pub fn clear_just_pressed(&mut self, id: u64) -> bool { + self.just_pressed.remove(&id).is_some() + } + /// An iterator visiting every just pressed [`Touch`] input in arbitrary order. pub fn iter_just_pressed(&self) -> impl Iterator { self.just_pressed.values() @@ -514,6 +521,9 @@ mod test { assert!(touches.get_pressed(touch_event.id).is_some()); assert!(touches.just_pressed(touch_event.id)); assert_eq!(touches.iter().count(), 1); + + touches.clear_just_pressed(touch_event.id); + assert!(!touches.just_pressed(touch_event.id)); } #[test] From 27f098440aa007ab6a6475fbae3989592ca5dafd Mon Sep 17 00:00:00 2001 From: Mateusz Wachowiak Date: Tue, 12 Dec 2023 19:10:43 +0100 Subject: [PATCH 2/7] Add `clear_just_released` in `Touches` and test for that function --- crates/bevy_input/src/touch.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/crates/bevy_input/src/touch.rs b/crates/bevy_input/src/touch.rs index 845c11b859ad4..acd6d9c224e95 100644 --- a/crates/bevy_input/src/touch.rs +++ b/crates/bevy_input/src/touch.rs @@ -287,6 +287,13 @@ impl Touches { self.just_released.contains_key(&id) } + /// Clears the `just_released` state of the touch input and returns `true` if the touch input has just been released. + /// + /// Future calls to [`Touches::just_released`] for the given touch input will return false until a new release event occurs. + pub fn clear_just_released(&mut self, id: u64) -> bool { + self.just_released.remove(&id).is_some() + } + /// An iterator visiting every just released [`Touch`] input in arbitrary order. pub fn iter_just_released(&self) -> impl Iterator { self.just_released.values() @@ -548,6 +555,9 @@ mod test { assert!(touches.get_released(touch_event.id).is_some()); assert!(touches.just_released(touch_event.id)); assert_eq!(touches.iter_just_released().count(), 1); + + touches.clear_just_released(touch_event.id); + assert!(!touches.just_released(touch_event.id)); } #[test] From 22a6ff78975f407988edb29e70bd881b38ceaad9 Mon Sep 17 00:00:00 2001 From: Mateusz Wachowiak Date: Tue, 12 Dec 2023 19:22:02 +0100 Subject: [PATCH 3/7] Add `clear_just_canceled` in `Touches` and test for that function --- crates/bevy_input/src/touch.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/crates/bevy_input/src/touch.rs b/crates/bevy_input/src/touch.rs index acd6d9c224e95..e7877bbbc7181 100644 --- a/crates/bevy_input/src/touch.rs +++ b/crates/bevy_input/src/touch.rs @@ -309,6 +309,13 @@ impl Touches { self.just_canceled.contains_key(&id) } + /// Clears the `just_canceled` state of the touch input and returns `true` if the touch input has just been canceled. + /// + /// Future calls to [`Touches::just_canceled`] for the given touch input will return false until a new cancel event occurs. + pub fn clear_just_canceled(&mut self, id: u64) -> bool { + self.just_canceled.remove(&id).is_some() + } + /// An iterator visiting every just canceled [`Touch`] input in arbitrary order. pub fn iter_just_canceled(&self) -> impl Iterator { self.just_canceled.values() @@ -581,5 +588,8 @@ mod test { assert!(touches.just_canceled(touch_event.id)); assert_eq!(touches.iter_just_canceled().count(), 1); + + touches.clear_just_canceled(touch_event.id); + assert!(!touches.just_canceled(touch_event.id)); } } From 893162411ee4c6bfdc77412525cb45ead336daf2 Mon Sep 17 00:00:00 2001 From: Mateusz Wachowiak Date: Tue, 12 Dec 2023 19:45:45 +0100 Subject: [PATCH 4/7] Add `release` in `Touches` and test for that function --- crates/bevy_input/src/touch.rs | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/crates/bevy_input/src/touch.rs b/crates/bevy_input/src/touch.rs index e7877bbbc7181..cedc40f9db40c 100644 --- a/crates/bevy_input/src/touch.rs +++ b/crates/bevy_input/src/touch.rs @@ -255,6 +255,13 @@ impl Touches { !self.just_pressed.is_empty() } + /// Register a release for a given touch input. + pub fn release(&mut self, id: u64) { + if let Some(touch) = self.pressed.remove(&id) { + self.just_released.insert(id, touch); + } + } + /// Returns `true` if the input corresponding to the `id` has just been pressed. pub fn just_pressed(&self, id: u64) -> bool { self.just_pressed.contains_key(&id) @@ -310,7 +317,7 @@ impl Touches { } /// Clears the `just_canceled` state of the touch input and returns `true` if the touch input has just been canceled. - /// + /// /// Future calls to [`Touches::just_canceled`] for the given touch input will return false until a new cancel event occurs. pub fn clear_just_canceled(&mut self, id: u64) -> bool { self.just_canceled.remove(&id).is_some() @@ -592,4 +599,28 @@ mod test { touches.clear_just_canceled(touch_event.id); assert!(!touches.just_canceled(touch_event.id)); } + + #[test] + fn release_touch() { + use crate::{touch::TouchPhase, TouchInput, Touches}; + use bevy_math::Vec2; + + let mut touches = Touches::default(); + + let touch_event = TouchInput { + phase: TouchPhase::Started, + position: Vec2::splat(4.0), + force: None, + id: 4, + }; + + // Register the touch and test that it was registered correctly + touches.process_touch_event(&touch_event); + + assert!(touches.get_pressed(touch_event.id).is_some()); + + touches.release(touch_event.id); + assert!(touches.get_pressed(touch_event.id).is_none()); + assert!(touches.just_released(touch_event.id)); + } } From 2dfaa1bd4683f8cade8696b0b941e275203bd554 Mon Sep 17 00:00:00 2001 From: Mateusz Wachowiak Date: Tue, 12 Dec 2023 20:10:18 +0100 Subject: [PATCH 5/7] Add `clear` and `reset_all` in `Touches` and tests for it --- crates/bevy_input/src/touch.rs | 111 +++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/crates/bevy_input/src/touch.rs b/crates/bevy_input/src/touch.rs index cedc40f9db40c..e5183a1427760 100644 --- a/crates/bevy_input/src/touch.rs +++ b/crates/bevy_input/src/touch.rs @@ -333,6 +333,25 @@ impl Touches { self.pressed.values().next().map(|t| t.position) } + /// Clears `just_pressed`, `just_released`, and `just_canceled` data for every touch input. + /// + /// See also [`Touches::reset_all`] for a full reset. + pub fn clear(&mut self) { + self.just_pressed.clear(); + self.just_released.clear(); + self.just_canceled.clear(); + } + + /// Clears `pressed`, `just_pressed`, `just_released`, and `just_canceled` data for every touch input. + /// + /// See also [`Touches::clear`] for clearing only touches that have just been pressed, released or canceled. + pub fn reset_all(&mut self) { + self.pressed.clear(); + self.just_pressed.clear(); + self.just_released.clear(); + self.just_canceled.clear(); + } + /// Processes a [`TouchInput`] event by updating the `pressed`, `just_pressed`, /// `just_released`, and `just_canceled` collections. fn process_touch_event(&mut self, event: &TouchInput) { @@ -623,4 +642,96 @@ mod test { assert!(touches.get_pressed(touch_event.id).is_none()); assert!(touches.just_released(touch_event.id)); } + + #[test] + fn clear_touches() { + use crate::{touch::TouchPhase, TouchInput, Touches}; + use bevy_math::Vec2; + + let mut touches = Touches::default(); + + let touch_press_event = TouchInput { + phase: TouchPhase::Started, + position: Vec2::splat(4.0), + force: None, + id: 4, + }; + + let touch_canceled_event = TouchInput { + phase: TouchPhase::Canceled, + position: Vec2::splat(4.0), + force: None, + id: 5, + }; + + let touch_released_event = TouchInput { + phase: TouchPhase::Ended, + position: Vec2::splat(4.0), + force: None, + id: 6, + }; + + // Register the touches and test that it was registered correctly + touches.process_touch_event(&touch_press_event); + touches.process_touch_event(&touch_canceled_event); + touches.process_touch_event(&touch_released_event); + + assert!(touches.get_pressed(touch_press_event.id).is_some()); + assert!(touches.just_pressed(touch_press_event.id)); + assert!(touches.just_canceled(touch_canceled_event.id)); + assert!(touches.just_released(touch_released_event.id)); + + touches.clear(); + + assert!(touches.get_pressed(touch_press_event.id).is_some()); + assert!(!touches.just_pressed(touch_press_event.id)); + assert!(!touches.just_canceled(touch_canceled_event.id)); + assert!(!touches.just_released(touch_released_event.id)); + } + + #[test] + fn reset_all_touches() { + use crate::{touch::TouchPhase, TouchInput, Touches}; + use bevy_math::Vec2; + + let mut touches = Touches::default(); + + let touch_press_event = TouchInput { + phase: TouchPhase::Started, + position: Vec2::splat(4.0), + force: None, + id: 4, + }; + + let touch_canceled_event = TouchInput { + phase: TouchPhase::Canceled, + position: Vec2::splat(4.0), + force: None, + id: 5, + }; + + let touch_released_event = TouchInput { + phase: TouchPhase::Ended, + position: Vec2::splat(4.0), + force: None, + id: 6, + }; + + // Register the touches and test that it was registered correctly + touches.process_touch_event(&touch_press_event); + touches.process_touch_event(&touch_canceled_event); + touches.process_touch_event(&touch_released_event); + + assert!(touches.get_pressed(touch_press_event.id).is_some()); + assert!(touches.just_pressed(touch_press_event.id)); + assert!(touches.just_canceled(touch_canceled_event.id)); + assert!(touches.just_released(touch_released_event.id)); + + touches.reset_all(); + + assert!(touches.get_pressed(touch_press_event.id).is_none()); + assert!(!touches.just_pressed(touch_press_event.id)); + assert!(!touches.just_canceled(touch_canceled_event.id)); + assert!(!touches.just_released(touch_released_event.id)); + } } From e7791c9c0802163591090c8ca592220344a7b4b5 Mon Sep 17 00:00:00 2001 From: Mateusz Wachowiak Date: Tue, 12 Dec 2023 20:22:47 +0100 Subject: [PATCH 6/7] Add `release_all` in `Touches` and test for it --- crates/bevy_input/src/touch.rs | 40 ++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/crates/bevy_input/src/touch.rs b/crates/bevy_input/src/touch.rs index e5183a1427760..7efdf74580aa1 100644 --- a/crates/bevy_input/src/touch.rs +++ b/crates/bevy_input/src/touch.rs @@ -262,6 +262,11 @@ impl Touches { } } + /// Registers a release for all currently pressed touch inputs. + pub fn release_all(&mut self) { + self.just_released.extend(self.pressed.drain()); + } + /// Returns `true` if the input corresponding to the `id` has just been pressed. pub fn just_pressed(&self, id: u64) -> bool { self.just_pressed.contains_key(&id) @@ -643,6 +648,41 @@ mod test { assert!(touches.just_released(touch_event.id)); } + #[test] + fn release_all_touches() { + use crate::{touch::TouchPhase, TouchInput, Touches}; + use bevy_math::Vec2; + + let mut touches = Touches::default(); + + let touch_pressed_event = TouchInput { + phase: TouchPhase::Started, + position: Vec2::splat(4.0), + force: None, + id: 4, + }; + + let touch_moved_event = TouchInput { + phase: TouchPhase::Moved, + position: Vec2::splat(4.0), + force: None, + id: 4, + }; + + touches.process_touch_event(&touch_pressed_event); + touches.process_touch_event(&touch_moved_event); + + assert!(touches.get_pressed(touch_pressed_event.id).is_some()); + assert!(touches.get_pressed(touch_moved_event.id).is_some()); + + touches.release_all(); + + assert!(touches.get_pressed(touch_pressed_event.id).is_none()); + assert!(touches.just_released(touch_pressed_event.id)); + assert!(touches.get_pressed(touch_moved_event.id).is_none()); + assert!(touches.just_released(touch_moved_event.id)); + } + #[test] fn clear_touches() { use crate::{touch::TouchPhase, TouchInput, Touches}; From dd90483303994ef756a5bbbb70cc13be7b1241b8 Mon Sep 17 00:00:00 2001 From: Mateusz Wachowiak Date: Wed, 3 Jan 2024 17:19:17 +0100 Subject: [PATCH 7/7] add window field in tests --- crates/bevy_input/src/touch.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/crates/bevy_input/src/touch.rs b/crates/bevy_input/src/touch.rs index 7efdf74580aa1..9b6a61b2bcd4e 100644 --- a/crates/bevy_input/src/touch.rs +++ b/crates/bevy_input/src/touch.rs @@ -627,6 +627,7 @@ mod test { #[test] fn release_touch() { use crate::{touch::TouchPhase, TouchInput, Touches}; + use bevy_ecs::entity::Entity; use bevy_math::Vec2; let mut touches = Touches::default(); @@ -634,6 +635,7 @@ mod test { let touch_event = TouchInput { phase: TouchPhase::Started, position: Vec2::splat(4.0), + window: Entity::PLACEHOLDER, force: None, id: 4, }; @@ -651,6 +653,7 @@ mod test { #[test] fn release_all_touches() { use crate::{touch::TouchPhase, TouchInput, Touches}; + use bevy_ecs::entity::Entity; use bevy_math::Vec2; let mut touches = Touches::default(); @@ -658,6 +661,7 @@ mod test { let touch_pressed_event = TouchInput { phase: TouchPhase::Started, position: Vec2::splat(4.0), + window: Entity::PLACEHOLDER, force: None, id: 4, }; @@ -665,6 +669,7 @@ mod test { let touch_moved_event = TouchInput { phase: TouchPhase::Moved, position: Vec2::splat(4.0), + window: Entity::PLACEHOLDER, force: None, id: 4, }; @@ -686,6 +691,7 @@ mod test { #[test] fn clear_touches() { use crate::{touch::TouchPhase, TouchInput, Touches}; + use bevy_ecs::entity::Entity; use bevy_math::Vec2; let mut touches = Touches::default(); @@ -693,6 +699,7 @@ mod test { let touch_press_event = TouchInput { phase: TouchPhase::Started, position: Vec2::splat(4.0), + window: Entity::PLACEHOLDER, force: None, id: 4, }; @@ -700,6 +707,7 @@ mod test { let touch_canceled_event = TouchInput { phase: TouchPhase::Canceled, position: Vec2::splat(4.0), + window: Entity::PLACEHOLDER, force: None, id: 5, }; @@ -707,6 +715,7 @@ mod test { let touch_released_event = TouchInput { phase: TouchPhase::Ended, position: Vec2::splat(4.0), + window: Entity::PLACEHOLDER, force: None, id: 6, }; @@ -732,6 +741,7 @@ mod test { #[test] fn reset_all_touches() { use crate::{touch::TouchPhase, TouchInput, Touches}; + use bevy_ecs::entity::Entity; use bevy_math::Vec2; let mut touches = Touches::default(); @@ -739,6 +749,7 @@ mod test { let touch_press_event = TouchInput { phase: TouchPhase::Started, position: Vec2::splat(4.0), + window: Entity::PLACEHOLDER, force: None, id: 4, }; @@ -746,6 +757,7 @@ mod test { let touch_canceled_event = TouchInput { phase: TouchPhase::Canceled, position: Vec2::splat(4.0), + window: Entity::PLACEHOLDER, force: None, id: 5, }; @@ -753,6 +765,7 @@ mod test { let touch_released_event = TouchInput { phase: TouchPhase::Ended, position: Vec2::splat(4.0), + window: Entity::PLACEHOLDER, force: None, id: 6, };