1use slotmap::{SecondaryMap, SlotMap, new_key_type};
2use std::collections::HashMap;
3
4new_key_type! {
5 pub struct RawAssetHandle;
11}
12
13pub struct Assets<T: 'static + Send + Sync> {
20 storage: SlotMap<RawAssetHandle, T>,
21 handles: HashMap<String, RawAssetHandle>,
22 queue: Vec<RawAssetHandle>,
23}
24
25impl<T: 'static + Send + Sync> Assets<T> {
26 pub fn new() -> Self {
27 Self {
28 storage: SlotMap::with_key(),
29 handles: HashMap::new(),
30 queue: Vec::new(),
31 }
32 }
33
34 pub fn insert(&mut self, name: &str, asset: T) -> RawAssetHandle {
39 let handle = self.storage.insert(asset);
40 self.queue.push(handle);
41
42 if let Some(old) = self.handles.insert(name.to_string(), handle) {
43 self.storage.remove(old);
44 self.queue.retain(|h| *h != old);
45 }
46 handle
47 }
48
49 pub fn get(&self, handle: RawAssetHandle) -> Option<&T> {
51 self.storage.get(handle)
52 }
53
54 pub fn get_mut(&mut self, handle: RawAssetHandle) -> Option<&mut T> {
56 self.storage.get_mut(handle)
57 }
58
59 pub fn get_by_name(&self, name: &str) -> Option<&T> {
61 self.handles
62 .get(name)
63 .and_then(|&handle| self.storage.get(handle))
64 }
65
66 pub fn get_mut_by_name(&mut self, name: &str) -> Option<&mut T> {
68 let handle = self.handles.get(name).copied()?;
69 self.storage.get_mut(handle)
70 }
71
72 pub fn get_handle_by_name(&self, name: &str) -> Option<RawAssetHandle> {
74 self.handles.get(name).copied()
75 }
76
77 pub fn take_dirty(&mut self) -> Vec<RawAssetHandle> {
81 std::mem::take(&mut self.queue)
82 }
83
84 pub fn remove(&mut self, handle: RawAssetHandle) -> Option<T> {
86 let value = self.storage.remove(handle)?;
87
88 self.handles.retain(|_, h| *h != handle);
89 self.queue.retain(|h| *h != handle);
90
91 Some(value)
92 }
93
94 pub fn remove_by_name(&mut self, name: &str) -> Option<T> {
96 let handle = self.handles.remove(name)?;
97 self.storage.remove(handle)
98 }
99
100 pub fn dirty_is_empty(&self) -> bool {
102 self.queue.is_empty()
103 }
104
105 pub fn dirty_len(&self) -> usize {
107 self.queue.len()
108 }
109
110 pub fn requeue(&mut self, handles: Vec<RawAssetHandle>) {
112 self.queue.extend(handles);
113 }
114
115 pub fn iter(&self) -> impl Iterator<Item = (RawAssetHandle, &T)> {
117 self.storage.iter()
118 }
119
120 pub fn iter_mut(&mut self) -> impl Iterator<Item = (RawAssetHandle, &mut T)> {
122 self.storage.iter_mut()
123 }
124
125 pub fn names(&self) -> impl Iterator<Item = (&str, RawAssetHandle)> {
127 self.handles
128 .iter()
129 .map(|(name, &handle)| (name.as_str(), handle))
130 }
131}
132
133impl<'a, T: 'static + Send + Sync> IntoIterator for &'a Assets<T> {
134 type Item = (RawAssetHandle, &'a T);
135 type IntoIter = slotmap::basic::Iter<'a, RawAssetHandle, T>;
136
137 fn into_iter(self) -> Self::IntoIter {
138 self.storage.iter()
139 }
140}
141
142impl<'a, T: 'static + Send + Sync> IntoIterator for &'a mut Assets<T> {
143 type Item = (RawAssetHandle, &'a mut T);
144 type IntoIter = slotmap::basic::IterMut<'a, RawAssetHandle, T>;
145
146 fn into_iter(self) -> Self::IntoIter {
147 self.storage.iter_mut()
148 }
149}
150
151pub struct ProcessedAssets<T: 'static + Send + Sync> {
156 storage: SecondaryMap<RawAssetHandle, T>,
157}
158
159impl<T: 'static + Send + Sync> ProcessedAssets<T> {
160 pub fn new() -> Self {
161 Self {
162 storage: SecondaryMap::new(),
163 }
164 }
165
166 pub fn insert(&mut self, handle: RawAssetHandle, asset: T) -> Option<T> {
168 self.storage.insert(handle, asset)
169 }
170
171 pub fn get(&self, handle: RawAssetHandle) -> Option<&T> {
173 self.storage.get(handle)
174 }
175
176 pub fn get_mut(&mut self, handle: RawAssetHandle) -> Option<&mut T> {
178 self.storage.get_mut(handle)
179 }
180
181 pub fn remove(&mut self, handle: RawAssetHandle) -> Option<T> {
183 self.storage.remove(handle)
184 }
185
186 pub fn contains(&self, handle: RawAssetHandle) -> bool {
188 self.storage.contains_key(handle)
189 }
190
191 pub fn iter(&self) -> impl Iterator<Item = (RawAssetHandle, &T)> {
193 self.storage.iter()
194 }
195
196 pub fn iter_mut(&mut self) -> impl Iterator<Item = (RawAssetHandle, &mut T)> {
198 self.storage.iter_mut()
199 }
200}
201
202impl<'a, T: 'static + Send + Sync> IntoIterator for &'a ProcessedAssets<T> {
203 type Item = (RawAssetHandle, &'a T);
204 type IntoIter = slotmap::secondary::Iter<'a, RawAssetHandle, T>;
205
206 fn into_iter(self) -> Self::IntoIter {
207 self.storage.iter()
208 }
209}
210
211impl<'a, T: 'static + Send + Sync> IntoIterator for &'a mut ProcessedAssets<T> {
212 type Item = (RawAssetHandle, &'a mut T);
213 type IntoIter = slotmap::secondary::IterMut<'a, RawAssetHandle, T>;
214
215 fn into_iter(self) -> Self::IntoIter {
216 self.storage.iter_mut()
217 }
218}