pi_local_timer/
local_timer.rs1
2use std::{collections::VecDeque, fmt::{Debug, Formatter, Result as FResult}};
3
4use pi_dyn_uint::{UintFactory, ClassFactory, SlabFactory};
5use pi_time::run_millis;
6use crate::frame_wheel::{FrameWheel};
7use crate::item::{TimeoutItem};
8
9pub struct LocalTimer<T, const N1: usize, const N2: usize, const N3: usize, const N4: usize> {
29 pub frame_time: u64,
31 pub start_time: u64,
33 pub roll_time: u64,
35 pub index_factory: SlabFactory<usize,()>,
37 pub frame_wheel: FrameWheel<T, N1, N2, N3, N4>
39}
40
41impl<T, const N1: usize, const N2: usize, const N3: usize, const N4: usize> LocalTimer<T, N1, N2, N3, N4>{
42
43 pub fn new(frame_time: u64, now: u64) -> Self{
53 LocalTimer {
54 frame_time,
55 start_time: now,
56 roll_time: 0,
57 index_factory: SlabFactory::new(),
58 frame_wheel: FrameWheel::new()
59 }
60 }
61
62 #[inline]
63 pub fn check_sleep(&self, now: u64) -> u64 {
66 let curr = self.start_time + self.roll_time;
67 if curr > now {
68 return curr - now;
69 }
70 else {
71 return 0;
72 }
73 }
74
75 pub fn len(&self) -> usize {
77 self.frame_wheel.len()
78 }
79
80 #[inline]
81 pub fn get_time(&mut self) -> u64{
83 self.roll_time
84 }
85
86 pub fn insert(&mut self, mut data: T, timeout: u64) -> usize{
90 let index = self.index_factory.create(0, 0, ());
91
92 let frame_point = timeout / (self.frame_time as u64) + self.frame_wheel.frame;
94
95 let elem = TimeoutItem::new(data, frame_point);
96
97 self.frame_wheel.insert(elem, index, &mut self.index_factory);
98
99 index
100 }
101
102 pub fn clear(&mut self){
104 self.frame_wheel.clear();
105 self.index_factory.clear();
106 }
107
108 #[inline]
109 pub fn pop(&mut self, now: u64) -> Option<(TimeoutItem<T>, usize)> {
112 if let Some(task) = self.frame_wheel.pop() {
113 self.index_factory.destroy(task.1);
114 return Some(task);
115 }
116 else {
117 if self.check(now) {
119 self.roll_once();
120 }
121 }
122 None
123 }
124
125 pub fn try_remove(&mut self, index: usize) -> Option<TimeoutItem<T>>{
128 match self.index_factory.try_load(index) {
129 Some(i) => {
130 if let Some((elem, _)) = self.frame_wheel.delete(self.index_factory.get_class(index).clone(), i, &mut self.index_factory) {
131 self.index_factory.destroy(index);
132 return Some(elem);
133 }
134
135 None
136 },
137 None => None,
138 }
139 }
140
141 pub fn remove(&mut self, index: usize) -> Option<TimeoutItem<T>> {
144 if let Some((elem, _)) = self.frame_wheel.delete(self.index_factory.get_class(index).clone(), self.index_factory.load(index), &mut self.index_factory) {
145 self.index_factory.destroy(index);
146 return Some(elem);
147 }
148 None
149 }
150
151 #[inline]
152 pub fn check(&self, now: u64) -> bool {
155 return self.check_sleep(now) == 0;
156 }
157
158 #[inline]
159 pub fn roll_once(&mut self) {
161
162 self.roll_time += self.frame_time as u64;
163 self.frame_wheel.roll_once(&mut self.index_factory);
164 }
165
166 pub fn get_item_timeout(&self, item: &TimeoutItem<T>) -> u64 {
167 item.get_frame_point() * self.frame_time
168 }
169}
170
171impl<T: Debug, const N1: usize, const N2: usize, const N3: usize, const N4: usize> Debug for LocalTimer<T, N1, N2, N3, N4> where T: Debug {
172 fn fmt(&self, fmt: &mut Formatter) -> FResult {
173 write!(fmt,
174r##"Wheel(
175 index_factory: {:?},
176 wheel: {:?},
177)"##,
178 self.index_factory,
179 self.frame_wheel
180 )
181 }
182}