Tracked one-shot systems#24165
Conversation
chescock
left a comment
There was a problem hiding this comment.
Looks good! I left some comments, but they're just style nits.
| @@ -69,6 +69,7 @@ std = [ | |||
| "bevy_utils/std", | |||
| "bitflags/std", | |||
| "concurrent-queue/std", | |||
There was a problem hiding this comment.
Since we already have a dependency on concurrent-queue, you might want to use ConcurrentQueue instead of crossbeam-channel. A queue is a little more lightweight since it doesn't support blocking, which you aren't using here.
| ) { | ||
| // `RegisteredSystemDespawner` is initialized lazily the first time a system | ||
| // is registered, so it's possible that it doesn't exist yet when this system runs. | ||
| if let Some(despawner) = despawner { |
There was a problem hiding this comment.
You could use If<Res<_>> instead of Option<Res<_>> to skip the system instead of needing this if let.
| sender: crossbeam_channel::Sender<Entity>, | ||
| } | ||
|
|
||
| #[cfg(feature = "std")] |
There was a problem hiding this comment.
It's too bad that you have to repeat the cfg so much. Would it make sense to put this type in a mod so that you only need one cfg? Or, does a bevy_platform::cfg::std! block work here?
| O: 'static, | ||
| { | ||
| let entity = self.spawn(RegisteredSystem::new(system)).id(); | ||
| #[cfg(feature = "std")] |
There was a problem hiding this comment.
This whole function is already in a cfg, right?
| #[cfg(feature = "std")] |
|
|
||
| SystemHandle::Strong(Arc::new(StrongSystemHandle { | ||
| entity, | ||
| #[cfg(feature = "std")] |
There was a problem hiding this comment.
... and here
| #[cfg(feature = "std")] |
| I: SystemInput + 'static, | ||
| O: 'static, | ||
| { | ||
| let id = id.into(); |
There was a problem hiding this comment.
Do we need to worry about this monomorphizing two versions of this function?
| } | ||
| } | ||
|
|
||
| // A manual impl is used because the trait bounds should ignore the `I` and `O` phantom parameters. |
There was a problem hiding this comment.
The PartialEq and Hash impls also need to be manual so that Weak == Strong for the same Entity, right?
| /// A strong handle for a registered system that keeps the system entity alive | ||
| /// as long as the handle (and any clones of it) exist. |
There was a problem hiding this comment.
The "keeps the entity alive" phrasing might be a little misleading here, since this is the thing inside the Arc.
| /// A strong handle for a registered system that keeps the system entity alive | |
| /// as long as the handle (and any clones of it) exist. | |
| /// A strong handle for a registered system that despawns the entity when dropped. |
| let mut cleanup = IntoSystem::into_system(despawn_unused_registered_systems); | ||
| cleanup.initialize(&mut world); | ||
| cleanup.run((), &mut world).unwrap(); |
There was a problem hiding this comment.
You can simplify this a bit with run_system_once or run_system_cached.
| let mut cleanup = IntoSystem::into_system(despawn_unused_registered_systems); | |
| cleanup.initialize(&mut world); | |
| cleanup.run((), &mut world).unwrap(); | |
| world | |
| .run_system_cached(despawn_unused_registered_systems) | |
| .unwrap(); |
Objective
#24087 introduces scene templating for
SystemIds, however it can result in a memory leak if a scene is re-constructed multiple times:#24087 (comment)
#24087 (comment)
Essentially, we need a way to connect the lifetime of the registered system to the lifetime of the scene.
Solution
This is a purely additive / opt-in / backwards-compatible version of #24114
Introducing:
SystemHandlesSimilar to
bevy_asset::Handles,SystemHandle's customDropimplementation enqueues the registered system entity into a message channel. The systemdespawn_unused_registered_systemspulls from the other end of this message channel and despawns the registered system entities.World::register_tracked_systemandWorld::register_tracked_boxed_systemare the only functions that returnSystemHandles.Testing
despawn_unused_registered_systemsdoes its jobdespawn_unused_registered_systemsFuture work
SystemIdscene templating #24087 will use this PR as a base