From 6e80f21046e5840ab77c920a3d0fddcd7239a4e2 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Mon, 16 Sep 2024 18:01:45 -0700 Subject: [PATCH] refactor(vm): fix Reagent code gen Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- Cargo.lock | 70 +++++++----- rust-analyzer.json | 3 +- xtask/src/generate.rs | 18 ++-- xtask/src/generate/database.rs | 188 +++++++++++++++++++++++---------- xtask/src/generate/enums.rs | 6 +- xtask/src/stationpedia.rs | 6 +- 6 files changed, 199 insertions(+), 92 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a12273f..f4a64db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -119,7 +119,7 @@ checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.77", ] [[package]] @@ -130,7 +130,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.77", ] [[package]] @@ -260,7 +260,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.77", ] [[package]] @@ -354,7 +354,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.10.0", - "syn 2.0.64", + "syn 2.0.77", ] [[package]] @@ -365,7 +365,7 @@ checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" dependencies = [ "darling_core", "quote", - "syn 2.0.64", + "syn 2.0.77", ] [[package]] @@ -484,7 +484,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.77", ] [[package]] @@ -636,6 +636,7 @@ dependencies = [ "strum_macros", "thiserror", "time", + "tracing", "tsify", "wasm-bindgen", ] @@ -658,6 +659,7 @@ dependencies = [ "serde_with", "stationeers_data", "thiserror", + "tracing-wasm", "tsify", "wasm-bindgen", "wasm-bindgen-futures", @@ -1078,7 +1080,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.77", ] [[package]] @@ -1116,7 +1118,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.77", ] [[package]] @@ -1150,7 +1152,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" dependencies = [ "proc-macro2", - "syn 2.0.64", + "syn 2.0.77", ] [[package]] @@ -1161,18 +1163,18 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.82" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -1308,7 +1310,7 @@ checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.77", ] [[package]] @@ -1319,7 +1321,7 @@ checksum = "e578a843d40b4189a4d66bba51d7684f57da5bd7c304c64e14bd63efbef49509" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.77", ] [[package]] @@ -1360,7 +1362,7 @@ checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.77", ] [[package]] @@ -1390,7 +1392,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.77", ] [[package]] @@ -1446,6 +1448,7 @@ dependencies = [ name = "stationeers_data" version = "0.2.3" dependencies = [ + "const-crc32", "num-integer", "phf 0.11.2", "serde", @@ -1488,7 +1491,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.64", + "syn 2.0.77", ] [[package]] @@ -1504,9 +1507,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.64" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ad3dee41f36859875573074334c200d1add8e4a87bb37113ebd31d926b7b11f" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -1536,7 +1539,7 @@ checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.77", ] [[package]] @@ -1625,7 +1628,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.77", ] [[package]] @@ -1694,7 +1697,7 @@ checksum = "84fd902d4e0b9a4b27f2f440108dc034e1758628a9b702f8ec61ad66355422fa" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.77", ] [[package]] @@ -1722,7 +1725,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.77", ] [[package]] @@ -1756,6 +1759,17 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "tracing-wasm" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4575c663a174420fa2d78f4108ff68f65bf2fbb7dd89f33749b6e826b3626e07" +dependencies = [ + "tracing", + "tracing-subscriber", + "wasm-bindgen", +] + [[package]] name = "tree-sitter" version = "0.20.10" @@ -1820,7 +1834,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.64", + "syn 2.0.77", ] [[package]] @@ -1911,7 +1925,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.77", "wasm-bindgen-shared", ] @@ -1946,7 +1960,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.77", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2150,7 +2164,7 @@ dependencies = [ "serde_path_to_error", "serde_with", "stationeers_data", - "syn 2.0.64", + "syn 2.0.77", "textwrap", "thiserror", "tracing", diff --git a/rust-analyzer.json b/rust-analyzer.json index 50418a4..7fb0194 100644 --- a/rust-analyzer.json +++ b/rust-analyzer.json @@ -1,5 +1,6 @@ { "rust-analyzer.cargo.features": [ - "tsify" + "tsify", + "prefab_database" ] } diff --git a/xtask/src/generate.rs b/xtask/src/generate.rs index 4016318..4aa7049 100644 --- a/xtask/src/generate.rs +++ b/xtask/src/generate.rs @@ -1,4 +1,4 @@ -use color_eyre::eyre; +use color_eyre::eyre::{self, Context}; use quote::ToTokens; use std::collections::BTreeMap; @@ -98,16 +98,22 @@ fn format_rust(content: impl ToTokens) -> color_eyre::Result { Ok(prettyplease::unparse(&content)) } -fn prepend_generated_comment_and_format(file_path: &std::path::Path, module: &str) -> color_eyre::Result<()> { +fn prepend_generated_comment_and_format( + file_path: &std::path::Path, + module: &str, +) -> color_eyre::Result<()> { use std::io::Write; let tmp_path = file_path.with_extension("rs.tmp"); { let mut tmp = std::fs::File::create(&tmp_path)?; - let src = syn::parse_file(&std::fs::read_to_string(file_path)?)?; + let src = syn::parse_file(&std::fs::read_to_string(file_path)?) + .with_context(|| format!("Error parsing file {}", file_path.display()))?; - let formated = format_rust(src)?; + let formatted = format_rust(src)?; - write!(&mut tmp, "\ + write!( + &mut tmp, + "\ // =================================================\n\ // !! <-----> DO NOT MODIFY <-----> !!\n\ //\n\ @@ -122,7 +128,7 @@ fn prepend_generated_comment_and_format(file_path: &std::path::Path, module: &st //\n\ // =================================================\n\ \n\ - {formated}\ + {formatted}\ " )?; } diff --git a/xtask/src/generate/database.rs b/xtask/src/generate/database.rs index 205fa7d..6d923af 100644 --- a/xtask/src/generate/database.rs +++ b/xtask/src/generate/database.rs @@ -19,11 +19,11 @@ use stationeers_data::templates::{ InstructionPartType, InternalAtmoInfo, ItemCircuitHolderTemplate, ItemConsumerTemplate, ItemInfo, ItemLogicMemoryTemplate, ItemLogicTemplate, ItemSlotsTemplate, ItemSuitCircuitHolderTemplate, ItemSuitLogicTemplate, ItemSuitTemplate, ItemTemplate, - LogicInfo, MemoryInfo, ObjectTemplate, PrefabInfo, Recipe, RecipeGasMix, RecipeRange, SlotInfo, - StructureCircuitHolderTemplate, StructureInfo, StructureLogicDeviceConsumerMemoryTemplate, - StructureLogicDeviceConsumerTemplate, StructureLogicDeviceMemoryTemplate, - StructureLogicDeviceTemplate, StructureLogicTemplate, StructureSlotsTemplate, - StructureTemplate, SuitInfo, ThermalInfo, + LogicInfo, MemoryInfo, ObjectTemplate, PrefabInfo, Reagent, Recipe, RecipeGasMix, RecipeRange, + SlotInfo, StructureCircuitHolderTemplate, StructureInfo, + StructureLogicDeviceConsumerMemoryTemplate, StructureLogicDeviceConsumerTemplate, + StructureLogicDeviceMemoryTemplate, StructureLogicDeviceTemplate, StructureLogicTemplate, + StructureSlotsTemplate, StructureTemplate, SuitInfo, ThermalInfo, }; #[allow(clippy::too_many_lines)] @@ -174,9 +174,21 @@ pub fn generate_database( } }) .collect(); + + let reagents = stationpedia + .reagents + .iter() + .map(|(name, reagent)| { + ( + name.clone(), + Into::::into(reagent).with_name(name.clone()), + ) + }) + .collect(); + let db: ObjectDatabase = ObjectDatabase { prefabs, - reagents: stationpedia.reagents.clone(), + reagents, enums: enums.clone(), prefabs_by_hash, structures, @@ -191,7 +203,7 @@ pub fn generate_database( .join("www") .join("src") .join("ts") - .join("virtualMachine"); + .join("database"); if !data_path.exists() { std::fs::create_dir(&data_path)?; } @@ -225,7 +237,15 @@ pub fn generate_database( let mut prefab_map_file = std::io::BufWriter::new(std::fs::File::create(&prefab_map_path)?); write_prefab_map(&mut prefab_map_file, &db.prefabs)?; - Ok(vec![prefab_map_path]) + let reagent_map_path = workspace + .join("stationeers_data") + .join("src") + .join("database") + .join("reagent_map.rs"); + let mut reagent_map_file = std::io::BufWriter::new(std::fs::File::create(&reagent_map_path)?); + write_reagent_map(&mut reagent_map_file, &db.reagents)?; + + Ok(vec![prefab_map_path, reagent_map_path]) } fn write_prefab_map( @@ -243,12 +263,17 @@ fn write_prefab_map( } )?; let enum_tag_regex = regex::Regex::new(r#"templateType:\s"\w+"\.into\(\),"#).unwrap(); + let numeric_string_literal_regex = regex::Regex::new(r#""(\d+)"\.into\(\)"#).unwrap(); let entries = prefabs .values() .map(|prefab| { let hash = prefab.prefab().prefab_hash; let uneval_src = &uneval::to_string(prefab)?; - let obj = syn::parse_str::(&enum_tag_regex.replace_all(&uneval_src, ""))?; + let fixed = enum_tag_regex.replace_all(&uneval_src, ""); + let fixed = numeric_string_literal_regex.replace_all(&fixed, |captures: ®ex::Captures| { + captures[1].to_string() + }); + let obj = syn::parse_str::(&fixed)?; let entry = quote! { map.insert(#hash, #obj.into()); }; @@ -270,9 +295,47 @@ fn write_prefab_map( Ok(()) } +fn write_reagent_map( + writer: &mut BufWriter, + reagents: &BTreeMap, +) -> color_eyre::Result<()> { + write!( + writer, + "{}", + quote! { + use crate::templates::Reagent; + } + )?; + let entries = reagents + .values() + .map(|reagent| { + let id = reagent.id; + let uneval_src = &uneval::to_string(reagent)?; + let obj = syn::parse_str::(&uneval_src)?; + let entry = quote! { + map.insert(#id, #obj); + }; + Ok(entry) + }) + .collect::, color_eyre::Report>>()?; + write!( + writer, + "{}", + quote! { + pub fn build_reagent_database() -> std::collections::BTreeMap { + #[allow(clippy::unreadable_literal)] + let mut map: std::collections::BTreeMap = std::collections::BTreeMap::new(); + #(#entries)* + map + } + }, + )?; + Ok(()) +} + #[allow(clippy::too_many_lines)] fn generate_templates(pedia: &Stationpedia) -> Vec { - println!("Generating templates ..."); + eprintln!("Generating templates ..."); let mut templates: Vec = Vec::new(); for page in &pedia.pages { let prefab = PrefabInfo { @@ -567,7 +630,6 @@ fn generate_templates(pedia: &Stationpedia) -> Vec { thermal_info: thermal.as_ref().map(Into::into), internal_atmo_info: internal_atmosphere.as_ref().map(Into::into), })); - // println!("Structure") } Page { item: None, @@ -591,7 +653,6 @@ fn generate_templates(pedia: &Stationpedia) -> Vec { internal_atmo_info: internal_atmosphere.as_ref().map(Into::into), slots: slot_inserts_to_info(slot_inserts), })); - // println!("Structure") } Page { item: None, @@ -624,7 +685,6 @@ fn generate_templates(pedia: &Stationpedia) -> Vec { logic, slots: slot_inserts_to_info(slot_inserts), })); - // println!("Structure") } Page { item: None, @@ -660,7 +720,6 @@ fn generate_templates(pedia: &Stationpedia) -> Vec { device: device.into(), }, )); - // println!("Structure") } Page { item: None, @@ -704,7 +763,6 @@ fn generate_templates(pedia: &Stationpedia) -> Vec { device: device.into(), }, )); - // println!("Structure") } Page { item: None, @@ -742,7 +800,6 @@ fn generate_templates(pedia: &Stationpedia) -> Vec { fabricator_info: device.fabricator.as_ref().map(Into::into), }, )); - // println!("Structure") } Page { item: None, @@ -778,7 +835,6 @@ fn generate_templates(pedia: &Stationpedia) -> Vec { memory: memory.into(), }, )); - // println!("Structure") } Page { item: None, @@ -816,7 +872,6 @@ fn generate_templates(pedia: &Stationpedia) -> Vec { memory: memory.into(), }, )); - // println!("Structure") } _ => panic!( "\ @@ -851,16 +906,32 @@ fn generate_templates(pedia: &Stationpedia) -> Vec { templates } -fn slot_inserts_to_info(slots: &[stationpedia::SlotInsert]) -> Vec { +fn slot_inserts_to_info(slots: &[stationpedia::SlotInsert]) -> BTreeMap { let mut tmp: Vec<_> = slots.into(); tmp.sort_by(|a, b| a.slot_index.cmp(&b.slot_index)); tmp.iter() - .map(|slot| SlotInfo { - name: slot.slot_name.clone(), - typ: slot - .slot_type - .parse() - .unwrap_or_else(|err| panic!("failed to parse slot class: {err}")), + .map(|slot| { + let typ = &slot.slot_type; + if typ == "Proxy" { + ( + slot.slot_index, + SlotInfo::Proxy { + name: slot.slot_name.clone(), + index: slot.slot_index, + }, + ) + } else { + ( + slot.slot_index, + SlotInfo::Direct { + name: slot.slot_name.clone(), + class: typ.parse().unwrap_or_else(|err| { + panic!("failed to parse slot class '{typ}': {err}") + }), + index: slot.slot_index, + }, + ) + } }) .collect() } @@ -877,7 +948,7 @@ fn mode_inserts_to_info(modes: &[stationpedia::ModeInsert]) -> BTreeMap, - pub reagents: BTreeMap, + pub reagents: BTreeMap, pub enums: enums::Enums, pub prefabs_by_hash: BTreeMap, pub structures: Vec, @@ -929,10 +1000,10 @@ impl From<&stationpedia::LogicInfo> for LogicInfo { .map(|(key, val)| { ( key.parse().unwrap_or_else(|err| { - panic!("failed to parse logic slot type: {err}") + panic!("failed to parse logic slot type '{key}': {err}") }), val.parse().unwrap_or_else(|err| { - panic!("failed to parse memory access: {err}") + panic!("failed to parse memory access '{val}': {err}") }), ) }) @@ -946,10 +1017,12 @@ impl From<&stationpedia::LogicInfo> for LogicInfo { .iter() .map(|(key, val)| { ( - key.parse() - .unwrap_or_else(|err| panic!("failed to parse logic type: {err}")), - val.parse() - .unwrap_or_else(|err| panic!("failed to parse memory access: {err}")), + key.parse().unwrap_or_else(|err| { + panic!("failed to parse logic type '{key}' : {err}") + }), + val.parse().unwrap_or_else(|err| { + panic!("failed to parse memory access '{val}': {err}") + }), ) }) .collect(), @@ -976,20 +1049,14 @@ impl From<&stationpedia::Item> for ItemInfo { .reagents .as_ref() .map(|map| map.iter().map(|(key, val)| (key.clone(), *val)).collect()), - slot_class: item - .slot_class - .parse() - .unwrap_or_else(|err| { - let slot_class = &item.slot_class; - panic!("failed to parse slot class `{slot_class}`: {err}"); - }), - sorting_class: item - .sorting_class - .parse() - .unwrap_or_else(|err| { - let sorting_class = &item.sorting_class; - panic!("failed to parse sorting class `{sorting_class}`: {err}"); - }), + slot_class: item.slot_class.parse().unwrap_or_else(|err| { + let slot_class = &item.slot_class; + panic!("failed to parse slot class `{slot_class}`: {err}"); + }), + sorting_class: item.sorting_class.parse().unwrap_or_else(|err| { + let sorting_class = &item.sorting_class; + panic!("failed to parse sorting class `{sorting_class}`: {err}"); + }), } } } @@ -1001,12 +1068,12 @@ impl From<&stationpedia::Device> for DeviceInfo { .connection_list .iter() .map(|(typ, role)| ConnectionInfo { - typ: typ - .parse() - .unwrap_or_else(|err| panic!("failed to parse connection type `{typ}`: {err}")), - role: role - .parse() - .unwrap_or_else(|err| panic!("failed to parse connection role `{role}`: {err}")), + typ: typ.parse().unwrap_or_else(|err| { + panic!("failed to parse connection type `{typ}`: {err}") + }), + role: role.parse().unwrap_or_else(|err| { + panic!("failed to parse connection role `{role}`: {err}") + }), }) .collect(), device_pins_length: value.devices_length, @@ -1123,6 +1190,19 @@ impl From<&stationpedia::ResourceConsumer> for ConsumerInfo { } } +impl From<&stationpedia::Reagent> for Reagent { + fn from(value: &stationpedia::Reagent) -> Self { + Reagent { + id: value.id, + name: String::new(), + hash: value.hash, + unit: value.unit.clone(), + is_organic: value.is_organic, + sources: value.sources.clone().unwrap_or_default(), + } + } +} + impl From<&stationpedia::Fabricator> for FabricatorInfo { fn from(value: &stationpedia::Fabricator) -> Self { FabricatorInfo { @@ -1133,7 +1213,7 @@ impl From<&stationpedia::Fabricator> for FabricatorInfo { recipes: value .recipes .iter() - .map(|(key, val)| (key.clone(), val.into())) + .map(|(prefab, val)| Into::::into(val).with_target(prefab)) .collect(), } } @@ -1142,6 +1222,8 @@ impl From<&stationpedia::Fabricator> for FabricatorInfo { impl From<&stationpedia::Recipe> for Recipe { fn from(value: &stationpedia::Recipe) -> Self { Recipe { + target_prefab: String::new(), + target_prefab_hash: 0, tier: value .tier_name .parse() diff --git a/xtask/src/generate/enums.rs b/xtask/src/generate/enums.rs index ba49b5a..3100457 100644 --- a/xtask/src/generate/enums.rs +++ b/xtask/src/generate/enums.rs @@ -15,7 +15,7 @@ pub fn generate( enums: &crate::enums::Enums, workspace: &std::path::Path, ) -> color_eyre::Result> { - println!("Writing Enum Listings ..."); + eprintln!("Writing Enum Listings ..."); let enums_path = workspace.join("stationeers_data").join("src").join("enums"); if !enums_path.exists() { std::fs::create_dir(&enums_path)?; @@ -51,7 +51,7 @@ pub fn generate( } write_enum_listing(&mut writer, enm)?; } - write_enum_aggragate_mod(&mut writer, &enums.basic_enums)?; + write_enum_aggregate_mod(&mut writer, &enums.basic_enums)?; let mut writer = std::io::BufWriter::new(std::fs::File::create(enums_path.join("prefabs.rs"))?); write_repr_enum_use_header(&mut writer)?; @@ -80,7 +80,7 @@ pub fn generate( } #[allow(clippy::type_complexity)] -fn write_enum_aggragate_mod( +fn write_enum_aggregate_mod( writer: &mut BufWriter, enums: &BTreeMap, ) -> color_eyre::Result<()> { diff --git a/xtask/src/stationpedia.rs b/xtask/src/stationpedia.rs index e20cc2c..5eb2012 100644 --- a/xtask/src/stationpedia.rs +++ b/xtask/src/stationpedia.rs @@ -30,10 +30,14 @@ impl Stationpedia { #[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)] #[serde(deny_unknown_fields)] pub struct Reagent { + #[serde(rename = "Id")] + pub id: u8, #[serde(rename = "Hash")] - pub hash: i64, + pub hash: i32, #[serde(rename = "Unit")] pub unit: String, + #[serde(rename = "IsOrganic")] + pub is_organic: bool, #[serde(rename = "Sources")] pub sources: Option>, }