yazi_scheduler/
ongoing.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
use std::collections::HashMap;

use futures::future::BoxFuture;
use yazi_config::TASKS;

use super::{Task, TaskStage};
use crate::TaskKind;

#[derive(Default)]
pub struct Ongoing {
	incr: usize,

	pub(super) hooks: HashMap<usize, Box<dyn (FnOnce(bool) -> BoxFuture<'static, ()>) + Send + Sync>>,
	pub(super) all:   HashMap<usize, Task>,
}

impl Ongoing {
	pub fn add(&mut self, kind: TaskKind, name: String) -> usize {
		self.incr += 1;
		self.all.insert(self.incr, Task::new(self.incr, kind, name));
		self.incr
	}

	#[inline]
	pub fn get(&self, id: usize) -> Option<&Task> { self.all.get(&id) }

	#[inline]
	pub fn get_mut(&mut self, id: usize) -> Option<&mut Task> { self.all.get_mut(&id) }

	#[inline]
	pub fn get_id(&self, idx: usize) -> Option<usize> { self.values().nth(idx).map(|t| t.id) }

	#[inline]
	pub fn len(&self) -> usize {
		if TASKS.suppress_preload {
			self.all.values().filter(|t| t.kind != TaskKind::Preload).count()
		} else {
			self.all.len()
		}
	}

	#[inline]
	pub fn exists(&self, id: usize) -> bool { self.all.contains_key(&id) }

	#[inline]
	pub fn values(&self) -> Box<dyn Iterator<Item = &Task> + '_> {
		if TASKS.suppress_preload {
			Box::new(self.all.values().filter(|t| t.kind != TaskKind::Preload))
		} else {
			Box::new(self.all.values())
		}
	}

	#[inline]
	pub fn is_empty(&self) -> bool { self.len() == 0 }

	pub fn try_remove(&mut self, id: usize, stage: TaskStage) -> Option<BoxFuture<'static, ()>> {
		if let Some(task) = self.get_mut(id) {
			if stage > task.stage {
				task.stage = stage;
			}

			match task.stage {
				TaskStage::Pending => return None,
				TaskStage::Dispatched => {
					if task.succ < task.total {
						return None;
					}
					if let Some(hook) = self.hooks.remove(&id) {
						return Some(hook(false));
					}
				}
				TaskStage::Hooked => {}
			}

			self.all.remove(&id);
		}
		None
	}
}