@@ -119,3 +119,112 @@ impl<'a> EventHandler for EventQueue<'a> {
119119 }
120120 }
121121}
122+
123+ #[ cfg( test) ]
124+ mod test {
125+ use bevy:: time:: TimePlugin ;
126+ use systems:: tests:: HeadlessRenderPlugin ;
127+
128+ use crate :: { plugin:: * , prelude:: * } ;
129+
130+ #[ cfg( feature = "dim3" ) ]
131+ fn cuboid ( hx : Real , hy : Real , hz : Real ) -> Collider {
132+ Collider :: cuboid ( hx, hy, hz)
133+ }
134+ #[ cfg( feature = "dim2" ) ]
135+ fn cuboid ( hx : Real , hy : Real , _hz : Real ) -> Collider {
136+ Collider :: cuboid ( hx, hy)
137+ }
138+
139+ #[ test]
140+ pub fn events_received ( ) {
141+ return main ( ) ;
142+
143+ use bevy:: prelude:: * ;
144+
145+ #[ derive( Resource , Reflect ) ]
146+ pub struct EventsSaver < E : Event > {
147+ pub events : Vec < E > ,
148+ }
149+ impl < E : Event > Default for EventsSaver < E > {
150+ fn default ( ) -> Self {
151+ Self {
152+ events : Default :: default ( ) ,
153+ }
154+ }
155+ }
156+ pub fn save_events < E : Event + Clone > (
157+ mut events : EventReader < E > ,
158+ mut saver : ResMut < EventsSaver < E > > ,
159+ ) {
160+ for event in events. read ( ) {
161+ saver. events . push ( event. clone ( ) ) ;
162+ }
163+ }
164+ fn run_test ( app : & mut App ) {
165+ app. add_systems ( PostUpdate , save_events :: < CollisionEvent > )
166+ . add_systems ( PostUpdate , save_events :: < ContactForceEvent > )
167+ . init_resource :: < EventsSaver < CollisionEvent > > ( )
168+ . init_resource :: < EventsSaver < ContactForceEvent > > ( ) ;
169+ // while app.plugins_state() == bevy::app::PluginsState::Adding {
170+ // #[cfg(not(target_arch = "wasm32"))]
171+ // bevy::tasks::tick_global_task_pools_on_main_thread();
172+ // }
173+ // app.finish();
174+ // app.cleanup();
175+ let mut time = app. world_mut ( ) . get_resource_mut :: < Time < Virtual > > ( ) . unwrap ( ) ;
176+ time. set_relative_speed ( 1000f32 ) ;
177+ for _ in 0 ..300 {
178+ // FIXME: advance by set durations to avoid being at the mercy of the CPU.
179+ app. update ( ) ;
180+ }
181+ let saved_collisions = app
182+ . world ( )
183+ . get_resource :: < EventsSaver < CollisionEvent > > ( )
184+ . unwrap ( ) ;
185+ assert ! ( saved_collisions. events. len( ) > 0 ) ;
186+ let saved_contact_forces = app
187+ . world ( )
188+ . get_resource :: < EventsSaver < CollisionEvent > > ( )
189+ . unwrap ( ) ;
190+ assert ! ( saved_contact_forces. events. len( ) > 0 ) ;
191+ }
192+
193+ /// Adapted from events example
194+ fn main ( ) {
195+ let mut app = App :: new ( ) ;
196+ app. add_plugins ( (
197+ HeadlessRenderPlugin ,
198+ TransformPlugin ,
199+ TimePlugin ,
200+ RapierPhysicsPlugin :: < NoUserData > :: default ( ) ,
201+ ) )
202+ . add_systems ( Startup , setup_physics) ;
203+ run_test ( & mut app) ;
204+ }
205+
206+ pub fn setup_physics ( mut commands : Commands ) {
207+ /*
208+ * Ground
209+ */
210+ commands. spawn ( (
211+ TransformBundle :: from ( Transform :: from_xyz ( 0.0 , -1.2 , 0.0 ) ) ,
212+ cuboid ( 4.0 , 1.0 , 1.0 ) ,
213+ ) ) ;
214+
215+ commands. spawn ( (
216+ TransformBundle :: from ( Transform :: from_xyz ( 0.0 , 5.0 , 0.0 ) ) ,
217+ cuboid ( 4.0 , 1.5 , 1.0 ) ,
218+ Sensor ,
219+ ) ) ;
220+
221+ commands. spawn ( (
222+ TransformBundle :: from ( Transform :: from_xyz ( 0.0 , 13.0 , 0.0 ) ) ,
223+ RigidBody :: Dynamic ,
224+ cuboid ( 0.5 , 0.5 , 0.5 ) ,
225+ ActiveEvents :: COLLISION_EVENTS ,
226+ ContactForceEventThreshold ( 30.0 ) ,
227+ ) ) ;
228+ }
229+ }
230+ }
0 commit comments