1#![allow(clippy::eval_order_dependence)] use crate::{AutomatedBuffer, BeltBufferId, IdBuffer};
4use std::{hash::Hash, sync::Arc};
5use wgpu::*;
6
7pub trait AutomatedBufferSet<'buf> {
11 type Key: Hash + Eq + Clone;
16 type Value;
18 fn get(self) -> Self::Value;
20 fn value_to_key(value: &Self::Value) -> Self::Key;
22}
23
24impl<'buf> AutomatedBufferSet<'buf> for &'buf AutomatedBuffer {
25 type Key = BeltBufferId;
26 type Value = Arc<IdBuffer>;
27 fn get(self) -> Self::Value {
28 self.get_current_inner()
29 }
30
31 fn value_to_key(value: &Self::Value) -> Self::Key {
32 value.id
33 }
34}
35
36impl<'buf> AutomatedBufferSet<'buf> for (&'buf AutomatedBuffer,) {
37 type Key = BeltBufferId;
38 type Value = Arc<IdBuffer>;
39 fn get(self) -> Self::Value {
40 self.0.get_current_inner()
41 }
42
43 fn value_to_key(value: &Self::Value) -> Self::Key {
44 value.id
45 }
46}
47
48impl<'buf> AutomatedBufferSet<'buf> for (&'buf AutomatedBuffer, &'buf AutomatedBuffer) {
49 type Key = (BeltBufferId, BeltBufferId);
50 type Value = (Arc<IdBuffer>, Arc<IdBuffer>);
51 fn get(self) -> Self::Value {
52 (self.0.get_current_inner(), self.1.get_current_inner())
53 }
54
55 fn value_to_key(value: &Self::Value) -> Self::Key {
56 (value.0.id, value.1.id)
57 }
58}
59
60impl<'buf> AutomatedBufferSet<'buf> for (&'buf AutomatedBuffer, &'buf AutomatedBuffer, &'buf AutomatedBuffer) {
61 type Key = (BeltBufferId, BeltBufferId, BeltBufferId);
62 type Value = (Arc<IdBuffer>, Arc<IdBuffer>, Arc<IdBuffer>);
63 fn get(self) -> Self::Value {
64 (
65 self.0.get_current_inner(),
66 self.1.get_current_inner(),
67 self.2.get_current_inner(),
68 )
69 }
70
71 fn value_to_key(value: &Self::Value) -> Self::Key {
72 (value.0.id, value.1.id, value.2.id)
73 }
74}
75
76impl<'buf> AutomatedBufferSet<'buf>
77 for (
78 &'buf AutomatedBuffer,
79 &'buf AutomatedBuffer,
80 &'buf AutomatedBuffer,
81 &'buf AutomatedBuffer,
82 )
83{
84 type Key = (BeltBufferId, BeltBufferId, BeltBufferId, BeltBufferId);
85 type Value = (Arc<IdBuffer>, Arc<IdBuffer>, Arc<IdBuffer>, Arc<IdBuffer>);
86 fn get(self) -> Self::Value {
87 (
88 self.0.get_current_inner(),
89 self.1.get_current_inner(),
90 self.2.get_current_inner(),
91 self.3.get_current_inner(),
92 )
93 }
94
95 fn value_to_key(value: &Self::Value) -> Self::Key {
96 (value.0.id, value.1.id, value.2.id, value.3.id)
97 }
98}
99
100pub type BufferCache1 = BeltBufferId;
102pub type BufferCache2 = (BeltBufferId, BeltBufferId);
104pub type BufferCache3 = (BeltBufferId, BeltBufferId, BeltBufferId);
106pub type BufferCache4 = (BeltBufferId, BeltBufferId, BeltBufferId, BeltBufferId);
108
109pub struct BindGroupCache<Key: Hash + Eq + Clone> {
114 cache: lru::LruCache<Key, BindGroup>,
115}
116impl<Key: Hash + Eq + Clone> BindGroupCache<Key> {
117 #[must_use]
119 pub fn new() -> Self {
120 Self::with_capacity(4)
121 }
122
123 #[must_use]
125 pub fn with_capacity(size: usize) -> Self {
126 Self {
127 cache: lru::LruCache::new(size),
128 }
129 }
130
131 pub fn clear(&mut self) {
133 self.cache.clear();
134 }
135
136 pub fn create_bind_group<'a, Set, BindGroupFn>(
149 &mut self,
150 buffers: Set,
151 use_cache: bool,
152 bind_group_fn: BindGroupFn,
153 ) -> Key
154 where
155 Set: AutomatedBufferSet<'a, Key = Key>,
156 BindGroupFn: FnOnce(&Set::Value) -> BindGroup,
157 {
158 let value = buffers.get();
159 let key = Set::value_to_key(&value);
160 if self.cache.contains(&key) && use_cache {
161 return key;
162 }
163 self.cache.put(key.clone(), bind_group_fn(&value));
165 key
166 }
167
168 pub fn get(&self, key: &Key) -> Option<&BindGroup> {
169 self.cache.peek(key)
170 }
171}
172
173impl<Key: Hash + Eq + Clone> Default for BindGroupCache<Key> {
174 fn default() -> Self {
175 Self::new()
176 }
177}