1 use fpnum::{fp, FPNum}; |
1 use fpnum::{fp, FPNum}; |
2 use std::{collections::BinaryHeap, num::NonZeroU16, ops::Add}; |
2 use std::{ |
|
3 collections::BinaryHeap, |
|
4 num::NonZeroU16, |
|
5 ops::{Add, Index, IndexMut}, |
|
6 }; |
3 |
7 |
4 pub type GearId = NonZeroU16; |
8 pub type GearId = NonZeroU16; |
5 pub trait GearData {} |
9 pub trait GearData {} |
6 |
10 |
7 #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug)] |
11 #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug)] |
|
12 #[repr(transparent)] |
8 pub struct Millis(u32); |
13 pub struct Millis(u32); |
9 |
14 |
10 impl Millis { |
15 impl Millis { |
11 #[inline] |
16 #[inline] |
12 pub fn new(value: u32) -> Self { |
17 pub fn new(value: u32) -> Self { |
65 |
70 |
66 pub fn free(&mut self, gear_id: GearId) { |
71 pub fn free(&mut self, gear_id: GearId) { |
67 self.free_ids.push(gear_id) |
72 self.free_ids.push(gear_id) |
68 } |
73 } |
69 } |
74 } |
|
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 } |