refactoring

This commit is contained in:
crusader 2020-12-16 22:02:09 +09:00
parent 0468d32bc1
commit 02355fa511
3 changed files with 125 additions and 44 deletions

View File

@ -5,12 +5,23 @@ pub use crate::windows::*;
use crate::keyboard::Key; use crate::keyboard::Key;
use crate::mouse::Button; use crate::mouse::Button;
use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::time::SystemTime; use std::{
collections::hash_map::HashMap,
sync::{Arc, Mutex},
time::SystemTime,
};
pub mod keyboard; pub mod keyboard;
pub mod mouse; pub mod mouse;
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize, Eq, Hash)]
pub enum EventListenType {
Mouse,
Keyboard,
}
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
pub enum EventType { pub enum EventType {
KeyPress(Key), KeyPress(Key),
@ -26,7 +37,55 @@ pub struct Event {
pub event_type: EventType, pub event_type: EventType,
} }
// pub type HookCallback = fn(event: Event); pub enum BlockInput {
pub type HookCallback = for<'a> fn(&'a Event); Block,
DontBlock,
}
pub enum Bind {
NormalBind(BindHandler),
BlockBind(BlockBindHandler),
BlockableBind(BlockableBindHandler),
}
pub type BindHandler = Arc<dyn Fn(Event) + Send + Sync + 'static>;
pub type BlockBindHandler = Arc<dyn Fn(Event) + Send + Sync + 'static>;
pub type BlockableBindHandler = Arc<dyn Fn(Event) -> BlockInput + Send + Sync + 'static>;
pub type EventBindMap = HashMap<EventListenType, Bind>;
pub static EVENT_BINDS: Lazy<Mutex<EventBindMap>> = Lazy::new(|| Mutex::new(EventBindMap::new()));
pub struct Robot; pub struct Robot;
impl Robot {
pub fn bind<F: Fn(Event) + Send + Sync + 'static>(listen_type: EventListenType, callback: F) {
EVENT_BINDS
.lock()
.unwrap()
.insert(listen_type, Bind::NormalBind(Arc::new(callback)));
}
pub fn block_bind<F: Fn(Event) + Send + Sync + 'static>(
listen_type: EventListenType,
callback: F,
) {
EVENT_BINDS
.lock()
.unwrap()
.insert(listen_type, Bind::BlockBind(Arc::new(callback)));
}
pub fn blockable_bind<F: Fn(Event) -> BlockInput + Send + Sync + 'static>(
listen_type: EventListenType,
callback: F,
) {
EVENT_BINDS
.lock()
.unwrap()
.insert(listen_type, Bind::BlockableBind(Arc::new(callback)));
}
pub fn unbind(listen_type: EventListenType) {
EVENT_BINDS.lock().unwrap().remove(&listen_type);
}
}

View File

@ -1,11 +1,18 @@
use crate::windows; use crate::windows;
use crate::{Event, EventType, HookCallback, Key, Robot}; use crate::{Bind, BlockInput, Event, EventListenType, EventType, Key, Robot, EVENT_BINDS};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use std::collections::HashMap; use std::{
use std::mem::{size_of, transmute_copy}; collections::HashMap,
use std::ptr::null_mut; mem::{size_of, transmute_copy},
use std::sync::atomic::{AtomicPtr, Ordering}; ptr::null_mut,
use std::time::SystemTime; sync::{
atomic::{AtomicPtr, Ordering},
Arc,
},
thread::spawn,
time::SystemTime,
};
use winapi::ctypes::c_int; use winapi::ctypes::c_int;
use winapi::shared::minwindef::{LPARAM, LRESULT, WORD, WPARAM}; use winapi::shared::minwindef::{LPARAM, LRESULT, WORD, WPARAM};
use winapi::shared::windef::HHOOK__; use winapi::shared::windef::HHOOK__;
@ -257,17 +264,10 @@ static VK_2_KEY_MAP: Lazy<HashMap<WORD, Key>> = Lazy::new(|| {
m m
}); });
fn default_callback(event: Event) {
println!("Default : Event {:?}", event);
}
static KEYBOARD_HHOOK: Lazy<AtomicPtr<HHOOK__>> = Lazy::new(AtomicPtr::default); static KEYBOARD_HHOOK: Lazy<AtomicPtr<HHOOK__>> = Lazy::new(AtomicPtr::default);
static mut HOOK_CALLBACK: HookCallback = |event| {
default_callback(*event);
};
impl Robot { impl Robot {
pub unsafe fn key_listen(callback: HookCallback) -> Result<(), windows::HookError> { pub unsafe fn key_listen() -> Result<(), windows::HookError> {
if KEYBOARD_HHOOK.load(Ordering::Relaxed).is_null() { if KEYBOARD_HHOOK.load(Ordering::Relaxed).is_null() {
let r = windows::hook(WH_KEYBOARD_LL, &*KEYBOARD_HHOOK, Self::key_raw_callback); let r = windows::hook(WH_KEYBOARD_LL, &*KEYBOARD_HHOOK, Self::key_raw_callback);
@ -276,8 +276,6 @@ impl Robot {
} }
} }
HOOK_CALLBACK = callback;
Ok(()) Ok(())
} }
@ -289,10 +287,6 @@ impl Robot {
} }
} }
HOOK_CALLBACK = |event| {
default_callback(*event);
};
Ok(()) Ok(())
} }
@ -379,7 +373,25 @@ impl Robot {
event_type, event_type,
time: SystemTime::now(), time: SystemTime::now(),
}; };
HOOK_CALLBACK(&event);
if let Some(bind) = EVENT_BINDS.lock().unwrap().get_mut(&EventListenType::Mouse) {
match bind {
Bind::NormalBind(cb) => {
let cb = Arc::clone(cb);
spawn(move || cb(event));
}
Bind::BlockBind(cb) => {
let cb = Arc::clone(cb);
spawn(move || cb(event));
return 1;
}
Bind::BlockableBind(cb) => {
if let BlockInput::Block = cb(event) {
return 1;
}
}
}
}
} }
} }
CallNextHookEx(null_mut(), code, w_param, l_param) CallNextHookEx(null_mut(), code, w_param, l_param)

