sdk-builder: rayon friendly refactor, much faster generation with rayon
This commit is contained in:
parent
0a0e72f30d
commit
3ffbcb0849
|
@ -249,6 +249,7 @@ pub mod rust {
|
|||
use itertools::Itertools;
|
||||
use proc_macro2::{Ident, TokenStream};
|
||||
use quote::{format_ident, quote};
|
||||
use rayon::prelude::{IntoParallelIterator, ParallelIterator};
|
||||
use unreal_sdk::sdk::repr::{
|
||||
Class, ClassField, ClassMethod, Enum, ObjectRef, PackageRef, PrimitiveType,
|
||||
ProcessedPackage, Sdk, StructKind, Type, UnrealType,
|
||||
|
@ -365,7 +366,7 @@ pub mod rust {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn build(self, args: &super::Build) -> anyhow::Result<BTreeMap<String, TokenStream>> {
|
||||
pub fn build(self, args: &super::Build) -> anyhow::Result<BTreeMap<String, String>> {
|
||||
let pkgs = if let Some(packages) = &args.packages {
|
||||
let deps = self.dependencies_for_package_names(packages);
|
||||
log::debug!("all dependencies: {deps:?}");
|
||||
|
@ -378,18 +379,73 @@ pub mod rust {
|
|||
};
|
||||
|
||||
let packages = pkgs
|
||||
.into_iter()
|
||||
.into_par_iter()
|
||||
.map(|pkg| {
|
||||
let name = canonicalize_name(&pkg.name).to_string();
|
||||
let tokens = self.generate_package(pkg, args.feature_gate)?;
|
||||
let (ident, tokens) = self.generate_package(pkg, args.feature_gate)?;
|
||||
|
||||
anyhow::Ok((name, tokens))
|
||||
let tokens = if args.single_file {
|
||||
tokens
|
||||
} else {
|
||||
quote! {
|
||||
pub mod #ident {
|
||||
#tokens
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
anyhow::Ok((ident.to_string(), tokens.to_string()))
|
||||
})
|
||||
.collect::<Result<BTreeMap<_, _>, _>>()?;
|
||||
|
||||
Ok(packages)
|
||||
}
|
||||
|
||||
pub fn build_in_dir<P: AsRef<Path>>(
|
||||
self,
|
||||
path: P,
|
||||
args: &super::Build,
|
||||
) -> anyhow::Result<()> {
|
||||
let packages = self.build(args)?;
|
||||
|
||||
let path = path.as_ref();
|
||||
std::fs::create_dir_all(&path)?;
|
||||
|
||||
let mut mod_rs = TokenStream::new();
|
||||
|
||||
for (name, tokens) in packages {
|
||||
let name = format_ident!("{name}");
|
||||
if args.single_file {
|
||||
mod_rs.extend(quote! {
|
||||
pub mod #name {
|
||||
#tokens
|
||||
}
|
||||
});
|
||||
} else {
|
||||
let path = path.join(format!("{name}.rs"));
|
||||
|
||||
log::info!("parsing {name}..");
|
||||
let file =
|
||||
syn::parse_file(&tokens).context("syn failed to parse generated code")?;
|
||||
|
||||
log::info!("pretty printing {name}..");
|
||||
let contents = prettyplease::unparse(&file);
|
||||
log::info!("writing to {}..", path.display());
|
||||
std::fs::write(path, contents)?;
|
||||
|
||||
mod_rs.extend(quote! {
|
||||
pub mod #name;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let contents = prettyplease::unparse(
|
||||
&syn::parse_file(&mod_rs.to_string()).context("syn failed to parse root module")?,
|
||||
);
|
||||
std::fs::write(path.join("mod.rs"), contents)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_package_by_name(&self, name: &str) -> Option<PackageRef> {
|
||||
self.sdk
|
||||
.packages
|
||||
|
@ -427,52 +483,6 @@ pub mod rust {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn build_in_dir<P: AsRef<Path>>(
|
||||
self,
|
||||
path: P,
|
||||
args: &super::Build,
|
||||
) -> anyhow::Result<()> {
|
||||
let packages = self.build(args)?;
|
||||
|
||||
let path = path.as_ref();
|
||||
std::fs::create_dir_all(&path)?;
|
||||
|
||||
let mut mod_rs = TokenStream::new();
|
||||
|
||||
for (name, tokens) in packages {
|
||||
let name = format_ident!("{name}");
|
||||
if args.single_file {
|
||||
mod_rs.extend(quote! {
|
||||
pub mod #name {
|
||||
#tokens
|
||||
}
|
||||
});
|
||||
} else {
|
||||
let path = path.join(format!("{name}.rs"));
|
||||
|
||||
log::info!("parsing {name}..");
|
||||
let file = syn::parse_file(&tokens.to_string())
|
||||
.context("syn failed to parse generated code")?;
|
||||
|
||||
log::info!("pretty printing {name}..");
|
||||
let contents = prettyplease::unparse(&file);
|
||||
log::info!("writing to {}..", path.display());
|
||||
std::fs::write(path, contents)?;
|
||||
|
||||
mod_rs.extend(quote! {
|
||||
pub mod #name;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let contents = prettyplease::unparse(
|
||||
&syn::parse_file(&mod_rs.to_string()).context("syn failed to parse root module")?,
|
||||
);
|
||||
std::fs::write(path.join("mod.rs"), contents)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn generate_enum(&self, enum0: &Enum) -> anyhow::Result<TokenStream> {
|
||||
let name = self
|
||||
.get_type_ident(&enum0.obj_ref)
|
||||
|
@ -971,7 +981,7 @@ pub mod rust {
|
|||
&self,
|
||||
pkg: &ProcessedPackage,
|
||||
feature_gate: bool,
|
||||
) -> anyhow::Result<TokenStream> {
|
||||
) -> anyhow::Result<(Ident, TokenStream)> {
|
||||
let pkg_name = canonicalize_ident(&pkg.name);
|
||||
log::info!(
|
||||
"generating package \"{pkg_name}\" with {} types..",
|
||||
|
@ -1009,14 +1019,15 @@ pub mod rust {
|
|||
None
|
||||
};
|
||||
|
||||
Ok(quote! {
|
||||
pub mod #pkg_name {
|
||||
Ok((
|
||||
pkg_name,
|
||||
quote! {
|
||||
#feature_gate
|
||||
#![allow(dead_code, unused_imports, non_snake_case, non_camel_case_types)]
|
||||
|
||||
#pkg_tokens
|
||||
}
|
||||
})
|
||||
},
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue