Allow user-specified component ids in ECS
parent
6e63b9c40f
commit
31832e8882
|
@ -1,5 +1,6 @@
|
||||||
use std::{error::Error, fs::read_to_string, path::Path, borrow::Cow};
|
use std::{error::Error, fs::read_to_string, path::Path, borrow::Cow, collections::HashMap};
|
||||||
use image::{DynamicImage, GenericImageView};
|
use image::{DynamicImage, GenericImageView};
|
||||||
|
use regex::Regex;
|
||||||
use roxmltree::Node;
|
use roxmltree::Node;
|
||||||
use crate::reskit::{utility::print_warning, cli::settings::TileOrder};
|
use crate::reskit::{utility::print_warning, cli::settings::TileOrder};
|
||||||
use super::ecs;
|
use super::ecs;
|
||||||
|
@ -9,6 +10,7 @@ pub struct TiledTilemap {
|
||||||
pub tileset: Vec<TiledTileset>,
|
pub tileset: Vec<TiledTileset>,
|
||||||
pub layers: Vec<Layer>,
|
pub layers: Vec<Layer>,
|
||||||
pub ecs: Vec<ecs::Entity>,
|
pub ecs: Vec<ecs::Entity>,
|
||||||
|
pub ecs_component_ids: HashMap<String, u8>,
|
||||||
pub width: usize,
|
pub width: usize,
|
||||||
pub height: usize
|
pub height: usize
|
||||||
}
|
}
|
||||||
|
@ -252,8 +254,28 @@ pub fn get_tiled_tilemap( path: &str ) -> Result<TiledTilemap, Box<dyn Error>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the entity-component system
|
// Get the entity-component system
|
||||||
|
let mut ecs_component_ids = HashMap::new();
|
||||||
let object_group = map.descendants().find( | node | node.tag_name() == "objectgroup".into() );
|
let object_group = map.descendants().find( | node | node.tag_name() == "objectgroup".into() );
|
||||||
let ecs = if let Some( object_group ) = object_group {
|
let ecs = if let Some( object_group ) = object_group {
|
||||||
|
let object_group_properties = object_group.descendants().find( | node | node.tag_name() == "properties".into() );
|
||||||
|
if let Some( object_group_properties ) = object_group_properties {
|
||||||
|
let component_id_properties = object_group_properties.descendants()
|
||||||
|
.filter( | node | node.attribute( "name" ).unwrap_or( "" ).starts_with( "reskit-component-id" ) );
|
||||||
|
for property in component_id_properties {
|
||||||
|
let name_attribute = property.attribute( "name" ).ok_or( "internal error: no name attribute" )?;
|
||||||
|
let id: u8 = property.attribute( "value" ).ok_or( "internal error: no property value in object layer" )?.parse()?;
|
||||||
|
|
||||||
|
// Set up regex to remove individual parts
|
||||||
|
let regex = Regex::new( r#"reskit-component-id\[([a-z0-9_]+)\]"# )?;
|
||||||
|
let captures = regex.captures( name_attribute ).ok_or( "invalid file: invalid reskit-component-id key in object layer" )?;
|
||||||
|
let component_name = captures.get( 1 ).ok_or( "internal error: regex did not match properly" )?.as_str();
|
||||||
|
ecs_component_ids.insert( component_name.to_owned(), id );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the "position" component by default
|
||||||
|
ecs_component_ids.insert( "position".to_owned(), ecs_component_ids.len() as u8 );
|
||||||
|
|
||||||
ecs::get_ecs( object_group )?
|
ecs::get_ecs( object_group )?
|
||||||
} else {
|
} else {
|
||||||
Vec::new()
|
Vec::new()
|
||||||
|
@ -264,6 +286,7 @@ pub fn get_tiled_tilemap( path: &str ) -> Result<TiledTilemap, Box<dyn Error>> {
|
||||||
tileset,
|
tileset,
|
||||||
layers,
|
layers,
|
||||||
ecs,
|
ecs,
|
||||||
|
ecs_component_ids,
|
||||||
width,
|
width,
|
||||||
height
|
height
|
||||||
}
|
}
|
||||||
|
|
|
@ -226,8 +226,7 @@ pub fn get_ecs( tilemap: &TiledTilemap ) -> Result<Vec<u8>, Box<dyn Error>> {
|
||||||
|
|
||||||
let mut result: Vec<u8> = Vec::new();
|
let mut result: Vec<u8> = Vec::new();
|
||||||
|
|
||||||
// Build a complete set of component IDs and types
|
// Build a complete set of types
|
||||||
let mut component_ids: LinkedHashSet<String> = LinkedHashSet::new();
|
|
||||||
let mut types: LinkedHashSet<LinkedHashSet<String>> = LinkedHashSet::new();
|
let mut types: LinkedHashSet<LinkedHashSet<String>> = LinkedHashSet::new();
|
||||||
for entity in &tilemap.ecs {
|
for entity in &tilemap.ecs {
|
||||||
// Get the list of components attached to this entity
|
// Get the list of components attached to this entity
|
||||||
|
@ -236,9 +235,6 @@ pub fn get_ecs( tilemap: &TiledTilemap ) -> Result<Vec<u8>, Box<dyn Error>> {
|
||||||
components.sort();
|
components.sort();
|
||||||
let components: LinkedHashSet<String> = components.into_iter().collect();
|
let components: LinkedHashSet<String> = components.into_iter().collect();
|
||||||
|
|
||||||
// Assign an index to each unique component id by inserting it into `component_ids`
|
|
||||||
component_ids.extend( components.clone() );
|
|
||||||
|
|
||||||
// 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`
|
||||||
types.insert_if_absent( components );
|
types.insert_if_absent( components );
|
||||||
|
@ -263,7 +259,7 @@ pub fn get_ecs( tilemap: &TiledTilemap ) -> Result<Vec<u8>, Box<dyn Error>> {
|
||||||
|
|
||||||
for component in ecs_type {
|
for component in ecs_type {
|
||||||
type_component_ids.push(
|
type_component_ids.push(
|
||||||
component_ids.iter().position( | value | component == value ).ok_or( "internal error: no component" )? as u8
|
*tilemap.ecs_component_ids.get( component ).ok_or( format!( "invalid file: undefined component symbol \"{}\"", component ) )?
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,12 +383,6 @@ pub fn get_ecs( tilemap: &TiledTilemap ) -> Result<Vec<u8>, Box<dyn Error>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output IDs to terminal
|
|
||||||
let component_ids: Vec<String> = component_ids.into_iter().collect();
|
|
||||||
for i in 0..component_ids.len() {
|
|
||||||
print_info( &format!( "Component ID {}: {}", i, component_ids[ i ] ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Output type structures to terminal
|
// Output type structures to terminal
|
||||||
let mut visited_types: LinkedHashSet<LinkedHashSet<String>> = LinkedHashSet::new();
|
let mut visited_types: LinkedHashSet<LinkedHashSet<String>> = LinkedHashSet::new();
|
||||||
for entity in &tilemap.ecs {
|
for entity in &tilemap.ecs {
|
||||||
|
|
Loading…
Reference in New Issue