use std::collections::HashMap;
use eframe::egui;
use log::trace;
use crate::texture_request::TextureRequest;
use maps_io_ros::ValueInterpretation;
#[derive(Clone)]
struct CachedTexture {
texture_handle: egui::TextureHandle,
color_to_alpha: Option<egui::Color32>,
thresholding: Option<ValueInterpretation>,
texture_options: Option<egui::TextureOptions>,
}
impl CachedTexture {
fn matches_appearance(&self, request: &TextureRequest) -> bool {
self.color_to_alpha == request.color_to_alpha
&& self.thresholding == request.thresholding
&& self.texture_options == request.texture_options
}
}
#[derive(Default)]
pub struct TextureCache {
cache: HashMap<String, CachedTexture>,
}
impl TextureCache {
pub fn new() -> Self {
Self {
cache: HashMap::new(),
}
}
fn generate_key(client: &str, pyramid_level: u32) -> String {
format!("{client}_{pyramid_level}")
}
pub fn query(
&mut self,
client: &str,
pyramid_level: u32,
request: &TextureRequest,
) -> Option<egui::TextureHandle> {
let cache_key = Self::generate_key(client, pyramid_level);
if let Some(cached_texture) = self.cache.get(&cache_key) {
if cached_texture.matches_appearance(request) {
return Some(cached_texture.texture_handle.clone());
}
trace!("Cache miss for client {client} at level {pyramid_level}.");
self.cache.remove(&cache_key);
}
None
}
pub fn store(
&mut self,
client: &str,
pyramid_level: u32,
texture_handle: egui::TextureHandle,
request: &TextureRequest,
) {
let cache_key = Self::generate_key(client, pyramid_level);
let cached_texture = CachedTexture {
texture_handle,
color_to_alpha: request.color_to_alpha,
thresholding: request.thresholding,
texture_options: request.texture_options,
};
self.cache.insert(cache_key, cached_texture);
}
}