bevy/crates/bevy_ecs/src
Joseph 9c2257332a
Add a method for detecting changes within a certain scope (#11687)
# Objective

Bevy's change detection functionality is invaluable for writing robust
apps, but it only works in the context of systems and exclusive systems.
Oftentimes it is necessary to detect changes made in earlier code
without having to place the code in separate systems, but it is not
currently possible to do so since there is no way to set the value of
`World::last_change_tick`.

`World::clear_trackers` allows you to update the change tick, but this
has unintended side effects, since it irreversibly affects the behavior
of change and removal detection for the entire app.

## Solution

Add a method `World::last_change_tick_scope`. This allows you to set
`last_change_tick` to a specific value for a region of code. To ensure
that misuse doesn't break unrelated functions, we restore the world's
original change tick at the end of the provided scope.

### Example

A function that uses this to run an update loop repeatedly, allowing
each iteration of the loop to react to changes made in the previous loop
iteration.

```rust
fn update_loop(
    world: &mut World,
    mut update_fn: impl FnMut(&mut World) -> std::ops::ControlFlow<()>,
) {
    let mut last_change_tick = world.last_change_tick();

    // Repeatedly run the update function until it requests a break.
    loop {
        // Update once.
        let control_flow = world.last_change_tick_scope(last_change_tick, |world| {
            update_fn(world)
        });

        // End the loop when the closure returns `ControlFlow::Break`.
        if control_flow.is_break() {
            break;
        }

        // Increment the change tick so the next update can detect changes from this update.
        last_change_tick = world.change_tick();
        world.increment_change_tick();
    }
}
```

---

## Changelog

+ Added `World::last_change_tick_scope`, which allows you to specify the
reference for change detection within a certain scope.
2024-02-12 15:09:11 +00:00
..
entity Move EntityHash related types into bevy_ecs (#11498) 2024-02-12 15:02:24 +00:00
identifier Unified identifer for entities & relations (#9797) 2024-01-13 01:09:32 +00:00
query Replace pointer castings (as) by their API equivalent (#11818) 2024-02-11 23:19:36 +00:00
reflect Move EntityHash related types into bevy_ecs (#11498) 2024-02-12 15:02:24 +00:00
schedule System::type_id Consistency (#11728) 2024-02-06 14:43:33 +00:00
storage Double the capacity when BlobVec is full (#11167) 2024-01-22 15:05:34 +00:00
system Add a method for detecting changes within a certain scope (#11687) 2024-02-12 15:09:11 +00:00
world Add a method for detecting changes within a certain scope (#11687) 2024-02-12 15:09:11 +00:00
archetype.rs Make Archetypes.archetype_component_count private (#10774) 2024-02-03 00:07:50 +00:00
bundle.rs Use TypeIdMap whenever possible (#11684) 2024-02-03 23:47:04 +00:00
change_detection.rs Mention Resource where missing from component/resource related type docs (#11769) 2024-02-08 06:31:48 +00:00
component.rs Mention Resource where missing from component/resource related type docs (#11769) 2024-02-08 06:31:48 +00:00
event.rs Fix bug where events are not being dropped (#11528) 2024-02-02 21:14:54 +00:00
lib.rs Use TypeIdMap whenever possible (#11684) 2024-02-03 23:47:04 +00:00
removal_detection.rs Docs reflect that RemovalDetection also yields despawned entities (#11795) 2024-02-10 11:18:05 +00:00