Skip to content
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

Setup World to be optionally !Send #17526

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 36 additions & 34 deletions crates/bevy_ecs/src/entity/entity_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ use core::{
option, result,
};

use crate::world::{Sendability, SendMarker};

use super::Entity;

use bevy_platform_support::sync::Arc;
Expand Down Expand Up @@ -144,120 +146,120 @@ impl<T: IntoIterator<IntoIter: EntitySetIterator>> EntitySet for T {}
///
/// `x != y` must hold for any 2 elements returned by the iterator.
/// This is always true for iterators that cannot return more than one element.
pub unsafe trait EntitySetIterator: Iterator<Item: TrustedEntityBorrow> {}
pub unsafe trait EntitySetIterator<S: Sendability = SendMarker>: Iterator<Item: TrustedEntityBorrow> {}

// SAFETY:
// A correct `BTreeMap` contains only unique keys.
// TrustedEntityBorrow guarantees a trustworthy Ord impl for T, and thus a correct `BTreeMap`.
unsafe impl<K: TrustedEntityBorrow, V> EntitySetIterator for btree_map::Keys<'_, K, V> {}
unsafe impl<K: TrustedEntityBorrow, V, S: Sendability> EntitySetIterator<S> for btree_map::Keys<'_, K, V> {}

// SAFETY:
// A correct `BTreeMap` contains only unique keys.
// TrustedEntityBorrow guarantees a trustworthy Ord impl for T, and thus a correct `BTreeMap`.
unsafe impl<K: TrustedEntityBorrow, V> EntitySetIterator for btree_map::IntoKeys<K, V> {}
unsafe impl<K: TrustedEntityBorrow, V, S: Sendability> EntitySetIterator<S> for btree_map::IntoKeys<K, V> {}

// SAFETY:
// A correct `BTreeSet` contains only unique elements.
// TrustedEntityBorrow guarantees a trustworthy Ord impl for T, and thus a correct `BTreeSet`.
// The sub-range maintains uniqueness.
unsafe impl<T: TrustedEntityBorrow> EntitySetIterator for btree_set::Range<'_, T> {}
unsafe impl<T: TrustedEntityBorrow, S: Sendability> EntitySetIterator<S> for btree_set::Range<'_, T> {}

// SAFETY:
// A correct `BTreeSet` contains only unique elements.
// TrustedEntityBorrow guarantees a trustworthy Ord impl for T, and thus a correct `BTreeSet`.
// The "intersection" operation maintains uniqueness.
unsafe impl<T: TrustedEntityBorrow + Ord> EntitySetIterator for btree_set::Intersection<'_, T> {}
unsafe impl<T: TrustedEntityBorrow + Ord, S: Sendability> EntitySetIterator<S> for btree_set::Intersection<'_, T> {}

// SAFETY:
// A correct `BTreeSet` contains only unique elements.
// TrustedEntityBorrow guarantees a trustworthy Ord impl for T, and thus a correct `BTreeSet`.
// The "union" operation maintains uniqueness.
unsafe impl<T: TrustedEntityBorrow + Ord> EntitySetIterator for btree_set::Union<'_, T> {}
unsafe impl<T: TrustedEntityBorrow + Ord, S: Sendability> EntitySetIterator<S> for btree_set::Union<'_, T> {}

// SAFETY:
// A correct `BTreeSet` contains only unique elements.
// TrustedEntityBorrow guarantees a trustworthy Ord impl for T, and thus a correct `BTreeSet`.
// The "difference" operation maintains uniqueness.
unsafe impl<T: TrustedEntityBorrow + Ord> EntitySetIterator for btree_set::Difference<'_, T> {}
unsafe impl<T: TrustedEntityBorrow + Ord, S: Sendability> EntitySetIterator<S> for btree_set::Difference<'_, T> {}

// SAFETY:
// A correct `BTreeSet` contains only unique elements.
// TrustedEntityBorrow guarantees a trustworthy Ord impl for T, and thus a correct `BTreeSet`.
// The "symmetric difference" operation maintains uniqueness.
unsafe impl<T: TrustedEntityBorrow + Ord> EntitySetIterator
unsafe impl<T: TrustedEntityBorrow + Ord, S: Sendability> EntitySetIterator<S>
for btree_set::SymmetricDifference<'_, T>
{
}

