diff options
| author | HampusM <hampus@hampusmat.com> | 2026-08-14 20:20:41 +0200 |
|---|---|---|
| committer | HampusM <hampus@hampusmat.com> | 2026-08-15 00:43:37 +0200 |
| commit | 1ac2ff603b1c843541234648ab801e83b2947444 (patch) | |
| tree | f8080920cd6c02de07b9f0314e18f473ad620adc /engine/src/windowing | |
| parent | a61463b205f3c3aaa9174cdae3704a8a53542aea (diff) | |
Diffstat (limited to 'engine/src/windowing')
| -rw-r--r-- | engine/src/windowing/keyboard.rs | 75 |
1 files changed, 42 insertions, 33 deletions
diff --git a/engine/src/windowing/keyboard.rs b/engine/src/windowing/keyboard.rs index 4515d8a..8e0cfbe 100644 --- a/engine/src/windowing/keyboard.rs +++ b/engine/src/windowing/keyboard.rs @@ -1,11 +1,12 @@ -use std::collections::HashMap; +use util_macros::VariantArr; use crate::ecs::Sole; +use crate::util::BitArray; #[derive(Debug, Default, Sole)] pub struct Keyboard { - map: HashMap<Key, KeyData>, + keys: BitArray<{ (Key::KEYS.len() * BITS_PER_KEY).div_ceil(8) }, BITS_PER_KEY>, text_keys: String, } @@ -43,33 +44,49 @@ impl Keyboard /// different state than they had the previous frame. pub fn new_key_states(&self) -> impl Iterator<Item = (Key, KeyState)> + use<'_> { - self.map.iter().filter_map(|(key, key_data)| { - if key_data.curr_state == key_data.previous_state { + self.keys.iter_occupied().filter_map(|(key_index, bits)| { + if bits == KEY_CURR_PRESSED_BITS | KEY_PREV_PRESSED_BITS { return None; } - Some((*key, key_data.curr_state)) + let key = Key::KEYS[key_index]; + + let curr_state = match bits & KEY_CURR_PRESSED_BITS { + KEY_CURR_PRESSED_BITS => KeyState::Pressed, + 0 => KeyState::Released, + _ => unreachable!(), + }; + + Some((key, curr_state)) }) } #[must_use] pub fn get_key_state(&self, key: Key) -> KeyState { - let Some(key_data) = self.map.get(&key) else { - return KeyState::Released; + let bits = self.keys.get(key as usize); + + let state = match bits & KEY_CURR_PRESSED_BITS { + KEY_CURR_PRESSED_BITS => KeyState::Pressed, + 0 => KeyState::Released, + _ => unreachable!(), }; - key_data.curr_state + state } #[must_use] pub fn get_prev_key_state(&self, key: Key) -> KeyState { - let Some(key_data) = self.map.get(&key) else { - return KeyState::Released; + let bits = self.keys.get(key as usize); + + let state = match bits & KEY_PREV_PRESSED_BITS { + KEY_PREV_PRESSED_BITS => KeyState::Pressed, + 0 => KeyState::Released, + _ => unreachable!(), }; - key_data.previous_state + state } pub fn text_keys(&self) -> &str @@ -79,15 +96,19 @@ impl Keyboard pub fn set_key_state(&mut self, key: Key, key_state: KeyState) { - let key_data = self.map.entry(key).or_default(); - - key_data.curr_state = key_state; + self.keys.set( + key as usize, + match key_state { + KeyState::Pressed => KEY_CURR_PRESSED_BITS, + KeyState::Released => 0, + }, + ); } pub fn make_key_states_previous(&mut self) { - for key_data in self.map.values_mut() { - key_data.previous_state = key_data.curr_state; + for byte in self.keys.bytes_mut() { + *byte = (*byte >> 1) & 0b01010101 | *byte & 0b10101010; } } @@ -98,7 +119,8 @@ impl Keyboard } } -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, VariantArr)] +#[variant_arr(name = KEYS)] #[non_exhaustive] pub enum Key { @@ -797,20 +819,7 @@ impl From<winit::event::ElementState> for KeyState } } -#[derive(Debug)] -struct KeyData -{ - curr_state: KeyState, - previous_state: KeyState, -} +const BITS_PER_KEY: usize = 2; -impl Default for KeyData -{ - fn default() -> Self - { - KeyData { - curr_state: KeyState::Released, - previous_state: KeyState::Released, - } - } -} +const KEY_CURR_PRESSED_BITS: u8 = 0b10; +const KEY_PREV_PRESSED_BITS: u8 = 0b01; |
