fix: use try_insert instead of insert in bevy_ui to prevent panics when despawning ui nodes #13000
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Objective
Sometimes when despawning a ui node in the PostUpdate schedule it panics. This is because both a despawn command and insert command are being run on the same entity.
See this example code:
This code spawns a UiNode with a sliced image scale mode, and despawns it in the same frame. The bevy_ui::texture_slice::compute_slices_on_image_change system tries to insert the ComputedTextureSlices component on that node, but that entity is already despawned causing this error:
Note that you might have to run the code a few times before this error appears.
Solution
Use try_insert instead of insert for non critical inserts in the bevy_ui crate.
Some notes
In a lot of cases it does not makes much sense to despawn ui nodes after the layout system has finished. Except maybe if you delete the root ui node of a tree. I personally encountered this issue in bevy
0.13.2
with a system that was running before the layout system. And in0.13.2
thecompute_slices_on_image_change
system was also running before the layout system. But now it runs after the layout system. So the only way that this bug appears now is if you despawn ui nodes after the layout system. So I am not 100% sure if using try_insert in this system is the best option. But personally I still think it is better then the program panicking.However the
update_children_target_camera
system does still run before the layout system. So I do think it might still be able to panic when ui nodes are despawned before the layout system. Though I haven't been able to verify that.