// SAFETY:
// A correct `BTreeSet` contains only unique elements.
// TrustedEntityBorrow guarantees a trustworthy Ord impl for T, and thus a correct `BTreeSet`.
unsafe impl<T: TrustedEntityBorrow> EntitySetIterator for btree_set::Iter<'_, T> {}
unsafe impl<T: TrustedEntityBorrow, S: Sendability> EntitySetIterator<S> for btree_set::Iter<'_, T> {}

// SAFETY:
// A correct `BTreeSet` contains only unique elements.
// TrustedEntityBorrow guarantees a trustworthy Ord impl for T, and thus a correct `BTreeSet`.
unsafe impl<T: TrustedEntityBorrow> EntitySetIterator for btree_set::IntoIter<T> {}
unsafe impl<T: TrustedEntityBorrow, S: Sendability> EntitySetIterator<S> for btree_set::IntoIter<T> {}

// SAFETY: This iterator only returns one element.
unsafe impl<T: TrustedEntityBorrow> EntitySetIterator for option::Iter<'_, T> {}
unsafe impl<T: TrustedEntityBorrow, S: Sendability> EntitySetIterator<S> for option::Iter<'_, T> {}

// SAFETY: This iterator only returns one element.
// unsafe impl<T: TrustedEntityBorrow> EntitySetIterator for option::IterMut<'_, T> {}
// unsafe impl<T: TrustedEntityBorrow, S: Sendability> EntitySetIterator<S> for option::IterMut<'_, T> {}

// SAFETY: This iterator only returns one element.
unsafe impl<T: TrustedEntityBorrow> EntitySetIterator for option::IntoIter<T> {}
unsafe impl<T: TrustedEntityBorrow, S: Sendability> EntitySetIterator<S> for option::IntoIter<T> {}

// SAFETY: This iterator only returns one element.
unsafe impl<T: TrustedEntityBorrow> EntitySetIterator for result::Iter<'_, T> {}
unsafe impl<T: TrustedEntityBorrow, S: Sendability> EntitySetIterator<S> for result::Iter<'_, T> {}

// SAFETY: This iterator only returns one element.
// unsafe impl<T: TrustedEntityBorrow> EntitySetIterator for result::IterMut<'_, T> {}
// unsafe impl<T: TrustedEntityBorrow, S: Sendability> EntitySetIterator<S> for result::IterMut<'_, T> {}

// SAFETY: This iterator only returns one element.
unsafe impl<T: TrustedEntityBorrow> EntitySetIterator for result::IntoIter<T> {}
unsafe impl<T: TrustedEntityBorrow, S: Sendability> EntitySetIterator<S> for result::IntoIter<T> {}

// SAFETY: This iterator only returns one element.
unsafe impl<T: TrustedEntityBorrow> EntitySetIterator for array::IntoIter<T, 1> {}
unsafe impl<T: TrustedEntityBorrow, S: Sendability> EntitySetIterator<S> for array::IntoIter<T, 1> {}

// SAFETY: This iterator does not return any elements.
unsafe impl<T: TrustedEntityBorrow> EntitySetIterator for array::IntoIter<T, 0> {}
unsafe impl<T: TrustedEntityBorrow, S: Sendability> EntitySetIterator<S> for array::IntoIter<T, 0> {}

// SAFETY: This iterator only returns one element.
unsafe impl<T: TrustedEntityBorrow, F: FnOnce() -> T> EntitySetIterator for iter::OnceWith<F> {}
unsafe impl<T: TrustedEntityBorrow, F: FnOnce() -> T, S: Sendability> EntitySetIterator<S> for iter::OnceWith<F> {}

// SAFETY: This iterator only returns one element.
unsafe impl<T: TrustedEntityBorrow> EntitySetIterator for iter::Once<T> {}
unsafe impl<T: TrustedEntityBorrow, S: Sendability> EntitySetIterator<S> for iter::Once<T> {}

// SAFETY: This iterator does not return any elements.
unsafe impl<T: TrustedEntityBorrow> EntitySetIterator for iter::Empty<T> {}
unsafe impl<T: TrustedEntityBorrow, S: Sendability> EntitySetIterator<S> for iter::Empty<T> {}

// SAFETY: Taking a mutable reference of an iterator has no effect on its elements.
unsafe impl<I: EntitySetIterator + ?Sized> EntitySetIterator for &mut I {}
unsafe impl<I: EntitySetIterator + ?Sized, S: Sendability> EntitySetIterator<S> for &mut I {}

