summaryrefslogtreecommitdiff
path: root/engine/src/input.rs
blob: f64d93e059ea2a4282e9cf1aaaa9150f235f2207 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
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>,
    pub has_moved: bool,
}

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,
        };

        cursor.has_moved = true;
    });
}