tiled/layers/tile/
finite.rs

1use xml::attribute::OwnedAttribute;
2
3use crate::{
4    util::{get_attrs, map_wrapper, XmlEventResult},
5    LayerTile, LayerTileData, MapTilesetGid, Result,
6};
7
8use super::util::parse_data_line;
9
10/// The raw data of a [`FiniteTileLayer`]. Does not include a reference to its parent [`Map`](crate::Map).
11#[derive(PartialEq, Clone, Default)]
12pub struct FiniteTileLayerData {
13    width: u32,
14    height: u32,
15    /// The tiles are arranged in rows.
16    tiles: Vec<Option<LayerTileData>>,
17}
18
19impl std::fmt::Debug for FiniteTileLayerData {
20    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21        f.debug_struct("FiniteTileLayerData")
22            .field("width", &self.width)
23            .field("height", &self.height)
24            .finish()
25    }
26}
27
28impl FiniteTileLayerData {
29    /// Get the tile layer's width in tiles.
30    #[inline]
31    pub fn width(&self) -> u32 {
32        self.width
33    }
34
35    /// Get the tile layer's height in tiles.
36    #[inline]
37    pub fn height(&self) -> u32 {
38        self.height
39    }
40
41    pub(crate) fn new(
42        parser: &mut impl Iterator<Item = XmlEventResult>,
43        attrs: Vec<OwnedAttribute>,
44        width: u32,
45        height: u32,
46        tilesets: &[MapTilesetGid],
47    ) -> Result<Self> {
48        let (e, c) = get_attrs!(
49            for v in attrs {
50                Some("encoding") => encoding = v,
51                Some("compression") => compression = v,
52            }
53            (encoding, compression)
54        );
55
56        let tiles = parse_data_line(e, c, parser, tilesets)?;
57
58        Ok(Self {
59            width,
60            height,
61            tiles,
62        })
63    }
64
65    /// Obtains the tile data present at the position given.
66    ///
67    /// If the position given is invalid or the position is empty, this function will return [`None`].
68    ///
69    /// If you want to get a [`Tile`](`crate::Tile`) instead, use [`FiniteTileLayer::get_tile()`].
70    pub fn get_tile_data(&self, x: i32, y: i32) -> Option<&LayerTileData> {
71        if x < self.width as i32 && y < self.height as i32 && x >= 0 && y >= 0 {
72            self.tiles[x as usize + y as usize * self.width as usize].as_ref()
73        } else {
74            None
75        }
76    }
77}
78
79map_wrapper!(
80    #[doc = "A [`TileLayer`](super::TileLayer) with a defined bound (width and height)."]
81    FiniteTileLayer => FiniteTileLayerData
82);
83
84impl<'map> FiniteTileLayer<'map> {
85    /// Obtains the tile present at the position given.
86    ///
87    /// If the position given is invalid or the position is empty, this function will return [`None`].
88    pub fn get_tile(&self, x: i32, y: i32) -> Option<LayerTile<'map>> {
89        self.data
90            .get_tile_data(x, y)
91            .map(|data| LayerTile::new(self.map(), data))
92    }
93}