refactor(vm): cleanup, trait docs, reenable interpreter tests

This commit is contained in:
Rachel Powers
2024-05-27 22:12:06 -07:00
parent dae6be9f4a
commit 1843bdbfce
33 changed files with 50351 additions and 51177 deletions

1
Cargo.lock generated
View File

@@ -688,6 +688,7 @@ dependencies = [
"color-eyre",
"const-crc32",
"getrandom",
"ic10emu",
"itertools",
"macro_rules_attribute",
"paste",

View File

@@ -45,5 +45,12 @@ time = { version = "0.3.36", features = [
color-eyre = "0.6.3"
serde_json = "1.0.117"
# Self dev dependency to enable prefab_database feature for tests
ic10emu = { path = ".", features = ["prefab_database"] }
[features]
default = []
tsify = ["dep:tsify", "dep:wasm-bindgen", "stationeers_data/tsify"]
prefab_database = [
"stationeers_data/prefab_database",
] # compile with the prefab database enabled

View File

@@ -16,15 +16,12 @@ use tsify::Tsify;
use wasm_bindgen::prelude::*;
#[derive(Error, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub enum VMError {
#[error("device with id '{0}' does not exist")]
UnknownId(u32),
UnknownId(ObjectID),
#[error("ic with id '{0}' does not exist")]
UnknownIcId(u32),
#[error("device with id '{0}' does not have a ic slot")]
NoIC(u32),
UnknownIcId(ObjectID),
#[error("ic encountered an error: {0}")]
ICError(#[from] ICError),
#[error("ic encountered an error: {0}")]
@@ -49,6 +46,10 @@ pub enum VMError {
NotAnItem(ObjectID),
#[error("object {0} is not programmable")]
NotProgrammable(ObjectID),
#[error("object {0} is not a circuit holder or programmable")]
NotCircuitHolderOrProgrammable(ObjectID),
#[error("object {0} is a circuit holder but there is no programmable ic present")]
NoIC(ObjectID),
#[error("{0}")]
TemplateError(#[from] TemplateError),
#[error("missing child object {0}")]
@@ -58,8 +59,7 @@ pub enum VMError {
}
#[derive(Error, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub enum TemplateError {
#[error("object id {0} has a non conforming set of interfaces")]
NonConformingObject(ObjectID),
@@ -77,8 +77,7 @@ pub enum TemplateError {
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct LineError {
pub error: ICError,
pub line: u32,
@@ -93,8 +92,7 @@ impl Display for LineError {
impl StdError for LineError {}
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct ParseError {
pub line: usize,
pub start: usize,
@@ -147,8 +145,7 @@ impl ParseError {
}
#[derive(Debug, Error, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub enum ICError {
#[error("error compiling code: {0}")]
ParseError(#[from] ParseError),

View File

@@ -1,5 +1,5 @@
use crate::{
errors::{ParseError},
errors::ParseError,
interpreter,
tokens::{SplitConsecutiveIndicesExt, SplitConsecutiveWithIndices},
vm::instructions::{
@@ -14,7 +14,6 @@ use stationeers_data::enums::{
script::{LogicBatchMethod, LogicReagentMode, LogicSlotType, LogicType},
};
use std::{fmt::Display, str::FromStr};
use strum::IntoEnumIterator;
pub fn parse(code: &str) -> Result<Vec<Line>, ParseError> {
code.lines()

View File

@@ -23,8 +23,7 @@ use crate::{
pub mod instructions;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub enum ICState {
Start,
Running,
@@ -39,8 +38,7 @@ pub enum ICState {
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct ICInfo {
pub instruction_pointer: u32,
pub registers: Vec<f64>,
@@ -74,8 +72,7 @@ impl Display for ICState {
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct Program {
pub instructions: Vec<Instruction>,
pub errors: Vec<ICError>,
@@ -214,87 +211,166 @@ pub fn i64_to_f64(i: i64) -> f64 {
#[cfg(test)]
mod tests {
use std::rc::Rc;
// static INIT: std::sync::Once = std::sync::Once::new();
//
// fn setup() {
// INIT.call_once(|| {
// let _ = color_eyre::install();
// })
// }
//
// #[test]
// fn batch_modes() -> color_eyre::Result<()> {
// setup();
// let mut vm = VM::new();
// let ic = vm.add_ic(None).unwrap();
// let ic_id = {
// let device = vm.devices.get(&ic).unwrap();
// let device_ref = device.borrow();
// device_ref.ic.unwrap()
// };
// let ic_chip = vm.circuit_holders.get(&ic_id).unwrap().borrow();
// vm.set_code(
// ic,
// r#"lb r0 HASH("ItemActiveVent") On Sum
// lb r1 HASH("ItemActiveVent") On Maximum
// lb r2 HASH("ItemActiveVent") On Minimum"#,
// )?;
// vm.step_ic(ic, false)?;
// let r0 = ic_chip.get_register(0, 0).unwrap();
// assert_eq!(r0, 0.0);
// vm.step_ic(ic, false)?;
// let r1 = ic_chip.get_register(0, 1).unwrap();
// assert_eq!(r1, f64::NEG_INFINITY);
// vm.step_ic(ic, false)?;
// let r2 = ic_chip.get_register(0, 2).unwrap();
// assert_eq!(r2, f64::INFINITY);
// Ok(())
// }
//
// #[test]
// fn stack() -> color_eyre::Result<()> {
// setup();
// let mut vm = VM::new();
// let ic = vm.add_ic(None).unwrap();
// let ic_id = {
// let device = vm.devices.get(&ic).unwrap();
// let device_ref = device.borrow();
// device_ref.ic.unwrap()
// };
// let ic_chip = vm.circuit_holders.get(&ic_id).unwrap().borrow();
// vm.set_code(
// ic,
// r#"push 100
// push 10
// pop r0
// push 1000
// peek r1
// poke 1 20
// pop r2
// "#,
// )?;
// vm.step_ic(ic, false)?;
// let stack0 = ic_chip.peek_addr(0.0)?;
// assert_eq!(stack0, 100.0);
// vm.step_ic(ic, false)?;
// let stack1 = ic_chip.peek_addr(1.0)?;
// assert_eq!(stack1, 10.0);
// vm.step_ic(ic, false)?;
// let r0 = ic_chip.get_register(0, 0).unwrap();
// assert_eq!(r0, 10.0);
// vm.step_ic(ic, false)?;
// let stack1 = ic_chip.peek_addr(1.0)?;
// assert_eq!(stack1, 1000.0);
// vm.step_ic(ic, false)?;
// let r1 = ic_chip.get_register(0, 1).unwrap();
// assert_eq!(r1, 1000.0);
// vm.step_ic(ic, false)?;
// let stack1 = ic_chip.peek_addr(1.0)?;
// assert_eq!(stack1, 20.0);
// vm.step_ic(ic, false)?;
// let r2 = ic_chip.get_register(0, 2).unwrap();
// assert_eq!(r2, 20.0);
// Ok(())
// }
use stationeers_data::enums::prefabs::StationpediaPrefab;
use crate::vm::{
object::{
templates::{FrozenObject, ObjectInfo, Prefab},
ObjectID,
},
VM,
};
static INIT: std::sync::Once = std::sync::Once::new();
fn setup() -> color_eyre::Result<(Rc<VM>, ObjectID, ObjectID)> {
INIT.call_once(|| {
let _ = color_eyre::install();
});
println!("building VM");
let vm = VM::new();
println!("VM built");
let frozen_ic = FrozenObject {
obj_info: ObjectInfo::with_prefab(Prefab::Hash(
StationpediaPrefab::ItemIntegratedCircuit10 as i32,
)),
database_template: true,
template: None,
};
println!("Adding IC");
let ic = vm.add_object_from_frozen(frozen_ic)?;
let frozen_circuit_holder = FrozenObject {
obj_info: ObjectInfo::with_prefab(Prefab::Hash(
StationpediaPrefab::StructureCircuitHousing as i32,
)),
database_template: true,
template: None,
};
println!("Adding circuit holder");
let ch = vm.add_object_from_frozen(frozen_circuit_holder)?;
println!("socketing ic into circuit holder");
vm.set_slot_occupant(ch, 0, Some(ic), 1)?;
Ok((vm, ch, ic))
}
#[test]
fn batch_modes() -> color_eyre::Result<()> {
let (vm, ch, ic) = setup()?;
eprintln!("Beginning batch mode test");
let ic_chip = vm.get_object(ic).unwrap();
let circuit_holder = vm.get_object(ch).unwrap();
eprintln!("IC Chip: {ic_chip:?}");
eprintln!("Circuit Holder: {circuit_holder:?}");
vm.set_code(
ic,
r#"lb r0 HASH("ItemActiveVent") On Sum
lb r1 HASH("ItemActiveVent") On Maximum
lb r2 HASH("ItemActiveVent") On Minimum"#,
)?;
vm.step_programmable(ic, false)?;
let r0 = ic_chip
.borrow()
.as_integrated_circuit()
.unwrap()
.get_register(0, 0)
.unwrap();
assert_eq!(r0, 0.0);
vm.step_programmable(ic, false)?;
let r1 = ic_chip
.borrow()
.as_integrated_circuit()
.unwrap()
.get_register(0, 1)
.unwrap();
assert_eq!(r1, f64::NEG_INFINITY);
vm.step_programmable(ic, false)?;
let r2 = ic_chip
.borrow()
.as_integrated_circuit()
.unwrap()
.get_register(0, 2)
.unwrap();
assert_eq!(r2, f64::INFINITY);
Ok(())
}
#[test]
fn stack() -> color_eyre::Result<()> {
let (vm, ch, ic) = setup()?;
eprintln!("Beginning stack test");
let ic_chip = vm.get_object(ic).unwrap();
let circuit_holder = vm.get_object(ch).unwrap();
eprintln!("IC Chip: {ic_chip:?}");
eprintln!("Circuit Holder: {circuit_holder:?}");
vm.set_code(
ic,
r#"push 100
push 10
pop r0
push 1000
peek r1
poke 1 20
pop r2
"#,
)?;
vm.step_programmable(ic, false)?;
let stack0 = ic_chip
.borrow()
.as_integrated_circuit()
.unwrap()
.get_stack(0.0)?;
assert_eq!(stack0, 100.0);
vm.step_programmable(ic, false)?;
let stack1 = ic_chip
.borrow()
.as_integrated_circuit()
.unwrap()
.get_stack(1.0)?;
assert_eq!(stack1, 10.0);
vm.step_programmable(ic, false)?;
let r0 = ic_chip
.borrow()
.as_integrated_circuit()
.unwrap()
.get_register(0, 0)
.unwrap();
assert_eq!(r0, 10.0);
vm.step_programmable(ic, false)?;
let stack1 = ic_chip
.borrow()
.as_integrated_circuit()
.unwrap()
.get_stack(1.0)?;
assert_eq!(stack1, 1000.0);
vm.step_programmable(ch, false)?;
let r1 = ic_chip
.borrow()
.as_integrated_circuit()
.unwrap()
.get_register(0, 1)
.unwrap();
assert_eq!(r1, 1000.0);
vm.step_programmable(ch, false)?;
let stack1 = ic_chip
.borrow()
.as_integrated_circuit()
.unwrap()
.get_stack(1.0)?;
assert_eq!(stack1, 20.0);
vm.step_programmable(ch, false)?;
let r2 = ic_chip
.borrow()
.as_integrated_circuit()
.unwrap()
.get_register(0, 2)
.unwrap();
assert_eq!(r2, 20.0);
Ok(())
}
}

View File

@@ -2124,8 +2124,8 @@ impl<T: IC10Marker> ClrInstruction for T {
obj_ref
.as_mut_memory_writable()
.ok_or(MemoryError::NotWriteable)?
.clear_memory()
.map_err(Into::into)
.clear_memory();
Ok(())
})
})?;
Ok(())
@@ -2147,8 +2147,8 @@ impl<T: IC10Marker> ClrdInstruction for T {
obj_ref
.as_mut_memory_writable()
.ok_or(MemoryError::NotWriteable)?
.clear_memory()
.map_err(Into::into)
.clear_memory();
Ok(())
})
})?;
Ok(())

View File

@@ -19,8 +19,7 @@ use tsify::Tsify;
use wasm_bindgen::prelude::*;
#[derive(Debug, Default, Clone, Copy, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub enum CableConnectionType {
Power,
Data,
@@ -29,8 +28,7 @@ pub enum CableConnectionType {
}
#[derive(Debug, Default, Clone, Copy, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub enum Connection {
CableNetwork {
net: Option<ObjectID>,
@@ -345,8 +343,7 @@ impl Network for CableNetwork {
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct FrozenCableNetwork {
pub id: ObjectID,
pub devices: Vec<u32>,

View File

@@ -73,6 +73,7 @@ struct VMTransaction {
}
impl VM {
/// Create a new VM with it's own state and a default network
pub fn new() -> Rc<Self> {
let id_space = IdSpace::default();
let mut network_id_space = IdSpace::default();
@@ -102,10 +103,14 @@ impl VM {
vm
}
/// get a random f64 value using a mscorlib rand PRNG
/// (Stationeers, being written in .net, using mscorlib's rand)
pub fn random_f64(&self) -> f64 {
self.random.borrow_mut().next_f64()
}
/// Take ownership of an iterable the produces (prefab hash, ObjectTemplate) pairs and build a prefab
/// database
pub fn import_template_database(
&mut self,
db: impl IntoIterator<Item = (i32, ObjectTemplate)>,
@@ -113,6 +118,7 @@ impl VM {
self.template_database.replace(db.into_iter().collect());
}
/// Get a Object Template by either prefab name or hash
pub fn get_template(&self, prefab: Prefab) -> Option<ObjectTemplate> {
let hash = match prefab {
Prefab::Hash(hash) => hash,
@@ -123,6 +129,9 @@ impl VM {
.and_then(|db| db.get(&hash).cloned())
}
/// Add an number of object to the VM state using Frozen Object strusts.
/// See also `add_objects_frozen`
/// Returns the built objects' IDs
pub fn add_objects_frozen(
self: &Rc<Self>,
frozen_objects: impl IntoIterator<Item = FrozenObject>,
@@ -175,6 +184,11 @@ impl VM {
Ok(obj_ids)
}
/// Add an object to the VM state using a frozen object struct
/// Errors if the frozen object does not provide a template and the prefab has is not in the
/// current database.
/// Errors if the object can not be built do to a template error
/// Returns the built object's ID
pub fn add_object_from_frozen(
self: &Rc<Self>,
frozen: FrozenObject,
@@ -223,6 +237,7 @@ impl VM {
Ok(obj_id)
}
/// Creates a new network adn return it's ID
pub fn add_network(self: &Rc<Self>) -> u32 {
let next_id = self.network_id_space.borrow_mut().next();
self.networks.borrow_mut().insert(
@@ -232,6 +247,7 @@ impl VM {
next_id
}
/// Get Id of default network
pub fn get_default_network(self: &Rc<Self>) -> VMObject {
self.networks
.borrow()
@@ -240,12 +256,15 @@ impl VM {
.expect("default network not present")
}
/// Get network form Id
pub fn get_network(self: &Rc<Self>, id: u32) -> Option<VMObject> {
self.networks.borrow().get(&id).cloned()
}
/// iterate over all object borrowing them mutably, never call unless VM is not currently
/// stepping
/// Change an object's ID
///
/// 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> {
if self.id_space.borrow().has_id(&new_id) {
return Err(VMError::IdInUse(new_id));
@@ -301,6 +320,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> {
let obj = self
.objects
@@ -308,15 +328,34 @@ impl VM {
.get(&id)
.cloned()
.ok_or(VMError::UnknownId(id))?;
let mut obj_ref = obj.borrow_mut();
let programmable = obj_ref
.as_mut_programmable()
.ok_or(VMError::NotProgrammable(id))?;
programmable.set_source_code(code)?;
Ok(true)
{
let mut obj_ref = obj.borrow_mut();
if let Some(programmable) = obj_ref.as_mut_programmable() {
programmable.set_source_code(code)?;
return Ok(true);
}
}
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(programmable) = ic_obj_ref.as_mut_programmable() {
programmable.set_source_code(code)?;
return Ok(true);
}
return Err(VMError::NotProgrammable(*ic_obj_ref.get_id()));
}
Err(VMError::NoIC(id))
}
/// 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> {
let obj = self
.objects
@@ -324,12 +363,30 @@ impl VM {
.get(&id)
.cloned()
.ok_or(VMError::UnknownId(id))?;
let mut obj_ref = obj.borrow_mut();
let programmable = obj_ref
.as_mut_programmable()
.ok_or(VMError::NotProgrammable(id))?;
programmable.set_source_code_with_invalid(code);
Ok(true)
{
let mut obj_ref = obj.borrow_mut();
if let Some(programmable) = obj_ref.as_mut_programmable() {
programmable.set_source_code_with_invalid(code);
return Ok(true);
}
}
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(programmable) = ic_obj_ref.as_mut_programmable() {
programmable.set_source_code_with_invalid(code);
return Ok(true);
}
return Err(VMError::NotProgrammable(*ic_obj_ref.get_id()));
}
Err(VMError::NoIC(id))
}
/// returns a list of device ids modified in the last operations
@@ -348,14 +405,36 @@ impl VM {
.get(&id)
.cloned()
.ok_or(VMError::UnknownId(id))?;
let mut obj_ref = obj.borrow_mut();
let programmable = obj_ref
.as_mut_programmable()
.ok_or(VMError::NotProgrammable(id))?;
self.operation_modified.borrow_mut().clear();
self.set_modified(id);
programmable.step(advance_ip_on_err)?;
Ok(())
{
let mut obj_ref = obj.borrow_mut();
if let Some(programmable) = obj_ref.as_mut_programmable() {
self.operation_modified.borrow_mut().clear();
self.set_modified(id);
programmable.step(advance_ip_on_err)?;
return Ok(());
}
}
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();
let ic_id = *ic_obj_ref.get_id();
if let Some(programmable) = ic_obj_ref.as_mut_programmable() {
self.operation_modified.borrow_mut().clear();
self.set_modified(ic_id);
programmable.step(advance_ip_on_err)?;
return Ok(());
}
return Err(VMError::NotProgrammable(ic_id));
}
Err(VMError::NoIC(id))
}
/// returns true if executed 128 lines, false if returned early.
@@ -370,28 +449,63 @@ impl VM {
.get(&id)
.cloned()
.ok_or(VMError::UnknownId(id))?;
let mut obj_ref = obj.borrow_mut();
let programmable = obj_ref
.as_mut_programmable()
.ok_or(VMError::NotProgrammable(id))?;
self.operation_modified.borrow_mut().clear();
self.set_modified(id);
for _i in 0..128 {
if let Err(err) = programmable.step(ignore_errors) {
if !ignore_errors {
return Err(err.into());
{
let mut obj_ref = obj.borrow_mut();
if let Some(programmable) = obj_ref.as_mut_programmable() {
self.operation_modified.borrow_mut().clear();
self.set_modified(id);
for _i in 0..128 {
if let Err(err) = programmable.step(ignore_errors) {
if !ignore_errors {
return Err(err.into());
}
}
match programmable.get_state() {
ICState::Yield => return Ok(false),
ICState::Sleep(_then, _sleep_for) => return Ok(false),
ICState::HasCaughtFire => return Ok(false),
ICState::Error(_) if !ignore_errors => return Ok(false),
_ => {}
}
}
}
match programmable.get_state() {
ICState::Yield => return Ok(false),
ICState::Sleep(_then, _sleep_for) => return Ok(false),
ICState::HasCaughtFire => return Ok(false),
ICState::Error(_) if !ignore_errors => return Ok(false),
_ => {}
programmable.set_state(ICState::Yield);
return Ok(true);
}
}
programmable.set_state(ICState::Yield);
Ok(true)
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();
let ic_id = *ic_obj_ref.get_id();
if let Some(programmable) = ic_obj_ref.as_mut_programmable() {
self.operation_modified.borrow_mut().clear();
self.set_modified(ic_id);
for _i in 0..128 {
if let Err(err) = programmable.step(ignore_errors) {
if !ignore_errors {
return Err(err.into());
}
}
match programmable.get_state() {
ICState::Yield => return Ok(false),
ICState::Sleep(_then, _sleep_for) => return Ok(false),
ICState::HasCaughtFire => return Ok(false),
ICState::Error(_) if !ignore_errors => return Ok(false),
_ => {}
}
}
programmable.set_state(ICState::Yield);
return Ok(true);
}
return Err(VMError::NotProgrammable(ic_id));
}
Err(VMError::NoIC(id))
}
pub fn set_modified(self: &Rc<Self>, id: ObjectID) {
@@ -427,13 +541,19 @@ impl VM {
.borrow()
.iter()
.filter(move |(id, device)| {
device.borrow().as_device().is_some_and(|device| {
device
.get_logic(LogicType::PrefabHash)
.is_ok_and(|f| f == prefab_hash)
}) && (name.is_none()
|| name.is_some_and(|name| name == device.borrow().get_name().hash as f64))
&& self.devices_on_same_network(&[source, **id])
if **id == source {
// FIXME: check to make sure this won't cause issues
// if it will pass in a self ref for access
false // exclude source to prevent re-borrow panics
} else {
device.borrow().as_device().is_some_and(|device| {
device
.get_logic(LogicType::PrefabHash)
.is_ok_and(|f| f == prefab_hash)
}) && (name.is_none()
|| name.is_some_and(|name| name == device.borrow().get_name().hash as f64))
&& self.devices_on_same_network(&[source, **id])
}
})
.map(|(_, d)| d)
.cloned()
@@ -856,7 +976,7 @@ impl VM {
if let Some(device) = obj.borrow().as_device() {
for conn in device.connection_list().iter() {
if let Connection::CableNetwork { net: Some(net), .. } = conn {
if let Some(network) = self.networks.borrow().get(&net) {
if let Some(network) = self.networks.borrow().get(net) {
network
.borrow_mut()
.as_mut_network()
@@ -1145,7 +1265,7 @@ impl VMTransaction {
role: ConnectionRole::None,
} = conn
{
if let Some(net) = self.networks.get_mut(&net_id) {
if let Some(net) = self.networks.get_mut(net_id) {
match typ {
CableConnectionType::Power => net.power_only.push(obj_id),
_ => net.devices.push(obj_id),
@@ -1294,8 +1414,7 @@ impl IdSpace {
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct FrozenVM {
pub objects: Vec<FrozenObject>,
pub circuit_holders: Vec<ObjectID>,

View File

@@ -1,6 +1,7 @@
pub mod enums;
mod codegen;
pub mod operands;
pub mod traits;
pub use codegen::enums;
pub use codegen::traits;
use enums::InstructionOp;
use operands::Operand;

View File

@@ -0,0 +1,2 @@
pub mod traits;
pub mod enums;

View File

@@ -1,3 +1,17 @@
// =================================================
// !! <-----> DO NOT MODIFY <-----> !!
//
// This module was automatically generated by an
// xtask
//
// run
//
// `cargo xtask generate -m instructions`
//
// from the workspace to regenerate
//
// =================================================
use serde_derive::{Deserialize, Serialize};
use strum::{Display, EnumIter, EnumProperty, EnumString, FromRepr};
use crate::vm::object::traits::Programmable;
@@ -18,8 +32,7 @@ use wasm_bindgen::prelude::*;
Deserialize
)]
#[derive(EnumIter, EnumString, EnumProperty, FromRepr)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
#[strum(use_phf, serialize_all = "lowercase")]
#[serde(rename_all = "lowercase")]
pub enum InstructionOp {

View File

@@ -1,3 +1,17 @@
// =================================================
// !! <-----> DO NOT MODIFY <-----> !!
//
// This module was automatically generated by an
// xtask
//
// run
//
// `cargo xtask generate -m instructions`
//
// from the workspace to regenerate
//
// =================================================
use crate::vm::object::traits::IntegratedCircuit;
use crate::vm::instructions::enums::InstructionOp;
pub trait AbsInstruction: IntegratedCircuit {

View File

@@ -12,8 +12,7 @@ use tsify::Tsify;
use wasm_bindgen::prelude::*;
#[derive(PartialEq, Eq, Debug, Clone, Copy, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub enum Device {
Db,
Numbered(u32),
@@ -21,31 +20,27 @@ pub enum Device {
}
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct RegisterSpec {
pub indirection: u32,
pub target: u32,
}
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct DeviceSpec {
pub device: Device,
pub connection: Option<usize>,
}
#[derive(PartialEq, Eq, Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct Identifier {
pub name: String,
}
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub enum Number {
Float(f64),
Binary(i64),
@@ -56,8 +51,7 @@ pub enum Number {
}
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub enum Operand {
RegisterSpec(RegisterSpec),
DeviceSpec(DeviceSpec),

View File

@@ -73,8 +73,7 @@ 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))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct Name {
pub value: String,
pub hash: i32,
@@ -110,24 +109,21 @@ impl Name {
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(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))]
#[cfg_attr(feature = "tsify", derive(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))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct Slot {
pub parent: ObjectID,
pub index: usize,

View File

@@ -8,8 +8,7 @@ use tsify::Tsify;
use wasm_bindgen::prelude::*;
#[derive(Error, Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub enum LogicError {
#[error("can't read LogicType {0}")]
CantRead(LogicType),
@@ -24,8 +23,7 @@ pub enum LogicError {
}
#[derive(Error, Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub enum MemoryError {
#[error("stack underflow: {0} < range [0..{1})")]
StackUnderflow(i32, usize),

View File

@@ -210,3 +210,68 @@ macro_rules! GWSuit {
};
}
pub(crate) use GWSuit;
macro_rules! GWCircuitHolderItem {
(
$( #[$attr:meta] )*
$viz:vis struct $struct:ident {
$($body:tt)*
}
) => {
impl GWCircuitHolder for $struct {
type Holder = ItemCircuitHolder;
fn gw_get_error(&self) -> i32 {
self.error
}
fn gw_set_error(&mut self, state: i32) {
self.error = state;
}
}
};
}
pub(crate) use GWCircuitHolderItem;
macro_rules! GWCircuitHolderSuit {
(
$( #[$attr:meta] )*
$viz:vis struct $struct:ident {
$($body:tt)*
}
) => {
impl GWCircuitHolder for $struct {
type Holder = SuitCircuitHolder;
fn gw_get_error(&self) -> i32 {
self.error
}
fn gw_set_error(&mut self, state: i32) {
self.error = state;
}
}
};
}
pub(crate) use GWCircuitHolderSuit;
macro_rules! GWCircuitHolderDevice {
(
$( #[$attr:meta] )*
$viz:vis struct $struct:ident {
$($body:tt)*
}
) => {
impl GWCircuitHolder for $struct {
type Holder = DeviceCircuitHolder;
fn gw_get_error(&self) -> i32 {
self.error
}
fn gw_set_error(&mut self, state: i32) {
self.error = state;
}
}
};
}
pub(crate) use GWCircuitHolderDevice;

View File

@@ -120,12 +120,13 @@ pub struct GenericLogicableDevice {
ObjectInterface!,
GWThermal!, GWInternalAtmo!,
GWStructure!, GWStorage!, GWLogicable!,
GWDevice!
GWDevice!, GWCircuitHolderDevice!
)]
#[custom(implements(Object {
Thermal[GWThermal::is_thermal],
InternalAtmosphere[GWInternalAtmo::is_internal_atmo],
Structure, Storage, Logicable, Device
Structure, Storage, Logicable, Device,
CircuitHolder
}))]
pub struct GenericCircuitHolder {
#[custom(object_id)]
@@ -146,6 +147,7 @@ pub struct GenericCircuitHolder {
pub connections: Vec<Connection>,
pub pins: Option<Vec<Option<ObjectID>>>,
pub reagents: Option<BTreeMap<i32, f64>>,
pub error: i32,
}
#[derive(
@@ -481,12 +483,14 @@ pub struct GenericItemLogicableMemoryReadWriteable {
#[derive(
ObjectInterface!,
GWThermal!, GWInternalAtmo!,
GWItem!, GWStorage!, GWLogicable!
GWItem!, GWStorage!, GWLogicable!,
GWCircuitHolderItem!
)]
#[custom(implements(Object {
Thermal[GWThermal::is_thermal],
InternalAtmosphere[GWInternalAtmo::is_internal_atmo],
Item, Storage, Logicable
Item, Storage, Logicable,
CircuitHolder
}))]
pub struct GenericItemCircuitHolder {
#[custom(object_id)]
@@ -505,6 +509,7 @@ pub struct GenericItemCircuitHolder {
pub slots: Vec<Slot>,
pub fields: BTreeMap<LogicType, LogicField>,
pub modes: Option<BTreeMap<u32, String>>,
pub error: i32,
}
#[derive(
@@ -543,12 +548,13 @@ pub struct GenericItemSuitLogic {
GWThermal!, GWInternalAtmo!,
GWItem!, GWStorage!, GWLogicable!,
GWMemoryReadable!, GWMemoryWritable!,
GWSuit!
GWSuit!, GWCircuitHolderSuit!
)]
#[custom(implements(Object {
Thermal[GWThermal::is_thermal],
InternalAtmosphere[GWInternalAtmo::is_internal_atmo],
Item, Storage, Suit, Logicable, MemoryReadable, MemoryWritable
Item, Storage, Suit, Logicable, MemoryReadable, MemoryWritable,
CircuitHolder
}))]
pub struct GenericItemSuitCircuitHolder {
#[custom(object_id)]
@@ -569,6 +575,7 @@ pub struct GenericItemSuitCircuitHolder {
pub fields: BTreeMap<LogicType, LogicField>,
pub modes: Option<BTreeMap<u32, String>>,
pub memory: Vec<f64>,
pub error: i32,
}
#[derive(

View File

@@ -381,9 +381,8 @@ impl<T: GWMemoryWritable + MemoryReadable + Object> MemoryWritable for T {
Ok(())
}
}
fn clear_memory(&mut self) -> Result<(), MemoryError> {
fn clear_memory(&mut self) {
self.memory_mut().fill(0.0);
Ok(())
}
}
@@ -564,7 +563,7 @@ impl<T: GWItem + Object> Item for T {
self.damage().unwrap_or(0.0)
}
fn set_damage(&mut self, damage: f32) {
self.damage_mut().replace(damage);
self.damage_mut().replace(damage.clamp(0.0, 1.0));
}
}

View File

@@ -79,8 +79,7 @@ pub struct HumanPlayer {
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct EntityInfo {
pub hydration: f32,
pub nutrition: f32,

View File

@@ -22,11 +22,13 @@ macro_rules! object_trait {
paste::paste! {
$(
#[doc = "Return a `& dyn " $trt "` if implimented by the object"]
#[inline(always)]
fn [<as_ $trt:snake>](&self) -> Option<[<$trt Ref>]> {
None
}
#[doc = "Return a `&mut dyn " $trt "` if implimented by the object"]
#[inline(always)]
fn [<as_mut_ $trt:snake>](&mut self) -> Option<[<$trt RefMut>]> {
None

View File

@@ -58,7 +58,7 @@ pub fn object_from_frozen(
.clone()
.unwrap_or_else(|| prefab.get_str("name").unwrap().to_string())),
),
prefab: Name::from_prefab_name(&prefab.to_string()),
prefab: Name::from_prefab_name(prefab.as_ref()),
fields: template
.logic
.logic_types
@@ -84,7 +84,7 @@ pub fn object_from_frozen(
.map(TryInto::try_into)
.transpose()
.map_err(|vec: Vec<f64>| TemplateError::MemorySize(vec.len(), 512))?
.unwrap_or_else(|| [0.0f64; 512]),
.unwrap_or( [0.0f64; 512]),
parent_slot: None,
registers: obj
.circuit
@@ -92,7 +92,7 @@ pub fn object_from_frozen(
.map(|circuit| circuit.registers.clone().try_into())
.transpose()
.map_err(|vec: Vec<f64>| TemplateError::MemorySize(vec.len(), 18))?
.unwrap_or_else(|| [0.0f64; 18]),
.unwrap_or( [0.0f64; 18]),
ip: obj
.circuit
.as_ref()

View File

@@ -23,7 +23,12 @@ static RETURN_ADDRESS_INDEX: usize = 17;
static STACK_POINTER_INDEX: usize = 16;
#[derive(ObjectInterface!)]
#[custom(implements(Object { Item, Storage, Logicable, MemoryReadable, MemoryWritable }))]
#[custom(implements(Object {
Item, Storage, Logicable,
MemoryReadable, MemoryWritable,
SourceCode, IntegratedCircuit,
Programmable
}))]
pub struct ItemIntegratedCircuit10 {
#[custom(object_id)]
pub id: ObjectID,
@@ -83,7 +88,7 @@ impl Item for ItemIntegratedCircuit10 {
self.damage
}
fn set_damage(&mut self, damage: f32) {
self.damage = damage;
self.damage = damage.clamp(0.0, 1.0);
}
}
@@ -208,9 +213,8 @@ impl MemoryWritable for ItemIntegratedCircuit10 {
Ok(())
}
}
fn clear_memory(&mut self) -> Result<(), MemoryError> {
fn clear_memory(&mut self) {
self.memory.fill(0.0);
Ok(())
}
}
@@ -369,6 +373,9 @@ impl IntegratedCircuit for ItemIntegratedCircuit10 {
}
fn set_state(&mut self, state: crate::interpreter::ICState) {
self.state = state;
if matches!(self.state, ICState::Yield | ICState::Sleep(..)) {
self.ic = 0;
}
}
fn get_instructions_since_yield(&self) -> u16 {
self.ic

View File

@@ -41,8 +41,7 @@ use wasm_bindgen::prelude::*;
use super::{stationpedia, MemoryAccess, ObjectID, VMObject};
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub enum Prefab {
Hash(i32),
Name(String),
@@ -55,7 +54,7 @@ impl std::fmt::Display for Prefab {
StationpediaPrefab::from_repr(*hash),
format!("Unknown({hash}))"),
),
Self::Name(name) => (StationpediaPrefab::from_str(&name).ok(), name.clone()),
Self::Name(name) => (StationpediaPrefab::from_str(name).ok(), name.clone()),
};
if let Some(known) = known_prefab {
write!(f, "{known}")
@@ -66,8 +65,7 @@ impl std::fmt::Display for Prefab {
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct ObjectInfo {
pub name: Option<String>,
pub id: Option<ObjectID>,
@@ -106,6 +104,28 @@ impl From<&VMObject> for ObjectInfo {
}
impl ObjectInfo {
/// Build empty info with a prefab name
pub fn with_prefab(prefab: Prefab) -> Self {
ObjectInfo {
name: None,
id: None,
prefab: Some(prefab),
slots: None,
damage: None,
device_pins: None,
connections: None,
reagents: None,
memory: None,
logic_values: None,
entity: None,
source_code: None,
circuit: None,
}
}
/// update the object info from the relavent implimented interfaces of a dyn object
/// use `ObjectInterfaces::from_object` with a `&dyn Object` (`&*VMObject.borrow()`)
/// to obtain the interfaces
pub fn update_from_interfaces(&mut self, interfaces: &ObjectInterfaces<'_>) -> &mut Self {
if let Some(storage) = interfaces.storage {
self.update_from_storage(storage);
@@ -134,6 +154,7 @@ impl ObjectInfo {
self
}
/// set `slots` to Some if there is relevant storage
pub fn update_from_storage(&mut self, storage: StorageRef<'_>) -> &mut Self {
let slots = storage.get_slots();
if slots.is_empty() {
@@ -154,6 +175,7 @@ impl ObjectInfo {
self
}
/// store `item` properties like `damage`
pub fn update_from_item(&mut self, item: ItemRef<'_>) -> &mut Self {
let damage = item.get_damage();
if damage == 0.0 {
@@ -164,6 +186,7 @@ impl ObjectInfo {
self
}
/// store `device_pins`, `reagents`, and `connections`
pub fn update_from_device(&mut self, device: DeviceRef<'_>) -> &mut Self {
let pins = device.device_pins();
if pins.is_some_and(<[Option<u32>]>::is_empty) {
@@ -188,18 +211,16 @@ impl ObjectInfo {
} else {
self.connections.replace(
connections
.into_iter()
.iter()
.enumerate()
.filter_map(|(index, conn)| match conn.get_network() {
Some(net) => Some((index as u32, net)),
None => None,
})
.filter_map(|(index, conn)| conn.get_network().map(|net| (index as u32, net)))
.collect(),
);
}
self
}
/// store memory state
pub fn update_from_memory(&mut self, memory: MemoryReadableRef<'_>) -> &mut Self {
if memory.memory_size() != 0 {
self.memory.replace(memory.get_memory_slice().to_vec());
@@ -209,6 +230,7 @@ impl ObjectInfo {
self
}
/// store logic field state
pub fn update_from_logic(&mut self, logic: LogicableRef<'_>) -> &mut Self {
self.logic_values.replace(
logic
@@ -223,6 +245,7 @@ impl ObjectInfo {
self
}
/// store entity state
pub fn update_from_human(&mut self, human: HumanRef<'_>) -> &mut Self {
let damage = human.get_damage();
if damage == 0.0 {
@@ -241,6 +264,7 @@ impl ObjectInfo {
self
}
/// store source code
pub fn update_from_source_code(&mut self, source: SourceCodeRef<'_>) -> &mut Self {
let code = source.get_source_code();
if !code.is_empty() {
@@ -249,6 +273,7 @@ impl ObjectInfo {
self
}
/// store circuit state; ie. `registers`, `aliases`, `defines` etc.
pub fn update_from_circuit(&mut self, circuit: IntegratedCircuitRef<'_>) -> &mut Self {
self.circuit.replace(ICInfo {
instruction_pointer: circuit.get_instruction_pointer(),
@@ -276,8 +301,7 @@ impl ObjectInfo {
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct FrozenObject {
pub obj_info: ObjectInfo,
pub database_template: bool,
@@ -379,7 +403,7 @@ impl FrozenObject {
.collect::<Vec<_>>()
})
})
.unwrap_or_else(Vec::new),
.unwrap_or_default(),
writeable_logic: logic_info
.and_then(|info| {
info.logic_slot_types.get(&(index as u32)).map(|s_info| {
@@ -393,7 +417,7 @@ impl FrozenObject {
.collect::<Vec<_>>()
})
})
.unwrap_or_else(Vec::new),
.unwrap_or_default(),
occupant: self
.obj_info
.slots
@@ -555,6 +579,7 @@ impl FrozenObject {
pins: self.build_pins(&s.device),
device_info: s.device.clone(),
reagents: self.obj_info.reagents.clone(),
error: 0,
})),
StructureLogicDeviceMemory(s)
if matches!(s.memory.memory_access, MemoryAccess::Read) =>
@@ -739,6 +764,7 @@ impl FrozenObject {
slots: self.build_slots(id, &i.slots, Some(&i.logic)),
fields: self.build_logic_fields(&i.logic),
modes: i.logic.modes.clone(),
error: 0,
})),
ItemSuit(i) => Ok(VMObject::new(GenericItemSuit {
id,
@@ -783,6 +809,7 @@ impl FrozenObject {
fields: self.build_logic_fields(&i.logic),
modes: i.logic.modes.clone(),
memory: self.build_memory(&i.memory),
error: 0,
})),
Human(h) => {
let mut human = HumanPlayer::with_species(id, vm, h.species);
@@ -1368,42 +1395,3 @@ impl From<StorageRef<'_>> for Vec<SlotInfo> {
.collect()
}
}
#[cfg(test)]
mod tests {
use serde_derive::Deserialize;
use serde_json;
use std::collections::BTreeMap;
use std::fs::File;
use std::io::BufReader;
use std::path::PathBuf;
use super::ObjectTemplate;
static INIT: std::sync::Once = std::sync::Once::new();
fn setup() {
INIT.call_once(|| {
let _ = color_eyre::install();
})
}
#[allow(dead_code)]
#[derive(Debug, Deserialize)]
struct Database {
pub prefabs: BTreeMap<String, ObjectTemplate>,
}
#[test]
fn all_database_prefabs_parse() -> color_eyre::Result<()> {
setup();
let mut d = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
d = d.parent().unwrap().join("data").join("database.json");
println!("loading database from {}", d.display());
let _database: Database = serde_json::from_reader(BufReader::new(File::open(d)?))?;
Ok(())
}
}

View File

@@ -27,8 +27,7 @@ use wasm_bindgen::prelude::*;
use strum::{AsRefStr, Display, EnumIter, EnumProperty, EnumString, FromRepr};
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct ParentSlotInfo {
pub parent: ObjectID,
pub slot: usize,
@@ -53,8 +52,7 @@ pub struct ParentSlotInfo {
Serialize,
Deserialize,
)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub enum StatState {
#[default]
Normal,
@@ -70,88 +68,154 @@ tag_object_traits! {
}
pub trait Storage {
/// Number of storage slots this object has
fn slots_count(&self) -> usize;
/// Get a reference to a indexed slot
fn get_slot(&self, index: usize) -> Option<&Slot>;
/// Get a mutable reference to a indexed slot
fn get_slot_mut(&mut self, index: usize) -> Option<&mut Slot>;
/// Get a vector of references to all an object's slots
fn get_slots(&self) -> Vec<&Slot>;
/// Get a vector a mutable references to all an object's slots
fn get_slots_mut(&mut self) -> Vec<&mut Slot>;
}
pub trait MemoryReadable {
/// Size of an object memory, the count of f64 elements stored
fn memory_size(&self) -> usize;
/// Get the value at the indexed memory.
/// Errors if the index over or under flows the memory
fn get_memory(&self, index: i32) -> Result<f64, MemoryError>;
/// get a slice of the objects' memory
fn get_memory_slice(&self) -> &[f64];
}
pub trait MemoryWritable: MemoryReadable {
/// Set the value at the indexed memory
/// Errors if the index over or under flows the memory
fn set_memory(&mut self, index: i32, val: f64) -> Result<(), MemoryError>;
fn clear_memory(&mut self) -> Result<(), MemoryError>;
/// Reset all an object's memory (typically to all zero values)
fn clear_memory(&mut self);
}
pub trait Logicable: Storage {
/// The crc32 hash of the object's prefab name
fn prefab_hash(&self) -> i32;
/// returns 0 if not set
/// The crc32 hash of an object's name
fn name_hash(&self) -> i32;
/// If the object has *any* readable logic fields
fn is_logic_readable(&self) -> bool;
/// If the object has *any* writable logic fields
fn is_logic_writeable(&self) -> bool;
/// Can the logic type be read form this object
fn can_logic_read(&self, lt: LogicType) -> bool;
/// Can the logic type be written to this object
fn can_logic_write(&self, lt: LogicType) -> bool;
/// Write the value of the logic type on this object.
/// Errors if the type can not be written to.
/// force will allow special cases for existing values that arn't
/// normally writable.
/// This is for use outside of ic10 code but does not guarantee the
/// value will write or that no error will result.
/// If a logic type is not present on an object the force write will still error.
fn set_logic(&mut self, lt: LogicType, value: f64, force: bool) -> Result<(), LogicError>;
/// Read the value of the logic type on this object.
/// Errors if a logic type is not readable
fn get_logic(&self, lt: LogicType) -> Result<f64, LogicError>;
/// Can a slot logic type be read from the indexed slot
fn can_slot_logic_read(&self, slt: LogicSlotType, index: f64) -> bool;
/// Read a slot logic type value from an index slot
fn get_slot_logic(&self, slt: LogicSlotType, index: f64) -> Result<f64, LogicError>;
/// Returns a vector of the `LogicType`'s that could be read or written to or form this
/// object
fn valid_logic_types(&self) -> Vec<LogicType>;
/// If this object has modes returns a vector of (value, name) pairs
fn known_modes(&self) -> Option<Vec<(u32, String)>>;
}
pub trait SourceCode {
/// Set the source code for this object.
/// Errors if the source code has compilation errors.
fn set_source_code(&mut self, code: &str) -> Result<(), ICError>;
/// Set the source code for this object, lines that fail to compile are reduced to nops.
fn set_source_code_with_invalid(&mut self, code: &str);
/// Return the source code form this object
fn get_source_code(&self) -> String;
/// Return the compiled instruction and it's operands at the indexed line in the source
/// code.
fn get_line(&self, line: usize) -> Result<&Instruction, ICError>;
}
pub trait CircuitHolder: Logicable + Storage {
/// Clear any error set on the circuit holder
fn clear_error(&mut self);
/// Set an int error value on the circuit holder
fn set_error(&mut self, state: i32);
/// Get a reference (which may be self) to a logicable object based on an index
/// (`db`, `d0`, `d1` etc.).
/// for a StructureCircuitHolder this would be the set pins
/// fpr a tablet or suit this would be the parent human's equipment
/// i32::MAX is db
fn get_logicable_from_index(
&self,
device: i32,
connection: Option<usize>,
) -> Option<ObjectRef>;
/// Get a mutable reference (which may be self) to a logicable object based on an index
/// (`db`, `d0`, `d1` etc.).
/// for a StructureCircuitHolder this would be the set pins
/// fpr a tablet or suit this would be the parent human's equipment
/// i32::MAX is db
fn get_logicable_from_index_mut(
&mut self,
device: i32,
connection: Option<usize>,
) -> Option<ObjectRefMut>;
/// Use an object id to get a reference to an object network visible object.
/// uses ObjectRef in case the object ID is it's own ID
fn get_logicable_from_id(
&self,
device: ObjectID,
connection: Option<usize>,
) -> Option<ObjectRef>;
/// Use an object id to get a mutable reference to an object network visible object.
/// uses ObjectRefMut in case the object ID is it's own ID
fn get_logicable_from_id_mut(
&mut self,
device: ObjectID,
connection: Option<usize>,
) -> Option<ObjectRefMut>;
/// Get the programmable circuit object slotted into this circuit holder
fn get_ic(&self) -> Option<VMObject>;
/// Execute a `hcf` instruction
fn hault_and_catch_fire(&mut self);
}
pub trait Item {
/// Is an item consumable?
fn consumable(&self) -> bool;
/// If an item is a filter what gas is it for?
fn filter_type(&self) -> Option<GasType>;
/// Is this item an ingredient ?
fn ingredient(&self) -> bool;
/// The max quantity this item stacks to
fn max_quantity(&self) -> u32;
/// Map of the reagents to the quantity produces by processing this item
fn reagents(&self) -> Option<&BTreeMap<String, f64>>;
/// The class of item this is for storage slots
fn slot_class(&self) -> Class;
/// The sorting class of the item
fn sorting_class(&self) -> SortingClass;
/// The parent object and slot index this item is stored in
fn get_parent_slot(&self) -> Option<ParentSlotInfo>;
/// Set the parent object and slot index this object is stored in
fn set_parent_slot(&mut self, info: Option<ParentSlotInfo>);
/// Get the damage 0.0 is no damage, 1.0 is full damage
fn get_damage(&self) -> f32;
/// Set the damage of the object, 0.0 is no damage, 1.0 is full damage
fn set_damage(&mut self, damage: f32);
/// If this object is stored in a human's inventory or in an inventory down the chain from
/// a human, return that human
fn root_parent_human(&self) -> Option<VMObject> {
self.get_parent_slot().and_then(|info| {
if let Some(obj) = self.get_vm().get_object(info.parent) {
@@ -192,34 +256,75 @@ tag_object_traits! {
}
pub trait IntegratedCircuit: Logicable + MemoryWritable + SourceCode + Item {
/// Get the object that acts as the circuit holder for this object
fn get_circuit_holder(&self) -> Option<VMObject>;
/// Get the current instruction pointer
fn get_instruction_pointer(&self) -> u32;
/// Set the next instruction to execute. The instruction pointer is set to this value once
/// execution of the current instruction is complete.
fn set_next_instruction(&mut self, next_instruction: f64);
/// Set the next instruction to execute relative to the current instruction pointer.
/// The instruction pointer is set to this value once execution of the current
/// instruction is complete.
fn set_next_instruction_relative(&mut self, offset: f64) {
self.set_next_instruction(self.get_instruction_pointer() as f64 + offset);
}
/// Reset the circuit. The instruction pointer, instruction count since last yield, all
/// registers and memory are set to 0; aliases and defines are cleared; state is set back
/// to start.
fn reset(&mut self);
/// When given some indirection level and a first target read registers values as
/// targets while reducing indirection level by one until it reaches to 0
/// to find the real target.
/// Errors if any index along the chain is out of range
fn get_real_target(&self, indirection: u32, target: u32) -> Result<f64, ICError>;
/// Return a register value through possible indirection
/// Errors if any index along the chain is out of range
fn get_register(&self, indirection: u32, target: u32) -> Result<f64, ICError>;
/// Get a slice of all registers
fn get_registers(&self) -> &[f64];
/// Get a mutable slice of all registers
fn get_registers_mut(&mut self) -> &mut [f64];
/// Set a register value through possible indirection
/// Errors if any index along the chain is out of range
fn set_register(&mut self, indirection: u32, target: u32, val: f64) -> Result<f64, ICError>;
/// Set the return address register's value
fn set_return_address(&mut self, addr: f64);
/// Set the return address to the instruction after the current instruction pointer
fn al(&mut self) {
self.set_return_address(self.get_instruction_pointer() as f64 + 1.0);
}
/// Write value to the stack memory at the current stack pointer and advance stack pointer
/// Errors for stack under or overflow of the stack pointer
fn push_stack(&mut self, val: f64) -> Result<f64, ICError>;
/// Read value from the stack memory at the current stack pointer and decrement the stack pointer
/// Errors for stack under or overflow of the stack pointer
fn pop_stack(&mut self) -> Result<f64, ICError>;
/// Read the value form the stack memory at the current stack pointer and leave the stack pointer
/// at the same location
/// Errors for stack under or overflow of the stack pointer
fn peek_stack(&self) -> Result<f64, ICError>;
/// Read the value from the stack memory at indexed address
/// Errors for stack under or overflow of the address
fn get_stack(&self, addr: f64) -> Result<f64, ICError>;
/// Write the value to the stack memory at the indexed address
/// Errors for stack under or overflow of the address
fn put_stack(&mut self, addr: f64, val: f64) -> Result<f64, ICError>;
/// Get a reference to the alias Map
fn get_aliases(&self) -> &BTreeMap<String, crate::vm::instructions::operands::Operand>;
/// Get a mutable reference to the alias Map
fn get_aliases_mut(&mut self) -> &mut BTreeMap<String, crate::vm::instructions::operands::Operand>;
/// Get a reference to the define Map
fn get_defines(&self) -> &BTreeMap<String, f64>;
/// Get a mutable reference to the define Map
fn get_defines_mut(&mut self) -> &mut BTreeMap<String, f64>;
/// Get a reference to the labels Map
fn get_labels(&self) -> &BTreeMap<String, u32>;
/// Get the current circuit state. (Start, Yield, Sleep, Error, etc.)
fn get_state(&self) -> ICState;
/// Set the current circuit state. (Start, Yield, Sleep, Error, etc.)
fn set_state(&mut self, state: ICState);
/// Get the count of instructions executed since the last yield
fn get_instructions_since_yield(&self) -> u16;
}
@@ -251,7 +356,10 @@ tag_object_traits! {
}
pub trait Device: Logicable {
/// Can the slot logic type be written to the object at the indexed slot
fn can_slot_logic_write(&self, slt: LogicSlotType, index: f64) -> bool;
/// Write to the slot logic type at the indexed slot
/// Errors if the index is out of range or the slot logic type is not writable
fn set_slot_logic(
&mut self,
slt: LogicSlotType,
@@ -259,30 +367,42 @@ tag_object_traits! {
value: f64,
force: bool,
) -> Result<(), LogicError>;
/// Get a slice of the Device's network connections
fn connection_list(&self) -> &[Connection];
/// Get a mutable slice of the Device's network connections
fn connection_list_mut(&mut self) -> &mut [Connection];
/// Get a slice of the devices "pins" (connected object Ids) if the device has pins
fn device_pins(&self) -> Option<&[Option<ObjectID>]>;
/// Get a mutable slice of the devices "pins" (connected object Ids) if the device has pins
fn device_pins_mut(&mut self) -> Option<&mut [Option<ObjectID>]>;
/// Does the device respond to Activate
fn has_activate_state(&self) -> bool;
/// Does the device have an internal atmosphere
fn has_atmosphere(&self) -> bool;
/// Does the device have a Color state
fn has_color_state(&self) -> bool;
/// Does the device have a Lock state
fn has_lock_state(&self) -> bool;
/// Does the device have a mode state
fn has_mode_state(&self) -> bool;
/// Does the device have an On / off state
fn has_on_off_state(&self) -> bool;
/// Does the device have an Open state
fn has_open_state(&self) -> bool;
/// Does the device store reagents
fn has_reagents(&self) -> bool;
/// return vector of (reagent_hash, quantity) pairs
/// Return vector of (reagent_hash, quantity) pairs
fn get_reagents(&self) -> Vec<(i32, f64)>;
/// overwrite present reagents
/// Overwrite present reagents
fn set_reagents(&mut self, reagents: &[(i32, f64)]);
/// adds the reagents to contents
/// Adds the reagents to contents
fn add_reagents(&mut self, reagents: &[(i32, f64)]);
}
pub trait ReagentInterface: Device {
/// reagents required by current recipe
/// Reagents required by current recipe
fn get_current_recipie(&self) -> Vec<(i32, f64)>;
/// reagents required to complete current recipe
/// Reagents required to complete current recipe
fn get_current_required(&self) -> Vec<(i32, f64)>;
}
@@ -293,20 +413,35 @@ tag_object_traits! {
pub trait WirelessReceive: Logicable {}
pub trait Network: Logicable {
/// Does the network contain the Object id
fn contains(&self, id: &ObjectID) -> bool;
/// Does the network contain all the object ids
fn contains_all(&self, ids: &[ObjectID]) -> bool;
/// Does the network contain the object id on a data connection
fn contains_data(&self, id: &ObjectID) -> bool;
/// Does the network contain all the object ids on a data connection
fn contains_all_data(&self, ids: &[ObjectID]) -> bool;
/// Does the network contain the object id on a power connection
fn contains_power(&self, id: &ObjectID) -> bool;
/// Does the network contain all the object ids on a power connection
fn contains_all_power(&self, ids: &[ObjectID]) -> bool;
/// Return a vector of all object ids visible to the data connection of the source ID object
fn data_visible(&self, source: &ObjectID) -> Vec<u32>;
/// Add the object to the network as a data connection
fn add_data(&mut self, id: ObjectID) -> bool;
/// Add the object id as a power connection
fn add_power(&mut self, id: ObjectID) -> bool;
/// remove the object id for both power and data connections if present in either
fn remove_all(&mut self, id: ObjectID) -> bool;
/// remove the object id from data network
fn remove_data(&mut self, id: ObjectID) -> bool;
/// remove object id from power network
fn remove_power(&mut self, id: ObjectID) -> bool;
/// get all data connected devices
fn get_devices(&self) -> Vec<ObjectID>;
/// get all power connected devices
fn get_power_only(&self) -> Vec<ObjectID>;
/// get a slice of the channel data values
fn get_channel_data(&self) -> &[f64; 8];
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1,17 @@
// =================================================
// !! <-----> DO NOT MODIFY <-----> !!
//
// This module was automatically generated by an
// xtask
//
// run
//
// `cargo xtask generate -m enums`
//
// from the workspace to regenerate
//
// =================================================
use serde_derive::{Deserialize, Serialize};
use strum::{AsRefStr, Display, EnumIter, EnumProperty, EnumString, FromRepr};
#[cfg(feature = "tsify")]
@@ -23,8 +37,7 @@ use super::script::{LogicSlotType, LogicType};
Serialize,
Deserialize
)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
#[strum(use_phf)]
#[repr(u8)]
pub enum AirConditioningMode {
@@ -71,8 +84,7 @@ impl TryFrom<f64> for AirConditioningMode {
Serialize,
Deserialize
)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
#[strum(use_phf)]
#[repr(u8)]
pub enum AirControlMode {
@@ -123,8 +135,7 @@ impl TryFrom<f64> for AirControlMode {
Serialize,
Deserialize
)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
#[strum(use_phf)]
#[repr(u8)]
pub enum ColorType {
@@ -199,8 +210,7 @@ impl TryFrom<f64> for ColorType {
Serialize,
Deserialize
)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
#[strum(use_phf)]
#[repr(u8)]
pub enum DaylightSensorMode {
@@ -250,8 +260,7 @@ impl TryFrom<f64> for DaylightSensorMode {
Serialize,
Deserialize
)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
#[strum(use_phf)]
#[repr(u8)]
pub enum ElevatorMode {
@@ -298,8 +307,7 @@ impl TryFrom<f64> for ElevatorMode {
Serialize,
Deserialize
)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
#[strum(use_phf)]
#[repr(u8)]
pub enum EntityState {
@@ -349,8 +357,7 @@ impl TryFrom<f64> for EntityState {
Serialize,
Deserialize
)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
#[strum(use_phf)]
#[repr(u32)]
pub enum GasType {
@@ -442,8 +449,7 @@ impl TryFrom<f64> for GasType {
Serialize,
Deserialize
)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
#[strum(use_phf)]
#[repr(u8)]
pub enum PowerMode {
@@ -497,8 +503,7 @@ impl TryFrom<f64> for PowerMode {
Serialize,
Deserialize
)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
#[strum(use_phf)]
#[repr(u8)]
pub enum PrinterInstruction {
@@ -570,8 +575,7 @@ impl TryFrom<f64> for PrinterInstruction {
Serialize,
Deserialize
)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
#[strum(use_phf)]
#[repr(u8)]
pub enum ReEntryProfile {
@@ -626,8 +630,7 @@ impl TryFrom<f64> for ReEntryProfile {
Serialize,
Deserialize
)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
#[strum(use_phf)]
#[repr(u8)]
pub enum RobotMode {
@@ -688,8 +691,7 @@ impl TryFrom<f64> for RobotMode {
Serialize,
Deserialize
)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
#[strum(use_phf)]
#[repr(u8)]
pub enum RocketMode {
@@ -747,8 +749,7 @@ impl TryFrom<f64> for RocketMode {
Serialize,
Deserialize
)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
#[strum(use_phf)]
#[repr(u8)]
pub enum Class {
@@ -908,8 +909,7 @@ impl TryFrom<f64> for Class {
Serialize,
Deserialize
)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
#[strum(use_phf)]
#[repr(u8)]
pub enum SorterInstruction {
@@ -970,8 +970,7 @@ impl TryFrom<f64> for SorterInstruction {
Serialize,
Deserialize
)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
#[strum(use_phf)]
#[repr(u8)]
pub enum SortingClass {
@@ -1044,8 +1043,7 @@ impl TryFrom<f64> for SortingClass {
Serialize,
Deserialize
)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
#[strum(use_phf)]
#[repr(u8)]
pub enum SoundAlert {
@@ -1222,8 +1220,7 @@ impl TryFrom<f64> for SoundAlert {
Serialize,
Deserialize
)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
#[strum(use_phf)]
#[repr(u8)]
pub enum LogicTransmitterMode {
@@ -1269,8 +1266,7 @@ impl TryFrom<f64> for LogicTransmitterMode {
Serialize,
Deserialize
)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
#[strum(use_phf)]
#[repr(u8)]
pub enum VentDirection {
@@ -1314,8 +1310,7 @@ impl TryFrom<f64> for VentDirection {
Serialize,
Deserialize
)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
#[strum(use_phf)]
#[repr(u8)]
pub enum ConditionOperation {

View File

@@ -1,3 +1,17 @@
// =================================================
// !! <-----> DO NOT MODIFY <-----> !!
//
// This module was automatically generated by an
// xtask
//
// run
//
// `cargo xtask generate -m enums`
//
// from the workspace to regenerate
//
// =================================================
use serde_derive::{Deserialize, Serialize};
use strum::{AsRefStr, Display, EnumIter, EnumProperty, EnumString, FromRepr};
#[cfg(feature = "tsify")]
@@ -22,8 +36,7 @@ use wasm_bindgen::prelude::*;
Serialize,
Deserialize
)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
#[strum(use_phf)]
#[repr(i32)]
pub enum StationpediaPrefab {

View File

@@ -1,3 +1,17 @@
// =================================================
// !! <-----> DO NOT MODIFY <-----> !!
//
// This module was automatically generated by an
// xtask
//
// run
//
// `cargo xtask generate -m enums`
//
// from the workspace to regenerate
//
// =================================================
use serde_derive::{Deserialize, Serialize};
use strum::{AsRefStr, Display, EnumIter, EnumProperty, EnumString, FromRepr};
#[cfg(feature = "tsify")]
@@ -22,8 +36,7 @@ use wasm_bindgen::prelude::*;
Serialize,
Deserialize
)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
#[strum(use_phf)]
#[repr(u8)]
pub enum LogicBatchMethod {
@@ -73,8 +86,7 @@ impl TryFrom<f64> for LogicBatchMethod {
Serialize,
Deserialize
)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
#[strum(use_phf)]
#[repr(u8)]
pub enum LogicReagentMode {
@@ -125,8 +137,7 @@ impl TryFrom<f64> for LogicReagentMode {
Serialize,
Deserialize
)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
#[strum(use_phf)]
#[repr(u8)]
pub enum LogicSlotType {
@@ -320,8 +331,7 @@ impl TryFrom<f64> for LogicSlotType {
Serialize,
Deserialize
)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
#[strum(use_phf)]
#[repr(u16)]
pub enum LogicType {

View File

@@ -12,8 +12,7 @@ use tsify::Tsify;
use wasm_bindgen::prelude::*;
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
#[serde(untagged)]
pub enum ObjectTemplate {
Structure(StructureTemplate),
@@ -173,8 +172,7 @@ impl From<HumanTemplate> for ObjectTemplate {
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct HumanTemplate {
pub prefab: PrefabInfo,
pub species: Species,
@@ -182,8 +180,7 @@ pub struct HumanTemplate {
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct PrefabInfo {
pub prefab_name: String,
pub prefab_hash: i32,
@@ -192,16 +189,14 @@ pub struct PrefabInfo {
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct SlotInfo {
pub name: String,
pub typ: Class,
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct LogicInfo {
pub logic_slot_types: BTreeMap<u32, BTreeMap<LogicSlotType, MemoryAccess>>,
pub logic_types: BTreeMap<LogicType, MemoryAccess>,
@@ -212,8 +207,7 @@ pub struct LogicInfo {
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct ItemInfo {
pub consumable: bool,
pub filter_type: Option<GasType>,
@@ -225,8 +219,7 @@ pub struct ItemInfo {
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct ConnectionInfo {
pub typ: ConnectionType,
pub role: ConnectionRole,
@@ -234,8 +227,7 @@ pub struct ConnectionInfo {
#[allow(clippy::struct_excessive_bools)]
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct DeviceInfo {
pub connection_list: Vec<ConnectionInfo>,
pub device_pins_length: Option<u32>,
@@ -250,16 +242,14 @@ pub struct DeviceInfo {
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct ConsumerInfo {
pub consumed_resouces: Vec<String>,
pub processed_reagents: Vec<i32>,
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct RecipeRange {
pub start: f64,
pub stop: f64,
@@ -267,8 +257,7 @@ pub struct RecipeRange {
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct RecipeGasMix {
pub rule: i64,
pub is_any: bool,
@@ -277,8 +266,7 @@ pub struct RecipeGasMix {
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct Recipe {
pub tier: MachineTier,
pub time: f64,
@@ -291,23 +279,20 @@ pub struct Recipe {
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct FabricatorInfo {
pub tier: MachineTier,
pub recipes: BTreeMap<String, Recipe>,
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct StructureInfo {
pub small_grid: bool,
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct Instruction {
pub description: String,
pub typ: String,
@@ -315,8 +300,7 @@ pub struct Instruction {
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct MemoryInfo {
pub instructions: Option<BTreeMap<String, Instruction>>,
pub memory_access: MemoryAccess,
@@ -324,31 +308,27 @@ pub struct MemoryInfo {
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct ThermalInfo {
pub convection_factor: f32,
pub radiation_factor: f32,
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct InternalAtmoInfo {
pub volume: f32,
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct SuitInfo {
pub hygine_reduction_multiplier: f32,
pub waste_max_pressure: f32,
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct StructureTemplate {
pub prefab: PrefabInfo,
pub structure: StructureInfo,
@@ -357,8 +337,7 @@ pub struct StructureTemplate {
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct StructureSlotsTemplate {
pub prefab: PrefabInfo,
pub structure: StructureInfo,
@@ -368,8 +347,7 @@ pub struct StructureSlotsTemplate {
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct StructureLogicTemplate {
pub prefab: PrefabInfo,
pub structure: StructureInfo,
@@ -380,8 +358,7 @@ pub struct StructureLogicTemplate {
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct StructureLogicDeviceTemplate {
pub prefab: PrefabInfo,
pub structure: StructureInfo,
@@ -393,8 +370,7 @@ pub struct StructureLogicDeviceTemplate {
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct StructureLogicDeviceConsumerTemplate {
pub prefab: PrefabInfo,
pub structure: StructureInfo,
@@ -408,8 +384,7 @@ pub struct StructureLogicDeviceConsumerTemplate {
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct StructureLogicDeviceMemoryTemplate {
pub prefab: PrefabInfo,
pub structure: StructureInfo,
@@ -422,8 +397,7 @@ pub struct StructureLogicDeviceMemoryTemplate {
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct StructureCircuitHolderTemplate {
pub prefab: PrefabInfo,
pub structure: StructureInfo,
@@ -435,8 +409,7 @@ pub struct StructureCircuitHolderTemplate {
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct StructureLogicDeviceConsumerMemoryTemplate {
pub prefab: PrefabInfo,
pub structure: StructureInfo,
@@ -451,8 +424,7 @@ pub struct StructureLogicDeviceConsumerMemoryTemplate {
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct ItemTemplate {
pub prefab: PrefabInfo,
pub item: ItemInfo,
@@ -461,8 +433,7 @@ pub struct ItemTemplate {
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct ItemSlotsTemplate {
pub prefab: PrefabInfo,
pub item: ItemInfo,
@@ -472,8 +443,7 @@ pub struct ItemSlotsTemplate {
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct ItemConsumerTemplate {
pub prefab: PrefabInfo,
pub item: ItemInfo,
@@ -484,8 +454,7 @@ pub struct ItemConsumerTemplate {
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct ItemLogicTemplate {
pub prefab: PrefabInfo,
pub item: ItemInfo,
@@ -496,8 +465,7 @@ pub struct ItemLogicTemplate {
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct ItemLogicMemoryTemplate {
pub prefab: PrefabInfo,
pub item: ItemInfo,
@@ -509,8 +477,7 @@ pub struct ItemLogicMemoryTemplate {
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct ItemCircuitHolderTemplate {
pub prefab: PrefabInfo,
pub item: ItemInfo,
@@ -521,8 +488,7 @@ pub struct ItemCircuitHolderTemplate {
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct ItemSuitTemplate {
pub prefab: PrefabInfo,
pub item: ItemInfo,
@@ -533,8 +499,7 @@ pub struct ItemSuitTemplate {
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct ItemSuitLogicTemplate {
pub prefab: PrefabInfo,
pub item: ItemInfo,
@@ -546,8 +511,7 @@ pub struct ItemSuitLogicTemplate {
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
pub struct ItemSuitCircuitHolderTemplate {
pub prefab: PrefabInfo,
pub item: ItemInfo,

View File

@@ -52,7 +52,7 @@ pub fn generate(
let enums_files = enums::generate(&pedia, &enums, workspace)?;
eprintln!("Formatting generated files...");
for file in &enums_files {
prepend_generated_comment_and_format(file)?;
prepend_generated_comment_and_format(file, "enums")?;
}
return Ok(());
}
@@ -61,18 +61,18 @@ pub fn generate(
eprintln!("generating database...");
let database_files = database::generate_database(&pedia, &enums, workspace)?;
generated_files.extend(database_files);
generated_files.extend(database_files.into_iter().map(|path| (path, "database")));
}
if modules.contains(&"instructions") {
eprintln!("generating instructions...");
let inst_files = instructions::generate_instructions(&pedia, workspace)?;
generated_files.extend(inst_files);
generated_files.extend(inst_files.into_iter().map(|path| (path, "instructions")));
}
eprintln!("Formatting generated files...");
for file in &generated_files {
prepend_generated_comment_and_format(file)?;
for (file, module) in &generated_files {
prepend_generated_comment_and_format(file, module)?;
}
Ok(())
}
@@ -98,29 +98,33 @@ fn format_rust(content: impl ToTokens) -> color_eyre::Result<String> {
Ok(prettyplease::unparse(&content))
}
fn prepend_generated_comment_and_format(file_path: &std::path::Path) -> color_eyre::Result<()> {
fn prepend_generated_comment_and_format(file_path: &std::path::Path, module: &str) -> color_eyre::Result<()> {
use std::io::Write;
let tmp_path = file_path.with_extension("rs.tmp");
{
let mut tmp = std::fs::File::create(&tmp_path)?;
let src = syn::parse_file(&std::fs::read_to_string(file_path)?)?;
let formated = format_rust(quote::quote! {
// =================================================
// !! <-----> DO NOT MODIFY <-----> !!
//
// This module was automatically generated by an
// xtask
//
// run `cargo xtask generate` from the workspace
// to regenerate
//
// =================================================
let formated = format_rust(src)?;
#src
})?;
write!(&mut tmp, "{formated}")?;
write!(&mut tmp, "\
// =================================================\n\
// !! <-----> DO NOT MODIFY <-----> !!\n\
//\n\
// This module was automatically generated by an\n\
// xtask\n\
//\n\
// run\n\
//\n\
// `cargo xtask generate -m {module}` \n\
//\n\
// from the workspace to regenerate\n\
//\n\
// =================================================\n\
\n\
{formated}\
"
)?;
}
std::fs::remove_file(file_path)?;
std::fs::rename(&tmp_path, file_path)?;

View File

@@ -229,9 +229,9 @@ fn write_prefab_map<T: std::io::Write>(
writer,
"{}",
quote! {
use crate::enums::script_enums::*;
use crate::enums::basic_enums::*;
use crate::enums::{MemoryAccess, ConnectionType, ConnectionRole};
use crate::enums::script::*;
use crate::enums::basic::*;
use crate::enums::{MemoryAccess, ConnectionType, ConnectionRole, MachineTier};
use crate::templates::*;
}
)?;
@@ -241,10 +241,7 @@ fn write_prefab_map<T: std::io::Write>(
let hash = prefab.prefab().prefab_hash;
let obj = syn::parse_str::<syn::Expr>(&uneval::to_string(prefab)?)?;
let entry = quote! {
(
#hash,
#obj.into(),
)
map.insert(#hash, #obj.into());
};
Ok(entry)
})
@@ -255,9 +252,9 @@ fn write_prefab_map<T: std::io::Write>(
quote! {
pub fn build_prefab_database() -> std::collections::BTreeMap<i32, crate::templates::ObjectTemplate> {
#[allow(clippy::unreadable_literal)]
std::collections::BTreeMap::from([
#(#entries),*
])
let mut map: std::collections::BTreeMap<i32, crate::templates::ObjectTemplate> = std::collections::BTreeMap::new();
#(#entries)*
map
}
},
)?;

View File

@@ -433,8 +433,7 @@ where
"{}",
quote! {
#[derive(#(#derives),*)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
#additional_strum
#[repr(#repr)]
pub enum #name {

View File

@@ -13,7 +13,8 @@ pub fn generate_instructions(
.join("ic10emu")
.join("src")
.join("vm")
.join("instructions");
.join("instructions")
.join("codegen");
if !instructions_path.exists() {
std::fs::create_dir(&instructions_path)?;
}
@@ -84,8 +85,7 @@ fn write_instructions_enum<T: std::io::Write>(
"{}",
quote::quote! {#[derive(Debug, Display, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Serialize, Deserialize)]
#[derive(EnumIter, EnumString, EnumProperty, FromRepr)]
#[cfg_attr(feature = "tsify", derive(Tsify))]
#[cfg_attr(feature = "tsify", tsify(into_wasm_abi, from_wasm_abi))]
#[cfg_attr(feature = "tsify", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
#[strum(use_phf, serialize_all = "lowercase")]
#[serde(rename_all = "lowercase")]
pub enum InstructionOp {