-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Arc-d assets #15813
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
base: main
Are you sure you want to change the base?
Arc-d assets #15813
Conversation
|
Can you fix the inconsistency between "[ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really like the concept of storing assets in an Arc. I find that I very rarely mutate existing assets, only add/remove/swap, so Arcs for assets make perfect sense to me. I am somewhat worried about a lot of usages of get_cloned_mut that this causes in the rest of the codebase though.
Done! |
fa180c8 to
7828700
Compare
46f0334 to
d51a0b2
Compare
cfb37d8 to
8e37d87
Compare
Removing these functions makes it simpler to redesign them for when assets are Arc'd.
|
really dislike the public api change, but not sure there's a better way to do it |
|
I don't understand how I haven't read the entire PR so I might have missed something. |
|
@kristoff3r |
Ah that makes total sense, thanks for explaining. |
|
@mockersf Sorry I realized I didn't respond to your other question: I have not tested this on an asset heavy scene. Does Bevy have an example or stress test of this? It is possible that the extra dereferences hurt performance, but that might not be too big a deal. We already put render assets in a hashmap so cache locality might already be hurting? Unsure. |
|
I'm not sure I would suggest investigating a custom smart pointer (or Thoughts? |
|
Fyi MeshletMesh is an example of a read-only asset that I use Arc to share with the render world cheaply. In general, I wish we could share assets between the main/render world without any copies, in the same way that bevy schedules systems across multiple threads to avoid conflicts. |
Me on Discord |
|
I made a discussion post #18949 that is an alternative to this. I don't have a crazy strong opinion, but I think my proposal is worth investigating before merging this. Just in case. |
|
Just a head's up that @andriyDev and I have come up with a followup to this PR. See here. I think we need to start with merging this pr, but I think in the end, we'll have a less breaking api change and a much more flexible system. |
|
If the goal of this PR is to make assets usable in async context, why not just wrap the specific read-only assets in Arc yourself? So instead of The ownership of assets used to be very simple: Both this PR and #15346 is trying to do one thing: we're trying to discretize the ownership of I feel like we're dancing around the constraints posed by
So yeah I do think that this PR requires a bit more deliberation so that we can think about the root problem we're trying to solve (the "have nothing or have it all" asset ownership model) rather than a particular pain point caused by that ownership model. My pain point in this case is #18295 and I think it shares the same root cause as this one. |
This is what MeshletMesh does for instance. |
|
@PixelDust22 First, it's not true that "once something is in an Arc, it's no longer mutable". https://doc.rust-lang.org/stable/std/sync/struct.Arc.html#method.get_mut allows you mutable access if there's only one Arc and no Weaks. That's exactly why I expose Your idea of just making assets be If we go with just an Arc RwLock, I would just avoid having an assets resource at all and just only deal with the assets directly. Handles also become pointless in that model, since you could just get the Arc instead. At that point, we're not even using the ECS (which I suppose is fine, but is kinda sad). |
|
With So again, I think we should allow separate ownership for each Regarding overhead: The current ownership model with However, the status quo is really heavy-handed whenever you need to write. The writing system will have to borrow all In the common scenario with mostly reads and virtually no contention, just how much more performant is
Exactly, and that's the whole point: get rid of
I mean |
Objective
Fixes #15723. This is an alternative to #15346 (and the associated PR #15359) obsolete. Note if we decide asset locking is preferable, there are learnings from this PR we can apply to #15359.
Solution
Assets are now stored as
Arc<A>instead of justA.getremains the same, but I've added an alternative calledget_arcwhich returns a clone of the Arc that stores an asset.Replaced the
get_mutwith one ofget_cloned_mut,get_inplace_mut, andget_reflect_cloned_mut(this last one is just because it's necessary for reflection, but not necessarily needed for users).Added
add_arcandinsert_arcto allow addingArctypes directly.addcurrently takesInto<A>. Trying to change this toInto<Arc<A>>breaks a lot of callsites likemeshes.add(Rectangle::new(1.0, 2.0))(since this requires twoIntocalls, which Rust can't figure out).add_arctakeInto<Arc<A>>is a fine middle ground to allow bothArc-ed assets and owned assets.insert_arc.RenderAssetnow takes anArc<Self::SourceAsset>. This means in most cases, cloning the asset can be skipped when passing data to the render world. Data only needs to be cloned if you mutate an asset.Testing
Showcase
Assets can now be used in asynchronous contexts! By using
Assets<A>::get_arc, you can get a clone of the underlyingArcof an asset, and pass it to an async closure.Migration Guide
Assets::get_muthas been removed. Useget_cloned_mutforCloneassets, orget_in_place_mutfor non-Cloneassets (and handle the case where the asset is aliased).Assets::iter_mutnow returns an iterator of&mut Arc<A>. Consider usingArc::make_mutforCloneassets, orArc::get_mutfor non-Cloneassets (and handle the case where the asset is aliased).RenderAssets now take anArc<Self::SourceAsset>. Consider usingArc::try_unwrap()and falling back to a clone if the asset is aliased (try_unwrapreturns an error). Otherwise, prefer borrowing the source asset's data instead of moving it.