Skip to content

Better ergonomics for WorldBorrow[Mut] API#7408

Closed
ruifengx wants to merge 2 commits intobevyengine:mainfrom
ruifengx:main
Closed

Better ergonomics for WorldBorrow[Mut] API#7408
ruifengx wants to merge 2 commits intobevyengine:mainfrom
ruifengx:main

Conversation

@ruifengx
Copy link

Objective

  • Allow mapping a WorldBorrow[Mut]<T> to WorldBorrow[Mut]<U>
  • Allow cloning a WorldBorrow<T>

Consider the following example:

#[derive(Resource)]
struct SomeResource {
    some_field: Vec<u32>,
    some_other_field: Option<Vec<u32>>,
}

pub fn get_global_some_field(world: &WorldCell) -> Option<WorldBorrow<[u32]>> {
    Some(world.resource::<SomeResource>()?.map(|res| &res.some_field))
}

pub fn get_global_some_other_field(world: &WorldCell) -> Option<WorldBorrow<[u32]>> {
    Some(world.resource::<SomeResource>()?.try_map(|res| res.some_field.as_ref())?)
}

Previously it is very complicated to define the two accessor functions, because &[u32] must outlive the WorldBorrow<SomeResource>, and we have to e.g. return a wrapper around WorldBorrow<SomeResource> implementing Deref<[u16]>.

Now that we have two functions consuming WorldBorrows, it might also be desirable to keep the original borrow by cloning it beforehand. Therefore we implement Clone for WorldBorrow<T>.

Solution

  • map and try_map consumes self and moves the witness of borrow.
  • clone simply borrows the data again from the same world.

Unresolved Questions


Changelog

  • Add map and try_map for WorldBorrow and WorldBorrowMut
  • Implement Clone for WorldBorrow
    Technically this will break downstream code because borrow.clone() is now ambiguous

Migration Guide

WorldBorrow<T> now implements Clone. If you have code cloning the inner value behind a WorldBorrow:

let borrow: WorldBorrow<T>;
let cloned = borrow.clone(); // T

You need to explicitly dereference the borrow to clone the inner value:

let t_cloned = T::clone(&borrow); // or
let t_cloned = (*borrow).clone();

Now you may also clone the borrow itself:

let borrow_cloned = borrow.clone(); // or
let borrow_cloned = WorldBorrow::clone(&borrow);

@alice-i-cecile alice-i-cecile added A-ECS Entities, components, systems, and events C-Usability A targeted quality-of-life change that makes Bevy easier to use labels Jan 29, 2023
@ItsDoot
Copy link
Contributor

ItsDoot commented Jul 15, 2024

WorldCell was removed in #12551, visit the linked PR for the rationale.

@ItsDoot ItsDoot closed this Jul 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-ECS Entities, components, systems, and events C-Usability A targeted quality-of-life change that makes Bevy easier to use

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants