fyrox_impl/renderer/cache/
mod.rs1#![allow(missing_docs)] use crate::{
24 asset::entry::DEFAULT_RESOURCE_LIFETIME,
25 core::sparse::{AtomicIndex, SparseBuffer},
26 scene::mesh::{
27 buffer::{BytesStorage, TriangleBuffer, VertexAttributeDescriptor, VertexBuffer},
28 surface::{SurfaceData, SurfaceResource},
29 },
30};
31use fxhash::FxHashMap;
32use fyrox_resource::untyped::ResourceKind;
33use std::{
34 ops::{Deref, DerefMut},
35 sync::Arc,
36};
37use uuid::Uuid;
38
39pub mod geometry;
40pub mod shader;
41pub mod texture;
42pub mod uniform;
43
44#[derive(Copy, Clone, PartialEq)]
45pub struct TimeToLive(pub f32);
46
47impl Default for TimeToLive {
48 fn default() -> Self {
49 Self(DEFAULT_RESOURCE_LIFETIME)
50 }
51}
52
53impl Deref for TimeToLive {
54 type Target = f32;
55
56 fn deref(&self) -> &Self::Target {
57 &self.0
58 }
59}
60
61impl DerefMut for TimeToLive {
62 fn deref_mut(&mut self) -> &mut Self::Target {
63 &mut self.0
64 }
65}
66
67pub struct CacheEntry<T> {
68 pub value: T,
69 pub time_to_live: TimeToLive,
70 pub self_index: Arc<AtomicIndex>,
71}
72
73impl<T> Drop for CacheEntry<T> {
74 fn drop(&mut self) {
75 self.self_index.set(AtomicIndex::UNASSIGNED_INDEX)
82 }
83}
84
85impl<T> Deref for CacheEntry<T> {
86 type Target = T;
87
88 fn deref(&self) -> &Self::Target {
89 &self.value
90 }
91}
92
93impl<T> DerefMut for CacheEntry<T> {
94 fn deref_mut(&mut self) -> &mut Self::Target {
95 &mut self.value
96 }
97}
98
99pub struct TemporaryCache<T> {
100 pub buffer: SparseBuffer<CacheEntry<T>>,
101}
102
103impl<T> Default for TemporaryCache<T> {
104 fn default() -> Self {
105 Self {
106 buffer: Default::default(),
107 }
108 }
109}
110
111impl<T> TemporaryCache<T> {
112 pub fn spawn(
113 &mut self,
114 value: T,
115 self_index: Arc<AtomicIndex>,
116 time_to_live: TimeToLive,
117 ) -> AtomicIndex {
118 let index = self.buffer.spawn(CacheEntry {
119 value,
120 time_to_live,
121 self_index,
122 });
123
124 self.buffer
125 .get_mut(&index)
126 .unwrap()
127 .self_index
128 .set(index.get());
129
130 index
131 }
132
133 pub fn get_mut(&mut self, index: &AtomicIndex) -> Option<&mut CacheEntry<T>> {
134 if let Some(entry) = self.buffer.get_mut(index) {
135 entry.time_to_live = TimeToLive::default();
136 Some(entry)
137 } else {
138 None
139 }
140 }
141
142 pub fn get_entry_mut_or_insert_with<F, E>(
143 &mut self,
144 index: &Arc<AtomicIndex>,
145 time_to_live: TimeToLive,
146 func: F,
147 ) -> Result<&mut CacheEntry<T>, E>
148 where
149 F: FnOnce() -> Result<T, E>,
150 {
151 if let Some(entry) = self.buffer.get_mut(index) {
152 entry.time_to_live = time_to_live;
153 Ok(self.buffer.get_mut(index).unwrap())
154 } else {
155 let value = func()?;
156 let index = self.buffer.spawn(CacheEntry {
157 value,
158 time_to_live,
159 self_index: index.clone(),
160 });
161 let entry = self.buffer.get_mut(&index).unwrap();
162 entry.self_index.set(index.get());
163 Ok(entry)
164 }
165 }
166
167 pub fn get_mut_or_insert_with<F, E>(
168 &mut self,
169 index: &Arc<AtomicIndex>,
170 time_to_live: TimeToLive,
171 func: F,
172 ) -> Result<&mut T, E>
173 where
174 F: FnOnce() -> Result<T, E>,
175 {
176 self.get_entry_mut_or_insert_with(index, time_to_live, func)
177 .map(|entry| &mut entry.value)
178 }
179
180 pub fn get_or_insert_with<F, E>(
181 &mut self,
182 index: &Arc<AtomicIndex>,
183 time_to_live: TimeToLive,
184 func: F,
185 ) -> Result<&T, E>
186 where
187 F: FnOnce() -> Result<T, E>,
188 {
189 self.get_entry_mut_or_insert_with(index, time_to_live, func)
190 .map(|entry| &entry.value)
191 }
192
193 pub fn update(&mut self, dt: f32) {
194 for entry in self.buffer.iter_mut() {
195 *entry.time_to_live -= dt;
196 }
197
198 for i in 0..self.buffer.len() {
199 if let Some(entry) = self.buffer.get_raw(i) {
200 if *entry.time_to_live <= 0.0 {
201 self.buffer.free_raw(i);
202 }
203 }
204 }
205 }
206
207 pub fn clear(&mut self) {
208 self.buffer.clear();
209 }
210
211 pub fn alive_count(&self) -> usize {
212 self.buffer.filled()
213 }
214
215 pub fn remove(&mut self, index: &AtomicIndex) {
216 self.buffer.free(index);
217 }
218}
219
220#[derive(Default)]
225pub struct DynamicSurfaceCache {
226 cache: FxHashMap<u64, SurfaceResource>,
227}
228
229impl DynamicSurfaceCache {
230 pub fn new() -> Self {
232 Self::default()
233 }
234
235 pub fn get_or_create(
238 &mut self,
239 unique_id: u64,
240 layout: &[VertexAttributeDescriptor],
241 ) -> SurfaceResource {
242 if let Some(surface) = self.cache.get(&unique_id) {
243 surface.clone()
244 } else {
245 let default_capacity = 4096;
246
247 let vertex_buffer = VertexBuffer::new_with_layout(
249 layout,
250 0,
251 BytesStorage::with_capacity(default_capacity),
252 )
253 .unwrap();
254
255 let triangle_buffer = TriangleBuffer::new(Vec::with_capacity(default_capacity * 3));
257
258 let surface = SurfaceResource::new_ok(
259 Uuid::new_v4(),
260 ResourceKind::Embedded,
261 SurfaceData::new(vertex_buffer, triangle_buffer),
262 );
263
264 self.cache.insert(unique_id, surface.clone());
265
266 surface
267 }
268 }
269
270 pub fn clear(&mut self) {
272 for surface in self.cache.values_mut() {
273 let mut surface_data = surface.data_ref();
274 surface_data.vertex_buffer.modify().clear();
275 surface_data.geometry_buffer.modify().clear();
276 }
277 }
278}