bevy_ecs/storage/mod.rs
1//! Storage layouts for ECS data.
2//!
3//! This module implements the low-level collections that store data in a [`World`]. These all offer minimal and often
4//! unsafe APIs, and have been made `pub` primarily for debugging and monitoring purposes.
5//!
6//! # Fetching Storages
7//! Each of the below data stores can be fetched via [`Storages`], which can be fetched from a
8//! [`World`] via [`World::storages`]. It exposes a top level container for each class of storage within
9//! ECS:
10//!
11//! - [`Tables`] - columnar contiguous blocks of memory, optimized for fast iteration.
12//! - [`SparseSets`] - sparse `HashMap`-like mappings from entities to components, optimized for random
13//! lookup and regular insertion/removal of components.
14//! - [`Resources`] - singleton storage for the resources in the world
15//!
16//! # Safety
17//! To avoid trivially unsound use of the APIs in this module, it is explicitly impossible to get a mutable
18//! reference to [`Storages`] from [`World`], and none of the types publicly expose a mutable interface.
19//!
20//! [`World`]: crate::world::World
21//! [`World::storages`]: crate::world::World::storages
22
23mod blob_array;
24mod resource;
25mod sparse_set;
26mod table;
27mod thin_array_ptr;
28
29pub use resource::*;
30pub use sparse_set::*;
31pub use table::*;
32
33use crate::component::{ComponentInfo, StorageType};
34use alloc::vec::Vec;
35
36/// The raw data stores of a [`World`](crate::world::World)
37#[derive(Default)]
38pub struct Storages {
39 /// Backing storage for [`SparseSet`] components.
40 /// Note that sparse sets are only present for components that have been spawned or have had a relevant bundle registered.
41 pub sparse_sets: SparseSets,
42 /// Backing storage for [`Table`] components.
43 pub tables: Tables,
44 /// Backing storage for resources.
45 pub resources: Resources<true>,
46 /// Backing storage for `!Send` resources.
47 pub non_send_resources: Resources<false>,
48}
49
50impl Storages {
51 /// ensures that the component has its necessary storage initialize.
52 pub fn prepare_component(&mut self, component: &ComponentInfo) {
53 match component.storage_type() {
54 StorageType::Table => {
55 // table needs no preparation
56 }
57 StorageType::SparseSet => {
58 self.sparse_sets.get_or_insert(component);
59 }
60 }
61 }
62}
63
64struct AbortOnPanic;
65
66impl Drop for AbortOnPanic {
67 fn drop(&mut self) {
68 // Panicking while unwinding will force an abort.
69 panic!("Aborting due to allocator error");
70 }
71}
72
73/// Unsafe extension functions for `Vec<T>`
74trait VecExtensions<T> {
75 /// Removes an element from the vector and returns it.
76 ///
77 /// The removed element is replaced by the last element of the vector.
78 ///
79 /// This does not preserve ordering of the remaining elements, but is O(1). If you need to preserve the element order, use [`remove`] instead.
80 ///
81 ///
82 /// # Safety
83 ///
84 /// All of the following must be true:
85 /// - `self.len() > 1`
86 /// - `index < self.len() - 1`
87 ///
88 /// [`remove`]: alloc::vec::Vec::remove
89 /// [`swap_remove`]: alloc::vec::Vec::swap_remove
90 unsafe fn swap_remove_nonoverlapping_unchecked(&mut self, index: usize) -> T;
91}
92
93impl<T> VecExtensions<T> for Vec<T> {
94 #[inline]
95 unsafe fn swap_remove_nonoverlapping_unchecked(&mut self, index: usize) -> T {
96 // SAFETY: The caller must ensure that the element at `index` must be valid.
97 // This function, and then the caller takes ownership of the value, and it cannot be
98 // accessed due to the length being decremented immediately after this.
99 let value = unsafe { self.as_mut_ptr().add(index).read() };
100 let len = self.len();
101 let base_ptr = self.as_mut_ptr();
102 // SAFETY: We replace self[index] with the last element. The caller must ensure that
103 // both the last element and `index` must be valid and cannot point to the same place.
104 unsafe { core::ptr::copy_nonoverlapping(base_ptr.add(len - 1), base_ptr.add(index), 1) };
105 // SAFETY: Upheld by caller
106 unsafe { self.set_len(len - 1) };
107 value
108 }
109}