-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow removing and reloading assets with live handles #10785
Conversation
I think there's still the existing issue where the last strong handle drop will infinitely loop for assets that have already been removed, as contains() will always return false, I believe. I think we need to instead query the AssetServer info for this check. I did that in this PR: #10520 bevy/crates/bevy_asset/src/assets.rs Lines 500 to 503 in 5450faf
|
@JMS55 good call / agreed. Just pushed a fix. |
# Objective Fixes #10444 Currently manually removing an asset prevents it from being reloaded while there are still active handles. Doing so will result in a panic, because the storage entry has been marked as "empty / None" but the ID is still assumed to be active by the asset server. Patterns like `images.remove() -> asset_server.reload()` and `images.remove() -> images.insert()` would fail if the handle was still alive. ## Solution Most of the groundwork for this was already laid in Bevy Asset V2. This is largely just a matter of splitting out `remove` into two separate operations: * `remove_dropped`: remove the stored asset, invalidate the internal Assets entry (preventing future insertions with the old id), and recycle the id * `remove_still_alive`: remove the stored asset, but leave the entry otherwise untouched (and dont recycle the id). `remove_still_alive` and `insert` can be called any number of times (in any order) for an id until `remove_dropped` has been called, which will invalidate the id. From a user-facing perspective, there are no API changes and this is non breaking. The public `Assets::remove` will internally call `remove_still_alive`. `remove_dropped` can only be called by the internal "handle management" system. --- ## Changelog - Fix a bug preventing `Assets::remove` from blocking future inserts for a specific `AssetIndex`.
# Objective Fixes bevyengine#10444 Currently manually removing an asset prevents it from being reloaded while there are still active handles. Doing so will result in a panic, because the storage entry has been marked as "empty / None" but the ID is still assumed to be active by the asset server. Patterns like `images.remove() -> asset_server.reload()` and `images.remove() -> images.insert()` would fail if the handle was still alive. ## Solution Most of the groundwork for this was already laid in Bevy Asset V2. This is largely just a matter of splitting out `remove` into two separate operations: * `remove_dropped`: remove the stored asset, invalidate the internal Assets entry (preventing future insertions with the old id), and recycle the id * `remove_still_alive`: remove the stored asset, but leave the entry otherwise untouched (and dont recycle the id). `remove_still_alive` and `insert` can be called any number of times (in any order) for an id until `remove_dropped` has been called, which will invalidate the id. From a user-facing perspective, there are no API changes and this is non breaking. The public `Assets::remove` will internally call `remove_still_alive`. `remove_dropped` can only be called by the internal "handle management" system. --- ## Changelog - Fix a bug preventing `Assets::remove` from blocking future inserts for a specific `AssetIndex`.
Objective
Fixes #10444
Currently manually removing an asset prevents it from being reloaded while there are still active handles. Doing so will result in a panic, because the storage entry has been marked as "empty / None" but the ID is still assumed to be active by the asset server.
Patterns like
images.remove() -> asset_server.reload()
andimages.remove() -> images.insert()
would fail if the handle was still alive.Solution
Most of the groundwork for this was already laid in Bevy Asset V2. This is largely just a matter of splitting out
remove
into two separate operations:remove_dropped
: remove the stored asset, invalidate the internal Assets entry (preventing future insertions with the old id), and recycle the idremove_still_alive
: remove the stored asset, but leave the entry otherwise untouched (and dont recycle the id).remove_still_alive
andinsert
can be called any number of times (in any order) for an id untilremove_dropped
has been called, which will invalidate the id.From a user-facing perspective, there are no API changes and this is non breaking. The public
Assets::remove
will internally callremove_still_alive
.remove_dropped
can only be called by the internal "handle management" system.Changelog
Assets::remove
from blocking future inserts for a specificAssetIndex
.