Replace picker shutdown bool with version number

This works nicely for dynamic pickers: we stop any running jobs like
global search that are pushing to the injector by incrementing the
version number when we start a new request. The boolean only allowed
us to shut the picker down once, but with a usize a picker can have
multiple "sessions" / "life-cycles" where it receives new options
from an injector.
pull/9647/head
Michael Davis 9 months ago
parent 385b398808
commit 53ac833efb
No known key found for this signature in database

@ -34,7 +34,7 @@ use std::{
io::Read, io::Read,
path::{Path, PathBuf}, path::{Path, PathBuf},
sync::{ sync::{
atomic::{self, AtomicBool}, atomic::{self, AtomicUsize},
Arc, Arc,
}, },
}; };
@ -154,7 +154,8 @@ pub struct Injector<T, D> {
dst: nucleo::Injector<T>, dst: nucleo::Injector<T>,
columns: Arc<[Column<T, D>]>, columns: Arc<[Column<T, D>]>,
editor_data: Arc<D>, editor_data: Arc<D>,
shutown: Arc<AtomicBool>, version: usize,
picker_version: Arc<AtomicUsize>,
} }
impl<I, D> Clone for Injector<I, D> { impl<I, D> Clone for Injector<I, D> {
@ -163,7 +164,8 @@ impl<I, D> Clone for Injector<I, D> {
dst: self.dst.clone(), dst: self.dst.clone(),
columns: self.columns.clone(), columns: self.columns.clone(),
editor_data: self.editor_data.clone(), editor_data: self.editor_data.clone(),
shutown: self.shutown.clone(), version: self.version,
picker_version: self.picker_version.clone(),
} }
} }
} }
@ -172,7 +174,7 @@ pub struct InjectorShutdown;
impl<T, D> Injector<T, D> { impl<T, D> Injector<T, D> {
pub fn push(&self, item: T) -> Result<(), InjectorShutdown> { pub fn push(&self, item: T) -> Result<(), InjectorShutdown> {
if self.shutown.load(atomic::Ordering::Relaxed) { if self.version != self.picker_version.load(atomic::Ordering::Relaxed) {
return Err(InjectorShutdown); return Err(InjectorShutdown);
} }
@ -220,7 +222,7 @@ pub struct Picker<T: 'static + Send + Sync, D: 'static> {
columns: Arc<[Column<T, D>]>, columns: Arc<[Column<T, D>]>,
primary_column: usize, primary_column: usize,
editor_data: Arc<D>, editor_data: Arc<D>,
shutdown: Arc<AtomicBool>, version: Arc<AtomicUsize>,
matcher: Nucleo<T>, matcher: Nucleo<T>,
/// Current height of the completions box /// Current height of the completions box
@ -261,7 +263,8 @@ impl<T: 'static + Send + Sync, D: 'static + Send + Sync> Picker<T, D> {
dst: matcher.injector(), dst: matcher.injector(),
columns: columns.into(), columns: columns.into(),
editor_data: Arc::new(editor_data), editor_data: Arc::new(editor_data),
shutown: Arc::new(AtomicBool::new(false)), version: 0,
picker_version: Arc::new(AtomicUsize::new(0)),
}; };
(matcher, streamer) (matcher, streamer)
} }
@ -290,7 +293,7 @@ impl<T: 'static + Send + Sync, D: 'static + Send + Sync> Picker<T, D> {
columns.into(), columns.into(),
primary_column, primary_column,
Arc::new(editor_data), Arc::new(editor_data),
Arc::new(AtomicBool::new(false)), Arc::new(AtomicUsize::new(0)),
callback_fn, callback_fn,
) )
} }
@ -306,7 +309,7 @@ impl<T: 'static + Send + Sync, D: 'static + Send + Sync> Picker<T, D> {
injector.columns, injector.columns,
primary_column, primary_column,
injector.editor_data, injector.editor_data,
injector.shutown, injector.picker_version,
callback_fn, callback_fn,
) )
} }
@ -316,7 +319,7 @@ impl<T: 'static + Send + Sync, D: 'static + Send + Sync> Picker<T, D> {
columns: Arc<[Column<T, D>]>, columns: Arc<[Column<T, D>]>,
default_column: usize, default_column: usize,
editor_data: Arc<D>, editor_data: Arc<D>,
shutdown: Arc<AtomicBool>, version: Arc<AtomicUsize>,
callback_fn: impl Fn(&mut Context, &T, Action) + 'static, callback_fn: impl Fn(&mut Context, &T, Action) + 'static,
) -> Self { ) -> Self {
assert!(!columns.is_empty()); assert!(!columns.is_empty());
@ -340,7 +343,7 @@ impl<T: 'static + Send + Sync, D: 'static + Send + Sync> Picker<T, D> {
primary_column: default_column, primary_column: default_column,
matcher, matcher,
editor_data, editor_data,
shutdown, version,
cursor: 0, cursor: 0,
prompt, prompt,
query, query,
@ -361,7 +364,8 @@ impl<T: 'static + Send + Sync, D: 'static + Send + Sync> Picker<T, D> {
dst: self.matcher.injector(), dst: self.matcher.injector(),
columns: self.columns.clone(), columns: self.columns.clone(),
editor_data: self.editor_data.clone(), editor_data: self.editor_data.clone(),
shutown: self.shutdown.clone(), version: self.version.load(atomic::Ordering::Relaxed),
picker_version: self.version.clone(),
} }
} }
@ -916,7 +920,7 @@ impl<I: 'static + Send + Sync, D: 'static + Send + Sync> Component for Picker<I,
// be restarting the stream somehow once the picker gets // be restarting the stream somehow once the picker gets
// reopened instead (like for an FS crawl) that would also remove the // reopened instead (like for an FS crawl) that would also remove the
// need for the special case above but that is pretty tricky // need for the special case above but that is pretty tricky
picker.shutdown.store(true, atomic::Ordering::Relaxed); picker.version.fetch_add(1, atomic::Ordering::Relaxed);
Box::new(|compositor: &mut Compositor, _ctx| { Box::new(|compositor: &mut Compositor, _ctx| {
// remove the layer // remove the layer
compositor.last_picker = compositor.pop(); compositor.last_picker = compositor.pop();
@ -1002,7 +1006,7 @@ impl<I: 'static + Send + Sync, D: 'static + Send + Sync> Component for Picker<I,
impl<T: 'static + Send + Sync, D> Drop for Picker<T, D> { impl<T: 'static + Send + Sync, D> Drop for Picker<T, D> {
fn drop(&mut self) { fn drop(&mut self) {
// ensure we cancel any ongoing background threads streaming into the picker // ensure we cancel any ongoing background threads streaming into the picker
self.shutdown.store(true, atomic::Ordering::Relaxed) self.version.fetch_add(1, atomic::Ordering::Relaxed);
} }
} }

Loading…
Cancel
Save