summaryrefslogtreecommitdiff
path: root/engine/src/input.rs
diff options
context:
space:
mode:
Diffstat (limited to 'engine/src/input.rs')
-rw-r--r--engine/src/input.rs110
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,
+ };
+ });
+}