Skip to content

Commit

Permalink
unique storage are stored on their own
Browse files Browse the repository at this point in the history
remove SparseSet::insert_unique and is_unique
fix #51
  • Loading branch information
leudz committed May 5, 2020
1 parent 03b93ba commit 9b62b8a
Show file tree
Hide file tree
Showing 10 changed files with 301 additions and 582 deletions.
12 changes: 6 additions & 6 deletions src/borrow/all_storages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,42 +106,42 @@ impl<'a, T: 'static + Sync> AllStoragesBorrow<'a> for NonSendSync<ViewMut<'a, T>
#[cfg(feature = "non_send")]
impl<'a, T: 'static + Sync> AllStoragesBorrow<'a> for NonSend<UniqueView<'a, T>> {
fn try_borrow(all_storages: &'a AllStorages) -> Result<Self, error::GetStorage> {
UniqueView::try_storage_from_non_send(all_storages).map(NonSend)
all_storages.try_into().map(NonSend)
}
}

#[cfg(feature = "non_send")]
impl<'a, T: 'static + Sync> AllStoragesBorrow<'a> for NonSend<UniqueViewMut<'a, T>> {
fn try_borrow(all_storages: &'a AllStorages) -> Result<Self, error::GetStorage> {
UniqueViewMut::try_storage_from_non_send(all_storages).map(NonSend)
all_storages.try_into().map(NonSend)
}
}

#[cfg(feature = "non_sync")]
impl<'a, T: 'static + Send> AllStoragesBorrow<'a> for NonSync<UniqueView<'a, T>> {
fn try_borrow(all_storages: &'a AllStorages) -> Result<Self, error::GetStorage> {
UniqueView::try_storage_from_non_sync(all_storages).map(NonSync)
all_storages.try_into().map(NonSync)
}
}

#[cfg(feature = "non_sync")]
impl<'a, T: 'static + Send> AllStoragesBorrow<'a> for NonSync<UniqueViewMut<'a, T>> {
fn try_borrow(all_storages: &'a AllStorages) -> Result<Self, error::GetStorage> {
UniqueViewMut::try_storage_from_non_sync(all_storages).map(NonSync)
all_storages.try_into().map(NonSync)
}
}

#[cfg(all(feature = "non_send", feature = "non_sync"))]
impl<'a, T: 'static + Sync> AllStoragesBorrow<'a> for NonSendSync<UniqueView<'a, T>> {
fn try_borrow(all_storages: &'a AllStorages) -> Result<Self, error::GetStorage> {
UniqueView::try_storage_from_non_send_sync(all_storages).map(NonSendSync)
all_storages.try_into().map(NonSendSync)
}
}

#[cfg(all(feature = "non_send", feature = "non_sync"))]
impl<'a, T: 'static + Sync> AllStoragesBorrow<'a> for NonSendSync<UniqueViewMut<'a, T>> {
fn try_borrow(all_storages: &'a AllStorages) -> Result<Self, error::GetStorage> {
UniqueViewMut::try_storage_from_non_send_sync(all_storages).map(NonSendSync)
all_storages.try_into().map(NonSendSync)
}
}

Expand Down
66 changes: 30 additions & 36 deletions src/borrow/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,12 +270,11 @@ impl<'a, T: 'static + Sync> Borrow<'a> for NonSend<UniqueView<'a, T>> {
all_storages: &'a AtomicRefCell<AllStorages>,
#[cfg(feature = "parallel")] _: &'a rayon::ThreadPool,
) -> Result<Self, error::GetStorage> {
UniqueView::try_from_non_send(
all_storages
.try_borrow()
.map_err(error::GetStorage::AllStoragesBorrow)?,
)
.map(NonSend)
all_storages
.try_borrow()
.map_err(error::GetStorage::AllStoragesBorrow)?
.try_into()
.map(NonSend)
}

fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) {
Expand All @@ -293,12 +292,11 @@ impl<'a, T: 'static + Sync> Borrow<'a> for NonSend<UniqueViewMut<'a, T>> {
all_storages: &'a AtomicRefCell<AllStorages>,
#[cfg(feature = "parallel")] _: &'a rayon::ThreadPool,
) -> Result<Self, error::GetStorage> {
UniqueViewMut::try_from_non_send(
all_storages
.try_borrow()
.map_err(error::GetStorage::AllStoragesBorrow)?,
)
.map(NonSend)
all_storages
.try_borrow()
.map_err(error::GetStorage::AllStoragesBorrow)?
.try_into()
.map(NonSend)
}

fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) {
Expand Down Expand Up @@ -362,12 +360,11 @@ impl<'a, T: 'static + Send> Borrow<'a> for NonSync<UniqueView<'a, T>> {
all_storages: &'a AtomicRefCell<AllStorages>,
#[cfg(feature = "parallel")] _: &'a rayon::ThreadPool,
) -> Result<Self, error::GetStorage> {
UniqueView::try_from_non_sync(
all_storages
.try_borrow()
.map_err(error::GetStorage::AllStoragesBorrow)?,
)
.map(NonSync)
all_storages
.try_borrow()
.map_err(error::GetStorage::AllStoragesBorrow)?
.try_into()
.map(NonSync)
}

fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) {
Expand All @@ -385,12 +382,11 @@ impl<'a, T: 'static + Send> Borrow<'a> for NonSync<UniqueViewMut<'a, T>> {
all_storages: &'a AtomicRefCell<AllStorages>,
#[cfg(feature = "parallel")] _: &'a rayon::ThreadPool,
) -> Result<Self, error::GetStorage> {
UniqueViewMut::try_from_non_sync(
all_storages
.try_borrow()
.map_err(error::GetStorage::AllStoragesBorrow)?,
)
.map(NonSync)
all_storages
.try_borrow()
.map_err(error::GetStorage::AllStoragesBorrow)?
.try_into()
.map(NonSync)
}

fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) {
Expand Down Expand Up @@ -454,12 +450,11 @@ impl<'a, T: 'static> Borrow<'a> for NonSendSync<UniqueView<'a, T>> {
all_storages: &'a AtomicRefCell<AllStorages>,
#[cfg(feature = "parallel")] _: &'a rayon::ThreadPool,
) -> Result<Self, error::GetStorage> {
UniqueView::try_from_non_send_sync(
all_storages
.try_borrow()
.map_err(error::GetStorage::AllStoragesBorrow)?,
)
.map(NonSendSync)
all_storages
.try_borrow()
.map_err(error::GetStorage::AllStoragesBorrow)?
.try_into()
.map(NonSendSync)
}
fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) {
<NonSendSync<View<'a, T>> as Borrow>::borrow_infos(infos)
Expand All @@ -476,12 +471,11 @@ impl<'a, T: 'static> Borrow<'a> for NonSendSync<UniqueViewMut<'a, T>> {
all_storages: &'a AtomicRefCell<AllStorages>,
#[cfg(feature = "parallel")] _: &'a rayon::ThreadPool,
) -> Result<Self, error::GetStorage> {
UniqueViewMut::try_from_non_send_sync(
all_storages
.try_borrow()
.map_err(error::GetStorage::AllStoragesBorrow)?,
)
.map(NonSendSync)
all_storages
.try_borrow()
.map_err(error::GetStorage::AllStoragesBorrow)?
.try_into()
.map(NonSendSync)
}

fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) {
Expand Down
12 changes: 9 additions & 3 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ impl Display for Borrow {
pub enum GetStorage {
AllStoragesBorrow(Borrow),
StorageBorrow((&'static str, Borrow)),
Unique { name: &'static str, borrow: Borrow },
NonUnique((&'static str, Borrow)),
MissingUnique(&'static str),
Entities(Borrow),
Expand All @@ -78,10 +79,15 @@ impl Debug for GetStorage {
Borrow::MultipleThreads => fmt.write_fmt(format_args!("Cannot borrow {} storage from multiple thread at the same time because it's !Sync.", name)),
Borrow::WrongThread => fmt.write_fmt(format_args!("Cannot borrow {} storage from other thread than the one it was created in because it's !Send and !Sync.", name)),
},
Self::MissingUnique(name) => fmt.write_fmt(format_args!("No unique storage exists for {name}.\nConsider adding this line after the creation of World: world.add_unique::<{name}>(/* your_storage */);", name = name)),
Self::Unique {name, borrow} => match borrow {
Borrow::Shared => fmt.write_fmt(format_args!("{}'s storage is unique.\nYou can access it with UniqueView instead of View.", name)),
Borrow::Unique => fmt.write_fmt(format_args!("{}'s storage is unique.\nYou can access it with UniqueViewMut instead of ViewMut.", name)),
_ => unreachable!()
},
Self::MissingUnique(name) => fmt.write_fmt(format_args!("No unique storage exists for {}.\nYou can register it with: world.add_unique(/* your_unique */);", name)),
Self::NonUnique((name, mutation)) => match mutation {
Borrow::Shared => fmt.write_fmt(format_args!("{name}'s storage isn't unique.\nYou might have forgotten to declare it, add world.add_unique(/* your_storage */) somewhere before accessing it.\nIf it isn't supposed to be a unique storage, replace Unique<&{name}> by &{name}.", name = name)),
Borrow::Unique => fmt.write_fmt(format_args!("{name}'s storage isn't unique.\nYou might have forgotten to declare it, add world.add_unique(/* your_storage */) somewhere before accessing it.\nIf it isn't supposed to be a unique storage, replace Unique<&mut {name}> by &mut {name}.", name = name)),
Borrow::Shared => fmt.write_fmt(format_args!("{}'s storage isn't unique.\nYou might have forgotten to declare it, add world.add_unique(/* your_storage */) before accessing it.", name)),
Borrow::Unique => fmt.write_fmt(format_args!("{}'s storage isn't unique.\nYou might have forgotten to declare it, add world.add_unique(/* your_storage */) before accessing it.", name)),
_ => unreachable!(),
},
Self::Entities(borrow) => match borrow {
Expand Down
36 changes: 12 additions & 24 deletions src/sparse_set/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -548,9 +548,6 @@ impl<T> SparseSet<T> {
pub fn clear_inserted_and_modified(&mut self) {
self.try_clear_inserted_and_modified().unwrap()
}
pub(crate) fn is_unique(&self) -> bool {
self.sparse.is_empty() && self.dense.is_empty() && self.data.len() == 1
}
// ▼ old end of pack
// ▼ new end of pack
// [_ _ _ _ | _ | _ _ _ _ _]
Expand Down Expand Up @@ -616,13 +613,6 @@ impl<T> SparseSet<T> {
pub(crate) fn unpack(&mut self, entity: EntityId) {
self.window_mut().unpack(entity)
}
/// Place the unique component in the storage.
/// The storage has to be completely empty.
pub(crate) fn insert_unique(&mut self, component: T) {
if self.sparse.is_empty() && self.dense.is_empty() && self.data.is_empty() {
self.data.push(component)
}
}
pub(crate) fn clone_indices(&self) -> Vec<EntityId> {
self.dense.clone()
}
Expand Down Expand Up @@ -660,21 +650,19 @@ impl<T> SparseSet<T> {
}
/// Deletes all components in this storage.
pub fn clear(&mut self) {
if !self.is_unique() {
for id in &self.dense {
self.sparse[id.bucket()].as_mut().unwrap()[id.bucket_index()] = core::usize::MAX;
}
match &mut self.pack_info.pack {
Pack::Tight(tight) => tight.len = 0,
Pack::Loose(loose) => loose.len = 0,
Pack::Update(update) => update
.deleted
.extend(self.dense.drain(..).zip(self.data.drain(..))),
Pack::NoPack => {}
}
self.dense.clear();
self.data.clear();
for id in &self.dense {
self.sparse[id.bucket()].as_mut().unwrap()[id.bucket_index()] = core::usize::MAX;
}
match &mut self.pack_info.pack {
Pack::Tight(tight) => tight.len = 0,
Pack::Loose(loose) => loose.len = 0,
Pack::Update(update) => update
.deleted
.extend(self.dense.drain(..).zip(self.data.drain(..))),
Pack::NoPack => {}
}
self.dense.clear();
self.data.clear();
}
/// Returns the `EntityId` at a given `index`.
pub fn try_id_at(&self, index: usize) -> Option<EntityId> {
Expand Down
Loading

0 comments on commit 9b62b8a

Please sign in to comment.