-
-
Notifications
You must be signed in to change notification settings - Fork 4k
Split PointerId into distinct id and PointerKind fields #17808
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -16,8 +16,6 @@ use bevy_reflect::prelude::*; | |||||
use bevy_render::camera::{Camera, NormalizedRenderTarget}; | ||||||
use bevy_window::PrimaryWindow; | ||||||
|
||||||
use uuid::Uuid; | ||||||
|
||||||
use core::{fmt::Debug, ops::Deref}; | ||||||
|
||||||
use crate::backend::HitData; | ||||||
|
@@ -29,41 +27,69 @@ use crate::backend::HitData; | |||||
#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash, Component, Reflect)] | ||||||
#[require(PointerLocation, PointerPress, PointerInteraction)] | ||||||
#[reflect(Component, Default, Debug, Hash, PartialEq)] | ||||||
pub enum PointerId { | ||||||
/// The mouse pointer. | ||||||
#[default] | ||||||
Mouse, | ||||||
/// A touch input, usually numbered by window touch events from `winit`. | ||||||
Touch(u64), | ||||||
/// A custom, uniquely identified pointer. Useful for mocking inputs or implementing a software | ||||||
/// controlled cursor. | ||||||
#[reflect(ignore)] | ||||||
Custom(Uuid), | ||||||
pub struct PointerId { | ||||||
/// A stable identifier for a specific pointer. | ||||||
/// | ||||||
/// This is typically provided by winit, | ||||||
/// and is unique for each touch input or mouse. | ||||||
Comment on lines
+31
to
+34
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This feels misleading. The id here corresponds to a specific touch on the device and it's only guaranteed to be unique for the duration of that touch I think. |
||||||
pub id: u64, | ||||||
/// The type of hardware device that created this pointer. | ||||||
pub kind: PointerKind, | ||||||
} | ||||||
|
||||||
impl PointerId { | ||||||
/// The [`PointerId`] of the mouse. | ||||||
/// | ||||||
/// Currently, only one mouse pointer is supported. | ||||||
pub const MOUSE: Self = Self { | ||||||
id: 0, | ||||||
kind: PointerKind::Mouse, | ||||||
}; | ||||||
|
||||||
/// Returns true if the pointer is a touch input. | ||||||
pub fn is_touch(&self) -> bool { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've left these utility methods alone to ease migration, but I'm not convinced they're particularly valuable now. |
||||||
matches!(self, PointerId::Touch(_)) | ||||||
matches!(self.kind, PointerKind::Touch) | ||||||
} | ||||||
/// Returns true if the pointer is the mouse. | ||||||
pub fn is_mouse(&self) -> bool { | ||||||
matches!(self, PointerId::Mouse) | ||||||
matches!(self.kind, PointerKind::Mouse) | ||||||
} | ||||||
/// Returns true if the pointer is a custom input. | ||||||
pub fn is_custom(&self) -> bool { | ||||||
matches!(self, PointerId::Custom(_)) | ||||||
/// Returns true if the pointer is a virtual input. | ||||||
pub fn is_virtual(&self) -> bool { | ||||||
matches!(self.kind, PointerKind::Virtual) | ||||||
} | ||||||
/// Returns the touch id if the pointer is a touch input. | ||||||
pub fn get_touch_id(&self) -> Option<u64> { | ||||||
if let PointerId::Touch(id) = self { | ||||||
Some(*id) | ||||||
if let PointerKind::Touch = self.kind { | ||||||
Some(self.id) | ||||||
} else { | ||||||
None | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
/// The input device that created a pointer. | ||||||
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash, Reflect)] | ||||||
#[reflect(Default, Debug, Hash, PartialEq)] | ||||||
pub enum PointerKind { | ||||||
/// A pointer that is controlled by a mouse. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
/// | ||||||
/// Not a rodent; the device that you move around on a desk. | ||||||
Mouse, | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, the intent is that things like UI libraries will match on this variant, and behave accordingly. |
||||||
/// A pointer that is controlled by a touch input. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Like an obvious thing I think we'd want to support here is touch input emulation with the mouse? |
||||||
/// | ||||||
/// Typically with your fingers on a touch screen, | ||||||
/// but can also be a stylus or other touch input device. | ||||||
Touch, | ||||||
/// A pointer that is driven by code. | ||||||
/// | ||||||
/// No underlying hardware is associated with this pointer, | ||||||
/// and it might represent a gamepad moving a cursor, | ||||||
/// or an input sent to a focused element in a UI. | ||||||
#[default] | ||||||
Virtual, | ||||||
} | ||||||
|
||||||
/// Holds a list of entities this pointer is currently interacting with, sorted from nearest to | ||||||
/// farthest. | ||||||
#[derive(Debug, Default, Clone, Component, Reflect)] | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,7 +17,7 @@ use bevy::{ | |
math::{CompassOctant, FloatOrd}, | ||
picking::{ | ||
backend::HitData, | ||
pointer::{Location, PointerId}, | ||
pointer::{Location, PointerId, PointerKind}, | ||
}, | ||
platform_support::collections::{HashMap, HashSet}, | ||
prelude::*, | ||
|
@@ -383,8 +383,10 @@ fn interact_with_focused_button( | |
commands.trigger_targets( | ||
Pointer::<Click> { | ||
target: focused_entity, | ||
// We're pretending that we're a mouse | ||
pointer_id: PointerId::Mouse, | ||
pointer_id: PointerId { | ||
id: 0, | ||
kind: PointerKind::Virtual, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No more pretending to be a mouse! |
||
}, | ||
// This field isn't used, so we're just setting it to a placeholder value | ||
pointer_location: Location { | ||
target: NormalizedRenderTarget::Image( | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that PointerId is now a common "thing" maybe it should just be
PointerId(u64)
andPointerKind
would just be stored adjacent to it in places where that is relevant (ex: as a separate Component)? To distinguish between two pointers, don't we only need to compare / hash the ID, not the kind?Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it is not a common thing, then I think we should move back to a typed-wrapper to protect against comparing "unlike" ids across types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right now (and before this PR), the IDs are only meaningfully used by touches. In theory you could encode information for Virtual / Custom types in the u64 / UUID, but I'm not sure what you would use that for.
In either case, in order for two PointerId to match, both the kind and the number associated with it must match. As a result, I don't think we should split these up, but I'm fine to go back to an enum design here. Which do you prefer?
enum PointerId
, onlyTouch
gets au64
.enum PointerId
, each kind has au64
.I think I prefer solution 2, but went with solution 1 to ease migration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also prefer solution (2). I think thats the move.