From 57c517b4999a89d0b17782c24abf3f7b3438f26c Mon Sep 17 00:00:00 2001
From: Louis Capitanchik <contact@louiscap.co>
Date: Tue, 9 Aug 2022 16:23:08 +0100
Subject: [PATCH] Check Loader cache before opening a file handle

---
 .gitignore    |  3 ++-
 CHANGELOG.md  |  3 +++
 src/loader.rs | 21 ++++++++++++++-------
 src/map.rs    |  6 ++++--
 4 files changed, 23 insertions(+), 10 deletions(-)

diff --git a/.gitignore b/.gitignore
index 6cd496a..c1aea38 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,5 @@ target
 Cargo.lock
 *.swp
 *.dll
-.vscode
\ No newline at end of file
+.vscode
+.idea
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f4e87ef..b9fb0ed 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 ### Added
 - Support for Wang sets.
 
+### Changed
+- `Loader` cache will be checked for matches before opening a file handle
+
 ## [0.10.2]
 ### Added
 - Map-wrapped chunks: `ChunkWrapper`.
diff --git a/src/loader.rs b/src/loader.rs
index 35e4953..91c5543 100644
--- a/src/loader.rs
+++ b/src/loader.rs
@@ -120,11 +120,15 @@ impl<Cache: ResourceCache> Loader<Cache> {
     ///
     /// If you need to parse a reader object instead, use [Loader::load_tsx_tileset_from()].
     pub fn load_tsx_tileset(&mut self, path: impl AsRef<Path>) -> Result<Tileset> {
-        let reader = File::open(path.as_ref()).map_err(|err| Error::CouldNotOpenFile {
-            path: path.as_ref().to_owned(),
-            err,
+        let tileset = self.cache.get_or_try_insert_tileset_with(path.as_ref().to_path_buf(), || {
+            let reader = File::open(path.as_ref()).map_err(|err| Error::CouldNotOpenFile {
+                path: path.as_ref().to_owned(),
+                err,
+            })?;
+            crate::parse::xml::parse_tileset(reader, path.as_ref())
         })?;
-        crate::parse::xml::parse_tileset(reader, path.as_ref())
+
+        Ok((*tileset).clone())
     }
 
     /// Parses a tileset out of a reader hopefully containing the contents of a Tiled tileset.
@@ -151,12 +155,15 @@ impl<Cache: ResourceCache> Loader<Cache> {
     /// assert_eq!(tileset.image.unwrap().source, PathBuf::from("assets/tilesheet.png"));
     /// ```
     pub fn load_tsx_tileset_from(
-        &self,
+        &mut self,
         reader: impl Read,
         path: impl AsRef<Path>,
     ) -> Result<Tileset> {
-        // This function doesn't need the cache right now, but will do once template support is in
-        crate::parse::xml::parse_tileset(reader, path.as_ref())
+       let tileset = self.cache.get_or_try_insert_tileset_with(path.as_ref().to_path_buf(), || {
+            crate::parse::xml::parse_tileset(reader, path.as_ref())
+        })?;
+
+        Ok((*tileset).clone())
     }
 
     /// Returns a reference to the loader's internal [`ResourceCache`].
diff --git a/src/map.rs b/src/map.rs
index 2343803..7ee3705 100644
--- a/src/map.rs
+++ b/src/map.rs
@@ -185,8 +185,10 @@ impl Map {
                 let res = Tileset::parse_xml_in_map(parser, attrs, map_path)?;
                 match res.result_type {
                     EmbeddedParseResultType::ExternalReference { tileset_path } => {
-                        let file = File::open(&tileset_path).map_err(|err| Error::CouldNotOpenFile{path: tileset_path.clone(), err })?;
-                        let tileset = cache.get_or_try_insert_tileset_with(tileset_path.clone(), || crate::parse::xml::parse_tileset(file, &tileset_path))?;
+                        let tileset = cache.get_or_try_insert_tileset_with(tileset_path.clone(), || {
+                            let file = File::open(&tileset_path).map_err(|err| Error::CouldNotOpenFile{path: tileset_path.clone(), err })?;
+                            crate::parse::xml::parse_tileset(file, &tileset_path)
+                        })?;
                         tilesets.push(MapTilesetGid{first_gid: res.first_gid, tileset});
                     }
                     EmbeddedParseResultType::Embedded { tileset } => {
-- 
GitLab