1use std::sync::mpsc::{Receiver, SendError, Sender, channel};
2use supreme_fs::SnapshotEvent;
3
4#[derive(Debug, Clone)]
5pub enum TaskEvent<T> {
6 Log(String),
7 SetStatus(String),
8 InitProgress(usize),
9 IncrementProgress,
10 UpdateProgress(usize),
11 Perf(String, String, u128), PageData(T), Finished(Result<T, String>),
14}
15
16impl<T> TaskEvent<T> {
17 pub fn map<U, F>(self, page_data_transform: F) -> TaskEvent<U>
18 where
19 F: FnOnce(T) -> U,
20 {
21 match self {
22 TaskEvent::Log(msg) => TaskEvent::Log(msg),
23 TaskEvent::SetStatus(msg) => TaskEvent::SetStatus(msg),
24 TaskEvent::InitProgress(total) => TaskEvent::InitProgress(total),
25 TaskEvent::IncrementProgress => TaskEvent::IncrementProgress,
26 TaskEvent::UpdateProgress(p) => TaskEvent::UpdateProgress(p),
27 TaskEvent::Perf(op, target, ms) => TaskEvent::Perf(op, target, ms),
28 TaskEvent::PageData(data) => TaskEvent::PageData(page_data_transform(data)),
29 TaskEvent::Finished(res) => TaskEvent::Finished(res.map(page_data_transform)),
30 }
31 }
32}
33
34pub struct TaskSender<T> {
37 tx: Sender<TaskEvent<T>>,
38 ctx: eframe::egui::Context,
39}
40
41impl<T> Clone for TaskSender<T> {
43 fn clone(&self) -> Self {
44 Self {
45 tx: self.tx.clone(),
46 ctx: self.ctx.clone(),
47 }
48 }
49}
50
51impl<T> TaskSender<T> {
52 pub fn send(&self, event: TaskEvent<T>) -> Result<(), SendError<TaskEvent<T>>> {
53 let res = self.tx.send(event);
54 self.ctx.request_repaint();
55 res
56 }
57}
58
59pub struct TaskHandle<T> {
60 pub receiver: Receiver<TaskEvent<T>>,
61}
62
63impl<T> TaskHandle<T> {
64 pub fn try_recv(&self) -> Result<TaskEvent<T>, std::sync::mpsc::TryRecvError> {
65 self.receiver.try_recv()
66 }
67}
68
69pub fn spawn_task<T, F>(ctx: eframe::egui::Context, f: F) -> TaskHandle<T>
70where
71 T: Send + 'static,
72 F: FnOnce(TaskSender<T>) -> Result<T, String> + Send + 'static,
73{
74 let (tx, rx) = channel();
75 let task_sender = TaskSender { tx, ctx };
76
77 let task_sender_clone = task_sender.clone();
79
80 std::thread::Builder::new()
81 .name("launcher-task".to_string())
82 .spawn(move || {
83 let res = f(task_sender);
84 let _ = task_sender_clone.send(TaskEvent::Finished(res));
85 })
86 .expect("Failed to spawn OS thread for launcher task");
87 TaskHandle { receiver: rx }
88}
89
90impl From<SnapshotEvent> for TaskEvent<()> {
92 fn from(event: SnapshotEvent) -> Self {
93 match event {
94 SnapshotEvent::Log(msg) => TaskEvent::Log(msg),
95 SnapshotEvent::SetStatus(msg) => TaskEvent::SetStatus(msg),
96 SnapshotEvent::InitProgress(total) => TaskEvent::InitProgress(total),
97 SnapshotEvent::IncrementProgress => TaskEvent::IncrementProgress,
98 SnapshotEvent::Perf(op, target, ms) => TaskEvent::Perf(op, target, ms),
99 }
100 }
101}
102
103impl From<supreme_cleaner::CleanerEvent> for TaskEvent<()> {
105 fn from(event: supreme_cleaner::CleanerEvent) -> Self {
106 match event {
107 supreme_cleaner::CleanerEvent::Log(msg) => TaskEvent::Log(msg),
108 supreme_cleaner::CleanerEvent::SetStatus(msg) => TaskEvent::SetStatus(msg),
109 supreme_cleaner::CleanerEvent::InitProgress(total) => TaskEvent::InitProgress(total),
110 supreme_cleaner::CleanerEvent::IncrementProgress => TaskEvent::IncrementProgress,
111 supreme_cleaner::CleanerEvent::Perf(op, target, ms) => TaskEvent::Perf(op, target, ms),
112 }
113 }
114}
115
116#[cfg(feature = "local")]
118impl From<supreme_diagnostics::DiagnosticsEvent> for TaskEvent<()> {
119 fn from(event: supreme_diagnostics::DiagnosticsEvent) -> Self {
120 match event {
121 supreme_diagnostics::DiagnosticsEvent::Log(msg) => TaskEvent::Log(msg),
122 supreme_diagnostics::DiagnosticsEvent::SetStatus(msg) => TaskEvent::SetStatus(msg),
123 supreme_diagnostics::DiagnosticsEvent::InitProgress(total) => {
124 TaskEvent::InitProgress(total)
125 }
126 supreme_diagnostics::DiagnosticsEvent::IncrementProgress => {
127 TaskEvent::IncrementProgress
128 }
129 supreme_diagnostics::DiagnosticsEvent::Perf(op, target, ms) => {
130 TaskEvent::Perf(op, target, ms)
131 }
132 supreme_diagnostics::DiagnosticsEvent::Finished(_) => {
133 TaskEvent::Log("Scanning finished".to_string())
135 }
136 }
137 }
138}
139
140impl From<supreme_dependencies::DependencyEvent> for TaskEvent<()> {
142 fn from(event: supreme_dependencies::DependencyEvent) -> Self {
143 match event {
144 supreme_dependencies::DependencyEvent::Log(msg) => TaskEvent::Log(msg),
145 supreme_dependencies::DependencyEvent::SetStatus(msg) => TaskEvent::SetStatus(msg),
146 supreme_dependencies::DependencyEvent::InitProgress(total) => {
147 TaskEvent::InitProgress(total)
148 }
149 supreme_dependencies::DependencyEvent::UpdateProgress(p) => {
150 TaskEvent::UpdateProgress(p)
151 }
152 supreme_dependencies::DependencyEvent::Finished(err) => {
153 TaskEvent::Finished(err.map_or(Ok(()), Err))
154 }
155 }
156 }
157}