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
					
				@ -255,11 +255,30 @@ 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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// 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)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// 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<Item = &Touch> {
 | 
			
		||||
        self.just_pressed.values()
 | 
			
		||||
@ -280,6 +299,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<Item = &Touch> {
 | 
			
		||||
        self.just_released.values()
 | 
			
		||||
@ -295,6 +321,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<Item = &Touch> {
 | 
			
		||||
        self.just_canceled.values()
 | 
			
		||||
@ -305,6 +338,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) {
 | 
			
		||||
@ -514,6 +566,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]
 | 
			
		||||
@ -538,6 +593,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]
 | 
			
		||||
@ -561,5 +619,172 @@ 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));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[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 New Issue
	
	Block a user