1use crate::timer::{Timer, TimerEvent, TimerType};
2use flume;
3use std::collections::HashMap;
4use std::sync::Arc;
5use std::sync::Mutex;
6use std::time::Duration;
7use tokio::task;
8
9#[derive(Clone)]
10pub struct Config {
11 pub work_duration: Duration,
12 pub break_duration: Duration,
13 pub long_break_duration: Duration,
14 pub long_break_interval: u64,
15 pub auto: bool,
16}
17
18pub struct Controller {
19 timer: Arc<Mutex<Timer>>,
20 tx: flume::Sender<String>,
21 rx: flume::Receiver<String>,
22 config: Config,
23 event_handlers: HashMap<TimerEvent, Vec<Arc<dyn Fn(&Timer) + Send + Sync>>>,
24 num_finished_timers: u64,
25}
26
27impl Controller {
28 pub fn new(config: Config) -> Arc<Mutex<Controller>> {
29 let (tx, rx) = flume::unbounded();
30
31 let Config { work_duration, .. } = config;
32
33 let timer = Controller::create_timer(tx.clone(), TimerType::Work, work_duration);
34
35 Arc::new(Mutex::new(Controller {
36 config,
37 timer,
38 tx,
39 rx,
40 event_handlers: HashMap::new(),
41 num_finished_timers: 0,
42 }))
43 }
44
45 fn create_timer(
46 tx: flume::Sender<String>,
47 timer_type: TimerType,
48 duration: Duration,
49 ) -> Arc<Mutex<Timer>> {
50 let timer = Timer::new(timer_type, &duration.clone());
52
53 let mut timer_guard = timer.lock().expect("Failed to lock timer");
54
55 timer_guard.on(
57 TimerEvent::Finish,
58 Arc::new(move |_: &Timer| {
59 tx.send("timer_finished".to_string())
60 .expect("Failed to send timer finished message");
61 }),
62 );
63
64 drop(timer_guard);
65
66 timer
67 }
68
69 fn attach_timer_handlers(&self) {
70 let mut timer = self.timer.lock().expect("Failed to lock timer");
71
72 for (event, handlers) in &self.event_handlers {
74 for handler in handlers {
75 timer.on(*event, handler.clone());
76 }
77 }
78 }
79
80 pub fn start(controller: &Arc<Mutex<Self>>) {
81 let controller = Arc::clone(controller);
82
83 let mut controller_guard_1 = controller.lock().expect("Failed to lock controller");
84 let rx = controller_guard_1.rx.clone();
85
86 controller_guard_1.start_current_timer();
87 drop(controller_guard_1);
88
89 task::spawn(async move {
90 loop {
91 let msg = rx
92 .recv_async()
93 .await
94 .expect("Failed to listen to socket messages");
95
96 let mut controller_guard_2 = controller.lock().expect("Failed to lock controller");
97
98 match msg.as_str() {
99 "timer_finished" => {
100 controller_guard_2.on_timer_finished();
101 }
102 "skip" => {
103 controller_guard_2.start_next_timer();
104 }
105 _ => {}
106 }
107
108 drop(controller_guard_2);
109 }
110 });
111 }
112
113 pub fn next(controller: &Arc<Mutex<Self>>) {
115 let mut controller = controller.lock().expect("Failed to lock controller");
116 controller.start_next_timer();
117 }
118
119 pub fn stop(controller: &Arc<Mutex<Self>>) {
120 let mut controller = controller.lock().expect("Failed to lock controller");
121 controller.stop_current_timer();
122 }
123
124 pub fn pause(controller: &Arc<Mutex<Self>>) {
125 let mut controller = controller.lock().expect("Failed to lock controller");
126 controller.pause_current_timer();
127 }
128
129 fn start_current_timer(&mut self) {
130 Timer::start(&self.timer);
131 }
132
133 fn stop_current_timer(&mut self) {
134 let mut timer = self.timer.lock().expect("Failed to lock timer");
135 timer.stop();
136 }
137
138 fn pause_current_timer(&mut self) {
139 let mut timer = self.timer.lock().expect("Failed to lock timer");
140 timer.pause();
141 }
142
143 fn start_next_timer(&mut self) {
144 self.num_finished_timers += 1;
145
146 self.stop_current_timer();
147
148 let current_timer = self.timer.lock().expect("Failed to lock timer");
149
150 let new_timer = match current_timer.timer_type() {
151 TimerType::Work => {
152 let mut duration = self.config.break_duration.clone();
153
154 let num_finished_break_timers = self.num_finished_timers / 2;
155
156 if num_finished_break_timers != 0
157 && num_finished_break_timers % (self.config.long_break_interval - 1) == 0
158 {
159 duration = self.config.long_break_duration.clone();
160 }
161
162 Controller::create_timer(self.tx.clone(), TimerType::Break, duration)
163 }
164 TimerType::Break => Controller::create_timer(
165 self.tx.clone(),
166 TimerType::Work,
167 self.config.work_duration.clone(),
168 ),
169 };
170
171 drop(current_timer);
172
173 self.timer = new_timer;
174
175 self.attach_timer_handlers();
176
177 self.start_current_timer();
178 }
179
180 fn on_timer_finished(&mut self) {
181 if self.config.auto {
183 self.start_next_timer();
184 return;
185 }
186 }
187
188 pub fn get_current_timer(controller: &Arc<Mutex<Self>>) -> Arc<Mutex<Timer>> {
189 let controller = Arc::clone(controller);
190
191 let controller = controller.lock().expect("Failed to lock controller");
192 let timer = Arc::clone(&controller.timer);
193 timer
195 }
196
197 pub fn on(
198 controller: &Arc<Mutex<Self>>,
199 event: TimerEvent,
200 callback: Arc<dyn Fn(&Timer) + Send + Sync>,
201 ) {
202 let mut controller = controller.lock().expect("Failed to lock controller");
203
204 controller
206 .event_handlers
207 .entry(event)
208 .or_default()
209 .push(callback.clone());
210
211 let mut timer = controller.timer.lock().expect("Failed to lock timer");
213
214 timer.on(event, callback);
216 }
217}