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 ///
17 /// `get_keys_pressed` is public because tests/input/fn.rs reads this field from
18 /// outside this crate. `get_mut` / `set` stay crate-internal.
19 #[get_mut(pub(crate))]
20 #[set(pub(crate))]
21 #[new(skip)]
22 pub keys_pressed: KeyStateSet,
23 /// Key codes that are currently held down.
24 ///
25 /// `get_keys_held` is public because tests/input/fn.rs reads this field from
26 /// outside this crate. `get_mut` / `set` stay crate-internal.
27 #[get_mut(pub(crate))]
28 #[set(pub(crate))]
29 #[new(skip)]
30 pub keys_held: KeyStateSet,
31 /// Key codes that were released during this frame.
32 ///
33 /// `get_keys_released` is public because tests/input/fn.rs reads this field from
34 /// outside this crate. `get_mut` / `set` stay crate-internal.
35 #[get_mut(pub(crate))]
36 #[set(pub(crate))]
37 #[new(skip)]
38 pub keys_released: KeyStateSet,
39 /// Mouse buttons that were pressed during this frame.
40 ///
41 /// `get_mouse_buttons_pressed` is public because tests/input/fn.rs reads this field from
42 /// outside this crate. `get_mut` / `set` stay crate-internal.
43 #[get_mut(pub(crate))]
44 #[set(pub(crate))]
45 #[new(skip)]
46 pub mouse_buttons_pressed: HashSet<MouseButton>,
47 /// Mouse buttons that are currently held down.
48 ///
49 /// `get_mouse_buttons_held` is public because tests/input/fn.rs reads this field from
50 /// outside this crate. `get_mut` / `set` stay crate-internal.
51 #[get_mut(pub(crate))]
52 #[set(pub(crate))]
53 #[new(skip)]
54 pub mouse_buttons_held: HashSet<MouseButton>,
55 /// Mouse buttons that were released during this frame.
56 ///
57 /// `get_mouse_buttons_released` is public because tests/input/fn.rs reads this field from
58 /// outside this crate. `get_mut` / `set` stay crate-internal.
59 #[get_mut(pub(crate))]
60 #[set(pub(crate))]
61 #[new(skip)]
62 pub mouse_buttons_released: HashSet<MouseButton>,
63 /// The current mouse position in screen coordinates.
64 ///
65 /// `get_mouse_position` is public because tests/input/fn.rs, tests/input_state/fn.rs reads this field from
66 /// outside this crate. `get_mut` / `set` stay crate-internal.
67 #[get_mut(pub(crate))]
68 #[get(type(copy))]
69 #[set(pub(crate))]
70 #[new(skip)]
71 pub mouse_position: Vector2D,
72 /// The mouse position delta (movement) since the last frame.
73 ///
74 /// `get_mouse_delta` is public because tests/input/fn.rs, tests/input_state/fn.rs reads this field from
75 /// outside this crate. `get_mut` / `set` stay crate-internal.
76 #[get_mut(pub(crate))]
77 #[get(type(copy))]
78 #[set(pub(crate))]
79 #[new(skip)]
80 pub mouse_delta: Vector2D,
81 /// Whether the mouse has moved during this frame.
82 ///
83 /// `get_mouse_moved` is public because tests/input/fn.rs reads this field from
84 /// outside this crate. `get_mut` / `set` stay crate-internal.
85 #[get_mut(pub(crate))]
86 #[get(type(copy))]
87 #[set(pub(crate))]
88 #[new(skip)]
89 pub mouse_moved: bool,
90 /// Active touch points mapped by identifier to screen position.
91 ///
92 /// `get_touch_points` is public because tests/input/fn.rs reads this field from
93 /// outside this crate. `get_mut` / `set` stay crate-internal.
94 #[get_mut(pub(crate))]
95 #[set(pub(crate))]
96 #[new(skip)]
97 pub touch_points: TouchPointMap,
98 /// Touch point identifiers that started during this frame.
99 ///
100 /// `get_touch_started` is public because tests/input/fn.rs reads this field from
101 /// outside this crate. `get_mut` / `set` stay crate-internal.
102 #[get_mut(pub(crate))]
103 #[set(pub(crate))]
104 #[new(skip)]
105 pub touch_started: HashSet<i32>,
106 /// Touch point identifiers that ended during this frame.
107 ///
108 /// `get_touch_ended` is public because tests/input/fn.rs reads this field from
109 /// outside this crate. `get_mut` / `set` stay crate-internal.
110 #[get_mut(pub(crate))]
111 #[set(pub(crate))]
112 #[new(skip)]
113 pub touch_ended: HashSet<i32>,
114}
115
116/// Per-frame and steady-state data for a single gamepad index.
117///
118/// The edge sets follow the same contract as [`InputState`]:
119/// `buttons_pressed` records a button that went down on the frame it
120/// went down and is cleared by [`GamepadState::end_frame`],
121/// `buttons_held` records every button currently down and survives
122/// `end_frame`, and `buttons_released` records a button that was held
123/// and came up on this frame.
124#[derive(Clone, Data, Debug, Default, PartialEq)]
125pub struct GamepadState {
126 /// The browser-reported identifier of the device, e.g. a mapping
127 /// string such as `Xbox 360 Controller (XInput STANDARD GAMEPAD)`.
128 #[get(pub(crate), type(clone))]
129 #[get_mut(pub(crate))]
130 #[set(pub(crate))]
131 pub(crate) id: String,
132 /// The current reading of every analog axis, indexed by axis number.
133 /// Values outside the deadzone are stored as reported; the deadzone
134 /// is applied on read by [`GamepadState::axis`].
135 #[get_mut(pub(crate))]
136 #[get(pub(crate))]
137 #[set(pub(crate))]
138 pub(crate) axes: Vec<f64>,
139 /// The current pressure of every button, indexed by button number.
140 /// Analog triggers report a continuous value here, digital buttons
141 /// report `1.0` while down and `0.0` while up.
142 #[get_mut(pub(crate))]
143 #[get(pub(crate))]
144 #[set(pub(crate))]
145 pub(crate) button_values: Vec<f64>,
146 /// Whether the device is currently connected. A disconnected pad
147 /// keeps its last `id` so callers can still identify it.
148 #[get(pub(crate), type(copy))]
149 #[get_mut(pub(crate))]
150 #[set(pub(crate))]
151 pub(crate) connected: bool,
152 /// Button indices that were pressed during this frame.
153 #[get_mut(pub(crate))]
154 #[get(pub(crate))]
155 #[set(pub(crate))]
156 pub(crate) buttons_pressed: GamepadButtonSet,
157 /// Button indices that are currently held down.
158 #[get_mut(pub(crate))]
159 #[get(pub(crate))]
160 #[set(pub(crate))]
161 pub(crate) buttons_held: GamepadButtonSet,
162 /// Button indices that were released during this frame.
163 #[get_mut(pub(crate))]
164 #[get(pub(crate))]
165 #[set(pub(crate))]
166 pub(crate) buttons_released: GamepadButtonSet,
167}
168
169/// Owns the state of every gamepad the page has seen and drives the
170/// per-frame poll.
171///
172/// A poll re-reads `navigator.get_gamepads()` and folds the fresh raw
173/// readings into the stored state, computing this frame's edge sets
174/// from the previous frame's held set. The DOM connect / disconnect
175/// events are honoured too: a device announced between two polls is
176/// already present as a state when the next poll runs, so polling
177/// alone never loses a connect or a disconnect.
178#[derive(Clone, Data, Debug, Default, PartialEq)]
179pub struct GamepadManager {
180 /// Every gamepad state ever observed, keyed by gamepad index.
181 ///
182 /// `get_states` is public because tests/gamepad_poll/fn.rs reads this field from
183 /// outside this crate. `get_mut` / `set` stay crate-internal.
184 #[get_mut(pub(crate))]
185 #[set(pub(crate))]
186 pub states: GamepadStateMap,
187 /// Gamepad indices that were first seen during this frame.
188 #[get_mut(pub(crate))]
189 #[set(pub(crate))]
190 #[get(pub(crate))]
191 pub(crate) connected: GamepadIndexSet,
192 /// Gamepad indices that were last seen leaving during this frame.
193 #[get_mut(pub(crate))]
194 #[get(pub(crate))]
195 #[set(pub(crate))]
196 pub(crate) disconnected: GamepadIndexSet,
197}