yazi_scheduler/
ongoing.rs

1use std::collections::HashMap;
2
3use futures::future::BoxFuture;
4use yazi_config::TASKS;
5
6use super::{Task, TaskStage};
7use crate::TaskKind;
8
9#[derive(Default)]
10pub struct Ongoing {
11	incr: usize,
12
13	pub(super) hooks: HashMap<usize, Box<dyn (FnOnce(bool) -> BoxFuture<'static, ()>) + Send + Sync>>,
14	pub(super) all:   HashMap<usize, Task>,
15}
16
17impl Ongoing {
18	pub fn add(&mut self, kind: TaskKind, name: String) -> usize {
19		self.incr += 1;
20		self.all.insert(self.incr, Task::new(self.incr, kind, name));
21		self.incr
22	}
23
24	#[inline]
25	pub fn get(&self, id: usize) -> Option<&Task> { self.all.get(&id) }
26
27	#[inline]
28	pub fn get_mut(&mut self, id: usize) -> Option<&mut Task> { self.all.get_mut(&id) }
29
30	#[inline]
31	pub fn get_id(&self, idx: usize) -> Option<usize> { self.values().nth(idx).map(|t| t.id) }
32
33	#[inline]
34	pub fn len(&self) -> usize {
35		if TASKS.suppress_preload {
36			self.all.values().filter(|t| t.kind != TaskKind::Preload).count()
37		} else {
38			self.all.len()
39		}
40	}
41
42	#[inline]
43	pub fn exists(&self, id: usize) -> bool { self.all.contains_key(&id) }
44
45	#[inline]
46	pub fn values(&self) -> Box<dyn Iterator<Item = &Task> + '_> {
47		if TASKS.suppress_preload {
48			Box::new(self.all.values().filter(|t| t.kind != TaskKind::Preload))
49		} else {
50			Box::new(self.all.values())
51		}
52	}
53
54	#[inline]
55	pub fn is_empty(&self) -> bool { self.len() == 0 }
56
57	pub fn try_remove(&mut self, id: usize, stage: TaskStage) -> Option<BoxFuture<'static, ()>> {
58		if let Some(task) = self.get_mut(id) {
59			if stage > task.stage {
60				task.stage = stage;
61			}
62
63			match task.stage {
64				TaskStage::Pending => return None,
65				TaskStage::Dispatched => {
66					if task.succ < task.total {
67						return None;
68					}
69					if let Some(hook) = self.hooks.remove(&id) {
70						return Some(hook(false));
71					}
72				}
73				TaskStage::Hooked => {}
74			}
75
76			self.all.remove(&id);
77		}
78		None
79	}
80}