# HG changeset patch # User alfadur # Date 1564073899 -10800 # Node ID 7446258fab986becafcf008c238c0db2326c8df3 # Parent 96fbf9bb960a8766a7dc3172958c8dcd4f30acd1 add time events diff -r 96fbf9bb960a -r 7446258fab98 rust/hwphysics/src/collision.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)] diff -r 96fbf9bb960a -r 7446258fab98 rust/hwphysics/src/lib.rs --- 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) { 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(&mut self, gear_id: GearId, data: T) diff -r 96fbf9bb960a -r 7446258fab98 rust/hwphysics/src/physics.rs --- 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(), diff -r 96fbf9bb960a -r 7446258fab98 rust/hwphysics/src/time.rs --- /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 { + 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, + 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 + } +}