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 take_dirty(&mut self) -> Vec<RawAssetHandle> {
76 std::mem::take(&mut self.queue)
77 }
78
79 pub fn remove(&mut self, handle: RawAssetHandle) -> Option<T> {
81 let value = self.storage.remove(handle)?;
82
83 self.handles.retain(|_, h| *h != handle);
84 self.queue.retain(|h| *h != handle);
85
86 Some(value)
87 }
88
89 pub fn remove_by_name(&mut self, name: &str) -> Option<T> {
91 let handle = self.handles.remove(name)?;
92 self.storage.remove(handle)
93 }
94
95 pub fn dirty_is_empty(&self) -> bool {
97 self.queue.is_empty()
98 }
99
100 pub fn dirty_len(&self) -> usize {
102 self.queue.len()
103 }
104
105 pub fn requeue(&mut self, handles: Vec<RawAssetHandle>) {
107 self.queue.extend(handles);
108 }
109
110 pub fn iter(&self) -> impl Iterator<Item = (RawAssetHandle, &T)> {
112 self.storage.iter()
113 }
114
115 pub fn iter_mut(&mut self) -> impl Iterator<Item = (RawAssetHandle, &mut T)> {
117 self.storage.iter_mut()
118 }
119
120 pub fn names(&self) -> impl Iterator<Item = (&str, RawAssetHandle)> {
122 self.handles
123 .iter()
124 .map(|(name, &handle)| (name.as_str(), handle))
125 }
126}
127
128impl<'a, T: 'static + Send + Sync> IntoIterator for &'a Assets<T> {
129 type Item = (RawAssetHandle, &'a T);
130 type IntoIter = slotmap::basic::Iter<'a, RawAssetHandle, T>;
131
132 fn into_iter(self) -> Self::IntoIter {
133 self.storage.iter()
134 }
135}
136
137impl<'a, T: 'static + Send + Sync> IntoIterator for &'a mut Assets<T> {
138 type Item = (RawAssetHandle, &'a mut T);
139 type IntoIter = slotmap::basic::IterMut<'a, RawAssetHandle, T>;
140
141 fn into_iter(self) -> Self::IntoIter {
142 self.storage.iter_mut()
143 }
144}
145
146pub struct ProcessedAssets<T: 'static + Send + Sync> {
151 storage: SecondaryMap<RawAssetHandle, T>,
152}
153
154impl<T: 'static + Send + Sync> ProcessedAssets<T> {
155 pub fn new() -> Self {
156 Self {
157 storage: SecondaryMap::new(),
158 }
159 }
160
161 pub fn insert(&mut self, handle: RawAssetHandle, asset: T) -> Option<T> {
163 self.storage.insert(handle, asset)
164 }
165
166 pub fn get(&self, handle: RawAssetHandle) -> Option<&T> {
168 self.storage.get(handle)
169 }
170
171 pub fn get_mut(&mut self, handle: RawAssetHandle) -> Option<&mut T> {
173 self.storage.get_mut(handle)
174 }
175
176 pub fn remove(&mut self, handle: RawAssetHandle) -> Option<T> {
178 self.storage.remove(handle)
179 }
180
181 pub fn contains(&self, handle: RawAssetHandle) -> bool {
183 self.storage.contains_key(handle)
184 }
185
186 pub fn iter(&self) -> impl Iterator<Item = (RawAssetHandle, &T)> {
188 self.storage.iter()
189 }
190
191 pub fn iter_mut(&mut self) -> impl Iterator<Item = (RawAssetHandle, &mut T)> {
193 self.storage.iter_mut()
194 }
195}
196
197impl<'a, T: 'static + Send + Sync> IntoIterator for &'a ProcessedAssets<T> {
198 type Item = (RawAssetHandle, &'a T);
199 type IntoIter = slotmap::secondary::Iter<'a, RawAssetHandle, T>;
200
201 fn into_iter(self) -> Self::IntoIter {
202 self.storage.iter()
203 }
204}
205
206impl<'a, T: 'static + Send + Sync> IntoIterator for &'a mut ProcessedAssets<T> {
207 type Item = (RawAssetHandle, &'a mut T);
208 type IntoIter = slotmap::secondary::IterMut<'a, RawAssetHandle, T>;
209
210 fn into_iter(self) -> Self::IntoIter {
211 self.storage.iter_mut()
212 }
213}