// SAFETY: Boxing an iterator has no effect on its elements.
unsafe impl<I: EntitySetIterator + ?Sized> EntitySetIterator for Box<I> {}
unsafe impl<I: EntitySetIterator + ?Sized, S: Sendability> EntitySetIterator<S> for Box<I> {}

// SAFETY: TrustedEntityBorrow ensures that Copy does not affect equality, via its restrictions on Clone.
unsafe impl<'a, T: 'a + TrustedEntityBorrow + Copy, I: EntitySetIterator<Item = &'a T>>
EntitySetIterator for iter::Copied<I>
unsafe impl<'a, T: 'a + TrustedEntityBorrow + Copy, I: EntitySetIterator<Item = &'a T>, S: Sendability>
EntitySetIterator<S> for iter::Copied<I>
{
}

// SAFETY: TrustedEntityBorrow ensures that Clone does not affect equality.
unsafe impl<'a, T: 'a + TrustedEntityBorrow + Clone, I: EntitySetIterator<Item = &'a T>>
EntitySetIterator for iter::Cloned<I>
unsafe impl<'a, T: 'a + TrustedEntityBorrow + Clone, I: EntitySetIterator<Item = &'a T>, S: Sendability>
EntitySetIterator<S> for iter::Cloned<I>
{
}

// SAFETY: Discarding elements maintains uniqueness.
unsafe impl<I: EntitySetIterator, P: FnMut(&<I as Iterator>::Item) -> bool> EntitySetIterator
unsafe impl<I: EntitySetIterator, P: FnMut(&<I as Iterator>::Item) -> bool, S: Sendability> EntitySetIterator<S>
for iter::Filter<I, P>
{
}

// SAFETY: Yielding only `None` after yielding it once can only remove elements, which maintains uniqueness.
unsafe impl<I: EntitySetIterator> EntitySetIterator for iter::Fuse<I> {}
unsafe impl<I: EntitySetIterator, S: Sendability> EntitySetIterator<S> for iter::Fuse<I> {}

// SAFETY:
// Obtaining immutable references the elements of an iterator does not affect uniqueness.
Expand All @@ -268,10 +270,10 @@ unsafe impl<I: EntitySetIterator, F: FnMut(&<I as Iterator>::Item)> EntitySetIte
}

// SAFETY: Reversing an iterator does not affect uniqueness.
unsafe impl<I: DoubleEndedIterator + EntitySetIterator> EntitySetIterator for iter::Rev<I> {}
unsafe impl<I: DoubleEndedIterator + EntitySetIterator, S: Sendability> EntitySetIterator<S> for iter::Rev<I> {}

// SAFETY: Discarding elements maintains uniqueness.
unsafe impl<I: EntitySetIterator> EntitySetIterator for iter::Skip<I> {}
unsafe impl<I: EntitySetIterator, S: Sendability> EntitySetIterator<S> for iter::Skip<I> {}

// SAFETY: Discarding elements maintains uniqueness.
unsafe impl<I: EntitySetIterator, P: FnMut(&<I as Iterator>::Item) -> bool> EntitySetIterator
Expand All @@ -280,7 +282,7 @@ unsafe impl<I: EntitySetIterator, P: FnMut(&<I as Iterator>::Item) -> bool> Enti
}

// SAFETY: Discarding elements maintains uniqueness.
unsafe impl<I: EntitySetIterator> EntitySetIterator for iter::Take<I> {}
unsafe impl<I: EntitySetIterator, S: Sendability> EntitySetIterator<S> for iter::Take<I> {}

// SAFETY: Discarding elements maintains uniqueness.
unsafe impl<I: EntitySetIterator, P: FnMut(&<I as Iterator>::Item) -> bool> EntitySetIterator
Expand All @@ -289,7 +291,7 @@ unsafe impl<I: EntitySetIterator, P: FnMut(&<I as Iterator>::Item) -> bool> Enti
}

// SAFETY: Discarding elements maintains uniqueness.
unsafe impl<I: EntitySetIterator> EntitySetIterator for iter::StepBy<I> {}
unsafe impl<I: EntitySetIterator, S: Sendability> EntitySetIterator<S> for iter::StepBy<I> {}

/// An iterator that yields unique entities.
///
Expand Down Expand Up @@ -340,7 +342,7 @@ impl<I: DoubleEndedIterator<Item: TrustedEntityBorrow>> DoubleEndedIterator
impl<I: FusedIterator<Item: TrustedEntityBorrow>> FusedIterator for UniqueEntityIter<I> {}

