diff --git a/src/keyboard/commodore.rs b/src/keyboard/commodore.rs index 5dc4d82..1ac9159 100644 --- a/src/keyboard/commodore.rs +++ b/src/keyboard/commodore.rs @@ -255,7 +255,7 @@ impl KeyAdapter for C64SymbolAdapter { }) } - if mapped.pressed().is_empty() { + if mapped.is_empty() { // If no non-shifted keys were pressed, check for shifted keys. for symbol in state.pressed() { use KeySymbol::*; @@ -286,7 +286,7 @@ impl KeyAdapter for C64SymbolAdapter { } // If we added keys, make sure shift is pressed - if !mapped.pressed().is_empty() { + if !mapped.is_empty() { mapped.press(C64Keys::LShift); } } @@ -327,8 +327,13 @@ mod tests { let mapped = C64KeyboardAdapter::map(&positions); assert_eq!( - &vec![C64Keys::Q, C64Keys::Digit2, C64Keys::Comma, C64Keys::Return], - mapped.pressed() + vec![ + &C64Keys::Q, + &C64Keys::Digit2, + &C64Keys::Comma, + &C64Keys::Return + ], + mapped.pressed().collect::>() ); positions.press(KeyPosition::LShift); @@ -337,8 +342,13 @@ mod tests { let mapped = C64KeyboardAdapter::map(&positions); assert_eq!( - &vec![C64Keys::Q, C64Keys::Digit2, C64Keys::Comma, C64Keys::LShift], - mapped.pressed() + vec![ + &C64Keys::Q, + &C64Keys::Digit2, + &C64Keys::Comma, + &C64Keys::LShift + ], + mapped.pressed().collect::>() ); } @@ -354,8 +364,13 @@ mod tests { let mapped = C64SymbolAdapter::map(&symbols); assert_eq!( - &vec![C64Keys::Q, C64Keys::Digit2, C64Keys::Comma, C64Keys::Return], - mapped.pressed() + vec![ + &C64Keys::Q, + &C64Keys::Digit2, + &C64Keys::Comma, + &C64Keys::Return + ], + mapped.pressed().collect::>() ); } @@ -370,13 +385,13 @@ mod tests { let mapped = C64SymbolAdapter::map(&symbols); assert_eq!( - &vec![ - C64Keys::Digit1, - C64Keys::Comma, - C64Keys::Period, - C64Keys::LShift + vec![ + &C64Keys::Digit1, + &C64Keys::Comma, + &C64Keys::Period, + &C64Keys::LShift ], - mapped.pressed() + mapped.pressed().collect::>() ); } @@ -392,7 +407,10 @@ mod tests { let mapped = C64SymbolAdapter::map(&symbols); // Do a "best effort" mapping, dropping the shifted keys - assert_eq!(&vec![C64Keys::Digit1, C64Keys::Return], mapped.pressed()); + assert_eq!( + vec![&C64Keys::Digit1, &C64Keys::Return], + mapped.pressed().collect::>() + ); } #[test] @@ -401,32 +419,32 @@ mod tests { state.press(KeySymbol::DownArrow); assert_eq!( - &vec![C64Keys::CursorUpDown], - C64SymbolAdapter::map(&state).pressed() + vec![&C64Keys::CursorUpDown], + C64SymbolAdapter::map(&state).pressed().collect::>() ); state.release(KeySymbol::DownArrow); state.press(KeySymbol::UpArrow); assert_eq!( - &vec![C64Keys::CursorUpDown, C64Keys::LShift], - C64SymbolAdapter::map(&state).pressed() + vec![&C64Keys::CursorUpDown, &C64Keys::LShift], + C64SymbolAdapter::map(&state).pressed().collect::>() ); state.press(KeySymbol::LeftArrow); assert_eq!( - &vec![ - C64Keys::CursorUpDown, - C64Keys::CursorLeftRight, - C64Keys::LShift + vec![ + &C64Keys::CursorUpDown, + &C64Keys::CursorLeftRight, + &C64Keys::LShift ], - C64SymbolAdapter::map(&state).pressed() + C64SymbolAdapter::map(&state).pressed().collect::>() ); // map the right arrow, but give up on the rest state.press(KeySymbol::RightArrow); assert_eq!( - &vec![C64Keys::CursorLeftRight], - C64SymbolAdapter::map(&state).pressed() + vec![&C64Keys::CursorLeftRight], + C64SymbolAdapter::map(&state).pressed().collect::>() ); } } diff --git a/src/keyboard/mod.rs b/src/keyboard/mod.rs index d1309cc..3ea4eaf 100644 --- a/src/keyboard/mod.rs +++ b/src/keyboard/mod.rs @@ -19,11 +19,11 @@ pub use virtualkey::VirtualKey; /// A set of keys that are currently pressed. /// Parameter `T` is the type of the key symbols. #[derive(Default, Debug, Clone, PartialEq)] -pub struct KeyState { +pub struct KeyState { pressed: Vec, } -impl KeyState { +impl KeyState { /// Creates a new, empty key state. pub fn new() -> Self { Self { @@ -42,17 +42,27 @@ impl KeyState { } /// Return the set of pressed keys. - pub fn pressed(&self) -> &Vec { - &self.pressed + pub fn pressed(&self) -> impl Iterator { + self.pressed.iter() } /// Returns true if the given key is currently pressed. pub fn is_pressed(&self, symbol: T) -> bool { self.pressed.contains(&symbol) } + + /// Returns true if the set of keys is empty. + pub fn is_empty(&self) -> bool { + self.pressed.is_empty() + } + + /// Returns the most recent key pressed. + pub fn get_one_key(&self) -> Option { + self.pressed.last().cloned() + } } -impl BitOr> for KeyState { +impl BitOr> for KeyState { type Output = KeyState; fn bitor(self, rhs: Self) -> Self::Output { @@ -70,7 +80,7 @@ impl BitOr> for KeyState { /// Mappings can be symbolic (preserve symbols across the mapping, and rewrite /// modifier keys as needed) or physical (maintain a one-to-one mapping from /// physical keys to physical keys). -pub trait KeyAdapter { +pub trait KeyAdapter { /// Map the current state of the keyboard with symbols of type `F` to an /// equivalent keyboard state with symbols of type `T`. fn map(state: &KeyState) -> KeyState; diff --git a/src/keyboard/symbols.rs b/src/keyboard/symbols.rs index ad59647..6caf954 100644 --- a/src/keyboard/symbols.rs +++ b/src/keyboard/symbols.rs @@ -338,13 +338,13 @@ mod tests { let symbols = SymbolAdapter::map(&positions); assert_eq!( - &vec![ - KeySymbol::Char('b'), - KeySymbol::Char('m'), - KeySymbol::Char('c'), + vec![ + &KeySymbol::Char('b'), + &KeySymbol::Char('m'), + &KeySymbol::Char('c'), ], - symbols.pressed() - ); + symbols.pressed().collect::>() + ) } #[test] @@ -357,12 +357,12 @@ mod tests { let symbols = SymbolAdapter::map(&positions); assert_eq!( - &vec![ - KeySymbol::Char('B'), - KeySymbol::Char('M'), - KeySymbol::Char('C'), + vec![ + &KeySymbol::Char('B'), + &KeySymbol::Char('M'), + &KeySymbol::Char('C'), ], - symbols.pressed() + symbols.pressed().collect::>() ); } @@ -375,24 +375,24 @@ mod tests { let symbols = SymbolAdapter::map(&positions); assert_eq!( - &vec![ - KeySymbol::Char('1'), - KeySymbol::Char('2'), - KeySymbol::Char('3'), + vec![ + &KeySymbol::Char('1'), + &KeySymbol::Char('2'), + &KeySymbol::Char('3'), ], - symbols.pressed() + symbols.pressed().collect::>() ); positions.press(KeyPosition::LShift); let symbols = SymbolAdapter::map(&positions); assert_eq!( - &vec![ - KeySymbol::Char('!'), - KeySymbol::Char('@'), - KeySymbol::Char('#'), + vec![ + &KeySymbol::Char('!'), + &KeySymbol::Char('@'), + &KeySymbol::Char('#'), ], - symbols.pressed() + symbols.pressed().collect::>() ); } @@ -405,12 +405,12 @@ mod tests { let symbols = SymbolAdapter::map(&positions); assert_eq!( - &vec![ - KeySymbol::Return, - KeySymbol::Backspace, - KeySymbol::Char(' '), + vec![ + &KeySymbol::Return, + &KeySymbol::Backspace, + &KeySymbol::Char(' '), ], - symbols.pressed() + symbols.pressed().collect::>() ); } @@ -441,21 +441,21 @@ mod tests { let symbols = SymbolAdapter::map(&positions); assert_eq!( - &vec![ - KeySymbol::Char('q'), - KeySymbol::Char('a'), - KeySymbol::Char('b'), - KeySymbol::Char('6'), - KeySymbol::Char('7'), - KeySymbol::Char('8'), - KeySymbol::Char('-'), - KeySymbol::Char('\\'), - KeySymbol::Char(';'), - KeySymbol::Char(','), - KeySymbol::Return, - KeySymbol::LAlt, + vec![ + &KeySymbol::Char('q'), + &KeySymbol::Char('a'), + &KeySymbol::Char('b'), + &KeySymbol::Char('6'), + &KeySymbol::Char('7'), + &KeySymbol::Char('8'), + &KeySymbol::Char('-'), + &KeySymbol::Char('\\'), + &KeySymbol::Char(';'), + &KeySymbol::Char(','), + &KeySymbol::Return, + &KeySymbol::LAlt, ], - symbols.pressed() + symbols.pressed().collect::>() ); positions.press(KeyPosition::LShift); @@ -463,21 +463,21 @@ mod tests { let symbols = SymbolAdapter::map(&positions); assert_eq!( - &vec![ - KeySymbol::Char('Q'), - KeySymbol::Char('A'), - KeySymbol::Char('B'), - KeySymbol::Char('^'), - KeySymbol::Char('&'), - KeySymbol::Char('*'), - KeySymbol::Char('_'), - KeySymbol::Char('|'), - KeySymbol::Char(':'), - KeySymbol::Char('<'), - KeySymbol::Return, - KeySymbol::LAlt, + vec![ + &KeySymbol::Char('Q'), + &KeySymbol::Char('A'), + &KeySymbol::Char('B'), + &KeySymbol::Char('^'), + &KeySymbol::Char('&'), + &KeySymbol::Char('*'), + &KeySymbol::Char('_'), + &KeySymbol::Char('|'), + &KeySymbol::Char(':'), + &KeySymbol::Char('<'), + &KeySymbol::Return, + &KeySymbol::LAlt, ], - symbols.pressed() + symbols.pressed().collect::>() ); } @@ -501,12 +501,12 @@ mod tests { let symbols = SymbolAdapter::map(&positions); assert_eq!( - &vec![ - KeySymbol::Char('b'), - KeySymbol::Char('m'), - KeySymbol::Char('c'), + vec![ + &KeySymbol::Char('b'), + &KeySymbol::Char('m'), + &KeySymbol::Char('c'), ], - symbols.pressed() + symbols.pressed().collect::>() ); } @@ -519,6 +519,9 @@ mod tests { let symbols = SymbolAdapter::map(&positions); - assert_eq!(&vec![KeySymbol::Interrupt], symbols.pressed()); + assert_eq!( + vec![&KeySymbol::Interrupt], + symbols.pressed().collect::>() + ); } } diff --git a/src/systems/pet/keyboard.rs b/src/systems/pet/keyboard.rs index 94708a2..a0c5073 100644 --- a/src/systems/pet/keyboard.rs +++ b/src/systems/pet/keyboard.rs @@ -363,13 +363,13 @@ mod tests { let mapped = PetKeyboardAdapter::map(&state); assert_eq!( - &vec![ - PetKeys::A, - PetKeys::Apostrophe, - PetKeys::Num9, - PetKeys::Semicolon, + vec![ + &PetKeys::A, + &PetKeys::Apostrophe, + &PetKeys::Num9, + &PetKeys::Semicolon, ], - mapped.pressed() + mapped.pressed().collect::>() ); } @@ -384,8 +384,8 @@ mod tests { let mapped = PetSymbolAdapter::map(&state); assert_eq!( - &vec![PetKeys::A, PetKeys::Apostrophe, PetKeys::Num9,], - mapped.pressed() + vec![&PetKeys::A, &PetKeys::Apostrophe, &PetKeys::Num9,], + mapped.pressed().collect::>() ); } @@ -397,7 +397,10 @@ mod tests { let mapped = PetSymbolAdapter::map(&state); - assert_eq!(&vec![PetKeys::DoubleQuote], mapped.pressed()); + assert_eq!( + vec![&PetKeys::DoubleQuote], + mapped.pressed().collect::>() + ); } #[test] @@ -408,13 +411,19 @@ mod tests { state.press(KeySymbol::Char('a')); let mapped = PetSymbolAdapter::map(&state); - assert_eq!(&vec![PetKeys::LShift, PetKeys::A], mapped.pressed()); + assert_eq!( + vec![&PetKeys::LShift, &PetKeys::A], + mapped.pressed().collect::>() + ); state.release(KeySymbol::LAlt); state.press(KeySymbol::RAlt); let mapped = PetSymbolAdapter::map(&state); - assert_eq!(&vec![PetKeys::A, PetKeys::RShift], mapped.pressed()); + assert_eq!( + vec![&PetKeys::A, &PetKeys::RShift], + mapped.pressed().collect::>() + ); } #[test] @@ -423,36 +432,36 @@ mod tests { state.press(KeySymbol::DownArrow); assert_eq!( - &vec![PetKeys::CursorUpDown], - PetSymbolAdapter::map(&state).pressed() + vec![&PetKeys::CursorUpDown], + PetSymbolAdapter::map(&state).pressed().collect::>() ); state.release(KeySymbol::DownArrow); state.press(KeySymbol::UpArrow); assert_eq!( - &vec![PetKeys::LShift, PetKeys::CursorUpDown], - PetSymbolAdapter::map(&state).pressed() + vec![&PetKeys::LShift, &PetKeys::CursorUpDown], + PetSymbolAdapter::map(&state).pressed().collect::>() ); state.press(KeySymbol::LeftArrow); assert_eq!( - &vec![ - PetKeys::LShift, - PetKeys::CursorUpDown, - PetKeys::CursorLeftRight, + vec![ + &PetKeys::LShift, + &PetKeys::CursorUpDown, + &PetKeys::CursorLeftRight, ], - PetSymbolAdapter::map(&state).pressed() + PetSymbolAdapter::map(&state).pressed().collect::>() ); // map the up and left arrow, but give up on the right state.press(KeySymbol::RightArrow); assert_eq!( - &vec![ - PetKeys::LShift, - PetKeys::CursorUpDown, - PetKeys::CursorLeftRight + vec![ + &PetKeys::LShift, + &PetKeys::CursorUpDown, + &PetKeys::CursorLeftRight ], - PetSymbolAdapter::map(&state).pressed() + PetSymbolAdapter::map(&state).pressed().collect::>() ); } }