Improve event handling system

This commit is contained in:
Federico Terzi 2019-09-12 23:53:17 +02:00
parent 8f47c6b216
commit 2e068154a7
8 changed files with 153 additions and 35 deletions

72
Cargo.lock generated
View File

@ -229,6 +229,9 @@ dependencies = [
"cmake 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
"dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_yaml 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)",
@ -324,6 +327,48 @@ name = "nodrop"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "num"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"num-complex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
"num-iter 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
"num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-bigint"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-complex"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-derive"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-integer"
version = "0.1.41"
@ -333,6 +378,27 @@ dependencies = [
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-iter"
version = "0.1.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-rational"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-traits"
version = "0.2.8"
@ -742,7 +808,13 @@ dependencies = [
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
"checksum miniz_oxide 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7108aff85b876d06f22503dcce091e29f76733b2bfdd91eebce81f5e68203a10"
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
"checksum num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cf4825417e1e1406b3782a8ce92f4d53f26ec055e3622e1881ca8e9f5f9e08db"
"checksum num-bigint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f9c3f34cdd24f334cb265d9bf8bfa8a241920d026916785747a92f0e55541a1a"
"checksum num-complex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fcb0cf31fb3ff77e6d2a6ebd6800df7fdcd106f2ad89113c9130bcd07f93dffc"
"checksum num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "eafd0b45c5537c3ba526f79d3e75120036502bebacbb3f3220914067ce39dbf2"
"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09"
"checksum num-iter 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "76bd5272412d173d6bf9afdf98db8612bbabc9a7a830b7bfc9c188911716132e"
"checksum num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2885278d5fe2adc2f75ced642d52d879bffaceb5a2e0b1d4309ffdfb239b454"
"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
"checksum podio 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "780fb4b6698bbf9cf2444ea5d22411cef2953f0824b98f33cf454ec5615645bd"
"checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b"

View File

@ -15,6 +15,9 @@ regex = "1.3.1"
log = "0.4.8"
simplelog = "0.7.1"
zip = "0.5.3"
num = "0.2.0"
num-traits = "0.2.8"
num-derive = "0.2.5"
[dev-dependencies]
tempfile = "3.1.0"

View File

@ -1,6 +1,6 @@
use std::sync::mpsc::Sender;
use crate::bridge::windows::*;
use crate::event::{Event, KeyEvent, KeyModifier, ActionEvent};
use crate::event::{Event, KeyEvent, KeyModifier, ActionEvent, ActionType};
use crate::event::KeyModifier::*;
use std::ffi::c_void;
use std::fs::create_dir_all;
@ -137,7 +137,7 @@ extern fn context_menu_click_callback(_self: *mut c_void, id: i32) {
unsafe {
let _self = _self as *mut WindowsContext;
let event = Event::Action(ActionEvent::ContextMenuClick(id));
let event = Event::Action(ActionEvent::ContextMenuClick(ActionType::from(id)));
(*_self).send_channel.send(event).unwrap();
}
}

View File

@ -5,7 +5,7 @@ use crate::config::BackendType;
use crate::clipboard::ClipboardManager;
use log::{info};
use crate::ui::{UIManager, MenuItem, MenuItemType};
use crate::event::{ActionEventReceiver, Event, ActionEvent};
use crate::event::{ActionEventReceiver, Event, ActionEvent, ActionType};
use std::cell::RefCell;
pub struct Engine<'a, S: KeyboardSender, C: ClipboardManager, M: ConfigManager<'a>,
@ -36,7 +36,7 @@ impl <'a, S: KeyboardSender, C: ClipboardManager, M: ConfigManager<'a>, U: UIMan
menu.push(MenuItem{
item_type: MenuItemType::Button,
item_name: toggle_text,
item_id: 2,
item_id: ActionType::Toggle as i32,
});
menu.push(MenuItem{
@ -48,7 +48,7 @@ impl <'a, S: KeyboardSender, C: ClipboardManager, M: ConfigManager<'a>, U: UIMan
menu.push(MenuItem{
item_type: MenuItemType::Button,
item_name: "Exit".to_owned(),
item_id: 1,
item_id: ActionType::Exit as i32,
});
menu
@ -119,7 +119,7 @@ impl <'a, S: KeyboardSender, C: ClipboardManager,
self.ui_manager.show_menu(self.build_menu());
},
ActionEvent::ContextMenuClick(id) => {
println!("{}", id);
}
}
}

View File

@ -7,17 +7,17 @@ pub trait EventManager {
pub struct DefaultEventManager<'a, K: KeyEventReceiver, A: ActionEventReceiver> {
receive_channel: Receiver<Event>,
key_receiver: &'a K,
action_receiver: &'a A,
key_receivers: Vec<&'a K>,
action_receivers: Vec<&'a A>,
}
impl<'a, K: KeyEventReceiver, A: ActionEventReceiver> DefaultEventManager<'a, K, A> {
pub fn new(receive_channel: Receiver<Event>, key_receiver: &'a K,
action_receiver: &'a A) -> DefaultEventManager<'a, K, A> {
pub fn new(receive_channel: Receiver<Event>, key_receivers: Vec<&'a K>,
action_receivers: Vec<&'a A>) -> DefaultEventManager<'a, K, A> {
DefaultEventManager {
receive_channel,
key_receiver,
action_receiver,
key_receivers,
action_receivers,
}
}
}
@ -29,10 +29,10 @@ impl <'a, K: KeyEventReceiver, A: ActionEventReceiver> EventManager for DefaultE
Ok(event) => {
match event {
Event::Key(key_event) => {
self.key_receiver.on_key_event(key_event);
self.key_receivers.iter().for_each(move |&receiver| receiver.on_key_event(key_event.clone()));
},
Event::Action(action_event) => {
self.action_receiver.on_action_event(action_event);
self.action_receivers.iter().for_each(|&receiver| receiver.on_action_event(action_event.clone()));
}
}
},

View File

@ -2,19 +2,36 @@ pub(crate) mod manager;
use serde::{Serialize, Deserialize};
#[derive(Debug)]
#[derive(Debug, Clone)]
pub enum Event {
Action(ActionEvent),
Key(KeyEvent)
}
#[derive(Debug)]
#[derive(Debug, Clone)]
pub enum ActionEvent {
IconClick,
ContextMenuClick(i32)
ContextMenuClick(ActionType)
}
#[derive(Debug)]
#[derive(Debug, Clone)]
pub enum ActionType {
Noop = 0,
Toggle = 1,
Exit = 2,
}
impl From<i32> for ActionType {
fn from(id: i32) -> Self {
match id {
1 => ActionType::Toggle,
2 => ActionType::Exit,
_ => ActionType::Noop,
}
}
}
#[derive(Debug, Clone)]
pub enum KeyEvent {
Char(char),
Modifier(KeyModifier)

View File

@ -1,3 +1,6 @@
#[macro_use]
extern crate num_derive;
use std::sync::{mpsc, Arc};
use crate::matcher::Matcher;
use crate::matcher::scrolling::ScrollingMatcher;
@ -122,8 +125,8 @@ fn espanso_background(receive_channel: Receiver<Event>, config_set: ConfigSet) {
let event_manager = DefaultEventManager::new(
receive_channel,
&matcher,
&engine,
vec!(&matcher),
vec!(&engine, &matcher),
);
event_manager.eventloop();

View File

@ -1,6 +1,6 @@
use crate::matcher::{Match, MatchReceiver};
use std::cell::RefCell;
use crate::event::KeyModifier;
use crate::event::{KeyModifier, ActionEventReceiver, ActionEvent, ActionType};
use crate::config::ConfigManager;
use crate::event::KeyModifier::BACKSPACE;
use std::time::SystemTime;
@ -19,7 +19,29 @@ struct MatchEntry<'a> {
_match: &'a Match
}
impl <'a, R: MatchReceiver, M: ConfigManager<'a>> super::Matcher for ScrollingMatcher<'a, R, M> where{
impl <'a, R: MatchReceiver, M: ConfigManager<'a>> ScrollingMatcher<'a, R, M> {
pub fn new(config_manager: &'a M, receiver: &'a R) -> ScrollingMatcher<'a, R, M> {
let current_set_queue = RefCell::new(VecDeque::new());
let toggle_press_time = RefCell::new(SystemTime::now());
ScrollingMatcher{
config_manager,
receiver,
current_set_queue,
toggle_press_time,
is_enabled: RefCell::new(true)
}
}
fn toggle(&self) {
let mut is_enabled = self.is_enabled.borrow_mut();
*is_enabled = !(*is_enabled);
self.receiver.on_toggle(*is_enabled);
}
}
impl <'a, R: MatchReceiver, M: ConfigManager<'a>> super::Matcher for ScrollingMatcher<'a, R, M> {
fn handle_char(&self, c: char) {
// if not enabled, avoid any processing
if !*(self.is_enabled.borrow()) {
@ -79,14 +101,13 @@ impl <'a, R: MatchReceiver, M: ConfigManager<'a>> super::Matcher for ScrollingMa
let mut toggle_press_time = self.toggle_press_time.borrow_mut();
if let Ok(elapsed) = toggle_press_time.elapsed() {
if elapsed.as_millis() < config.toggle_interval as u128 {
let mut is_enabled = self.is_enabled.borrow_mut();
*is_enabled = !(*is_enabled);
let mut is_enabled = self.is_enabled.borrow();
if !*is_enabled {
self.current_set_queue.borrow_mut().clear();
}
self.receiver.on_toggle(*is_enabled);
self.toggle();
}
}
@ -100,17 +121,19 @@ impl <'a, R: MatchReceiver, M: ConfigManager<'a>> super::Matcher for ScrollingMa
}
}
}
impl <'a, R: MatchReceiver, M: ConfigManager<'a>> ScrollingMatcher<'a, R, M> {
pub fn new(config_manager: &'a M, receiver: &'a R) -> ScrollingMatcher<'a, R, M> {
let current_set_queue = RefCell::new(VecDeque::new());
let toggle_press_time = RefCell::new(SystemTime::now());
ScrollingMatcher{
config_manager,
receiver,
current_set_queue,
toggle_press_time,
is_enabled: RefCell::new(true)
impl <'a, R: MatchReceiver, M: ConfigManager<'a>> ActionEventReceiver for ScrollingMatcher<'a, R, M> {
fn on_action_event(&self, e: ActionEvent) {
match e {
ActionEvent::ContextMenuClick(action_type) => {
match action_type {
ActionType::Toggle => {
self.toggle();
},
_ => {}
}
},
_ => {}
}
}
}