rusteal_codegen/cpp_gen/
mod.rs1pub mod fill_table;
2pub mod func_ids;
3pub mod wrapper;
4
5use std::collections::{BTreeMap, HashSet};
6use std::path::Path;
7
8use crate::context::CodegenContext;
9use crate::write_if_changed;
10
11pub fn generate(ctx: &CodegenContext, out_dir: &Path) {
12 std::fs::create_dir_all(out_dir).expect("Failed to create C++ output directory");
13
14 let mut by_class: BTreeMap<(String, String), Vec<&crate::context::FuncEntry>> = BTreeMap::new();
15
16 for entry in &ctx.func_table {
17 by_class
18 .entry((entry.module_name.clone(), entry.class_name.clone()))
19 .or_default()
20 .push(entry);
21 }
22
23 let mut written: HashSet<String> = HashSet::new();
24
25 for ((module, class), entries) in &by_class {
26 let code = wrapper::generate_wrapper_file(entries, ctx);
27 let filename = format!("RustealFunc_{module}_{class}.cpp");
28
29 write_if_changed(&out_dir.join(&filename), &code)
30 .unwrap_or_else(|e| panic!("Failed to write {filename}: {e}"));
31
32 written.insert(filename);
33 }
34
35 remove_stale_wrappers(out_dir, &written);
36
37 let ids_code = func_ids::generate_cpp_func_ids(&ctx.func_table);
38
39 write_if_changed(&out_dir.join("RustealFuncIds.h"), &ids_code)
40 .expect("Failed to write RustealFuncIds.h");
41
42 let fill_code = fill_table::generate_fill_table(&ctx.cpp_prefix, &ctx.func_table, &by_class);
43
44 write_if_changed(&out_dir.join("RustealFillFuncTable.cpp"), &fill_code)
45 .expect("Failed to write RustealFillFuncTable.cpp");
46}
47
48fn remove_stale_wrappers(out_dir: &Path, written: &HashSet<String>) {
49 let Ok(entries) = std::fs::read_dir(out_dir) else {
50 return;
51 };
52
53 for entry in entries.flatten() {
54 let name = entry.file_name();
55 let name = name.to_string_lossy();
56
57 if name.starts_with("RustealFunc_")
58 && name.ends_with(".cpp")
59 && !written.contains(name.as_ref())
60 {
61 std::fs::remove_file(entry.path())
62 .unwrap_or_else(|e| panic!("Failed to remove stale {name}: {e}"));
63 }
64 }
65}