Skip to content

Tracked one-shot systems#24165

Open
ItsDoot wants to merge 4 commits intobevyengine:mainfrom
ItsDoot:ecs/optinoneshothandle
Open

Tracked one-shot systems#24165
ItsDoot wants to merge 4 commits intobevyengine:mainfrom
ItsDoot:ecs/optinoneshothandle

Conversation

@ItsDoot
Copy link
Copy Markdown
Contributor

@ItsDoot ItsDoot commented May 7, 2026

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)

This was proposed basically 1:1 in #24026 (this was later changed though). The issue is that it's unclear who owns these systems, that is who is responsible for unregistering them once they are no longer needed. Given that recreating the template will spawn the system again this basically becomes a memory leak.

#24087 (comment)

Hm, are you sure this is the case even tho in build_template it only registers the system the first time its called, switching over to storing the SystemId after the first call?

If you recreate the template (e.g. you call my_scene() again) then you will create a new instance of the system. And since the system is not scoped to the scene once the scene is despawned the system entity will be leaked.

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: SystemHandles

pub enum SystemHandle<I: SystemInput = (), O = ()> {
    /// A strong handle keeps the system entity alive as long as the handle
    /// (and any clones of it) exist.
    Strong(Arc<StrongSystemHandle>),
    /// A weak handle does not keep the system entity alive.
    Weak(SystemId<I, O>),
}

pub struct StrongSystemHandle {
    entity: Entity,
    drop_queue: Arc<ConcurrentQueue<<Entity>>,
}

Similar to bevy_asset::Handles,SystemHandle's custom Drop implementation enqueues the registered system entity into a concurrent queue. The system despawn_unused_registered_systems pulls from the other end of this queue and despawns the registered system entities.

World::register_tracked_system and World::register_tracked_boxed_system are the only functions that return SystemHandles.

Testing

  • Added a test to ensure that despawn_unused_registered_systems does its job
  • Added a test to ensure that the default app will automatically call despawn_unused_registered_systems

Future work

@ItsDoot ItsDoot added A-ECS Entities, components, systems, and events C-Performance A change motivated by improving speed, memory usage or compile times D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels May 7, 2026
@github-project-automation github-project-automation Bot moved this to Needs SME Triage in ECS May 7, 2026
@ItsDoot ItsDoot requested a review from chescock May 7, 2026 03:41
Copy link
Copy Markdown
Contributor

@chescock chescock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! I left some comments, but they're just style nits.

Comment thread crates/bevy_ecs/Cargo.toml
Comment thread crates/bevy_ecs/src/system/system_registry.rs Outdated
Comment thread crates/bevy_ecs/src/system/system_registry.rs Outdated
Comment thread crates/bevy_ecs/src/system/system_registry.rs Outdated
Comment thread crates/bevy_ecs/src/system/system_registry.rs Outdated
I: SystemInput + 'static,
O: 'static,
{
let id = id.into();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to worry about this monomorphizing two versions of this function?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe! Would be good to check how much of a difference the codegen is

Comment thread crates/bevy_ecs/src/system/system_registry.rs Outdated
Comment thread crates/bevy_ecs/src/system/system_registry.rs Outdated
Comment thread crates/bevy_ecs/src/system/system_registry.rs Outdated
ItsDoot and others added 3 commits May 9, 2026 02:15
Co-authored-by: Chris Russell <8494645+chescock@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-ECS Entities, components, systems, and events C-Performance A change motivated by improving speed, memory usage or compile times D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes S-Needs-Review Needs reviewer attention (from anyone!) to move forward

Projects

Status: Needs SME Triage

Development

Successfully merging this pull request may close these issues.

2 participants