Skip to content
Snippets Groups Projects
finite.rs 2.33 KiB
Newer Older
use xml::attribute::OwnedAttribute;

use crate::{
    util::{get_attrs, map_wrapper, XmlEventResult},
    LayerTile, LayerTileData, MapTilesetGid, TiledError,
};

use super::util::parse_data_line;

#[derive(PartialEq, Clone, Default)]
pub(crate) struct FiniteTileLayerData {
    width: u32,
    height: u32,
    /// The tiles are arranged in rows.
    tiles: Vec<Option<LayerTileData>>,
}

impl std::fmt::Debug for FiniteTileLayerData {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("FiniteTileLayerData")
            .field("width", &self.width)
            .field("height", &self.height)
            .finish()
    }
}

impl FiniteTileLayerData {
    pub(crate) fn new(
        parser: &mut impl Iterator<Item = XmlEventResult>,
        attrs: Vec<OwnedAttribute>,
        width: u32,
        height: u32,
        tilesets: &[MapTilesetGid],
    ) -> Result<Self, TiledError> {
Alejandro Perea's avatar
Alejandro Perea committed
        let (e, c) = get_attrs!(
            attrs,
            optionals: [
                ("encoding", encoding, |v| Some(v)),
                ("compression", compression, |v| Some(v)),
        );

        let tiles = parse_data_line(e, c, parser, tilesets)?;

        Ok(Self {
            width,
            height,
            tiles,
        })
    }

    pub(crate) fn get_tile(&self, x: i32, y: i32) -> Option<&LayerTileData> {
        if x < self.width as i32 && y < self.height as i32 && x >= 0 && y >= 0 {
            self.tiles[x as usize + y as usize * self.width as usize].as_ref()
map_wrapper!(
    #[doc = "A [`TileLayer`](super::TileLayer) with a defined bound (width and height)."]
    FiniteTileLayer => FiniteTileLayerData
);

impl<'map> FiniteTileLayer<'map> {
    /// Obtains the tile present at the position given.
    /// 
    /// If the position given is invalid or the position is empty, this function will return [`None`].
    pub fn get_tile(&self, x: i32, y: i32) -> Option<LayerTile> {
        self.data
            .get_tile(x, y)
            .and_then(|data| Some(LayerTile::new(self.map(), data)))
    }

    /// Get the tile layer's width in tiles.
    pub fn width(&self) -> u32 {
    }

    /// Get the tile layer's height in tiles.
    pub fn height(&self) -> u32 {