mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
Extend Touches
with clear and reset methods (#10930)
# Objective - Resolves #10913. - Extend `Touches` with methods that are implemented on `ButtonInput`. ## Solution - Add function `clear_just_pressed` that clears the `just_pressed` state of the touch input. - Add function `clear_just_released` that clears the `just_released` state of the touch input. - Add function `clear_just_canceled` that clears the `just_canceled` state of the touch input. - Add function `release` that changes state of the touch input from `pressed` to `just_released`. - Add function `release_all` that changes state of every touch input from `pressed` to `just_released` - Add function `clear` that clears `just_pressed`, `just_released` and `just_canceled` data for every input. - Add function `reset_all` that clears `pressed`, `just_pressed`, `just_released` and `just_canceled` data for every input. - Add tests for functions above.
This commit is contained in:
parent
cf70f53227
commit
759b3985d8
1 changed files with 225 additions and 0 deletions
|
@ -255,11 +255,30 @@ impl Touches {
|
||||||
!self.just_pressed.is_empty()
|
!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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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.
|
/// Returns `true` if the input corresponding to the `id` has just been pressed.
|
||||||
pub fn just_pressed(&self, id: u64) -> bool {
|
pub fn just_pressed(&self, id: u64) -> bool {
|
||||||
self.just_pressed.contains_key(&id)
|
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.
|
/// An iterator visiting every just pressed [`Touch`] input in arbitrary order.
|
||||||
pub fn iter_just_pressed(&self) -> impl Iterator<Item = &Touch> {
|
pub fn iter_just_pressed(&self) -> impl Iterator<Item = &Touch> {
|
||||||
self.just_pressed.values()
|
self.just_pressed.values()
|
||||||
|
@ -280,6 +299,13 @@ impl Touches {
|
||||||
self.just_released.contains_key(&id)
|
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.
|
/// An iterator visiting every just released [`Touch`] input in arbitrary order.
|
||||||
pub fn iter_just_released(&self) -> impl Iterator<Item = &Touch> {
|
pub fn iter_just_released(&self) -> impl Iterator<Item = &Touch> {
|
||||||
self.just_released.values()
|
self.just_released.values()
|
||||||
|
@ -295,6 +321,13 @@ impl Touches {
|
||||||
self.just_canceled.contains_key(&id)
|
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.
|
/// An iterator visiting every just canceled [`Touch`] input in arbitrary order.
|
||||||
pub fn iter_just_canceled(&self) -> impl Iterator<Item = &Touch> {
|
pub fn iter_just_canceled(&self) -> impl Iterator<Item = &Touch> {
|
||||||
self.just_canceled.values()
|
self.just_canceled.values()
|
||||||
|
@ -305,6 +338,25 @@ impl Touches {
|
||||||
self.pressed.values().next().map(|t| t.position)
|
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`,
|
/// Processes a [`TouchInput`] event by updating the `pressed`, `just_pressed`,
|
||||||
/// `just_released`, and `just_canceled` collections.
|
/// `just_released`, and `just_canceled` collections.
|
||||||
fn process_touch_event(&mut self, event: &TouchInput) {
|
fn process_touch_event(&mut self, event: &TouchInput) {
|
||||||
|
@ -514,6 +566,9 @@ mod test {
|
||||||
assert!(touches.get_pressed(touch_event.id).is_some());
|
assert!(touches.get_pressed(touch_event.id).is_some());
|
||||||
assert!(touches.just_pressed(touch_event.id));
|
assert!(touches.just_pressed(touch_event.id));
|
||||||
assert_eq!(touches.iter().count(), 1);
|
assert_eq!(touches.iter().count(), 1);
|
||||||
|
|
||||||
|
touches.clear_just_pressed(touch_event.id);
|
||||||
|
assert!(!touches.just_pressed(touch_event.id));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -538,6 +593,9 @@ mod test {
|
||||||
assert!(touches.get_released(touch_event.id).is_some());
|
assert!(touches.get_released(touch_event.id).is_some());
|
||||||
assert!(touches.just_released(touch_event.id));
|
assert!(touches.just_released(touch_event.id));
|
||||||
assert_eq!(touches.iter_just_released().count(), 1);
|
assert_eq!(touches.iter_just_released().count(), 1);
|
||||||
|
|
||||||
|
touches.clear_just_released(touch_event.id);
|
||||||
|
assert!(!touches.just_released(touch_event.id));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -561,5 +619,172 @@ mod test {
|
||||||
|
|
||||||
assert!(touches.just_canceled(touch_event.id));
|
assert!(touches.just_canceled(touch_event.id));
|
||||||
assert_eq!(touches.iter_just_canceled().count(), 1);
|
assert_eq!(touches.iter_just_canceled().count(), 1);
|
||||||
|
|
||||||
|
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_ecs::entity::Entity;
|
||||||
|
use bevy_math::Vec2;
|
||||||
|
|
||||||
|
let mut touches = Touches::default();
|
||||||
|
|
||||||
|
let touch_event = TouchInput {
|
||||||
|
phase: TouchPhase::Started,
|
||||||
|
position: Vec2::splat(4.0),
|
||||||
|
window: Entity::PLACEHOLDER,
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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();
|
||||||
|
|
||||||
|
let touch_pressed_event = TouchInput {
|
||||||
|
phase: TouchPhase::Started,
|
||||||
|
position: Vec2::splat(4.0),
|
||||||
|
window: Entity::PLACEHOLDER,
|
||||||
|
force: None,
|
||||||
|
id: 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
let touch_moved_event = TouchInput {
|
||||||
|
phase: TouchPhase::Moved,
|
||||||
|
position: Vec2::splat(4.0),
|
||||||
|
window: Entity::PLACEHOLDER,
|
||||||
|
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};
|
||||||
|
use bevy_ecs::entity::Entity;
|
||||||
|
use bevy_math::Vec2;
|
||||||
|
|
||||||
|
let mut touches = Touches::default();
|
||||||
|
|
||||||
|
let touch_press_event = TouchInput {
|
||||||
|
phase: TouchPhase::Started,
|
||||||
|
position: Vec2::splat(4.0),
|
||||||
|
window: Entity::PLACEHOLDER,
|
||||||
|
force: None,
|
||||||
|
id: 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
let touch_canceled_event = TouchInput {
|
||||||
|
phase: TouchPhase::Canceled,
|
||||||
|
position: Vec2::splat(4.0),
|
||||||
|
window: Entity::PLACEHOLDER,
|
||||||
|
force: None,
|
||||||
|
id: 5,
|
||||||
|
};
|
||||||
|
|
||||||
|
let touch_released_event = TouchInput {
|
||||||
|
phase: TouchPhase::Ended,
|
||||||
|
position: Vec2::splat(4.0),
|
||||||
|
window: Entity::PLACEHOLDER,
|
||||||
|
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_ecs::entity::Entity;
|
||||||
|
use bevy_math::Vec2;
|
||||||
|
|
||||||
|
let mut touches = Touches::default();
|
||||||
|
|
||||||
|
let touch_press_event = TouchInput {
|
||||||
|
phase: TouchPhase::Started,
|
||||||
|
position: Vec2::splat(4.0),
|
||||||
|
window: Entity::PLACEHOLDER,
|
||||||
|
force: None,
|
||||||
|
id: 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
let touch_canceled_event = TouchInput {
|
||||||
|
phase: TouchPhase::Canceled,
|
||||||
|
position: Vec2::splat(4.0),
|
||||||
|
window: Entity::PLACEHOLDER,
|
||||||
|
force: None,
|
||||||
|
id: 5,
|
||||||
|
};
|
||||||
|
|
||||||
|
let touch_released_event = TouchInput {
|
||||||
|
phase: TouchPhase::Ended,
|
||||||
|
position: Vec2::splat(4.0),
|
||||||
|
window: Entity::PLACEHOLDER,
|
||||||
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue