Update touch.rs docs (#4523)
# Objective - Part of the splitting process of #3692. ## Solution - Document `touch.rs` inside of `bevy_input`.
This commit is contained in:
parent
06d709b178
commit
b3e39d0a19
@ -3,38 +3,45 @@ use bevy_ecs::system::ResMut;
|
|||||||
use bevy_math::Vec2;
|
use bevy_math::Vec2;
|
||||||
use bevy_utils::HashMap;
|
use bevy_utils::HashMap;
|
||||||
|
|
||||||
/// Represents a touch event
|
/// A touch input event.
|
||||||
///
|
///
|
||||||
/// Every time the user touches the screen, a new `Start` event with an unique
|
/// ## Logic
|
||||||
/// identifier for the finger is generated. When the finger is lifted, an `End`
|
///
|
||||||
|
/// Every time the user touches the screen, a new [`TouchPhase::Started`] event with an unique
|
||||||
|
/// identifier for the finger is generated. When the finger is lifted, the [`TouchPhase::Ended`]
|
||||||
/// event is generated with the same finger id.
|
/// event is generated with the same finger id.
|
||||||
///
|
///
|
||||||
/// After a `Start` event has been emitted, there may be zero or more `Move`
|
/// After a [`TouchPhase::Started`] event has been emitted, there may be zero or more [`TouchPhase::Moved`]
|
||||||
/// events when the finger is moved or the touch pressure changes.
|
/// events when the finger is moved or the touch pressure changes.
|
||||||
///
|
///
|
||||||
/// The finger id may be reused by the system after an `End` event. The user
|
/// The finger id may be reused by the system after an [`TouchPhase::Ended`] event. The user
|
||||||
/// should assume that a new `Start` event received with the same id has nothing
|
/// should assume that a new [`TouchPhase::Started`] event received with the same id has nothing
|
||||||
/// to do with the old finger and is a new finger.
|
/// to do with the old finger and is a new finger.
|
||||||
///
|
///
|
||||||
/// A `Cancelled` event is emitted when the system has canceled tracking this
|
/// A [`TouchPhase::Cancelled`] event is emitted when the system has canceled tracking this
|
||||||
/// touch, such as when the window loses focus, or on iOS if the user moves the
|
/// touch, such as when the window loses focus, or on iOS if the user moves the
|
||||||
/// device against their face.
|
/// device against their face.
|
||||||
|
///
|
||||||
|
/// ## Note
|
||||||
|
///
|
||||||
|
/// This event is the translated version of the `WindowEvent::Touch` from the `winit` crate.
|
||||||
|
/// It is available to the end user and can be used for game logic.
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub struct TouchInput {
|
pub struct TouchInput {
|
||||||
|
/// The phase of the touch input.
|
||||||
pub phase: TouchPhase,
|
pub phase: TouchPhase,
|
||||||
|
/// The position of the finger on the touchscreen.
|
||||||
pub position: Vec2,
|
pub position: Vec2,
|
||||||
/// Describes how hard the screen was pressed. May be `None` if the platform
|
/// Describes how hard the screen was pressed.
|
||||||
/// does not support pressure sensitivity.
|
|
||||||
///
|
///
|
||||||
/// ## Platform-specific
|
/// May be [`None`] if the platform does not support pressure sensitivity.
|
||||||
///
|
/// This feature is only available on **iOS** 9.0+ and **Windows** 8+.
|
||||||
/// - Only available on **iOS** 9.0+ and **Windows** 8+.
|
|
||||||
pub force: Option<ForceTouch>,
|
pub force: Option<ForceTouch>,
|
||||||
/// Unique identifier of a finger.
|
/// The unique identifier of the finger.
|
||||||
pub id: u64,
|
pub id: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Describes the force of a touch event
|
/// A force description of a [`Touch`](crate::touch::Touch) input.
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub enum ForceTouch {
|
pub enum ForceTouch {
|
||||||
/// On iOS, the force is calibrated so that the same number corresponds to
|
/// On iOS, the force is calibrated so that the same number corresponds to
|
||||||
@ -63,65 +70,107 @@ pub enum ForceTouch {
|
|||||||
/// If the platform reports the force as normalized, we have no way of
|
/// If the platform reports the force as normalized, we have no way of
|
||||||
/// knowing how much pressure 1.0 corresponds to – we know it's the maximum
|
/// knowing how much pressure 1.0 corresponds to – we know it's the maximum
|
||||||
/// amount of force, but as to how much force, you might either have to
|
/// amount of force, but as to how much force, you might either have to
|
||||||
/// press really really hard, or not hard at all, depending on the device.
|
/// press really hard, or not hard at all, depending on the device.
|
||||||
Normalized(f64),
|
Normalized(f64),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Describes touch-screen input state.
|
/// A phase of a [`TouchInput`](crate::touch::TouchInput).
|
||||||
|
///
|
||||||
|
/// ## Usage
|
||||||
|
///
|
||||||
|
/// It is used to describe the phase of the touch input that is currently active.
|
||||||
|
/// This includes a phase that indicates that a touch input has started or ended,
|
||||||
|
/// or that a finger has moved. There is also a cancelled phase that indicates that
|
||||||
|
/// the system cancelled the tracking of the finger.
|
||||||
#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
|
#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
|
||||||
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
|
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
|
||||||
pub enum TouchPhase {
|
pub enum TouchPhase {
|
||||||
|
/// A finger started to touch the touchscreen.
|
||||||
Started,
|
Started,
|
||||||
|
/// A finger moved over the touchscreen.
|
||||||
Moved,
|
Moved,
|
||||||
|
/// A finger stopped touching the touchscreen.
|
||||||
Ended,
|
Ended,
|
||||||
|
/// The system cancelled the tracking of the finger.
|
||||||
|
///
|
||||||
|
/// This occurs when the window loses focus, or on iOS if the user moves the
|
||||||
|
/// device against their face.
|
||||||
Cancelled,
|
Cancelled,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A touch input.
|
||||||
|
///
|
||||||
|
/// ## Usage
|
||||||
|
///
|
||||||
|
/// It is used to store the position and force of a touch input and also the `id` of the finger.
|
||||||
|
/// The data of the touch input comes from the [`TouchInput`] event and is being stored
|
||||||
|
/// inside of the [`Touches`] `bevy` resource.
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct Touch {
|
pub struct Touch {
|
||||||
|
/// The id of the touch input.
|
||||||
id: u64,
|
id: u64,
|
||||||
|
/// The starting position of the touch input.
|
||||||
start_position: Vec2,
|
start_position: Vec2,
|
||||||
|
/// The starting force of the touch input.
|
||||||
start_force: Option<ForceTouch>,
|
start_force: Option<ForceTouch>,
|
||||||
|
/// The previous position of the touch input.
|
||||||
previous_position: Vec2,
|
previous_position: Vec2,
|
||||||
|
/// The previous force of the touch input.
|
||||||
previous_force: Option<ForceTouch>,
|
previous_force: Option<ForceTouch>,
|
||||||
|
/// The current position of the touch input.
|
||||||
position: Vec2,
|
position: Vec2,
|
||||||
|
/// The current force of the touch input.
|
||||||
force: Option<ForceTouch>,
|
force: Option<ForceTouch>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Touch {
|
impl Touch {
|
||||||
|
/// The delta of the current `position` and the `previous_position`.
|
||||||
pub fn delta(&self) -> Vec2 {
|
pub fn delta(&self) -> Vec2 {
|
||||||
self.position - self.previous_position
|
self.position - self.previous_position
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The distance of the `start_position` and the current `position`.
|
||||||
pub fn distance(&self) -> Vec2 {
|
pub fn distance(&self) -> Vec2 {
|
||||||
self.position - self.start_position
|
self.position - self.start_position
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the `id` of the touch.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn id(&self) -> u64 {
|
pub fn id(&self) -> u64 {
|
||||||
self.id
|
self.id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the `start_position` of the touch.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn start_position(&self) -> Vec2 {
|
pub fn start_position(&self) -> Vec2 {
|
||||||
self.start_position
|
self.start_position
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the `start_force` of the touch.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn start_force(&self) -> Option<ForceTouch> {
|
pub fn start_force(&self) -> Option<ForceTouch> {
|
||||||
self.start_force
|
self.start_force
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the `previous_position` of the touch.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn previous_position(&self) -> Vec2 {
|
pub fn previous_position(&self) -> Vec2 {
|
||||||
self.previous_position
|
self.previous_position
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the `previous_force` of the touch.
|
||||||
|
#[inline]
|
||||||
|
pub fn previous_force(&self) -> Option<ForceTouch> {
|
||||||
|
self.previous_force
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the current `position` of the touch.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn position(&self) -> Vec2 {
|
pub fn position(&self) -> Vec2 {
|
||||||
self.position
|
self.position
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the current `force` of the touch.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn force(&self) -> Option<ForceTouch> {
|
pub fn force(&self) -> Option<ForceTouch> {
|
||||||
self.force
|
self.force
|
||||||
@ -142,51 +191,76 @@ impl From<&TouchInput> for Touch {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A collection of [`Touch`]es.
|
||||||
|
///
|
||||||
|
/// ## Usage
|
||||||
|
///
|
||||||
|
/// It is used to create a `bevy` resource that stores the data of the touches on a touchscreen
|
||||||
|
/// and can be accessed inside of a system.
|
||||||
|
///
|
||||||
|
/// ## Updating
|
||||||
|
///
|
||||||
|
/// The resource is updated inside of the [`touch_screen_input_system`](crate::touch::touch_screen_input_system).
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct Touches {
|
pub struct Touches {
|
||||||
|
/// A collection of every [`Touch`] that is currently being pressed.
|
||||||
pressed: HashMap<u64, Touch>,
|
pressed: HashMap<u64, Touch>,
|
||||||
|
/// A collection of every [`Touch`] that just got pressed.
|
||||||
just_pressed: HashMap<u64, Touch>,
|
just_pressed: HashMap<u64, Touch>,
|
||||||
|
/// A collection of every [`Touch`] that just got released.
|
||||||
just_released: HashMap<u64, Touch>,
|
just_released: HashMap<u64, Touch>,
|
||||||
|
/// A collection of every [`Touch`] that just got cancelled.
|
||||||
just_cancelled: HashMap<u64, Touch>,
|
just_cancelled: HashMap<u64, Touch>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Touches {
|
impl Touches {
|
||||||
|
/// An iterator visiting every pressed [`Touch`] input in arbitrary order.
|
||||||
pub fn iter(&self) -> impl Iterator<Item = &Touch> + '_ {
|
pub fn iter(&self) -> impl Iterator<Item = &Touch> + '_ {
|
||||||
self.pressed.values()
|
self.pressed.values()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the [`Touch`] input corresponding to the `id` if it is being pressed.
|
||||||
pub fn get_pressed(&self, id: u64) -> Option<&Touch> {
|
pub fn get_pressed(&self, id: u64) -> Option<&Touch> {
|
||||||
self.pressed.get(&id)
|
self.pressed.get(&id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the [`Touch`] input corresponding to the `id` if it has just been released.
|
||||||
pub fn get_released(&self, id: u64) -> Option<&Touch> {
|
pub fn get_released(&self, id: u64) -> Option<&Touch> {
|
||||||
self.just_released.get(&id)
|
self.just_released.get(&id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if the input corresponding to the `id` has just been released.
|
||||||
pub fn just_released(&self, id: u64) -> bool {
|
pub fn just_released(&self, id: u64) -> bool {
|
||||||
self.just_released.contains_key(&id)
|
self.just_released.contains_key(&id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if the input corresponding to the `id` has just been cancelled.
|
||||||
pub fn just_cancelled(&self, id: u64) -> bool {
|
pub fn just_cancelled(&self, id: u64) -> bool {
|
||||||
self.just_cancelled.contains_key(&id)
|
self.just_cancelled.contains_key(&id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An iterator visiting every just cancelled [`Touch`] input in arbitrary order.
|
||||||
pub fn iter_just_cancelled(&self) -> impl Iterator<Item = &Touch> {
|
pub fn iter_just_cancelled(&self) -> impl Iterator<Item = &Touch> {
|
||||||
self.just_cancelled.values()
|
self.just_cancelled.values()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Processes a [`TouchInput`] event by updating the `pressed`, `just_pressed`,
|
||||||
|
/// `just_released`, and `just_cancelled` collections.
|
||||||
fn process_touch_event(&mut self, event: &TouchInput) {
|
fn process_touch_event(&mut self, event: &TouchInput) {
|
||||||
match event.phase {
|
match event.phase {
|
||||||
TouchPhase::Started => {
|
TouchPhase::Started => {
|
||||||
@ -213,6 +287,13 @@ impl Touches {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Clears the `just_pressed`, `just_released`, and `just_cancelled` collections.
|
||||||
|
///
|
||||||
|
/// This is not clearing the `pressed` collection, because it could incorrectly mark
|
||||||
|
/// a touch input as not pressed eventhough it is pressed. This could happen if the
|
||||||
|
/// touch input is not moving for a single frame and would therefore be marked as
|
||||||
|
/// not pressed, because this function is called on every single frame no matter
|
||||||
|
/// if there was an event or not.
|
||||||
fn update(&mut self) {
|
fn update(&mut self) {
|
||||||
self.just_pressed.clear();
|
self.just_pressed.clear();
|
||||||
self.just_released.clear();
|
self.just_released.clear();
|
||||||
@ -220,7 +301,12 @@ impl Touches {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Updates the `Touches` resource with the latest `TouchInput` events
|
/// Updates the [`Touches`] resource with the latest [`TouchInput`] events.
|
||||||
|
///
|
||||||
|
/// ## Differences
|
||||||
|
///
|
||||||
|
/// The main difference between the [`TouchInput`] event and the [`Touches`] resource is that
|
||||||
|
/// the latter has convenient functions like [`Touches::just_pressed`] and [`Touches::just_released`].
|
||||||
pub fn touch_screen_input_system(
|
pub fn touch_screen_input_system(
|
||||||
mut touch_state: ResMut<Touches>,
|
mut touch_state: ResMut<Touches>,
|
||||||
mut touch_input_events: EventReader<TouchInput>,
|
mut touch_input_events: EventReader<TouchInput>,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user