Skip to content

Commit

Permalink
Merge pull request #1 from singalen/refactor
Browse files Browse the repository at this point in the history
There is only one image per Tile OR per Tileset. Added columns field.
  • Loading branch information
aleokdev authored Dec 27, 2021
2 parents 9fc0b74 + 6da58bd commit 95a6aa2
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 20 deletions.
8 changes: 4 additions & 4 deletions src/tile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::{
#[derive(Debug, PartialEq, Clone)]
pub struct Tile {
pub id: u32,
pub images: Vec<Image>,
pub image: Option<Image>,
pub properties: Properties,
pub objectgroup: Option<ObjectGroup>,
pub animation: Option<Vec<Frame>>,
Expand All @@ -39,13 +39,13 @@ impl Tile {
TiledError::MalformedAttributes("tile must have an id with the correct type".to_string())
);

let mut images = Vec::new();
let mut image = Option::None;
let mut properties = HashMap::new();
let mut objectgroup = None;
let mut animation = None;
parse_tag!(parser, "tile", {
"image" => |attrs| {
images.push(Image::new(parser, attrs)?);
image = Some(Image::new(parser, attrs)?);
Ok(())
},
"properties" => |_| {
Expand All @@ -63,7 +63,7 @@ impl Tile {
});
Ok(Tile {
id,
images,
image: image,
properties,
objectgroup,
animation,
Expand Down
59 changes: 43 additions & 16 deletions src/tileset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,14 @@ pub struct Tileset {
pub spacing: u32,
pub margin: u32,
pub tilecount: Option<u32>,
/// The Tiled spec says that a tileset can have mutliple images so a `Vec`
/// is used. Usually you will only use one.
pub images: Vec<Image>,
pub columns: u32,
/// A tileset can either:
/// * have a single spritesheet `image` in `tileset` ("regular" tileset);
/// * have zero images in `tileset` and one `image` per `tile` ("image collection" tileset).
///
/// - Source: [tiled issue #2117](https://github.com/mapeditor/tiled/issues/2117)
/// - Source: [`columns` documentation](https://doc.mapeditor.org/en/stable/reference/tmx-map-format/#tileset)
pub image: Option<Image>,
pub tiles: Vec<Tile>,
pub properties: Properties,
}
Expand Down Expand Up @@ -54,12 +59,13 @@ impl Tileset {
parser: &mut EventReader<R>,
attrs: &Vec<OwnedAttribute>,
) -> Result<Tileset, TiledError> {
let ((spacing, margin, tilecount), (first_gid, name, width, height)) = get_attrs!(
let ((spacing, margin, tilecount, columns), (first_gid, name, width, height)) = get_attrs!(
attrs,
optionals: [
("spacing", spacing, |v:String| v.parse().ok()),
("margin", margin, |v:String| v.parse().ok()),
("tilecount", tilecount, |v:String| v.parse().ok()),
("columns", columns, |v:String| v.parse().ok()),
],
required: [
("firstgid", first_gid, |v:String| v.parse().ok()),
Expand All @@ -70,12 +76,12 @@ impl Tileset {
TiledError::MalformedAttributes("tileset must have a firstgid, name tile width and height with correct types".to_string())
);

let mut images = Vec::new();
let mut image = Option::None;
let mut tiles = Vec::new();
let mut properties = HashMap::new();
parse_tag!(parser, "tileset", {
"image" => |attrs| {
images.push(Image::new(parser, attrs)?);
image = Some(Image::new(parser, attrs)?);
Ok(())
},
"properties" => |_| {
Expand All @@ -88,6 +94,15 @@ impl Tileset {
},
});

let columns = match columns {
Some(col) => col,
None => match &image {
None => return Err(TiledError::MalformedAttributes(
"No <image> and no <columns> in <tileset>".to_string())),
Some(image) => image.width as u32 / width,
},
};

Ok(Tileset {
tile_width: width,
tile_height: height,
Expand All @@ -96,7 +111,8 @@ impl Tileset {
first_gid,
name,
tilecount,
images,
columns,
image,
tiles,
properties,
})
Expand Down Expand Up @@ -159,12 +175,13 @@ impl Tileset {
parser: &mut EventReader<R>,
attrs: &Vec<OwnedAttribute>,
) -> Result<Tileset, TiledError> {
let ((spacing, margin, tilecount), (name, width, height)) = get_attrs!(
let ((spacing, margin, tilecount, columns), (name, width, height)) = get_attrs!(
attrs,
optionals: [
("spacing", spacing, |v:String| v.parse().ok()),
("margin", margin, |v:String| v.parse().ok()),
("tilecount", tilecount, |v:String| v.parse().ok()),
("columns", columns, |v:String| v.parse().ok()),
],
required: [
("name", name, |v| Some(v)),
Expand All @@ -174,33 +191,43 @@ impl Tileset {
TiledError::MalformedAttributes("tileset must have a firstgid, name tile width and height with correct types".to_string())
);

let mut images = Vec::new();
let mut image = Option::None;
let mut tiles = Vec::new();
let mut properties = HashMap::new();
parse_tag!(parser, "tileset", {
"image" => |attrs| {
images.push(Image::new(parser, attrs)?);
Ok(())
},
"tile" => |attrs| {
tiles.push(Tile::new(parser, attrs)?);
image = Some(Image::new(parser, attrs)?);
Ok(())
},
"properties" => |_| {
properties = parse_properties(parser)?;
Ok(())
},
"tile" => |attrs| {
tiles.push(Tile::new(parser, attrs)?);
Ok(())
},
});

let columns = match columns {
Some(col) => col,
None => match &image {
None => return Err(TiledError::MalformedAttributes(
"No <image> and no <columns> in <tileset>".to_string())),
Some(image) => image.width as u32 / width,
},
};

Ok(Tileset {
first_gid: first_gid,
name: name,
tile_width: width,
tile_height: height,
spacing: spacing.unwrap_or(0),
margin: margin.unwrap_or(0),
tilecount: tilecount,
images: images,
columns,
tilecount,
image,
tiles: tiles,
properties,
})
Expand Down

0 comments on commit 95a6aa2

Please sign in to comment.