mirror of
https://github.com/bevyengine/bevy
synced 2024-11-29 16:10:19 +00:00
9e34c748c6
# Objective I'm build a UI system for bevy. In this UI system there is a concept of a system per UI entity. I had an issue where change detection wasn't working how I would expect and it's because when a function system is ran the `last_change_tick` is updated with the latest tick(from world). In my particular case I want to "wait" to update the `last_change_tick` until after my system runs for each entity. ## Solution Initially I thought bypassing the change detection all together would be a good fix, but on talking to some users in discord a simpler fix is to just expose `last_change_tick` to the end users. This is achieved by adding the following to the `System` trait: ```rust /// Allows users to get the system's last change tick. fn get_last_change_tick(&self) -> u32; /// Allows users to set the system's last change tick. fn set_last_change_tick(&mut self, last_change_tick: u32); ``` This causes a bit of weirdness with two implementors of `System`. `FixedTimestep` and `ChainSystem` both implement system and thus it's required that some sort of implementation be given for the new functions. I solved this by outputting a warning and not doing anything for these systems. I think it's important to understand why I can't add the new functions only to the function system and not to the `System` trait. In my code I store the systems generically as `Box<dyn System<...>>`. I do this because I have differing parameters that are being passed in depending on the UI widget's system. As far as I can tell there isn't a way to take a system trait and cast it into a specific type without knowing what those parameters are. In my own code this ends up looking something like: ```rust // Runs per entity. let old_tick = widget_system.get_last_change_tick(); should_update_children = widget_system.run((widget_tree.clone(), entity.0), world); widget_system.set_last_change_tick(old_tick); // later on after all the entities have been processed: for system in context.systems.values_mut() { system.set_last_change_tick(world.read_change_tick()); } ``` ## Changelog - Added `get_last_change_tick` and `set_last_change_tick` to `System`'s. |
||
---|---|---|
.. | ||
src | ||
Cargo.toml |