xref: /DragonReach/src/manager/timer_manager/mod.rs (revision e945c217b313a00a228c454741360ee9a74397d2)
1 use std::{
2     sync::{Arc, Mutex, RwLock},
3     time::Duration,
4 };
5 
6 use crate::{
7     error::runtime_error::RuntimeError, time::timer::Timer, unit::timer::TimerUnit, unit::Unit,
8 };
9 use hashbrown::HashMap;
10 use lazy_static::lazy_static;
11 lazy_static! {
12     // 管理全局计时器任务
13     static ref TIMER_TASK_MANAGER:RwLock<TimerManager> = RwLock::new(TimerManager {
14         inner_timers: Vec::new(),
15         timer_unit_map: RwLock::new(HashMap::new()),
16 
17         id_table:RwLock::new(Vec::new())
18     });
19 }
20 
21 pub struct TimerManager {
22     inner_timers: Vec<Timer>,
23     timer_unit_map: RwLock<HashMap<usize, Arc<Mutex<TimerUnit>>>>, //id->TimerUnit
24     id_table: RwLock<Vec<(usize, usize)>>, //.0是TimerUnit的id,.1是父Unit的id
25 }
26 
27 impl<'a> IntoIterator for &'a mut TimerManager {
28     type Item = &'a mut Timer;
29 
30     type IntoIter = std::slice::IterMut<'a, Timer>;
31 
32     fn into_iter(self) -> Self::IntoIter {
33         self.inner_timers.iter_mut()
34     }
35 }
36 
37 impl TimerManager {
38     /// ## 添加定时器任务
39     ///
40     /// 只有通过两这个方式载入的Timer或Timer_unit对象才会真正的实现计时
41     pub fn push_timer<F>(duration: Duration, callback: F, parent: usize)
42     where
43         F: FnMut() -> Result<(), RuntimeError> + Send + Sync + 'static,
44     {
45         TIMER_TASK_MANAGER
46             .write()
47             .unwrap()
48             .inner_timers
49             .push(Timer::new(duration, Box::new(callback), parent));
50     }
51 
52     pub fn push_timer_unit(unit: Arc<Mutex<TimerUnit>>) {
53         let timemanager = TIMER_TASK_MANAGER.write().unwrap();
54         let mut unit_guard = unit.lock().unwrap();
55         let unit_id = unit_guard.unit_id();
56         timemanager
57             .id_table
58             .write()
59             .unwrap()
60             .push((unit_id, unit_guard.get_parent_unit()));
61         drop(unit_guard);
62         timemanager
63             .timer_unit_map
64             .write()
65             .unwrap()
66             .insert(unit_id, unit); //加入到inner_timers_map
67     }
68 
69     /// ## 检测定时器是否到时,到时则触发
70     ///
71     /// 该方法在主循环中每循环一次检测一次,是伪计时器的主运行函数
72     pub fn check_timer() {
73         let mut writer = TIMER_TASK_MANAGER.write().unwrap();
74         //此处触发定时器,若定时器被触发,则移除
75         writer.inner_timers.retain_mut(|x| !x.check());
76         drop(writer);
77         //此处触发Timer_unit,不移除
78         let reader = TIMER_TASK_MANAGER.read().unwrap();
79         let timer_unit_map = reader.timer_unit_map.read().unwrap();
80         let mut inactive_unit: Vec<usize> = Vec::new();
81         for (_, timer_unit) in timer_unit_map.iter() {
82             let mut unit_guard = timer_unit.lock().unwrap();
83             if unit_guard.enter_inactive() {
84                 inactive_unit.push(unit_guard.unit_id());
85                 continue;
86             }
87             if unit_guard.check() {
88                 //println!("unit id : {} , parent id : {} ",timer_unit.unit_id(),timer_unit.get_parent_unit());
89                 let _ = unit_guard._run(); //运行作出相应操作
90                 let id = unit_guard.get_parent_unit();
91                 drop(unit_guard);
92                 TimerManager::update_next_trigger(id, true); //更新触发时间
93             }
94         }
95 
96         for id in inactive_unit {
97             //处理Inactive需要退出的计时器
98             //println!("Prepared to exit...");
99             timer_unit_map.get(&id).unwrap().lock().unwrap().exit();
100 
101             TimerManager::remove_timer_unit(id);
102         }
103     }
104 
105     /// ## 取消掉一个unit的所有定时任务,
106     ///
107     /// 一般在unit启动失败或者退出unit时进行该操作
108     pub fn cancel_timer(unit_id: usize) {
109         TIMER_TASK_MANAGER
110             .write()
111             .unwrap()
112             .inner_timers
113             .retain(|x| x.parent() == unit_id)
114     }
115 
116     pub fn is_timer(id: &usize) -> bool {
117         let id_table = &TIMER_TASK_MANAGER.read().unwrap().id_table;
118         for iter in id_table.read().unwrap().iter() {
119             if iter.0 == *id {
120                 return true;
121             }
122         }
123         false
124     }
125     /// unit_id:父unit的id  flag:1为exec 0为exit
126     fn adjust_timevalue(unit_id: &usize, flag: bool /*1为启动0为退出 */) -> Vec<usize> {
127         let mut result = Vec::new();
128         let manager = TIMER_TASK_MANAGER.read().unwrap();
129         for (self_id, parent_id) in manager.id_table.read().unwrap().iter() {
130             if unit_id == parent_id {
131                 let timer_unit_map = manager.timer_unit_map.read().unwrap();
132                 let mut timer_unit = timer_unit_map.get(self_id).unwrap().lock().unwrap();
133                 timer_unit.change_stage(flag);
134                 result.push(*self_id);
135             }
136         }
137         result
138     }
139 
140     /// 从Timer表中删除该Unit
141     pub fn remove_timer_unit(unit_id: usize) {
142         let manager = TIMER_TASK_MANAGER.read().unwrap();
143 
144         manager.timer_unit_map.write().unwrap().remove(&unit_id);
145         let mut index: usize = 0;
146         let mut id_table = manager.id_table.write().unwrap();
147         for (self_id, _) in id_table.iter() {
148             //因为id是递增的,后续可优化为二分查找
149             if unit_id == *self_id {
150                 id_table.remove(index);
151                 println!("remove id:{}", unit_id);
152                 return;
153             }
154             index = index + 1
155         }
156     }
157 
158     /// 获得该id下的所有计时器
159     pub fn get_timer(parent_id: usize) -> Vec<usize> {
160         let mut result = Vec::new();
161         let timer_manager = TIMER_TASK_MANAGER.read().unwrap();
162         let reader = timer_manager.id_table.read().unwrap();
163         for (timer_id, id) in reader.iter() {
164             if *id == parent_id {
165                 result.push(*timer_id);
166             }
167         }
168         result
169     }
170     ///此时传入的是parent_id
171     pub fn update_next_trigger(unit_id: usize, flag: bool) {
172         let timer_vec = Self::adjust_timevalue(&unit_id, flag);
173 
174         let timer_manager = TIMER_TASK_MANAGER.read().unwrap();
175         let timer_unit_map = timer_manager.timer_unit_map.read().unwrap();
176         timer_vec.iter().for_each(|id| {
177             timer_unit_map
178                 .get(id)
179                 .unwrap()
180                 .lock()
181                 .unwrap()
182                 .mut_timer_part()
183                 .update_next_trigger();
184         });
185     }
186 }
187