use crate::HashMap;
use crate::RBTree;
use std::cmp::Ordering;
use std::u64;
use std::vec;
use super::Timer;
#[derive(PartialEq, Eq)]
struct TreeKey(u64, u64);
impl Ord for TreeKey {
fn cmp(&self, other: &Self) -> Ordering {
if self.0 != other.0 {
return self.0.cmp(&other.0);
}
other.1.cmp(&self.1)
}
}
impl PartialOrd for TreeKey {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
pub struct TimerRBTree<T: Timer> {
tree: RBTree<TreeKey, T>,
map: HashMap<u64, u64>,
cur_step: u64,
next_timer_id: u64,
max_timer_id: u64,
}
impl<T: Timer> TimerRBTree<T> {
pub fn new() -> Self {
Self {
tree: RBTree::new(),
map: HashMap::new(),
cur_step: 0,
next_timer_id: 1,
max_timer_id: u64::MAX,
}
}
pub fn len(&self) -> usize {
self.tree.len()
}
pub fn is_empty(&self) -> bool {
self.tree.is_empty()
}
pub fn clear(&mut self) {
self.tree.clear();
self.map.clear();
self.cur_step = 0;
self.next_timer_id = 1;
}
pub fn get_max_timerid(&self) -> u64 {
self.max_timer_id
}
pub fn set_max_timerid(&mut self, max: u64) {
self.max_timer_id = max;
}
fn get_next_timerid(&mut self) -> u64 {
let mut timer_id;
loop {
timer_id = self.next_timer_id;
if self.next_timer_id >= self.max_timer_id {
self.next_timer_id = 1;
} else {
self.next_timer_id = self.next_timer_id + 1;
}
if !self.map.contains_key(&timer_id) {
break;
}
}
timer_id
}
pub fn add_timer(&mut self, val: T) -> u64 {
let timer_id = self.get_next_timerid();
self.add_timer_by_id(timer_id, val);
timer_id
}
pub fn add_timer_by_id(&mut self, timer_id: u64, val: T) {
let when = val.when();
self.tree.insert(TreeKey(when, timer_id), val);
self.map.insert(timer_id, when);
}
pub fn del_timer(&mut self, timer_id: u64) -> Option<T> {
if let Some(when) = self.map.remove(&timer_id) {
let tree = TreeKey(when, timer_id);
self.tree.remove(&tree).map(|e| e)
} else {
None
}
}
pub fn get_timer(&self, timer_id: &u64) -> Option<&T> {
if let Some(when) = self.map.get(timer_id) {
let tree = TreeKey(*when, *timer_id);
self.tree.get(&tree).map(|e| e)
} else {
None
}
}
pub fn get_mut_timer(&mut self, timer_id: &u64) -> Option<&mut T> {
if let Some(when) = self.map.get(timer_id) {
let tree = TreeKey(*when, *timer_id);
self.tree.get_mut(&tree).map(|e| e)
} else {
None
}
}
pub fn tick_first(&self) -> Option<u64> {
self.tree
.get_first()
.map(|(key, _)| Some(key.0))
.unwrap_or(None)
}
pub fn tick_time(&mut self, tm: u64) -> Option<T> {
if tm < self.tick_first().unwrap_or(tm + 1) {
return None;
}
self.tree.pop_first().map(|(_, e)| e)
}
pub fn update_now(&mut self, now: u64) -> Option<Vec<(u64, T)>> {
self.cur_step = now;
let mut result = vec![];
loop {
if let Some(val) = self.tick_first() {
if self.cur_step < val {
break;
}
result.push(self.tree.pop_first().map(|(k, e)| (k.1, e)).unwrap());
} else {
break;
}
}
Some(result)
}
pub fn update_deltatime(&mut self, delta: u64) -> Option<Vec<(u64, T)>> {
self.update_now(self.cur_step.wrapping_add(delta))
}
pub fn update_deltatime_with_callback<F>(&mut self, delta: u64, f: &mut F)
where
F: FnMut(&mut Self, u64, T) -> Option<(u64, T)>,
{
self.update_now_with_callback(self.cur_step.wrapping_add(delta), f)
}
pub fn update_now_with_callback<F>(&mut self, now: u64, f: &mut F)
where
F: FnMut(&mut Self, u64, T) -> Option<(u64, T)>,
{
if let Some(result) = self.update_now(now) {
let mut collect_result = vec![];
for r in result.into_iter() {
if let Some(v) = (*f)(self, r.0, r.1) {
collect_result.push(v);
}
}
for (timer_id, v) in collect_result.drain(..) {
self.add_timer_by_id(timer_id, v);
}
}
}
}