rafx_framework/render_features/
render_objects.rs1use crate::render_features::render_features_prelude::*;
2use rafx_base::slab::{DropSlab, GenericDropSlabKey, RawSlabKey, SlabIndexT};
3use std::cmp::Ordering;
4use std::hash::{Hash, Hasher};
5use std::marker::PhantomData;
6use std::sync::Arc;
7
8pub type RenderObjectsMap<RenderObjectStaticDataT> =
9 RenderObjectSetStorage<RenderObjectStaticDataT>;
10
11pub type RenderObjectCount = u32;
12
13type RenderObjectSetKey = GenericDropSlabKey;
14
15#[derive(Clone, Debug)]
20pub struct RenderObjectHandle {
21 render_feature_index: RenderFeatureIndex,
22 render_object_set_key: RenderObjectSetKey,
23}
24
25#[derive(Copy, Eq, PartialEq, Hash, Clone, Debug)]
30pub struct RenderObjectId {
31 render_feature_index: RenderFeatureIndex,
32 render_object_set_index: SlabIndexT,
33}
34
35impl Ord for RenderObjectId {
36 fn cmp(
37 &self,
38 other: &Self,
39 ) -> Ordering {
40 self.render_feature_index
41 .cmp(&other.render_feature_index)
42 .then(
43 self.render_object_set_index
44 .cmp(&other.render_object_set_index),
45 )
46 }
47}
48
49impl PartialOrd for RenderObjectId {
50 fn partial_cmp(
51 &self,
52 other: &Self,
53 ) -> Option<Ordering> {
54 Some(self.cmp(other))
55 }
56}
57
58impl Default for RenderObjectId {
59 fn default() -> Self {
60 Self {
61 render_feature_index: RenderFeatureIndex::MAX,
62 render_object_set_index: SlabIndexT::MAX,
63 }
64 }
65}
66
67impl Eq for RenderObjectHandle {}
68
69impl PartialEq for RenderObjectHandle {
70 fn eq(
71 &self,
72 other: &Self,
73 ) -> bool {
74 self.render_feature_index == other.render_feature_index
75 && self.render_object_set_key.index() == other.render_object_set_key.index()
76 }
77}
78
79impl Hash for RenderObjectHandle {
80 fn hash<H: Hasher>(
81 &self,
82 state: &mut H,
83 ) {
84 self.render_feature_index.hash(state);
85 self.render_object_set_key.index().hash(state);
86 }
87}
88
89impl RenderObjectHandle {
90 fn new(
91 render_feature_index: RenderFeatureIndex,
92 render_object_id: RenderObjectSetKey,
93 ) -> Self {
94 RenderObjectHandle {
95 render_feature_index,
96 render_object_set_key: render_object_id,
97 }
98 }
99
100 pub fn render_feature_index(&self) -> RenderFeatureIndex {
101 self.render_feature_index
102 }
103
104 pub fn as_id(&self) -> RenderObjectId {
105 RenderObjectId {
106 render_feature_index: self.render_feature_index,
107 render_object_set_index: self.render_object_set_key.index(),
108 }
109 }
110}
111
112impl RenderObjectId {
113 #[inline(always)]
114 pub fn render_feature_index(&self) -> RenderFeatureIndex {
115 self.render_feature_index
116 }
117}
118
119pub struct RenderObjectSet<RenderFeatureT: RenderFeature, RenderObjectStaticDataT> {
120 storage: Arc<RwLock<RenderObjectsMap<RenderObjectStaticDataT>>>,
121 _phantom: PhantomData<RenderFeatureT>,
122}
123
124impl<RenderFeatureT: RenderFeature, RenderObjectStaticDataT> Clone
125 for RenderObjectSet<RenderFeatureT, RenderObjectStaticDataT>
126{
127 fn clone(&self) -> Self {
128 Self {
129 storage: self.storage.clone(),
130 _phantom: Default::default(),
131 }
132 }
133}
134
135impl<RenderFeatureT: RenderFeature, RenderObjectStaticDataT>
136 RenderObjectSet<RenderFeatureT, RenderObjectStaticDataT>
137{
138 pub fn new() -> Self {
139 Self {
140 storage: Arc::new(RwLock::new(RenderObjectSetStorage::new())),
141 _phantom: Default::default(),
142 }
143 }
144
145 pub fn register_render_object(
146 &mut self,
147 render_object: RenderObjectStaticDataT,
148 ) -> RenderObjectHandle {
149 let render_object_handle = {
150 let mut render_objects = self.write();
151 render_objects.register_render_object(RenderFeatureT::feature_index(), render_object)
152 };
153
154 render_object_handle
155 }
156
157 pub fn read(&self) -> RwLockReadGuard<RenderObjectsMap<RenderObjectStaticDataT>> {
158 let registry = &self.storage;
159 registry.try_read().unwrap_or_else(move || {
160 log::warn!(
161 "{} is being written by another thread.",
162 std::any::type_name::<RenderObjectsMap<RenderObjectStaticDataT>>()
163 );
164
165 registry.read()
166 })
167 }
168
169 fn write(&mut self) -> RwLockWriteGuard<RenderObjectsMap<RenderObjectStaticDataT>> {
170 let registry = &self.storage;
171 registry.try_write().unwrap_or_else(move || {
172 log::warn!(
173 "{} is being read or written by another thread.",
174 std::any::type_name::<RenderObjectsMap<RenderObjectStaticDataT>>()
175 );
176
177 registry.write()
178 })
179 }
180
181 #[allow(dead_code)]
182 fn feature_index(&self) -> RenderFeatureIndex {
183 RenderFeatureT::feature_index()
184 }
185}
186
187impl<RenderFeatureT: RenderFeature, RenderObjectStaticDataT> Default
188 for RenderObjectSet<RenderFeatureT, RenderObjectStaticDataT>
189{
190 fn default() -> Self {
191 Self::new()
192 }
193}
194
195pub struct RenderObjectSetStorage<RenderObjectStaticDataT> {
196 inner: DropSlab<RenderObjectStaticDataT>,
197}
198
199impl<RenderObjectStaticDataT> RenderObjectSetStorage<RenderObjectStaticDataT> {
200 pub fn new() -> Self {
201 Self {
202 inner: Default::default(),
203 }
204 }
205
206 pub fn len(&self) -> RenderObjectCount {
207 self.inner.allocated_count() as RenderObjectCount
208 }
209
210 pub fn register_render_object(
211 &mut self,
212 feature_index: RenderFeatureIndex,
213 render_object: RenderObjectStaticDataT,
214 ) -> RenderObjectHandle {
215 self.inner.process_drops();
216
217 let drop_slab_key = self.inner.allocate(render_object);
218 RenderObjectHandle::new(feature_index, drop_slab_key.generic_drop_slab_key())
219 }
220
221 pub fn get_id(
222 &self,
223 render_object: &RenderObjectId,
224 ) -> &RenderObjectStaticDataT {
225 let raw_slab_key =
226 RawSlabKey::<RenderObjectStaticDataT>::new(render_object.render_object_set_index);
227
228 self.inner.get_raw(raw_slab_key).unwrap_or_else(|| {
229 panic!(
230 "{} did not contain id {:?}.",
231 std::any::type_name::<RenderObjectsMap<RenderObjectStaticDataT>>(),
232 render_object
233 )
234 })
235 }
236
237 pub fn get(
238 &self,
239 render_object: &RenderObjectHandle,
240 ) -> &RenderObjectStaticDataT {
241 self.inner
242 .get(&render_object.render_object_set_key.drop_slab_key())
243 .unwrap_or_else(|| {
244 panic!(
245 "{} did not contain handle {:?}.",
246 std::any::type_name::<RenderObjectsMap<RenderObjectStaticDataT>>(),
247 render_object
248 )
249 })
250 }
251
252 pub fn get_mut(
253 &mut self,
254 render_object: &RenderObjectHandle,
255 ) -> &mut RenderObjectStaticDataT {
256 self.inner
257 .get_mut(&render_object.render_object_set_key.drop_slab_key())
258 .unwrap_or_else(|| {
259 panic!(
260 "{} did not contain handle {:?}.",
261 std::any::type_name::<RenderObjectsMap<RenderObjectStaticDataT>>(),
262 render_object
263 )
264 })
265 }
266}
267
268impl<RenderObjectStaticDataT> Default for RenderObjectSetStorage<RenderObjectStaticDataT> {
269 fn default() -> Self {
270 Self::new()
271 }
272}