Correctly handle working directory of input file

stinkhead7ds
Ashley N. 2023-09-19 17:32:12 -04:00
parent 0dc7e95c21
commit 6fe992cb33
1 changed files with 16 additions and 5 deletions

View File

@ -1,4 +1,4 @@
use std::{error::Error, fs::read_to_string};
use std::{error::Error, fs::read_to_string, path::Path, borrow::Cow};
use image::{DynamicImage, GenericImageView};
use roxmltree::Node;
use crate::reskit::utility::print_warning;
@ -102,10 +102,11 @@ fn get_layer( layer: Node, map_width: usize, map_height: usize ) -> Result<Optio
}
}
fn get_tiles( tileset: Node ) -> Result<TiledTileset, Box<dyn Error>> {
fn get_tiles( tileset: Node, working_directory: &str ) -> Result<TiledTileset, Box<dyn Error>> {
// Get the image for the tileset
let image = tileset.descendants().find( | node | node.tag_name() == "image".into() ).ok_or( "invalid file: no image object" )?;
let image = image::open( image.attribute( "source" ).ok_or( "invalid file: no source attribute on image" )? )?;
let image_path = format!( "{}/{}", working_directory, image.attribute( "source" ).ok_or( "invalid file: no source attribute on image" )? );
let image = image::open( image_path )?;
// Image must be a multiple of 8 (--system md)
if image.width() % 8 != 0 { return Err( "invalid file: tileset width not multiple of 8" )? }
@ -141,6 +142,16 @@ fn get_tiles( tileset: Node ) -> Result<TiledTileset, Box<dyn Error>> {
pub fn get_tiled_tilemap( path: &str ) -> Result<TiledTilemap, Box<dyn Error>> {
let file = read_to_string( path )?;
let document = roxmltree::Document::parse( &file )?;
let working_directory = {
let result = Path::new( path ).parent().unwrap_or( Path::new( "." ) ).to_string_lossy();
if result == "" {
Cow::from( "." )
} else {
result
}
};
println!( "working directory is {}/", working_directory );
let map = document.descendants().find( | node | node.tag_name() == "map".into() );
if let Some( map ) = map {
@ -181,7 +192,7 @@ pub fn get_tiled_tilemap( path: &str ) -> Result<TiledTilemap, Box<dyn Error>> {
// Build tileset (current version assumes one tileset per level)
let tileset = map.descendants().find( | node | node.tag_name() == "tileset".into() ).ok_or( "invalid file: no tileset" )?;
let tileset_source_path = tileset.attribute( "source" ).ok_or( "invalid file: no tileset source" )?;
let tileset_file = read_to_string( tileset_source_path )?;
let tileset_file = read_to_string( format!( "{}/{}", working_directory, tileset_source_path ) )?;
let tileset_document = roxmltree::Document::parse( &tileset_file )?;
let tileset = tileset_document.descendants().find( | node | node.tag_name() == "tileset".into() ).ok_or( "invalid file: no tileset origin object" )?;
@ -195,7 +206,7 @@ pub fn get_tiled_tilemap( path: &str ) -> Result<TiledTilemap, Box<dyn Error>> {
return Err( "invalid file: referenced tilemap doesn't have same per-tile width and height of parent tilemap" )?
}
let tileset = get_tiles( tileset )?;
let tileset = get_tiles( tileset, &working_directory )?;
// Get the layers
let layers: Vec<Layer> = map.descendants()