Skip to content

Commit

Permalink
Uncomment drain module, update safety comments and implement `LendJ…
Browse files Browse the repository at this point in the history
…oin` for

`Drain`.
  • Loading branch information
Imberflur committed Jul 23, 2023
1 parent 6ca2338 commit 0fad41d
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 20 deletions.
4 changes: 2 additions & 2 deletions src/join/lend_join.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,8 @@ pub unsafe trait LendJoin {

/// # Safety
///
/// Implementing this trait guarantees that `<Self as LendJoin>::get` can soundly be called
/// multiple times with the same ID.
/// Implementing this trait guarantees that `<Self as LendJoin>::get` can
/// soundly be called multiple times with the same ID.
pub unsafe trait RepeatableLendGet: LendJoin {}

/// Type alias to refer to the `<J as LendJoin>::Type<'next>` (except this
Expand Down
4 changes: 1 addition & 3 deletions src/join/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,7 @@ pub use par_join::{JoinParIter, ParJoin};
/// The `Self::Mask` value returned with the `Self::Value` must correspond such
/// that it is safe to retrieve items from `Self::Value` whose presence is
/// indicated in the mask. As part of this, `BitSetLike::iter` must not produce
/// an iterator that repeats an `Index` value. (S-TODO update impls: probably
/// drain)
/// an iterator that repeats an `Index` value.
pub unsafe trait Join {
/// Type of joined components.
type Type;
Expand Down Expand Up @@ -125,7 +124,6 @@ pub unsafe trait Join {

/// Get a joined component value by a given index.
///
// S-TODO: evaluate all impls (TODO: probably restrict, entry, and drain)
///
/// # Safety
///
Expand Down
43 changes: 37 additions & 6 deletions src/storage/drain.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use hibitset::BitSet;

#[nougat::gat(Type)]
use crate::join::LendJoin;
use crate::{
join::Join,
join::{Join, RepeatableLendGet},
storage::MaskedStorage,
world::{Component, Index},
};
Expand All @@ -13,18 +15,48 @@ pub struct Drain<'a, T: Component> {
pub data: &'a mut MaskedStorage<T>,
}

// S-TODO implement LendJoin
// S-TODO implement RepeatableLendGet
// SAFETY: Calling `get` is always safe! Iterating the mask does not repeat
// indices.
#[nougat::gat]
unsafe impl<'a, T> LendJoin for Drain<'a, T>
where
T: Component,
{
type Mask = BitSet;
type Type<'next> = T;
type Value = &'a mut MaskedStorage<T>;

unsafe fn open(self) -> (Self::Mask, Self::Value) {
// TODO: Cloning the whole bitset here seems expensive, and it is
// hidden from the user, but there is no obvious way to restructure
// things to avoid this with the way that bitsets are composed together
// for iteration.
let mask = self.data.mask.clone();

(mask, self.data)
}

unsafe fn get<'next>(value: &'next mut Self::Value, id: Index) -> T
where
Self: 'next,
{
value.remove(id).expect("Tried to access same index twice")
}
}

// SAFETY: Calling `get` is always safe!
unsafe impl<'a, T> RepeatableLendGet for Drain<'a, T> where T: Component {}

impl<'a, T> Join for Drain<'a, T>
// SAFETY: Calling `get` is always safe! Iterating the mask does not repeat
// indices.
unsafe impl<'a, T> Join for Drain<'a, T>
where
T: Component,
{
type Mask = BitSet;
type Type = T;
type Value = &'a mut MaskedStorage<T>;

// SAFETY: No invariants to meet and no unsafe code.
unsafe fn open(self) -> (Self::Mask, Self::Value) {
// TODO: Cloning the whole bitset here seems expensive, and it is
// hidden from the user, but there is no obvious way to restructure
Expand All @@ -35,7 +67,6 @@ where
(mask, self.data)
}

// SAFETY: No invariants to meet and no unsafe code.
unsafe fn get(value: &mut Self::Value, id: Index) -> T {
value.remove(id).expect("Tried to access same index twice")
}
Expand Down
18 changes: 9 additions & 9 deletions src/storage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ use crate::{
world::{Component, EntitiesRes, Entity, Index},
};

// D-TODO use self::drain::Drain;
use self::drain::Drain;
use self::sync_unsafe_cell::SyncUnsafeCell;

mod data;
mod deref_flagged;
// D-TODO mod drain;
mod drain;
mod entry;
mod flagged;
mod generic;
Expand Down Expand Up @@ -449,13 +449,13 @@ where
self.data.clear();
}

// /// Creates a draining storage wrapper which can be `.join`ed
// /// to get a draining iterator.
// D-TODO pub fn drain(&mut self) -> Drain<T> {
// Drain {
// data: &mut self.data,
// }
//}
/// Creates a draining storage wrapper which can be `.join`ed
/// to get a draining iterator.
pub fn drain(&mut self) -> Drain<T> {
Drain {
data: &mut self.data,
}
}
}

impl<'a, T, D: Clone> Clone for Storage<'a, T, D> {
Expand Down

0 comments on commit 0fad41d

Please sign in to comment.