forked from pop-os/cosmic-files
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontroller.rs
More file actions
112 lines (94 loc) · 2.64 KB
/
Copy pathcontroller.rs
File metadata and controls
112 lines (94 loc) · 2.64 KB
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use std::sync::{Arc, Mutex};
use tokio::sync::Notify;
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum ControllerState {
Cancelled,
Failed,
Paused,
Running,
}
#[derive(Debug)]
struct ControllerInner {
state: Mutex<ControllerState>,
progress: Mutex<f32>,
notify: Notify,
}
#[derive(Debug)]
pub struct Controller {
primary: bool,
inner: Arc<ControllerInner>,
}
impl Default for Controller {
fn default() -> Self {
Self {
primary: true,
inner: Arc::new(ControllerInner {
state: Mutex::new(ControllerState::Running),
progress: Mutex::new(0.0),
notify: Notify::new(),
}),
}
}
}
impl Controller {
pub async fn check(&self) -> Result<(), ControllerState> {
loop {
match self.state() {
ControllerState::Cancelled => return Err(ControllerState::Cancelled),
ControllerState::Failed => return Err(ControllerState::Failed),
ControllerState::Paused => (),
ControllerState::Running => return Ok(()),
}
self.inner.notify.notified().await;
}
}
pub fn progress(&self) -> f32 {
*self.inner.progress.lock().unwrap()
}
pub fn set_progress(&self, progress: f32) {
*self.inner.progress.lock().unwrap() = progress;
}
pub fn state(&self) -> ControllerState {
*self.inner.state.lock().unwrap()
}
pub fn set_state(&self, state: ControllerState) {
*self.inner.state.lock().unwrap() = state;
self.inner.notify.notify_waiters();
}
pub fn is_cancelled(&self) -> bool {
matches!(self.state(), ControllerState::Cancelled)
}
pub fn cancel(&self) {
self.set_state(ControllerState::Cancelled);
}
pub fn is_failed(&self) -> bool {
matches!(self.state(), ControllerState::Failed)
}
pub fn is_paused(&self) -> bool {
matches!(self.state(), ControllerState::Paused)
}
pub fn pause(&self) {
self.set_state(ControllerState::Paused);
}
pub fn unpause(&self) {
if !self.is_cancelled() | !self.is_failed() {
self.set_state(ControllerState::Running);
}
}
}
impl Clone for Controller {
fn clone(&self) -> Self {
Self {
primary: false,
inner: self.inner.clone(),
}
}
}
impl Drop for Controller {
fn drop(&mut self) {
// Cancel operations if primary controller is dropped and controller is still running
if self.primary && self.state() != ControllerState::Failed {
self.cancel();
}
}
}