Skip to content

Commit

Permalink
Added 'realistic' test for events (#544)
Browse files Browse the repository at this point in the history
Co-authored-by: Sébastien Crozet <sebastien@crozet.re>
  • Loading branch information
Vrixyz and sebcrozet committed Jul 4, 2024
1 parent 09d6f9d commit 9abe4c3
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 3 deletions.
117 changes: 115 additions & 2 deletions src/pipeline/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@ use rapier::pipeline::EventHandler;
use std::collections::HashMap;
use std::sync::RwLock;

#[cfg(doc)]
use crate::prelude::ActiveEvents;

/// Events occurring when two colliders start or stop colliding
///
/// This will only get triggered if the entity has the
/// [`ActiveEvent::COLLISION_EVENTS`] flag enabled.
/// [`ActiveEvents::COLLISION_EVENTS`] flag enabled.
#[derive(Event, Copy, Clone, Debug, PartialEq, Eq)]
pub enum CollisionEvent {
/// Event occurring when two colliders start colliding
Expand All @@ -25,7 +28,7 @@ pub enum CollisionEvent {
/// between two colliders exceed a threshold ([`ContactForceEventThreshold`]).
///
/// This will only get triggered if the entity has the
/// [`ActiveEvent::CONTACT_FORCE_EVENTS`] flag enabled.
/// [`ActiveEvents::CONTACT_FORCE_EVENTS`] flag enabled.
#[derive(Event, Copy, Clone, Debug, PartialEq)]
pub struct ContactForceEvent {
/// The first collider involved in the contact.
Expand Down Expand Up @@ -119,3 +122,113 @@ impl<'a> EventHandler for EventQueue<'a> {
}
}
}

#[cfg(test)]
mod test {
use bevy::time::{TimePlugin, TimeUpdateStrategy};
use systems::tests::HeadlessRenderPlugin;

use crate::{plugin::*, prelude::*};

#[cfg(feature = "dim3")]
fn cuboid(hx: Real, hy: Real, hz: Real) -> Collider {
Collider::cuboid(hx, hy, hz)
}
#[cfg(feature = "dim2")]
fn cuboid(hx: Real, hy: Real, _hz: Real) -> Collider {
Collider::cuboid(hx, hy)
}

#[test]
pub fn events_received() {
return main();

use bevy::prelude::*;

#[derive(Resource, Reflect)]
pub struct EventsSaver<E: Event> {
pub events: Vec<E>,
}

impl<E: Event> Default for EventsSaver<E> {
fn default() -> Self {
Self {
events: Default::default(),
}
}
}

pub fn save_events<E: Event + Clone>(
mut events: EventReader<E>,
mut saver: ResMut<EventsSaver<E>>,
) {
for event in events.read() {
saver.events.push(event.clone());
}
}

fn run_test(app: &mut App) {
app.add_systems(PostUpdate, save_events::<CollisionEvent>)
.add_systems(PostUpdate, save_events::<ContactForceEvent>)
.init_resource::<EventsSaver<CollisionEvent>>()
.init_resource::<EventsSaver<ContactForceEvent>>();

// Simulates 60 updates per seconds
app.insert_resource(TimeUpdateStrategy::ManualDuration(
std::time::Duration::from_secs_f32(1f32 / 60f32),
));
// 2 seconds should be plenty of time for the cube to fall on the
// lowest collider.
for _ in 0..120 {
app.update();
}
let saved_collisions = app
.world()
.get_resource::<EventsSaver<CollisionEvent>>()
.unwrap();
assert_eq!(saved_collisions.events.len(), 3);
let saved_contact_forces = app
.world()
.get_resource::<EventsSaver<ContactForceEvent>>()
.unwrap();
assert_eq!(saved_contact_forces.events.len(), 1);
}

/// Adapted from events example
fn main() {
let mut app = App::new();
app.add_plugins((
HeadlessRenderPlugin,
TransformPlugin,
TimePlugin,
RapierPhysicsPlugin::<NoUserData>::default(),
))
.add_systems(Startup, setup_physics);
run_test(&mut app);
}

pub fn setup_physics(mut commands: Commands) {
/*
* Ground
*/
commands.spawn((
TransformBundle::from(Transform::from_xyz(0.0, -1.2, 0.0)),
cuboid(4.0, 1.0, 1.0),
));

commands.spawn((
TransformBundle::from(Transform::from_xyz(0.0, 5.0, 0.0)),
cuboid(4.0, 1.5, 1.0),
Sensor,
));

commands.spawn((
TransformBundle::from(Transform::from_xyz(0.0, 13.0, 0.0)),
RigidBody::Dynamic,
cuboid(0.5, 0.5, 0.5),
ActiveEvents::COLLISION_EVENTS | ActiveEvents::CONTACT_FORCE_EVENTS,
ContactForceEventThreshold(30.0),
));
}
}
}
2 changes: 1 addition & 1 deletion src/plugin/systems/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ pub fn step_simulation<Hooks>(
}

#[cfg(test)]
mod tests {
pub mod tests {
use bevy::{
asset::AssetPlugin,
ecs::event::Events,
Expand Down

0 comments on commit 9abe4c3

Please sign in to comment.