add time events
authoralfadur
Thu, 25 Jul 2019 19:58:19 +0300
changeset 15270 7446258fab98
parent 15269 96fbf9bb960a
child 15271 a0e425458694
add time events
rust/hwphysics/src/collision.rs
rust/hwphysics/src/lib.rs
rust/hwphysics/src/physics.rs
rust/hwphysics/src/time.rs
--- a/rust/hwphysics/src/collision.rs	Thu Jul 25 18:40:06 2019 +0200
+++ b/rust/hwphysics/src/collision.rs	Thu Jul 25 19:58:19 2019 +0300
@@ -11,7 +11,7 @@
 use land2d::Land2D;
 
 pub fn fppoint_round(point: &FPPoint) -> Point {
-    Point::new(point.x().round() as i32, point.y().round() as i32)
+    Point::new(point.x().round(), point.y().round())
 }
 
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
--- a/rust/hwphysics/src/lib.rs	Thu Jul 25 18:40:06 2019 +0200
+++ b/rust/hwphysics/src/lib.rs	Thu Jul 25 19:58:19 2019 +0300
@@ -2,6 +2,7 @@
 pub mod common;
 mod grid;
 pub mod physics;
+pub mod time;
 
 use fpnum::FPNum;
 use integral_geometry::Size;
@@ -11,6 +12,7 @@
     collision::{CollisionData, CollisionProcessor, ContactData},
     common::{GearData, GearDataAggregator, GearDataProcessor, GearId},
     physics::{PhysicsData, PhysicsProcessor},
+    time::TimeProcessor,
 };
 
 pub struct JoinedData {
@@ -23,6 +25,7 @@
 pub struct World {
     physics: PhysicsProcessor,
     collision: CollisionProcessor,
+    time: TimeProcessor,
 }
 
 macro_rules! processor_map {
@@ -43,12 +46,14 @@
         Self {
             physics: PhysicsProcessor::new(),
             collision: CollisionProcessor::new(world_size),
+            time: TimeProcessor::new(),
         }
     }
 
     pub fn step(&mut self, time_step: FPNum, land: &Land2D<u32>) {
         let updates = self.physics.process(time_step);
         let collision = self.collision.process(land, &updates);
+        let events = self.time.process(time_step);
     }
 
     pub fn add_gear_data<T>(&mut self, gear_id: GearId, data: T)
--- a/rust/hwphysics/src/physics.rs	Thu Jul 25 18:40:06 2019 +0200
+++ b/rust/hwphysics/src/physics.rs	Thu Jul 25 19:58:19 2019 +0300
@@ -110,7 +110,7 @@
 
 impl PhysicsProcessor {
     pub fn new() -> Self {
-        PhysicsProcessor {
+        Self {
             dynamic_physics: DynamicPhysicsCollection::new(),
             static_physics: StaticPhysicsCollection::new(),
             physics_cleanup: Vec::new(),
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rust/hwphysics/src/time.rs	Thu Jul 25 19:58:19 2019 +0300
@@ -0,0 +1,96 @@
+use crate::common::{GearDataProcessor, GearId};
+use fpnum::{fp, FPNum};
+use std::{
+    cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd},
+    collections::BinaryHeap,
+};
+
+pub type EventId = u16;
+
+struct TimeEvent {
+    time: FPNum,
+    gear_id: GearId,
+    event_id: EventId,
+}
+
+impl PartialOrd for TimeEvent {
+    #[inline]
+    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+        self.time.partial_cmp(&other.time)
+    }
+}
+
+impl PartialEq for TimeEvent {
+    #[inline]
+    fn eq(&self, other: &Self) -> bool {
+        self.time.eq(&other.time)
+    }
+}
+
+impl Ord for TimeEvent {
+    #[inline]
+    fn cmp(&self, other: &Self) -> Ordering {
+        self.time.cmp(&other.time)
+    }
+}
+
+impl Eq for TimeEvent {}
+
+pub struct OccurredEvents {
+    events: Vec<(GearId, EventId)>,
+}
+
+impl OccurredEvents {
+    fn new() -> Self {
+        Self { events: vec![] }
+    }
+
+    fn clear(&mut self) {
+        self.events.clear()
+    }
+}
+
+pub struct TimeProcessor {
+    current_event_id: EventId,
+    current_time: FPNum,
+    events: BinaryHeap<TimeEvent>,
+    timeouts: OccurredEvents,
+}
+
+impl TimeProcessor {
+    pub fn new() -> Self {
+        Self {
+            current_event_id: 0,
+            current_time: fp!(0),
+            events: BinaryHeap::with_capacity(1024),
+            timeouts: OccurredEvents::new(),
+        }
+    }
+
+    pub fn register(&mut self, gear_id: GearId, timeout: FPNum) -> EventId {
+        let event_id = self.current_event_id;
+        self.current_event_id.wrapping_add(1);
+        let event = TimeEvent {
+            time: self.current_time + timeout,
+            gear_id,
+            event_id,
+        };
+        self.events.push(event);
+        event_id
+    }
+
+    pub fn process(&mut self, time_step: FPNum) -> &OccurredEvents {
+        self.timeouts.clear();
+        self.current_time += time_step;
+        while self
+            .events
+            .peek()
+            .filter(|e| e.time <= self.current_time)
+            .is_some()
+        {
+            let event = self.events.pop().unwrap();
+            self.timeouts.events.push((event.gear_id, event.event_id))
+        }
+        &self.timeouts
+    }
+}