// SAFETY: The underlying iterator is ensured to only return unique elements by its construction.
unsafe impl<I: Iterator<Item: TrustedEntityBorrow>> EntitySetIterator for UniqueEntityIter<I> {}
unsafe impl<I: Iterator<Item: TrustedEntityBorrow>, S: Sendability> EntitySetIterator<S> for UniqueEntityIter<I> {}

impl<T, I: Iterator<Item: TrustedEntityBorrow> + AsRef<[T]>> AsRef<[T]> for UniqueEntityIter<I> {
fn as_ref(&self) -> &[T] {
Expand Down
3 changes: 1 addition & 2 deletions crates/bevy_ecs/src/query/fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ use crate::{
query::{Access, DebugCheckedUnwrap, FilteredAccess, WorldQuery},
storage::{ComponentSparseSet, Table, TableRow},
world::{
unsafe_world_cell::UnsafeWorldCell, EntityMut, EntityMutExcept, EntityRef, EntityRefExcept,
FilteredEntityMut, FilteredEntityRef, Mut, Ref, World,
unsafe_world_cell::UnsafeWorldCell, EntityMut, EntityMutExcept, EntityRef, EntityRefExcept, FilteredEntityMut, FilteredEntityRef, Mut, Ref, World
},
};
use bevy_ptr::{ThinSlicePtr, UnsafeCellDeref};
Expand Down
18 changes: 9 additions & 9 deletions crates/bevy_ecs/src/query/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
entity::Entity,
query::{DebugCheckedUnwrap, FilteredAccess, StorageSwitch, WorldQuery},
storage::{ComponentSparseSet, Table, TableRow},
world::{unsafe_world_cell::UnsafeWorldCell, World},
world::{unsafe_world_cell::UnsafeWorldCell, SendMarker, Sendability, World},
};
use bevy_ptr::{ThinSlicePtr, UnsafeCellDeref};
use core::{cell::UnsafeCell, marker::PhantomData};
Expand Down Expand Up @@ -149,8 +149,8 @@ unsafe impl<T: Component> WorldQuery for With<T> {
fn shrink_fetch<'wlong: 'wshort, 'wshort>(_: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {}

#[inline]
unsafe fn init_fetch(
_world: UnsafeWorldCell,
unsafe fn init_fetch<S: Sendability>(
_world: UnsafeWorldCell<S>,
_state: &ComponentId,
_last_run: Tick,
_this_run: Tick,
Expand Down Expand Up @@ -189,7 +189,7 @@ unsafe impl<T: Component> WorldQuery for With<T> {
access.and_with(id);
}

fn init_state(world: &mut World) -> ComponentId {
fn init_state(world: &mut World<S>) -> ComponentId {
world.register_component::<T>()
}

Expand Down Expand Up @@ -261,7 +261,7 @@ unsafe impl<T: Component> WorldQuery for Without<T> {

#[inline]
unsafe fn init_fetch(
_world: UnsafeWorldCell,
_world: UnsafeWorldCell<S>,
_state: &ComponentId,
_last_run: Tick,
_this_run: Tick,
Expand Down Expand Up @@ -300,7 +300,7 @@ unsafe impl<T: Component> WorldQuery for Without<T> {
access.and_without(id);
}

fn init_state(world: &mut World) -> ComponentId {
fn init_state(world: &mut World<S>) -> ComponentId {
world.register_component::<T>()
}

Expand All @@ -317,7 +317,7 @@ unsafe impl<T: Component> WorldQuery for Without<T> {
}

// SAFETY: WorldQuery impl performs no access at all
unsafe impl<T: Component> QueryFilter for Without<T> {
unsafe impl<T: Component> QueryFilter<S> for Without<T> {
const IS_ARCHETYPAL: bool = true;

#[inline(always)]
Expand Down Expand Up @@ -920,7 +920,7 @@ unsafe impl<T: Component> WorldQuery for Changed<T> {

#[inline]
unsafe fn init_fetch<'w>(
world: UnsafeWorldCell<'w>,
world: UnsafeWorldCell<'w, S>,
&id: &ComponentId,
last_run: Tick,
this_run: Tick,
Expand Down Expand Up @@ -1013,7 +1013,7 @@ unsafe impl<T: Component> WorldQuery for Changed<T> {
access.add_component_read(id);
}

fn init_state(world: &mut World) -> ComponentId {
fn init_state(world: &mut World<S>) -> ComponentId {
world.register_component::<T>()
}

Expand Down
Loading