Skip to content

Commit

Permalink
Fix directory/file path inconsistencies
Browse files Browse the repository at this point in the history
  • Loading branch information
aleokdev committed Jun 12, 2022
1 parent 5343d5f commit 8153a5f
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 25 deletions.
4 changes: 2 additions & 2 deletions src/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ impl Image {
pub(crate) fn new(
parser: &mut impl Iterator<Item = XmlEventResult>,
attrs: Vec<OwnedAttribute>,
path_relative_to: impl AsRef<Path>,
file_path_being_loaded: &Path,
) -> Result<Image> {
let (c, (s, w, h)) = get_attrs!(
attrs,
Expand All @@ -94,7 +94,7 @@ impl Image {

parse_tag!(parser, "image", {});
Ok(Image {
source: path_relative_to.as_ref().join(s),
source: file_path_being_loaded.parent().unwrap().join(s),
width: w,
height: h,
transparent_colour: c,
Expand Down
6 changes: 2 additions & 4 deletions src/layers/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,14 @@ pub struct ImageLayerData {
impl ImageLayerData {
pub(crate) fn new(
parser: &mut impl Iterator<Item = XmlEventResult>,
map_path: &Path,
file_path_being_loaded: &Path,
) -> Result<(Self, Properties)> {
let mut image: Option<Image> = None;
let mut properties = HashMap::new();

let path_relative_to = map_path.parent().ok_or(Error::PathIsNotFile)?;

parse_tag!(parser, "imagelayer", {
"image" => |attrs| {
image = Some(Image::new(parser, attrs, path_relative_to)?);
image = Some(Image::new(parser, attrs, file_path_being_loaded)?);
Ok(())
},
"properties" => |_| {
Expand Down
4 changes: 2 additions & 2 deletions src/layers/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ impl ObjectLayerData {
attrs: Vec<OwnedAttribute>,
tilesets: Option<&[MapTilesetGid]>,
for_tileset: Option<Arc<Tileset>>,
path_relative_to: &Path,
file_path_being_loaded: &Path,
reader: &mut impl ResourceReader,
cache: &mut impl ResourceCache,
) -> Result<(ObjectLayerData, Properties)> {
Expand All @@ -39,7 +39,7 @@ impl ObjectLayerData {
let mut properties = HashMap::new();
parse_tag!(parser, "objectgroup", {
"object" => |attrs| {
objects.push(ObjectData::new(parser, attrs, tilesets, for_tileset.as_ref().cloned(), path_relative_to, reader, cache)?);
objects.push(ObjectData::new(parser, attrs, tilesets, for_tileset.as_ref().cloned(), file_path_being_loaded, reader, cache)?);
Ok(())
},
"properties" => |_| {
Expand Down
21 changes: 17 additions & 4 deletions src/objects.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
use std::{collections::HashMap, path::Path, sync::Arc};
use std::{
collections::HashMap,
path::{Path, PathBuf},
sync::Arc,
};

use xml::attribute::OwnedAttribute;

Expand Down Expand Up @@ -186,10 +190,12 @@ impl ObjectData {
attrs: Vec<OwnedAttribute>,
tilesets: Option<&[MapTilesetGid]>,
for_tileset: Option<Arc<Tileset>>,
base_path: &Path,
file_path_being_loaded: &Path,
reader: &mut impl ResourceReader,
cache: &mut impl ResourceCache,
) -> Result<ObjectData> {
assert!(file_path_being_loaded.is_file());

let (id, mut tile, x, y, mut n, mut t, mut w, mut h, mut v, mut r, template) = get_attrs!(
attrs,
optionals: [
Expand All @@ -211,8 +217,15 @@ impl ObjectData {
// If the template attribute is there, we need to go fetch the template file
let template = template
.map(|template_path: String| {
let parent_dir = base_path.parent().ok_or(Error::PathIsNotFile)?;
let template_path = parent_dir.join(Path::new(&template_path));
// The base path may be a directory or a file
let template_path = {
let path = PathBuf::from(template_path);
if path.is_relative() {
file_path_being_loaded.parent().unwrap().join(&path)
} else {
path
}
};

// Check the cache to see if this template exists
let template = if let Some(templ) = cache.get_template(&template_path) {
Expand Down
6 changes: 3 additions & 3 deletions src/tile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ impl TileData {
pub(crate) fn new(
parser: &mut impl Iterator<Item = XmlEventResult>,
attrs: Vec<OwnedAttribute>,
path_relative_to: &Path,
file_path_being_loaded: &Path,
reader: &mut impl ResourceReader,
cache: &mut impl ResourceCache,
) -> Result<(TileId, TileData)> {
Expand All @@ -85,7 +85,7 @@ impl TileData {
let mut animation = None;
parse_tag!(parser, "tile", {
"image" => |attrs| {
image = Some(Image::new(parser, attrs, path_relative_to)?);
image = Some(Image::new(parser, attrs, file_path_being_loaded)?);
Ok(())
},
"properties" => |_| {
Expand All @@ -95,7 +95,7 @@ impl TileData {
"objectgroup" => |attrs| {
// Tile objects are not allowed within tile object groups, so we can pass None as the
// tilesets vector
objectgroup = Some(ObjectLayerData::new(parser, attrs, None, None, path_relative_to, reader, cache)?.0);
objectgroup = Some(ObjectLayerData::new(parser, attrs, None, None, file_path_being_loaded, reader, cache)?.0);
Ok(())
},
"animation" => |_| {
Expand Down
15 changes: 5 additions & 10 deletions src/tileset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,7 @@ struct TilesetProperties {
name: String,
tile_width: u32,
tile_height: u32,
/// The root all non-absolute paths contained within the tileset are relative to.
root_path: PathBuf,
file_path_being_loaded: PathBuf,
}

impl Tileset {
Expand Down Expand Up @@ -136,15 +135,13 @@ impl Tileset {
Error::MalformedAttributes("tileset must have a firstgid, tilecount, tilewidth, and tileheight with correct types".to_string())
);

let root_path = path.parent().ok_or(Error::PathIsNotFile)?.to_owned();

Self::finish_parsing_xml(
parser,
TilesetProperties {
spacing,
margin,
name: name.unwrap_or_default(),
root_path,
file_path_being_loaded: path.to_owned(),
columns,
tilecount,
tile_height,
Expand Down Expand Up @@ -203,15 +200,13 @@ impl Tileset {
Error::MalformedAttributes("tileset must have a name, tile width and height with correct types".to_string())
);

let root_path = path.parent().ok_or(Error::PathIsNotFile)?.to_owned();

Self::finish_parsing_xml(
parser,
TilesetProperties {
spacing,
margin,
name: name.unwrap_or_default(),
root_path,
file_path_being_loaded: path.to_owned(),
columns,
tilecount,
tile_height,
Expand All @@ -234,15 +229,15 @@ impl Tileset {

parse_tag!(parser, "tileset", {
"image" => |attrs| {
image = Some(Image::new(parser, attrs, &prop.root_path)?);
image = Some(Image::new(parser, attrs, &prop.file_path_being_loaded)?);
Ok(())
},
"properties" => |_| {
properties = parse_properties(parser)?;
Ok(())
},
"tile" => |attrs| {
let (id, tile) = TileData::new(parser, attrs, &prop.root_path, reader, cache)?;
let (id, tile) = TileData::new(parser, attrs, &prop.file_path_being_loaded, reader, cache)?;
tiles.insert(id, tile);
Ok(())
},
Expand Down
25 changes: 25 additions & 0 deletions tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,3 +467,28 @@ fn test_object_template_property() {
assert_eq!(object.get_tile().unwrap().id(), 44);
assert_eq!(object_nt.get_tile().unwrap().id(), 44);
}

#[test]
fn test_templates() {
let mut loader = Loader::new();
let map = loader.load_tmx_map("assets/templates/example.tmx").unwrap();

assert_eq!(loader.cache().templates.len(), 3);
assert_eq!(
if let LayerType::Tiles(x) = map.get_layer(0).unwrap().layer_type() {
x
} else {
panic!()
}
.get_tile(0, 0)
.unwrap()
.get_tileset()
.image
.as_ref()
.unwrap()
.source
.canonicalize()
.unwrap(),
PathBuf::from(concat!(env!("CARGO_MANIFEST_DIR"), "/assets/tilesheet.png"))
);
}

0 comments on commit 8153a5f

Please sign in to comment.