rendy_resource/
resources.rs1use {
2 crate::escape::{Escape, Handle, Terminal},
3 smallvec::SmallVec,
4 std::collections::VecDeque,
5};
6
7#[doc(hidden)]
9#[derive(Clone, Debug)]
10pub struct Epochs {
11 pub values: SmallVec<[SmallVec<[u64; 8]>; 4]>,
13}
14
15impl Epochs {
16 fn is_before(&self, other: &Self) -> bool {
17 debug_assert_eq!(self.values.len(), other.values.len());
18 self.values.iter().zip(other.values.iter()).all(|(a, b)| {
19 debug_assert_eq!(a.len(), b.len());
20 a.iter().zip(b.iter()).all(|(a, b)| a < b)
21 })
22 }
23}
24
25#[derive(Debug)]
27pub struct ResourceTracker<T> {
28 terminal: Terminal<T>,
29 dropped: VecDeque<(Epochs, T)>,
30}
31
32impl<T> Default for ResourceTracker<T> {
33 fn default() -> Self {
34 ResourceTracker {
35 terminal: Terminal::default(),
36 dropped: VecDeque::default(),
37 }
38 }
39}
40
41impl<T> ResourceTracker<T> {
42 pub fn new() -> Self {
44 Self::default()
45 }
46
47 pub fn escape(&self, resource: T) -> Escape<T>
49 where
50 T: Sized,
51 {
52 Escape::escape(resource, &self.terminal)
53 }
54
55 pub fn handle(&self, resource: T) -> Handle<T>
57 where
58 T: Sized,
59 {
60 self.escape(resource).into()
61 }
62
63 pub fn cleanup(&mut self, mut dispose: impl FnMut(T), next: &Epochs, complete: &Epochs) {
72 while let Some((epoch, resource)) = self.dropped.pop_front() {
73 if !epoch.is_before(complete) {
74 self.dropped.push_front((epoch, resource));
75 break;
76 }
77
78 dispose(resource);
79 }
80
81 self.dropped
82 .extend(self.terminal.drain().map(|res| (next.clone(), res)));
83 }
84
85 pub fn dispose(&mut self, dispose: impl FnMut(T)) {
93 self.dropped
94 .drain(..)
95 .map(|(_, res)| res)
96 .chain(self.terminal.drain())
97 .for_each(dispose);
98 }
99}