15296
|
1 |
use fpnum::{fp, FPNum};
|
15302
|
2 |
use std::{
|
|
3 |
collections::BinaryHeap,
|
|
4 |
num::NonZeroU16,
|
|
5 |
ops::{Add, Index, IndexMut},
|
|
6 |
};
|
15295
|
7 |
|
|
8 |
pub type GearId = NonZeroU16;
|
15141
|
9 |
pub trait GearData {}
|
|
10 |
|
15296
|
11 |
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug)]
|
15302
|
12 |
#[repr(transparent)]
|
15296
|
13 |
pub struct Millis(u32);
|
|
14 |
|
|
15 |
impl Millis {
|
|
16 |
#[inline]
|
|
17 |
pub fn new(value: u32) -> Self {
|
|
18 |
Self(value)
|
|
19 |
}
|
|
20 |
|
|
21 |
#[inline]
|
|
22 |
pub fn get(self) -> u32 {
|
|
23 |
self.0
|
|
24 |
}
|
|
25 |
|
|
26 |
#[inline]
|
|
27 |
pub fn to_fixed(self) -> FPNum {
|
|
28 |
FPNum::new(self.0 as i32, 1000)
|
|
29 |
}
|
|
30 |
}
|
|
31 |
|
|
32 |
impl Add for Millis {
|
|
33 |
type Output = Self;
|
|
34 |
|
|
35 |
fn add(self, rhs: Self) -> Self::Output {
|
|
36 |
Self(self.0 + rhs.0)
|
|
37 |
}
|
|
38 |
}
|
|
39 |
|
15141
|
40 |
pub trait GearDataProcessor<T: GearData> {
|
|
41 |
fn add(&mut self, gear_id: GearId, gear_data: T);
|
15295
|
42 |
fn remove(&mut self, gear_id: GearId);
|
15141
|
43 |
}
|
|
44 |
|
|
45 |
pub trait GearDataAggregator<T: GearData> {
|
|
46 |
fn find_processor(&mut self) -> &mut GearDataProcessor<T>;
|
|
47 |
}
|
15295
|
48 |
|
|
49 |
pub struct GearAllocator {
|
|
50 |
max_id: u16,
|
|
51 |
free_ids: BinaryHeap<GearId>,
|
|
52 |
}
|
|
53 |
|
|
54 |
impl GearAllocator {
|
|
55 |
pub fn new() -> Self {
|
|
56 |
Self {
|
|
57 |
max_id: 0,
|
|
58 |
free_ids: BinaryHeap::with_capacity(1024),
|
|
59 |
}
|
|
60 |
}
|
|
61 |
|
|
62 |
pub fn alloc(&mut self) -> Option<GearId> {
|
|
63 |
self.free_ids.pop().or_else(|| {
|
|
64 |
self.max_id.checked_add(1).and_then(|new_max_id| {
|
|
65 |
self.max_id = new_max_id;
|
|
66 |
NonZeroU16::new(new_max_id)
|
|
67 |
})
|
|
68 |
})
|
|
69 |
}
|
|
70 |
|
|
71 |
pub fn free(&mut self, gear_id: GearId) {
|
|
72 |
self.free_ids.push(gear_id)
|
|
73 |
}
|
|
74 |
}
|
15302
|
75 |
|
|
76 |
#[derive(Clone, Copy, Default)]
|
|
77 |
pub struct LookupEntry<T> {
|
|
78 |
pub index: u16,
|
|
79 |
pub value: T,
|
|
80 |
}
|
|
81 |
|
|
82 |
impl<T> LookupEntry<T> {
|
|
83 |
pub fn new(index: u16, value: T) -> Self {
|
|
84 |
Self { index, value }
|
|
85 |
}
|
|
86 |
}
|
|
87 |
|
|
88 |
pub struct GearDataLookup<T> {
|
|
89 |
lookup: [LookupEntry<T>; u16::max_value() as usize],
|
|
90 |
}
|
|
91 |
|
|
92 |
impl<T: Default + Copy> GearDataLookup<T> {
|
|
93 |
pub fn new() -> Self {
|
|
94 |
Self {
|
|
95 |
lookup: [LookupEntry::<T>::default(); u16::max_value() as usize],
|
|
96 |
}
|
|
97 |
}
|
|
98 |
}
|
|
99 |
|
|
100 |
impl<T> GearDataLookup<T> {
|
|
101 |
pub fn get(&self, gear_id: GearId) -> &LookupEntry<T> {
|
|
102 |
// All possible Gear IDs are valid indices
|
|
103 |
unsafe { self.lookup.get_unchecked(gear_id.get() as usize - 1) }
|
|
104 |
}
|
|
105 |
|
|
106 |
pub fn get_mut(&mut self, gear_id: GearId) -> &mut LookupEntry<T> {
|
|
107 |
// All possible Gear IDs are valid indices
|
|
108 |
unsafe { self.lookup.get_unchecked_mut(gear_id.get() as usize - 1) }
|
|
109 |
}
|
|
110 |
}
|
|
111 |
|
|
112 |
impl<T> Index<GearId> for GearDataLookup<T> {
|
|
113 |
type Output = LookupEntry<T>;
|
|
114 |
|
|
115 |
fn index(&self, index: GearId) -> &Self::Output {
|
|
116 |
self.get(index)
|
|
117 |
}
|
|
118 |
}
|
|
119 |
|
|
120 |
impl<T> IndexMut<GearId> for GearDataLookup<T> {
|
|
121 |
fn index_mut(&mut self, index: GearId) -> &mut Self::Output {
|
|
122 |
self.get_mut(index)
|
|
123 |
}
|
|
124 |
}
|