Skip to main content

euv_engine/input/
struct.rs

1use super::*;
2
3/// A zero-sized namespace struct providing static input event extraction methods.
4///
5/// This struct follows the same pattern as `App`, serving as a namespace for
6/// free-standing input utility functions that extract data from DOM events.
7#[derive(Clone, Copy, Data, Debug, Default, Eq, Hash, New, Ord, PartialEq, PartialOrd)]
8pub struct Input;
9
10/// Tracks the current state of all input devices (keyboard, mouse, touch)
11/// for a single game frame. The state should be updated by event handlers
12/// and cleared of per-frame data at the end of each frame.
13#[derive(Clone, Data, Debug, New, PartialEq)]
14pub struct InputState {
15    /// Key codes that were pressed during this frame.
16    #[get_mut(pub(crate))]
17    #[new(skip)]
18    pub(crate) keys_pressed: KeyStateSet,
19    /// Key codes that are currently held down.
20    #[get_mut(pub(crate))]
21    #[new(skip)]
22    pub(crate) keys_held: KeyStateSet,
23    /// Key codes that were released during this frame.
24    #[get_mut(pub(crate))]
25    #[new(skip)]
26    pub(crate) keys_released: KeyStateSet,
27    /// Mouse buttons that were pressed during this frame.
28    #[get_mut(pub(crate))]
29    #[new(skip)]
30    pub(crate) mouse_buttons_pressed: HashSet<MouseButton>,
31    /// Mouse buttons that are currently held down.
32    #[get_mut(pub(crate))]
33    #[new(skip)]
34    pub(crate) mouse_buttons_held: HashSet<MouseButton>,
35    /// Mouse buttons that were released during this frame.
36    #[get_mut(pub(crate))]
37    #[new(skip)]
38    pub(crate) mouse_buttons_released: HashSet<MouseButton>,
39    /// The current mouse position in screen coordinates.
40    #[get(type(copy))]
41    #[get_mut(pub(crate))]
42    #[new(skip)]
43    pub(crate) mouse_position: Vector2D,
44    /// The mouse position delta (movement) since the last frame.
45    #[get(type(copy))]
46    #[get_mut(pub(crate))]
47    #[new(skip)]
48    pub(crate) mouse_delta: Vector2D,
49    /// Whether the mouse has moved during this frame.
50    #[get(type(copy))]
51    #[get_mut(pub(crate))]
52    #[new(skip)]
53    pub(crate) mouse_moved: bool,
54    /// Active touch points mapped by identifier to screen position.
55    #[get_mut(pub(crate))]
56    #[new(skip)]
57    pub(crate) touch_points: TouchPointMap,
58    /// Touch point identifiers that started during this frame.
59    #[get_mut(pub(crate))]
60    #[new(skip)]
61    pub(crate) touch_started: HashSet<i32>,
62    /// Touch point identifiers that ended during this frame.
63    #[get_mut(pub(crate))]
64    #[new(skip)]
65    pub(crate) touch_ended: HashSet<i32>,
66}
67
68/// Per-frame and steady-state data for a single gamepad index.
69///
70/// The edge sets follow the same contract as [`InputState`]:
71/// `buttons_pressed` records a button that went down on the frame it
72/// went down and is cleared by [`GamepadState::end_frame`],
73/// `buttons_held` records every button currently down and survives
74/// `end_frame`, and `buttons_released` records a button that was held
75/// and came up on this frame.
76#[derive(Clone, Data, Debug, Default, PartialEq)]
77pub struct GamepadState {
78    /// The browser-reported identifier of the device, e.g. a mapping
79    /// string such as `Xbox 360 Controller (XInput STANDARD GAMEPAD)`.
80    #[get(type(clone))]
81    #[set]
82    pub(crate) id: String,
83    /// The current reading of every analog axis, indexed by axis number.
84    /// Values outside the deadzone are stored as reported; the deadzone
85    /// is applied on read by [`GamepadState::axis`].
86    #[get]
87    #[get_mut(pub(crate))]
88    #[set]
89    pub(crate) axes: Vec<f64>,
90    /// The current pressure of every button, indexed by button number.
91    /// Analog triggers report a continuous value here, digital buttons
92    /// report `1.0` while down and `0.0` while up.
93    #[get]
94    #[get_mut(pub(crate))]
95    #[set]
96    pub(crate) button_values: Vec<f64>,
97    /// Whether the device is currently connected. A disconnected pad
98    /// keeps its last `id` so callers can still identify it.
99    #[get(type(copy))]
100    #[set]
101    pub(crate) connected: bool,
102    /// Button indices that were pressed during this frame.
103    #[get]
104    #[get_mut(pub(crate))]
105    pub(crate) buttons_pressed: GamepadButtonSet,
106    /// Button indices that are currently held down.
107    #[get]
108    #[get_mut(pub(crate))]
109    pub(crate) buttons_held: GamepadButtonSet,
110    /// Button indices that were released during this frame.
111    #[get]
112    #[get_mut(pub(crate))]
113    pub(crate) buttons_released: GamepadButtonSet,
114}
115
116/// Owns the state of every gamepad the page has seen and drives the
117/// per-frame poll.
118///
119/// A poll re-reads `navigator.get_gamepads()` and folds the fresh raw
120/// readings into the stored state, computing this frame's edge sets
121/// from the previous frame's held set. The DOM connect / disconnect
122/// events are honoured too: a device announced between two polls is
123/// already present as a state when the next poll runs, so polling
124/// alone never loses a connect or a disconnect.
125#[derive(Clone, Data, Debug, Default, PartialEq)]
126pub struct GamepadManager {
127    /// Every gamepad state ever observed, keyed by gamepad index.
128    #[get]
129    #[get_mut(pub(crate))]
130    pub(crate) states: GamepadStateMap,
131    /// Gamepad indices that were first seen during this frame.
132    #[get]
133    #[get_mut(pub(crate))]
134    pub(crate) connected: GamepadIndexSet,
135    /// Gamepad indices that were last seen leaving during this frame.
136    #[get]
137    #[get_mut(pub(crate))]
138    pub(crate) disconnected: GamepadIndexSet,
139}