Skip to content

Commit a88293c

Browse files
committed
make the design less confusing
1 parent 1a1dae6 commit a88293c

File tree

6 files changed

+54
-56
lines changed

6 files changed

+54
-56
lines changed

benches/benches/bevy_ecs/scheduling/schedule.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,8 @@ pub fn build_schedule(criterion: &mut Criterion) {
7373
fn data(&self) -> u64 {
7474
self.0
7575
}
76-
#[inline]
77-
fn dbg(&self) -> fn(u64, &mut std::fmt::Formatter) -> std::fmt::Result {
78-
|x, f| write!(f, "NumLabel({x})")
76+
fn fmt(data: u64, f: &mut std::fmt::Formatter) -> std::fmt::Result {
77+
f.debug_tuple("NumLabel").field(&data).finish()
7978
}
8079
}
8180

crates/bevy_ecs/src/schedule/mod.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -211,9 +211,10 @@ impl Schedule {
211211
)
212212
}
213213

214+
let stage_label = stage_label.as_label();
214215
let stage = self
215-
.get_stage_mut::<SystemStage>(&stage_label)
216-
.unwrap_or_else(move || stage_not_found(&stage_label.as_label()));
216+
.get_stage_mut::<SystemStage>(stage_label)
217+
.unwrap_or_else(move || stage_not_found(&stage_label));
217218
stage.add_system(system);
218219
self
219220
}
@@ -281,11 +282,9 @@ impl Schedule {
281282
label: impl StageLabel,
282283
func: F,
283284
) -> &mut Self {
284-
let stage = self.get_stage_mut::<T>(&label).unwrap_or_else(move || {
285-
panic!(
286-
"stage '{:?}' does not exist or is the wrong type",
287-
label.as_label()
288-
)
285+
let label = label.as_label();
286+
let stage = self.get_stage_mut::<T>(label).unwrap_or_else(move || {
287+
panic!("stage '{:?}' does not exist or is the wrong type", label)
289288
});
290289
func(stage);
291290
self
@@ -306,7 +305,7 @@ impl Schedule {
306305
/// #
307306
/// let stage = schedule.get_stage::<SystemStage>(&"my_stage").unwrap();
308307
/// ```
309-
pub fn get_stage<T: Stage>(&self, label: &dyn StageLabel) -> Option<&T> {
308+
pub fn get_stage<T: Stage>(&self, label: StageLabelId) -> Option<&T> {
310309
self.stages
311310
.get(&label.as_label())
312311
.and_then(|stage| stage.downcast_ref::<T>())
@@ -327,7 +326,7 @@ impl Schedule {
327326
/// #
328327
/// let stage = schedule.get_stage_mut::<SystemStage>(&"my_stage").unwrap();
329328
/// ```
330-
pub fn get_stage_mut<T: Stage>(&mut self, label: &dyn StageLabel) -> Option<&mut T> {
329+
pub fn get_stage_mut<T: Stage>(&mut self, label: StageLabelId) -> Option<&mut T> {
331330
self.stages
332331
.get_mut(&label.as_label())
333332
.and_then(|stage| stage.downcast_mut::<T>())

crates/bevy_ecs/src/schedule/state.rs

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ use crate::{
66
system::{In, IntoChainSystem, Local, Res, ResMut},
77
};
88
use std::{
9-
any::TypeId,
109
fmt::{self, Debug},
1110
hash::Hash,
11+
marker::PhantomData,
1212
};
1313

1414
pub trait StateData: Send + Sync + Clone + Eq + Debug + Hash + 'static {}
@@ -52,28 +52,23 @@ enum ScheduledOperation<T: StateData> {
5252
Push(T),
5353
}
5454

55-
struct DriverLabel(
56-
TypeId,
57-
fn(u64, &mut std::fmt::Formatter) -> std::fmt::Result,
58-
);
59-
impl RunCriteriaLabel for DriverLabel {
60-
fn type_id(&self) -> core::any::TypeId {
61-
self.0
55+
struct DriverLabel<T: StateData>(PhantomData<fn() -> T>);
56+
impl<T: StateData> RunCriteriaLabel for DriverLabel<T> {
57+
#[inline]
58+
fn type_id(&self) -> std::any::TypeId {
59+
std::any::TypeId::of::<T>()
6260
}
61+
#[inline]
6362
fn data(&self) -> u64 {
6463
0
6564
}
66-
fn dbg(&self) -> fn(u64, &mut std::fmt::Formatter) -> std::fmt::Result {
67-
self.1
65+
fn fmt(data: u64, f: &mut std::fmt::Formatter) -> std::fmt::Result {
66+
write!(f, "{}", std::any::type_name::<T>())
6867
}
6968
}
7069

71-
impl DriverLabel {
72-
fn of<T: 'static>() -> Self {
73-
Self(TypeId::of::<T>(), |_, f| {
74-
write!(f, "{}", std::any::type_name::<T>())
75-
})
76-
}
70+
fn driver_label<T: StateData>() -> DriverLabel<T> {
71+
DriverLabel(PhantomData)
7772
}
7873

7974
impl<T> State<T>
@@ -85,7 +80,7 @@ where
8580
state.stack.last().unwrap() == &pred && state.transition.is_none()
8681
})
8782
.chain(should_run_adapter::<T>)
88-
.after(DriverLabel::of::<T>())
83+
.after(driver_label::<T>())
8984
}
9085

9186
pub fn on_inactive_update(pred: T) -> RunCriteriaDescriptor {
@@ -101,7 +96,7 @@ where
10196
None => *is_inactive,
10297
})
10398
.chain(should_run_adapter::<T>)
104-
.after(DriverLabel::of::<T>())
99+
.after(driver_label::<T>())
105100
}
106101

107102
pub fn on_in_stack_update(pred: T) -> RunCriteriaDescriptor {
@@ -124,7 +119,7 @@ where
124119
None => *is_in_stack,
125120
})
126121
.chain(should_run_adapter::<T>)
127-
.after(DriverLabel::of::<T>())
122+
.after(driver_label::<T>())
128123
}
129124

130125
pub fn on_enter(pred: T) -> RunCriteriaDescriptor {
@@ -139,7 +134,7 @@ where
139134
})
140135
})
141136
.chain(should_run_adapter::<T>)
142-
.after(DriverLabel::of::<T>())
137+
.after(driver_label::<T>())
143138
}
144139

145140
pub fn on_exit(pred: T) -> RunCriteriaDescriptor {
@@ -154,7 +149,7 @@ where
154149
})
155150
})
156151
.chain(should_run_adapter::<T>)
157-
.after(DriverLabel::of::<T>())
152+
.after(driver_label::<T>())
158153
}
159154

160155
pub fn on_pause(pred: T) -> RunCriteriaDescriptor {
@@ -168,7 +163,7 @@ where
168163
})
169164
})
170165
.chain(should_run_adapter::<T>)
171-
.after(DriverLabel::of::<T>())
166+
.after(driver_label::<T>())
172167
}
173168

174169
pub fn on_resume(pred: T) -> RunCriteriaDescriptor {
@@ -182,7 +177,7 @@ where
182177
})
183178
})
184179
.chain(should_run_adapter::<T>)
185-
.after(DriverLabel::of::<T>())
180+
.after(driver_label::<T>())
186181
}
187182

188183
pub fn on_update_set(s: T) -> SystemSet {
@@ -214,7 +209,7 @@ where
214209
/// Important note: this set must be inserted **before** all other state-dependant sets to work
215210
/// properly!
216211
pub fn get_driver() -> SystemSet {
217-
SystemSet::default().with_run_criteria(state_cleaner::<T>.label(DriverLabel::of::<T>()))
212+
SystemSet::default().with_run_criteria(state_cleaner::<T>.label(driver_label::<T>()))
218213
}
219214

220215
pub fn new(initial: T) -> Self {

crates/bevy_ecs/src/system/function_system.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -461,9 +461,8 @@ impl<T: 'static> SystemLabel for SystemTypeIdLabel<T> {
461461
fn data(&self) -> u64 {
462462
0
463463
}
464-
#[inline]
465-
fn dbg(&self) -> fn(u64, &mut fmt::Formatter) -> fmt::Result {
466-
|_, f| write!(f, "{}", std::any::type_name::<T>())
464+
fn fmt(_: u64, f: &mut std::fmt::Formatter) -> std::fmt::Result {
465+
write!(f, "{}", std::any::type_name::<T>())
467466
}
468467
}
469468

crates/bevy_macro_utils/src/lib.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ pub fn derive_label(
141141
.predicates
142142
.push(syn::parse2(quote! { Self: 'static }).unwrap());
143143

144-
let (data, as_str) = match input.data {
144+
let (data, fmt) = match input.data {
145145
syn::Data::Struct(d) => {
146146
// see if the user tried to ignore fields incorrectly
147147
if let Some(attr) = d
@@ -161,7 +161,7 @@ pub fn derive_label(
161161
if matches!(d.fields, syn::Fields::Unit) || ignore_fields {
162162
let lit = ident.to_string();
163163
let data = quote! { 0 };
164-
let as_str = quote! { |_, f| write!(f, #lit) };
164+
let as_str = quote! { write!(f, #lit) };
165165
(data, as_str)
166166
} else {
167167
let err_msg = format!("Labels cannot contain data, unless explicitly ignored with `#[{attr_name}(ignore_fields)]`");
@@ -182,7 +182,7 @@ pub fn derive_label(
182182
}
183183

184184
let mut data_arms = Vec::with_capacity(d.variants.len());
185-
let mut str_arms = Vec::with_capacity(d.variants.len());
185+
let mut fmt_arms = Vec::with_capacity(d.variants.len());
186186

187187
for (i, v) in d.variants.iter().enumerate() {
188188
// Variants must either be fieldless, or explicitly ignore the fields.
@@ -195,7 +195,7 @@ pub fn derive_label(
195195
data_arms.push(quote! { #path { .. } => #i });
196196

197197
let lit = format!("{ident}::{}", v.ident.clone());
198-
str_arms.push(quote! { #path { .. } => { |_, f| write!(f, #lit) } });
198+
fmt_arms.push(quote! { #i => { write!(f, #lit) } });
199199
} else {
200200
let err_msg = format!("Label variants cannot contain data, unless explicitly ignored with `#[{attr_name}(ignore_fields)]`");
201201
return quote_spanned! {
@@ -210,12 +210,13 @@ pub fn derive_label(
210210
#(#data_arms),*
211211
}
212212
};
213-
let as_str = quote! {
214-
match self {
215-
#(#str_arms),*
213+
let fmt = quote! {
214+
match data {
215+
#(#fmt_arms),*
216+
_ => ::std::unreachable!(),
216217
}
217218
};
218-
(data, as_str)
219+
(data, fmt)
219220
}
220221
syn::Data::Union(_) => {
221222
return quote_spanned! {
@@ -231,8 +232,8 @@ pub fn derive_label(
231232
fn data(&self) -> u64 {
232233
#data
233234
}
234-
fn dbg(&self) -> fn(u64, &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
235-
#as_str
235+
fn fmt(data: u64, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
236+
#fmt
236237
}
237238
}
238239
})

crates/bevy_utils/src/label.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,18 +76,18 @@ macro_rules! define_label {
7676
impl ::std::fmt::Debug for $id_name {
7777
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
7878
let data = self.data();
79-
self.dbg()(data, f)
79+
self.2(data, f)
8080
}
8181
}
8282

8383
$(#[$label_attr])*
8484
pub trait $label_name: 'static {
8585
/// Converts this type into an opaque, strongly-typed label.
86+
#[inline]
8687
fn as_label(&self) -> $id_name {
8788
let ty = self.type_id();
8889
let data = self.data();
89-
let dbg = self.dbg();
90-
$id_name(ty, data, dbg)
90+
$id_name(ty, data, Self::fmt)
9191
}
9292
/// Returns the [`TypeId`] used to differentiate labels.
9393
#[inline]
@@ -96,7 +96,12 @@ macro_rules! define_label {
9696
}
9797
/// Returns a number used to distinguish different labels of the same type.
9898
fn data(&self) -> u64;
99-
fn dbg(&self) -> fn(u64, &mut ::std::fmt::Formatter) -> ::std::fmt::Result;
99+
/// Writes debug info for a label of the current type.
100+
/// * `data`: the result of calling [`data()`](#method.data) on an instance of this type.
101+
///
102+
/// You should not call this method directly, as it may panic for some types;
103+
/// use [`as_label`](#method.as_label) instead.
104+
fn fmt(data: u64, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result;
100105
}
101106

102107
impl $label_name for $id_name {
@@ -112,9 +117,9 @@ macro_rules! define_label {
112117
fn data(&self) -> u64 {
113118
self.1
114119
}
115-
#[inline]
116-
fn dbg(&self) -> fn(u64, &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
117-
self.2
120+
#[track_caller]
121+
fn fmt(data: u64, f: &mut ::std::fmt::Formatter) -> std::fmt::Result {
122+
::std::unimplemented!("do not call `Label::fmt` directly -- use the result of `as_label()` for formatting instead")
118123
}
119124
}
120125

0 commit comments

Comments
 (0)