diff --git a/src/layers/tile/mod.rs b/src/layers/tile/mod.rs index c38bd0edb22a20ff86907d4c3b43ba93f327893a..6ff195be933c0b9d631f129aefc862825d85273c 100644 --- a/src/layers/tile/mod.rs +++ b/src/layers/tile/mod.rs @@ -5,7 +5,7 @@ use xml::attribute::OwnedAttribute; use crate::{ parse_properties, util::{get_attrs, map_wrapper, parse_tag, XmlEventResult}, - Gid, Map, MapTilesetGid, Properties, Tile, TileId, TiledError, Tileset, + Gid, Map, MapTilesetGid, Properties, Tile, TileId, TiledError, Tileset, }; mod finite; @@ -110,7 +110,7 @@ map_wrapper!(LayerTile => LayerTileData); impl<'map> LayerTile<'map> { /// Get a reference to the layer tile's referenced tile, if it exists. - pub fn get_tile(&self) -> Option<&'map Tile> { + pub fn get_tile(&self) -> Option<Tile<'map>> { self.get_tileset().get_tile(self.data.id) } /// Get a reference to the layer tile's referenced tileset. diff --git a/src/tile.rs b/src/tile.rs index 5d8f18374dfeb6141f02e7ff5153da89afac60bb..c99301b35e7ee80ea19395558d91f2d81dfbb338 100644 --- a/src/tile.rs +++ b/src/tile.rs @@ -9,26 +9,73 @@ use crate::{ layers::ObjectLayerData, properties::{parse_properties, Properties}, util::{get_attrs, parse_tag, XmlEventResult}, + Tileset, }; pub type TileId = u32; #[derive(Debug, PartialEq, Clone, Default)] -pub struct Tile { - pub image: Option<Image>, - pub properties: Properties, - pub collision: Option<ObjectLayerData>, - pub animation: Option<Vec<Frame>>, - pub tile_type: Option<String>, - pub probability: f32, +pub(crate) struct TileData { + image: Option<Image>, + properties: Properties, + collision: Option<ObjectLayerData>, + animation: Option<Vec<Frame>>, + tile_type: Option<String>, + probability: f32, } -impl Tile { +pub struct Tile<'tileset> { + pub(crate) tileset: &'tileset Tileset, + pub(crate) data: &'tileset TileData, +} + +impl<'tileset> Tile<'tileset> { + pub(crate) fn new(tileset: &'tileset Tileset, data: &'tileset TileData) -> Self { + Self { tileset, data } + } + + /// Get the tileset this tile is from. + pub fn tileset(&self) -> &'tileset Tileset { + self.tileset + } + + /// Get a reference to the tile's image. + pub fn image(&self) -> Option<&Image> { + self.data.image.as_ref() + } + + /// Get a reference to the tile's properties. + pub fn properties(&self) -> &Properties { + &self.data.properties + } + + /// Get a reference to the tile's collision. + pub fn collision(&self) -> Option<&ObjectLayerData> { + self.data.collision.as_ref() + } + + /// Get a reference to the tile's animation frames. + pub fn animation(&self) -> Option<&[Frame]> { + self.data.animation.as_ref().map(Vec::as_slice) + } + + /// Get a reference to the tile's type. + pub fn tile_type(&self) -> Option<&str> { + self.data.tile_type.as_deref() + } + + /// Get the tile's probability. + pub fn probability(&self) -> f32 { + self.data.probability + } +} + +impl TileData { pub(crate) fn new( parser: &mut impl Iterator<Item = XmlEventResult>, attrs: Vec<OwnedAttribute>, path_relative_to: &Path, - ) -> Result<(TileId, Tile), TiledError> { + ) -> Result<(TileId, TileData), TiledError> { let ((tile_type, probability), id) = get_attrs!( attrs, optionals: [ @@ -65,7 +112,7 @@ impl Tile { }); Ok(( id, - Tile { + TileData { image, properties, collision: objectgroup, diff --git a/src/tileset.rs b/src/tileset.rs index 9a7d8ab024c6676c44855c5362cd7993ca182927..6e819883a28c6704b1bbbb33c16ef73afd26c67c 100644 --- a/src/tileset.rs +++ b/src/tileset.rs @@ -9,8 +9,8 @@ use xml::EventReader; use crate::error::TiledError; use crate::image::Image; use crate::properties::{parse_properties, Properties}; -use crate::tile::Tile; -use crate::{util::*, Gid}; +use crate::tile::TileData; +use crate::{util::*, Gid, Tile}; /// A tileset, usually the tilesheet image. #[derive(Debug, PartialEq, Clone)] @@ -33,7 +33,7 @@ pub struct Tileset { pub image: Option<Image>, /// All the tiles present in this tileset, indexed by their local IDs. - pub tiles: HashMap<u32, Tile>, + tiles: HashMap<u32, TileData>, /// The custom properties of the tileset. pub properties: Properties, @@ -106,8 +106,8 @@ impl Tileset { } /// Gets the tile with the specified ID from the tileset. - pub fn get_tile(&self, id: u32) -> Option<&Tile> { - self.tiles.get(&id) + pub fn get_tile(&self, id: u32) -> Option<Tile> { + self.tiles.get(&id).map(|data| Tile::new(self, data)) } } @@ -244,20 +244,20 @@ impl Tileset { let mut properties = HashMap::new(); parse_tag!(parser, "tileset", { - "image" => |attrs| { - image = Some(Image::new(parser, attrs, &prop.root_path)?); - Ok(()) - }, - "properties" => |_| { - properties = parse_properties(parser)?; - Ok(()) - }, - "tile" => |attrs| { - let (id, tile) = Tile::new(parser, attrs, &prop.root_path)?; - tiles.insert(id, tile); - Ok(()) - }, - }); + "image" => |attrs| { + image = Some(Image::new(parser, attrs, &prop.root_path)?); + Ok(()) + }, + "properties" => |_| { + properties = parse_properties(parser)?; + Ok(()) + }, + "tile" => |attrs| { + let (id, tile) = TileData::new(parser, attrs, &prop.root_path)?; + tiles.insert(id, tile); + Ok(()) + }, + }); // A tileset is considered an image collection tileset if there is no image attribute (because its tiles do). let is_image_collection_tileset = image.is_none(); diff --git a/tests/lib.rs b/tests/lib.rs index d6ff22b7da196e99c891d38d19f65f19e775bd2b..1a405ff6236a0c8e81489c9130f340ea0d2058fa 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -191,7 +191,7 @@ fn test_tile_property() { let prop_value: String = if let Some(&PropertyValue::StringValue(ref v)) = r.tilesets()[0] .get_tile(1) .unwrap() - .properties + .properties() .get("a tile property") { v.clone()