Add config caching
This commit is contained in:
parent
f4fecccd99
commit
97841963b3
|
@ -12,6 +12,8 @@ use std::collections::HashSet;
|
|||
use regex::Regex;
|
||||
use std::process::exit;
|
||||
use log::{debug, info, warn, error};
|
||||
use std::cell::RefCell;
|
||||
use std::time::SystemTime;
|
||||
|
||||
// TODO: add documentation link
|
||||
const DEFAULT_CONFIG_FILE_CONTENT : &str = include_str!("res/config.yaml");
|
||||
|
@ -171,23 +173,27 @@ impl ConfigSet { // TODO: tests
|
|||
}
|
||||
}
|
||||
|
||||
pub trait ConfigManager {
|
||||
fn active_config(&self) -> &Configs;
|
||||
fn default_config(&self) -> &Configs;
|
||||
fn matches(&self) -> &Vec<Match>;
|
||||
pub trait ConfigManager<'a> {
|
||||
fn active_config(&'a self) -> &'a Configs;
|
||||
fn default_config(&'a self) -> &'a Configs;
|
||||
fn matches(&'a self) -> &'a Vec<Match>;
|
||||
}
|
||||
|
||||
pub struct RuntimeConfigManager<S: SystemManager> {
|
||||
pub struct RuntimeConfigManager<'a, S: SystemManager> {
|
||||
set: ConfigSet,
|
||||
title_regexps: Vec<Option<Regex>>,
|
||||
class_regexps: Vec<Option<Regex>>,
|
||||
exec_regexps: Vec<Option<Regex>>,
|
||||
|
||||
system_manager: S
|
||||
system_manager: S,
|
||||
|
||||
// Cache
|
||||
last_config_update: RefCell<SystemTime>,
|
||||
last_config: RefCell<Option<&'a Configs>>
|
||||
}
|
||||
|
||||
impl <S: SystemManager> RuntimeConfigManager<S> {
|
||||
pub fn new(set: ConfigSet, system_manager: S) -> RuntimeConfigManager<S> {
|
||||
impl <'a, S: SystemManager> RuntimeConfigManager<'a, S> {
|
||||
pub fn new<'b>(set: ConfigSet, system_manager: S) -> RuntimeConfigManager<'b, S> {
|
||||
// Compile all the regexps
|
||||
let title_regexps = set.specific.iter().map(
|
||||
|config| {
|
||||
|
@ -237,18 +243,21 @@ impl <S: SystemManager> RuntimeConfigManager<S> {
|
|||
}
|
||||
).collect();
|
||||
|
||||
let last_config_update = RefCell::new(SystemTime::now());
|
||||
let last_config = RefCell::new(None);
|
||||
|
||||
RuntimeConfigManager {
|
||||
set,
|
||||
title_regexps,
|
||||
class_regexps,
|
||||
exec_regexps,
|
||||
system_manager
|
||||
system_manager,
|
||||
last_config_update,
|
||||
last_config
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl <S: SystemManager> ConfigManager for RuntimeConfigManager<S> {
|
||||
fn active_config(&self) -> &Configs {
|
||||
fn calculate_active_config(&'a self) -> &'a Configs {
|
||||
// TODO: optimize performance by avoiding some of these checks if no Configs use the filters
|
||||
|
||||
debug!("Requested config for window:");
|
||||
|
@ -308,12 +317,36 @@ impl <S: SystemManager> ConfigManager for RuntimeConfigManager<S> {
|
|||
debug!("No matches for custom configs, using default settings.");
|
||||
&self.set.default
|
||||
}
|
||||
}
|
||||
|
||||
fn default_config(&self) -> &Configs {
|
||||
impl <'a, S: SystemManager> ConfigManager<'a> for RuntimeConfigManager<'a, S> {
|
||||
fn active_config(&'a self) -> &'a Configs {
|
||||
let mut last_config_update = self.last_config_update.borrow_mut();
|
||||
if let Ok(elapsed) = (*last_config_update).elapsed() {
|
||||
*last_config_update = SystemTime::now();
|
||||
|
||||
if elapsed.as_millis() < 800 { // TODO: make config option
|
||||
let last_config = self.last_config.borrow();
|
||||
if let Some(cached_config) = *last_config {
|
||||
debug!("Using cached config");
|
||||
return cached_config;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let config = self.calculate_active_config();
|
||||
|
||||
let mut last_config = self.last_config.borrow_mut();
|
||||
*last_config = Some(config);
|
||||
|
||||
config
|
||||
}
|
||||
|
||||
fn default_config(&'a self) -> &'a Configs {
|
||||
&self.set.default
|
||||
}
|
||||
|
||||
fn matches(&self) -> &Vec<Match> {
|
||||
fn matches(&'a self) -> &'a Vec<Match> {
|
||||
&self.active_config().matches
|
||||
}
|
||||
}
|
|
@ -6,7 +6,7 @@ use crate::clipboard::ClipboardManager;
|
|||
use log::{info};
|
||||
use crate::ui::UIManager;
|
||||
|
||||
pub struct Engine<'a, S: KeyboardSender, C: ClipboardManager, M: ConfigManager,
|
||||
pub struct Engine<'a, S: KeyboardSender, C: ClipboardManager, M: ConfigManager<'a>,
|
||||
U: UIManager> {
|
||||
sender: S,
|
||||
clipboard_manager: &'a C,
|
||||
|
@ -14,14 +14,14 @@ pub struct Engine<'a, S: KeyboardSender, C: ClipboardManager, M: ConfigManager,
|
|||
ui_manager: &'a U,
|
||||
}
|
||||
|
||||
impl <'a, S: KeyboardSender, C: ClipboardManager, M: ConfigManager, U: UIManager>
|
||||
impl <'a, S: KeyboardSender, C: ClipboardManager, M: ConfigManager<'a>, U: UIManager>
|
||||
Engine<'a, S, C, M, U> {
|
||||
pub fn new<'b>(sender: S, clipboard_manager: &'b C, config_manager: &'b M, ui_manager: &'b U) -> Engine<'b, S, C, M, U> {
|
||||
pub fn new(sender: S, clipboard_manager: &'a C, config_manager: &'a M, ui_manager: &'a U) -> Engine<'a, S, C, M, U> {
|
||||
Engine{sender, clipboard_manager, config_manager, ui_manager }
|
||||
}
|
||||
}
|
||||
|
||||
impl <'a, S: KeyboardSender, C: ClipboardManager, M: ConfigManager, U: UIManager>
|
||||
impl <'a, S: KeyboardSender, C: ClipboardManager, M: ConfigManager<'a>, U: UIManager>
|
||||
MatchReceiver for Engine<'a, S, C, M, U>{
|
||||
|
||||
fn on_match(&self, m: &Match) {
|
||||
|
|
|
@ -6,7 +6,7 @@ use crate::keyboard::KeyModifier::BACKSPACE;
|
|||
use std::time::SystemTime;
|
||||
use std::collections::VecDeque;
|
||||
|
||||
pub struct ScrollingMatcher<'a, R: MatchReceiver, M: ConfigManager> {
|
||||
pub struct ScrollingMatcher<'a, R: MatchReceiver, M: ConfigManager<'a>> {
|
||||
config_manager: &'a M,
|
||||
receiver: R,
|
||||
current_set_queue: RefCell<VecDeque<Vec<MatchEntry<'a>>>>,
|
||||
|
@ -19,7 +19,7 @@ struct MatchEntry<'a> {
|
|||
_match: &'a Match
|
||||
}
|
||||
|
||||
impl <'a, R: MatchReceiver, M: ConfigManager> super::Matcher for ScrollingMatcher<'a, R, M> where{
|
||||
impl <'a, R: MatchReceiver, M: ConfigManager<'a>> super::Matcher for ScrollingMatcher<'a, R, M> where{
|
||||
fn handle_char(&self, c: char) {
|
||||
// if not enabled, avoid any processing
|
||||
if !*(self.is_enabled.borrow()) {
|
||||
|
@ -100,7 +100,7 @@ impl <'a, R: MatchReceiver, M: ConfigManager> super::Matcher for ScrollingMatche
|
|||
}
|
||||
}
|
||||
}
|
||||
impl <'a, R: MatchReceiver, M: ConfigManager> ScrollingMatcher<'a, R, M> {
|
||||
impl <'a, R: MatchReceiver, M: ConfigManager<'a>> ScrollingMatcher<'a, R, M> {
|
||||
pub fn new(config_manager: &'a M, receiver: R) -> ScrollingMatcher<'a, R, M> {
|
||||
let current_set_queue = RefCell::new(VecDeque::new());
|
||||
let toggle_press_time = RefCell::new(SystemTime::now());
|
||||
|
|
Loading…
Reference in New Issue
Block a user