summaryrefslogtreecommitdiff
path: root/engine/src/input.rs
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2025-10-18 17:04:28 +0200
committerHampusM <hampus@hampusmat.com>2025-10-18 17:04:28 +0200
commit7083a19bf1029bff21a9550d40cc3260e99aac53 (patch)
tree524a8bd2e75ca712b0536218089804cf9838553b /engine/src/input.rs
parent7f3072ed7e016dff359439d7580403e36ad6b325 (diff)
refactor(engine): use winit instead of glfw
Diffstat (limited to 'engine/src/input.rs')
-rw-r--r--engine/src/input.rs247
1 files changed, 11 insertions, 236 deletions
diff --git a/engine/src/input.rs b/engine/src/input.rs
index c53175e..f8c9dfd 100644
--- a/engine/src/input.rs
+++ b/engine/src/input.rs
@@ -1,257 +1,32 @@
-use std::collections::HashMap;
-
+use ecs::declare_entity;
use ecs::extension::Collector as ExtensionCollector;
-use ecs::pair::{ChildOf, Pair};
-use ecs::phase::{Phase, PRE_UPDATE as PRE_UPDATE_PHASE, START as START_PHASE};
-use ecs::sole::Single;
-use ecs::{declare_entity, Sole};
-
-use crate::vector::Vec2;
-use crate::window::{Window, UPDATE_PHASE as WINDOW_UPDATE_PHASE};
+use ecs::pair::{DependsOn, Pair};
+use ecs::phase::Phase;
-mod reexports
-{
- pub use crate::window::{Key, KeyState};
-}
+use crate::windowing::PHASE as WINDOWING_PHASE;
-pub use reexports::*;
+pub mod keyboard;
+pub mod mouse;
declare_entity!(
- SET_PREV_KEY_STATE_PHASE,
+ pub PHASE,
(
Phase,
Pair::builder()
- .relation::<ChildOf>()
- .target_id(*WINDOW_UPDATE_PHASE)
+ .relation::<DependsOn>()
+ .target_id(*WINDOWING_PHASE)
.build()
)
);
-#[derive(Debug, Sole)]
-pub struct Keys
-{
- map: HashMap<Key, KeyData>,
- pending: Vec<(Key, KeyState)>,
-}
-
-impl Keys
-{
- #[must_use]
- pub fn new() -> Self
- {
- Self {
- map: Key::KEYS
- .iter()
- .map(|key| {
- (
- *key,
- KeyData {
- state: KeyState::Released,
- prev_tick_state: KeyState::Released,
- },
- )
- })
- .collect(),
- pending: Vec::with_capacity(Key::KEYS.len()),
- }
- }
-
- #[must_use]
- pub fn get_key_state(&self, key: Key) -> KeyState
- {
- let Some(key_data) = self.map.get(&key) else {
- unreachable!();
- };
-
- key_data.state
- }
-
- #[must_use]
- pub fn get_prev_key_state(&self, key: Key) -> KeyState
- {
- let Some(key_data) = self.map.get(&key) else {
- unreachable!();
- };
-
- key_data.prev_tick_state
- }
-
- pub fn set_key_state(&mut self, key: Key, new_key_state: KeyState)
- {
- let Some(key_data) = self.map.get_mut(&key) else {
- unreachable!();
- };
-
- key_data.state = new_key_state;
- }
-
- #[must_use]
- pub fn is_anything_pressed(&self) -> bool
- {
- self.map
- .values()
- .any(|key_data| matches!(key_data.state, KeyState::Pressed))
- }
-}
-
-impl Default for Keys
-{
- fn default() -> Self
- {
- Self::new()
- }
-}
-
-#[derive(Debug, Default, Clone, Sole)]
-pub struct Cursor
-{
- pub position: Vec2<f64>,
- pub has_moved: bool,
-}
-
-#[derive(Debug, Clone, Sole)]
-pub struct CursorFlags
-{
- /// This flag is set in two situations:
- /// A: The window has just started
- /// B: The window has gained focus again after losing focus.
- ///
- /// This flag only lasts a single tick then it is cleared (at the beginning of the
- /// next tick).
- pub is_first_move: CursorFlag,
-}
-
-impl Default for CursorFlags
-{
- fn default() -> Self
- {
- Self {
- is_first_move: CursorFlag { flag: true, ..Default::default() },
- }
- }
-}
-
-#[derive(Debug, Default, Clone)]
-pub struct CursorFlag
-{
- pub flag: bool,
- pub pending_clear: bool,
-}
-
-impl CursorFlag
-{
- pub fn clear(&mut self)
- {
- self.flag = false;
- self.pending_clear = false;
- }
-}
-
/// Input extension.
#[derive(Debug, Default)]
pub struct Extension {}
impl ecs::extension::Extension for Extension
{
- fn collect(self, mut collector: ExtensionCollector<'_>)
+ fn collect(self, _collector: ExtensionCollector<'_>)
{
- collector.add_declared_entity(&SET_PREV_KEY_STATE_PHASE);
-
- collector.add_system(*START_PHASE, initialize);
- collector.add_system(*PRE_UPDATE_PHASE, maybe_clear_cursor_is_first_move);
- collector.add_system(*SET_PREV_KEY_STATE_PHASE, set_pending_key_states);
-
- collector.add_sole(Keys::default()).ok();
- collector.add_sole(Cursor::default()).ok();
- collector.add_sole(CursorFlags::default()).ok();
- }
-}
-
-fn initialize(
- keys: Single<Keys>,
- cursor: Single<Cursor>,
- cursor_flags: Single<CursorFlags>,
- window: Single<Window>,
-)
-{
- let keys_weak_ref = keys.to_weak_ref();
-
- window.set_key_callback(move |key, _scancode, key_state, _modifiers| {
- let keys_ref = keys_weak_ref.access().expect("No world");
-
- let mut keys = keys_ref.to_single();
-
- keys.pending.push((key, key_state));
- });
-
- let cursor_weak_ref = cursor.to_weak_ref();
-
- window.set_cursor_pos_callback(move |cursor_position| {
- let cursor_ref = cursor_weak_ref.access().expect("No world");
-
- let mut cursor = cursor_ref.to_single();
-
- cursor.position = Vec2 {
- x: cursor_position.x,
- y: cursor_position.y,
- };
-
- cursor.has_moved = true;
- });
-
- let cursor_flags_weak_ref = cursor_flags.to_weak_ref();
-
- window.set_focus_callback(move |is_focused| {
- tracing::trace!("Window is focused: {is_focused}");
-
- let cursor_flags_ref = cursor_flags_weak_ref.access().expect("No world");
-
- cursor_flags_ref.to_single().is_first_move.flag = is_focused;
- });
-}
-
-fn maybe_clear_cursor_is_first_move(
- cursor: Single<Cursor>,
- mut cursor_flags: Single<CursorFlags>,
-)
-{
- if cursor_flags.is_first_move.pending_clear {
- tracing::trace!("Clearing is_first_move");
-
- // This flag was set for the whole previous tick so it can be cleared now
- cursor_flags.is_first_move.clear();
-
- return;
- }
-
- if cursor.has_moved && cursor_flags.is_first_move.flag {
- tracing::trace!("Setting flag to clear is_first_move next tick");
-
- // Make this system clear is_first_move the next time it runs
- cursor_flags.is_first_move.pending_clear = true;
+ // TODO: Add input mapping
}
}
-
-fn set_pending_key_states(mut keys: Single<Keys>)
-{
- let Keys { map, pending } = &mut *keys;
-
- for key_data in map.values_mut() {
- key_data.prev_tick_state = key_data.state;
- }
-
- for (key, key_state) in pending {
- let Some(key_data) = map.get_mut(key) else {
- unreachable!();
- };
-
- key_data.state = *key_state;
- }
-}
-
-#[derive(Debug)]
-struct KeyData
-{
- state: KeyState,
- prev_tick_state: KeyState,
-}