input: Remove all_mappings_cache

Replace it with a chained iterator.

This not only simplifies the code, but also removes a RefCell.
This commit is contained in:
Fabian Boehm 2024-05-14 16:10:33 +02:00
parent e7f13ac329
commit 403920e9d6

View file

@ -16,14 +16,13 @@ use crate::signal::signal_clear_cancel;
use crate::threads::assert_is_main_thread; use crate::threads::assert_is_main_thread;
use crate::wchar::prelude::*; use crate::wchar::prelude::*;
use once_cell::sync::{Lazy, OnceCell}; use once_cell::sync::{Lazy, OnceCell};
use std::cell::RefCell;
use std::collections::VecDeque; use std::collections::VecDeque;
use std::ffi::CString; use std::ffi::CString;
use std::os::fd::RawFd; use std::os::fd::RawFd;
use std::rc::Rc; use std::rc::Rc;
use std::sync::{ use std::sync::{
atomic::{AtomicU32, Ordering}, atomic::{AtomicU32, Ordering},
Arc, Mutex, MutexGuard, Mutex, MutexGuard,
}; };
pub const FISH_BIND_MODE_VAR: &wstr = L!("fish_bind_mode"); pub const FISH_BIND_MODE_VAR: &wstr = L!("fish_bind_mode");
@ -241,7 +240,6 @@ pub fn describe_char(c: i32) -> WString {
pub struct InputMappingSet { pub struct InputMappingSet {
mapping_list: Vec<InputMapping>, mapping_list: Vec<InputMapping>,
preset_mapping_list: Vec<InputMapping>, preset_mapping_list: Vec<InputMapping>,
all_mappings_cache: RefCell<Option<Arc<Box<[InputMapping]>>>>,
} }
/// Access the singleton input mapping set. /// Access the singleton input mapping set.
@ -295,9 +293,6 @@ impl InputMappingSet {
sets_mode: Option<WString>, sets_mode: Option<WString>,
user: bool, user: bool,
) { ) {
// Clear cached mappings.
self.all_mappings_cache = RefCell::new(None);
// Update any existing mapping with this sequence. // Update any existing mapping with this sequence.
// FIXME: this makes adding multiple bindings quadratic. // FIXME: this makes adding multiple bindings quadratic.
let ml = if user { let ml = if user {
@ -809,8 +804,9 @@ impl Inputter {
let bind_mode = input_get_bind_mode(vars); let bind_mode = input_get_bind_mode(vars);
let mut escape: Option<&InputMapping> = None; let mut escape: Option<&InputMapping> = None;
let ml = input_mappings().all_mappings(); let ip = input_mappings();
for m in ml.iter() { let ml = ip.mapping_list.iter().chain(ip.preset_mapping_list.iter());
for m in ml {
if m.mode != bind_mode { if m.mode != bind_mode {
continue; continue;
} }
@ -1004,9 +1000,6 @@ impl InputMappingSet {
/// Erase all bindings. /// Erase all bindings.
pub fn clear(&mut self, mode: Option<&wstr>, user: bool) { pub fn clear(&mut self, mode: Option<&wstr>, user: bool) {
// Clear cached mappings.
self.all_mappings_cache = RefCell::new(None);
let ml = if user { let ml = if user {
&mut self.mapping_list &mut self.mapping_list
} else { } else {
@ -1018,9 +1011,6 @@ impl InputMappingSet {
/// Erase binding for specified key sequence. /// Erase binding for specified key sequence.
pub fn erase(&mut self, sequence: &[Key], mode: &wstr, user: bool) -> bool { pub fn erase(&mut self, sequence: &[Key], mode: &wstr, user: bool) -> bool {
// Clear cached mappings.
self.all_mappings_cache = RefCell::new(None);
let ml = if user { let ml = if user {
&mut self.mapping_list &mut self.mapping_list
} else { } else {
@ -1063,20 +1053,6 @@ impl InputMappingSet {
} }
false false
} }
/// Return a snapshot of the list of input mappings.
fn all_mappings(&self) -> Arc<Box<[InputMapping]>> {
// Populate the cache if needed.
let mut cache = self.all_mappings_cache.borrow_mut();
if cache.is_none() {
let mut all_mappings =
Vec::with_capacity(self.mapping_list.len() + self.preset_mapping_list.len());
all_mappings.extend(self.mapping_list.iter().cloned());
all_mappings.extend(self.preset_mapping_list.iter().cloned());
*cache = Some(Arc::new(all_mappings.into_boxed_slice()));
}
Arc::clone(cache.as_ref().unwrap())
}
} }
/// Create a list of terminfo mappings. /// Create a list of terminfo mappings.