refactor(wasm): remap wasm interface (rust side)

This commit is contained in:
Rachel Powers
2024-05-28 01:00:49 -07:00
parent 1843bdbfce
commit 7efcec9194
7 changed files with 351 additions and 375 deletions

1
Cargo.lock generated
View File

@@ -720,6 +720,7 @@ dependencies = [
"serde-wasm-bindgen 0.6.5",
"serde_derive",
"serde_with",
"stationeers_data",
"strum",
"thiserror",
"tsify",

View File

@@ -46,8 +46,12 @@ pub enum VMError {
NotAnItem(ObjectID),
#[error("object {0} is not programmable")]
NotProgrammable(ObjectID),
#[error("object {0} is not memory writable")]
NotMemoryWritable(ObjectID),
#[error("object {0} is not a circuit holder or programmable")]
NotCircuitHolderOrProgrammable(ObjectID),
#[error("object {0} is not a circuit holder or memory writable")]
NotCircuitHolderOrMemoryWritable(ObjectID),
#[error("object {0} is a circuit holder but there is no programmable ic present")]
NoIC(ObjectID),
#[error("{0}")]
@@ -56,6 +60,8 @@ pub enum VMError {
MissingChild(ObjectID),
#[error("object {0} is not parentable")]
NotParentable(ObjectID),
#[error("object {0} is not logicable")]
NotLogicable(ObjectID),
}
#[derive(Error, Debug, Serialize, Deserialize)]

View File

@@ -238,7 +238,7 @@ impl VM {
}
/// Creates a new network adn return it's ID
pub fn add_network(self: &Rc<Self>) -> u32 {
pub fn add_network(self: &Rc<Self>) -> ObjectID {
let next_id = self.network_id_space.borrow_mut().next();
self.networks.borrow_mut().insert(
next_id,
@@ -257,7 +257,7 @@ impl VM {
}
/// Get network form Id
pub fn get_network(self: &Rc<Self>, id: u32) -> Option<VMObject> {
pub fn get_network(self: &Rc<Self>, id: ObjectID) -> Option<VMObject> {
self.networks.borrow().get(&id).cloned()
}
@@ -265,7 +265,11 @@ impl VM {
///
/// Iterates over all objects borrowing them mutably, never call unless VM is not currently
/// stepping or you'll get reborrow panics
pub fn change_device_id(self: &Rc<Self>, old_id: u32, new_id: u32) -> Result<(), VMError> {
pub fn change_device_id(
self: &Rc<Self>,
old_id: ObjectID,
new_id: ObjectID,
) -> Result<(), VMError> {
if self.id_space.borrow().has_id(&new_id) {
return Err(VMError::IdInUse(new_id));
}
@@ -321,7 +325,7 @@ impl VM {
/// Set program code if it's valid
/// Object Id is the programmable Id or the circuit holder's id
pub fn set_code(self: &Rc<Self>, id: u32, code: &str) -> Result<bool, VMError> {
pub fn set_code(self: &Rc<Self>, id: ObjectID, code: &str) -> Result<bool, VMError> {
let obj = self
.objects
.borrow()
@@ -356,7 +360,7 @@ impl VM {
/// Set program code and translate invalid lines to Nop, collecting errors
/// Object Id is the programmable Id or the circuit holder's id
pub fn set_code_invalid(self: &Rc<Self>, id: u32, code: &str) -> Result<bool, VMError> {
pub fn set_code_invalid(self: &Rc<Self>, id: ObjectID, code: &str) -> Result<bool, VMError> {
let obj = self
.objects
.borrow()
@@ -389,6 +393,143 @@ impl VM {
Err(VMError::NoIC(id))
}
/// Set register of integrated circuit
/// Object Id is the circuit Id or the circuit holder's id
pub fn set_register(
self: &Rc<Self>,
id: ObjectID,
index: u32,
val: f64,
) -> Result<f64, VMError> {
let obj = self
.objects
.borrow()
.get(&id)
.cloned()
.ok_or(VMError::UnknownId(id))?;
{
let mut obj_ref = obj.borrow_mut();
if let Some(circuit) = obj_ref.as_mut_integrated_circuit() {
let last = circuit.set_register(0, index, val)?;
return Ok(last);
}
}
let ic_obj = {
let obj_ref = obj.borrow();
if let Some(circuit_holder) = obj_ref.as_circuit_holder() {
circuit_holder.get_ic()
} else {
return Err(VMError::NotCircuitHolderOrProgrammable(id));
}
};
if let Some(ic_obj) = ic_obj {
let mut ic_obj_ref = ic_obj.borrow_mut();
if let Some(circuit) = ic_obj_ref.as_mut_integrated_circuit() {
let last = circuit.set_register(0, index, val)?;
return Ok(last);
}
return Err(VMError::NotProgrammable(*ic_obj_ref.get_id()));
}
Err(VMError::NoIC(id))
}
/// Set memory at address of object with memory
/// Object Id is the memory writable Id or the circuit holder's id
pub fn set_memory(
self: &Rc<Self>,
id: ObjectID,
address: u32,
val: f64,
) -> Result<f64, VMError> {
let obj = self
.objects
.borrow()
.get(&id)
.cloned()
.ok_or(VMError::UnknownId(id))?;
{
let mut obj_ref = obj.borrow_mut();
if let Some(circuit) = obj_ref.as_mut_memory_writable() {
let last = circuit
.get_memory(address as i32)
.map_err(Into::<ICError>::into)?;
circuit
.set_memory(address as i32, val)
.map_err(Into::<ICError>::into)?;
return Ok(last);
}
}
let ic_obj = {
let obj_ref = obj.borrow();
if let Some(circuit_holder) = obj_ref.as_circuit_holder() {
circuit_holder.get_ic()
} else {
None
}
};
if let Some(ic_obj) = ic_obj {
let mut ic_obj_ref = ic_obj.borrow_mut();
if let Some(circuit) = ic_obj_ref.as_mut_memory_writable() {
let last = circuit
.get_memory(address as i32)
.map_err(Into::<ICError>::into)?;
circuit
.set_memory(address as i32, val)
.map_err(Into::<ICError>::into)?;
return Ok(last);
}
return Err(VMError::NotMemoryWritable(*ic_obj_ref.get_id()));
}
Err(VMError::NotCircuitHolderOrMemoryWritable(id))
}
/// Set logic field on a logicable object
pub fn set_logic_field(
self: &Rc<Self>,
id: ObjectID,
lt: LogicType,
val: f64,
force: bool,
) -> Result<(), VMError> {
let obj = self
.objects
.borrow()
.get(&id)
.cloned()
.ok_or(VMError::UnknownId(id))?;
let mut obj_ref = obj.borrow_mut();
let logicable = obj_ref
.as_mut_logicable()
.ok_or(VMError::NotLogicable(id))?;
logicable
.set_logic(lt, val, force)
.map_err(Into::<ICError>::into)?;
Ok(())
}
/// Set slot logic filed on device object
pub fn set_slot_logic_field(
self: &Rc<Self>,
id: ObjectID,
slt: LogicSlotType,
index: u32,
val: f64,
force: bool,
) -> Result<(), VMError> {
let obj = self
.objects
.borrow()
.get(&id)
.cloned()
.ok_or(VMError::UnknownId(id))?;
let mut obj_ref = obj.borrow_mut();
let device = obj_ref.as_mut_device().ok_or(VMError::NotLogicable(id))?;
device
.set_slot_logic(slt, index as f64, val, force)
.map_err(Into::<ICError>::into)?;
Ok(())
}
/// returns a list of device ids modified in the last operations
pub fn last_operation_modified(self: &Rc<Self>) -> Vec<u32> {
self.operation_modified.borrow().clone()
@@ -396,7 +537,7 @@ impl VM {
pub fn step_programmable(
self: &Rc<Self>,
id: u32,
id: ObjectID,
advance_ip_on_err: bool,
) -> Result<(), VMError> {
let obj = self
@@ -440,7 +581,7 @@ impl VM {
/// returns true if executed 128 lines, false if returned early.
pub fn run_programmable(
self: &Rc<Self>,
id: u32,
id: ObjectID,
ignore_errors: bool,
) -> Result<bool, VMError> {
let obj = self
@@ -573,7 +714,11 @@ impl VM {
}
}
pub fn get_network_channel(self: &Rc<Self>, id: u32, channel: usize) -> Result<f64, ICError> {
pub fn get_network_channel(
self: &Rc<Self>,
id: ObjectID,
channel: usize,
) -> Result<f64, ICError> {
let network = self
.networks
.borrow()
@@ -653,7 +798,7 @@ impl VM {
pub fn set_pin(
self: &Rc<Self>,
id: u32,
id: ObjectID,
pin: usize,
val: Option<ObjectID>,
) -> Result<bool, VMError> {
@@ -1071,6 +1216,13 @@ impl VM {
Ok(last)
}
pub fn freeze_object(self: &Rc<Self>, id: ObjectID) -> Result<FrozenObject, VMError> {
let Some(obj) = self.objects.borrow().get(&id).cloned() else {
return Err(VMError::UnknownId(id));
};
Ok(FrozenObject::freeze_object(&obj, self)?)
}
pub fn save_vm_state(self: &Rc<Self>) -> Result<FrozenVM, TemplateError> {
Ok(FrozenVM {
objects: self
@@ -1085,7 +1237,7 @@ impl VM {
{
None
} else {
Some(FrozenObject::freeze_object(obj, self))
Some(FrozenObject::freeze_object_sparse(obj, self))
}
})
.collect::<Result<Vec<_>, _>>()?,

View File

@@ -5,8 +5,9 @@ version.workspace = true
edition.workspace = true
[dependencies]
stationeers_data = { path = "../stationeers_data", features = ["tsify"] }
ic10emu = { path = "../ic10emu", features = ["tsify"] }
console_error_panic_hook = {version = "0.1.7", optional = true}
console_error_panic_hook = { version = "0.1.7", optional = true }
js-sys = "0.3.69"
web-sys = { version = "0.3.69", features = ["WritableStream", "console"] }
wasm-bindgen = "0.2.92"
@@ -24,12 +25,42 @@ serde_derive = "1.0.203"
[build-dependencies]
ic10emu = { path = "../ic10emu" }
strum = { version = "0.26.2"}
strum = { version = "0.26.2" }
itertools = "0.13.0"
[features]
default = ["console_error_panic_hook"]
console_error_panic_hook = ["dep:console_error_panic_hook"]
prefab_database = [
"ic10emu/prefab_database",
"stationeers_data/prefab_database",
]
[lib]
crate-type = ["cdylib", "rlib"]
[profile.release]
# Tell `rustc` to optimize for small code size.
opt-level = "s"
[package.metadata.wasm-pack.profile.dev]
wasm-opt = ['-O']
[package.metadata.wasm-pack.profile.dev.wasm-bindgen]
# Should we enable wasm-bindgen's debug assertions in its generated JS glue?
debug-js-glue = true
# Should wasm-bindgen demangle the symbols in the "name" custom section?
demangle-name-section = true
# Should we emit the DWARF debug info custom sections?
dwarf-debug-info = false
# Should we omit the default import path?
omit-default-module-path = false
[package.metadata.wasm-pack.profile.release]
wasm-opt = ['-Os']
[package.metadata.wasm-pack.profile.release.wasm-bindgen]
debug-js-glue = false
demangle-name-section = true
dwarf-debug-info = false
omit-default-module-path = false

View File

@@ -1,12 +1,7 @@
use std::{
env,
fs::{self, File},
io::{BufWriter, Write},
path::Path,
};
use itertools::Itertools;
use strum::IntoEnumIterator;
fn main() {
// let out_dir = env::var_os("OUT_DIR").unwrap();

View File

@@ -3,20 +3,19 @@ mod utils;
// mod types;
use ic10emu::{
errors::{TemplateError, VMError},
errors::VMError,
vm::{
object::{templates::FrozenObject, ObjectID, VMObject},
FrozenVM, VM,
},
};
use serde_derive::{Deserialize, Serialize};
// use types::{Registers, Stack};
use std::{cell::RefCell, rc::Rc, str::FromStr};
use itertools::Itertools;
// use std::iter::FromIterator;
// use itertools::Itertools;
use serde_derive::{Deserialize, Serialize};
use stationeers_data::enums::script::{LogicSlotType, LogicType};
use std::rc::Rc;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
@@ -24,12 +23,6 @@ extern "C" {
fn alert(s: &str);
}
// #[wasm_bindgen]
// pub struct DeviceRef {
// device: Rc<RefCell<Device>>,
// vm: Rc<RefCell<VM>>,
// }
use thiserror::Error;
#[derive(Error, Debug, Serialize, Deserialize)]
@@ -40,330 +33,12 @@ 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) -> 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<VM>,
}
// #[wasm_bindgen]
// pub struct ObjectRef(VMObject);
#[wasm_bindgen]
impl VMRef {
#[wasm_bindgen(constructor)]
@@ -382,9 +57,12 @@ impl VMRef {
#[wasm_bindgen(js_name = "getDevice")]
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
self.vm.get_object(id)
}
#[wasm_bindgen(js_name = "freezeDevice")]
pub fn freeze_object(&self, id: ObjectID) -> Result<FrozenObject, JsError> {
Ok(self.vm.freeze_object(id)?)
}
#[wasm_bindgen(js_name = "setCode")]
@@ -399,17 +77,17 @@ impl VMRef {
Ok(self.vm.set_code_invalid(id, code)?)
}
#[wasm_bindgen(js_name = "stepIC")]
pub fn step_ic(&self, id: ObjectID, advance_ip_on_err: bool) -> Result<(), JsError> {
#[wasm_bindgen(js_name = "stepProgrammable")]
pub fn step_programmable(&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: ObjectID, ignore_errors: bool) -> Result<bool, JsError> {
#[wasm_bindgen(js_name = "runProgrammable")]
pub fn run_programmable(&self, id: ObjectID, ignore_errors: bool) -> Result<bool, JsError> {
Ok(self.vm.run_programmable(id, ignore_errors)?)
}
#[wasm_bindgen(js_name = "resetIC")]
#[wasm_bindgen(js_name = "resetProgrammable")]
pub fn reset_ic(&self, id: ObjectID) -> Result<bool, JsError> {
Ok(self.vm.reset_programmable(id)?)
}
@@ -419,20 +97,25 @@ impl VMRef {
*self.vm.default_network_key.borrow()
}
// #[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)]
pub fn objects(&self) -> Vec<ObjectID> {
self.vm.objects.borrow().keys().copied().collect_vec()
}
#[wasm_bindgen(getter)]
pub fn networks(&self) -> Vec<ObjectID> {
self.vm.networks.borrow().keys().copied().collect_vec()
}
#[wasm_bindgen(getter)]
pub fn circuit_holders(&self) -> Vec<ObjectID> {
self.vm.circuit_holders.borrow().clone()
}
#[wasm_bindgen(getter)]
pub fn program_holders(&self) -> Vec<ObjectID> {
self.vm.program_holders.borrow().clone()
}
#[wasm_bindgen(getter, js_name = "lastOperationModified")]
pub fn last_operation_modified(&self) -> Vec<ObjectID> {
@@ -498,7 +181,11 @@ impl VMRef {
}
#[wasm_bindgen(js_name = "removeSlotOccupant")]
pub fn remove_slot_occupant(&self, id: ObjectID, index: usize) -> Result<Option<ObjectID>, JsError> {
pub fn remove_slot_occupant(
&self,
id: ObjectID,
index: usize,
) -> Result<Option<ObjectID>, JsError> {
Ok(self.vm.remove_slot_occupant(id, index)?)
}
@@ -512,6 +199,84 @@ impl VMRef {
self.vm.restore_vm_state(state)?;
Ok(())
}
#[wasm_bindgen(js_name = "getObjectName")]
pub fn get_object_name(&self, id: ObjectID) -> Result<String, JsError> {
let obj = self.vm.get_object(id).ok_or(VMError::UnknownId(id))?;
let name = obj.borrow().get_name().value.clone();
Ok(name)
}
#[wasm_bindgen(js_name = "setObjectName")]
pub fn set_object_name(&self, id: ObjectID, name: &str) -> Result<(), JsError> {
let obj = self.vm.get_object(id).ok_or(VMError::UnknownId(id))?;
obj.borrow_mut().get_mut_name().value = name.to_string();
Ok(())
}
#[wasm_bindgen(js_name = "getObjectHash")]
pub fn get_object_hash(&self, id: ObjectID) -> Result<i32, JsError> {
let obj = self.vm.get_object(id).ok_or(VMError::UnknownId(id))?;
let hash = obj.borrow().get_name().hash;
Ok(hash)
}
#[wasm_bindgen(js_name = "getObjectPrefabName")]
pub fn get_object_prefab_name(&self, id: ObjectID) -> Result<String, JsError> {
let obj = self.vm.get_object(id).ok_or(VMError::UnknownId(id))?;
let name = obj.borrow().get_prefab().value.clone();
Ok(name)
}
#[wasm_bindgen(js_name = "getObjectPrefabHash")]
pub fn get_object_prefab_hash(&self, id: ObjectID) -> Result<i32, JsError> {
let obj = self.vm.get_object(id).ok_or(VMError::UnknownId(id))?;
let hash = obj.borrow().get_prefab().hash;
Ok(hash)
}
#[wasm_bindgen(js_name = "getObjectSourceCode")]
pub fn get_object_source_code(&self, id: ObjectID) -> Result<Option<String>, JsError> {
let obj = self.vm.get_object(id).ok_or(VMError::UnknownId(id))?;
let code = obj
.borrow()
.as_source_code()
.map(|source| source.get_source_code());
Ok(code)
}
#[wasm_bindgen(js_name = "setRegister")]
pub fn set_register(&self, id: ObjectID, index: u32, val: f64) -> Result<f64, JsError> {
Ok(self.vm.set_register(id, index, val)?)
}
#[wasm_bindgen(js_name = "setMemory")]
pub fn set_memory(&self, id: ObjectID, address: u32, val: f64) -> Result<f64, JsError> {
Ok(self.vm.set_memory(id, address, val)?)
}
#[wasm_bindgen(js_name = "setLogicField")]
pub fn set_logic_field(
&self,
id: ObjectID,
lt: LogicType,
val: f64,
force: bool,
) -> Result<(), JsError> {
Ok(self.vm.set_logic_field(id, lt, val, force)?)
}
#[wasm_bindgen(js_name = "setSlotLogicField")]
pub fn set_slot_logic_field(
&self,
id: ObjectID,
slt: LogicSlotType,
index: u32,
val: f64,
force: bool,
) -> Result<(), JsError> {
Ok(self.vm.set_slot_logic_field(id, slt, index, val, force)?)
}
}
impl Default for VMRef {

View File

@@ -27,3 +27,29 @@ wasm-streams = "0.4"
# web-tree-sitter-sys = "1.3"
ic10lsp = { git = "https://github.com/Ryex/ic10lsp.git", branch = "wasm" }
# ic10lsp = { path = "../../ic10lsp" }
[profile.release]
# Tell `rustc` to optimize for small code size.
opt-level = "s"
[package.metadata.wasm-pack.profile.dev]
wasm-opt = ['-O']
[package.metadata.wasm-pack.profile.dev.wasm-bindgen]
# Should we enable wasm-bindgen's debug assertions in its generated JS glue?
debug-js-glue = true
# Should wasm-bindgen demangle the symbols in the "name" custom section?
demangle-name-section = true
# Should we emit the DWARF debug info custom sections?
dwarf-debug-info = false
# Should we omit the default import path?
omit-default-module-path = false
[package.metadata.wasm-pack.profile.release]
wasm-opt = ['-Oz']
[package.metadata.wasm-pack.profile.release.wasm-bindgen]
debug-js-glue = false
demangle-name-section = true
dwarf-debug-info = false
omit-default-module-path = false