refactor(vm): make wasmbindings build again, use tsify for types

This commit is contained in:
Rachel Powers
2024-05-27 04:11:40 -07:00
parent 88ff2d1bdb
commit dae6be9f4a
20 changed files with 571 additions and 556 deletions

9
Cargo.lock generated
View File

@@ -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",

View File

@@ -47,4 +47,3 @@ serde_json = "1.0.117"
[features]
tsify = ["dep:tsify", "dep:wasm-bindgen", "stationeers_data/tsify"]
wasm-bindgen = ["dep:wasm-bindgen"]

View File

@@ -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 {

View File

@@ -1,5 +1,5 @@
use crate::{
errors::{ICError, ParseError},
errors::{ParseError},
interpreter,
tokens::{SplitConsecutiveIndicesExt, SplitConsecutiveWithIndices},
vm::instructions::{

View File

@@ -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,

View File

@@ -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;

View File

@@ -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<LogicType>,
slot_logic_type: Option<LogicSlotType>,
batch_mode: Option<BatchMode>,
reagent_mode: Option<ReagentMode>,
batch_mode: Option<LogicBatchMethod>,
reagent_mode: Option<LogicReagentMode>,
identifier: Identifier,
},
Identifier(Identifier),
@@ -285,7 +285,10 @@ impl InstOperand {
}
}
pub fn as_batch_mode<IC: IntegratedCircuit>(&self, ic: &IC) -> Result<BatchMode, ICError> {
pub fn as_batch_mode<IC: IntegratedCircuit>(
&self,
ic: &IC,
) -> Result<LogicBatchMethod, ICError> {
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<IC: IntegratedCircuit>(&self, ic: &IC) -> Result<ReagentMode, ICError> {
pub fn as_reagent_mode<IC: IntegratedCircuit>(
&self,
ic: &IC,
) -> Result<LogicReagentMode, ICError> {
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))
}
}
}

View File

@@ -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<RefCell<dyn Object>>;
#[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<LogicSlotType>,
pub writeable_logic: Vec<LogicSlotType>,
pub occupant: Option<SlotOccupantInfo>,
@@ -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,

View File

