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