use std::cell::RefCell;
use std::collections::hash_map::DefaultHasher;
use std::collections::BTreeMap;
use std::hash::Hasher;
use std::ops::Deref;
use std::rc::Rc;
use super::{ImStr, ImTextureID};
pub trait ImTexture {
fn get_id(&self) -> ImTextureID;
fn get_size(&self) -> (u32, u32);
}
impl ImTexture for ImTextureID {
fn get_id(&self) -> ImTextureID { *self }
fn get_size(&self) -> (u32, u32) {
panic!("Cannot get size of ImTextureID (it is a raw pointer)!")
}
}
#[derive(Clone)]
pub struct AnyTexture(Rc<Box<ImTexture>>);
impl AnyTexture {
fn new<T: 'static + ImTexture>(texture: T) -> Self { AnyTexture(Rc::new(Box::new(texture))) }
}
impl ImTexture for AnyTexture {
fn get_id(&self) -> ImTextureID { self.deref().get_id() }
fn get_size(&self) -> (u32, u32) { self.deref().get_size() }
}
impl Deref for AnyTexture {
type Target = Box<ImTexture>;
fn deref(&self) -> &Self::Target { Deref::deref(&self.0) }
}
pub trait FromImTexture {
fn from_im_texture<T: ImTexture>(texture: &T) -> &Self {
let texture = texture.get_id();
Self::from_id(texture)
}
fn from_id<'a>(texture_id: ImTextureID) -> &'a Self;
}
pub struct TextureCache(RefCell<BTreeMap<u64, AnyTexture>>);
impl TextureCache {
pub fn new() -> Self { TextureCache(RefCell::new(BTreeMap::new())) }
pub fn register_texture<T>(&self, name: &ImStr, texture: T) -> Option<AnyTexture>
where
T: 'static + ImTexture,
{
let id = hash_imstring(name);
self.0.borrow_mut().insert(id, AnyTexture::new(texture))
}
pub fn get_texture(&self, name: &ImStr) -> Option<AnyTexture> {
let id = hash_imstring(name);
self.0.borrow().get(&id).map(Clone::clone)
}
}
fn hash_imstring(string: &ImStr) -> u64 {
let mut h = DefaultHasher::new();
h.write(string.to_str().as_bytes());
h.finish()
}