@@ -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<T: GWItem + Object> Item for T {
fn reagents(&self) -> Option<&BTreeMap<String, f64>> {
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<crate::vm::object::VMObject> {
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<crate::vm::object::VMObject> {
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<crate::vm::object::VMObject> {
self.get_slots()
.into_iter()
.find(|slot| slot.typ == SlotClass::ProgrammableChip)
.find(|slot| slot.typ == Class::ProgrammableChip)
.and_then(|slot| {
slot.occupant
.as_ref()

View File

@@ -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<VM>, 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),
}
}

View File

@@ -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,
},
};

View File

@@ -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,

View File

@@ -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<String, f64>> {
None
}
fn slot_class(&self) -> SlotClass {
SlotClass::ProgrammableChip
fn slot_class(&self) -> Class {
Class::ProgrammableChip
}
fn sorting_class(&self) -> SortingClass {
SortingClass::Default

View File

@@ -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<ItemRef<'_>> for ItemInfo {
impl From<DeviceRef<'_>> for DeviceInfo {
fn from(device: DeviceRef) -> Self {
let reagents: BTreeMap<i32, f64> = device.get_reagents().iter().copied().collect();
let _reagents: BTreeMap<i32, f64> = device.get_reagents().iter().copied().collect();
DeviceInfo {
connection_list: device
.connection_list()

View File

@@ -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<String, f64>>;
fn slot_class(&self) -> SlotClass;
fn slot_class(&self) -> Class;
fn sorting_class(&self) -> SortingClass;
fn get_parent_slot(&self) -> Option<ParentSlotInfo>;
fn set_parent_slot(&mut self, info: Option<ParentSlotInfo>);

View File

@@ -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" }

View File

@@ -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(&lt_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(&lt_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();
}

View File

@@ -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<RefCell<Device>>,
vm: Rc<RefCell<VM>>,
}
// #[wasm_bindgen]
// pub struct DeviceRef {
// device: Rc<RefCell<Device>>,
// vm: Rc<RefCell<VM>>,
// }
use thiserror::Error;
@@ -38,484 +40,476 @@ pub enum BindingError {
OutOfBounds(usize, usize),
}
#[wasm_bindgen]
impl DeviceRef {
fn from_device(device: Rc<RefCell<Device>>, vm: Rc<RefCell<VM>>) -> Self {
DeviceRef { device, vm }
}
#[wasm_bindgen(getter)]
pub fn id(&self) -> u32 {
self.device.borrow().id
}
#[wasm_bindgen(getter)]
pub fn ic(&self) -> Option<u32> {
self.device.borrow().ic
}
#[wasm_bindgen(getter)]
pub fn name(&self) -> Option<String> {
self.device.borrow().name.clone()
}
#[wasm_bindgen(getter, js_name = "nameHash")]
pub fn name_hash(&self) -> Option<i32> {
self.device.borrow().name_hash
}
#[wasm_bindgen(getter, js_name = "prefabName")]
pub fn prefab_name(&self) -> Option<String> {
self.device
.borrow()
.prefab
.as_ref()
.map(|prefab| prefab.name.clone())
}
#[wasm_bindgen(getter, js_name = "prefabHash")]
pub fn prefab_hash(&self) -> Option<i32> {
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<u32> {
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<u16> {
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<Stack> {
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<Registers> {
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<String> {
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<String> {
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<bool, JsError> {
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<bool, JsError> {
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<bool, JsError> {
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<bool, JsError> {
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<bool, JsError> {
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<f64, JsError> {
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<f64, JsError> {
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<f64, JsError> {
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<JsValue, JsError> {
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<u32>) -> 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<bool, JsError> {
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<u32>) -> Result<bool, JsError> {
let id = self.device.borrow().id;
Ok(self.vm.borrow().set_pin(id, pin, val)?)
}
}
// #[wasm_bindgen]
// impl DeviceRef {
// fn from_device(device: Rc<RefCell<Device>>, vm: Rc<RefCell<VM>>) -> Self {
// DeviceRef { device, vm }
// }
//
// #[wasm_bindgen(getter)]
// pub fn id(&self) -> ObjectID {
// self.device.id
// }
//
// #[wasm_bindgen(getter)]
// pub fn ic(&self) -> Option<ObjectID> {
// self.device.ic
// }
//
// #[wasm_bindgen(getter)]
// pub fn name(&self) -> Option<String> {
// self.device.name.clone()
// }
//
// #[wasm_bindgen(getter, js_name = "nameHash")]
// pub fn name_hash(&self) -> Option<i32> {
// self.device.name_hash
// }
//
// #[wasm_bindgen(getter, js_name = "prefabName")]
// pub fn prefab_name(&self) -> Option<String> {
// self.device
//
// .prefab
// .as_ref()
// .map(|prefab| prefab.name.clone())
// }
//
// #[wasm_bindgen(getter, js_name = "prefabHash")]
// pub fn prefab_hash(&self) -> Option<i32> {
// 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<ObjectID> {
// 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<u16> {
// 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<Stack> {
// 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<Registers> {
// 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<String> {
// 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<String> {
// 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<bool, JsError> {
// 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<bool, JsError> {
// let id = self.device.id;
// Ok(self.vm.run_ic(id, ignore_errors)?)
// }
//
// #[wasm_bindgen(js_name = "reset")]
// pub fn reset_ic(&self) -> Result<bool, JsError> {
// 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<bool, JsError> {
// 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<bool, JsError> {
// 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<f64, JsError> {
// 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<f64, JsError> {
// 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<f64, JsError> {
// 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<JsValue, JsError> {
// 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<ObjectID>) -> 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<bool, JsError> {
// 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<ObjectID>) -> Result<bool, JsError> {
// let id = self.device.id;
// Ok(self.vm.set_pin(id, pin, val)?)
// }
// }
#[wasm_bindgen]
#[derive(Debug)]
pub struct VMRef {
vm: Rc<RefCell<VM>>,
vm: Rc<VM>,
}
// #[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<u32>) -> Result<u32, JsError> {
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<u32, JsError> {
let template: DeviceTemplate = serde_wasm_bindgen::from_value(template)?;
#[wasm_bindgen(js_name = "addDeviceFromTemplate")]
pub fn add_device_from_template(&self, frozen: FrozenObject) -> Result<ObjectID, JsError> {
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<DeviceRef> {
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<VMObject> {
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<bool, JsError> {
Ok(self.vm.borrow().set_code(id, code)?)
pub fn set_code(&self, id: ObjectID, code: &str) -> Result<bool, JsError> {
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<bool, JsError> {
Ok(self.vm.borrow().set_code_invalid(id, code)?)
pub fn set_code_invalid(&self, id: ObjectID, code: &str) -> Result<bool, JsError> {
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<bool, JsError> {
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<bool, JsError> {
Ok(self.vm.borrow().run_ic(id, ignore_errors)?)
pub fn run_ic(&self, id: ObjectID, ignore_errors: bool) -> Result<bool, JsError> {
Ok(self.vm.run_programmable(id, ignore_errors)?)
}
#[wasm_bindgen(js_name = "resetIC")]
pub fn reset_ic(&self, id: u32) -> Result<bool, JsError> {
Ok(self.vm.borrow().reset_ic(id)?)
pub fn reset_ic(&self, id: ObjectID) -> Result<bool, JsError> {
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<u32> {
self.vm.borrow().devices.keys().copied().collect_vec()
}
#[wasm_bindgen(getter)]
pub fn networks(&self) -> Vec<u32> {
self.vm.borrow().networks.keys().copied().collect_vec()
}
#[wasm_bindgen(getter)]
pub fn ics(&self) -> Vec<u32> {
self.vm
.borrow()
.circuit_holders
.keys()
.copied()
.collect_vec()
}
// #[wasm_bindgen(getter)]
// pub fn devices(&self) -> Vec<ObjectID> {
// self.vm.devices.keys().copied().collect_vec()
// }
//
// #[wasm_bindgen(getter)]
// pub fn networks(&self) -> Vec<ObjectID> {
// self.vm.networks.keys().copied().collect_vec()
// }
//
// #[wasm_bindgen(getter)]
// pub fn ics(&self) -> Vec<ObjectID> {
// self.vm.circuit_holders.keys().copied().collect_vec()
// }
#[wasm_bindgen(getter, js_name = "lastOperationModified")]
pub fn last_operation_modified(&self) -> Vec<u32> {
self.vm.borrow().last_operation_modified()
pub fn last_operation_modified(&self) -> Vec<ObjectID> {
self.vm.last_operation_modified()
}
#[wasm_bindgen(js_name = "visibleDevices")]
pub fn visible_devices(&self, source: u32) -> Vec<u32> {
self.vm.borrow().visible_devices(source)
pub fn visible_devices(&self, source: ObjectID) -> Vec<u32> {
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<u32>,
network_id: Option<ObjectID>,
) -> Result<bool, JsError> {
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<bool, JsError> {
Ok(self
.vm
.borrow()
.remove_device_from_network(id, network_id)?)
pub fn remove_device_from_network(
&self,
id: ObjectID,
network_id: u32,
) -> Result<bool, JsError> {
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<u32>) -> Result<bool, JsError> {
Ok(self.vm.borrow().set_pin(id, pin, val)?)
pub fn set_pin(&self, id: ObjectID, pin: usize, val: Option<u32>) -> Result<bool, JsError> {
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<Option<ObjectID>, 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<Option<ObjectID>, 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<FrozenVM, JsError> {
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(())
}
}

View File

@@ -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());
}
}

View File

@@ -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<BTreeMap<String, f64>>,
pub slot_class: SlotClass,
pub slot_class: Class,
pub sorting_class: SortingClass,
}