fyrox_impl/renderer/cache/
mod.rs1#![allow(missing_docs)] use crate::{
24 asset::entry::DEFAULT_RESOURCE_LIFETIME,
25 core::sparse::{AtomicIndex, SparseBuffer},
26};
27use std::{
28 ops::{Deref, DerefMut},
29 sync::Arc,
30};
31
32pub mod geometry;
33pub mod shader;
34pub mod texture;
35pub mod uniform;
36
37#[derive(Copy, Clone, PartialEq)]
38pub struct TimeToLive(pub f32);
39
40impl Default for TimeToLive {
41 fn default() -> Self {
42 Self(DEFAULT_RESOURCE_LIFETIME)
43 }
44}
45
46impl Deref for TimeToLive {
47 type Target = f32;
48
49 fn deref(&self) -> &Self::Target {
50 &self.0
51 }
52}
53
54impl DerefMut for TimeToLive {
55 fn deref_mut(&mut self) -> &mut Self::Target {
56 &mut self.0
57 }
58}
59
60pub struct CacheEntry<T> {
61 pub value: T,
62 pub time_to_live: TimeToLive,
63 pub self_index: Arc<AtomicIndex>,
64}
65
66impl<T> Drop for CacheEntry<T> {
67 fn drop(&mut self) {
68 self.self_index.set(AtomicIndex::UNASSIGNED_INDEX)
75 }
76}
77
78impl<T> Deref for CacheEntry<T> {
79 type Target = T;
80
81 fn deref(&self) -> &Self::Target {
82 &self.value
83 }
84}
85
86impl<T> DerefMut for CacheEntry<T> {
87 fn deref_mut(&mut self) -> &mut Self::Target {
88 &mut self.value
89 }
90}
91
92pub struct TemporaryCache<T> {
93 pub buffer: SparseBuffer<CacheEntry<T>>,
94}
95
96impl<T> Default for TemporaryCache<T> {
97 fn default() -> Self {
98 Self {
99 buffer: Default::default(),
100 }
101 }
102}
103
104impl<T> TemporaryCache<T> {
105 pub fn spawn(
106 &mut self,
107 value: T,
108 self_index: Arc<AtomicIndex>,
109 time_to_live: TimeToLive,
110 ) -> AtomicIndex {
111 let index = self.buffer.spawn(CacheEntry {
112 value,
113 time_to_live,
114 self_index,
115 });
116
117 self.buffer
118 .get_mut(&index)
119 .unwrap()
120 .self_index
121 .set(index.get());
122
123 index
124 }
125
126 pub fn get_mut(&mut self, index: &AtomicIndex) -> Option<&mut CacheEntry<T>> {
127 if let Some(entry) = self.buffer.get_mut(index) {
128 entry.time_to_live = TimeToLive::default();
129 Some(entry)
130 } else {
131 None
132 }
133 }
134
135 pub fn get_entry_mut_or_insert_with<F, E>(
136 &mut self,
137 index: &Arc<AtomicIndex>,
138 time_to_live: TimeToLive,
139 func: F,
140 ) -> Result<&mut CacheEntry<T>, E>
141 where
142 F: FnOnce() -> Result<T, E>,
143 {
144 if let Some(entry) = self.buffer.get_mut(index) {
145 entry.time_to_live = time_to_live;
146 Ok(self.buffer.get_mut(index).unwrap())
147 } else {
148 let value = func()?;
149 let index = self.buffer.spawn(CacheEntry {
150 value,
151 time_to_live,
152 self_index: index.clone(),
153 });
154 let entry = self.buffer.get_mut(&index).unwrap();
155 entry.self_index.set(index.get());
156 Ok(entry)
157 }
158 }
159
160 pub fn get_mut_or_insert_with<F, E>(
161 &mut self,
162 index: &Arc<AtomicIndex>,
163 time_to_live: TimeToLive,
164 func: F,
165 ) -> Result<&mut T, E>
166 where
167 F: FnOnce() -> Result<T, E>,
168 {
169 self.get_entry_mut_or_insert_with(index, time_to_live, func)
170 .map(|entry| &mut entry.value)
171 }
172
173 pub fn get_or_insert_with<F, E>(
174 &mut self,
175 index: &Arc<AtomicIndex>,
176 time_to_live: TimeToLive,
177 func: F,
178 ) -> Result<&T, E>
179 where
180 F: FnOnce() -> Result<T, E>,
181 {
182 self.get_entry_mut_or_insert_with(index, time_to_live, func)
183 .map(|entry| &entry.value)
184 }
185
186 pub fn update(&mut self, dt: f32) {
187 for entry in self.buffer.iter_mut() {
188 *entry.time_to_live -= dt;
189 }
190
191 for i in 0..self.buffer.len() {
192 if let Some(entry) = self.buffer.get_raw(i) {
193 if *entry.time_to_live <= 0.0 {
194 self.buffer.free_raw(i);
195 }
196 }
197 }
198 }
199
200 pub fn clear(&mut self) {
201 self.buffer.clear();
202 }
203
204 pub fn alive_count(&self) -> usize {
205 self.buffer.filled()
206 }
207
208 pub fn remove(&mut self, index: &AtomicIndex) {
209 self.buffer.free(index);
210 }
211}