From fc90a986e536f40f34c40321f99845de5d5a704c Mon Sep 17 00:00:00 2001 From: Quaternions <krakow20@gmail.com> Date: Mon, 3 Feb 2025 14:05:39 -0800 Subject: [PATCH] fin --- src/source.rs | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/src/source.rs b/src/source.rs index 95c11e7..60a3464 100644 --- a/src/source.rs +++ b/src/source.rs @@ -21,13 +21,15 @@ pub struct SourceToSNFSubcommand { output_folder:PathBuf, #[arg(required=true)] input_files:Vec<PathBuf>, + #[arg(long)] + vpk_dir_files:Vec<PathBuf>, } #[derive(Args)] pub struct ExtractTexturesSubcommand{ #[arg(required=true)] bsp_files:Vec<PathBuf>, #[arg(long)] - vpk_dir_file:Vec<PathBuf>, + vpk_dir_files:Vec<PathBuf>, } #[derive(Args)] pub struct VPKContentsSubcommand { @@ -43,8 +45,8 @@ pub struct BSPContentsSubcommand { impl Commands{ pub async fn run(self)->AResult<()>{ match self{ - Commands::SourceToSNF(subcommand)=>source_to_snf(subcommand.input_files,subcommand.output_folder).await, - Commands::ExtractTextures(subcommand)=>extract_textures(subcommand.bsp_files,subcommand.vpk_dir_file).await, + Commands::SourceToSNF(subcommand)=>source_to_snf(subcommand.input_files,subcommand.output_folder,subcommand.vpk_dir_files).await, + Commands::ExtractTextures(subcommand)=>extract_textures(subcommand.bsp_files,subcommand.vpk_dir_files).await, Commands::VPKContents(subcommand)=>vpk_contents(subcommand.input_file), Commands::BSPContents(subcommand)=>bsp_contents(subcommand.input_file), } @@ -280,6 +282,15 @@ async fn convert_texture(texture:Vec<u8>,write_file_name:impl AsRef<Path>)->Resu Ok(()) } +async fn read_vpks(vpk_paths:Vec<PathBuf>,thread_limit:usize)->Vec<vpk::VPK>{ + futures::stream::iter(vpk_paths).map(|vpk_path|async{ + // idk why it doesn't want to pass out the errors but this is fatal anyways + tokio::task::spawn_blocking(move||vpk::VPK::read(&vpk_path)).await.unwrap().unwrap() + }) + .buffer_unordered(thread_limit) + .collect().await +} + async fn extract_textures(paths:Vec<PathBuf>,vpk_paths:Vec<PathBuf>)->AResult<()>{ tokio::try_join!( tokio::fs::create_dir_all("extracted_textures"), @@ -289,15 +300,10 @@ async fn extract_textures(paths:Vec<PathBuf>,vpk_paths:Vec<PathBuf>)->AResult<() let thread_limit=std::thread::available_parallelism()?.get(); // load vpk list - let vpk_list=futures::stream::iter(vpk_paths).map(|vpk_path|async{ - // idk why it doesn't want to pass out the errors but this is fatal anyways - tokio::task::spawn_blocking(move||vpk::VPK::read(&vpk_path)).await.unwrap().unwrap() - }) - .buffer_unordered(thread_limit) - .collect::<Vec<vpk::VPK>>().await; + let vpk_list=read_vpks(vpk_paths,thread_limit).await; // leak vpk_list for static lifetime? - let vpk_list=vpk_list.leak(); + let vpk_list:&[vpk::VPK]=vpk_list.leak(); let (send_texture,mut recv_texture)=tokio::sync::mpsc::channel(thread_limit); let mut it=paths.into_iter(); @@ -378,10 +384,17 @@ async fn convert_to_snf(path:&Path,vpk_list:&[vpk::VPK],output_folder:PathBuf)-> Ok(()) } -async fn source_to_snf(paths:Vec<std::path::PathBuf>,output_folder:PathBuf)->AResult<()>{ +async fn source_to_snf(paths:Vec<std::path::PathBuf>,output_folder:PathBuf,vpk_paths:Vec<PathBuf>)->AResult<()>{ let start=std::time::Instant::now(); let thread_limit=std::thread::available_parallelism()?.get(); + + // load vpk list + let vpk_list=read_vpks(vpk_paths,thread_limit).await; + + // leak vpk_list for static lifetime? + let vpk_list:&[vpk::VPK]=vpk_list.leak(); + let mut it=paths.into_iter(); static SEM:tokio::sync::Semaphore=tokio::sync::Semaphore::const_new(0); SEM.add_permits(thread_limit); @@ -389,7 +402,7 @@ async fn source_to_snf(paths:Vec<std::path::PathBuf>,output_folder:PathBuf)->ARe while let (Ok(permit),Some(path))=(SEM.acquire().await,it.next()){ let output_folder=output_folder.clone(); tokio::spawn(async move{ - let result=convert_to_snf(path.as_path(),output_folder).await; + let result=convert_to_snf(path.as_path(),vpk_list,output_folder).await; drop(permit); match result{ Ok(())=>(),