getter for fnames, partial sdk generation, canon arg names

This commit is contained in:
Janis 2023-05-12 12:13:20 +02:00
parent 406146e772
commit f88c890210
4 changed files with 142 additions and 8 deletions

View file

@ -1,3 +1,12 @@
use std::{
cell::RefCell,
collections::{hash_map::Entry, HashMap},
sync::Mutex,
};
use anyhow::Context;
use once_cell::sync::{Lazy, OnceCell};
use crate::global_tables::names::GNAMES; use crate::global_tables::names::GNAMES;
#[repr(C)] #[repr(C)]
@ -8,6 +17,45 @@ pub struct FName {
} }
impl FName { impl FName {
pub fn new(name: &'static str) -> anyhow::Result<Self> {
static CACHE: Lazy<Mutex<RefCell<HashMap<&'static str, u32>>>> =
Lazy::new(|| Mutex::new(RefCell::new(HashMap::new())));
let cache = CACHE.lock().unwrap();
let name = match cache.borrow_mut().entry(name) {
Entry::Occupied(entry) => Self {
comparison_index: *entry.get(),
number: 0,
},
Entry::Vacant(entry) => {
let name = GNAMES
.read()
.unwrap()
.as_names()
.unwrap()
.iter()
.position(|entry| entry.as_str() == name)
.context("could not find fname.")? as u32;
entry.insert(name);
Self {
comparison_index: name,
number: 0,
}
}
};
Ok(name)
}
pub fn none() -> FName {
static NAME: Lazy<FName> = Lazy::new(|| FName::new("None").expect("FName \"None\"."));
*NAME
}
pub fn get_name(&self) -> anyhow::Result<String> { pub fn get_name(&self) -> anyhow::Result<String> {
GNAMES GNAMES
.read() .read()

View file

@ -1,7 +1,5 @@
use std::marker::PhantomData; use std::marker::PhantomData;
use crate::{fname::FName, tarray::FString};
#[repr(C)] #[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct TEnumAsByte<T> { pub struct TEnumAsByte<T> {
@ -10,6 +8,13 @@ pub struct TEnumAsByte<T> {
} }
impl<T> TEnumAsByte<T> { impl<T> TEnumAsByte<T> {
pub fn new(value: T) -> Self {
Self {
inner: unsafe { *core::mem::transmute::<_, *const u8>(&value as *const T) },
phantom: PhantomData,
}
}
pub fn as_enum(&self) -> &T { pub fn as_enum(&self) -> &T {
unsafe { &*core::mem::transmute::<_, *const T>(&self.inner as *const u8) } unsafe { &*core::mem::transmute::<_, *const T>(&self.inner as *const u8) }
} }

View file

@ -423,7 +423,11 @@ pub mod sdk {
let param = MethodParameter { let param = MethodParameter {
name: format!( name: format!(
"Arg{}", "Arg{}",
prop.get_name().context("failed to get parameter name")? canonicalize_name(
&prop
.get_name()
.context("failed to get parameter name")?
)
), ),
ty, ty,
}; };
@ -735,7 +739,7 @@ pub mod sdk {
fn canonicalize_name(name: &str) -> Cow<str> { fn canonicalize_name(name: &str) -> Cow<str> {
let valid = split_at_illegal_char(name).into_valid(); let valid = split_at_illegal_char(name).into_valid();
if keywords().contains(valid.as_ref()) { if keywords().contains(valid.as_ref()) || valid.starts_with(|c: char| !c.is_alphabetic()) {
Cow::Owned(format!("_{}", &valid)) Cow::Owned(format!("_{}", &valid))
} else { } else {
valid valid

View file

@ -1,4 +1,7 @@
use std::io::{BufWriter, Write}; use std::{
collections::HashSet,
io::{BufWriter, Write},
};
use anyhow::Context; use anyhow::Context;
use itertools::Itertools; use itertools::Itertools;
@ -8,7 +11,10 @@ use crate::{
canonicalize_name, Class, ClassField, ClassMethod, Enum, PrimitiveType, ProcessedPackage, canonicalize_name, Class, ClassField, ClassMethod, Enum, PrimitiveType, ProcessedPackage,
Sdk, Type, Types, Sdk, Type, Types,
}, },
v2_types::traits::{AsUObject, UObjectNonConst, UStructNonConst}, v2_types::{
traits::{AsUObject, UObjectNonConst, UStructNonConst},
UObject,
},
}; };
pub trait RustType { pub trait RustType {
@ -201,7 +207,7 @@ impl AsPtr for {name} {{
w, w,
r#" r#"
impl {name} {{ impl {name} {{
fn zeroed() -> Self {{ pub fn zeroed() -> Self {{
unsafe {{ core::mem::MaybeUninit::<Self>::zeroed().assume_init() }} unsafe {{ core::mem::MaybeUninit::<Self>::zeroed().assume_init() }}
}} }}
}} }}
@ -464,6 +470,77 @@ impl {name} {{
Ok(()) Ok(())
} }
pub fn generate_partial_sdk_to_tmp(
sdk: &Sdk,
packages: HashSet<&'static str>,
) -> anyhow::Result<()> {
std::fs::create_dir_all("z:/tmp/ark_sdk/")?;
let file = std::fs::File::create("z:/tmp/ark_sdk/mod.rs")?;
let mut writer = BufWriter::new(file);
writeln!(writer, "use core::cell::UnsafeCell;")?;
writeln!(writer, "use core::ptr::NonNull;")?;
writeln!(writer, "use super::AsPtr;")?;
writeln!(writer, "use super::process_event;")?;
writeln!(writer, "use super::StaticClass;")?;
let packages = sdk.packages.iter().filter(|(_, pkg)| {
let pkg_name = canonicalize_name(
&pkg.package
.get_full_name()
.expect("could not get package name"),
)
.to_string();
packages.contains(pkg_name.as_str())
});
let mut processed_packages = HashSet::new();
for (obj, pkg) in packages {
if processed_packages.insert(*obj) {
generate_package(sdk, &mut writer, &mut processed_packages, pkg)?;
}
}
todo!()
}
fn generate_package<W: Write>(
sdk: &Sdk,
writer: &mut W,
processed_packages: &mut HashSet<UObject>,
pkg: &ProcessedPackage,
) -> anyhow::Result<()> {
let pkg_name = canonicalize_name(
&pkg.package
.get_full_name()
.context("could not get package name")?,
)
.to_string();
writeln!(writer, "pub mod {pkg_name};")?;
let file = std::fs::File::create(format!("z:/tmp/ark_sdk/{pkg_name}.rs"))?;
let mut file = BufWriter::new(file);
generate_package_rust_module(pkg, sdk, &mut file)?;
for (obj, _) in pkg.package_dependencies.iter() {
if processed_packages.insert(*obj) {
generate_package(
sdk,
writer,
processed_packages,
sdk.packages
.get(obj)
.context("could not find dependency package")?,
)?;
}
}
Ok(())
}
pub fn generate_sdk_to_tmp(sdk: &Sdk) -> anyhow::Result<()> { pub fn generate_sdk_to_tmp(sdk: &Sdk) -> anyhow::Result<()> {
std::fs::create_dir_all("z:/tmp/ark_sdk/")?; std::fs::create_dir_all("z:/tmp/ark_sdk/")?;
let file = std::fs::File::create("z:/tmp/ark_sdk/mod.rs")?; let file = std::fs::File::create("z:/tmp/ark_sdk/mod.rs")?;
@ -506,7 +583,7 @@ pub fn generate_package_rust_module<W: Write>(
for (pkg, _) in &pkg.package_dependencies { for (pkg, _) in &pkg.package_dependencies {
writeln!( writeln!(
w, w,
"use {}::*;", "pub use {}::*;",
canonicalize_name(&pkg.get_full_name().context("could not get package name")?) canonicalize_name(&pkg.get_full_name().context("could not get package name")?)
)?; )?;
} }