summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--alligator_resources/src/lib.rs5
-rw-r--r--alligator_resources/src/texture.rs43
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");