Better SystemId to Entity conversions (#13090)

# Objective

- Better `SystemId` <-> `Entity` conversion.

## Solution

- Provide a method `SystemId::from_entity` to create a `SystemId<I, O>`
form an `Entity`. When users want to deal with the entities manually
they need a way to convert the `Entity` back to a `SystemId` to actually
run the system with `Commands` or `World`.
- Provide a method `SystemId::entity` that returns an `Entity` from
`SystemId`. The current `From` impl is not very discoverable as it does
not appear on the `SystemId` doc page.
- Remove old `From` impl.

## Migration Guide

```rust
let system_id = world.register_system(my_sys);

// old
let entity = Entity::from(system_id);

// new
let entity = system_id.entity();
```

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
This commit is contained in:
iiYese 2024-04-25 19:47:49 +01:00 committed by GitHub
parent a1adba19a9
commit 5b899b48f5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 24 additions and 16 deletions

View File

@ -581,10 +581,7 @@ impl<'w, 's> Commands<'w, 's> {
) -> SystemId<I, O> {
let entity = self.spawn_empty().id();
self.queue.push(RegisterSystem::new(system, entity));
SystemId {
entity,
marker: std::marker::PhantomData,
}
SystemId::from_entity(entity)
}
/// Pushes a generic [`Command`] to the command queue.

View File

@ -43,6 +43,29 @@ pub struct SystemId<I = (), O = ()> {
pub(crate) marker: std::marker::PhantomData<fn(I) -> O>,
}
impl<I, O> SystemId<I, O> {
/// Transforms a [`SystemId`] into the [`Entity`] that holds the one-shot system's state.
///
/// It's trivial to convert [`SystemId`] into an [`Entity`] since a one-shot system
/// is really an entity with associated handler function.
///
/// For example, this is useful if you want to assign a name label to a system.
pub fn entity(self) -> Entity {
self.entity
}
/// Create [`SystemId`] from an [`Entity`]. Useful when you only have entity handles to avoid
/// adding extra components that have a [`SystemId`] everywhere. To run a system with this ID
/// - The entity must be a system
/// - The `I` + `O` types must be correct
pub fn from_entity(entity: Entity) -> Self {
Self {
entity,
marker: std::marker::PhantomData,
}
}
}
impl<I, O> Eq for SystemId<I, O> {}
// A manual impl is used because the trait bounds should ignore the `I` and `O` phantom parameters.
@ -78,18 +101,6 @@ impl<I, O> std::fmt::Debug for SystemId<I, O> {
}
}
impl<I, O> From<SystemId<I, O>> for Entity {
/// Transforms a [`SystemId`] into the [`Entity`] that holds the one-shot system's state.
///
/// It's trivial to convert [`SystemId`] into an [`Entity`] since a system
/// is really an entity with associated handler function.
///
/// For example, this is useful if you want to assign a name label to a system.
fn from(SystemId { entity, .. }: SystemId<I, O>) -> Self {
entity
}
}
impl World {
/// Registers a system and returns a [`SystemId`] so it can later be called by [`World::run_system`].
///