-
-
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
Provide access to world storages when using UnsafeWorldCell
#8175
Conversation
I'm still not entirely sure how This function is sound: struct T;
fn use_storage(storages: &Storages) {
let component_id = /* component ID that I know is for T */;
let column = storages.tables.get(table_id).unwrap().get_column(component_id).unwrap();
let ptr = column.get_data(row).unwrap();
assert!(ptr is aligned for T):
// SAFETY: ptr points to T and is aligned.
let value = unsafe { ptr.deref::<T>() };
} That means, that having access to Under that model, This means however, that fn use_world(world: &World) {
world.storages().stable.get... // same as above
} The alternative would be to declare that having a reference to
I think I prefer 1 or 2, because these are at the granularity that bevy actually work on. (can multiple systems access distinct parts of the same |
I think a better solution would be to enforce the fact that To me, this would make |
I agree that The question is still where the boundary of unsafety is for storage. Either I think the second approch leads to better |
I strongly prefer this option. That's the approach I went for in this PR. |
I don't think it is yet. To prevent that we would have to make |
The only way to obtain an |
Yeah, I'm not saying it is unsound. Both options are valid. // Safety: we only access what we're allowed to
let storages = unsafe { worldcell.storages() };
let table = storages.tables.get(id);
let value = table.get(row); vs let storages = worldcell.storages();
let table = storages.tables.get(id);
// Safety: we only access what we're allowed to
let value = unsafe { table.get(row) }; I think usually the latter is a better place to put safety comments, especially when there are multiple layers of functions between. |
Ah, I see what you're saying. Yeah, that is a better way to encapsulate these safety invariants, and this PR isn't quite doing that yet. |
To reduce the impact of that refactor, I'd like to first migrate |
Closing in favor of #8280, which implements the cleaner unsafe API discussed before. |
Objective
UnsafeWorldCell
is a type used to provide interior mutable access to a world, meant to be a replacement for&World
. However, it is not currently possible to directly access the world's underlying storages, which meansUnsafeWorldCell
is not enough for every case where you need interior mutable world access.Solution
Provide access to world storages. Make the function unsafe, requiring the user to only use world accesses allowed by the
UnsafeWorldCell
.Changelog
UnsafeWorldCell::storages
, which gives low-level access to the underlying data storages of theWorld
.