rust/hwphysics/src/common.rs
author alfadur
Sat, 03 Aug 2019 02:14:07 +0300
changeset 15287 3bb3fe1cf87c
parent 15282 478d5372eb4a
child 15288 0f734fa371e1
permissions -rw-r--r--
fix gear lookup allocated on stack
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
15282
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
     1
use fpnum::FPNum;
15281
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
     2
use std::{
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
     3
    collections::BinaryHeap,
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
     4
    num::NonZeroU16,
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
     5
    ops::{Add, Index, IndexMut},
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
     6
};
15274
42b710b0f883 add gear allocator
alfadur
parents: 15263
diff changeset
     7
42b710b0f883 add gear allocator
alfadur
parents: 15263
diff changeset
     8
pub type GearId = NonZeroU16;
15120
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14179
diff changeset
     9
pub trait GearData {}
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14179
diff changeset
    10
15275
66c987015f2d replace time with milliseconds
alfadur
parents: 15274
diff changeset
    11
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug)]
15281
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
    12
#[repr(transparent)]
15275
66c987015f2d replace time with milliseconds
alfadur
parents: 15274
diff changeset
    13
pub struct Millis(u32);
66c987015f2d replace time with milliseconds
alfadur
parents: 15274
diff changeset
    14
66c987015f2d replace time with milliseconds
alfadur
parents: 15274
diff changeset
    15
impl Millis {
66c987015f2d replace time with milliseconds
alfadur
parents: 15274
diff changeset
    16
    #[inline]
66c987015f2d replace time with milliseconds
alfadur
parents: 15274
diff changeset
    17
    pub fn new(value: u32) -> Self {
66c987015f2d replace time with milliseconds
alfadur
parents: 15274
diff changeset
    18
        Self(value)
66c987015f2d replace time with milliseconds
alfadur
parents: 15274
diff changeset
    19
    }
66c987015f2d replace time with milliseconds
alfadur
parents: 15274
diff changeset
    20
66c987015f2d replace time with milliseconds
alfadur
parents: 15274
diff changeset
    21
    #[inline]
66c987015f2d replace time with milliseconds
alfadur
parents: 15274
diff changeset
    22
    pub fn get(self) -> u32 {
66c987015f2d replace time with milliseconds
alfadur
parents: 15274
diff changeset
    23
        self.0
66c987015f2d replace time with milliseconds
alfadur
parents: 15274
diff changeset
    24
    }
66c987015f2d replace time with milliseconds
alfadur
parents: 15274
diff changeset
    25
66c987015f2d replace time with milliseconds
alfadur
parents: 15274
diff changeset
    26
    #[inline]
66c987015f2d replace time with milliseconds
alfadur
parents: 15274
diff changeset
    27
    pub fn to_fixed(self) -> FPNum {
66c987015f2d replace time with milliseconds
alfadur
parents: 15274
diff changeset
    28
        FPNum::new(self.0 as i32, 1000)
66c987015f2d replace time with milliseconds
alfadur
parents: 15274
diff changeset
    29
    }
66c987015f2d replace time with milliseconds
alfadur
parents: 15274
diff changeset
    30
}
66c987015f2d replace time with milliseconds
alfadur
parents: 15274
diff changeset
    31
66c987015f2d replace time with milliseconds
alfadur
parents: 15274
diff changeset
    32
impl Add for Millis {
66c987015f2d replace time with milliseconds
alfadur
parents: 15274
diff changeset
    33
    type Output = Self;
66c987015f2d replace time with milliseconds
alfadur
parents: 15274
diff changeset
    34
66c987015f2d replace time with milliseconds
alfadur
parents: 15274
diff changeset
    35
    fn add(self, rhs: Self) -> Self::Output {
66c987015f2d replace time with milliseconds
alfadur
parents: 15274
diff changeset
    36
        Self(self.0 + rhs.0)
66c987015f2d replace time with milliseconds
alfadur
parents: 15274
diff changeset
    37
    }
66c987015f2d replace time with milliseconds
alfadur
parents: 15274
diff changeset
    38
}
66c987015f2d replace time with milliseconds
alfadur
parents: 15274
diff changeset
    39
