diff -r b12f63054c94 -r 8095853811a6 rust/hwphysics/src/common.rs --- a/rust/hwphysics/src/common.rs Mon Jul 29 21:58:39 2019 +0200 +++ b/rust/hwphysics/src/common.rs Tue Jul 30 19:53:23 2019 +0300 @@ -1,10 +1,15 @@ use fpnum::{fp, FPNum}; -use std::{collections::BinaryHeap, num::NonZeroU16, ops::Add}; +use std::{ + collections::BinaryHeap, + num::NonZeroU16, + ops::{Add, Index, IndexMut}, +}; pub type GearId = NonZeroU16; pub trait GearData {} #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug)] +#[repr(transparent)] pub struct Millis(u32); impl Millis { @@ -67,3 +72,53 @@ self.free_ids.push(gear_id) } } + +#[derive(Clone, Copy, Default)] +pub struct LookupEntry { + pub index: u16, + pub value: T, +} + +impl LookupEntry { + pub fn new(index: u16, value: T) -> Self { + Self { index, value } + } +} + +pub struct GearDataLookup { + lookup: [LookupEntry; u16::max_value() as usize], +} + +impl GearDataLookup { + pub fn new() -> Self { + Self { + lookup: [LookupEntry::::default(); u16::max_value() as usize], + } + } +} + +impl GearDataLookup { + pub fn get(&self, gear_id: GearId) -> &LookupEntry { + // All possible Gear IDs are valid indices + unsafe { self.lookup.get_unchecked(gear_id.get() as usize - 1) } + } + + pub fn get_mut(&mut self, gear_id: GearId) -> &mut LookupEntry { + // All possible Gear IDs are valid indices + unsafe { self.lookup.get_unchecked_mut(gear_id.get() as usize - 1) } + } +} + +impl Index for GearDataLookup { + type Output = LookupEntry; + + fn index(&self, index: GearId) -> &Self::Output { + self.get(index) + } +} + +impl IndexMut for GearDataLookup { + fn index_mut(&mut self, index: GearId) -> &mut Self::Output { + self.get_mut(index) + } +}