From 1390a86a09dd0a6acc6d42e3425fcc19eb759060 Mon Sep 17 00:00:00 2001 From: Krzysztof Szot Date: Thu, 15 Aug 2019 00:14:27 +0200 Subject: [PATCH 1/3] Flatten tiles to Vec u32 * Create TilesContainer for ease of use * Provide some means to easily convert to Vec Vec u32 * Override [], use as [row][column] --- src/lib.rs | 80 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 56 insertions(+), 24 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index be48dd69..00136da1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -623,6 +623,38 @@ impl Image { } } +#[derive(Debug, PartialEq, Clone)] +pub struct TilesContainer { + pub data: Vec, + pub tiles_per_row: u32, +} + +impl std::ops::Index for TilesContainer { + type Output = [u32]; + + fn index(&self, index: usize) -> &Self::Output { + let tiles_per_row = self.tiles_per_row as usize; + let start_index = index * tiles_per_row; + let end_index = start_index + tiles_per_row; + &self.data[start_index..end_index] + } +} + +impl From<&TilesContainer> for Vec> { + fn from(item: &TilesContainer) -> Self { + let mut data: Vec> = Vec::new(); + let tiles_per_row = item.tiles_per_row as usize; + let number_of_vectors = item.data.len() / tiles_per_row; + for x in 0..number_of_vectors { + let start_index = x * tiles_per_row; + let end_index = start_index + tiles_per_row; + let row: Vec = (&item.data[start_index..end_index]).iter().cloned().collect(); + data.push(row); + } + data + } +} + #[derive(Debug, PartialEq, Clone)] pub struct Layer { pub name: String, @@ -630,7 +662,7 @@ pub struct Layer { pub visible: bool, /// The tiles are arranged in rows. Each tile is a number which can be used /// to find which tileset it belongs to and can then be rendered. - pub tiles: Vec>, + pub tiles: TilesContainer, pub properties: Properties, pub layer_index: u32, } @@ -653,7 +685,10 @@ impl Layer { ], TiledError::MalformedAttributes("layer must have a name".to_string()) ); - let mut tiles = Vec::new(); + let mut tiles = TilesContainer { + data: Vec::new(), + tiles_per_row: 0, + }; let mut properties = HashMap::new(); parse_tag!(parser, "layer", { "data" => |attrs| { @@ -971,7 +1006,7 @@ fn parse_data( parser: &mut EventReader, attrs: Vec, width: u32, -) -> Result>, TiledError> { +) -> Result { let ((e, c), ()) = get_attrs!( attrs, optionals: [ @@ -990,7 +1025,7 @@ fn parse_data( } (Some(e), None) => match e.as_ref() { "base64" => return parse_base64(parser).map(|v| convert_to_u32(&v, width)), - "csv" => return decode_csv(parser), + "csv" => return decode_csv(parser, width), e => return Err(TiledError::Other(format!("Unknown encoding format {}", e))), }, (Some(e), Some(c)) => match (e.as_ref(), c.as_ref()) { @@ -1054,27 +1089,23 @@ fn decode_gzip(data: Vec) -> Result, TiledError> { Ok(data) } -fn decode_csv(parser: &mut EventReader) -> Result>, TiledError> { +fn decode_csv(parser: &mut EventReader, width: u32) -> Result { loop { match try!(parser.next().map_err(TiledError::XmlDecodingError)) { XmlEvent::Characters(s) => { - let mut rows: Vec> = Vec::new(); - for row in s.split('\n') { - if row.trim() == "" { - continue; - } - rows.push( - row.split(',') - .filter(|v| v.trim() != "") - .map(|v| v.replace('\r', "").parse().unwrap()) - .collect(), - ); - } - return Ok(rows); + let data: Vec = s.replace('\r', "").replace('\n',"").split(",").map(|v| v.parse().unwrap()).collect(); + let tiles = TilesContainer { + data, + tiles_per_row: width, + }; + return Ok(tiles); } XmlEvent::EndElement { name, .. } => { if name.local_name == "data" { - return Ok(Vec::new()); + return Ok(TilesContainer { + data: Vec::new(), + tiles_per_row: 0, + }); } } _ => {} @@ -1082,21 +1113,22 @@ fn decode_csv(parser: &mut EventReader) -> Result>, Til } } -fn convert_to_u32(all: &Vec, width: u32) -> Vec> { +fn convert_to_u32(all: &Vec, width: u32) -> TilesContainer { let mut data = Vec::new(); for chunk in all.chunks((width * 4) as usize) { - let mut row = Vec::new(); for i in 0..width { let start: usize = i as usize * 4; let n = ((chunk[start + 3] as u32) << 24) + ((chunk[start + 2] as u32) << 16) + ((chunk[start + 1] as u32) << 8) + chunk[start] as u32; - row.push(n); + data.push(n); } - data.push(row); } - data + TilesContainer { + data, + tiles_per_row: width, + } } fn parse_impl(reader: R, map_path: Option<&Path>) -> Result { From c0cbeb14069707035b276c46ddb2e037cf4cb07c Mon Sep 17 00:00:00 2001 From: Krzysztof Szot Date: Thu, 15 Aug 2019 00:31:37 +0200 Subject: [PATCH 2/3] Ran cargo fmt --- src/lib.rs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 00136da1..7f074ec8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -648,7 +648,10 @@ impl From<&TilesContainer> for Vec> { for x in 0..number_of_vectors { let start_index = x * tiles_per_row; let end_index = start_index + tiles_per_row; - let row: Vec = (&item.data[start_index..end_index]).iter().cloned().collect(); + let row: Vec = (&item.data[start_index..end_index]) + .iter() + .cloned() + .collect(); data.push(row); } data @@ -1089,11 +1092,19 @@ fn decode_gzip(data: Vec) -> Result, TiledError> { Ok(data) } -fn decode_csv(parser: &mut EventReader, width: u32) -> Result { +fn decode_csv( + parser: &mut EventReader, + width: u32, +) -> Result { loop { match try!(parser.next().map_err(TiledError::XmlDecodingError)) { XmlEvent::Characters(s) => { - let data: Vec = s.replace('\r', "").replace('\n',"").split(",").map(|v| v.parse().unwrap()).collect(); + let data: Vec = s + .replace('\r', "") + .replace('\n', "") + .split(",") + .map(|v| v.parse().unwrap()) + .collect(); let tiles = TilesContainer { data, tiles_per_row: width, From a6920f8d047267aeae175346e52906fe41d53750 Mon Sep 17 00:00:00 2001 From: Krzysztof Szot Date: Thu, 15 Aug 2019 06:48:40 +0200 Subject: [PATCH 3/3] * Removed [] operator overload * added number_of_rows field --- src/lib.rs | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 7f074ec8..b2d3eab4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -627,25 +627,15 @@ impl Image { pub struct TilesContainer { pub data: Vec, pub tiles_per_row: u32, -} - -impl std::ops::Index for TilesContainer { - type Output = [u32]; - - fn index(&self, index: usize) -> &Self::Output { - let tiles_per_row = self.tiles_per_row as usize; - let start_index = index * tiles_per_row; - let end_index = start_index + tiles_per_row; - &self.data[start_index..end_index] - } + pub number_of_rows: u32, } impl From<&TilesContainer> for Vec> { fn from(item: &TilesContainer) -> Self { let mut data: Vec> = Vec::new(); let tiles_per_row = item.tiles_per_row as usize; - let number_of_vectors = item.data.len() / tiles_per_row; - for x in 0..number_of_vectors { + let number_of_rows = item.number_of_rows as usize; + for x in 0..number_of_rows { let start_index = x * tiles_per_row; let end_index = start_index + tiles_per_row; let row: Vec = (&item.data[start_index..end_index]) @@ -691,6 +681,7 @@ impl Layer { let mut tiles = TilesContainer { data: Vec::new(), tiles_per_row: 0, + number_of_rows: 0, }; let mut properties = HashMap::new(); parse_tag!(parser, "layer", { @@ -1105,9 +1096,11 @@ fn decode_csv( .split(",") .map(|v| v.parse().unwrap()) .collect(); + let number_of_rows = data.len() as u32 / width; let tiles = TilesContainer { data, tiles_per_row: width, + number_of_rows, }; return Ok(tiles); } @@ -1116,6 +1109,7 @@ fn decode_csv( return Ok(TilesContainer { data: Vec::new(), tiles_per_row: 0, + number_of_rows: 0, }); } } @@ -1136,9 +1130,11 @@ fn convert_to_u32(all: &Vec, width: u32) -> TilesContainer { data.push(n); } } + let number_of_rows = data.len() as u32 / width; TilesContainer { data, tiles_per_row: width, + number_of_rows, } }