minor performance boost
This commit is contained in:
parent
ab56048574
commit
0557593230
1 changed files with 45 additions and 27 deletions
|
@ -1,6 +1,6 @@
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex, RwLock};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ use crate::config::{Anchor, Config, MatchMethod, SortOrder, WrapMode};
|
||||||
use crate::desktop::known_image_extension_regex_pattern;
|
use crate::desktop::known_image_extension_regex_pattern;
|
||||||
use crate::{Error, config, desktop};
|
use crate::{Error, config, desktop};
|
||||||
|
|
||||||
type ArcMenuMap<T> = Arc<Mutex<HashMap<FlowBoxChild, MenuItem<T>>>>;
|
type ArcMenuMap<T> = Arc<RwLock<HashMap<FlowBoxChild, MenuItem<T>>>>;
|
||||||
type ArcProvider<T> = Arc<Mutex<dyn ItemProvider<T> + Send>>;
|
type ArcProvider<T> = Arc<Mutex<dyn ItemProvider<T> + Send>>;
|
||||||
|
|
||||||
pub struct Selection<T: Clone + Send> {
|
pub struct Selection<T: Clone + Send> {
|
||||||
|
@ -83,6 +83,20 @@ impl From<config::Align> for Align {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn into_core_order(gtk_order: &Ordering) -> core::cmp::Ordering {
|
||||||
|
match gtk_order {
|
||||||
|
Ordering::Smaller => {
|
||||||
|
core::cmp::Ordering::Less
|
||||||
|
}
|
||||||
|
Ordering::Larger => {
|
||||||
|
core::cmp::Ordering::Greater
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
core::cmp::Ordering::Equal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An entry in the list of selectable items in the UI.
|
/// An entry in the list of selectable items in the UI.
|
||||||
/// Supports nested items but these cannot nested again (only nesting with depth == 1 is supported)
|
/// Supports nested items but these cannot nested again (only nesting with depth == 1 is supported)
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(Clone, PartialEq)]
|
||||||
|
@ -523,7 +537,7 @@ fn build_ui<T, P>(
|
||||||
window,
|
window,
|
||||||
search: SearchEntry::new(),
|
search: SearchEntry::new(),
|
||||||
main_box: FlowBox::new(),
|
main_box: FlowBox::new(),
|
||||||
menu_rows: Arc::new(Mutex::new(HashMap::new())),
|
menu_rows: Arc::new(RwLock::new(HashMap::new())),
|
||||||
search_text: Arc::new(Mutex::new(String::new())),
|
search_text: Arc::new(Mutex::new(String::new())),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -581,15 +595,15 @@ fn build_ui<T, P>(
|
||||||
log::debug!("got items after {:?}", wait_for_items.elapsed());
|
log::debug!("got items after {:?}", wait_for_items.elapsed());
|
||||||
|
|
||||||
let active_cfg = config.clone();
|
let active_cfg = config.clone();
|
||||||
let map_cfg = config.clone();
|
//let map_cfg = config.clone();
|
||||||
let animate_window = ui_elements.window.clone();
|
let animate_window = ui_elements.window.clone();
|
||||||
|
|
||||||
animate_window.connect_is_active_notify(move |w| {
|
animate_window.connect_is_active_notify(move |w| {
|
||||||
window_show_resize(&active_cfg.clone(), w);
|
window_show_resize(&active_cfg.clone(), w);
|
||||||
});
|
});
|
||||||
animate_window.connect_map(move |w| {
|
// animate_window.connect_map(move |w| {
|
||||||
window_show_resize(&map_cfg.clone(), w);
|
// window_show_resize(&map_cfg.clone(), w);
|
||||||
});
|
// });
|
||||||
|
|
||||||
build_ui_from_menu_items(&ui_elements, &meta, provider_elements);
|
build_ui_from_menu_items(&ui_elements, &meta, provider_elements);
|
||||||
|
|
||||||
|
@ -626,7 +640,7 @@ fn build_main_box<T: Clone + 'static>(config: &Config, ui_elements: &Rc<UiElemen
|
||||||
fb.grab_focus();
|
fb.grab_focus();
|
||||||
fb.invalidate_sort();
|
fb.invalidate_sort();
|
||||||
|
|
||||||
let lock = ui_clone.menu_rows.lock().unwrap();
|
let lock = ui_clone.menu_rows.read().unwrap();
|
||||||
select_first_visible_child(&*lock, &ui_clone.main_box);
|
select_first_visible_child(&*lock, &ui_clone.main_box);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -697,22 +711,22 @@ fn build_ui_from_menu_items<T: Clone + 'static + Send>(
|
||||||
meta: &Rc<MetaData<T>>,
|
meta: &Rc<MetaData<T>>,
|
||||||
mut items: Vec<MenuItem<T>>,
|
mut items: Vec<MenuItem<T>>,
|
||||||
) {
|
) {
|
||||||
|
items.reverse();
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
{
|
{
|
||||||
while let Some(b) = ui.main_box.child_at_index(0) {
|
while let Some(b) = ui.main_box.child_at_index(0) {
|
||||||
ui.main_box.remove(&b);
|
ui.main_box.remove(&b);
|
||||||
drop(b);
|
drop(b);
|
||||||
}
|
}
|
||||||
ui.menu_rows.lock().unwrap().clear();
|
ui.menu_rows.write().unwrap().clear();
|
||||||
|
|
||||||
let meta_clone = Rc::<MetaData<T>>::clone(meta);
|
let meta_clone = Rc::<MetaData<T>>::clone(meta);
|
||||||
let ui_clone = Rc::<UiElements<T>>::clone(ui);
|
let ui_clone = Rc::<UiElements<T>>::clone(ui);
|
||||||
|
|
||||||
glib::idle_add_local(move || {
|
glib::idle_add_local(move || {
|
||||||
ui_clone.main_box.unset_sort_func();
|
|
||||||
let mut done = false;
|
let mut done = false;
|
||||||
{
|
{
|
||||||
let mut lock = ui_clone.menu_rows.lock().unwrap();
|
let mut lock = ui_clone.menu_rows.write().unwrap();
|
||||||
|
|
||||||
for _ in 0..25 {
|
for _ in 0..25 {
|
||||||
if let Some(item) = items.pop() {
|
if let Some(item) = items.pop() {
|
||||||
|
@ -732,19 +746,18 @@ fn build_ui_from_menu_items<T: Clone + 'static + Send>(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let items_sort = ArcMenuMap::clone(&ui_clone.menu_rows);
|
|
||||||
ui_clone.main_box.set_sort_func(move |child1, child2| {
|
|
||||||
sort_menu_items_by_score(child1, child2, &items_sort)
|
|
||||||
});
|
|
||||||
|
|
||||||
if done {
|
if done {
|
||||||
let mut lock = ui_clone.menu_rows.lock().unwrap();
|
let lock = ui_clone.menu_rows.read().unwrap();
|
||||||
let menus = &mut *lock;
|
let items_sort = ArcMenuMap::clone(&ui_clone.menu_rows);
|
||||||
select_first_visible_child(menus, &ui_clone.main_box);
|
ui_clone.main_box.set_sort_func(move |child1, child2| {
|
||||||
|
sort_flow_box_childs(child1, child2, &items_sort)
|
||||||
|
});
|
||||||
|
|
||||||
|
select_first_visible_child(&lock, &ui_clone.main_box);
|
||||||
|
|
||||||
log::debug!(
|
log::debug!(
|
||||||
"Created {} menu items in {:?}",
|
"Created {} menu items in {:?}",
|
||||||
menus.len(),
|
&lock.len(),
|
||||||
start.elapsed()
|
start.elapsed()
|
||||||
);
|
);
|
||||||
ControlFlow::Break
|
ControlFlow::Break
|
||||||
|
@ -787,11 +800,10 @@ fn handle_key_press<T: Clone + 'static + Send>(
|
||||||
custom_keys: Option<&Vec<KeyBinding>>,
|
custom_keys: Option<&Vec<KeyBinding>>,
|
||||||
) -> Propagation {
|
) -> Propagation {
|
||||||
let update_view = |query: &String| {
|
let update_view = |query: &String| {
|
||||||
let mut lock = ui.menu_rows.lock().unwrap();
|
let mut lock = ui.menu_rows.write().unwrap();
|
||||||
let menus = &mut *lock;
|
|
||||||
set_menu_visibility_for_search(
|
set_menu_visibility_for_search(
|
||||||
query,
|
query,
|
||||||
menus,
|
&mut lock,
|
||||||
&meta.config,
|
&meta.config,
|
||||||
meta.search_ignored_words.as_ref(),
|
meta.search_ignored_words.as_ref(),
|
||||||
);
|
);
|
||||||
|
@ -865,7 +877,7 @@ fn handle_key_press<T: Clone + 'static + Send>(
|
||||||
expander.set_expanded(true);
|
expander.set_expanded(true);
|
||||||
} else {
|
} else {
|
||||||
let opt_changed = {
|
let opt_changed = {
|
||||||
let lock = ui.menu_rows.lock().unwrap();
|
let lock = ui.menu_rows.read().unwrap();
|
||||||
let menu_item = lock.get(fb);
|
let menu_item = lock.get(fb);
|
||||||
menu_item.map(|menu_item| {
|
menu_item.map(|menu_item| {
|
||||||
(
|
(
|
||||||
|
@ -904,12 +916,12 @@ fn handle_key_press<T: Clone + 'static + Send>(
|
||||||
Propagation::Proceed
|
Propagation::Proceed
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sort_menu_items_by_score<T: Clone>(
|
fn sort_flow_box_childs<T: Clone>(
|
||||||
child1: &FlowBoxChild,
|
child1: &FlowBoxChild,
|
||||||
child2: &FlowBoxChild,
|
child2: &FlowBoxChild,
|
||||||
items_lock: &ArcMenuMap<T>,
|
items_lock: &ArcMenuMap<T>,
|
||||||
) -> Ordering {
|
) -> Ordering {
|
||||||
let lock = items_lock.lock().unwrap();
|
let lock = items_lock.read().unwrap();
|
||||||
let m1 = lock.get(child1);
|
let m1 = lock.get(child1);
|
||||||
let m2 = lock.get(child2);
|
let m2 = lock.get(child2);
|
||||||
|
|
||||||
|
@ -920,6 +932,10 @@ fn sort_menu_items_by_score<T: Clone>(
|
||||||
return Ordering::Larger;
|
return Ordering::Larger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sort_menu_items_by_score(m1, m2)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sort_menu_items_by_score<T: Clone>(m1: Option<&MenuItem<T>>, m2: Option<&MenuItem<T>>) -> Ordering {
|
||||||
match (m1, m2) {
|
match (m1, m2) {
|
||||||
(Some(menu1), Some(menu2)) => {
|
(Some(menu1), Some(menu2)) => {
|
||||||
fn compare(a: f64, b: f64) -> Ordering {
|
fn compare(a: f64, b: f64) -> Ordering {
|
||||||
|
@ -988,7 +1004,7 @@ where
|
||||||
send_selected_item(ui, meta, custom_key.cloned(), selected_item);
|
send_selected_item(ui, meta, custom_key.cloned(), selected_item);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
} else if let Some(s) = ui.main_box.selected_children().into_iter().next() {
|
} else if let Some(s) = ui.main_box.selected_children().into_iter().next() {
|
||||||
let list_items = ui.menu_rows.lock().unwrap();
|
let list_items = ui.menu_rows.read().unwrap();
|
||||||
let item = list_items.get(&s);
|
let item = list_items.get(&s);
|
||||||
if let Some(selected_item) = item {
|
if let Some(selected_item) = item {
|
||||||
if selected_item.visible {
|
if selected_item.visible {
|
||||||
|
@ -1359,6 +1375,8 @@ pub fn apply_sort<T: Clone>(items: &mut [MenuItem<T>], order: &SortOrder) {
|
||||||
item.initial_sort_score += special_score;
|
item.initial_sort_score += special_score;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
items.sort_by(|l, r| into_core_order(&sort_menu_items_by_score(Some(l), Some(r))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue