Skip to content

Commit 07c7b1c

Browse files
committed
use a reference to shrink the stack size
1 parent af4f557 commit 07c7b1c

File tree

1 file changed

+26
-7
lines changed

1 file changed

+26
-7
lines changed

crates/bevy_utils/src/label.rs

+26-7
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,13 @@ pub trait LabelDowncast<Id> {
5656
fn downcast_from(data: u64) -> Option<Self::Output>;
5757
}
5858

59+
#[doc(hidden)]
60+
pub struct VTable {
61+
// FIXME: When const TypeId stabilizes, inline the type instead of using a fn pointer for indirection.
62+
pub ty: fn() -> ::std::any::TypeId,
63+
pub fmt: fn(u64, &mut ::std::fmt::Formatter) -> ::std::fmt::Result,
64+
}
65+
5966
/// Macro to define a new label trait
6067
///
6168
/// # Example
@@ -81,25 +88,30 @@ macro_rules! define_label {
8188
$(#[$id_attr])*
8289
#[derive(Clone, Copy)]
8390
pub struct $id_name {
84-
ty: ::std::any::TypeId,
8591
data: u64,
86-
f: fn(u64, &mut ::std::fmt::Formatter) -> ::std::fmt::Result,
92+
vtable: &'static $crate::label::VTable,
8793
}
8894

8995
impl ::std::fmt::Debug for $id_name {
9096
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
9197
let data = self.data();
92-
(self.f)(data, f)
98+
(self.vtable.fmt)(data, f)
9399
}
94100
}
95101

96102
$(#[$label_attr])*
97103
pub trait $label_name: 'static {
104+
/// Essentially acts like a dynamic dispatch virtual table,
105+
/// but specialized for labels.
106+
const VTABLE : $crate::label::VTable = $crate::label::VTable {
107+
ty: || ::std::any::TypeId::of::<Self>(),
108+
fmt: Self::fmt,
109+
};
98110
/// Converts this type into an opaque, strongly-typed label.
99111
#[inline]
100112
fn as_label(&self) -> $id_name {
101113
let data = self.data();
102-
$id_name { data, ty: ::std::any::TypeId::of::<Self>(), f: Self::fmt }
114+
$id_name { data, vtable: &Self::VTABLE }
103115
}
104116
/// Returns a number used to distinguish different labels of the same type.
105117
fn data(&self) -> u64;
@@ -129,23 +141,30 @@ macro_rules! define_label {
129141
impl PartialEq for $id_name {
130142
#[inline]
131143
fn eq(&self, rhs: &Self) -> bool {
132-
self.ty == rhs.ty && self.data() == rhs.data()
144+
self.data() == rhs.data() && self.type_id() == rhs.type_id()
133145
}
134146
}
135147
impl Eq for $id_name {}
136148

137149

138150
impl std::hash::Hash for $id_name {
139151
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
140-
self.ty.hash(state);
152+
self.type_id().hash(state);
141153
self.data().hash(state);
142154
}
143155
}
144156

145157
impl $id_name {
158+
/// Returns the [`TypeId`] of the label from which this ID was constructed.
159+
///
160+
/// [`TypeId`]: ::std::any::TypeId
161+
#[inline]
162+
pub fn type_id(self) -> ::std::any::TypeId {
163+
(self.vtable.ty)()
164+
}
146165
/// Returns true if this label was constructed from an instance of type `L`.
147166
pub fn is<L: $label_name>(self) -> bool {
148-
self.ty == ::std::any::TypeId::of::<L>()
167+
self.type_id() == ::std::any::TypeId::of::<L>()
149168
}
150169
/// Attempts to downcast this label to type `L`.
151170
///

0 commit comments

Comments
 (0)