Skip to content

Commit f584e12

Browse files
committed
use a reference to shrink the stack size
1 parent 239f8dc commit f584e12

File tree

1 file changed

+25
-7
lines changed

1 file changed

+25
-7
lines changed

crates/bevy_utils/src/label.rs

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

59+
#[doc(hidden)]
60+
pub struct VTable {
61+
pub ty: fn() -> ::std::any::TypeId,
62+
pub fmt: fn(u64, &mut ::std::fmt::Formatter) -> ::std::fmt::Result,
63+
}
64+
5965
/// Macro to define a new label trait
6066
///
6167
/// # Example
@@ -81,25 +87,30 @@ macro_rules! define_label {
8187
$(#[$id_attr])*
8288
#[derive(Clone, Copy)]
8389
pub struct $id_name {
84-
ty: ::std::any::TypeId,
8590
data: u64,
86-
f: fn(u64, &mut ::std::fmt::Formatter) -> ::std::fmt::Result,
91+
vtable: &'static $crate::label::VTable,
8792
}
8893

8994
impl ::std::fmt::Debug for $id_name {
9095
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
9196
let data = self.data();
92-
(self.f)(data, f)
97+
(self.vtable.fmt)(data, f)
9398
}
9499
}
95100

96101
$(#[$label_attr])*
97102
pub trait $label_name: 'static {
103+
/// Essentially acts like a dynamic dispatch virtual table,
104+
/// but specialized for labels.
105+
const VTABLE : $crate::label::VTable = $crate::label::VTable {
106+
ty: || ::std::any::TypeId::of::<Self>(),
107+
fmt: Self::fmt,
108+
};
98109
/// Converts this type into an opaque, strongly-typed label.
99110
#[inline]
100111
fn as_label(&self) -> $id_name {
101112
let data = self.data();
102-
$id_name { data, ty: ::std::any::TypeId::of::<Self>(), f: Self::fmt }
113+
$id_name { data, vtable: &Self::VTABLE }
103114
}
104115
/// Returns a number used to distinguish different labels of the same type.
105116
fn data(&self) -> u64;
@@ -129,23 +140,30 @@ macro_rules! define_label {
129140
impl PartialEq for $id_name {
130141
#[inline]
131142
fn eq(&self, rhs: &Self) -> bool {
132-
self.ty == rhs.ty && self.data() == rhs.data()
143+
self.data() == rhs.data() && self.type_id() == rhs.type_id()
133144
}
134145
}
135146
impl Eq for $id_name {}
136147

137148

138149
impl std::hash::Hash for $id_name {
139150
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
140-
self.ty.hash(state);
151+
self.type_id().hash(state);
141152
self.data().hash(state);
142153
}
143154
}
144155

145156
impl $id_name {
157+
/// Returns the [`TypeId`] of the label from which this ID was constructed.
158+
///
159+
/// [`TypeId`]: ::std::any::TypeId
160+
#[inline]
161+
pub fn type_id(self) -> ::std::any::TypeId {
162+
(self.vtable.ty)()
163+
}
146164
/// Returns true if this label was constructed from an instance of type `L`.
147165
pub fn is<L: $label_name>(self) -> bool {
148-
self.ty == ::std::any::TypeId::of::<L>()
166+
self.type_id() == ::std::any::TypeId::of::<L>()
149167
}
150168
/// Attempts to downcast this label to type `L`.
151169
///

0 commit comments

Comments
 (0)