diff --git a/crates/graphics/src/loaders/atlas.rs b/crates/graphics/src/loaders/atlas.rs
index 7507b1b6..2f9741db 100644
--- a/crates/graphics/src/loaders/atlas.rs
+++ b/crates/graphics/src/loaders/atlas.rs
@@ -14,11 +14,39 @@
//
// You should have received a copy of the GNU General Public License
// along with Luminol. If not, see .
-use crate::{Atlas, GraphicsState};
+use crate::{primitives::tiles::AUTOTILE_AMOUNT, Atlas, GraphicsState, Texture};
+use std::sync::{Arc, Weak};
#[derive(Default)]
pub struct Loader {
- atlases: dashmap::DashMap,
+ atlases: dashmap::DashMap,
+}
+
+struct WeakAtlas {
+ atlas_texture: Weak,
+ autotile_width: u32,
+ tileset_height: u32,
+ autotile_frames: [u32; AUTOTILE_AMOUNT as usize],
+}
+
+impl WeakAtlas {
+ fn upgrade(&self) -> Option {
+ self.atlas_texture.upgrade().map(|atlas_texture| Atlas {
+ atlas_texture,
+ autotile_width: self.autotile_width,
+ tileset_height: self.tileset_height,
+ autotile_frames: self.autotile_frames,
+ })
+ }
+
+ fn from_atlas(atlas: &Atlas) -> Self {
+ WeakAtlas {
+ atlas_texture: Arc::downgrade(&atlas.atlas_texture),
+ autotile_width: atlas.autotile_width,
+ tileset_height: atlas.tileset_height,
+ autotile_frames: atlas.autotile_frames,
+ }
+ }
}
impl Loader {
@@ -28,11 +56,17 @@ impl Loader {
filesystem: &impl luminol_filesystem::FileSystem,
tileset: &luminol_data::rpg::Tileset,
) -> color_eyre::Result {
- Ok(self
- .atlases
- .entry(tileset.id)
- .or_insert_with(|| Atlas::new(graphics_state, filesystem, tileset))
- .clone())
+ self.atlases
+ .get(&tileset.id)
+ .as_deref()
+ .and_then(WeakAtlas::upgrade)
+ .map(Ok)
+ .unwrap_or_else(|| {
+ let atlas = Atlas::new(graphics_state, filesystem, tileset);
+ let weak_atlas = WeakAtlas::from_atlas(&atlas);
+ self.atlases.insert(tileset.id, weak_atlas);
+ Ok(atlas)
+ })
}
pub fn reload_atlas(
@@ -41,11 +75,25 @@ impl Loader {
filesystem: &impl luminol_filesystem::FileSystem,
tileset: &luminol_data::rpg::Tileset,
) -> color_eyre::Result {
- Ok(self
- .atlases
- .entry(tileset.id)
- .insert(Atlas::new(graphics_state, filesystem, tileset))
- .clone())
+ let atlas = Atlas::new(graphics_state, filesystem, tileset);
+ let weak_atlas = WeakAtlas::from_atlas(&atlas);
+ self.atlases.insert(tileset.id, weak_atlas);
+ Ok(atlas)
+ }
+
+ pub fn get_atlas(&self, id: usize) -> Option {
+ self.atlases
+ .get(&id)
+ .as_deref()
+ .and_then(WeakAtlas::upgrade)
+ }
+
+ pub fn get_expect(&self, id: usize) -> Atlas {
+ self.atlases
+ .get(&id)
+ .as_deref()
+ .and_then(WeakAtlas::upgrade)
+ .expect("Atlas not loaded!")
}
pub fn clear(&self) {
diff --git a/crates/graphics/src/loaders/texture.rs b/crates/graphics/src/loaders/texture.rs
index e330f4db..2652cfb0 100644
--- a/crates/graphics/src/loaders/texture.rs
+++ b/crates/graphics/src/loaders/texture.rs
@@ -24,12 +24,12 @@
use dashmap::DashMap;
-use std::sync::Arc;
+use std::sync::{Arc, Weak};
use wgpu::util::DeviceExt;
pub struct Loader {
- loaded_textures: DashMap>,
+ loaded_textures: DashMap>,
placeholder_texture: Arc,
blank_autotile_texture: Arc,
@@ -231,18 +231,21 @@ impl Loader {
let texture =
register_native_texture(self.render_state.clone(), texture, Some(path.as_str()));
- self.loaded_textures.insert(path, texture.clone());
+ self.loaded_textures.insert(path, Arc::downgrade(&texture));
texture
}
pub fn get(&self, path: impl AsRef) -> Option> {
- self.loaded_textures.get(path.as_ref()).as_deref().cloned()
+ self.loaded_textures
+ .get(path.as_ref())
+ .as_deref()
+ .and_then(Weak::upgrade)
}
pub fn remove(&self, path: impl AsRef) -> Option> {
self.loaded_textures
.remove(path.as_ref())
- .map(|(_, value)| value)
+ .and_then(|(_, value)| value.upgrade())
}
pub fn clear(&self) {