From dae6be9f4a81d9e15c82b876c6d35404b786f4c2 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Mon, 27 May 2024 04:11:40 -0700 Subject: [PATCH] refactor(vm): make wasmbindings build again, use tsify for types --- Cargo.lock | 9 +- ic10emu/Cargo.toml | 1 - ic10emu/src/errors.rs | 2 +- ic10emu/src/grammar.rs | 2 +- ic10emu/src/interpreter.rs | 5 +- ic10emu/src/network.rs | 2 +- ic10emu/src/vm/instructions/operands.rs | 20 +- ic10emu/src/vm/object.rs | 20 +- ic10emu/src/vm/object/generic/traits.rs | 10 +- ic10emu/src/vm/object/humans.rs | 37 +- ic10emu/src/vm/object/stationpedia.rs | 4 +- .../stationpedia/structs/circuit_holder.rs | 4 +- .../structs/integrated_circuit.rs | 6 +- ic10emu/src/vm/object/templates.rs | 4 +- ic10emu/src/vm/object/traits.rs | 4 +- ic10emu_wasm/Cargo.toml | 5 +- ic10emu_wasm/build.rs | 170 ++-- ic10emu_wasm/src/lib.rs | 814 +++++++++--------- ic10emu_wasm/src/utils.rs | 2 +- stationeers_data/src/templates.rs | 6 +- 20 files changed, 571 insertions(+), 556 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5045ce6..e3c5721 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -717,6 +717,7 @@ dependencies = [ "js-sys", "serde", "serde-wasm-bindgen 0.6.5", + "serde_derive", "serde_with", "strum", "thiserror", @@ -1423,9 +1424,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.202" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] @@ -1454,9 +1455,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.202" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", diff --git a/ic10emu/Cargo.toml b/ic10emu/Cargo.toml index 2b17415..d8e453c 100644 --- a/ic10emu/Cargo.toml +++ b/ic10emu/Cargo.toml @@ -47,4 +47,3 @@ serde_json = "1.0.117" [features] tsify = ["dep:tsify", "dep:wasm-bindgen", "stationeers_data/tsify"] -wasm-bindgen = ["dep:wasm-bindgen"] diff --git a/ic10emu/src/errors.rs b/ic10emu/src/errors.rs index 2eb2a4a..90e90a4 100644 --- a/ic10emu/src/errors.rs +++ b/ic10emu/src/errors.rs @@ -249,7 +249,7 @@ pub enum ICError { #[error("{0} is not a valid number of sleep seconds")] SleepDurationError(f64), #[error("{0} can not be added to {1} ")] - SleepAddtionError(time::Duration, time::OffsetDateTime), + SleepAddtionError(time::Duration, #[cfg_attr(feature = "tsify", tsify(type = "Date"))] time::OffsetDateTime), } impl ICError { diff --git a/ic10emu/src/grammar.rs b/ic10emu/src/grammar.rs index d2dbff7..c440dad 100644 --- a/ic10emu/src/grammar.rs +++ b/ic10emu/src/grammar.rs @@ -1,5 +1,5 @@ use crate::{ - errors::{ICError, ParseError}, + errors::{ParseError}, interpreter, tokens::{SplitConsecutiveIndicesExt, SplitConsecutiveWithIndices}, vm::instructions::{ diff --git a/ic10emu/src/interpreter.rs b/ic10emu/src/interpreter.rs index 008bf31..349d9ab 100644 --- a/ic10emu/src/interpreter.rs +++ b/ic10emu/src/interpreter.rs @@ -29,7 +29,10 @@ pub enum ICState { Start, Running, Yield, - Sleep(time::OffsetDateTime, f64), + Sleep( + #[cfg_attr(feature = "tsify", tsify(type = "Date"))] time::OffsetDateTime, + f64, + ), Error(LineError), HasCaughtFire, Ended, diff --git a/ic10emu/src/network.rs b/ic10emu/src/network.rs index 9f6bca9..f8643ec 100644 --- a/ic10emu/src/network.rs +++ b/ic10emu/src/network.rs @@ -11,7 +11,7 @@ use stationeers_data::{ enums::{script::LogicType, ConnectionRole, ConnectionType}, templates::ConnectionInfo, }; -use strum_macros::{AsRefStr, EnumIter}; + use thiserror::Error; #[cfg(feature = "tsify")] use tsify::Tsify; diff --git a/ic10emu/src/vm/instructions/operands.rs b/ic10emu/src/vm/instructions/operands.rs index c35797d..1f55441 100644 --- a/ic10emu/src/vm/instructions/operands.rs +++ b/ic10emu/src/vm/instructions/operands.rs @@ -3,7 +3,7 @@ use crate::interpreter; use crate::vm::{instructions::enums::InstructionOp, object::traits::IntegratedCircuit}; use serde_derive::{Deserialize, Serialize}; use stationeers_data::enums::script::{ - LogicBatchMethod as BatchMode, LogicReagentMode as ReagentMode, LogicSlotType, LogicType, + LogicBatchMethod, LogicReagentMode, LogicSlotType, LogicType, }; use strum::EnumProperty; #[cfg(feature = "tsify")] @@ -65,8 +65,8 @@ pub enum Operand { Type { logic_type: Option, slot_logic_type: Option, - batch_mode: Option, - reagent_mode: Option, + batch_mode: Option, + reagent_mode: Option, identifier: Identifier, }, Identifier(Identifier), @@ -285,7 +285,10 @@ impl InstOperand { } } - pub fn as_batch_mode(&self, ic: &IC) -> Result { + pub fn as_batch_mode( + &self, + ic: &IC, + ) -> Result { match &self.operand { Operand::Type { batch_mode: Some(bm), @@ -293,12 +296,15 @@ impl InstOperand { } => Ok(*bm), _ => { let val = self.as_value(ic)?; - BatchMode::try_from(val).map_err(|_| ICError::UnknownBatchMode(val)) + LogicBatchMethod::try_from(val).map_err(|_| ICError::UnknownBatchMode(val)) } } } - pub fn as_reagent_mode(&self, ic: &IC) -> Result { + pub fn as_reagent_mode( + &self, + ic: &IC, + ) -> Result { match &self.operand { Operand::Type { reagent_mode: Some(rm), @@ -306,7 +312,7 @@ impl InstOperand { } => Ok(*rm), _ => { let val = self.as_value(ic)?; - ReagentMode::try_from(val).map_err(|_| ICError::UnknownReagentMode(val)) + LogicReagentMode::try_from(val).map_err(|_| ICError::UnknownReagentMode(val)) } } } diff --git a/ic10emu/src/vm/object.rs b/ic10emu/src/vm/object.rs index 44edeb9..21c7ac5 100644 --- a/ic10emu/src/vm/object.rs +++ b/ic10emu/src/vm/object.rs @@ -18,15 +18,21 @@ pub mod traits; use traits::Object; use crate::vm::VM; +#[cfg(feature = "tsify")] +use tsify::{declare, Tsify}; +#[cfg(feature = "tsify")] +use wasm_bindgen::prelude::*; use stationeers_data::enums::{ - basic::Class as SlotClass, prefabs::StationpediaPrefab, script::LogicSlotType, MemoryAccess, + basic::Class, prefabs::StationpediaPrefab, script::LogicSlotType, MemoryAccess, }; +#[cfg_attr(feature = "tsify", declare)] pub type ObjectID = u32; pub type BoxedObject = Rc>; #[derive(Debug, Clone)] +#[cfg_attr(feature = "tsify", wasm_bindgen)] pub struct VMObject(BoxedObject); impl Deref for VMObject { @@ -67,6 +73,8 @@ impl VMObject { } #[derive(Debug, Default, Clone, Serialize, Deserialize)] +#[cfg_attr(feature = "tsify", derive(Tsify))] +#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))] pub struct Name { pub value: String, pub hash: i32, @@ -102,23 +110,29 @@ impl Name { } #[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(feature = "tsify", derive(Tsify))] +#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))] pub struct LogicField { pub field_type: MemoryAccess, pub value: f64, } #[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)] +#[cfg_attr(feature = "tsify", derive(Tsify))] +#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))] pub struct SlotOccupantInfo { pub quantity: u32, pub id: ObjectID, } #[derive(Debug, Default, Clone, Serialize, Deserialize)] +#[cfg_attr(feature = "tsify", derive(Tsify))] +#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))] pub struct Slot { pub parent: ObjectID, pub index: usize, pub name: String, - pub typ: SlotClass, + pub typ: Class, pub readable_logic: Vec, pub writeable_logic: Vec, pub occupant: Option, @@ -126,7 +140,7 @@ pub struct Slot { impl Slot { #[must_use] - pub fn new(parent: ObjectID, index: usize, name: String, typ: SlotClass) -> Self { + pub fn new(parent: ObjectID, index: usize, name: String, typ: Class) -> Self { Slot { parent, index, diff --git a/ic10emu/src/vm/object/generic/traits.rs b/ic10emu/src/vm/object/generic/traits.rs index f721f56..c66f668 100644 --- a/ic10emu/src/vm/object/generic/traits.rs +++ b/ic10emu/src/vm/object/generic/traits.rs @@ -9,7 +9,7 @@ use crate::{ use stationeers_data::{ enums::{ - basic::{Class as SlotClass, GasType, SortingClass}, + basic::{Class, GasType, SortingClass}, script::{LogicSlotType, LogicType}, }, templates::{DeviceInfo, InternalAtmoInfo, ItemInfo, SuitInfo, ThermalInfo}, @@ -548,7 +548,7 @@ impl Item for T { fn reagents(&self) -> Option<&BTreeMap> { self.item_info().reagents.as_ref() } - fn slot_class(&self) -> SlotClass { + fn slot_class(&self) -> Class { self.item_info().slot_class } fn sorting_class(&self) -> SortingClass { @@ -823,7 +823,7 @@ where fn get_ic_gw(&self) -> Option { self.get_slots() .into_iter() - .find(|slot| slot.typ == SlotClass::ProgrammableChip) + .find(|slot| slot.typ == Class::ProgrammableChip) .and_then(|slot| { slot.occupant .as_ref() @@ -974,7 +974,7 @@ where fn get_ic_gw(&self) -> Option { self.get_slots() .into_iter() - .find(|slot| slot.typ == SlotClass::ProgrammableChip) + .find(|slot| slot.typ == Class::ProgrammableChip) .and_then(|slot| { slot.occupant .as_ref() @@ -1149,7 +1149,7 @@ where fn get_ic_gw(&self) -> Option { self.get_slots() .into_iter() - .find(|slot| slot.typ == SlotClass::ProgrammableChip) + .find(|slot| slot.typ == Class::ProgrammableChip) .and_then(|slot| { slot.occupant .as_ref() diff --git a/ic10emu/src/vm/object/humans.rs b/ic10emu/src/vm/object/humans.rs index af856e8..bc12020 100644 --- a/ic10emu/src/vm/object/humans.rs +++ b/ic10emu/src/vm/object/humans.rs @@ -2,8 +2,7 @@ use std::collections::BTreeMap; use macro_rules_attribute::derive; use stationeers_data::{ - enums::{basic::Class as SlotClass, Species}, - templates::SlotInfo, + enums::{basic::Class, Species}, }; #[cfg(feature = "tsify")] use tsify::Tsify; @@ -106,21 +105,21 @@ impl HumanPlayer { food_quality: 0.75, mood: 1.0, hygiene: 1.0, - left_hand_slot: Slot::new(id, 0, "LeftHand".to_string(), SlotClass::None), - right_hand_slot: Slot::new(id, 1, "RightHand".to_string(), SlotClass::None), - suit_slot: Slot::new(id, 2, "Suit".to_string(), SlotClass::Suit), - helmet_slot: Slot::new(id, 3, "Helmet".to_string(), SlotClass::Helmet), - glasses_slot: Slot::new(id, 4, "Glasses".to_string(), SlotClass::Glasses), - backpack_slot: Slot::new(id, 5, "Back".to_string(), SlotClass::Back), - uniform_slot: Slot::new(id, 6, "Uniform".to_string(), SlotClass::Uniform), - toolbelt_slot: Slot::new(id, 7, "Belt".to_string(), SlotClass::Belt), + left_hand_slot: Slot::new(id, 0, "LeftHand".to_string(), Class::None), + right_hand_slot: Slot::new(id, 1, "RightHand".to_string(), Class::None), + suit_slot: Slot::new(id, 2, "Suit".to_string(), Class::Suit), + helmet_slot: Slot::new(id, 3, "Helmet".to_string(), Class::Helmet), + glasses_slot: Slot::new(id, 4, "Glasses".to_string(), Class::Glasses), + backpack_slot: Slot::new(id, 5, "Back".to_string(), Class::Back), + uniform_slot: Slot::new(id, 6, "Uniform".to_string(), Class::Uniform), + toolbelt_slot: Slot::new(id, 7, "Belt".to_string(), Class::Belt), } } pub fn with_species(id: ObjectID, vm: std::rc::Rc, species: Species) -> Self { let uniform_slot = if species == Species::Robot { - Slot::new(id, 6, "Battery".to_string(), SlotClass::Battery) + Slot::new(id, 6, "Battery".to_string(), Class::Battery) } else { - Slot::new(id, 6, "Uniform".to_string(), SlotClass::Uniform) + Slot::new(id, 6, "Uniform".to_string(), Class::Uniform) }; HumanPlayer { id, @@ -135,14 +134,14 @@ impl HumanPlayer { food_quality: 0.75, mood: 1.0, hygiene: 1.0, - left_hand_slot: Slot::new(id, 0, "LeftHand".to_string(), SlotClass::None), - right_hand_slot: Slot::new(id, 1, "RightHand".to_string(), SlotClass::None), - suit_slot: Slot::new(id, 2, "Suit".to_string(), SlotClass::Suit), - helmet_slot: Slot::new(id, 3, "Helmet".to_string(), SlotClass::Helmet), - glasses_slot: Slot::new(id, 4, "Glasses".to_string(), SlotClass::Glasses), - backpack_slot: Slot::new(id, 5, "Back".to_string(), SlotClass::Back), + left_hand_slot: Slot::new(id, 0, "LeftHand".to_string(), Class::None), + right_hand_slot: Slot::new(id, 1, "RightHand".to_string(), Class::None), + suit_slot: Slot::new(id, 2, "Suit".to_string(), Class::Suit), + helmet_slot: Slot::new(id, 3, "Helmet".to_string(), Class::Helmet), + glasses_slot: Slot::new(id, 4, "Glasses".to_string(), Class::Glasses), + backpack_slot: Slot::new(id, 5, "Back".to_string(), Class::Back), uniform_slot, - toolbelt_slot: Slot::new(id, 7, "Belt".to_string(), SlotClass::Belt), + toolbelt_slot: Slot::new(id, 7, "Belt".to_string(), Class::Belt), } } diff --git a/ic10emu/src/vm/object/stationpedia.rs b/ic10emu/src/vm/object/stationpedia.rs index e6c6998..088dc19 100644 --- a/ic10emu/src/vm/object/stationpedia.rs +++ b/ic10emu/src/vm/object/stationpedia.rs @@ -2,13 +2,13 @@ use std::rc::Rc; use stationeers_data::{ enums::prefabs::StationpediaPrefab, - templates::{ObjectTemplate, PrefabInfo}, + templates::{ObjectTemplate}, }; use crate::{ errors::TemplateError, vm::object::{ - templates::{FrozenObject, ObjectInfo, Prefab}, + templates::{ObjectInfo, Prefab}, Name, VMObject, }, }; diff --git a/ic10emu/src/vm/object/stationpedia/structs/circuit_holder.rs b/ic10emu/src/vm/object/stationpedia/structs/circuit_holder.rs index 71067ea..9940952 100644 --- a/ic10emu/src/vm/object/stationpedia/structs/circuit_holder.rs +++ b/ic10emu/src/vm/object/stationpedia/structs/circuit_holder.rs @@ -9,7 +9,7 @@ use crate::{ }; use macro_rules_attribute::derive; use stationeers_data::enums::{ - basic::Class as SlotClass, + basic::Class, prefabs::StationpediaPrefab, script::{LogicSlotType, LogicType}, ConnectionRole, @@ -58,7 +58,7 @@ impl StructureCircuitHousing { parent: id, index: 0, name: "Programmable Chip".to_string(), - typ: SlotClass::ProgrammableChip, + typ: Class::ProgrammableChip, readable_logic: vec![ LogicSlotType::Class, LogicSlotType::Damage, diff --git a/ic10emu/src/vm/object/stationpedia/structs/integrated_circuit.rs b/ic10emu/src/vm/object/stationpedia/structs/integrated_circuit.rs index 4a9fb7c..c0dae7e 100644 --- a/ic10emu/src/vm/object/stationpedia/structs/integrated_circuit.rs +++ b/ic10emu/src/vm/object/stationpedia/structs/integrated_circuit.rs @@ -14,7 +14,7 @@ use crate::{ }; use macro_rules_attribute::derive; use stationeers_data::enums::{ - basic::{Class as SlotClass, GasType, SortingClass}, + basic::{Class, GasType, SortingClass}, script::{LogicSlotType, LogicType}, }; use std::{collections::BTreeMap, rc::Rc}; @@ -67,8 +67,8 @@ impl Item for ItemIntegratedCircuit10 { fn reagents(&self) -> Option<&BTreeMap> { None } - fn slot_class(&self) -> SlotClass { - SlotClass::ProgrammableChip + fn slot_class(&self) -> Class { + Class::ProgrammableChip } fn sorting_class(&self) -> SortingClass { SortingClass::Default diff --git a/ic10emu/src/vm/object/templates.rs b/ic10emu/src/vm/object/templates.rs index 2abb3dc..bfc69c3 100644 --- a/ic10emu/src/vm/object/templates.rs +++ b/ic10emu/src/vm/object/templates.rs @@ -27,10 +27,8 @@ use crate::{ use serde_derive::{Deserialize, Serialize}; use stationeers_data::{ enums::{ - basic::{Class as SlotClass, GasType, SortingClass}, prefabs::StationpediaPrefab, script::{LogicSlotType, LogicType}, - ConnectionRole, ConnectionType, }, templates::*, }; @@ -1298,7 +1296,7 @@ impl From> for ItemInfo { impl From> for DeviceInfo { fn from(device: DeviceRef) -> Self { - let reagents: BTreeMap = device.get_reagents().iter().copied().collect(); + let _reagents: BTreeMap = device.get_reagents().iter().copied().collect(); DeviceInfo { connection_list: device .connection_list() diff --git a/ic10emu/src/vm/object/traits.rs b/ic10emu/src/vm/object/traits.rs index 210e128..47a545a 100644 --- a/ic10emu/src/vm/object/traits.rs +++ b/ic10emu/src/vm/object/traits.rs @@ -14,7 +14,7 @@ use crate::{ }, }; use stationeers_data::enums::{ - basic::{Class as SlotClass, GasType, SortingClass}, + basic::{Class, GasType, SortingClass}, script::{LogicSlotType, LogicType}, Species, }; @@ -146,7 +146,7 @@ tag_object_traits! { fn ingredient(&self) -> bool; fn max_quantity(&self) -> u32; fn reagents(&self) -> Option<&BTreeMap>; - fn slot_class(&self) -> SlotClass; + fn slot_class(&self) -> Class; fn sorting_class(&self) -> SortingClass; fn get_parent_slot(&self) -> Option; fn set_parent_slot(&mut self, info: Option); diff --git a/ic10emu_wasm/Cargo.toml b/ic10emu_wasm/Cargo.toml index 4ba219b..ea06db8 100644 --- a/ic10emu_wasm/Cargo.toml +++ b/ic10emu_wasm/Cargo.toml @@ -5,7 +5,7 @@ version.workspace = true edition.workspace = true [dependencies] -ic10emu = { path = "../ic10emu", feaures = ["tsify"] } +ic10emu = { path = "../ic10emu", features = ["tsify"] } console_error_panic_hook = {version = "0.1.7", optional = true} js-sys = "0.3.69" web-sys = { version = "0.3.69", features = ["WritableStream", "console"] } @@ -18,8 +18,9 @@ serde-wasm-bindgen = "0.6.5" itertools = "0.13.0" serde = { version = "1.0.202", features = ["derive"] } serde_with = "3.8.1" -tsify = { version = "0.4.5", default-features = false, features = ["js"] } +tsify = { version = "0.4.5", features = ["js"] } thiserror = "1.0.61" +serde_derive = "1.0.203" [build-dependencies] ic10emu = { path = "../ic10emu" } diff --git a/ic10emu_wasm/build.rs b/ic10emu_wasm/build.rs index 422bcaa..b83ec9b 100644 --- a/ic10emu_wasm/build.rs +++ b/ic10emu_wasm/build.rs @@ -9,89 +9,89 @@ use itertools::Itertools; use strum::IntoEnumIterator; fn main() { - let out_dir = env::var_os("OUT_DIR").unwrap(); - let dest_path = Path::new(&out_dir).join("ts_types.rs"); - let output_file = File::create(dest_path).unwrap(); - let mut writer = BufWriter::new(&output_file); - - let mut ts_types: String = String::new(); - - let lt_tsunion: String = Itertools::intersperse( - ic10emu::grammar::generated::LogicType::iter().map(|lt| format!("\"{}\"", lt.as_ref())), - "\n | ".to_owned(), - ) - .collect(); - let lt_tstype = format!("\nexport type LogicType = {};", lt_tsunion); - ts_types.push_str(<_tstype); - - let slt_tsunion: String = Itertools::intersperse( - ic10emu::grammar::generated::LogicSlotType::iter() - .map(|slt| format!("\"{}\"", slt.as_ref())), - "\n | ".to_owned(), - ) - .collect(); - let slt_tstype = format!("\nexport type LogicSlotType = {};", slt_tsunion); - ts_types.push_str(&slt_tstype); - - let bm_tsunion: String = Itertools::intersperse( - ic10emu::grammar::generated::BatchMode::iter().map(|bm| format!("\"{}\"", bm.as_ref())), - "\n | ".to_owned(), - ) - .collect(); - let bm_tstype = format!("\nexport type BatchMode = {};", bm_tsunion); - ts_types.push_str(&bm_tstype); - - let rm_tsunion: String = Itertools::intersperse( - ic10emu::grammar::generated::ReagentMode::iter().map(|rm| format!("\"{}\"", rm.as_ref())), - "\n | ".to_owned(), - ) - .collect(); - let rm_tstype = format!("\nexport type ReagentMode = {};", rm_tsunion); - ts_types.push_str(&rm_tstype); - - let sc_tsunion: String = Itertools::intersperse( - ic10emu::device::SortingClass::iter().map(|rm| format!("\"{}\"", rm.as_ref())), - "\n | ".to_owned(), - ) - .collect(); - let sc_tstype = format!("\nexport type SortingClass = {};", sc_tsunion); - ts_types.push_str(&sc_tstype); - - let st_tsunion: String = Itertools::intersperse( - ic10emu::device::SlotType::iter().map(|rm| format!("\"{}\"", rm.as_ref())), - "\n | ".to_owned(), - ) - .collect(); - let st_tstype = format!("\nexport type SlotType = {};", st_tsunion); - ts_types.push_str(&st_tstype); - - let ct_tsunion: String = Itertools::intersperse( - ic10emu::network::ConnectionType::iter().map(|rm| format!("\"{}\"", rm.as_ref())), - "\n | ".to_owned(), - ) - .collect(); - let ct_tstype = format!("\nexport type ConnectionType = {};", ct_tsunion); - ts_types.push_str(&ct_tstype); - - let cr_tsunion: String = Itertools::intersperse( - ic10emu::network::ConnectionRole::iter().map(|rm| format!("\"{}\"", rm.as_ref())), - "\n | ".to_owned(), - ) - .collect(); - let cr_tstype = format!("\nexport type ConnectionRole = {};", cr_tsunion); - ts_types.push_str(&cr_tstype); - - let infile = Path::new("src/types.ts"); - let contents = fs::read_to_string(infile).unwrap(); - - ts_types.push('\n'); - ts_types.push_str(&contents); - - write!( - &mut writer, - "#[wasm_bindgen(typescript_custom_section)]\n\ - const TYPES: &'static str = r#\"{ts_types}\"#; - " - ) - .unwrap(); + // let out_dir = env::var_os("OUT_DIR").unwrap(); + // let dest_path = Path::new(&out_dir).join("ts_types.rs"); + // let output_file = File::create(dest_path).unwrap(); + // let mut writer = BufWriter::new(&output_file); + // + // let mut ts_types: String = String::new(); + // + // let lt_tsunion: String = Itertools::intersperse( + // ic10emu::grammar::generated::LogicType::iter().map(|lt| format!("\"{}\"", lt.as_ref())), + // "\n | ".to_owned(), + // ) + // .collect(); + // let lt_tstype = format!("\nexport type LogicType = {};", lt_tsunion); + // ts_types.push_str(<_tstype); + // + // let slt_tsunion: String = Itertools::intersperse( + // ic10emu::grammar::generated::LogicSlotType::iter() + // .map(|slt| format!("\"{}\"", slt.as_ref())), + // "\n | ".to_owned(), + // ) + // .collect(); + // let slt_tstype = format!("\nexport type LogicSlotType = {};", slt_tsunion); + // ts_types.push_str(&slt_tstype); + // + // let bm_tsunion: String = Itertools::intersperse( + // ic10emu::grammar::generated::BatchMode::iter().map(|bm| format!("\"{}\"", bm.as_ref())), + // "\n | ".to_owned(), + // ) + // .collect(); + // let bm_tstype = format!("\nexport type BatchMode = {};", bm_tsunion); + // ts_types.push_str(&bm_tstype); + // + // let rm_tsunion: String = Itertools::intersperse( + // ic10emu::grammar::generated::ReagentMode::iter().map(|rm| format!("\"{}\"", rm.as_ref())), + // "\n | ".to_owned(), + // ) + // .collect(); + // let rm_tstype = format!("\nexport type ReagentMode = {};", rm_tsunion); + // ts_types.push_str(&rm_tstype); + // + // let sc_tsunion: String = Itertools::intersperse( + // ic10emu::device::SortingClass::iter().map(|rm| format!("\"{}\"", rm.as_ref())), + // "\n | ".to_owned(), + // ) + // .collect(); + // let sc_tstype = format!("\nexport type SortingClass = {};", sc_tsunion); + // ts_types.push_str(&sc_tstype); + // + // let st_tsunion: String = Itertools::intersperse( + // ic10emu::device::SlotType::iter().map(|rm| format!("\"{}\"", rm.as_ref())), + // "\n | ".to_owned(), + // ) + // .collect(); + // let st_tstype = format!("\nexport type SlotType = {};", st_tsunion); + // ts_types.push_str(&st_tstype); + // + // let ct_tsunion: String = Itertools::intersperse( + // ic10emu::network::ConnectionType::iter().map(|rm| format!("\"{}\"", rm.as_ref())), + // "\n | ".to_owned(), + // ) + // .collect(); + // let ct_tstype = format!("\nexport type ConnectionType = {};", ct_tsunion); + // ts_types.push_str(&ct_tstype); + // + // let cr_tsunion: String = Itertools::intersperse( + // ic10emu::network::ConnectionRole::iter().map(|rm| format!("\"{}\"", rm.as_ref())), + // "\n | ".to_owned(), + // ) + // .collect(); + // let cr_tstype = format!("\nexport type ConnectionRole = {};", cr_tsunion); + // ts_types.push_str(&cr_tstype); + // + // let infile = Path::new("src/types.ts"); + // let contents = fs::read_to_string(infile).unwrap(); + // + // ts_types.push('\n'); + // ts_types.push_str(&contents); + // + // write!( + // &mut writer, + // "#[wasm_bindgen(typescript_custom_section)]\n\ + // const TYPES: &'static str = r#\"{ts_types}\"#; + // " + // ) + // .unwrap(); } diff --git a/ic10emu_wasm/src/lib.rs b/ic10emu_wasm/src/lib.rs index 5a9ed3d..eadff29 100644 --- a/ic10emu_wasm/src/lib.rs +++ b/ic10emu_wasm/src/lib.rs @@ -1,14 +1,16 @@ #[macro_use] mod utils; -mod types; +// mod types; use ic10emu::{ - device::{Device, DeviceTemplate, SlotOccupantTemplate}, - grammar::{LogicSlotType, LogicType}, - vm::{FrozenVM, VMError, VM}, + errors::{TemplateError, VMError}, + vm::{ + object::{templates::FrozenObject, ObjectID, VMObject}, + FrozenVM, VM, + }, }; use serde_derive::{Deserialize, Serialize}; -use types::{Registers, Stack}; +// use types::{Registers, Stack}; use std::{cell::RefCell, rc::Rc, str::FromStr}; @@ -22,11 +24,11 @@ extern "C" { fn alert(s: &str); } -#[wasm_bindgen] -pub struct DeviceRef { - device: Rc>, - vm: Rc>, -} +// #[wasm_bindgen] +// pub struct DeviceRef { +// device: Rc>, +// vm: Rc>, +// } use thiserror::Error; @@ -38,484 +40,476 @@ pub enum BindingError { OutOfBounds(usize, usize), } -#[wasm_bindgen] -impl DeviceRef { - fn from_device(device: Rc>, vm: Rc>) -> Self { - DeviceRef { device, vm } - } - - #[wasm_bindgen(getter)] - pub fn id(&self) -> u32 { - self.device.borrow().id - } - - #[wasm_bindgen(getter)] - pub fn ic(&self) -> Option { - self.device.borrow().ic - } - - #[wasm_bindgen(getter)] - pub fn name(&self) -> Option { - self.device.borrow().name.clone() - } - - #[wasm_bindgen(getter, js_name = "nameHash")] - pub fn name_hash(&self) -> Option { - self.device.borrow().name_hash - } - - #[wasm_bindgen(getter, js_name = "prefabName")] - pub fn prefab_name(&self) -> Option { - self.device - .borrow() - .prefab - .as_ref() - .map(|prefab| prefab.name.clone()) - } - - #[wasm_bindgen(getter, js_name = "prefabHash")] - pub fn prefab_hash(&self) -> Option { - self.device - .borrow() - .prefab - .as_ref() - .map(|prefab| prefab.hash) - } - - #[wasm_bindgen(getter, skip_typescript)] - pub fn fields(&self) -> JsValue { - serde_wasm_bindgen::to_value(&self.device.borrow().get_fields(&self.vm.borrow())).unwrap() - } - - #[wasm_bindgen(getter)] - pub fn slots(&self) -> types::Slots { - types::Slots::from_iter(self.device.borrow().slots.iter()) - } - - #[wasm_bindgen(getter, skip_typescript)] - pub fn reagents(&self) -> JsValue { - serde_wasm_bindgen::to_value(&self.device.borrow().reagents).unwrap() - } - - #[wasm_bindgen(getter, skip_typescript)] - pub fn connections(&self) -> JsValue { - serde_wasm_bindgen::to_value(&self.device.borrow().connections).unwrap() - } - - #[wasm_bindgen(getter, js_name = "ip")] - pub fn ic_ip(&self) -> Option { - self.device.borrow().ic.as_ref().and_then(|ic| { - self.vm - .borrow() - .circuit_holders - .get(ic) - .map(|ic| ic.as_ref().borrow().ip()) - }) - } - - #[wasm_bindgen(getter, js_name = "instructionCount")] - pub fn ic_instruction_count(&self) -> Option { - self.device.borrow().ic.as_ref().and_then(|ic| { - self.vm - .borrow() - .circuit_holders - .get(ic) - .map(|ic| ic.as_ref().borrow().ic.get()) - }) - } - - #[wasm_bindgen(getter, js_name = "stack")] - pub fn ic_stack(&self) -> Option { - self.device.borrow().ic.as_ref().and_then(|ic| { - self.vm - .borrow() - .circuit_holders - .get(ic) - .map(|ic| Stack(*ic.as_ref().borrow().stack.borrow())) - }) - } - - #[wasm_bindgen(getter, js_name = "registers")] - pub fn ic_registers(&self) -> Option { - self.device.borrow().ic.as_ref().and_then(|ic| { - self.vm - .borrow() - .circuit_holders - .get(ic) - .map(|ic| Registers(*ic.as_ref().borrow().registers.borrow())) - }) - } - - #[wasm_bindgen(getter, js_name = "aliases", skip_typescript)] - pub fn ic_aliases(&self) -> JsValue { - let aliases = &self.device.borrow().ic.as_ref().and_then(|ic| { - self.vm - .borrow() - .circuit_holders - .get(ic) - .map(|ic| ic.as_ref().borrow().aliases.borrow().clone()) - }); - serde_wasm_bindgen::to_value(aliases).unwrap() - } - - #[wasm_bindgen(getter, js_name = "defines", skip_typescript)] - pub fn ic_defines(&self) -> JsValue { - let defines = &self.device.borrow().ic.as_ref().and_then(|ic| { - self.vm - .borrow() - .circuit_holders - .get(ic) - .map(|ic| ic.as_ref().borrow().defines.borrow().clone()) - }); - serde_wasm_bindgen::to_value(defines).unwrap() - } - - #[wasm_bindgen(getter, js_name = "pins", skip_typescript)] - pub fn ic_pins(&self) -> JsValue { - let pins = &self.device.borrow().ic.as_ref().and_then(|ic| { - self.vm - .borrow() - .circuit_holders - .get(ic) - .map(|ic| *ic.as_ref().borrow().pins.borrow()) - }); - serde_wasm_bindgen::to_value(pins).unwrap() - } - - #[wasm_bindgen(getter, js_name = "state")] - pub fn ic_state(&self) -> Option { - self.device - .borrow() - .ic - .as_ref() - .and_then(|ic| { - self.vm - .borrow() - .circuit_holders - .get(ic) - .map(|ic| ic.borrow().state.clone()) - }) - .map(|state| state.borrow().to_string()) - } - - #[wasm_bindgen(getter, js_name = "program", skip_typescript)] - pub fn ic_program(&self) -> JsValue { - let prog = &self.device.borrow().ic.as_ref().and_then(|ic| { - self.vm - .borrow() - .circuit_holders - .get(ic) - .map(|ic| ic.borrow().program.borrow().clone()) - }); - serde_wasm_bindgen::to_value(prog).unwrap() - } - - #[wasm_bindgen(getter, js_name = "code")] - pub fn get_code(&self) -> Option { - self.device.borrow().ic.as_ref().and_then(|ic| { - self.vm - .borrow() - .circuit_holders - .get(ic) - .map(|ic| ic.borrow().code.borrow().clone()) - }) - } - - #[wasm_bindgen(js_name = "step")] - pub fn step_ic(&self, advance_ip_on_err: bool) -> Result { - let id = self.device.borrow().id; - Ok(self.vm.borrow().step_ic(id, advance_ip_on_err)?) - } - - #[wasm_bindgen(js_name = "run")] - pub fn run_ic(&self, ignore_errors: bool) -> Result { - let id = self.device.borrow().id; - Ok(self.vm.borrow().run_ic(id, ignore_errors)?) - } - - #[wasm_bindgen(js_name = "reset")] - pub fn reset_ic(&self) -> Result { - let id = self.device.borrow().id; - Ok(self.vm.borrow().reset_ic(id)?) - } - - #[wasm_bindgen(js_name = "setCode")] - /// Set program code if it's valid - pub fn set_code(&self, code: &str) -> Result { - let id = self.device.borrow().id; - Ok(self.vm.borrow().set_code(id, code)?) - } - - #[wasm_bindgen(js_name = "setCodeInvalid")] - /// Set program code and translate invalid lines to Nop, collecting errors - pub fn set_code_invlaid(&self, code: &str) -> Result { - let id = self.device.borrow().id; - Ok(self.vm.borrow().set_code_invalid(id, code)?) - } - - #[wasm_bindgen(js_name = "setRegister")] - pub fn ic_set_register(&self, index: u32, val: f64) -> Result { - let ic_id = *self - .device - .borrow() - .ic - .as_ref() - .ok_or(VMError::NoIC(self.device.borrow().id))?; - let vm_borrow = self.vm.borrow(); - let ic = vm_borrow - .circuit_holders - .get(&ic_id) - .ok_or(VMError::NoIC(self.device.borrow().id))?; - let result = ic.borrow_mut().set_register(0, index, val)?; - Ok(result) - } - - #[wasm_bindgen(js_name = "setStack")] - pub fn ic_set_stack(&self, address: f64, val: f64) -> Result { - let ic_id = *self - .device - .borrow() - .ic - .as_ref() - .ok_or(VMError::NoIC(self.device.borrow().id))?; - let vm_borrow = self.vm.borrow(); - let ic = vm_borrow - .circuit_holders - .get(&ic_id) - .ok_or(VMError::NoIC(self.device.borrow().id))?; - let result = ic.borrow_mut().poke(address, val)?; - Ok(result) - } - - #[wasm_bindgen(js_name = "setName")] - pub fn set_name(&self, name: &str) { - self.device.borrow_mut().set_name(name) - } - - #[wasm_bindgen(js_name = "setField", skip_typescript)] - pub fn set_field(&self, field: &str, value: f64, force: bool) -> Result<(), JsError> { - let logic_typ = LogicType::from_str(field)?; - let mut device_ref = self.device.borrow_mut(); - device_ref.set_field(logic_typ, value, &self.vm.borrow(), force)?; - Ok(()) - } - - #[wasm_bindgen(js_name = "setSlotField", skip_typescript)] - pub fn set_slot_field( - &self, - slot: f64, - field: &str, - value: f64, - force: bool, - ) -> Result<(), JsError> { - let logic_typ = LogicSlotType::from_str(field)?; - let mut device_ref = self.device.borrow_mut(); - device_ref.set_slot_field(slot, logic_typ, value, &self.vm.borrow(), force)?; - Ok(()) - } - - #[wasm_bindgen(js_name = "getSlotField", skip_typescript)] - pub fn get_slot_field(&self, slot: f64, field: &str) -> Result { - let logic_typ = LogicSlotType::from_str(field)?; - let device_ref = self.device.borrow_mut(); - Ok(device_ref.get_slot_field(slot, logic_typ, &self.vm.borrow())?) - } - - #[wasm_bindgen(js_name = "getSlotFields", skip_typescript)] - pub fn get_slot_fields(&self, slot: f64) -> Result { - let device_ref = self.device.borrow_mut(); - let fields = device_ref.get_slot_fields(slot, &self.vm.borrow())?; - Ok(serde_wasm_bindgen::to_value(&fields).unwrap()) - } - - #[wasm_bindgen(js_name = "setConnection")] - pub fn set_connection(&self, conn: usize, net: Option) -> Result<(), JsError> { - let device_id = self.device.borrow().id; - self.vm - .borrow() - .set_device_connection(device_id, conn, net)?; - Ok(()) - } - - #[wasm_bindgen(js_name = "removeDeviceFromNetwork")] - pub fn remove_device_from_network(&self, network_id: u32) -> Result { - let id = self.device.borrow().id; - Ok(self - .vm - .borrow() - .remove_device_from_network(id, network_id)?) - } - - #[wasm_bindgen(js_name = "setPin")] - pub fn set_pin(&self, pin: usize, val: Option) -> Result { - let id = self.device.borrow().id; - Ok(self.vm.borrow().set_pin(id, pin, val)?) - } -} +// #[wasm_bindgen] +// impl DeviceRef { +// fn from_device(device: Rc>, vm: Rc>) -> Self { +// DeviceRef { device, vm } +// } +// +// #[wasm_bindgen(getter)] +// pub fn id(&self) -> ObjectID { +// self.device.id +// } +// +// #[wasm_bindgen(getter)] +// pub fn ic(&self) -> Option { +// self.device.ic +// } +// +// #[wasm_bindgen(getter)] +// pub fn name(&self) -> Option { +// self.device.name.clone() +// } +// +// #[wasm_bindgen(getter, js_name = "nameHash")] +// pub fn name_hash(&self) -> Option { +// self.device.name_hash +// } +// +// #[wasm_bindgen(getter, js_name = "prefabName")] +// pub fn prefab_name(&self) -> Option { +// self.device +// +// .prefab +// .as_ref() +// .map(|prefab| prefab.name.clone()) +// } +// +// #[wasm_bindgen(getter, js_name = "prefabHash")] +// pub fn prefab_hash(&self) -> Option { +// self.device +// +// .prefab +// .as_ref() +// .map(|prefab| prefab.hash) +// } +// +// #[wasm_bindgen(getter, skip_typescript)] +// pub fn fields(&self) -> JsValue { +// serde_wasm_bindgen::to_value(&self.device.get_fields(&self.vm.borrow())).unwrap() +// } +// +// #[wasm_bindgen(getter)] +// pub fn slots(&self) -> types::Slots { +// types::Slots::from_iter(self.device.slots.iter()) +// } +// +// #[wasm_bindgen(getter, skip_typescript)] +// pub fn reagents(&self) -> JsValue { +// serde_wasm_bindgen::to_value(&self.device.reagents).unwrap() +// } +// +// #[wasm_bindgen(getter, skip_typescript)] +// pub fn connections(&self) -> JsValue { +// serde_wasm_bindgen::to_value(&self.device.connections).unwrap() +// } +// +// #[wasm_bindgen(getter, js_name = "ip")] +// pub fn ic_ip(&self) -> Option { +// self.device.ic.as_ref().and_then(|ic| { +// self.vm +// +// .circuit_holders +// .get(ic) +// .map(|ic| ic.as_ref().ip()) +// }) +// } +// +// #[wasm_bindgen(getter, js_name = "instructionCount")] +// pub fn ic_instruction_count(&self) -> Option { +// self.device.ic.as_ref().and_then(|ic| { +// self.vm +// +// .circuit_holders +// .get(ic) +// .map(|ic| ic.as_ref().ic.get()) +// }) +// } +// +// #[wasm_bindgen(getter, js_name = "stack")] +// pub fn ic_stack(&self) -> Option { +// self.device.ic.as_ref().and_then(|ic| { +// self.vm +// +// .circuit_holders +// .get(ic) +// .map(|ic| Stack(*ic.as_ref().stack.borrow())) +// }) +// } +// +// #[wasm_bindgen(getter, js_name = "registers")] +// pub fn ic_registers(&self) -> Option { +// self.device.ic.as_ref().and_then(|ic| { +// self.vm +// +// .circuit_holders +// .get(ic) +// .map(|ic| Registers(*ic.as_ref().registers.borrow())) +// }) +// } +// +// #[wasm_bindgen(getter, js_name = "aliases", skip_typescript)] +// pub fn ic_aliases(&self) -> JsValue { +// let aliases = &self.device.ic.as_ref().and_then(|ic| { +// self.vm +// +// .circuit_holders +// .get(ic) +// .map(|ic| ic.as_ref().aliases.borrow().clone()) +// }); +// serde_wasm_bindgen::to_value(aliases).unwrap() +// } +// +// #[wasm_bindgen(getter, js_name = "defines", skip_typescript)] +// pub fn ic_defines(&self) -> JsValue { +// let defines = &self.device.ic.as_ref().and_then(|ic| { +// self.vm +// +// .circuit_holders +// .get(ic) +// .map(|ic| ic.as_ref().defines.borrow().clone()) +// }); +// serde_wasm_bindgen::to_value(defines).unwrap() +// } +// +// #[wasm_bindgen(getter, js_name = "pins", skip_typescript)] +// pub fn ic_pins(&self) -> JsValue { +// let pins = &self.device.ic.as_ref().and_then(|ic| { +// self.vm +// +// .circuit_holders +// .get(ic) +// .map(|ic| *ic.as_ref().pins.borrow()) +// }); +// serde_wasm_bindgen::to_value(pins).unwrap() +// } +// +// #[wasm_bindgen(getter, js_name = "state")] +// pub fn ic_state(&self) -> Option { +// self.device +// +// .ic +// .as_ref() +// .and_then(|ic| { +// self.vm +// +// .circuit_holders +// .get(ic) +// .map(|ic| ic.state.clone()) +// }) +// .map(|state| state.to_string()) +// } +// +// #[wasm_bindgen(getter, js_name = "program", skip_typescript)] +// pub fn ic_program(&self) -> JsValue { +// let prog = &self.device.ic.as_ref().and_then(|ic| { +// self.vm +// +// .circuit_holders +// .get(ic) +// .map(|ic| ic.program.borrow().clone()) +// }); +// serde_wasm_bindgen::to_value(prog).unwrap() +// } +// +// #[wasm_bindgen(getter, js_name = "code")] +// pub fn get_code(&self) -> Option { +// self.device.ic.as_ref().and_then(|ic| { +// self.vm +// +// .circuit_holders +// .get(ic) +// .map(|ic| ic.code.borrow().clone()) +// }) +// } +// +// #[wasm_bindgen(js_name = "step")] +// pub fn step_ic(&self, advance_ip_on_err: bool) -> Result { +// let id = self.device.id; +// Ok(self.vm.step_ic(id, advance_ip_on_err)?) +// } +// +// #[wasm_bindgen(js_name = "run")] +// pub fn run_ic(&self, ignore_errors: bool) -> Result { +// let id = self.device.id; +// Ok(self.vm.run_ic(id, ignore_errors)?) +// } +// +// #[wasm_bindgen(js_name = "reset")] +// pub fn reset_ic(&self) -> Result { +// let id = self.device.id; +// Ok(self.vm.reset_ic(id)?) +// } +// +// #[wasm_bindgen(js_name = "setCode")] +// /// Set program code if it's valid +// pub fn set_code(&self, code: &str) -> Result { +// let id = self.device.id; +// Ok(self.vm.set_code(id, code)?) +// } +// +// #[wasm_bindgen(js_name = "setCodeInvalid")] +// /// Set program code and translate invalid lines to Nop, collecting errors +// pub fn set_code_invlaid(&self, code: &str) -> Result { +// let id = self.device.id; +// Ok(self.vm.set_code_invalid(id, code)?) +// } +// +// #[wasm_bindgen(js_name = "setRegister")] +// pub fn ic_set_register(&self, index: ObjectID, val: f64) -> Result { +// let ic_id = *self +// .device +// +// .ic +// .as_ref() +// .ok_or(VMError::NoIC(self.device.id))?; +// let vm_borrow = self.vm; +// let ic = vm_borrow +// .circuit_holders +// .get(&ic_id) +// .ok_or(VMError::NoIC(self.device.id))?; +// let result = ic.set_register(0, index, val)?; +// Ok(result) +// } +// +// #[wasm_bindgen(js_name = "setStack")] +// pub fn ic_set_stack(&self, address: f64, val: f64) -> Result { +// let ic_id = *self +// .device +// +// .ic +// .as_ref() +// .ok_or(VMError::NoIC(self.device.id))?; +// let vm_borrow = self.vm; +// let ic = vm_borrow +// .circuit_holders +// .get(&ic_id) +// .ok_or(VMError::NoIC(self.device.id))?; +// let result = ic.poke(address, val)?; +// Ok(result) +// } +// +// #[wasm_bindgen(js_name = "setName")] +// pub fn set_name(&self, name: &str) { +// self.device.set_name(name) +// } +// +// #[wasm_bindgen(js_name = "setField", skip_typescript)] +// pub fn set_field(&self, field: &str, value: f64, force: bool) -> Result<(), JsError> { +// let logic_typ = LogicType::from_str(field)?; +// let mut device_ref = self.device; +// device_ref.set_field(logic_typ, value, &self.vm, force)?; +// Ok(()) +// } +// +// #[wasm_bindgen(js_name = "setSlotField", skip_typescript)] +// pub fn set_slot_field( +// &self, +// slot: f64, +// field: &str, +// value: f64, +// force: bool, +// ) -> Result<(), JsError> { +// let logic_typ = LogicSlotType::from_str(field)?; +// let mut device_ref = self.device; +// device_ref.set_slot_field(slot, logic_typ, value, &self.vm, force)?; +// Ok(()) +// } +// +// #[wasm_bindgen(js_name = "getSlotField", skip_typescript)] +// pub fn get_slot_field(&self, slot: f64, field: &str) -> Result { +// let logic_typ = LogicSlotType::from_str(field)?; +// let device_ref = self.device; +// Ok(device_ref.get_slot_field(slot, logic_typ, &self.vm)?) +// } +// +// #[wasm_bindgen(js_name = "getSlotFields", skip_typescript)] +// pub fn get_slot_fields(&self, slot: f64) -> Result { +// let device_ref = self.device; +// let fields = device_ref.get_slot_fields(slot, &self.vm)?; +// Ok(serde_wasm_bindgen::to_value(&fields).unwrap()) +// } +// +// #[wasm_bindgen(js_name = "setConnection")] +// pub fn set_connection(&self, conn: usize, net: Option) -> Result<(), JsError> { +// let device_id = self.device.id; +// self.vm +// +// .set_device_connection(device_id, conn, net)?; +// Ok(()) +// } +// +// #[wasm_bindgen(js_name = "removeDeviceFromNetwork")] +// pub fn remove_device_from_network(&self, network_id: ObjectID) -> Result { +// let id = self.device.id; +// Ok(self +// .vm +// +// .remove_device_from_network(id, network_id)?) +// } +// +// #[wasm_bindgen(js_name = "setPin")] +// pub fn set_pin(&self, pin: usize, val: Option) -> Result { +// let id = self.device.id; +// Ok(self.vm.set_pin(id, pin, val)?) +// } +// } #[wasm_bindgen] #[derive(Debug)] pub struct VMRef { - vm: Rc>, + vm: Rc, } +// #[wasm_bindgen] +// pub struct ObjectRef(VMObject); + #[wasm_bindgen] impl VMRef { #[wasm_bindgen(constructor)] pub fn new() -> Self { - VMRef { - vm: Rc::new(RefCell::new(VM::new())), - } + VMRef { vm: VM::new() } } - #[wasm_bindgen(js_name = "addDevice")] - pub fn add_device(&self, network: Option) -> Result { - Ok(self.vm.borrow_mut().add_object(network)?) - } - - #[wasm_bindgen(js_name = "addDeviceFromTemplate", skip_typescript)] - pub fn add_device_from_template(&self, template: JsValue) -> Result { - let template: DeviceTemplate = serde_wasm_bindgen::from_value(template)?; + #[wasm_bindgen(js_name = "addDeviceFromTemplate")] + pub fn add_device_from_template(&self, frozen: FrozenObject) -> Result { web_sys::console::log_2( &"(wasm) adding device".into(), - &serde_wasm_bindgen::to_value(&template).unwrap(), + &serde_wasm_bindgen::to_value(&frozen).unwrap(), ); - Ok(self.vm.borrow_mut().add_device_from_template(template)?) + Ok(self.vm.add_object_from_frozen(frozen)?) } #[wasm_bindgen(js_name = "getDevice")] - pub fn get_device(&self, id: u32) -> Option { - let device = self.vm.borrow().get_object(id); - device.map(|d| DeviceRef::from_device(d.clone(), self.vm.clone())) + pub fn get_object(&self, id: ObjectID) -> Option { + let obj = self.vm.get_object(id); + // device.map(|d| DeviceRef::from_device(d.clone(), self.vm.clone())) + obj } #[wasm_bindgen(js_name = "setCode")] /// Set program code if it's valid - pub fn set_code(&self, id: u32, code: &str) -> Result { - Ok(self.vm.borrow().set_code(id, code)?) + pub fn set_code(&self, id: ObjectID, code: &str) -> Result { + Ok(self.vm.set_code(id, code)?) } #[wasm_bindgen(js_name = "setCodeInvalid")] /// Set program code and translate invalid lines to Nop, collecting errors - pub fn set_code_invalid(&self, id: u32, code: &str) -> Result { - Ok(self.vm.borrow().set_code_invalid(id, code)?) + pub fn set_code_invalid(&self, id: ObjectID, code: &str) -> Result { + Ok(self.vm.set_code_invalid(id, code)?) } #[wasm_bindgen(js_name = "stepIC")] - pub fn step_ic(&self, id: u32, advance_ip_on_err: bool) -> Result { - Ok(self.vm.borrow().step_ic(id, advance_ip_on_err)?) + pub fn step_ic(&self, id: ObjectID, advance_ip_on_err: bool) -> Result<(), JsError> { + Ok(self.vm.step_programmable(id, advance_ip_on_err)?) } #[wasm_bindgen(js_name = "runIC")] - pub fn run_ic(&self, id: u32, ignore_errors: bool) -> Result { - Ok(self.vm.borrow().run_ic(id, ignore_errors)?) + pub fn run_ic(&self, id: ObjectID, ignore_errors: bool) -> Result { + Ok(self.vm.run_programmable(id, ignore_errors)?) } #[wasm_bindgen(js_name = "resetIC")] - pub fn reset_ic(&self, id: u32) -> Result { - Ok(self.vm.borrow().reset_ic(id)?) + pub fn reset_ic(&self, id: ObjectID) -> Result { + Ok(self.vm.reset_programmable(id)?) } #[wasm_bindgen(getter, js_name = "defaultNetwork")] - pub fn default_network(&self) -> u32 { - self.vm.borrow().default_network_key + pub fn default_network(&self) -> ObjectID { + *self.vm.default_network_key.borrow() } - #[wasm_bindgen(getter)] - pub fn devices(&self) -> Vec { - self.vm.borrow().devices.keys().copied().collect_vec() - } - - #[wasm_bindgen(getter)] - pub fn networks(&self) -> Vec { - self.vm.borrow().networks.keys().copied().collect_vec() - } - - #[wasm_bindgen(getter)] - pub fn ics(&self) -> Vec { - self.vm - .borrow() - .circuit_holders - .keys() - .copied() - .collect_vec() - } + // #[wasm_bindgen(getter)] + // pub fn devices(&self) -> Vec { + // self.vm.devices.keys().copied().collect_vec() + // } + // + // #[wasm_bindgen(getter)] + // pub fn networks(&self) -> Vec { + // self.vm.networks.keys().copied().collect_vec() + // } + // + // #[wasm_bindgen(getter)] + // pub fn ics(&self) -> Vec { + // self.vm.circuit_holders.keys().copied().collect_vec() + // } #[wasm_bindgen(getter, js_name = "lastOperationModified")] - pub fn last_operation_modified(&self) -> Vec { - self.vm.borrow().last_operation_modified() + pub fn last_operation_modified(&self) -> Vec { + self.vm.last_operation_modified() } #[wasm_bindgen(js_name = "visibleDevices")] - pub fn visible_devices(&self, source: u32) -> Vec { - self.vm.borrow().visible_devices(source) + pub fn visible_devices(&self, source: ObjectID) -> Vec { + self.vm.visible_devices(source) } #[wasm_bindgen(js_name = "setDeviceConnection")] pub fn set_device_connection( &self, - id: u32, + id: ObjectID, connection: usize, - network_id: Option, + network_id: Option, ) -> Result { - Ok(self - .vm - .borrow() - .set_device_connection(id, connection, network_id)?) + Ok(self.vm.set_device_connection(id, connection, network_id)?) } #[wasm_bindgen(js_name = "removeDeviceFromNetwork")] - pub fn remove_device_from_network(&self, id: u32, network_id: u32) -> Result { - Ok(self - .vm - .borrow() - .remove_device_from_network(id, network_id)?) + pub fn remove_device_from_network( + &self, + id: ObjectID, + network_id: u32, + ) -> Result { + Ok(self.vm.remove_device_from_network(id, network_id)?) } #[wasm_bindgen(js_name = "setPin")] - pub fn set_pin(&self, id: u32, pin: usize, val: Option) -> Result { - Ok(self.vm.borrow().set_pin(id, pin, val)?) + pub fn set_pin(&self, id: ObjectID, pin: usize, val: Option) -> Result { + Ok(self.vm.set_pin(id, pin, val)?) } #[wasm_bindgen(js_name = "changeDeviceId")] - pub fn change_device_id(&self, old_id: u32, new_id: u32) -> Result<(), JsError> { - Ok(self.vm.borrow_mut().change_device_id(old_id, new_id)?) + pub fn change_device_id(&self, old_id: ObjectID, new_id: u32) -> Result<(), JsError> { + Ok(self.vm.change_device_id(old_id, new_id)?) } #[wasm_bindgen(js_name = "removeDevice")] - pub fn remove_device(&self, id: u32) -> Result<(), JsError> { - Ok(self.vm.borrow_mut().remove_object(id)?) + pub fn remove_device(&self, id: ObjectID) -> Result<(), JsError> { + Ok(self.vm.remove_object(id)?) } - #[wasm_bindgen(js_name = "setSlotOccupant", skip_typescript)] + #[wasm_bindgen(js_name = "setSlotOccupant")] pub fn set_slot_occupant( &self, - id: u32, + id: ObjectID, index: usize, - template: JsValue, - ) -> Result<(), JsError> { - let template: SlotOccupantTemplate = serde_wasm_bindgen::from_value(template)?; + frozen: FrozenObject, + quantity: u32, + ) -> Result, JsError> { + let obj_id = if let Some(obj) = frozen.obj_info.id.and_then(|id| self.vm.get_object(id)) { + // TODO: we just assume if the ID is found that the frozen object passed is the same object.. + obj.get_id() + } else { + self.vm.add_object_from_frozen(frozen)? + }; Ok(self .vm - .borrow_mut() - .set_slot_occupant(id, index, template)?) + .set_slot_occupant(id, index, Some(obj_id), quantity)?) } #[wasm_bindgen(js_name = "removeSlotOccupant")] - pub fn remove_slot_occupant(&self, id: u32, index: usize) -> Result<(), JsError> { - Ok(self.vm.borrow_mut().remove_slot_occupant(id, index)?) + pub fn remove_slot_occupant(&self, id: ObjectID, index: usize) -> Result, JsError> { + Ok(self.vm.remove_slot_occupant(id, index)?) } - #[wasm_bindgen(js_name = "saveVMState", skip_typescript)] - pub fn save_vm_state(&self) -> JsValue { - let state = self.vm.borrow().save_vm_state(); - serde_wasm_bindgen::to_value(&state).unwrap() + #[wasm_bindgen(js_name = "saveVMState")] + pub fn save_vm_state(&self) -> Result { + Ok(self.vm.save_vm_state()?) } - #[wasm_bindgen(js_name = "restoreVMState", skip_typescript)] - pub fn restore_vm_state(&self, state: JsValue) -> Result<(), JsError> { - let state: FrozenVM = serde_wasm_bindgen::from_value(state)?; - self.vm.borrow_mut().restore_vm_state(state)?; + #[wasm_bindgen(js_name = "restoreVMState")] + pub fn restore_vm_state(&self, state: FrozenVM) -> Result<(), JsError> { + self.vm.restore_vm_state(state)?; Ok(()) } } diff --git a/ic10emu_wasm/src/utils.rs b/ic10emu_wasm/src/utils.rs index ead4cd6..7439406 100644 --- a/ic10emu_wasm/src/utils.rs +++ b/ic10emu_wasm/src/utils.rs @@ -8,7 +8,7 @@ pub fn set_panic_hook() { #[cfg(feature = "console_error_panic_hook")] { console_error_panic_hook::set_once(); - web_sys::console::log_1(&format!("Panic hook set...").into()); + web_sys::console::log_1(&"Panic hook set...".into()); } } diff --git a/stationeers_data/src/templates.rs b/stationeers_data/src/templates.rs index 07c91db..3a25ab1 100644 --- a/stationeers_data/src/templates.rs +++ b/stationeers_data/src/templates.rs @@ -1,7 +1,7 @@ use std::collections::BTreeMap; use crate::enums::{ - basic::{Class as SlotClass, GasType, SortingClass}, + basic::{Class, GasType, SortingClass}, script::{LogicSlotType, LogicType}, ConnectionRole, ConnectionType, MachineTier, MemoryAccess, Species, }; @@ -196,7 +196,7 @@ pub struct PrefabInfo { #[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))] pub struct SlotInfo { pub name: String, - pub typ: SlotClass, + pub typ: Class, } #[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)] @@ -220,7 +220,7 @@ pub struct ItemInfo { pub ingredient: bool, pub max_quantity: u32, pub reagents: Option>, - pub slot_class: SlotClass, + pub slot_class: Class, pub sorting_class: SortingClass, }