--- 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
+ }
+}