tiled/tileset/
wangset.rs

1use std::collections::HashMap;
2
3use xml::attribute::OwnedAttribute;
4
5use crate::{
6    error::Error,
7    properties::{parse_properties, Properties},
8    util::{get_attrs, parse_tag, XmlEventResult},
9    Result, TileId,
10};
11
12mod wang_color;
13pub use wang_color::*;
14mod wang_tile;
15pub use wang_tile::*;
16
17/// Wang set's terrain brush connection type.
18#[derive(Debug, PartialEq, Clone, Copy)]
19#[allow(missing_docs)]
20pub enum WangSetType {
21    Corner,
22    Edge,
23    Mixed,
24}
25
26impl Default for WangSetType {
27    fn default() -> Self {
28        WangSetType::Mixed
29    }
30}
31
32/// Raw data belonging to a WangSet.
33#[derive(Debug, PartialEq, Clone)]
34pub struct WangSet {
35    /// The name of the Wang set.
36    pub name: String,
37    /// Type of Wang set.
38    pub wang_set_type: WangSetType,
39    /// The tile ID of the tile representing this Wang set.
40    pub tile: Option<TileId>,
41    /// The colors color that can be used to define the corner and/or edge of each Wang tile.
42    pub wang_colors: Vec<WangColor>,
43    ///  All the Wang tiles present in this Wang set, indexed by their local IDs.
44    pub wang_tiles: HashMap<TileId, WangTile>,
45    /// The custom properties of this Wang set.
46    pub properties: Properties,
47}
48
49impl WangSet {
50    /// Reads data from XML parser to create a WangSet.
51    pub fn new(
52        parser: &mut impl Iterator<Item = XmlEventResult>,
53        attrs: Vec<OwnedAttribute>,
54    ) -> Result<WangSet> {
55        // Get common data
56        let (name, wang_set_type, tile) = get_attrs!(
57            for v in attrs {
58                "name" => name ?= v.parse::<String>(),
59                "type" => wang_set_type ?= v.parse::<String>(),
60                "tile" => tile ?= v.parse::<i64>(),
61            }
62            (name, wang_set_type, tile)
63        );
64
65        let wang_set_type = match wang_set_type.as_str() {
66            "corner" => WangSetType::Corner,
67            "edge" => WangSetType::Edge,
68            _ => WangSetType::default(),
69        };
70        let tile = if tile >= 0 { Some(tile as u32) } else { None };
71
72        // Gather variable data
73        let mut wang_colors = Vec::new();
74        let mut wang_tiles = HashMap::new();
75        let mut properties = HashMap::new();
76        parse_tag!(parser, "wangset", {
77            "wangcolor" => |attrs| {
78                let color = WangColor::new(parser, attrs)?;
79                wang_colors.push(color);
80                Ok(())
81            },
82            "wangtile" => |attrs| {
83                let (id, t) = WangTile::new(parser, attrs)?;
84                wang_tiles.insert(id, t);
85                Ok(())
86            },
87            "properties" => |_| {
88                properties = parse_properties(parser)?;
89                Ok(())
90            },
91        });
92
93        Ok(WangSet {
94            name,
95            wang_set_type,
96            tile,
97            wang_colors,
98            wang_tiles,
99            properties,
100        })
101    }
102}