rust/hwphysics/src/common.rs
changeset 15380 6e3e5be8b2e2
parent 15288 0f734fa371e1
child 15381 52844baced17
equal deleted inserted replaced
15379:27915135f87f 15380:6e3e5be8b2e2
     4     num::NonZeroU16,
     4     num::NonZeroU16,
     5     ops::{Add, Index, IndexMut},
     5     ops::{Add, Index, IndexMut},
     6 };
     6 };
     7 
     7 
     8 pub type GearId = NonZeroU16;
     8 pub type GearId = NonZeroU16;
     9 pub trait GearData {}
       
    10 
     9 
    11 #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug)]
    10 #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug)]
    12 #[repr(transparent)]
    11 #[repr(transparent)]
    13 pub struct Millis(u32);
    12 pub struct Millis(u32);
    14 
    13 
    35     fn add(self, rhs: Self) -> Self::Output {
    34     fn add(self, rhs: Self) -> Self::Output {
    36         Self(self.0 + rhs.0)
    35         Self(self.0 + rhs.0)
    37     }
    36     }
    38 }
    37 }
    39 
    38 
    40 pub trait GearDataProcessor<T: GearData> {
       
    41     fn add(&mut self, gear_id: GearId, gear_data: T);
       
    42     fn remove(&mut self, gear_id: GearId);
       
    43     fn get(&mut self, gear_id: GearId) -> Option<T>;
       
    44 }
       
    45 
       
    46 pub trait GearDataAggregator<T: GearData> {
       
    47     fn find_processor(&mut self) -> &mut GearDataProcessor<T>;
       
    48 }
       
    49 
       
    50 pub struct GearAllocator {
    39 pub struct GearAllocator {
    51     max_id: u16,
    40     max_id: u16,
    52     free_ids: BinaryHeap<GearId>,
    41     free_ids: BinaryHeap<GearId>,
    53 }
    42 }
    54 
    43 
    71 
    60 
    72     pub fn free(&mut self, gear_id: GearId) {
    61     pub fn free(&mut self, gear_id: GearId) {
    73         self.free_ids.push(gear_id)
    62         self.free_ids.push(gear_id)
    74     }
    63     }
    75 }
    64 }
    76 
       
    77 #[derive(Clone, Copy, Default)]
       
    78 pub struct LookupEntry<T> {
       
    79     index: Option<NonZeroU16>,
       
    80     value: T,
       
    81 }
       
    82 
       
    83 impl<T> LookupEntry<T> {
       
    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;
       
   107     }
       
   108 }
       
   109 
       
   110 pub struct GearDataLookup<T> {
       
   111     lookup: Box<[LookupEntry<T>]>,
       
   112 }
       
   113 
       
   114 impl<T: Default + Copy> GearDataLookup<T> {
       
   115     pub fn new() -> Self {
       
   116         Self {
       
   117             lookup: vec![LookupEntry::default(); u16::max_value() as usize].into_boxed_slice(),
       
   118         }
       
   119     }
       
   120 }
       
   121 
       
   122 impl<T> GearDataLookup<T> {
       
   123     pub fn add(&mut self, gear_id: GearId, index: u16, value: T) {
       
   124         // All possible Gear IDs are valid indices
       
   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);
       
   128     }
       
   129 
       
   130     pub fn get(&self, gear_id: GearId) -> Option<&LookupEntry<T>> {
       
   131         // All possible Gear IDs are valid indices
       
   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         }
       
   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 {
       
   155         self.get(index).unwrap()
       
   156     }
       
   157 }
       
   158 
       
   159 impl<T> IndexMut<GearId> for GearDataLookup<T> {
       
   160     fn index_mut(&mut self, index: GearId) -> &mut Self::Output {
       
   161         self.get_mut(index).unwrap()
       
   162     }
       
   163 }