Skip to content

Commit 35d535a

Browse files
committed
Replace boxed labels with interned labels
1 parent eb485b1 commit 35d535a

File tree

18 files changed

+644
-142
lines changed

18 files changed

+644
-142
lines changed

crates/bevy_app/src/app.rs

+18-13
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use bevy_ecs::{
44
prelude::*,
55
schedule::{
66
apply_state_transition, common_conditions::run_once as run_once_condition,
7-
run_enter_schedule, BoxedScheduleLabel, IntoSystemConfigs, IntoSystemSetConfigs,
7+
run_enter_schedule, InternedScheduleLabel, IntoSystemConfigs, IntoSystemSetConfigs,
88
ScheduleLabel,
99
},
1010
};
@@ -70,7 +70,7 @@ pub struct App {
7070
/// The schedule that runs the main loop of schedule execution.
7171
///
7272
/// This is initially set to [`Main`].
73-
pub main_schedule_label: BoxedScheduleLabel,
73+
pub main_schedule_label: InternedScheduleLabel,
7474
sub_apps: HashMap<AppLabelId, SubApp>,
7575
plugin_registry: Vec<Box<dyn Plugin>>,
7676
plugin_name_added: HashSet<String>,
@@ -219,7 +219,7 @@ impl App {
219219
sub_apps: HashMap::default(),
220220
plugin_registry: Vec::default(),
221221
plugin_name_added: Default::default(),
222-
main_schedule_label: Box::new(Main),
222+
main_schedule_label: Main.into(),
223223
building_plugin_depth: 0,
224224
}
225225
}
@@ -379,9 +379,10 @@ impl App {
379379
schedule: impl ScheduleLabel,
380380
systems: impl IntoSystemConfigs<M>,
381381
) -> &mut Self {
382+
let schedule: InternedScheduleLabel = (&schedule as &dyn ScheduleLabel).into();
382383
let mut schedules = self.world.resource_mut::<Schedules>();
383384

384-
if let Some(schedule) = schedules.get_mut(&schedule) {
385+
if let Some(schedule) = schedules.get_mut(schedule) {
385386
schedule.add_systems(systems);
386387
} else {
387388
let mut new_schedule = Schedule::new();
@@ -398,8 +399,9 @@ impl App {
398399
schedule: impl ScheduleLabel,
399400
set: impl IntoSystemSetConfig,
400401
) -> &mut Self {
402+
let schedule: InternedScheduleLabel = (&schedule as &dyn ScheduleLabel).into();
401403
let mut schedules = self.world.resource_mut::<Schedules>();
402-
if let Some(schedule) = schedules.get_mut(&schedule) {
404+
if let Some(schedule) = schedules.get_mut(schedule) {
403405
schedule.configure_set(set);
404406
} else {
405407
let mut new_schedule = Schedule::new();
@@ -415,8 +417,9 @@ impl App {
415417
schedule: impl ScheduleLabel,
416418
sets: impl IntoSystemSetConfigs,
417419
) -> &mut Self {
420+
let schedule: InternedScheduleLabel = (&schedule as &dyn ScheduleLabel).into();
418421
let mut schedules = self.world.resource_mut::<Schedules>();
419-
if let Some(schedule) = schedules.get_mut(&schedule) {
422+
if let Some(schedule) = schedules.get_mut(schedule) {
420423
schedule.configure_sets(sets);
421424
} else {
422425
let mut new_schedule = Schedule::new();
@@ -797,7 +800,7 @@ impl App {
797800
/// To avoid this behavior, use the `init_schedule` method instead.
798801
pub fn add_schedule(&mut self, label: impl ScheduleLabel, schedule: Schedule) -> &mut Self {
799802
let mut schedules = self.world.resource_mut::<Schedules>();
800-
schedules.insert(label, schedule);
803+
schedules.insert(&label as &dyn ScheduleLabel, schedule);
801804

802805
self
803806
}
@@ -806,8 +809,9 @@ impl App {
806809
///
807810
/// See [`App::add_schedule`] to pass in a pre-constructed schedule.
808811
pub fn init_schedule(&mut self, label: impl ScheduleLabel) -> &mut Self {
812+
let label: InternedScheduleLabel = (&label as &dyn ScheduleLabel).into();
809813
let mut schedules = self.world.resource_mut::<Schedules>();
810-
if !schedules.contains(&label) {
814+
if !schedules.contains(label) {
811815
schedules.insert(label, Schedule::new());
812816
}
813817
self
@@ -816,15 +820,15 @@ impl App {
816820
/// Gets read-only access to the [`Schedule`] with the provided `label` if it exists.
817821
pub fn get_schedule(&self, label: impl ScheduleLabel) -> Option<&Schedule> {
818822
let schedules = self.world.get_resource::<Schedules>()?;
819-
schedules.get(&label)
823+
schedules.get(&label as &dyn ScheduleLabel)
820824
}
821825

822826
/// Gets read-write access to a [`Schedule`] with the provided `label` if it exists.
823827
pub fn get_schedule_mut(&mut self, label: impl ScheduleLabel) -> Option<&mut Schedule> {
824828
let schedules = self.world.get_resource_mut::<Schedules>()?;
825829
// We need to call .into_inner here to satisfy the borrow checker:
826830
// it can reason about reborrows using ordinary references but not the `Mut` smart pointer.
827-
schedules.into_inner().get_mut(&label)
831+
schedules.into_inner().get_mut(&label as &dyn ScheduleLabel)
828832
}
829833

830834
/// Applies the function to the [`Schedule`] associated with `label`.
@@ -835,13 +839,14 @@ impl App {
835839
label: impl ScheduleLabel,
836840
f: impl FnOnce(&mut Schedule),
837841
) -> &mut Self {
842+
let label: InternedScheduleLabel = (&label as &dyn ScheduleLabel).into();
838843
let mut schedules = self.world.resource_mut::<Schedules>();
839844

840-
if schedules.get(&label).is_none() {
841-
schedules.insert(label.dyn_clone(), Schedule::new());
845+
if schedules.get(label).is_none() {
846+
schedules.insert(label, Schedule::new());
842847
}
843848

844-
let schedule = schedules.get_mut(&label).unwrap();
849+
let schedule = schedules.get_mut(label).unwrap();
845850
// Call the function f, passing in the schedule retrieved
846851
f(schedule);
847852

crates/bevy_ecs/macros/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ mod states;
77

88
use crate::{fetch::derive_world_query_impl, set::derive_set};
99
use bevy_macro_utils::{
10-
derive_boxed_label, ensure_no_collision, get_named_struct_fields, BevyManifest,
10+
derive_interned_label, ensure_no_collision, get_named_struct_fields, BevyManifest,
1111
};
1212
use proc_macro::TokenStream;
1313
use proc_macro2::Span;
@@ -435,7 +435,7 @@ pub fn derive_schedule_label(input: TokenStream) -> TokenStream {
435435
trait_path
436436
.segments
437437
.push(format_ident!("ScheduleLabel").into());
438-
derive_boxed_label(input, &trait_path)
438+
derive_interned_label(input, &trait_path)
439439
}
440440

441441
/// Derive macro generating an impl of the trait `SystemSet`.

crates/bevy_ecs/macros/src/set.rs

+47-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use proc_macro::TokenStream;
2-
use quote::quote;
2+
use quote::{quote, quote_spanned};
3+
use syn::spanned::Spanned;
34

45
/// Derive a set trait
56
///
@@ -21,12 +22,56 @@ pub fn derive_set(input: syn::DeriveInput, trait_path: &syn::Path) -> TokenStrea
2122
})
2223
.unwrap(),
2324
);
24-
25+
let dyn_static_ref_impl = match input.data {
26+
syn::Data::Struct(data) => {
27+
if data.fields.is_empty() {
28+
quote! { std::option::Option::Some(&Self) }
29+
} else {
30+
quote! { std::option::Option::None }
31+
}
32+
}
33+
syn::Data::Enum(data) => {
34+
let mut use_fallback_variant = false;
35+
let variants: Vec<_> = data
36+
.variants
37+
.into_iter()
38+
.filter_map(|variant| {
39+
if variant.fields.is_empty() {
40+
let span = variant.span();
41+
let variant_ident = variant.ident;
42+
Some(quote_spanned! { span => Self::#variant_ident => std::option::Option::Some(&Self::#variant_ident), })
43+
} else {
44+
use_fallback_variant = true;
45+
None
46+
}
47+
})
48+
.collect();
49+
if use_fallback_variant {
50+
quote! {
51+
match self {
52+
#(#variants)*
53+
_ => None
54+
}
55+
}
56+
} else {
57+
quote! {
58+
match self {
59+
#(#variants)*
60+
}
61+
}
62+
}
63+
}
64+
syn::Data::Union(_) => quote! { std::option::Option::None },
65+
};
2566
(quote! {
2667
impl #impl_generics #trait_path for #ident #ty_generics #where_clause {
2768
fn dyn_clone(&self) -> std::boxed::Box<dyn #trait_path> {
2869
std::boxed::Box::new(std::clone::Clone::clone(self))
2970
}
71+
72+
fn dyn_static_ref(&self) -> std::option::Option<&'static dyn #trait_path> {
73+
#dyn_static_ref_impl
74+
}
3075
}
3176
})
3277
.into()

0 commit comments

Comments
 (0)