rust/hwphysics/src/common.rs
changeset 15282 478d5372eb4a
parent 15281 8095853811a6
child 15287 3bb3fe1cf87c
equal deleted inserted replaced
15281:8095853811a6 15282:478d5372eb4a
     1 use fpnum::{fp, FPNum};
     1 use fpnum::FPNum;
     2 use std::{
     2 use std::{
     3     collections::BinaryHeap,
     3     collections::BinaryHeap,
     4     num::NonZeroU16,
     4     num::NonZeroU16,
     5     ops::{Add, Index, IndexMut},
     5     ops::{Add, Index, IndexMut},
     6 };
     6 };
    38 }
    38 }
    39 
    39 
    40 pub trait GearDataProcessor<T: GearData> {
    40 pub trait GearDataProcessor<T: GearData> {
    41     fn add(&mut self, gear_id: GearId, gear_data: T);
    41     fn add(&mut self, gear_id: GearId, gear_data: T);
    42     fn remove(&mut self, gear_id: GearId);
    42     fn remove(&mut self, gear_id: GearId);
       
    43     fn get(&mut self, gear_id: GearId) -> Option<T>;
    43 }
    44 }
    44 
    45 
    45 pub trait GearDataAggregator<T: GearData> {
    46 pub trait GearDataAggregator<T: GearData> {
    46     fn find_processor(&mut self) -> &mut GearDataProcessor<T>;
    47     fn find_processor(&mut self) -> &mut GearDataProcessor<T>;
    47 }
    48 }
    73     }
    74     }
    74 }
    75 }
    75 
    76 
    76 #[derive(Clone, Copy, Default)]
    77 #[derive(Clone, Copy, Default)]
    77 pub struct LookupEntry<T> {
    78 pub struct LookupEntry<T> {
    78     pub index: u16,
    79     index: Option<NonZeroU16>,
    79     pub value: T,
    80     value: T,
    80 }
    81 }
    81 
    82 
    82 impl<T> LookupEntry<T> {
    83 impl<T> LookupEntry<T> {
    83     pub fn new(index: u16, value: T) -> Self {
    84     #[inline]
    84         Self { index, value }
    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;
    85     }
   107     }
    86 }
   108 }
    87 
   109 
    88 pub struct GearDataLookup<T> {
   110 pub struct GearDataLookup<T> {
    89     lookup: [LookupEntry<T>; u16::max_value() as usize],
   111     lookup: [LookupEntry<T>; u16::max_value() as usize],
    96         }
   118         }
    97     }
   119     }
    98 }
   120 }
    99 
   121 
   100 impl<T> GearDataLookup<T> {
   122 impl<T> GearDataLookup<T> {
   101     pub fn get(&self, gear_id: GearId) -> &LookupEntry<T> {
   123     pub fn add(&mut self, gear_id: GearId, index: u16, value: T) {
   102         // All possible Gear IDs are valid indices
   124         // All possible Gear IDs are valid indices
   103         unsafe { self.lookup.get_unchecked(gear_id.get() as usize - 1) }
   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);
   104     }
   128     }
   105 
   129 
   106     pub fn get_mut(&mut self, gear_id: GearId) -> &mut LookupEntry<T> {
   130     pub fn get(&self, gear_id: GearId) -> Option<&LookupEntry<T>> {
   107         // All possible Gear IDs are valid indices
   131         // All possible Gear IDs are valid indices
   108         unsafe { self.lookup.get_unchecked_mut(gear_id.get() as usize - 1) }
   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         }
   109     }
   148     }
   110 }
   149 }
   111 
   150 
   112 impl<T> Index<GearId> for GearDataLookup<T> {
   151 impl<T> Index<GearId> for GearDataLookup<T> {
   113     type Output = LookupEntry<T>;
   152     type Output = LookupEntry<T>;
   114 
   153 
   115     fn index(&self, index: GearId) -> &Self::Output {
   154     fn index(&self, index: GearId) -> &Self::Output {
   116         self.get(index)
   155         self.get(index).unwrap()
   117     }
   156     }
   118 }
   157 }
   119 
   158 
   120 impl<T> IndexMut<GearId> for GearDataLookup<T> {
   159 impl<T> IndexMut<GearId> for GearDataLookup<T> {
   121     fn index_mut(&mut self, index: GearId) -> &mut Self::Output {
   160     fn index_mut(&mut self, index: GearId) -> &mut Self::Output {
   122         self.get_mut(index)
   161         self.get_mut(index).unwrap()
   123     }
   162     }
   124 }
   163 }