async_ecs/storage/
mod.rs

1mod anti_storage;
2mod btree_storage;
3mod dense_vec_storage;
4mod drain;
5mod hash_map_storage;
6mod masked_storage;
7mod storage_wrapper;
8mod vec_storage;
9
10pub use anti_storage::AntiStorage;
11pub use btree_storage::BTreeStorage;
12pub use dense_vec_storage::DenseVecStorage;
13pub use drain::Drain;
14pub use hash_map_storage::HashMapStorage;
15pub use masked_storage::MaskedStorage;
16pub use storage_wrapper::StorageWrapper;
17pub use vec_storage::VecStorage;
18
19use hibitset::BitSetLike;
20
21use crate::{entity::Index, misc::TryDefault};
22
23/// Used by the framework to quickly join components.
24pub trait Storage<T>: TryDefault {
25    /// Tries reading the data associated with an `Index`.
26    /// This is unsafe because the external set used
27    /// to protect this storage is absent.
28    ///
29    /// # Safety
30    ///
31    /// May only be called after a call to `insert` with `id` and
32    /// no following call to `remove` with `id`.
33    ///
34    /// A mask should keep track of those states, and an `id` being contained
35    /// in the tracking mask is sufficient to call this method.
36    unsafe fn get(&self, index: Index) -> &T;
37
38    /// Tries mutating the data associated with an `Index`.
39    /// This is unsafe because the external set used
40    /// to protect this storage is absent.
41    ///
42    /// # Safety
43    ///
44    /// May only be called after a call to `insert` with `id` and
45    /// no following call to `remove` with `id`.
46    ///
47    /// A mask should keep track of those states, and an `id` being contained
48    /// in the tracking mask is sufficient to call this method.
49    unsafe fn get_mut(&mut self, index: Index) -> &mut T;
50
51    /// Inserts new data for a given `Index`.
52    ///
53    /// # Safety
54    ///
55    /// May only be called if `insert` was not called with `id` before, or
56    /// was reverted by a call to `remove` with `id.
57    ///
58    /// A mask should keep track of those states, and an `id` missing from the
59    /// mask is sufficient to call `insert`.
60    unsafe fn insert(&mut self, index: Index, value: T);
61
62    /// Removes the data associated with an `Index`.
63    ///
64    /// # Safety
65    ///
66    /// May only be called if an element with `id` was `insert`ed and not yet
67    /// removed / dropped.
68    unsafe fn remove(&mut self, index: Index) -> T;
69
70    /// Clean the storage given a bitset with bits set for valid indices.
71    /// Allows us to safely drop the storage.
72    ///
73    /// # Safety
74    ///
75    /// May only be called with the mask which keeps track of the elements
76    /// existing in this storage.
77    unsafe fn clean<B>(&mut self, has: B)
78    where
79        B: BitSetLike;
80
81    /// Drops the data associated with an `Index`.
82    /// This could be used when a more efficient implementation for it exists than `remove` when the data
83    /// is no longer needed.
84    /// Defaults to simply calling `remove`.
85    ///
86    /// # Safety
87    ///
88    /// May only be called if an element with `id` was `insert`ed and not yet
89    /// removed / dropped.
90    unsafe fn drop(&mut self, index: Index) {
91        self.remove(index);
92    }
93}
94
95/// This is a marker trait which requires you to uphold the following guarantee:
96///
97/// > Multiple threads may call `get_mut()` with distinct indices without
98/// causing > undefined behavior.
99///
100/// This is for example valid for `Vec`:
101///
102/// ```rust
103/// vec![1, 2, 3];
104/// ```
105///
106/// We may modify both element 1 and 2 at the same time; indexing the vector
107/// mutably does not modify anything else than the respective elements.
108///
109/// As a counter example, we may have some kind of cached storage; it caches
110/// elements when they're retrieved, so pushes a new element to some
111/// cache-vector. This storage is not allowed to implement `DistinctStorage`.
112///
113/// Implementing this trait marks the storage safe for concurrent mutation (of
114/// distinct elements), thus allows `join_par()`.
115pub trait DistinctStorage {}