Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_ecs/src/entity/hash_map.rs
6849 views
1
//! Contains the [`EntityHashMap`] type, a [`HashMap`] pre-configured to use [`EntityHash`] hashing.
2
//!
3
//! This module is a lightweight wrapper around Bevy's [`HashMap`] that is more performant for [`Entity`] keys.
4
5
use core::{
6
fmt::{self, Debug, Formatter},
7
iter::FusedIterator,
8
marker::PhantomData,
9
ops::{Deref, DerefMut, Index},
10
};
11
12
use bevy_platform::collections::hash_map::{self, HashMap};
13
#[cfg(feature = "bevy_reflect")]
14
use bevy_reflect::Reflect;
15
16
use super::{Entity, EntityEquivalent, EntityHash, EntitySetIterator};
17
18
/// A [`HashMap`] pre-configured to use [`EntityHash`] hashing.
19
#[cfg_attr(feature = "bevy_reflect", derive(Reflect))]
20
#[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize))]
21
#[derive(Debug, Clone, PartialEq, Eq)]
22
pub struct EntityHashMap<V>(pub(crate) HashMap<Entity, V, EntityHash>);
23
24
impl<V> EntityHashMap<V> {
25
/// Creates an empty `EntityHashMap`.
26
///
27
/// Equivalent to [`HashMap::with_hasher(EntityHash)`].
28
///
29
/// [`HashMap::with_hasher(EntityHash)`]: HashMap::with_hasher
30
pub const fn new() -> Self {
31
Self(HashMap::with_hasher(EntityHash))
32
}
33
34
/// Creates an empty `EntityHashMap` with the specified capacity.
35
///
36
/// Equivalent to [`HashMap::with_capacity_and_hasher(n, EntityHash)`].
37
///
38
/// [`HashMap:with_capacity_and_hasher(n, EntityHash)`]: HashMap::with_capacity_and_hasher
39
pub fn with_capacity(n: usize) -> Self {
40
Self(HashMap::with_capacity_and_hasher(n, EntityHash))
41
}
42
43
/// Returns the inner [`HashMap`].
44
pub fn into_inner(self) -> HashMap<Entity, V, EntityHash> {
45
self.0
46
}
47
48
/// An iterator visiting all keys in arbitrary order.
49
/// The iterator element type is `&'a Entity`.
50
///
51
/// Equivalent to [`HashMap::keys`].
52
pub fn keys(&self) -> Keys<'_, V> {
53
Keys(self.0.keys(), PhantomData)
54
}
55
56
/// Creates a consuming iterator visiting all the keys in arbitrary order.
57
/// The map cannot be used after calling this.
58
/// The iterator element type is [`Entity`].
59
///
60
/// Equivalent to [`HashMap::into_keys`].
61
pub fn into_keys(self) -> IntoKeys<V> {
62
IntoKeys(self.0.into_keys(), PhantomData)
63
}
64
}
65
66
impl<V> Default for EntityHashMap<V> {
67
fn default() -> Self {
68
Self(Default::default())
69
}
70
}
71
72
impl<V> Deref for EntityHashMap<V> {
73
type Target = HashMap<Entity, V, EntityHash>;
74
75
fn deref(&self) -> &Self::Target {
76
&self.0
77
}
78
}
79
80
impl<V> DerefMut for EntityHashMap<V> {
81
fn deref_mut(&mut self) -> &mut Self::Target {
82
&mut self.0
83
}
84
}
85
86
impl<'a, V: Copy> Extend<&'a (Entity, V)> for EntityHashMap<V> {
87
fn extend<T: IntoIterator<Item = &'a (Entity, V)>>(&mut self, iter: T) {
88
self.0.extend(iter);
89
}
90
}
91
92
impl<'a, V: Copy> Extend<(&'a Entity, &'a V)> for EntityHashMap<V> {
93
fn extend<T: IntoIterator<Item = (&'a Entity, &'a V)>>(&mut self, iter: T) {
94
self.0.extend(iter);
95
}
96
}
97
98
impl<V> Extend<(Entity, V)> for EntityHashMap<V> {
99
fn extend<T: IntoIterator<Item = (Entity, V)>>(&mut self, iter: T) {
100
self.0.extend(iter);
101
}
102
}
103
104
impl<V, const N: usize> From<[(Entity, V); N]> for EntityHashMap<V> {
105
fn from(value: [(Entity, V); N]) -> Self {
106
Self(HashMap::from_iter(value))
107
}
108
}
109
110
impl<V> FromIterator<(Entity, V)> for EntityHashMap<V> {
111
fn from_iter<I: IntoIterator<Item = (Entity, V)>>(iterable: I) -> Self {
112
Self(HashMap::from_iter(iterable))
113
}
114
}
115
116
impl<V, Q: EntityEquivalent + ?Sized> Index<&Q> for EntityHashMap<V> {
117
type Output = V;
118
fn index(&self, key: &Q) -> &V {
119
self.0.index(&key.entity())
120
}
121
}
122
123
impl<'a, V> IntoIterator for &'a EntityHashMap<V> {
124
type Item = (&'a Entity, &'a V);
125
type IntoIter = hash_map::Iter<'a, Entity, V>;
126
127
fn into_iter(self) -> Self::IntoIter {
128
self.0.iter()
129
}
130
}
131
132
impl<'a, V> IntoIterator for &'a mut EntityHashMap<V> {
133
type Item = (&'a Entity, &'a mut V);
134
type IntoIter = hash_map::IterMut<'a, Entity, V>;
135
136
fn into_iter(self) -> Self::IntoIter {
137
self.0.iter_mut()
138
}
139
}
140
141
impl<V> IntoIterator for EntityHashMap<V> {
142
type Item = (Entity, V);
143
type IntoIter = hash_map::IntoIter<Entity, V>;
144
145
fn into_iter(self) -> Self::IntoIter {
146
self.0.into_iter()
147
}
148
}
149
150
/// An iterator over the keys of a [`EntityHashMap`] in arbitrary order.
151
/// The iterator element type is `&'a Entity`.
152
///
153
/// This struct is created by the [`keys`] method on [`EntityHashMap`]. See its documentation for more.
154
///
155
/// [`keys`]: EntityHashMap::keys
156
pub struct Keys<'a, V, S = EntityHash>(hash_map::Keys<'a, Entity, V>, PhantomData<S>);
157
158
impl<'a, V> Keys<'a, V> {
159
/// Returns the inner [`Keys`](hash_map::Keys).
160
pub fn into_inner(self) -> hash_map::Keys<'a, Entity, V> {
161
self.0
162
}
163
}
164
165
impl<'a, V> Deref for Keys<'a, V> {
166
type Target = hash_map::Keys<'a, Entity, V>;
167
168
fn deref(&self) -> &Self::Target {
169
&self.0
170
}
171
}
172
173
impl<'a, V> Iterator for Keys<'a, V> {
174
type Item = &'a Entity;
175
176
fn next(&mut self) -> Option<Self::Item> {
177
self.0.next()
178
}
179
}
180
181
impl<V> ExactSizeIterator for Keys<'_, V> {}
182
183
impl<V> FusedIterator for Keys<'_, V> {}
184
185
impl<V> Clone for Keys<'_, V> {
186
fn clone(&self) -> Self {
187
Self(self.0.clone(), PhantomData)
188
}
189
}
190
191
impl<V: Debug> Debug for Keys<'_, V> {
192
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
193
f.debug_tuple("Keys").field(&self.0).field(&self.1).finish()
194
}
195
}
196
197
impl<V> Default for Keys<'_, V> {
198
fn default() -> Self {
199
Self(Default::default(), PhantomData)
200
}
201
}
202
203
// SAFETY: Keys stems from a correctly behaving `HashMap<Entity, V, EntityHash>`.
204
unsafe impl<V> EntitySetIterator for Keys<'_, V> {}
205
206
/// An owning iterator over the keys of a [`EntityHashMap`] in arbitrary order.
207
/// The iterator element type is [`Entity`].
208
///
209
/// This struct is created by the [`into_keys`] method on [`EntityHashMap`].
210
/// See its documentation for more.
211
/// The map cannot be used after calling that method.
212
///
213
/// [`into_keys`]: EntityHashMap::into_keys
214
pub struct IntoKeys<V, S = EntityHash>(hash_map::IntoKeys<Entity, V>, PhantomData<S>);
215
216
impl<V> IntoKeys<V> {
217
/// Returns the inner [`IntoKeys`](hash_map::IntoKeys).
218
pub fn into_inner(self) -> hash_map::IntoKeys<Entity, V> {
219
self.0
220
}
221
}
222
223
impl<V> Deref for IntoKeys<V> {
224
type Target = hash_map::IntoKeys<Entity, V>;
225
226
fn deref(&self) -> &Self::Target {
227
&self.0
228
}
229
}
230
231
impl<V> Iterator for IntoKeys<V> {
232
type Item = Entity;
233
234
fn next(&mut self) -> Option<Self::Item> {
235
self.0.next()
236
}
237
}
238
239
impl<V> ExactSizeIterator for IntoKeys<V> {}
240
241
impl<V> FusedIterator for IntoKeys<V> {}
242
243
impl<V: Debug> Debug for IntoKeys<V> {
244
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
245
f.debug_tuple("IntoKeys")
246
.field(&self.0)
247
.field(&self.1)
248
.finish()
249
}
250
}
251
252
impl<V> Default for IntoKeys<V> {
253
fn default() -> Self {
254
Self(Default::default(), PhantomData)
255
}
256
}
257
258
// SAFETY: IntoKeys stems from a correctly behaving `HashMap<Entity, V, EntityHash>`.
259
unsafe impl<V> EntitySetIterator for IntoKeys<V> {}
260
261
#[cfg(test)]
262
mod tests {
263
use super::*;
264
use bevy_reflect::Reflect;
265
use static_assertions::assert_impl_all;
266
267
// Check that the HashMaps are Clone if the key/values are Clone
268
assert_impl_all!(EntityHashMap::<usize>: Clone);
269
// EntityHashMap should implement Reflect
270
#[cfg(feature = "bevy_reflect")]
271
assert_impl_all!(EntityHashMap::<i32>: Reflect);
272
}
273
274