15120
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14179
diff changeset
    40
pub trait GearDataProcessor<T: GearData> {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14179
diff changeset
    41
    fn add(&mut self, gear_id: GearId, gear_data: T);
15274
42b710b0f883 add gear allocator
alfadur
parents: 15263
diff changeset
    42
    fn remove(&mut self, gear_id: GearId);
15282
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
    43
    fn get(&mut self, gear_id: GearId) -> Option<T>;
15120
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14179
diff changeset
    44
}
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14179
diff changeset
    45
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14179
diff changeset
    46
pub trait GearDataAggregator<T: GearData> {
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14179
diff changeset
    47
    fn find_processor(&mut self) -> &mut GearDataProcessor<T>;
febccab419b1 Apply dos2unix to rust sources
unc0rr
parents: 14179
diff changeset
    48
}
15274
42b710b0f883 add gear allocator
alfadur
parents: 15263
diff changeset
    49
42b710b0f883 add gear allocator
alfadur
parents: 15263
diff changeset
    50
pub struct GearAllocator {
42b710b0f883 add gear allocator
alfadur
parents: 15263
diff changeset
    51
    max_id: u16,
42b710b0f883 add gear allocator
alfadur
parents: 15263
diff changeset
    52
    free_ids: BinaryHeap<GearId>,
42b710b0f883 add gear allocator
alfadur
parents: 15263
diff changeset
    53
}
42b710b0f883 add gear allocator
alfadur
parents: 15263
diff changeset
    54
42b710b0f883 add gear allocator
alfadur
parents: 15263
diff changeset
    55
impl GearAllocator {
42b710b0f883 add gear allocator
alfadur
parents: 15263
diff changeset
    56
    pub fn new() -> Self {
42b710b0f883 add gear allocator
alfadur
parents: 15263
diff changeset
    57
        Self {
42b710b0f883 add gear allocator
alfadur
parents: 15263
diff changeset
    58
            max_id: 0,
42b710b0f883 add gear allocator
alfadur
parents: 15263
diff changeset
    59
            free_ids: BinaryHeap::with_capacity(1024),
42b710b0f883 add gear allocator
alfadur
parents: 15263
diff changeset
    60
        }
42b710b0f883 add gear allocator
alfadur
parents: 15263
diff changeset
    61
    }
42b710b0f883 add gear allocator
alfadur
parents: 15263
diff changeset
    62
42b710b0f883 add gear allocator
alfadur
parents: 15263
diff changeset
    63
    pub fn alloc(&mut self) -> Option<GearId> {
42b710b0f883 add gear allocator
alfadur
parents: 15263
diff changeset
    64
        self.free_ids.pop().or_else(|| {
42b710b0f883 add gear allocator
alfadur
parents: 15263
diff changeset
    65
            self.max_id.checked_add(1).and_then(|new_max_id| {
42b710b0f883 add gear allocator
alfadur
parents: 15263
diff changeset
    66
                self.max_id = new_max_id;
42b710b0f883 add gear allocator
alfadur
parents: 15263
diff changeset
    67
                NonZeroU16::new(new_max_id)
42b710b0f883 add gear allocator
alfadur
parents: 15263
diff changeset
    68
            })
42b710b0f883 add gear allocator
alfadur
parents: 15263
diff changeset
    69
        })
42b710b0f883 add gear allocator
alfadur
parents: 15263
diff changeset
    70
    }
42b710b0f883 add gear allocator
alfadur
parents: 15263
diff changeset
    71
42b710b0f883 add gear allocator
alfadur
parents: 15263
diff changeset
    72
    pub fn free(&mut self, gear_id: GearId) {
42b710b0f883 add gear allocator
alfadur
parents: 15263
diff changeset
    73
        self.free_ids.push(gear_id)
42b710b0f883 add gear allocator
alfadur
parents: 15263
diff changeset
    74
    }
42b710b0f883 add gear allocator
alfadur
parents: 15263
diff changeset
    75
}
15281
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
    76
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
    77
#[derive(Clone, Copy, Default)]
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
    78
pub struct LookupEntry<T> {
15282
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
    79
    index: Option<NonZeroU16>,
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
    80
    value: T,
15281
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
    81
}
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
    82
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
    83
impl<T> LookupEntry<T> {
15282
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
    84
    #[inline]
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
    85
    pub fn index(&self) -> u16 {
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
    86
        self.index.map(|i| i.get()).unwrap_or(0) - 1
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
    87
    }
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
    88
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
    89
    #[inline]
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
    90
    pub fn set_index(&mut self, index: u16) {
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
    91
        self.index = unsafe { Some(NonZeroU16::new_unchecked(index.saturating_add(1))) };
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
    92
    }
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
    93
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
    94
    #[inline]
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
    95
    pub fn value(&self) -> &T {
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
    96
        &self.value
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
    97
    }
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
    98
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
    99
    #[inline]
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
   100
    pub fn value_mut(&mut self) -> &mut T {
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
   101
        &mut self.value
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
   102
    }
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
   103
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
   104
    #[inline]
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
   105
    pub fn set_value(&mut self, value: T) {
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
   106
        self.value = value;
15281
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
   107
    }
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
   108
}
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
   109
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
   110
pub struct GearDataLookup<T> {
15287
3bb3fe1cf87c fix gear lookup allocated on stack
alfadur
parents: 15282
diff changeset
   111
    lookup: Box<[LookupEntry<T>]>,
15281
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
   112
}
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
   113
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
   114
impl<T: Default + Copy> GearDataLookup<T> {
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
   115
    pub fn new() -> Self {
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
   116
        Self {
15287
3bb3fe1cf87c fix gear lookup allocated on stack
alfadur
parents: 15282
diff changeset
   117
            lookup: Vec::with_capacity(u16::max_value() as usize).into_boxed_slice()
15281
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
   118
        }
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
   119
    }
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
   120
}
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
   121
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
   122
impl<T> GearDataLookup<T> {
15282
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
   123
    pub fn add(&mut self, gear_id: GearId, index: u16, value: T) {
15281
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
   124
        // All possible Gear IDs are valid indices
15282
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
   125
        let entry = unsafe { self.lookup.get_unchecked_mut(gear_id.get() as usize - 1) };
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
   126
        entry.set_index(index);
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
   127
        entry.set_value(value);
15281
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
   128
    }
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
   129
15282
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
   130
    pub fn get(&self, gear_id: GearId) -> Option<&LookupEntry<T>> {
15281
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
   131
        // All possible Gear IDs are valid indices
15282
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
   132
        let entry = unsafe { self.lookup.get_unchecked(gear_id.get() as usize - 1) };
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
   133
        if let Some(index) = entry.index {
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
   134
            Some(entry)
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
   135
        } else {
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
   136
            None
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
   137
        }
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
   138
    }
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
   139
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
   140
    pub fn get_mut(&mut self, gear_id: GearId) -> Option<&mut LookupEntry<T>> {
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
   141
        // All possible Gear IDs are valid indices
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
   142
        let entry = unsafe { self.lookup.get_unchecked_mut(gear_id.get() as usize - 1) };
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
   143
        if let Some(index) = entry.index {
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
   144
            Some(entry)
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
   145
        } else {
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
   146
            None
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
   147
        }
15281
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
   148
    }
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
   149
}
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
   150
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
   151
impl<T> Index<GearId> for GearDataLookup<T> {
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
   152
    type Output = LookupEntry<T>;
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
   153
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
   154
    fn index(&self, index: GearId) -> &Self::Output {
15282
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
   155
        self.get(index).unwrap()
15281
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
   156
    }
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
   157
}
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
   158
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
   159
impl<T> IndexMut<GearId> for GearDataLookup<T> {
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
   160
    fn index_mut(&mut self, index: GearId) -> &mut Self::Output {
15282
478d5372eb4a implement empty gear lookup entries
alfadur
parents: 15281
diff changeset
   161
        self.get_mut(index).unwrap()
15281
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
   162
    }
8095853811a6 add gear lookup to the physics processor
alfadur
parents: 15275
diff changeset
   163
}