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;
#[repr(C)]
@ -8,6 +17,45 @@ pub struct 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> {
GNAMES
.read()

View file

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

View file

@ -423,7 +423,11 @@ pub mod sdk {
let param = MethodParameter {
name: format!(
"Arg{}",
prop.get_name().context("failed to get parameter name")?
canonicalize_name(
&prop
.get_name()
.context("failed to get parameter name")?
)
),
ty,
};
@ -735,7 +739,7 @@ pub mod sdk {
fn canonicalize_name(name: &str) -> Cow<str> {
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))
} else {
valid

View file

@ -1,4 +1,7 @@
use std::io::{BufWriter, Write};
use std::{
collections::HashSet,
io::{BufWriter, Write},
};
use anyhow::Context;
use itertools::Itertools;
@ -8,7 +11,10 @@ use crate::{
canonicalize_name, Class, ClassField, ClassMethod, Enum, PrimitiveType, ProcessedPackage,
Sdk, Type, Types,
},
v2_types::traits::{AsUObject, UObjectNonConst, UStructNonConst},
v2_types::{
traits::{AsUObject, UObjectNonConst, UStructNonConst},
UObject,
},
};
pub trait RustType {
@ -201,7 +207,7 @@ impl AsPtr for {name} {{
w,
r#"
impl {name} {{
fn zeroed() -> Self {{
pub fn zeroed() -> Self {{
unsafe {{ core::mem::MaybeUninit::<Self>::zeroed().assume_init() }}
}}
}}
@ -464,6 +470,77 @@ impl {name} {{
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<()> {
std::fs::create_dir_all("z:/tmp/ark_sdk/")?;
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 {
writeln!(
w,
"use {}::*;",
"pub use {}::*;",
canonicalize_name(&pkg.get_full_name().context("could not get package name")?)
)?;
}