@@ -25,7 +25,7 @@ pub mod prelude {
2525}
2626
2727use bevy_app:: { prelude:: * , RunFixedMainLoop } ;
28- use bevy_ecs:: event:: { event_queue_update_system , EventUpdateSignal } ;
28+ use bevy_ecs:: event:: { signal_event_update_system , EventUpdateSignal , EventUpdates } ;
2929use bevy_ecs:: prelude:: * ;
3030use bevy_utils:: { tracing:: warn, Duration , Instant } ;
3131pub use crossbeam_channel:: TrySendError ;
@@ -61,7 +61,11 @@ impl Plugin for TimePlugin {
6161
6262 // ensure the events are not dropped until `FixedMain` systems can observe them
6363 app. init_resource :: < EventUpdateSignal > ( )
64- . add_systems ( FixedPostUpdate , event_queue_update_system) ;
64+ . add_systems ( FixedPostUpdate , signal_event_update_system)
65+ . add_systems (
66+ First ,
67+ bevy_ecs:: event:: reset_event_update_signal_system. after ( EventUpdates ) ,
68+ ) ;
6569
6670 #[ cfg( feature = "bevy_ci_testing" ) ]
6771 if let Some ( ci_testing_config) = app
@@ -142,3 +146,66 @@ fn time_system(
142146 TimeUpdateStrategy :: ManualDuration ( duration) => time. update_with_duration ( * duration) ,
143147 }
144148}
149+
150+ #[ cfg( test) ]
151+ mod tests {
152+ use crate :: { Fixed , Time , TimePlugin , TimeUpdateStrategy } ;
153+ use bevy_app:: { App , Startup , Update } ;
154+ use bevy_ecs:: event:: { Event , EventReader , EventWriter } ;
155+ use std:: error:: Error ;
156+ use std:: time:: Duration ;
157+
158+ #[ derive( Event ) ]
159+ struct TestEvent < T : Default > {
160+ sender : std:: sync:: mpsc:: Sender < T > ,
161+ }
162+
163+ impl < T : Default > Drop for TestEvent < T > {
164+ fn drop ( & mut self ) {
165+ self . sender
166+ . send ( T :: default ( ) )
167+ . expect ( "Failed to send drop signal" ) ;
168+ }
169+ }
170+
171+ #[ test]
172+ fn events_get_dropped_regression_test_11528 ( ) -> Result < ( ) , impl Error > {
173+ let ( tx1, rx1) = std:: sync:: mpsc:: channel ( ) ;
174+ let ( tx2, rx2) = std:: sync:: mpsc:: channel ( ) ;
175+ let mut app = App :: new ( ) ;
176+ app. add_plugins ( TimePlugin )
177+ . add_event :: < TestEvent < i32 > > ( )
178+ . add_event :: < TestEvent < ( ) > > ( )
179+ . add_systems ( Startup , move |mut ev2 : EventWriter < TestEvent < ( ) > > | {
180+ ev2. send ( TestEvent {
181+ sender : tx2. clone ( ) ,
182+ } ) ;
183+ } )
184+ . add_systems ( Update , move |mut ev1 : EventWriter < TestEvent < i32 > > | {
185+ // Keep adding events so this event type is processed every update
186+ ev1. send ( TestEvent {
187+ sender : tx1. clone ( ) ,
188+ } ) ;
189+ } )
190+ . add_systems (
191+ Update ,
192+ |mut ev1 : EventReader < TestEvent < i32 > > , mut ev2 : EventReader < TestEvent < ( ) > > | {
193+ // Read events so they can be dropped
194+ for _ in ev1. read ( ) { }
195+ for _ in ev2. read ( ) { }
196+ } ,
197+ )
198+ . insert_resource ( TimeUpdateStrategy :: ManualDuration (
199+ Time :: < Fixed > :: default ( ) . timestep ( ) ,
200+ ) ) ;
201+
202+ for _ in 0 ..10 {
203+ app. update ( ) ;
204+ }
205+
206+ // Check event type 1 as been dropped at least once
207+ let _drop_signal = rx1. recv_timeout ( Duration :: from_millis ( 1000 ) ) ;
208+ // Check event type 2 has been dropped
209+ rx2. recv_timeout ( Duration :: from_millis ( 1000 ) )
210+ }
211+ }
0 commit comments