Skip to content
Snippets Groups Projects
Commit e6043afa authored by Matthew Hall's avatar Matthew Hall
Browse files

Can now save object groups

parent 3a29e2b6
No related branches found
No related tags found
No related merge requests found
...@@ -17,4 +17,16 @@ ...@@ -17,4 +17,16 @@
eJzt1zEKwzAMBVBdIScIJXPS+9+uDY1BuHbpULvLeyDIkEkfIXmLiK2qW6cYb7lqv+p41r1TcpmjZFLPyamVEXOcGSzpu66SixkZb41Xz9dO7fE+O4yR+703KmdyhExGK32v+1zv+rxLZDJO7vO5G3KvSyY1eYxT31Dlrm3t9AhZzNC6a+v3RsmhNzP83qdc8ttdHuO07thWLlt4E87w7S6wM+bo7e3ef8z1KRt5/N+388N88gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIHsArPIXTA== eJzt1zEKwzAMBVBdIScIJXPS+9+uDY1BuHbpULvLeyDIkEkfIXmLiK2qW6cYb7lqv+p41r1TcpmjZFLPyamVEXOcGSzpu66SixkZb41Xz9dO7fE+O4yR+703KmdyhExGK32v+1zv+rxLZDJO7vO5G3KvSyY1eYxT31Dlrm3t9AhZzNC6a+v3RsmhNzP83qdc8ttdHuO07thWLlt4E87w7S6wM+bo7e3ef8z1KRt5/N+388N88gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIHsArPIXTA==
</data> </data>
</layer> </layer>
<objectgroup name="Object group" width="100" height="100">
<object x="14" y="9" width="285" height="135"/>
<object x="329" y="217" width="102" height="109">
<ellipse/>
</object>
<object x="314" y="376">
<polyline points="0,0 -111,-63 -203,27 -205,-130 -78,-150 -6,-6"/>
</object>
<object x="479" y="84">
<polygon points="0,0 139,128 -55,64 -37,-49 159,47 138,126"/>
</object>
</objectgroup>
</map> </map>
#![feature(globs, macro_rules)] #![feature(globs, macro_rules, struct_variant)]
extern crate flate2; extern crate flate2;
extern crate xml; extern crate xml;
extern crate serialize; extern crate serialize;
...@@ -59,7 +59,7 @@ macro_rules! parse_tag { ...@@ -59,7 +59,7 @@ macro_rules! parse_tag {
#[deriving(Show)] #[deriving(Show)]
pub enum TiledError { pub enum TiledError {
MissingAttributes(String), MalformedAttributes(String),
DecompressingError(IoError), DecompressingError(IoError),
DecodingError(FromBase64Error), DecodingError(FromBase64Error),
Other(String) Other(String)
...@@ -76,7 +76,7 @@ fn parse_properties<B: Buffer>(parser: &mut EventReader<B>) -> Result<Properties ...@@ -76,7 +76,7 @@ fn parse_properties<B: Buffer>(parser: &mut EventReader<B>) -> Result<Properties
optionals: [], optionals: [],
required: [("name", key, String, |v| Some(v)), required: [("name", key, String, |v| Some(v)),
("value", value, String, |v| Some(v))], ("value", value, String, |v| Some(v))],
MissingAttributes("property must have a name and a value".to_string())); MalformedAttributes("property must have a name and a value".to_string()));
p.insert(k, v); p.insert(k, v);
Ok(()) Ok(())
}); });
...@@ -93,6 +93,7 @@ pub struct Map { ...@@ -93,6 +93,7 @@ pub struct Map {
tile_height: int, tile_height: int,
tilesets: Vec<Tileset>, tilesets: Vec<Tileset>,
layers: Vec<Layer>, layers: Vec<Layer>,
object_groups: Vec<ObjectGroup>,
properties: Properties properties: Properties
} }
...@@ -107,11 +108,12 @@ impl Map { ...@@ -107,11 +108,12 @@ impl Map {
("height", height, int, |v:String| from_str(v[])), ("height", height, int, |v:String| from_str(v[])),
("tilewidth", tile_width, int, |v:String| from_str(v[])), ("tilewidth", tile_width, int, |v:String| from_str(v[])),
("tileheight", tile_height, int, |v:String| from_str(v[]))], ("tileheight", tile_height, int, |v:String| from_str(v[]))],
MissingAttributes("map must have a version, width and height with correct types".to_string())); MalformedAttributes("map must have a version, width and height with correct types".to_string()));
let mut tilesets = Vec::new(); let mut tilesets = Vec::new();
let mut layers = Vec::new(); let mut layers = Vec::new();
let mut properties = HashMap::new(); let mut properties = HashMap::new();
let mut object_groups = Vec::new();
parse_tag!(parser, "map", parse_tag!(parser, "map",
"tileset" => |attrs| { "tileset" => |attrs| {
tilesets.push(try!(Tileset::new(parser, attrs))); tilesets.push(try!(Tileset::new(parser, attrs)));
...@@ -124,11 +126,15 @@ impl Map { ...@@ -124,11 +126,15 @@ impl Map {
"properties" => |_| { "properties" => |_| {
properties = try!(parse_properties(parser)); properties = try!(parse_properties(parser));
Ok(()) Ok(())
},
"objectgroup" => |attrs| {
object_groups.push(try!(ObjectGroup::new(parser, attrs)));
Ok(())
}); });
Ok(Map {version: v, orientation: o, Ok(Map {version: v, orientation: o,
width: w, height: h, width: w, height: h,
tile_width: tw, tile_height: th, tile_width: tw, tile_height: th,
tilesets: tilesets, layers: layers, tilesets: tilesets, layers: layers, object_groups: object_groups,
properties: properties}) properties: properties})
} }
...@@ -177,7 +183,7 @@ impl Tileset { ...@@ -177,7 +183,7 @@ impl Tileset {
optionals: [], optionals: [],
required: [("firstgid", first_gid, uint, |v:String| from_str(v[])), required: [("firstgid", first_gid, uint, |v:String| from_str(v[])),
("name", name, String, |v| Some(v))], ("name", name, String, |v| Some(v))],
MissingAttributes("tileset must have a firstgid and name with correct types".to_string())); MalformedAttributes("tileset must have a firstgid and name with correct types".to_string()));
let mut images = Vec::new(); let mut images = Vec::new();
parse_tag!(parser, "tileset", parse_tag!(parser, "tileset",
...@@ -204,7 +210,7 @@ impl Image { ...@@ -204,7 +210,7 @@ impl Image {
required: [("source", source, String, |v| Some(v)), required: [("source", source, String, |v| Some(v)),
("width", width, int, |v:String| from_str(v[])), ("width", width, int, |v:String| from_str(v[])),
("height", height, int, |v:String| from_str(v[]))], ("height", height, int, |v:String| from_str(v[]))],
MissingAttributes("image must have a source, width and height with correct types".to_string())); MalformedAttributes("image must have a source, width and height with correct types".to_string()));
parse_tag!(parser, "image", "" => |_| Ok(())); parse_tag!(parser, "image", "" => |_| Ok(()));
Ok(Image {source: s, width: w, height: h}) Ok(Image {source: s, width: w, height: h})
...@@ -227,7 +233,7 @@ impl Layer { ...@@ -227,7 +233,7 @@ impl Layer {
optionals: [("opacity", opacity, f32, |v:String| from_str(v[])), optionals: [("opacity", opacity, f32, |v:String| from_str(v[])),
("visible", visible, bool, |v:String| from_str(v[]).map(|x:int| x == 1))], ("visible", visible, bool, |v:String| from_str(v[]).map(|x:int| x == 1))],
required: [("name", name, String, |v| Some(v))], required: [("name", name, String, |v| Some(v))],
MissingAttributes("layer must have a name".to_string())); MalformedAttributes("layer must have a name".to_string()));
let mut tiles = Vec::new(); let mut tiles = Vec::new();
let mut properties = HashMap::new(); let mut properties = HashMap::new();
parse_tag!(parser, "layer", parse_tag!(parser, "layer",
...@@ -244,13 +250,120 @@ impl Layer { ...@@ -244,13 +250,120 @@ impl Layer {
} }
} }
#[deriving(Show)]
pub struct ObjectGroup {
pub name: String,
pub objects: Vec<Object>
}
impl ObjectGroup {
pub fn new<B: Buffer>(parser: &mut EventReader<B>, attrs: Vec<Attribute>) -> Result<ObjectGroup, TiledError> {
let ((), n) = get_attrs!(
attrs,
optionals: [],
required: [("name", name, String, |v| Some(v))],
MalformedAttributes("object groups must have a name".to_string()));
let mut objects = Vec::new();
parse_tag!(parser, "objectgroup",
"object" => |attrs| {
objects.push(try!(Object::new(parser, attrs)));
Ok(())
});
Ok(ObjectGroup {name: n, objects: objects})
}
}
#[deriving(Show)]
pub enum Object {
Rect {x: int, y: int, width: uint, height: uint},
Ellipse {x: int, y: int, width: uint, height: uint},
Polyline {x: int, y: int, points: Vec<(int, int)>},
Polygon {x: int, y: int, points: Vec<(int, int)>}
}
impl Object {
pub fn new<B: Buffer>(parser: &mut EventReader<B>, attrs: Vec<Attribute>) -> Result<Object, TiledError> {
let ((w, h), (x, y)) = get_attrs!(
attrs,
optionals: [("width", width, uint, |v:String| from_str(v[])),
("height", height, uint, |v:String| from_str(v[]))],
required: [("x", x, int, |v:String| from_str(v[])),
("y", y, int, |v:String| from_str(v[]))],
MalformedAttributes("objects must have an x and a y number".to_string()));
let mut obj = None;
parse_tag!(parser, "object",
"ellipse" => |_| {
if w.is_none() || h.is_none() {
return Err(MalformedAttributes("An ellipse must have a width and height".to_string()));
}
let (w, h) = (w.unwrap(), h.unwrap());
obj = Some(Ellipse {x: x, y: y, width: w as uint, height: h as uint});
Ok(())
},
"polyline" => |attrs| {
obj = Some(try!(Object::new_polyline(x, y, attrs)));
Ok(())
},
"polygon" => |attrs| {
obj = Some(try!(Object::new_polygon(x, y, attrs)));
Ok(())
});
if obj.is_some() {
Ok(obj.unwrap())
} else if w.is_some() && h.is_some() {
let w = w.unwrap();
let h = h.unwrap();
Ok(Rect {x: x, y: y, width: w as uint, height: h as uint})
} else {
Err(MalformedAttributes("A rect must have a width and a height".to_string()))
}
}
fn new_polyline(x: int, y: int, attrs: Vec<Attribute>) -> Result<Object, TiledError> {
let ((), s) = get_attrs!(
attrs,
optionals: [],
required: [("points", points, String, |v| Some(v))],
MalformedAttributes("A polyline must have points".to_string()));
let points = try!(Object::parse_points(s));
Ok(Polyline {x: x, y: y, points: points})
}
fn new_polygon(x: int, y: int, attrs: Vec<Attribute>) -> Result<Object, TiledError> {
let ((), s) = get_attrs!(
attrs,
optionals: [],
required: [("points", points, String, |v| Some(v))],
MalformedAttributes("A polygon must have points".to_string()));
let points = try!(Object::parse_points(s));
Ok(Polygon {x: x, y: y, points: points})
}
fn parse_points(s: String) -> Result<Vec<(int, int)>, TiledError> {
let pairs = s[].split(' ');
let mut points = Vec::new();
for v in pairs.map(|p| p.splitn(1, ',')) {
let v: Vec<&str> = v.clone().collect();
if v.len() != 2 {
return Err(MalformedAttributes("one of a polyline's points does not have an x and y coordinate".to_string()));
}
let (x, y) = (from_str(v[0]), from_str(v[1]));
if x.is_none() || y.is_none() {
return Err(MalformedAttributes("one of polyline's points does not have integer coordinates".to_string()));
}
points.push((x.unwrap(), y.unwrap()));
}
Ok(points)
}
}
fn parse_data<B: Buffer>(parser: &mut EventReader<B>, attrs: Vec<Attribute>, width: uint) -> Result<Vec<Vec<u32>>, TiledError> { fn parse_data<B: Buffer>(parser: &mut EventReader<B>, attrs: Vec<Attribute>, width: uint) -> Result<Vec<Vec<u32>>, TiledError> {
let ((), (e, c)) = get_attrs!( let ((), (e, c)) = get_attrs!(
attrs, attrs,
optionals: [], optionals: [],
required: [("encoding", encoding, String, |v| Some(v)), required: [("encoding", encoding, String, |v| Some(v)),
("compression", compression, String, |v| Some(v))], ("compression", compression, String, |v| Some(v))],
MissingAttributes("data must have an encoding and a compression".to_string())); MalformedAttributes("data must have an encoding and a compression".to_string()));
if !(e[] == "base64" && c[] == "zlib") { if !(e[] == "base64" && c[] == "zlib") {
return Err(Other("Only base64 and zlib allowed for the moment".to_string())); return Err(Other("Only base64 and zlib allowed for the moment".to_string()));
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment