#![expect(1unsafe_op_in_unsafe_fn,2reason = "See #11590. To be removed once all applicable unsafe code has an unsafe block with a safety comment."3)]45//! Storage layouts for ECS data.6//!7//! This module implements the low-level collections that store data in a [`World`]. These all offer minimal and often8//! unsafe APIs, and have been made `pub` primarily for debugging and monitoring purposes.9//!10//! # Fetching Storages11//! Each of the below data stores can be fetched via [`Storages`], which can be fetched from a12//! [`World`] via [`World::storages`]. It exposes a top level container for each class of storage within13//! ECS:14//!15//! - [`Tables`] - columnar contiguous blocks of memory, optimized for fast iteration.16//! - [`SparseSets`] - sparse `HashMap`-like mappings from entities to components, optimized for random17//! lookup and regular insertion/removal of components.18//! - [`NonSends`] - singleton storage for non send data in the world.19//!20//! # Safety21//! To avoid trivially unsound use of the APIs in this module, it is explicitly impossible to get a mutable22//! reference to [`Storages`] from [`World`], and none of the types publicly expose a mutable interface.23//!24//! [`World`]: crate::world::World25//! [`World::storages`]: crate::world::World::storages2627mod blob_array;28mod non_send;29mod sparse_set;30mod table;31mod thin_array_ptr;3233pub use non_send::*;34pub use sparse_set::*;35pub use table::*;3637use crate::component::{ComponentInfo, StorageType};38use alloc::vec::Vec;3940/// The raw data stores of a [`World`](crate::world::World)41#[derive(Default)]42pub struct Storages {43/// Backing storage for [`SparseSet`] components.44/// Note that sparse sets are only present for components that have been spawned or have had a relevant bundle registered.45pub sparse_sets: SparseSets,46/// Backing storage for [`Table`] components.47pub tables: Tables,48/// Backing storage for `!Send` data.49pub non_sends: NonSends,50}5152impl Storages {53/// ensures that the component has its necessary storage initialize.54pub fn prepare_component(&mut self, component: &ComponentInfo) {55match component.storage_type() {56StorageType::Table => {57// table needs no preparation58}59StorageType::SparseSet => {60self.sparse_sets.get_or_insert(component);61}62}63}64}6566struct AbortOnPanic;6768impl Drop for AbortOnPanic {69fn drop(&mut self) {70// Panicking while unwinding will force an abort.71panic!("Aborting due to allocator error");72}73}7475/// Unsafe extension functions for `Vec<T>`76trait VecExtensions<T> {77/// Removes an element from the vector and returns it.78///79/// The removed element is replaced by the last element of the vector.80///81/// This does not preserve ordering of the remaining elements, but is O(1). If you need to preserve the element order, use [`remove`] instead.82///83///84/// # Safety85///86/// All of the following must be true:87/// - `self.len() > 1`88/// - `index < self.len() - 1`89///90/// [`remove`]: alloc::vec::Vec::remove91/// [`swap_remove`]: alloc::vec::Vec::swap_remove92unsafe fn swap_remove_nonoverlapping_unchecked(&mut self, index: usize) -> T;93}9495impl<T> VecExtensions<T> for Vec<T> {96#[inline]97unsafe fn swap_remove_nonoverlapping_unchecked(&mut self, index: usize) -> T {98// SAFETY: The caller must ensure that the element at `index` must be valid.99// This function, and then the caller takes ownership of the value, and it cannot be100// accessed due to the length being decremented immediately after this.101let value = unsafe { self.as_mut_ptr().add(index).read() };102let len = self.len();103let base_ptr = self.as_mut_ptr();104// SAFETY: We replace self[index] with the last element. The caller must ensure that105// both the last element and `index` must be valid and cannot point to the same place.106unsafe { core::ptr::copy_nonoverlapping(base_ptr.add(len - 1), base_ptr.add(index), 1) };107// SAFETY: Upheld by caller108unsafe { self.set_len(len - 1) };109value110}111}112113114