use std::hash::Hash;
use super::CacheTrait;
/// Stores a key:value pair for the duration of this frame and the next.
pub struct FramePublisher<Key: Eq + Hash, Value> {
generation: u32,
cache: ahash::HashMap<Key, (u32, Value)>,
}
impl<Key: Eq + Hash, Value> Default for FramePublisher<Key, Value> {
fn default() -> Self {
Self::new()
}
}
impl<Key: Eq + Hash, Value> FramePublisher<Key, Value> {
pub fn new() -> Self {
Self {
generation: 0,
cache: Default::default(),
}
}
/// Publish the value. It will be available for the duration of this and the next frame.
pub fn set(&mut self, key: Key, value: Value) {
self.cache.insert(key, (self.generation, value));
}
/// Retrieve a value if it was published this or the previous frame.
pub fn get(&self, key: &Key) -> Option<&Value> {
self.cache.get(key).map(|(_, value)| value)
}
/// Must be called once per frame to clear the cache.
pub fn evict_cache(&mut self) {
let current_generation = self.generation;
self.cache.retain(|_key, cached| {
cached.0 == current_generation // only keep those that were published this frame
});
self.generation = self.generation.wrapping_add(1);
}
}
impl<Key, Value> CacheTrait for FramePublisher<Key, Value>
where
Key: 'static + Eq + Hash + Send + Sync,
Value: 'static + Send + Sync,
{
fn update(&mut self) {
self.evict_cache();
}
fn len(&self) -> usize {
self.cache.len()
}
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
self
}
}