xref: /DragonReach/src/manager/timer_manager/mod.rs (revision 909e4d102ffeb8646e7346c10b007cb0861226a4)
1 use crate::{error::runtime_error::RuntimeError, time::timer::Timer};
2 use lazy_static::lazy_static;
3 use std::{boxed::Box, sync::RwLock, time::Duration, vec::Vec};
4 
5 lazy_static! {
6     // 管理全局计时器任务
7     static ref TIMER_TASK_MANAGER: RwLock<TimerManager> = RwLock::new(TimerManager {
8         inner_timers: Vec::new()
9     });
10 }
11 
12 pub struct TimerManager {
13     inner_timers: Vec<Timer>,
14 }
15 
16 impl<'a> IntoIterator for &'a mut TimerManager {
17     type Item = &'a mut Timer;
18 
19     type IntoIter = std::slice::IterMut<'a, Timer>;
20 
21     fn into_iter(self) -> Self::IntoIter {
22         self.inner_timers.iter_mut()
23     }
24 }
25 
26 impl TimerManager {
27     /// ## 添加定时器任务
28     ///
29     /// 只有通过这个方式创建的Timer对象才会真正的实现计时
30     pub fn push_timer<F>(duration: Duration, callback: F, parent: usize)
31     where
32         F: FnMut() -> Result<(), RuntimeError> + Send + Sync + 'static,
33     {
34         TIMER_TASK_MANAGER
35             .write()
36             .unwrap()
37             .inner_timers
38             .push(Timer::new(duration, Box::new(callback), parent));
39     }
40 
41     /// ## 检测定时器是否到时,到时则触发
42     ///
43     /// 该方法在主循环中每循环一次检测一次,是伪计时器的主运行函数
44     pub fn check_timer() {
45         let mut writer = TIMER_TASK_MANAGER.write().unwrap();
46         //此处触发定时器,若定时器被触发,则移除
47         writer.inner_timers.retain_mut(|x| !x.check());
48     }
49 
50     /// ## 取消掉一个unit的所有定时任务,
51     ///
52     /// 一般在unit启动失败或者退出unit时进行该操作
53     pub fn cancel_timer(unit_id: usize) {
54         TIMER_TASK_MANAGER
55             .write()
56             .unwrap()
57             .inner_timers
58             .retain(|x| x.parent() == unit_id)
59     }
60 }
61