Add a separate IconCache type for use by the map renderer

This commit is contained in:
Tad Hardesty 2018-03-13 01:09:27 -07:00
parent 21810da9f7
commit 8ad1e85673
3 changed files with 51 additions and 13 deletions

43
src/tools/icon_cache.rs Normal file
View file

@ -0,0 +1,43 @@
use std::sync::{Arc, RwLock};
use std::path::{Path, PathBuf};
use std::collections::{HashMap, hash_map};
use super::dmi::IconFile;
#[derive(Default)]
pub struct IconCache {
lock: RwLock<HashMap<PathBuf, Arc<IconFile>>>,
}
impl IconCache {
pub fn retrieve_uniq(&mut self, path: &Path) -> Option<&IconFile> {
let map = self.lock.get_mut().unwrap();
match map.entry(path.to_owned()) {
hash_map::Entry::Occupied(entry) => Some(entry.into_mut()),
hash_map::Entry::Vacant(entry) => load(path).map(|icon| &**entry.insert(Arc::new(icon))),
}
}
pub fn retrieve_shared(&self, path: &Path) -> Option<Arc<IconFile>> {
let existing = self.lock.read().unwrap().get(path).cloned();
// shouldn't be inlined or the lifetime of the lock will be extended
match existing {
Some(existing) => Some(existing),
None => load(path).map(|icon| {
let arc = Arc::new(icon);
self.lock.write().unwrap().insert(path.to_owned(), arc.clone());
arc
}),
}
}
}
fn load(path: &Path) -> Option<IconFile> {
match IconFile::from_file(path) {
Ok(loaded) => Some(loaded),
Err(err) => {
eprintln!("error loading icon: {}\n{}", path.display(), err);
None
}
}
}

View file

@ -13,6 +13,7 @@ extern crate rand;
#[macro_use] mod utils;
pub mod dmi;
pub mod dmm;
pub mod icon_cache;
pub mod minimap;
pub mod render_passes;
pub mod lint;

View file

@ -1,5 +1,4 @@
use std::collections::{HashMap, hash_map};
use std::path::{Path, PathBuf};
use std::path::Path;
use ndarray::{self, Axis};
@ -7,8 +6,9 @@ use dm::objtree::*;
use dm::objtree::subpath as subtype;
use dm::constants::Constant;
use dmm::{Map, Grid, Prefab};
use dmi::{Image, IconFile};
use dmi::Image;
use render_passes::RenderPass;
use icon_cache::IconCache;
const TILE_SIZE: u32 = 32;
@ -27,7 +27,7 @@ pub struct Context<'a> {
pub fn generate(
ctx: Context,
icon_cache: &mut HashMap<PathBuf, IconFile>,
icon_cache: &IconCache,
) -> Result<Image, ()> {
flame!("minimap");
let Context { objtree, map, grid, render_passes, .. } = ctx;
@ -188,15 +188,9 @@ pub fn generate(
let dir = atom.get_var("dir", objtree).to_int().unwrap_or(::dmi::SOUTH);
let path: &Path = icon.as_ref();
let icon_file = match icon_cache.entry(path.to_owned()) {
hash_map::Entry::Occupied(entry) => entry.into_mut(),
hash_map::Entry::Vacant(entry) => match IconFile::from_file(path) {
Ok(found) => entry.insert(found),
Err(err) => {
println!("error loading icon: {}\n{:?}", path.display(), err);
continue 'atom;
}
}
let icon_file = match icon_cache.retrieve_shared(path) {
Some(icon_file) => icon_file,
None => continue 'atom,
};
if let Some(mut rect) = icon_file.rect_of(&icon_state, dir) {