diff options
Diffstat (limited to 'alligator_resources')
| -rw-r--r-- | alligator_resources/src/texture.rs | 58 |
1 files changed, 33 insertions, 25 deletions
diff --git a/alligator_resources/src/texture.rs b/alligator_resources/src/texture.rs index 75c3889..90bc662 100644 --- a/alligator_resources/src/texture.rs +++ b/alligator_resources/src/texture.rs @@ -2,9 +2,10 @@ use std::cmp::Reverse; use std::collections::HashMap; use std::mem::{self}; use std::path::Path; -use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; use std::sync::Arc; +use dashmap::DashMap; use image::ImageBuffer; use parking_lot::Mutex; use texture_packer::exporter::ImageExporter; @@ -112,6 +113,7 @@ impl TextureFile { fn load(&mut self) -> Result<&Rgba16Texture, LoadError> { if self.texture.is_none() { + log::warn!("{} was not pre-loaded", self.path.to_string_lossy()); let texture = image::open(&self.path).map_err(convert_image_load_error)?; let texture = texture.to_rgba16(); let texture = Arc::new(vec_image_to_box(texture)); @@ -333,22 +335,22 @@ impl<'a> TextureAtlas<'a> { } pub struct TextureManager { - textures: HashMap<TextureId, Texture>, + textures: DashMap<TextureId, Texture>, max_size: usize, atlas_width: u32, atlas_height: u32, - needs_atlas_update: bool, + needs_atlas_update: AtomicBool, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct TextureConfig { +pub struct TextureManagerConfig { pub initial_capacity: usize, pub max_size: usize, pub atlas_width: u32, pub atlas_height: u32, } -impl Default for TextureConfig { +impl Default for TextureManagerConfig { fn default() -> Self { Self { initial_capacity: 500, @@ -362,25 +364,25 @@ impl Default for TextureConfig { impl TextureManager { /// Create a new `TextureManager` with the given config options. #[must_use] - pub fn new(config: TextureConfig) -> Self { - let textures = HashMap::with_capacity(config.initial_capacity); + pub fn new(config: TextureManagerConfig) -> Self { + let textures = DashMap::with_capacity(config.initial_capacity); Self { textures, max_size: config.max_size, atlas_width: config.atlas_width, atlas_height: config.atlas_height, - needs_atlas_update: false, + needs_atlas_update: AtomicBool::new(false), } } /// Load textures into memory that will be needed soon. Unload unnecessary textures - pub fn cache_files(&mut self) { - let mut textures: Vec<&mut Texture> = self + pub fn cache_files(&self) { + let mut textures: Vec<_> = self .textures - .values_mut() - .map(|t| { - t.unqueue_priority(); + .iter_mut() + .map(|mut t| { + t.value_mut().unqueue_priority(); t }) .collect(); @@ -389,7 +391,7 @@ impl TextureManager { let max_size = self.max_size; let mut total_size = 0; - for texture in textures { + for texture in &mut textures { drop(texture.load_texture()); total_size += texture.allocated_size(); if total_size > max_size && texture.priority() != Priority::Urgent { @@ -418,7 +420,7 @@ impl TextureManager { let texture = Texture::from_buffer(texture); self.textures.insert(id, texture); - self.needs_atlas_update = true; + self.needs_atlas_update.store(true, Ordering::Release); Ok(id) } @@ -441,7 +443,7 @@ impl TextureManager { match texture.load_texture() { Ok(_) => { self.textures.insert(id, texture); - self.needs_atlas_update = true; + self.needs_atlas_update.store(true, Ordering::Release); } Err(e) => { self.textures.insert(id, texture); @@ -462,13 +464,13 @@ impl TextureManager { /// This returns an error if `priority` is set to [`Priority::Urgent`] but /// there was an error in loading the file to a texture. pub fn set_priority(&mut self, id: TextureId, priority: Priority) -> Result<(), LoadError> { - let texture = self.textures.get_mut(&id).expect("invalid texture id"); + let mut texture = self.textures.get_mut(&id).expect("invalid texture id"); texture.set_priority(priority); if !texture.is_loaded() && priority == Priority::Urgent { - let texture = self.textures.get_mut(&id).expect("invalid texture id"); + let mut texture = self.textures.get_mut(&id).expect("invalid texture id"); texture.load_texture()?; - self.needs_atlas_update = true; + self.needs_atlas_update.store(true, Ordering::Release); } Ok(()) @@ -477,16 +479,22 @@ impl TextureManager { /// This returns `true` if a texture has been set to have an urgent /// priority since the last time this function was called. pub fn needs_atlas_update(&mut self) -> bool { - let needs_update = self.needs_atlas_update; - self.needs_atlas_update = false; - needs_update + self.needs_atlas_update.fetch_and(false, Ordering::AcqRel) } - /// Create a texture atlas - pub fn atlas(&mut self) -> TextureAtlas<'_> { + pub fn load_texture(&self, id: TextureId) -> Result<Rgba16Texture, LoadError> { + self.textures + .get_mut(&id) + .expect("the TextureId was invalid") + .load_texture() + .cloned() + } + + // Create a texture atlas + /*pub fn atlas(&mut self) -> TextureAtlas<'_> { let atlas = TextureAtlas::new(self.atlas_width, self.atlas_height, &self.textures); self.atlas_width = atlas.atlas_width(); self.atlas_height = atlas.atlas_height(); atlas - } + }*/ } |
