Skip to content

Commit

Permalink
Merge pull request #80 from Anders429/clippy
Browse files Browse the repository at this point in the history
Fix clippy lints.
  • Loading branch information
Anders429 committed Aug 9, 2022
2 parents 6095bc3 + 3265030 commit 9f87ea3
Show file tree
Hide file tree
Showing 9 changed files with 51 additions and 7 deletions.
2 changes: 2 additions & 0 deletions src/archetype/impl_send.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use crate::{archetype::Archetype, registry::Registry};

// SAFETY: This type is safe to send between threads, since the pointers to its columns are
// uniquely owned and cannot be mutated without mutable access to the type.
unsafe impl<R> Send for Archetype<R> where R: Registry {}
2 changes: 2 additions & 0 deletions src/query/result/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,8 @@ where
{
}

// SAFETY: This type is safe to send between threads, as its mutable views are guaranteed to be
// exclusive.
unsafe impl<'a, R, F, V> Send for Iter<'a, R, F, V>
where
R: Registry + 'a,
Expand Down
8 changes: 8 additions & 0 deletions src/query/result/par_iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ where
}
}

// SAFETY: This type is safe to send between threads, as its mutable views are guaranteed to be
// exclusive.
unsafe impl<'a, R, F, V> Send for ParIter<'a, R, F, V>
where
R: Registry,
Expand All @@ -99,6 +101,8 @@ where
{
}

// SAFETY: This type is safe to share between threads, as its mutable views are guaranteed to be
// exclusive.
unsafe impl<'a, R, F, V> Sync for ParIter<'a, R, F, V>
where
R: Registry,
Expand Down Expand Up @@ -144,8 +148,12 @@ impl<'a, C, F, V> ResultsConsumer<'a, C, F, V> {
}
}

// SAFETY: This type is safe to send between threads, as its mutable views are guaranteed to be
// exclusive.
unsafe impl<C, F, V> Send for ResultsConsumer<'_, C, F, V> {}

// SAFETY: This type is safe to share between threads, as its mutable views are guaranteed to be
// exclusive.
unsafe impl<C, F, V> Sync for ResultsConsumer<'_, C, F, V> {}

impl<'a, C, R, F, V> Consumer<&'a mut Archetype<R>> for ResultsConsumer<'a, C, F, V>
Expand Down
5 changes: 4 additions & 1 deletion src/system/schedule/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,9 @@ where
where
R: Registry,
{
self.stages.run(SendableWorld(world));
self.stages.run(
// SAFETY: The pointer provided here is unique, being created from a mutable reference.
unsafe { SendableWorld::new(world) },
);
}
}
25 changes: 24 additions & 1 deletion src/system/schedule/sendable.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,27 @@
use crate::{registry::Registry, world::World};

pub struct SendableWorld<R>(pub(crate) *mut World<R>)
pub struct SendableWorld<R>(*mut World<R>)
where
R: Registry;

impl<R> SendableWorld<R>
where
R: Registry,
{
/// # Safety
/// The `world` pointer passed here must be exclusively.
pub(crate) unsafe fn new(world: *mut World<R>) -> Self {
Self(world)
}

/// # Safety
/// The pointer returned here must only be used for access to components that follow Rust's
/// borrowing rules.
pub(crate) unsafe fn get(self) -> *mut World<R> {
self.0
}
}

impl<R> Clone for SendableWorld<R>
where
R: Registry,
Expand All @@ -15,6 +33,11 @@ where

impl<R> Copy for SendableWorld<R> where R: Registry {}

// SAFETY: This type can be safely sent between threads as long as the safety contracts of its
// methods are upheld, because the data accessed will be accessed uniquely.
unsafe impl<R> Send for SendableWorld<R> where R: Registry {}

// SAFETY: This type can be safely shared between threads as long as the safety contracts of its
// methods are upheld, because the data accessed will be accessed uniquely, including mutable
// reference access.
unsafe impl<R> Sync for SendableWorld<R> where R: Registry {}
4 changes: 2 additions & 2 deletions src/system/schedule/stage/seal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,15 +147,15 @@ where
task.flush(
// SAFETY: This is guaranteed to be the only reference to this `World<R>`,
// meaning this cast to a mutable reference is sound.
unsafe { &mut *(world.0 as *const World<R> as *mut World<R>) },
unsafe { &mut *(world.get() as *const World<R> as *mut World<R>) },
);
}
Stage::Continue(task) => {
self.1.flush(world);
task.flush(
// SAFETY: This is guaranteed to be the only reference to this `World<R>`,
// meaning this cast to a mutable reference is sound.
unsafe { &mut *(world.0 as *const World<R> as *mut World<R>) },
unsafe { &mut *(world.get() as *const World<R> as *mut World<R>) },
);
}
Stage::Flush => {}
Expand Down
8 changes: 5 additions & 3 deletions src/system/schedule/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,17 @@ where
Task::Seq(system) => {
// Query world using system.
// SAFETY: The `Views` checks were already done when constructing the `Schedule`.
let result = unsafe { (*world.0).query_unchecked::<S::Views, S::Filter>() };
// Also, the access to the world's components follows Rust's borrowing rules.
let result = unsafe { (*world.get()).query_unchecked::<S::Views, S::Filter>() };
// Run system using the query result.
system.run(result);
}
Task::Par(system) => {
// Query world using system.
// SAFETY: The `ParViews` checks were already done when constructing the
// `Schedule`.
let result = unsafe { (*world.0).par_query_unchecked::<P::Views, P::Filter>() };
// `Schedule`. Also, the access to the world's components follows Rust's borrowing
// rules.
let result = unsafe { (*world.get()).par_query_unchecked::<P::Views, P::Filter>() };
// Run system using the query result.
system.run(result);
}
Expand Down
2 changes: 2 additions & 0 deletions src/world/impl_send.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use crate::{registry::RegistrySend, world::World};

// SAFETY: This type is safe to send between threads, since all pointers are owned and cannot be
// mutated without mutable access.
unsafe impl<R> Send for World<R> where R: RegistrySend {}
2 changes: 2 additions & 0 deletions src/world/impl_sync.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use crate::{registry::RegistrySync, world::World};

// SAFETY: This type is safe to share between multiple threads as you can't mutate it without a
// &mut reference.
unsafe impl<R> Sync for World<R> where R: RegistrySync {}

0 comments on commit 9f87ea3

Please sign in to comment.