Skip to content

Commit

Permalink
Add docs and fix inverted condition
Browse files Browse the repository at this point in the history
  • Loading branch information
DJMcNab committed Jan 8, 2022
1 parent 769bff9 commit 22b4033
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 12 deletions.
36 changes: 31 additions & 5 deletions crates/bevy_ecs/src/world/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1143,14 +1143,25 @@ impl World {
self.entities.clear();
}

/// Create a version of this [`World`] which can be sent to another thread
///
/// # Panics
///
/// If `self` contains any [`!Send`] resources, e.g. from calls to [`World::insert_non_send`]
///
/// [`!Send`]: Send

pub fn turtle(self) -> Turtle {
let non_send = self.components().non_send_components().collect::<Vec<_>>();
for id in non_send {
assert!(
self.get_populated_resource_column(id).is_some(),
self.get_populated_resource_column(id).is_none(),
"Tried to create a Turtle from a World containing a !Send resource"
);
}
// Safety: this world does not contain anything !Send, as confirmed by the check above
// In practise this method is used for GLTF loading, which does not add any resources to the given world
// (i.e. the above check is trivially true)
Turtle { world: self }
}
}
Expand All @@ -1173,29 +1184,44 @@ impl fmt::Debug for World {
unsafe impl Sync for World {}

/// A world which does not contain any [`!Send`] resources, and therefore
/// can be safely sent between threads
/// can be safely sent between threads.
///
/// The name turtle is derived from this being something which is moving a
/// [`World`] (between threads)
///
/// [`!Send`]: Send
#[derive(Debug)]
pub struct Turtle {
// Safety: does not have any !Send resources
world: World,
}

// Safety: The contained world does not contain anything which is !Send
unsafe impl Send for Turtle {}

impl Turtle {
/// The [`World`] this [`Turtle`] was created from.
///
/// The returned [`World`] does not contain any [`!Send`] resources
///
/// [`!Send`]: Send
pub fn world(self) -> World {
self.world
}

/// A view on this [`Turtle`]'s [`World`], which contains no [`!Send`] resources
///
/// [`!Send`]: Send
// Safety: NonSend resources cannot be added using a raw reference
// to the world, so this cannot break our invariants
pub fn world_ref(&self) -> &World {
&self.world
}
}

impl Into<World> for Turtle {
fn into(self) -> World {
self.world()
impl From<Turtle> for World {
fn from(turtle: Turtle) -> Self {
turtle.world()
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_scene/src/dynamic_scene.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub struct DynamicEntity {
impl DynamicScene {
/// Create a new dynamic scene from a given scene.
pub fn from_scene(scene: &Scene, type_registry: &TypeRegistryArc) -> Self {
Self::from_world(&scene.turtle.world_ref(), type_registry)
Self::from_world(scene.turtle.world_ref(), type_registry)
}

/// Create a new dynamic scene from a given world.
Expand Down
7 changes: 1 addition & 6 deletions crates/bevy_scene/src/scene_spawner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,12 +179,7 @@ impl SceneSpawner {
}
})
})?;
reflect_component.copy_component(
&scene_world,
world,
*scene_entity,
entity,
);
reflect_component.copy_component(scene_world, world, *scene_entity, entity);
}
}
}
Expand Down

0 comments on commit 22b4033

Please sign in to comment.