yazi_scheduler/
ongoing.rs1use 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}