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