diff options
| -rw-r--r-- | alligator_resources/src/lib.rs | 5 | ||||
| -rw-r--r-- | alligator_resources/src/texture.rs | 43 |
2 files changed, 35 insertions, 13 deletions
diff --git a/alligator_resources/src/lib.rs b/alligator_resources/src/lib.rs index 0f7b544..89a8f3c 100644 --- a/alligator_resources/src/lib.rs +++ b/alligator_resources/src/lib.rs @@ -1,6 +1,5 @@ -#![feature(new_uninit)] -#![warn(clippy::nursery)] -#![warn(clippy::pedantic)] +#![feature(new_uninit, let_chains)] +#![warn(clippy::nursery, clippy::pedantic)] #![allow(clippy::module_name_repetitions)] pub mod texture; diff --git a/alligator_resources/src/texture.rs b/alligator_resources/src/texture.rs index ac9e70f..81c2105 100644 --- a/alligator_resources/src/texture.rs +++ b/alligator_resources/src/texture.rs @@ -121,11 +121,14 @@ impl TextureFile { Ok(self.texture.as_ref().expect("the texture wasn't loaded")) } + fn is_used(&self) -> bool { + let Some(arc) = &self.texture else { return false }; + Arc::strong_count(arc) > 1 + } + fn unload(&mut self) { - if let Some(arc) = &self.texture { - if Arc::strong_count(arc) == 1 { - self.texture = None; - } + if !self.is_used() { + self.texture = None; } } @@ -164,8 +167,8 @@ impl Texture { } fn set_priority(&mut self, priority: Priority) { - // memory textures should always be urgent - if let TextureBuffer::Disk(_) = self.buffer { + // memory textures and textures in use should always be urgent + if let TextureBuffer::Disk(disk) = &self.buffer && !disk.is_used() { self.priority = priority; } } @@ -198,6 +201,11 @@ pub struct TextureRef<'a> { } impl<'a> TextureRef<'a> { + #[must_use] + pub const fn id(&self) -> TextureId { + self.id + } + fn texture_width(&self) -> u32 { self.texture.width() } @@ -290,14 +298,14 @@ impl TextureManager { } } - fn can_load(&mut self, texture: &Texture) -> bool { + fn can_load(&mut self, size: usize, priority: Priority) -> bool { let mut textures: Vec<&mut Texture> = self.textures.values_mut().collect(); textures.sort_by_key(|a| a.priority()); textures.reverse(); let max_size = self.max_size; - let priority = texture.priority(); - let mut total_size = texture.allocated_size(); + let priority = priority; + let mut total_size = size; for texture in textures { if total_size + texture.allocated_size() < max_size { @@ -342,8 +350,9 @@ impl TextureManager { ) -> Result<TextureId, LoadError> { let id = TextureId::new(); let mut texture = Texture::from_path(path, priority); + let size = texture.allocated_size(); - if priority == Priority::Urgent || self.can_load(&texture) { + if priority == Priority::Urgent || self.can_load(size, texture.priority()) { match texture.load_texture() { Ok(_) => { self.textures.insert(id, texture); @@ -360,6 +369,20 @@ impl TextureManager { Ok(id) } + pub fn set_priority(&mut self, id: TextureId, priority: Priority) -> Result<(), LoadError> { + let texture = self.textures.get_mut(&id).expect("invalid texture id"); + texture.set_priority(priority); + let size = texture.allocated_size(); + let priority = texture.priority(); + + if priority == Priority::Urgent || self.can_load(size, priority) { + let texture = self.textures.get_mut(&id).expect("invalid texture id"); + texture.load_texture()?; + } + + Ok(()) + } + pub fn atlas(&mut self) -> &Rgba16Texture { let atlas = { profiling::scope!("export atlas"); |
