tokio-ify source-to-snf
This commit is contained in:
parent
e7aac2c796
commit
387475d494
@ -27,7 +27,7 @@ async fn main()->AResult<()>{
|
|||||||
let cli=Cli::parse();
|
let cli=Cli::parse();
|
||||||
match cli.command{
|
match cli.command{
|
||||||
Commands::Roblox(commands)=>commands.run().await,
|
Commands::Roblox(commands)=>commands.run().await,
|
||||||
Commands::Source(commands)=>commands.run(),
|
Commands::Source(commands)=>commands.run().await,
|
||||||
Commands::ConvertTextures=>common::convert_textures(),
|
Commands::ConvertTextures=>common::convert_textures(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::path::PathBuf;
|
use std::path::{Path,PathBuf};
|
||||||
use clap::{Args,Subcommand};
|
use clap::{Args,Subcommand};
|
||||||
use anyhow::Result as AResult;
|
use anyhow::Result as AResult;
|
||||||
use strafesnet_deferred_loader::deferred_loader::LoadFailureMode;
|
use strafesnet_deferred_loader::deferred_loader::LoadFailureMode;
|
||||||
@ -37,10 +37,10 @@ pub struct BSPContentsSubcommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Commands{
|
impl Commands{
|
||||||
pub fn run(self)->AResult<()>{
|
pub async fn run(self)->AResult<()>{
|
||||||
match self{
|
match self{
|
||||||
Commands::SourceToSNF(subcommand)=>source_to_snf(subcommand.input_files,subcommand.output_folder),
|
|
||||||
Commands::ExtractTextures(subcommand)=>extract_textures(vec![subcommand.bsp_file],subcommand.vpk_dir_files),
|
Commands::ExtractTextures(subcommand)=>extract_textures(vec![subcommand.bsp_file],subcommand.vpk_dir_files),
|
||||||
|
Commands::SourceToSNF(subcommand)=>source_to_snf(subcommand.input_files,subcommand.output_folder).await,
|
||||||
Commands::VPKContents(subcommand)=>vpk_contents(subcommand.input_file),
|
Commands::VPKContents(subcommand)=>vpk_contents(subcommand.input_file),
|
||||||
Commands::BSPContents(subcommand)=>bsp_contents(subcommand.input_file),
|
Commands::BSPContents(subcommand)=>bsp_contents(subcommand.input_file),
|
||||||
}
|
}
|
||||||
@ -288,47 +288,45 @@ impl std::fmt::Display for ConvertError{
|
|||||||
}
|
}
|
||||||
impl std::error::Error for ConvertError{}
|
impl std::error::Error for ConvertError{}
|
||||||
|
|
||||||
type MapThread=std::thread::JoinHandle<Result<(),ConvertError>>;
|
async fn convert_to_snf(path:&Path,output_folder:PathBuf)->AResult<()>{
|
||||||
|
let entire_file=tokio::fs::read(path).await?;
|
||||||
|
|
||||||
fn source_to_snf(pathlist:Vec<std::path::PathBuf>,output_folder:PathBuf)->AResult<()>{
|
let bsp=strafesnet_bsp_loader::read(
|
||||||
let n_paths=pathlist.len();
|
std::io::Cursor::new(entire_file)
|
||||||
let start = std::time::Instant::now();
|
).map_err(ConvertError::BspRead)?;
|
||||||
let mut threads:std::collections::VecDeque<MapThread>=std::collections::VecDeque::new();
|
|
||||||
let mut i=0;
|
|
||||||
let mut join_thread=|thread:MapThread|{
|
|
||||||
i+=1;
|
|
||||||
if let Err(e)=thread.join(){
|
|
||||||
println!("thread error: {:?}",e);
|
|
||||||
}else{
|
|
||||||
println!("{}/{}",i,n_paths);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
for path in pathlist{
|
|
||||||
if 32<=threads.len(){
|
|
||||||
join_thread(threads.pop_front().unwrap());
|
|
||||||
}
|
|
||||||
let output_folder=output_folder.clone();
|
|
||||||
threads.push_back(std::thread::spawn(move ||{
|
|
||||||
let bsp=strafesnet_bsp_loader::read(
|
|
||||||
std::fs::File::open(path.as_path())
|
|
||||||
.map_err(ConvertError::IO)?
|
|
||||||
).map_err(ConvertError::BspRead)?;
|
|
||||||
|
|
||||||
let map=bsp.to_snf(LoadFailureMode::DefaultToNone).map_err(ConvertError::BspLoad)?;
|
let map=bsp.to_snf(LoadFailureMode::DefaultToNone).map_err(ConvertError::BspLoad)?;
|
||||||
|
|
||||||
let mut dest=output_folder.clone();
|
let mut dest=output_folder;
|
||||||
dest.push(path.file_stem().unwrap());
|
dest.push(path.file_stem().unwrap());
|
||||||
dest.set_extension("snfm");
|
dest.set_extension("snfm");
|
||||||
let file=std::fs::File::create(dest).map_err(ConvertError::IO)?;
|
let file=std::fs::File::create(dest).map_err(ConvertError::IO)?;
|
||||||
|
|
||||||
strafesnet_snf::map::write_map(file,map).map_err(ConvertError::SNFMap)?;
|
strafesnet_snf::map::write_map(file,map).map_err(ConvertError::SNFMap)?;
|
||||||
Ok(())
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
for thread in threads{
|
Ok(())
|
||||||
join_thread(thread);
|
}
|
||||||
}
|
async fn source_to_snf(paths:Vec<std::path::PathBuf>,output_folder:PathBuf)->AResult<()>{
|
||||||
println!("{:?}", start.elapsed());
|
let start=std::time::Instant::now();
|
||||||
|
|
||||||
|
let thread_limit=std::thread::available_parallelism()?.get();
|
||||||
|
let mut it=paths.into_iter();
|
||||||
|
static SEM:tokio::sync::Semaphore=tokio::sync::Semaphore::const_new(0);
|
||||||
|
SEM.add_permits(thread_limit);
|
||||||
|
|
||||||
|
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;
|
||||||
|
drop(permit);
|
||||||
|
match result{
|
||||||
|
Ok(())=>(),
|
||||||
|
Err(e)=>println!("Convert error: {e:?}"),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
_=SEM.acquire_many(thread_limit as u32).await.unwrap();
|
||||||
|
|
||||||
|
println!("elapsed={:?}", start.elapsed());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user