15303
|
1 |
use fpnum::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);
|
15303
|
43 |
fn get(&mut self, gear_id: GearId) -> Option<T>;
|
15141
|
44 |
}
|
|
45 |
|
|
46 |
pub trait GearDataAggregator<T: GearData> {
|
|
47 |
fn find_processor(&mut self) -> &mut GearDataProcessor<T>;
|
|
48 |
}
|
15295
|
49 |
|
|
50 |
pub struct GearAllocator {
|
|
51 |
max_id: u16,
|
|
52 |
free_ids: BinaryHeap<GearId>,
|
|
53 |
}
|
|
54 |
|
|
55 |
impl GearAllocator {
|
|
56 |
pub fn new() -> Self {
|
|
57 |
Self {
|
|
58 |
max_id: 0,
|
|
59 |
free_ids: BinaryHeap::with_capacity(1024),
|
|
60 |
}
|
|
61 |
}
|
|
62 |
|
|
63 |
pub fn alloc(&mut self) -> Option<GearId> {
|
|
64 |
self.free_ids.pop().or_else(|| {
|
|
65 |
self.max_id.checked_add(1).and_then(|new_max_id| {
|
|
66 |
self.max_id = new_max_id;
|
|
67 |
NonZeroU16::new(new_max_id)
|
|
68 |
})
|
|
69 |
})
|
|
70 |
}
|
|
71 |
|
|
72 |
pub fn free(&mut self, gear_id: GearId) {
|
|
73 |
self.free_ids.push(gear_id)
|
|
74 |
}
|
|
75 |
}
|
15302
|
76 |
|
|
77 |
#[derive(Clone, Copy, Default)]
|
|
78 |
pub struct LookupEntry<T> {
|
15303
|
79 |
index: Option<NonZeroU16>,
|
|
80 |
value: T,
|
15302
|
81 |
}
|
|
82 |
|
|
83 |
impl<T> LookupEntry<T> {
|
15303
|
84 |
#[inline]
|
|
85 |
pub fn index(&self) -> u16 {
|
|
86 |
self.index.map(|i| i.get()).unwrap_or(0) - 1
|
|
87 |
}
|
|
88 |
|
|
89 |
#[inline]
|
|
90 |
pub fn set_index(&mut self, index: u16) {
|
|
91 |
self.index = unsafe { Some(NonZeroU16::new_unchecked(index.saturating_add(1))) };
|
|
92 |
}
|
|
93 |
|
|
94 |
#[inline]
|
|
95 |
pub fn value(&self) -> &T {
|
|
96 |
&self.value
|
|
97 |
}
|
|
98 |
|
|
99 |
#[inline]
|
|
100 |
pub fn value_mut(&mut self) -> &mut T {
|
|
101 |
&mut self.value
|
|
102 |
}
|
|
103 |
|
|
104 |
#[inline]
|
|
105 |
pub fn set_value(&mut self, value: T) {
|
|
106 |
self.value = value;
|
15302
|
107 |
}
|
|
108 |
}
|
|
109 |
|
|
110 |
pub struct GearDataLookup<T> {
|
15308
|
111 |
lookup: Box<[LookupEntry<T>]>,
|
15302
|
112 |
}
|
|
113 |
|
|
114 |
impl<T: Default + Copy> GearDataLookup<T> {
|
|
115 |
pub fn new() -> Self {
|
|
116 |
Self {
|
15309
|
117 |
lookup: vec![LookupEntry::default(); u16::max_value() as usize].into_boxed_slice(),
|
15302
|
118 |
}
|
|
119 |
}
|
|
120 |
}
|
|
121 |
|
|
122 |
impl<T> GearDataLookup<T> {
|
15303
|
123 |
pub fn add(&mut self, gear_id: GearId, index: u16, value: T) {
|
15302
|
124 |
// All possible Gear IDs are valid indices
|
15303
|
125 |
let entry = unsafe { self.lookup.get_unchecked_mut(gear_id.get() as usize - 1) };
|
|
126 |
entry.set_index(index);
|
|
127 |
entry.set_value(value);
|
15302
|
128 |
}
|
|
129 |
|
15303
|
130 |
pub fn get(&self, gear_id: GearId) -> Option<&LookupEntry<T>> {
|
15302
|
131 |
// All possible Gear IDs are valid indices
|
15303
|
132 |
let entry = unsafe { self.lookup.get_unchecked(gear_id.get() as usize - 1) };
|
|
133 |
if let Some(index) = entry.index {
|
|
134 |
Some(entry)
|
|
135 |
} else {
|
|
136 |
None
|
|
137 |
}
|
|
138 |
}
|
|
139 |
|
|
140 |
pub fn get_mut(&mut self, gear_id: GearId) -> Option<&mut LookupEntry<T>> {
|
|
141 |
// All possible Gear IDs are valid indices
|
|
142 |
let entry = unsafe { self.lookup.get_unchecked_mut(gear_id.get() as usize - 1) };
|
|
143 |
if let Some(index) = entry.index {
|
|
144 |
Some(entry)
|
|
145 |
} else {
|
|
146 |
None
|
|
147 |
}
|
15302
|
148 |
}
|
|
149 |
}
|
|
150 |
|
|
151 |
impl<T> Index<GearId> for GearDataLookup<T> {
|
|
152 |
type Output = LookupEntry<T>;
|
|
153 |
|
|
154 |
fn index(&self, index: GearId) -> &Self::Output {
|
15303
|
155 |
self.get(index).unwrap()
|
15302
|
156 |
}
|
|
157 |
}
|
|
158 |
|
|
159 |
impl<T> IndexMut<GearId> for GearDataLookup<T> {
|
|
160 |
fn index_mut(&mut self, index: GearId) -> &mut Self::Output {
|
15303
|
161 |
self.get_mut(index).unwrap()
|
15302
|
162 |
}
|
|
163 |
}
|