@@ -13,16 +13,14 @@ use crate::App;
13
13
14
14
/// Methods for converting a schedule into a [sub-Schedule](SubSchedule) descriptor.
15
15
pub trait IntoSubSchedule : Sized {
16
- /// The wrapped schedule type.
17
- type Sched : Stage ;
18
16
/// The type that controls the behaviour of the exclusive system
19
17
/// which runs [`SubSchedule`]s of this type.
20
- type Runner : FnMut ( & mut Self :: Sched , & mut World ) + Send + Sync + ' static ;
18
+ type Runner : FnMut ( & mut dyn Stage , & mut World ) + Send + Sync + ' static ;
21
19
22
20
/// Applies the specified label to the current schedule.
23
21
/// This means it will be accessible in the [`SubSchedules`] resource after
24
22
/// being added to the [`App`].
25
- fn label ( self , label : impl ScheduleLabel ) -> SubSchedule < Self :: Sched , Self :: Runner > {
23
+ fn label ( self , label : impl ScheduleLabel ) -> SubSchedule < Self :: Runner > {
26
24
let mut sub = Self :: into_sched ( self ) ;
27
25
sub. label = Some ( label. as_label ( ) ) ;
28
26
sub
@@ -31,9 +29,9 @@ pub trait IntoSubSchedule: Sized {
31
29
/// an exclusive system within the stage `stage`.
32
30
///
33
31
/// Overwrites any previously set runner or stage.
34
- fn with_runner < F > ( self , stage : impl StageLabel , f : F ) -> SubSchedule < Self :: Sched , F >
32
+ fn with_runner < F > ( self , stage : impl StageLabel , f : F ) -> SubSchedule < F >
35
33
where
36
- F : FnMut ( & mut Self :: Sched , & mut World ) + Send + Sync + ' static ,
34
+ F : FnMut ( & mut dyn Stage , & mut World ) + Send + Sync + ' static ,
37
35
{
38
36
let SubSchedule {
39
37
schedule, label, ..
@@ -46,39 +44,37 @@ pub trait IntoSubSchedule: Sized {
46
44
}
47
45
48
46
/// Performs the conversion. You usually do not need to call this directly.
49
- fn into_sched ( _: Self ) -> SubSchedule < Self :: Sched , Self :: Runner > ;
47
+ fn into_sched ( _: Self ) -> SubSchedule < Self :: Runner > ;
50
48
}
51
49
52
50
impl < S : Stage > IntoSubSchedule for S {
53
- type Sched = Self ;
54
- type Runner = fn ( & mut Self , & mut World ) ;
55
- fn into_sched ( schedule : Self ) -> SubSchedule < Self , Self :: Runner > {
51
+ type Runner = fn ( & mut dyn Stage , & mut World ) ;
52
+ fn into_sched ( schedule : Self ) -> SubSchedule < Self :: Runner > {
56
53
SubSchedule {
57
- schedule,
54
+ schedule : Box :: new ( schedule ) ,
58
55
label : None ,
59
56
runner : None ,
60
57
}
61
58
}
62
59
}
63
60
64
- impl < S : Stage , R > IntoSubSchedule for SubSchedule < S , R >
61
+ impl < R > IntoSubSchedule for SubSchedule < R >
65
62
where
66
- R : FnMut ( & mut S , & mut World ) + Send + Sync + ' static ,
63
+ R : FnMut ( & mut dyn Stage , & mut World ) + Send + Sync + ' static ,
67
64
{
68
- type Sched = S ;
69
65
type Runner = R ;
70
66
#[ inline]
71
- fn into_sched ( sched : Self ) -> SubSchedule < S , R > {
67
+ fn into_sched ( sched : Self ) -> SubSchedule < R > {
72
68
sched
73
69
}
74
70
}
75
71
76
72
/// A schedule that may run independently of the main app schedule.
77
- pub struct SubSchedule < S : Stage , F >
73
+ pub struct SubSchedule < F >
78
74
where
79
- F : FnMut ( & mut S , & mut World ) + Send + Sync + ' static ,
75
+ F : FnMut ( & mut dyn Stage , & mut World ) + Send + Sync + ' static ,
80
76
{
81
- schedule : S ,
77
+ schedule : Box < dyn Stage > ,
82
78
label : Option < ScheduleLabelId > ,
83
79
runner : Option < ( StageLabelId , F ) > ,
84
80
}
@@ -208,7 +204,7 @@ impl SubSchedules {
208
204
}
209
205
210
206
#[ track_caller]
211
- pub ( crate ) fn add_to_app < S : Stage > ( app : & mut App , schedule : impl IntoSubSchedule < Sched = S > ) {
207
+ pub ( crate ) fn add_to_app ( app : & mut App , schedule : impl IntoSubSchedule ) {
212
208
let SubSchedule {
213
209
mut schedule,
214
210
label,
@@ -218,35 +214,12 @@ pub(crate) fn add_to_app<S: Stage>(app: &mut App, schedule: impl IntoSubSchedule
218
214
// If it has a label, insert it to the public resource.
219
215
if let Some ( label) = label {
220
216
let mut res: Mut < SubSchedules > = app. world . get_resource_or_insert_with ( Default :: default) ;
221
- res. insert ( label, Box :: new ( schedule) ) . unwrap ( ) ;
217
+ res. insert ( label, schedule) . unwrap ( ) ;
222
218
223
219
if let Some ( ( stage, mut runner) ) = runner {
224
220
// Driver which extracts the schedule from the world and runs it.
225
221
let driver = move |w : & mut World | {
226
222
SubSchedules :: extract_scope ( w, label, |w, sched| {
227
- let sched = if let Some ( s) = sched. downcast_mut :: < S > ( ) {
228
- s
229
- } else {
230
- #[ cfg( debug_assertions) ]
231
- unreachable ! (
232
- r#"
233
- The sub-schedule '{label:?}' changed types after being inserted:
234
- it should be of type `{expect}`, but it's really of type `{actual}`.
235
- This should be impossible.
236
- If you run into this error, please file an issue at https://github.com/bevyengine/bevy/issues/new/choose"# ,
237
- expect = std:: any:: type_name:: <S >( ) ,
238
- actual = AnyTypeName :: name( sched) ,
239
- ) ;
240
- // SAFETY: Due to the invariant on `SubSchedules`, we can be sure that
241
- // `sched` is the same instance that we inserted.
242
- // Thus, we can rely on its type matching `S`.
243
- //
244
- // FIXME: this is unsound
245
- #[ cfg( not( debug_assertions) ) ]
246
- unsafe {
247
- std:: hint:: unreachable_unchecked ( )
248
- }
249
- } ;
250
223
runner ( sched, w) ;
251
224
} )
252
225
. unwrap ( ) ;
@@ -257,7 +230,7 @@ pub(crate) fn add_to_app<S: Stage>(app: &mut App, schedule: impl IntoSubSchedule
257
230
// If there's no label, then the schedule isn't visible publicly.
258
231
// We can just store it locally
259
232
let driver = move |w : & mut World | {
260
- runner ( & mut schedule, w) ;
233
+ runner ( schedule. as_mut ( ) , w) ;
261
234
} ;
262
235
app. add_system_to_stage ( stage, driver. exclusive_system ( ) ) ;
263
236
} else {
0 commit comments