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
111pub struct ProcessedAssets<T: 'static + Send + Sync> {
116 storage: SecondaryMap<RawAssetHandle, T>,
117}
118
119impl<T: 'static + Send + Sync> ProcessedAssets<T> {
120 pub fn new() -> Self {
121 Self {
122 storage: SecondaryMap::new(),
123 }
124 }
125
126 pub fn insert(&mut self, handle: RawAssetHandle, asset: T) -> Option<T> {
128 self.storage.insert(handle, asset)
129 }
130
131 pub fn get(&self, handle: RawAssetHandle) -> Option<&T> {
133 self.storage.get(handle)
134 }
135
136 pub fn get_mut(&mut self, handle: RawAssetHandle) -> Option<&mut T> {
138 self.storage.get_mut(handle)
139 }
140
141 pub fn remove(&mut self, handle: RawAssetHandle) -> Option<T> {
143 self.storage.remove(handle)
144 }
145
146 pub fn contains(&self, handle: RawAssetHandle) -> bool {
148 self.storage.contains_key(handle)
149 }
150}