-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
[Merged by Bors] - Auto-label function systems with SystemTypeIdLabel #4224
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
e8a5c6a
649987b
76ca7f6
a964e8e
ca7c674
c39276e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,14 +2,15 @@ use crate::{ | |
archetype::{Archetype, ArchetypeComponentId, ArchetypeGeneration, ArchetypeId}, | ||
component::ComponentId, | ||
query::{Access, FilteredAccessSet}, | ||
schedule::SystemLabel, | ||
system::{ | ||
check_system_change_tick, ReadOnlySystemParamFetch, System, SystemParam, SystemParamFetch, | ||
SystemParamState, | ||
}, | ||
world::{World, WorldId}, | ||
}; | ||
use bevy_ecs_macros::all_tuples; | ||
use std::{borrow::Cow, marker::PhantomData}; | ||
use std::{borrow::Cow, fmt::Debug, hash::Hash, marker::PhantomData}; | ||
|
||
/// The metadata of a [`System`]. | ||
pub struct SystemMeta { | ||
|
@@ -421,6 +422,47 @@ where | |
self.system_meta.name.as_ref(), | ||
); | ||
} | ||
fn default_labels(&self) -> Vec<Box<dyn SystemLabel>> { | ||
vec![Box::new(self.func.as_system_label())] | ||
} | ||
} | ||
|
||
/// A [`SystemLabel`] that was automatically generated for a system on the basis of its `TypeId`. | ||
pub struct SystemTypeIdLabel<T: 'static>(PhantomData<fn() -> T>); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This couldn't be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Interesting. This would enable people to construct these labels without an instance to a system type. Maybe thats good. Is there a use case? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This could be useful if you wanted to initialize an array of these things, especially if we also impl'd Copy. I'm not immediately sure why you'd want to do that though. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Haha I'm impatient, so I'm just going to merge this now. I'm happy to add this if we decide its needed. |
||
|
||
impl<T> Debug for SystemTypeIdLabel<T> { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
f.debug_tuple("SystemTypeIdLabel") | ||
.field(&std::any::type_name::<T>()) | ||
.finish() | ||
} | ||
} | ||
impl<T> Hash for SystemTypeIdLabel<T> { | ||
fn hash<H: std::hash::Hasher>(&self, _state: &mut H) { | ||
// All SystemTypeIds of a given type are the same. | ||
} | ||
} | ||
impl<T> Clone for SystemTypeIdLabel<T> { | ||
fn clone(&self) -> Self { | ||
Self(PhantomData) | ||
} | ||
} | ||
|
||
impl<T> Copy for SystemTypeIdLabel<T> {} | ||
|
||
impl<T> PartialEq for SystemTypeIdLabel<T> { | ||
#[inline] | ||
fn eq(&self, _other: &Self) -> bool { | ||
// All labels of a given type are equal, as they will all have the same type id | ||
true | ||
} | ||
} | ||
impl<T> Eq for SystemTypeIdLabel<T> {} | ||
|
||
impl<T> SystemLabel for SystemTypeIdLabel<T> { | ||
fn dyn_clone(&self) -> Box<dyn SystemLabel> { | ||
Box::new(*self) | ||
} | ||
} | ||
|
||
/// A trait implemented for all functions that can be used as [`System`]s. | ||
|
@@ -489,3 +531,28 @@ macro_rules! impl_system_function { | |
} | ||
|
||
all_tuples!(impl_system_function, 0, 16, F); | ||
|
||
/// Used to implicitly convert systems to their default labels. For example, it will convert | ||
/// "system functions" to their [`SystemTypeIdLabel`]. | ||
pub trait AsSystemLabel<Marker> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add a short doc comment stating this is used for system -> SystemLabel coercion plus a pointer to SystemLabel which illustrates the ergonomics. It'd also stave off the perpetually missing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good call! |
||
type SystemLabel: SystemLabel; | ||
fn as_system_label(&self) -> Self::SystemLabel; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll record that I'm still not super happy with this being a method, but I don't think that's changing. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah I'm not (yet) convinced. I think there are good reasons to make "manually retrieving the label from a system instance" a part of our api. We don't abstract out "other" labels and we let those instances float around. Why abstract out these? |
||
} | ||
|
||
impl<In, Out, Param: SystemParam, Marker, T: SystemParamFunction<In, Out, Param, Marker>> | ||
AsSystemLabel<(In, Out, Param, Marker)> for T | ||
{ | ||
type SystemLabel = SystemTypeIdLabel<Self>; | ||
|
||
fn as_system_label(&self) -> Self::SystemLabel { | ||
SystemTypeIdLabel(PhantomData::<fn() -> Self>) | ||
} | ||
} | ||
|
||
impl<T: SystemLabel + Clone> AsSystemLabel<()> for T { | ||
type SystemLabel = T; | ||
|
||
fn as_system_label(&self) -> Self::SystemLabel { | ||
self.clone() | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.