Skip to main content

gizmo_core/
asset.rs

1use std::collections::HashMap;
2use std::hash::{Hash, Hasher};
3use std::marker::PhantomData;
4use std::sync::atomic::{AtomicUsize, Ordering};
5
6static NEXT_HANDLE_ID: AtomicUsize = AtomicUsize::new(1);
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
9pub struct HandleId(pub usize);
10
11impl Default for HandleId {
12    fn default() -> Self {
13        Self::new()
14    }
15}
16
17impl HandleId {
18    pub fn new() -> Self {
19        HandleId(NEXT_HANDLE_ID.fetch_add(1, Ordering::Relaxed))
20    }
21}
22
23pub struct Handle<T> {
24    pub id: HandleId,
25    _marker: PhantomData<T>,
26}
27
28impl<T> Default for Handle<T> {
29    fn default() -> Self {
30        Self::new()
31    }
32}
33
34impl<T> Handle<T> {
35    pub fn new() -> Self {
36        Self {
37            id: HandleId::new(),
38            _marker: PhantomData,
39        }
40    }
41
42    pub fn weak(id: HandleId) -> Self {
43        Self {
44            id,
45            _marker: PhantomData,
46        }
47    }
48}
49
50impl<T> Clone for Handle<T> {
51    fn clone(&self) -> Self {
52        Self {
53            id: self.id,
54            _marker: PhantomData,
55        }
56    }
57}
58
59impl<T> PartialEq for Handle<T> {
60    fn eq(&self, other: &Self) -> bool {
61        self.id == other.id
62    }
63}
64
65impl<T> Eq for Handle<T> {}
66
67impl<T> Hash for Handle<T> {
68    fn hash<H: Hasher>(&self, state: &mut H) {
69        self.id.hash(state);
70    }
71}
72
73impl<T: 'static + Send + Sync> crate::component::Component for Handle<T> {}
74
75impl<T> std::fmt::Debug for Handle<T> {
76    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
77        write!(f, "Handle({:?})", self.id)
78    }
79}
80
81/// Generic resource to store assets by their handle ID.
82pub struct Assets<T> {
83    pub data: HashMap<HandleId, T>,
84}
85
86impl<T> Default for Assets<T> {
87    fn default() -> Self {
88        Self {
89            data: HashMap::new(),
90        }
91    }
92}
93
94impl<T> Assets<T> {
95    pub fn new() -> Self {
96        Self::default()
97    }
98
99    pub fn add(&mut self, asset: T) -> Handle<T> {
100        let id = HandleId::new();
101        self.data.insert(id, asset);
102        Handle::weak(id)
103    }
104
105    pub fn get(&self, handle: &Handle<T>) -> Option<&T> {
106        self.data.get(&handle.id)
107    }
108
109    pub fn get_mut(&mut self, handle: &Handle<T>) -> Option<&mut T> {
110        self.data.get_mut(&handle.id)
111    }
112
113    pub fn insert(&mut self, handle: &Handle<T>, asset: T) {
114        self.data.insert(handle.id, asset);
115    }
116
117    pub fn remove(&mut self, handle: &Handle<T>) -> Option<T> {
118        self.data.remove(&handle.id)
119    }
120}