Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix & add tests for template object loading #227

Merged
merged 4 commits into from
Jun 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ objects. As such, `ResourceCache` has now methods for both getting and inserting
### Changed
- `LayerType` variants have been stripped from the `Layer` suffix (#203).
- `ResourceCache::get_or_try_insert_tileset_with` has been replaced by `ResourceCache::insert_tileset`.
- `DefaultResourceCache`'s members have been made public.

## [0.10.2]
### Added
Expand Down
4 changes: 4 additions & 0 deletions assets/templates/corner.tx
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<template>
<object type="wall" width="16" height="16"/>
</template>
4 changes: 4 additions & 0 deletions assets/templates/edge.tx
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<template>
<object type="wall" width="16" height="32"/>
</template>
118 changes: 118 additions & 0 deletions assets/templates/example.tmx

Large diffs are not rendered by default.

111 changes: 111 additions & 0 deletions assets/templates/grass_walls.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<?xml version="1.0" encoding="UTF-8"?>
<tileset version="1.5" tiledversion="1.7.2" name="wang_tileset" tilewidth="32" tileheight="32" tilecount="18" columns="6">
<image source="../tilesheet.png" width="192" height="96"/>
<tile id="0">
<objectgroup draworder="index" id="2">
<object id="1" type="wall" x="0" y="0" width="32" height="32"/>
</objectgroup>
</tile>
<tile id="1">
<objectgroup draworder="index" id="2">
<object id="2" template="corner.tx" x="0" y="16"/>
<object id="3" template="corner.tx" x="0" y="0"/>
<object id="4" template="corner.tx" x="16" y="0"/>
</objectgroup>
</tile>
<tile id="2">
<objectgroup draworder="index" id="2">
<object id="2" template="edge.tx" x="0" y="16" rotation="270"/>
</objectgroup>
</tile>
<tile id="3">
<objectgroup draworder="index" id="2">
<object id="1" template="corner.tx" x="0" y="0"/>
<object id="2" template="corner.tx" x="16" y="0"/>
<object id="3" template="corner.tx" x="16" y="16"/>
</objectgroup>
</tile>
<tile id="4">
<objectgroup draworder="index" id="2">
<object id="2" template="corner.tx" x="16" y="16"/>
</objectgroup>
</tile>
<tile id="5">
<objectgroup draworder="index" id="2">
<object id="2" template="corner.tx" x="0" y="16"/>
</objectgroup>
</tile>
<tile id="6">
<objectgroup draworder="index" id="2">
<object id="1" type="wall" x="0" y="16" width="16" height="16"/>
<object id="2" type="wall" x="16" y="0" width="16" height="16"/>
</objectgroup>
</tile>
<tile id="7">
<objectgroup draworder="index" id="2">
<object id="1" template="edge.tx" x="0" y="0"/>
</objectgroup>
</tile>
<tile id="9">
<objectgroup draworder="index" id="2">
<object id="2" template="edge.tx" x="16" y="0"/>
</objectgroup>
</tile>
<tile id="10">
<objectgroup draworder="index" id="2">
<object id="2" template="corner.tx" x="16" y="0"/>
</objectgroup>
</tile>
<tile id="11">
<objectgroup draworder="index" id="2">
<object id="2" template="corner.tx" x="0" y="0"/>
</objectgroup>
</tile>
<tile id="12">
<objectgroup draworder="index" id="2">
<object id="2" type="wall" x="0" y="0" width="16" height="16"/>
<object id="3" type="wall" x="16" y="16" width="16" height="16"/>
</objectgroup>
</tile>
<tile id="13">
<objectgroup draworder="index" id="2">
<object id="2" template="corner.tx" x="0" y="0"/>
<object id="3" template="corner.tx" x="0" y="16"/>
<object id="4" template="corner.tx" x="16" y="16"/>
</objectgroup>
</tile>
<tile id="14">
<objectgroup draworder="index" id="2">
<object id="2" template="edge.tx" x="32" y="16" rotation="90"/>
</objectgroup>
</tile>
<tile id="15">
<objectgroup draworder="index" id="2">
<object id="2" template="corner.tx" x="16" y="0"/>
<object id="3" template="corner.tx" x="16" y="16"/>
<object id="4" template="corner.tx" x="0" y="16"/>
</objectgroup>
</tile>
<wangsets>
<wangset name="grass_walls" type="corner" tile="6">
<wangcolor name="walls" color="#ff0000" tile="0" probability="1"/>
<wangcolor name="grass" color="#00ff00" tile="8" probability="1"/>
<wangtile tileid="0" wangid="0,1,0,1,0,1,0,1"/>
<wangtile tileid="1" wangid="0,1,0,2,0,1,0,1"/>
<wangtile tileid="2" wangid="0,1,0,2,0,2,0,1"/>
<wangtile tileid="3" wangid="0,1,0,1,0,2,0,1"/>
<wangtile tileid="4" wangid="0,2,0,1,0,2,0,2"/>
<wangtile tileid="5" wangid="0,2,0,2,0,1,0,2"/>
<wangtile tileid="6" wangid="0,1,0,2,0,1,0,2"/>
<wangtile tileid="7" wangid="0,2,0,2,0,1,0,1"/>
<wangtile tileid="8" wangid="0,2,0,2,0,2,0,2"/>
<wangtile tileid="9" wangid="0,1,0,1,0,2,0,2"/>
<wangtile tileid="10" wangid="0,1,0,2,0,2,0,2"/>
<wangtile tileid="11" wangid="0,2,0,2,0,2,0,1"/>
<wangtile tileid="12" wangid="0,2,0,1,0,2,0,1"/>
<wangtile tileid="13" wangid="0,2,0,1,0,1,0,1"/>
<wangtile tileid="14" wangid="0,2,0,1,0,1,0,2"/>
<wangtile tileid="15" wangid="0,1,0,1,0,1,0,2"/>
</wangset>
</wangsets>
</tileset>
4 changes: 4 additions & 0 deletions assets/templates/simple_figure.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<tileset version="1.5" tiledversion="1.7.2" name="simple_figure" tilewidth="32" tileheight="32" tilecount="18" columns="3">
<image source="../tilesheet.png" width="96" height="192"/>
</tileset>
9 changes: 9 additions & 0 deletions assets/templates/simple_figure.tx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<template>
<tileset firstgid="1" source="simple_figure.tsx"/>
<object name="simple_figure" type="simple_figure" gid="1" width="32" height="32">
<properties>
<property name="playable" type="bool" value="false"/>
</properties>
</object>
</template>
8 changes: 5 additions & 3 deletions src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,13 @@ pub trait ResourceCache {
fn insert_template(&mut self, path: impl AsRef<ResourcePath>, tileset: Arc<Template>);
}

/// A cache that identifies resources by their path, storing a map of them.
/// A cache that identifies resources by their path, storing them in a [`HashMap`].
#[derive(Debug, Default)]
pub struct DefaultResourceCache {
tilesets: HashMap<ResourcePathBuf, Arc<Tileset>>,
templates: HashMap<ResourcePathBuf, Arc<Template>>,
/// The tilesets cached until now.
pub tilesets: HashMap<ResourcePathBuf, Arc<Tileset>>,
/// The templates cached until now.
pub templates: HashMap<ResourcePathBuf, Arc<Template>>,
}

impl DefaultResourceCache {
Expand Down
2 changes: 1 addition & 1 deletion src/layers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ impl LayerData {
attrs,
Some(tilesets),
for_tileset,
map_path,
map_path.parent().ok_or(crate::Error::PathIsNotFile)?,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we pass in the parent directory to LayerData::new in the first place? Or does the map_path parameter to ImageLayerData::new and GroupLayerData::new need to be the actual map path?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could change that, but I was trying to change as few lines as possible since you asked to patch just the bug.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's appreciated! It just highlighted that the inconsistency goes further than this one line. But, we can merge this fix and make it consistent in a follow-up change.

For following this up, I think we should always pass just the directory.

reader,
cache,
)?;
Expand Down
1 change: 1 addition & 0 deletions src/layers/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ impl ObjectLayerData {
attrs: Vec<OwnedAttribute>,
tilesets: Option<&[MapTilesetGid]>,
for_tileset: Option<Arc<Tileset>>,
// path_relative_to is a directory to which all other files are relative to
path_relative_to: &Path,
reader: &mut impl ResourceReader,
cache: &mut impl ResourceCache,
Expand Down
4 changes: 2 additions & 2 deletions src/objects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ impl ObjectData {
attrs: Vec<OwnedAttribute>,
tilesets: Option<&[MapTilesetGid]>,
for_tileset: Option<Arc<Tileset>>,
// Base path is a directory to which all other files are relative to
base_path: &Path,
reader: &mut impl ResourceReader,
cache: &mut impl ResourceCache,
Expand All @@ -211,8 +212,7 @@ 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));
let template_path = base_path.join(Path::new(&template_path));

// Check the cache to see if this template exists
let template = if let Some(templ) = cache.get_template(&template_path) {
Expand Down
2 changes: 1 addition & 1 deletion src/template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ impl Template {

parse_tag!(parser, "template", {
"object" => |attrs| {
object = Some(ObjectData::new(parser, attrs, Some(&tileset_gid), tileset.clone(), template_path, reader, cache)?);
object = Some(ObjectData::new(parser, attrs, Some(&tileset_gid), tileset.clone(), template_path.parent().ok_or(Error::PathIsNotFile)?, reader, cache)?);
Ok(())
},
"tileset" => |attrs: Vec<OwnedAttribute>| {
Expand Down
27 changes: 27 additions & 0 deletions tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,3 +467,30 @@ 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"))
.canonicalize()
.unwrap()
);
}