From c7c57c1527dab73248a63006bb158532bb336d8c Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 26 Jul 2024 18:21:56 -0700 Subject: [PATCH] naive multithread --- src/main.rs | 56 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 45 insertions(+), 11 deletions(-) diff --git a/src/main.rs b/src/main.rs index 90aad4c..1402ed6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,7 +13,7 @@ struct Cli { #[derive(Subcommand)] enum Commands { - ConvertToSNF(ConvertToSNFSubcommand), + RobloxToSNF(RobloxToSNFSubcommand), DownloadTextures(DownloadTexturesSubcommand), ExtractTextures(ExtractTexturesSubcommand), ConvertTextures(ConvertTexturesSubcommand), @@ -24,11 +24,11 @@ enum Commands { } #[derive(Args)] -struct ConvertToSNFSubcommand { - #[arg(long,required=true)] - input_files:Vec, +struct RobloxToSNFSubcommand { #[arg(long)] output_folder:PathBuf, + #[arg(required=true)] + input_files:Vec, } #[derive(Args)] struct DownloadTexturesSubcommand { @@ -67,7 +67,7 @@ struct WriteAttributesSubcommand { fn main() -> AResult<()> { let cli = Cli::parse(); match cli.command { - Commands::ConvertToSNF(subcommand)=>convert_to_snf(subcommand.input_files,subcommand.output_folder), + Commands::RobloxToSNF(subcommand)=>convert_to_snf(subcommand.input_files,subcommand.output_folder), Commands::DownloadTextures(subcommand)=>download_textures(subcommand.roblox_files), Commands::ExtractTextures(subcommand)=>extract_textures(vec![subcommand.bsp_file],subcommand.vpk_dir_files), Commands::VPKContents(subcommand)=>vpk_contents(subcommand.input_file), @@ -641,10 +641,30 @@ fn bsp_contents(path:PathBuf)->AResult<()>{ Ok(()) } +#[derive(Debug)] +enum ConvertError{ + IO(std::io::Error), + SNFMap(strafesnet_snf::map::Error), + RbxLoader(strafesnet_rbx_loader::ReadError), +} +impl std::fmt::Display for ConvertError{ + fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{ + write!(f,"{self:?}") + } +} +impl std::error::Error for ConvertError{} + fn convert_to_snf(pathlist:Vec,output_folder:PathBuf)->AResult<()>{ + let start = std::time::Instant::now(); + let mut threads:Vec>>=Vec::new(); for path in pathlist{ - let dom=strafesnet_rbx_loader::read(std::fs::File::open(path.as_path())?)?; - let mut loader=strafesnet_deferred_loader::roblox_legacy(); + let output_folder=output_folder.clone(); + threads.push(std::thread::spawn(move ||{ + let dom=strafesnet_rbx_loader::read( + std::fs::File::open(path.as_path()) + .map_err(ConvertError::IO)? + ).map_err(ConvertError::RbxLoader)?; + let mut loader=strafesnet_deferred_loader::roblox_legacy(); let (texture_loader,mesh_loader)=loader.get_inner_mut(); @@ -654,7 +674,7 @@ fn convert_to_snf(pathlist:Vec,output_folder:PathBuf)->AResu |name|mesh_loader.acquire_mesh_id(name), ); - let meshpart_meshes=mesh_loader.load_meshes()?; + let meshpart_meshes=mesh_loader.load_meshes().map_err(ConvertError::IO)?; let map_step2=map_step1.add_meshpart_meshes_and_calculate_attributes( meshpart_meshes.into_iter().map(|(mesh_id,loader_model)| @@ -662,7 +682,7 @@ fn convert_to_snf(pathlist:Vec,output_folder:PathBuf)->AResu ) ); - let (textures,render_configs)=loader.into_render_configs()?.consume(); + let (textures,render_configs)=loader.into_render_configs().map_err(ConvertError::IO)?.consume(); let map=map_step2.add_render_configs_and_textures( render_configs.into_iter(), @@ -676,9 +696,23 @@ fn convert_to_snf(pathlist:Vec,output_folder:PathBuf)->AResu let mut dest=output_folder.clone(); dest.push(path.file_stem().unwrap()); dest.set_extension("snfm"); - let file=std::fs::File::create(dest)?; + let file=std::fs::File::create(dest).map_err(ConvertError::IO)?; - strafesnet_snf::map::write_map(file,map)?; + strafesnet_snf::map::write_map(file,map).map_err(ConvertError::SNFMap)?; + Ok(()) + })); } + + let mut i=0; + let n_threads=threads.len(); + for thread in threads{ + i+=1; + if let Err(e)=thread.join(){ + println!("thread error: {:?}",e); + }else{ + println!("{}/{}",i,n_threads); + } + } + println!("{:?}", start.elapsed()); Ok(()) }