small clean ups for flag operations

This commit is contained in:
LordMZTE 2020-09-07 00:35:53 +02:00
parent 4bbde71e8e
commit 395cd49d4f
2 changed files with 30 additions and 19 deletions

View file

@ -2,7 +2,7 @@ use std::ffi::OsString;
use winapi::um::winuser::{GetKeyNameTextW, KBDLLHOOKSTRUCT, LLKHF_EXTENDED, LLKHF_UP}; use winapi::um::winuser::{GetKeyNameTextW, KBDLLHOOKSTRUCT, LLKHF_EXTENDED, LLKHF_UP};
use wio::wide::FromWide; use wio::wide::FromWide;
use crate::get_flag; use crate::FlagOperations;
#[allow(clippy::struct_excessive_bools)] #[allow(clippy::struct_excessive_bools)]
pub struct KeyState { pub struct KeyState {
@ -33,7 +33,7 @@ impl KeyState {
/// `key_down` if the event was a keydown event, this should be true. if it was keyup it should be false /// `key_down` if the event was a keydown event, this should be true. if it was keyup it should be false
pub fn update(&mut self, key: KBDLLHOOKSTRUCT) { pub fn update(&mut self, key: KBDLLHOOKSTRUCT) {
let key_down = !get_flag(key.flags, LLKHF_UP); let key_down = !key.flags.get_flag(LLKHF_UP);
self.kbdllstruct = key; self.kbdllstruct = key;
match key.vkCode { match key.vkCode {
@ -53,7 +53,7 @@ impl KeyState {
#[no_mangle] //required to not get garbage from native call #[no_mangle] //required to not get garbage from native call
pub fn name(&self) -> String { pub fn name(&self) -> String {
unsafe { unsafe {
let flags = if get_flag(self.kbdllstruct.flags, LLKHF_EXTENDED) { 1 << 24 } else { 0 }; let flags = if self.kbdllstruct.flags.get_flag(LLKHF_EXTENDED) { 1 << 24 } else { 0 };
let mut out = [0_u16; 128]; let mut out = [0_u16; 128];
GetKeyNameTextW((self.kbdllstruct.scanCode << 16 | flags /*this distinguishes special keys by setting a flag. yes only microsoft thinks that input and flags in 1 param is a good idea*/) as i32, (&mut out).as_mut_ptr(), 128); GetKeyNameTextW((self.kbdllstruct.scanCode << 16 | flags /*this distinguishes special keys by setting a flag. yes only microsoft thinks that input and flags in 1 param is a good idea*/) as i32, (&mut out).as_mut_ptr(), 128);
@ -64,7 +64,7 @@ impl KeyState {
///true if this event is keydown, otherwise false ///true if this event is keydown, otherwise false
pub fn is_down(&self) -> bool { pub fn is_down(&self) -> bool {
!get_flag(self.kbdllstruct.flags, LLKHF_UP) !self.kbdllstruct.flags.get_flag(LLKHF_UP)
} }
} }

View file

@ -12,38 +12,49 @@ clippy::cast_lossless, clippy::cast_possible_wrap, //lossy casts are required to
pub mod logging; pub mod logging;
pub mod key; pub mod key;
///gets the flag at the position of `flag`. `flag` must have exactly 1 bit set //TODO generify this?
fn get_flag(val: u32, flag: u32) -> bool { impl FlagOperations for u32 {
if has_one_bit_set(flag) { fn has_one_bit_set(&self) -> bool {
val & flag != 0 *self > 0 && *self & (*self - 1) == 0
} else { }
panic!("flag must have 1 bit set")
fn get_flag(&self, flag: Self) -> bool {
if flag.has_one_bit_set() {
self & flag != 0
} else {
panic!("flag must have 1 bit set")
}
} }
} }
///true if exactly 1 bit of the given number is set trait FlagOperations {
fn has_one_bit_set(n: u32) -> bool { ///true if exactly 1 bit of the given number is set
//Dont ask me why this works! its mathgic! fn has_one_bit_set(&self) -> bool;
n > 0 && n & (n - 1) == 0
///gets the flag at the position of `flag`. `flag` must have exactly 1 bit set
/// `flag` should have 1 bit set at the position of the flag to get
fn get_flag(&self, flag: Self) -> bool;
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::FlagOperations;
#[test] #[test]
fn get_flag() { fn get_flag() {
assert!(super::get_flag(5, 1 << 2)); assert!(5u32.get_flag(1 << 2));
assert!(!super::get_flag(3, 1 << 2)); assert!(!3u32.get_flag(1 << 2));
} }
#[test] #[test]
#[should_panic] #[should_panic]
fn get_flag_panic() { fn get_flag_panic() {
super::get_flag(0, 3); 0u32.get_flag(3);
} }
#[test] #[test]
fn has_one_bit_set() { fn has_one_bit_set() {
assert!(super::has_one_bit_set(1)); assert!(1u32.has_one_bit_set());
assert!(!super::has_one_bit_set(3)); assert!(!3u32.has_one_bit_set());
} }
} }