use std::rc::{Rc, Weak}; use std::cell::RefCell; use std::any::Any; use std::cmp; /* use proc_macro::TokenStream; use quote::quote; use syn; */ const TVN_BITS: usize = 6; const TVR_BITS: usize = 8; const TVN_SIZE: usize = 1 << TVN_BITS; const TVR_SIZE: usize = 1 << TVR_BITS; const TVN_MASK: usize = TVN_SIZE - 1; const TVR_MASK: usize = TVR_SIZE - 1; pub type TimerAttacherRp = Rc::>; pub type TimerWp = Weak::>>; pub type TimerCb = Box::>>)>; type TimerListListHeadRp = Rc::>>; type TimerListRp = Rc::>; type TimerListWp = Weak::>; pub enum TimerEvent { Exec, Delete, Destory, Custom(i32) } pub struct TimerAttacher { timers: TimerListListHeadRp, } enum TimerType { Timeout, Interval } impl Default for TimerType { fn default() -> Self { return TimerType::Timeout; } } #[derive(Default)] //#[derive(crate::EnableSharedFromSelf)] pub struct TimerList { holder: TimerListRp, wp: Rc::, timer_entry: TimerListListHeadRp, attach_entry: TimerListListHeadRp, timer_type: TimerType, expire_time: i32, expires: i64, cb: Option, } pub struct Timer { free_timer_num: i32, free_timer_list: TimerListListHeadRp, running_timer: TimerListWp, timer_tick: i64, get_tick_count: fn () -> i64, cache_timer_num: i32, work_list: TimerListListHeadRp, tv1: [TimerListListHeadRp; TVR_SIZE], tv2: [TimerListListHeadRp; TVN_SIZE], tv3: [TimerListListHeadRp; TVN_SIZE], tv4: [TimerListListHeadRp; TVN_SIZE], tv5: [TimerListListHeadRp; TVN_SIZE], } impl Timer { pub fn init(mut self, get_tick_count: fn () -> i64, gctime: i32, cache_timer_num: i32) { self.get_tick_count = get_tick_count; self.cache_timer_num = cache_timer_num; self.free_timer_num = 0; self.mut_traverse_timer_list( &mut |timer_list: &mut TimerListListHeadRp| { *timer_list = crate::ListHead::::new_head(); }); self.timer_tick = (self.get_tick_count)(); { let self_wp = self.shared_from_self(); let cb = Box::new( move |event: TimerEvent, args: Option>>| { self_wp.borrow_mut().gc_timer(event, args); } ); self.set_interval(gctime, cb); } } fn traverse_timer_list(&self, cb: &mut dyn FnMut (&TimerListListHeadRp)) { (*cb)(&self.work_list); let mut for_each_cb = |tv: &[TimerListListHeadRp]| { for i in 0..tv.len() { (*cb)(&tv[i]); } }; for_each_cb(&self.tv1); for_each_cb(&self.tv2); for_each_cb(&self.tv3); for_each_cb(&self.tv4); for_each_cb(&self.tv5); } fn mut_traverse_timer_list(&mut self, cb: &mut dyn FnMut (&mut TimerListListHeadRp)) { (*cb)(&mut self.work_list); let mut for_each_cb = |tv: &mut [TimerListListHeadRp]| { for i in 0..tv.len() { (*cb)(&mut tv[i]); } }; for_each_cb(&mut self.tv1); for_each_cb(&mut self.tv2); for_each_cb(&mut self.tv3); for_each_cb(&mut self.tv4); for_each_cb(&mut self.tv5); } fn shared_from_self(&self) -> Rc::> { //let cell_rc: &Rc = &self ; //let head: &ListHead = &*cell_rc.borrow(); let cell_start = 0 as *const u8; //let data_start = head as *const ListHead as *const u8; //let cell_offset = unsafe { data_start.offset_from(cell_start) }; unsafe { return Rc::from_raw(cell_start as *const RefCell::); }; } pub fn uninit(&mut self) { self.clear(); } fn clear(&mut self) { let free_timer = |head: &TimerListListHeadRp| { while !head.borrow().empty() { let timer = &head.borrow().first_entry().upgrade().unwrap(); self.detach_timer(timer); if timer.borrow().attach_entry.borrow().empty() { timer.borrow().attach_entry.borrow_mut().del_init(); } } }; self.traverse_timer_list( &mut |timer_list: &TimerListListHeadRp| { free_timer(timer_list); }); } fn new_timer_list(&mut self) -> Rc::> { let p: Rc::>; if self.free_timer_list.borrow().empty() { p = self.free_timer_list.borrow().first_entry().upgrade().unwrap(); if Rc::weak_count(&p.borrow().wp) > 0 { p.borrow_mut().wp = Rc::new(p.borrow().holder.clone()); } } else { p = Rc::new(RefCell::new(TimerList{ holder: Default::default(), wp: Default::default(), timer_entry: Default::default(), attach_entry: Default::default(), timer_type: TimerType::Timeout, expire_time: 0, expires: 0, cb: None, })); p.borrow_mut().holder = p.clone(); p.borrow_mut().wp = Rc::new(p.borrow().holder.clone()); p.borrow_mut().timer_entry = crate::ListHead::::new_node( Rc::downgrade(&p.borrow().holder) ); p.borrow_mut().attach_entry = crate::ListHead::::new_head(); } return p; } fn cascade(&mut self, idx: usize) -> usize { let index = self.get_timer_index(idx); let tv : &mut [TimerListListHeadRp]; match idx { 0 => { tv = &mut self.tv2; } 1 => { tv = &mut self.tv3; } 2 => { tv = &mut self.tv4; } 3 => { tv = &mut self.tv5; } _ => { tv = &mut self.tv5; } } if !tv[index].borrow().empty() { let mut cascade_list = crate::ListHead::::new_head(); tv[index].borrow().replace_init(&mut cascade_list); while !cascade_list.borrow().empty() { let timer = &cascade_list.borrow().first_entry().upgrade().unwrap(); timer.borrow_mut().timer_entry.borrow_mut().del_init(); self.internal_add2(timer); } } return index; } fn get_timer_index(&self, index : usize) -> usize { return ((self.timer_tick as usize) >> (TVR_BITS + index * TVN_BITS)) & TVN_MASK; } pub fn update(&mut self) { let tick = (self.get_tick_count)(); while tick >= self.timer_tick { let index = (self.timer_tick & (TVR_MASK as i64)) as usize; if index == 0 && self.cascade(0) == 0 && self.cascade(1) == 0 && self.cascade(2) == 0 { self.cascade(3); } self.timer_tick += 1; self.work_list.borrow().replace_init(&mut self.tv1[index]); while !self.work_list.borrow().empty() { let timer = &self.work_list.borrow().first_entry(); self.running_timer = timer.clone(); match &mut timer.upgrade().unwrap().borrow_mut().cb { Some(v) => { (*v)(TimerEvent::Exec, None); } None => { } } match self.running_timer.upgrade() { Some(v) => { match v.borrow().timer_type { TimerType::Timeout => { self.internal_delete(Rc::downgrade(&v.borrow().wp), false); } TimerType::Interval => { self.modify(Rc::downgrade(&v.borrow().wp), v.borrow().expire_time); } } } None => { } } } } self.running_timer = Weak::new(); } fn internal_add(&mut self, timer_type: TimerType, expire_time: i32, cb: TimerCb, attacher: Option) -> TimerWp { let t = self.new_timer_list(); t.borrow_mut().cb = Some(cb); t.borrow_mut().timer_type = timer_type; t.borrow_mut().expire_time = expire_time; t.borrow_mut().expires = (self.get_tick_count)() + expire_time as i64; match attacher { Some(v) => { v.borrow_mut().timers.borrow().add_tail(&t.borrow_mut().attach_entry); } None => { } } self.internal_add2(&t); return Rc::downgrade(&t.borrow().wp); } fn internal_add2(&mut self, t: &Rc::>) { let idx = t.borrow().expires - self.timer_tick; let index; let vec: &mut Rc::>>; if idx < 0 { index = self.timer_tick & (TVR_MASK as i64); vec = &mut self.tv1[index as usize]; } else if idx < TVR_SIZE as i64 { index = t.borrow().expires & (TVR_MASK as i64); vec = &mut self.tv1[index as usize]; } else if idx < (1 << (TVR_BITS + TVN_BITS)) { index = (t.borrow().expires >> TVR_BITS) & (TVN_MASK as i64); vec = &mut self.tv2[index as usize]; } else if idx < (1 << (TVR_BITS + 2 * TVN_BITS)) { index = (t.borrow().expires >> (TVR_BITS + 1 * TVN_BITS)) & (TVN_MASK as i64); vec = &mut self.tv3[index as usize]; } else if idx < (1 << (TVR_BITS + 3 * TVN_BITS)) { index = (t.borrow().expires >> (TVR_BITS + 2 * TVN_BITS)) & (TVN_MASK as i64); vec = &mut self.tv4[index as usize]; } else { index = (t.borrow().expires >> (TVR_BITS + 3 * TVN_BITS)) & (TVN_MASK as i64); vec = &mut self.tv5[index as usize]; } vec.borrow().add_tail(&t.borrow_mut().timer_entry); } fn internal_delete(&mut self, timer_wp: TimerWp, is_destory: bool) { match timer_wp.upgrade() { Some(v) => { if Weak::ptr_eq(&self.running_timer, &Rc::downgrade(&v)) { self.running_timer = Weak::new(); } self.detach_timer(&*v); match &mut v.borrow_mut().cb { Some(cb) => { if is_destory { (*cb)(TimerEvent::Destory, None); } else { (*cb)(TimerEvent::Delete, None); } v.borrow_mut().cb = None; } None => { } } if Rc::weak_count(&v.borrow().wp) > 0 { v.borrow_mut().wp = Rc::new(v.borrow().holder.clone()); } self.free_timer_list.borrow().add_tail(&v.borrow_mut().timer_entry); self.free_timer_num += 1; } None => { } } } pub fn set_timeout(&mut self, time: i32, cb: TimerCb) -> TimerWp { return self.internal_add(TimerType::Timeout, time, cb, None); } pub fn set_timeout_ex (&mut self, time: i32, cb: TimerCb, attacher: TimerAttacherRp) -> TimerWp { return self.internal_add(TimerType::Timeout, time, cb, Some(attacher)); } pub fn set_interval(&mut self, time: i32, cb: TimerCb) -> TimerWp { return self.internal_add(TimerType::Interval, time, cb, None); } pub fn set_interval_ex (&mut self, time: i32, cb: TimerCb, attacher: TimerAttacherRp) -> TimerWp { return self.internal_add(TimerType::Interval, time, cb, Some(attacher)); } pub fn fire_event(&mut self, timer_wp: TimerWp, e: TimerEvent, args: Option>>) { match timer_wp.upgrade() { Some(t) => { match &mut t.borrow_mut().cb { Some(cb) => { (*cb)(e, args); } None => { } } } None => { } } } pub fn modify(&mut self, timer_wp: TimerWp, expire_time: i32) { match timer_wp.upgrade() { Some(_) => { self.modify(timer_wp, expire_time); } None => { } } } pub fn delete_current_timer(&mut self) { match self.running_timer.upgrade() { Some(v) => { self.internal_delete(Rc::downgrade(&v.borrow().wp), false); } None => { } } } pub fn is_running(&self) -> bool { match self.running_timer.upgrade() { Some(_) => { return true; } None => { return false; } } } pub fn delete(&mut self, timer_wp: TimerWp) { match timer_wp.upgrade() { Some(_) => { self.internal_delete(timer_wp, false); } None => { } } } pub fn get_remain_time(&mut self, timer_wp: TimerWp) -> i64 { match timer_wp.upgrade() { Some(t) => { let remain_time = t.borrow().expires - (self.get_tick_count)(); return cmp::max(remain_time, 0); } None => { return 0; } } } pub fn get_idle_time(&self) -> i64 { let mut idle_time = 0; let start_idx = (self.timer_tick as usize) & TVR_MASK; for i in start_idx..self.tv1.len() { if !self.tv1[i].borrow().empty() { break; } idle_time += 1; } return idle_time; } fn gc_timer(&mut self, e: TimerEvent, _args: Option>>) { match e { TimerEvent::Exec => { while self.free_timer_num > self.cache_timer_num && !self.free_timer_list.borrow().empty() { let timer = &self.free_timer_list.borrow().first_entry().upgrade().unwrap(); timer.borrow_mut().timer_entry.borrow_mut().del_init(); self.free_timer_num -= 1; } } _ => { } } } fn detach_timer(&self, timer: &Rc::>) { if !timer.borrow().timer_entry.borrow().empty() { timer.borrow().timer_entry.borrow_mut().del_init() } } }