View File

@ -1,10 +1,16 @@
use crate::windows; use crate::windows;
use crate::{Button, Event, EventType, HookCallback, Robot}; use crate::{Bind, BlockInput, Button, Event, EventListenType, EventType, Robot, EVENT_BINDS};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use std::mem::{size_of, transmute}; use std::{
use std::ptr::null_mut; mem::{size_of, transmute},
use std::sync::atomic::{AtomicPtr, Ordering}; ptr::null_mut,
use std::time::SystemTime; sync::{
atomic::{AtomicPtr, Ordering},
Arc,
},
thread::spawn,
time::SystemTime,
};
use winapi::ctypes::c_int; use winapi::ctypes::c_int;
use winapi::shared::minwindef::{DWORD, HIWORD, LPARAM, LRESULT, WPARAM}; use winapi::shared::minwindef::{DWORD, HIWORD, LPARAM, LRESULT, WPARAM};
use winapi::shared::windef::{HHOOK__, POINT}; use winapi::shared::windef::{HHOOK__, POINT};
@ -19,17 +25,10 @@ use winapi::um::winuser::{
WM_RBUTTONUP, WM_XBUTTONDOWN, WM_XBUTTONUP, XBUTTON1, XBUTTON2, WM_RBUTTONUP, WM_XBUTTONDOWN, WM_XBUTTONUP, XBUTTON1, XBUTTON2,
}; };
fn default_callback(event: Event) {
println!("Default : Event {:?}", event);
}
static MOUSE_HHOOK: Lazy<AtomicPtr<HHOOK__>> = Lazy::new(AtomicPtr::default); static MOUSE_HHOOK: Lazy<AtomicPtr<HHOOK__>> = Lazy::new(AtomicPtr::default);
static mut HOOK_CALLBACK: HookCallback = |event| {
default_callback(*event);
};
impl Robot { impl Robot {
pub unsafe fn mouse_listen(callback: HookCallback) -> Result<(), windows::HookError> { pub unsafe fn mouse_listen() -> Result<(), windows::HookError> {
if MOUSE_HHOOK.load(Ordering::Relaxed).is_null() { if MOUSE_HHOOK.load(Ordering::Relaxed).is_null() {
let r = windows::hook(WH_MOUSE_LL, &*MOUSE_HHOOK, Self::mouse_raw_callback); let r = windows::hook(WH_MOUSE_LL, &*MOUSE_HHOOK, Self::mouse_raw_callback);
@ -38,8 +37,6 @@ impl Robot {
} }
} }
HOOK_CALLBACK = callback;
Ok(()) Ok(())
} }
@ -51,10 +48,6 @@ impl Robot {
} }
} }
HOOK_CALLBACK = |event| {
default_callback(*event);
};
Ok(()) Ok(())
} }
@ -229,7 +222,24 @@ impl Robot {
time: SystemTime::now(), time: SystemTime::now(),
}; };
HOOK_CALLBACK(&event); if let Some(bind) = EVENT_BINDS.lock().unwrap().get_mut(&EventListenType::Mouse) {
match bind {
Bind::NormalBind(cb) => {
let cb = Arc::clone(cb);
spawn(move || cb(event));
}
Bind::BlockBind(cb) => {
let cb = Arc::clone(cb);
spawn(move || cb(event));
return 1;
}
Bind::BlockableBind(cb) => {
if let BlockInput::Block = cb(event) {
return 1;
}
}
}
}
} }
} }
CallNextHookEx(null_mut(), code, w_param, l_param) CallNextHookEx(null_mut(), code, w_param, l_param)