-
alexdevteam authoredc3867665
tile.rs 2.11 KiB
use std::{collections::HashMap, io::Read};
use xml::{attribute::OwnedAttribute, EventReader};
use crate::{
animation::Frame,
error::TiledError,
image::Image,
objects::ObjectGroup,
properties::{parse_properties, Properties},
util::{get_attrs, parse_animation, parse_tag},
};
#[derive(Debug, PartialEq, Clone)]
pub struct Tile {
pub id: u32,
pub images: Vec<Image>,
pub properties: Properties,
pub objectgroup: Option<ObjectGroup>,
pub animation: Option<Vec<Frame>>,
pub tile_type: Option<String>,
pub probability: f32,
}
impl Tile {
pub(crate) fn new<R: Read>(
parser: &mut EventReader<R>,
attrs: Vec<OwnedAttribute>,
) -> Result<Tile, TiledError> {
let ((tile_type, probability), id) = get_attrs!(
attrs,
optionals: [
("type", tile_type, |v:String| v.parse().ok()),
("probability", probability, |v:String| v.parse().ok()),
],
required: [
("id", id, |v:String| v.parse::<u32>().ok()),
],
TiledError::MalformedAttributes("tile must have an id with the correct type".to_string())
);
let mut images = Vec::new();
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)?);
Ok(())
},
"properties" => |_| {
properties = parse_properties(parser)?;
Ok(())
},
"objectgroup" => |attrs| {
objectgroup = Some(ObjectGroup::new(parser, attrs, None)?);
Ok(())
},
"animation" => |_| {
animation = Some(parse_animation(parser)?);
Ok(())
},
});
Ok(Tile {
id,
images,
properties,
objectgroup,
animation,
tile_type,
probability: probability.unwrap_or(1.0),
})
}
}