diff options
author | HampusM <hampus@hampusmat.com> | 2024-04-14 12:34:52 +0200 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2024-04-14 12:35:28 +0200 |
commit | 101b455e51f9b702da5517cabe2c3b1086fcb2e7 (patch) | |
tree | 470e28acd7a3777dbb4be0208f9cd3177bba52a9 /engine/src/input.rs | |
parent | ef7b76ff39d501028852835649f618fcbe17a003 (diff) |
feat(engine): use ECS architecture
Diffstat (limited to 'engine/src/input.rs')
-rw-r--r-- | engine/src/input.rs | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/engine/src/input.rs b/engine/src/input.rs new file mode 100644 index 0000000..78c8270 --- /dev/null +++ b/engine/src/input.rs @@ -0,0 +1,110 @@ +use std::collections::HashMap; + +use ecs::extension::Collector as ExtensionCollector; +use ecs::sole::Single; +use ecs::Sole; + +use crate::event::Start as StartEvent; +use crate::vector::Vec2; +use crate::window::{Key, KeyState, Window}; + +#[derive(Debug, Clone, Default, Sole)] +pub struct Keys +{ + map: HashMap<Key, KeyState>, +} + +impl Keys +{ + #[must_use] + pub fn new() -> Self + { + Self::default() + } + + #[must_use] + pub fn get_key_state(&self, key: Key) -> KeyState + { + self.map.get(&key).copied().unwrap_or(KeyState::Released) + } + + pub fn set_key_state(&mut self, key: Key, key_state: KeyState) + { + if matches!(key_state, KeyState::Released) { + self.map.remove(&key); + return; + } + + if matches!(key_state, KeyState::Repeat) { + return; + } + + self.map.insert(key, key_state); + } + + #[must_use] + pub fn is_anything_pressed(&self) -> bool + { + !self.map.is_empty() + } +} + +#[derive(Debug, Clone, Default, Sole)] +pub struct Cursor +{ + pub position: Vec2<f64>, +} + +impl Cursor +{ + #[must_use] + pub fn new() -> Self + { + Self::default() + } +} + +/// Input extension. +#[derive(Debug, Default)] +pub struct Extension {} + +impl ecs::extension::Extension for Extension +{ + fn collect(self, mut collector: ExtensionCollector<'_>) + { + collector.add_system(StartEvent, initialize); + + collector.add_sole(Keys::default()).ok(); + collector.add_sole(Cursor::default()).ok(); + } +} + +fn initialize(keys: Single<Keys>, cursor: Single<Cursor>, window: Single<Window>) +{ + let keys_weak_ref = keys.to_weak_ref(); + + window.set_key_callback(move |key, _scancode, key_state, _modifiers| { + let keys_weak_ref = keys_weak_ref.clone(); + + let keys_ref = keys_weak_ref.access().expect("No world"); + + let mut keys = keys_ref.to_single(); + + keys.set_key_state(key, key_state); + }); + + let cursor_weak_ref = cursor.to_weak_ref(); + + window.set_cursor_pos_callback(move |cursor_position| { + let cursor_weak_ref = cursor_weak_ref.clone(); + + 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, + }; + }); +} |