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 wio::wide::FromWide;
use crate::get_flag;
use crate::FlagOperations;
#[allow(clippy::struct_excessive_bools)]
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
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;
match key.vkCode {
@ -53,7 +53,7 @@ impl KeyState {
#[no_mangle] //required to not get garbage from native call
pub fn name(&self) -> String {
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];
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
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 key;
///gets the flag at the position of `flag`. `flag` must have exactly 1 bit set
fn get_flag(val: u32, flag: u32) -> bool {
if has_one_bit_set(flag) {
val & flag != 0
//TODO generify this?
impl FlagOperations for u32 {
fn has_one_bit_set(&self) -> bool {
*self > 0 && *self & (*self - 1) == 0
}
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
fn has_one_bit_set(n: u32) -> bool {
//Dont ask me why this works! its mathgic!
n > 0 && n & (n - 1) == 0
trait FlagOperations {
///true if exactly 1 bit of the given number is set
fn has_one_bit_set(&self) -> bool;
///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)]
mod tests {
use crate::FlagOperations;
#[test]
fn get_flag() {
assert!(super::get_flag(5, 1 << 2));
assert!(!super::get_flag(3, 1 << 2));
assert!(5u32.get_flag(1 << 2));
assert!(!3u32.get_flag(1 << 2));
}
#[test]
#[should_panic]
fn get_flag_panic() {
super::get_flag(0, 3);
0u32.get_flag(3);
}
#[test]
fn has_one_bit_set() {
assert!(super::has_one_bit_set(1));
assert!(!super::has_one_bit_set(3));
assert!(1u32.has_one_bit_set());
assert!(!3u32.has_one_bit_set());
}
}