Newer
Older
use std::collections::HashMap;
use xml::attribute::OwnedAttribute;
use crate::{
parse_properties,
util::{get_attrs, map_wrapper, parse_tag, XmlEventResult},
Color, Map, MapTilesetGid, Object, ObjectData, Properties, TiledError,
/// Raw data referring to a map object layer or tile collision data.
#[derive(Debug, PartialEq, Clone)]
pub struct ObjectLayerData {
/// The objects present in this layer.
/// The color used in the editor to display objects in this layer.
pub colour: Option<Color>,
}
impl ObjectLayerData {
/// If it is known that there are no objects with tile images in it (i.e. collision data)
/// then we can pass in [`None`] as the tilesets
pub(crate) fn new(
parser: &mut impl Iterator<Item = XmlEventResult>,
attrs: Vec<OwnedAttribute>,
tilesets: Option<&[MapTilesetGid]>,
) -> Result<(ObjectLayerData, Properties), TiledError> {
attrs,
optionals: [
("color", colour, |v:String| v.parse().ok()),
);
let mut objects = Vec::new();
let mut properties = HashMap::new();
parse_tag!(parser, "objectgroup", {
"object" => |attrs| {
objects.push(ObjectData::new(parser, attrs, tilesets)?);
Ok(())
},
"properties" => |_| {
properties = parse_properties(parser)?;
Ok(())
},
});
Ok((ObjectLayerData { objects, colour: c }, properties))
}
}
map_wrapper!(
#[doc = "Also called an \"object group\". Used for storing [`Object`]s in a map."]
ObjectLayer => ObjectLayerData);
/// Obtains the object corresponding to the index given.
pub fn get_object(&self, idx: usize) -> Option<Object<'map>> {
.map(|data| Object::new(self.map, data))
}
/// Returns an iterator over the objects present in this layer, in the order they were declared
/// in in the TMX file.
pub fn objects(&self) -> Objects<'map> {
Objects::new(self.map, self.data)
}
/// Get a reference to the object layer's colour.
pub fn colour(&self) -> Option<Color> {
self.data.colour
}
}
/// An iterator that iterates over all the objects in an object layer, obtained via [`ObjectLayer::objects`].
pub struct Objects<'map> {
map: &'map Map,
data: &'map ObjectLayerData,
index: usize,
}
impl<'map> Objects<'map> {
fn new(map: &'map Map, data: &'map ObjectLayerData) -> Self {
Self {
map,
data,
index: 0,
}
}
}
impl<'map> Iterator for Objects<'map> {
type Item = Object<'map>;
fn next(&mut self) -> Option<Self::Item> {
let object_data = self.data.objects.get(self.index)?;
self.index += 1;
Some(Object::new(self.map, object_data))
}
}
impl<'map> ExactSizeIterator for Objects<'map> {
fn len(&self) -> usize {
self.data.objects.len() - self.index