Consistent ordering of components and attributes on export
parent
73b5ba6cc7
commit
07a7ee97b7
|
@ -1,8 +1,7 @@
|
||||||
use std::{error::Error, convert::TryInto, cmp::max, num::ParseIntError, collections::HashMap};
|
use std::{error::Error, convert::TryInto, cmp::max, num::ParseIntError, collections::HashMap};
|
||||||
use image::GenericImageView;
|
use image::GenericImageView;
|
||||||
use linked_hash_set::LinkedHashSet;
|
|
||||||
use crate::reskit::{tileset::image_to_tiles, utility::{symbol_to_pascal, print_info}, cli::settings::TileOrder};
|
use crate::reskit::{tileset::image_to_tiles, utility::{symbol_to_pascal, print_info}, cli::settings::TileOrder};
|
||||||
use super::converter::{TiledTilemap, Layer, SystemPlane, TiledTileset};
|
use super::{converter::{TiledTilemap, Layer, SystemPlane, TiledTileset}, ecs::Component};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Output the .bin and .pal file (using `tileset` tool to build it) containing each of the tiles
|
* Output the .bin and .pal file (using `tileset` tool to build it) containing each of the tiles
|
||||||
|
@ -227,14 +226,18 @@ pub fn get_ecs( tilemap: &TiledTilemap, component_ids: &HashMap<String, u8>, att
|
||||||
let mut result: Vec<u8> = Vec::new();
|
let mut result: Vec<u8> = Vec::new();
|
||||||
|
|
||||||
// Build a complete set of types
|
// Build a complete set of types
|
||||||
let mut types: LinkedHashSet<LinkedHashSet<String>> = LinkedHashSet::new();
|
let mut types: Vec<Vec<u8>> = Vec::new();
|
||||||
for entity in &tilemap.ecs {
|
for entity in &tilemap.ecs {
|
||||||
// Get the list of components attached to this entity
|
// Get the list of component IDs attached to this entity
|
||||||
let components: LinkedHashSet<String> = entity.components.keys().map( | id | id.to_lowercase() ).collect();
|
let mut components: Vec<u8> = entity.components.keys()
|
||||||
|
.map( | id | Ok( *component_ids.get( id ).ok_or( format!( "invalid file: when building type table: undefined component \"{}\"", id ) )? ) )
|
||||||
|
.collect::<Result<Vec<u8>, Box<dyn Error>>>()?;
|
||||||
|
components.sort();
|
||||||
|
|
||||||
// Assign this unique combination of components a type id
|
// Assign this unique combination of components a type id by inserting it into `types`
|
||||||
// by inserting it into `types`
|
if let None = types.iter().find( | ecs_type | ecs_type == &&components ) {
|
||||||
types.insert_if_absent( components );
|
types.push( components );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let largest_type_size: u16 = types.iter()
|
let largest_type_size: u16 = types.iter()
|
||||||
|
@ -252,13 +255,7 @@ pub fn get_ecs( tilemap: &TiledTilemap, component_ids: &HashMap<String, u8>, att
|
||||||
// For (Number of Types):
|
// For (Number of Types):
|
||||||
for ecs_type in &types {
|
for ecs_type in &types {
|
||||||
// (Type Definition Union Size) bytes: List of Component IDs
|
// (Type Definition Union Size) bytes: List of Component IDs
|
||||||
let mut type_component_ids: Vec<u8> = vec![];
|
let mut type_component_ids: Vec<u8> = ecs_type.clone();
|
||||||
|
|
||||||
for component in ecs_type {
|
|
||||||
type_component_ids.push(
|
|
||||||
*component_ids.get( component ).ok_or( format!( "invalid file: when building type table: undefined component \"{}\"", component ) )?
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fill the remainder of the union with 0xFF, if needed
|
// Fill the remainder of the union with 0xFF, if needed
|
||||||
let remainder = largest_type_size as usize - type_component_ids.len();
|
let remainder = largest_type_size as usize - type_component_ids.len();
|
||||||
|
@ -275,10 +272,10 @@ pub fn get_ecs( tilemap: &TiledTilemap, component_ids: &HashMap<String, u8>, att
|
||||||
|
|
||||||
// For (Object Table Size)
|
// For (Object Table Size)
|
||||||
for entity in &tilemap.ecs {
|
for entity in &tilemap.ecs {
|
||||||
// Do the thing again
|
let mut components: Vec<u8> = entity.components.keys()
|
||||||
let mut components: Vec<String> = entity.components.keys().map( | id | id.to_lowercase() ).collect();
|
.map( | id | Ok( *component_ids.get( id ).ok_or( format!( "invalid file: when building type table: undefined component \"{}\"", id ) )? ) )
|
||||||
|
.collect::<Result<Vec<u8>, Box<dyn Error>>>()?;
|
||||||
components.sort();
|
components.sort();
|
||||||
let components: LinkedHashSet<String> = components.into_iter().collect();
|
|
||||||
|
|
||||||
// What type id is this?
|
// What type id is this?
|
||||||
let type_id: u8 = types.iter().position( | ecs_type | ecs_type == &components ).ok_or( "internal error: no type id" )? as u8;
|
let type_id: u8 = types.iter().position( | ecs_type | ecs_type == &components ).ok_or( "internal error: no type id" )? as u8;
|
||||||
|
@ -314,7 +311,10 @@ pub fn get_ecs( tilemap: &TiledTilemap, component_ids: &HashMap<String, u8>, att
|
||||||
for entity in &tilemap.ecs {
|
for entity in &tilemap.ecs {
|
||||||
let mut written_attributes = 0;
|
let mut written_attributes = 0;
|
||||||
|
|
||||||
for ( component_id, component ) in &entity.components {
|
let mut components: Vec<(&String, &Component)> = entity.components.iter().collect();
|
||||||
|
components.sort_by_key( | ( component_id, _ ) | component_ids[ *component_id ] );
|
||||||
|
|
||||||
|
for ( component_id, component ) in components {
|
||||||
let attributes_in_order = attribute_ids.get( component_id );
|
let attributes_in_order = attribute_ids.get( component_id );
|
||||||
if let Some( attributes_in_order ) = attributes_in_order {
|
if let Some( attributes_in_order ) = attributes_in_order {
|
||||||
for attribute_id in attributes_in_order {
|
for attribute_id in attributes_in_order {
|
||||||
|
|
Loading…
Reference in New Issue