rust/hwphysics/src/time.rs
changeset 15270 7446258fab98
child 15274 42b710b0f883
equal deleted inserted replaced
15269:96fbf9bb960a 15270:7446258fab98
       
     1 use crate::common::{GearDataProcessor, GearId};
       
     2 use fpnum::{fp, FPNum};
       
     3 use std::{
       
     4     cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd},
       
     5     collections::BinaryHeap,
       
     6 };
       
     7 
       
     8 pub type EventId = u16;
       
     9 
       
    10 struct TimeEvent {
       
    11     time: FPNum,
       
    12     gear_id: GearId,
       
    13     event_id: EventId,
       
    14 }
       
    15 
       
    16 impl PartialOrd for TimeEvent {
       
    17     #[inline]
       
    18     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
       
    19         self.time.partial_cmp(&other.time)
       
    20     }
       
    21 }
       
    22 
       
    23 impl PartialEq for TimeEvent {
       
    24     #[inline]
       
    25     fn eq(&self, other: &Self) -> bool {
       
    26         self.time.eq(&other.time)
       
    27     }
       
    28 }
       
    29 
       
    30 impl Ord for TimeEvent {
       
    31     #[inline]
       
    32     fn cmp(&self, other: &Self) -> Ordering {
       
    33         self.time.cmp(&other.time)
       
    34     }
       
    35 }
       
    36 
       
    37 impl Eq for TimeEvent {}
       
    38 
       
    39 pub struct OccurredEvents {
       
    40     events: Vec<(GearId, EventId)>,
       
    41 }
       
    42 
       
    43 impl OccurredEvents {
       
    44     fn new() -> Self {
       
    45         Self { events: vec![] }
       
    46     }
       
    47 
       
    48     fn clear(&mut self) {
       
    49         self.events.clear()
       
    50     }
       
    51 }
       
    52 
       
    53 pub struct TimeProcessor {
       
    54     current_event_id: EventId,
       
    55     current_time: FPNum,
       
    56     events: BinaryHeap<TimeEvent>,
       
    57     timeouts: OccurredEvents,
       
    58 }
       
    59 
       
    60 impl TimeProcessor {
       
    61     pub fn new() -> Self {
       
    62         Self {
       
    63             current_event_id: 0,
       
    64             current_time: fp!(0),
       
    65             events: BinaryHeap::with_capacity(1024),
       
    66             timeouts: OccurredEvents::new(),
       
    67         }
       
    68     }
       
    69 
       
    70     pub fn register(&mut self, gear_id: GearId, timeout: FPNum) -> EventId {
       
    71         let event_id = self.current_event_id;
       
    72         self.current_event_id.wrapping_add(1);
       
    73         let event = TimeEvent {
       
    74             time: self.current_time + timeout,
       
    75             gear_id,
       
    76             event_id,
       
    77         };
       
    78         self.events.push(event);
       
    79         event_id
       
    80     }
       
    81 
       
    82     pub fn process(&mut self, time_step: FPNum) -> &OccurredEvents {
       
    83         self.timeouts.clear();
       
    84         self.current_time += time_step;
       
    85         while self
       
    86             .events
       
    87             .peek()
       
    88             .filter(|e| e.time <= self.current_time)
       
    89             .is_some()
       
    90         {
       
    91             let event = self.events.pop().unwrap();
       
    92             self.timeouts.events.push((event.gear_id, event.event_id))
       
    93         }
       
    94         &self.timeouts
       
    95     }
       
    96 }