use crate::dynamics::RigidBodySet;
use crate::geometry::{ColliderSet, CollisionEvent, ContactForceEvent, ContactPair};
use crate::math::Real;
use std::sync::mpsc::Sender;
bitflags::bitflags! {
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
pub struct ActiveEvents: u32 {
const COLLISION_EVENTS = 0b0001;
const CONTACT_FORCE_EVENTS = 0b0010;
}
}
impl Default for ActiveEvents {
fn default() -> Self {
ActiveEvents::empty()
}
}
pub trait EventHandler: Send + Sync {
fn handle_collision_event(
&self,
bodies: &RigidBodySet,
colliders: &ColliderSet,
event: CollisionEvent,
contact_pair: Option<&ContactPair>,
);
fn handle_contact_force_event(
&self,
dt: Real,
bodies: &RigidBodySet,
colliders: &ColliderSet,
contact_pair: &ContactPair,
total_force_magnitude: Real,
);
}
impl EventHandler for () {
fn handle_collision_event(
&self,
_bodies: &RigidBodySet,
_colliders: &ColliderSet,
_event: CollisionEvent,
_contact_pair: Option<&ContactPair>,
) {
}
fn handle_contact_force_event(
&self,
_dt: Real,
_bodies: &RigidBodySet,
_colliders: &ColliderSet,
_contact_pair: &ContactPair,
_total_force_magnitude: Real,
) {
}
}
pub struct ChannelEventCollector {
collision_event_sender: Sender<CollisionEvent>,
contact_force_event_sender: Sender<ContactForceEvent>,
}
impl ChannelEventCollector {
pub fn new(
collision_event_sender: Sender<CollisionEvent>,
contact_force_event_sender: Sender<ContactForceEvent>,
) -> Self {
Self {
collision_event_sender,
contact_force_event_sender,
}
}
}
impl EventHandler for ChannelEventCollector {
fn handle_collision_event(
&self,
_bodies: &RigidBodySet,
_colliders: &ColliderSet,
event: CollisionEvent,
_: Option<&ContactPair>,
) {
let _ = self.collision_event_sender.send(event);
}
fn handle_contact_force_event(
&self,
dt: Real,
_bodies: &RigidBodySet,
_colliders: &ColliderSet,
contact_pair: &ContactPair,
total_force_magnitude: Real,
) {
let result = ContactForceEvent::from_contact_pair(dt, contact_pair, total_force_magnitude);
let _ = self.contact_force_event_sender.send(result);
}
}