-
Notifications
You must be signed in to change notification settings - Fork 106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Flatten tiles to vec u32 #58
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -623,14 +623,39 @@ impl Image { | |
} | ||
} | ||
|
||
#[derive(Debug, PartialEq, Clone)] | ||
pub struct TilesContainer { | ||
pub data: Vec<u32>, | ||
pub tiles_per_row: u32, | ||
pub number_of_rows: u32, | ||
} | ||
|
||
impl From<&TilesContainer> for Vec<Vec<u32>> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think we need this converter. What use would people have for converting to this sub-optimal data structure? Maybe instead it could be useful to provide a getter to retrieve a tile given |
||
fn from(item: &TilesContainer) -> Self { | ||
let mut data: Vec<Vec<u32>> = Vec::new(); | ||
let tiles_per_row = item.tiles_per_row as usize; | ||
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<u32> = (&item.data[start_index..end_index]) | ||
.iter() | ||
.cloned() | ||
.collect(); | ||
data.push(row); | ||
} | ||
data | ||
} | ||
} | ||
|
||
#[derive(Debug, PartialEq, Clone)] | ||
pub struct Layer { | ||
pub name: String, | ||
pub opacity: f32, | ||
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<Vec<u32>>, | ||
pub tiles: TilesContainer, | ||
pub properties: Properties, | ||
pub layer_index: u32, | ||
} | ||
|
@@ -653,7 +678,11 @@ impl Layer { | |
], | ||
TiledError::MalformedAttributes("layer must have a name".to_string()) | ||
); | ||
let mut tiles = Vec::new(); | ||
let mut tiles = TilesContainer { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could this be initialized with correct data from the start? I feel like this could lead to invalid states where the tiles member never got initialized. |
||
data: Vec::new(), | ||
tiles_per_row: 0, | ||
number_of_rows: 0, | ||
}; | ||
let mut properties = HashMap::new(); | ||
parse_tag!(parser, "layer", { | ||
"data" => |attrs| { | ||
|
@@ -971,7 +1000,7 @@ fn parse_data<R: Read>( | |
parser: &mut EventReader<R>, | ||
attrs: Vec<OwnedAttribute>, | ||
width: u32, | ||
) -> Result<Vec<Vec<u32>>, TiledError> { | ||
) -> Result<TilesContainer, TiledError> { | ||
let ((e, c), ()) = get_attrs!( | ||
attrs, | ||
optionals: [ | ||
|
@@ -990,7 +1019,7 @@ fn parse_data<R: Read>( | |
} | ||
(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,49 +1083,59 @@ fn decode_gzip(data: Vec<u8>) -> Result<Vec<u8>, TiledError> { | |
Ok(data) | ||
} | ||
|
||
fn decode_csv<R: Read>(parser: &mut EventReader<R>) -> Result<Vec<Vec<u32>>, TiledError> { | ||
fn decode_csv<R: Read>( | ||
parser: &mut EventReader<R>, | ||
width: u32, | ||
) -> Result<TilesContainer, TiledError> { | ||
loop { | ||
match try!(parser.next().map_err(TiledError::XmlDecodingError)) { | ||
XmlEvent::Characters(s) => { | ||
let mut rows: Vec<Vec<u32>> = 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<u32> = s | ||
.replace('\r', "") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think |
||
.replace('\n', "") | ||
.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); | ||
} | ||
XmlEvent::EndElement { name, .. } => { | ||
if name.local_name == "data" { | ||
return Ok(Vec::new()); | ||
return Ok(TilesContainer { | ||
aleokdev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
data: Vec::new(), | ||
tiles_per_row: 0, | ||
number_of_rows: 0, | ||
}); | ||
} | ||
} | ||
_ => {} | ||
} | ||
} | ||
} | ||
|
||
fn convert_to_u32(all: &Vec<u8>, width: u32) -> Vec<Vec<u32>> { | ||
fn convert_to_u32(all: &Vec<u8>, 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 | ||
let number_of_rows = data.len() as u32 / width; | ||
TilesContainer { | ||
data, | ||
tiles_per_row: width, | ||
number_of_rows, | ||
} | ||
} | ||
|
||
fn parse_impl<R: Read>(reader: R, map_path: Option<&Path>) -> Result<Map, TiledError> { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe just
width
andheight
would do as property names?