refactor(wasm): remap wasm interface (rust side)
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -720,6 +720,7 @@ dependencies = [
|
||||
"serde-wasm-bindgen 0.6.5",
|
||||
"serde_derive",
|
||||
"serde_with",
|
||||
"stationeers_data",
|
||||
"strum",
|
||||
"thiserror",
|
||||
"tsify",
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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<_>, _>>()?,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user