refactor(vm) start impl of IC trait function

This commit is contained in:
Rachel Powers
2024-05-10 13:57:51 -07:00
parent 095e17a4fb
commit 17bde04c86
23 changed files with 2961 additions and 246 deletions

File diff suppressed because one or more lines are too long

View File

@@ -3,8 +3,8 @@ use crate::{
interpreter::ICState,
network::{CableConnectionType, Connection},
vm::enums::{
script_enums::{LogicReagentMode as ReagentMode, LogicSlotType, LogicType},
basic_enums::{Class as SlotClass, SortingClass},
script_enums::{LogicReagentMode as ReagentMode, LogicSlotType, LogicType},
},
vm::VM,
};

View File

@@ -101,7 +101,7 @@ pub enum ICError {
#[error("duplicate label {0}")]
DuplicateLabel(String),
#[error("instruction pointer out of range: '{0}'")]
InstructionPointerOutOfRange(u32),
InstructionPointerOutOfRange(usize),
#[error("register pointer out of range: '{0}'")]
RegisterIndexOutOfRange(f64),
#[error("device pointer out of range: '{0}'")]

View File

@@ -721,7 +721,7 @@ mod tests {
static INIT: std::sync::Once = std::sync::Once::new();
fn setup() {
fn setup() {
INIT.call_once(|| {
let _ = color_eyre::install();
})

View File

@@ -459,6 +459,7 @@ impl IC {
Nop => Ok(()),
Hcf => Ok(()), // TODO
Clr => Ok(()), // TODO
Clrd => Ok(()), // TODO
Label => Ok(()), // NOP
Sleep => match &operands[..] {
[a] => {
@@ -2515,7 +2516,7 @@ mod tests {
static INIT: std::sync::Once = std::sync::Once::new();
fn setup() {
fn setup() {
INIT.call_once(|| {
let _ = color_eyre::install();
})

View File

@@ -282,42 +282,6 @@ pub enum GasType {
)]
#[strum(use_phf)]
#[repr(u8)]
pub enum RocketMode {
#[strum(serialize = "Invalid", props(docs = r#""#, value = "0"))]
Invalid = 0u8,
#[strum(serialize = "None", props(docs = r#""#, value = "1"))]
#[default]
None = 1u8,
#[strum(serialize = "Mine", props(docs = r#""#, value = "2"))]
Mine = 2u8,
#[strum(serialize = "Survey", props(docs = r#""#, value = "3"))]
Survey = 3u8,
#[strum(serialize = "Discover", props(docs = r#""#, value = "4"))]
Discover = 4u8,
#[strum(serialize = "Chart", props(docs = r#""#, value = "5"))]
Chart = 5u8,
}
#[derive(
Debug,
Default,
Display,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
EnumString,
AsRefStr,
EnumProperty,
EnumIter,
FromRepr,
Serialize,
Deserialize,
)]
#[strum(use_phf)]
#[repr(u8)]
pub enum LogicSlotType {
#[strum(serialize = "None", props(docs = r#"No description"#, value = "0"))]
#[default]
@@ -2502,6 +2466,14 @@ pub enum LogicType {
)
)]
BestContactFilter = 267u16,
#[strum(
serialize = "NameHash",
props(
docs = r#"Provides the hash value for the name of the object as a 32 bit integer."#,
value = "268"
)
)]
NameHash = 268u16,
}
#[derive(
Debug,
@@ -2556,6 +2528,50 @@ pub enum PowerMode {
)]
#[strum(use_phf)]
#[repr(u8)]
pub enum PrinterInstruction {
#[strum(serialize = "None", props(docs = r#""#, value = "0"))]
#[default]
None = 0u8,
#[strum(serialize = "StackPointer", props(docs = r#""#, value = "1"))]
StackPointer = 1u8,
#[strum(serialize = "ExecuteRecipe", props(docs = r#""#, value = "2"))]
ExecuteRecipe = 2u8,
#[strum(serialize = "WaitUntilNextValid", props(docs = r#""#, value = "3"))]
WaitUntilNextValid = 3u8,
#[strum(serialize = "JumpIfNextInvalid", props(docs = r#""#, value = "4"))]
JumpIfNextInvalid = 4u8,
#[strum(serialize = "JumpToAddress", props(docs = r#""#, value = "5"))]
JumpToAddress = 5u8,
#[strum(serialize = "DeviceSetLock", props(docs = r#""#, value = "6"))]
DeviceSetLock = 6u8,
#[strum(serialize = "EjectReagent", props(docs = r#""#, value = "7"))]
EjectReagent = 7u8,
#[strum(serialize = "EjectAllReagents", props(docs = r#""#, value = "8"))]
EjectAllReagents = 8u8,
#[strum(serialize = "MissingRecipeReagent", props(docs = r#""#, value = "9"))]
MissingRecipeReagent = 9u8,
}
#[derive(
Debug,
Default,
Display,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
EnumString,
AsRefStr,
EnumProperty,
EnumIter,
FromRepr,
Serialize,
Deserialize,
)]
#[strum(use_phf)]
#[repr(u8)]
pub enum ReEntryProfile {
#[strum(serialize = "None", props(docs = r#""#, value = "0"))]
#[default]
@@ -2628,6 +2644,42 @@ pub enum RobotMode {
)]
#[strum(use_phf)]
#[repr(u8)]
pub enum RocketMode {
#[strum(serialize = "Invalid", props(docs = r#""#, value = "0"))]
Invalid = 0u8,
#[strum(serialize = "None", props(docs = r#""#, value = "1"))]
#[default]
None = 1u8,
#[strum(serialize = "Mine", props(docs = r#""#, value = "2"))]
Mine = 2u8,
#[strum(serialize = "Survey", props(docs = r#""#, value = "3"))]
Survey = 3u8,
#[strum(serialize = "Discover", props(docs = r#""#, value = "4"))]
Discover = 4u8,
#[strum(serialize = "Chart", props(docs = r#""#, value = "5"))]
Chart = 5u8,
}
#[derive(
Debug,
Default,
Display,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
EnumString,
AsRefStr,
EnumProperty,
EnumIter,
FromRepr,
Serialize,
Deserialize,
)]
#[strum(use_phf)]
#[repr(u8)]
pub enum Class {
#[strum(serialize = "None", props(docs = r#""#, value = "0"))]
#[default]
@@ -3010,12 +3062,13 @@ pub enum BasicEnum {
ElevatorMode(ElevatorMode),
EntityState(EntityState),
GasType(GasType),
GasTypeRocketMode(RocketMode),
LogicSlotType(LogicSlotType),
LogicType(LogicType),
PowerMode(PowerMode),
PrinterInstruction(PrinterInstruction),
ReEntryProfile(ReEntryProfile),
RobotMode(RobotMode),
RocketMode(RocketMode),
SlotClass(Class),
SorterInstruction(SorterInstruction),
SortingClass(SortingClass),
@@ -3034,12 +3087,13 @@ impl BasicEnum {
Self::ElevatorMode(enm) => *enm as u32,
Self::EntityState(enm) => *enm as u32,
Self::GasType(enm) => *enm as u32,
Self::GasTypeRocketMode(enm) => *enm as u32,
Self::LogicSlotType(enm) => *enm as u32,
Self::LogicType(enm) => *enm as u32,
Self::PowerMode(enm) => *enm as u32,
Self::PrinterInstruction(enm) => *enm as u32,
Self::ReEntryProfile(enm) => *enm as u32,
Self::RobotMode(enm) => *enm as u32,
Self::RocketMode(enm) => *enm as u32,
Self::SlotClass(enm) => *enm as u32,
Self::SorterInstruction(enm) => *enm as u32,
Self::SortingClass(enm) => *enm as u32,
@@ -3058,12 +3112,13 @@ impl BasicEnum {
Self::ElevatorMode(enm) => enm.get_str(prop),
Self::EntityState(enm) => enm.get_str(prop),
Self::GasType(enm) => enm.get_str(prop),
Self::GasTypeRocketMode(enm) => enm.get_str(prop),
Self::LogicSlotType(enm) => enm.get_str(prop),
Self::LogicType(enm) => enm.get_str(prop),
Self::PowerMode(enm) => enm.get_str(prop),
Self::PrinterInstruction(enm) => enm.get_str(prop),
Self::ReEntryProfile(enm) => enm.get_str(prop),
Self::RobotMode(enm) => enm.get_str(prop),
Self::RocketMode(enm) => enm.get_str(prop),
Self::SlotClass(enm) => enm.get_str(prop),
Self::SorterInstruction(enm) => enm.get_str(prop),
Self::SortingClass(enm) => enm.get_str(prop),
@@ -3083,12 +3138,13 @@ impl BasicEnum {
.chain(ElevatorMode::iter().map(|enm| Self::ElevatorMode(enm)))
.chain(EntityState::iter().map(|enm| Self::EntityState(enm)))
.chain(GasType::iter().map(|enm| Self::GasType(enm)))
.chain(RocketMode::iter().map(|enm| Self::GasTypeRocketMode(enm)))
.chain(LogicSlotType::iter().map(|enm| Self::LogicSlotType(enm)))
.chain(LogicType::iter().map(|enm| Self::LogicType(enm)))
.chain(PowerMode::iter().map(|enm| Self::PowerMode(enm)))
.chain(PrinterInstruction::iter().map(|enm| Self::PrinterInstruction(enm)))
.chain(ReEntryProfile::iter().map(|enm| Self::ReEntryProfile(enm)))
.chain(RobotMode::iter().map(|enm| Self::RobotMode(enm)))
.chain(RocketMode::iter().map(|enm| Self::RocketMode(enm)))
.chain(Class::iter().map(|enm| Self::SlotClass(enm)))
.chain(SorterInstruction::iter().map(|enm| Self::SorterInstruction(enm)))
.chain(SortingClass::iter().map(|enm| Self::SortingClass(enm)))
@@ -3155,12 +3211,6 @@ impl std::str::FromStr for BasicEnum {
"gastype.undefined" => Ok(Self::GasType(GasType::Undefined)),
"gastype.volatiles" => Ok(Self::GasType(GasType::Volatiles)),
"gastype.water" => Ok(Self::GasType(GasType::Water)),
"gastype_rocketmode.chart" => Ok(Self::GasTypeRocketMode(RocketMode::Chart)),
"gastype_rocketmode.discover" => Ok(Self::GasTypeRocketMode(RocketMode::Discover)),
"gastype_rocketmode.invalid" => Ok(Self::GasTypeRocketMode(RocketMode::Invalid)),
"gastype_rocketmode.mine" => Ok(Self::GasTypeRocketMode(RocketMode::Mine)),
"gastype_rocketmode.none" => Ok(Self::GasTypeRocketMode(RocketMode::None)),
"gastype_rocketmode.survey" => Ok(Self::GasTypeRocketMode(RocketMode::Survey)),
"logicslottype.charge" => Ok(Self::LogicSlotType(LogicSlotType::Charge)),
"logicslottype.chargeratio" => Ok(Self::LogicSlotType(LogicSlotType::ChargeRatio)),
"logicslottype.class" => Ok(Self::LogicSlotType(LogicSlotType::Class)),
@@ -3281,6 +3331,7 @@ impl std::str::FromStr for BasicEnum {
Ok(Self::LogicType(LogicType::MinimumWattsToContact))
}
"logictype.mode" => Ok(Self::LogicType(LogicType::Mode)),
"logictype.namehash" => Ok(Self::LogicType(LogicType::NameHash)),
"logictype.navpoints" => Ok(Self::LogicType(LogicType::NavPoints)),
"logictype.nextweathereventtime" => {
Ok(Self::LogicType(LogicType::NextWeatherEventTime))
@@ -3566,6 +3617,34 @@ impl std::str::FromStr for BasicEnum {
"powermode.discharged" => Ok(Self::PowerMode(PowerMode::Discharged)),
"powermode.discharging" => Ok(Self::PowerMode(PowerMode::Discharging)),
"powermode.idle" => Ok(Self::PowerMode(PowerMode::Idle)),
"printerinstruction.devicesetlock" => {
Ok(Self::PrinterInstruction(PrinterInstruction::DeviceSetLock))
}
"printerinstruction.ejectallreagents" => Ok(Self::PrinterInstruction(
PrinterInstruction::EjectAllReagents,
)),
"printerinstruction.ejectreagent" => {
Ok(Self::PrinterInstruction(PrinterInstruction::EjectReagent))
}
"printerinstruction.executerecipe" => {
Ok(Self::PrinterInstruction(PrinterInstruction::ExecuteRecipe))
}
"printerinstruction.jumpifnextinvalid" => Ok(Self::PrinterInstruction(
PrinterInstruction::JumpIfNextInvalid,
)),
"printerinstruction.jumptoaddress" => {
Ok(Self::PrinterInstruction(PrinterInstruction::JumpToAddress))
}
"printerinstruction.missingrecipereagent" => Ok(Self::PrinterInstruction(
PrinterInstruction::MissingRecipeReagent,
)),
"printerinstruction.none" => Ok(Self::PrinterInstruction(PrinterInstruction::None)),
"printerinstruction.stackpointer" => {
Ok(Self::PrinterInstruction(PrinterInstruction::StackPointer))
}
"printerinstruction.waituntilnextvalid" => Ok(Self::PrinterInstruction(
PrinterInstruction::WaitUntilNextValid,
)),
"reentryprofile.high" => Ok(Self::ReEntryProfile(ReEntryProfile::High)),
"reentryprofile.max" => Ok(Self::ReEntryProfile(ReEntryProfile::Max)),
"reentryprofile.medium" => Ok(Self::ReEntryProfile(ReEntryProfile::Medium)),
@@ -3578,6 +3657,12 @@ impl std::str::FromStr for BasicEnum {
"robotmode.roam" => Ok(Self::RobotMode(RobotMode::Roam)),
"robotmode.storagefull" => Ok(Self::RobotMode(RobotMode::StorageFull)),
"robotmode.unload" => Ok(Self::RobotMode(RobotMode::Unload)),
"rocketmode.chart" => Ok(Self::RocketMode(RocketMode::Chart)),
"rocketmode.discover" => Ok(Self::RocketMode(RocketMode::Discover)),
"rocketmode.invalid" => Ok(Self::RocketMode(RocketMode::Invalid)),
"rocketmode.mine" => Ok(Self::RocketMode(RocketMode::Mine)),
"rocketmode.none" => Ok(Self::RocketMode(RocketMode::None)),
"rocketmode.survey" => Ok(Self::RocketMode(RocketMode::Survey)),
"slotclass.accesscard" => Ok(Self::SlotClass(Class::AccessCard)),
"slotclass.appliance" => Ok(Self::SlotClass(Class::Appliance)),
"slotclass.back" => Ok(Self::SlotClass(Class::Back)),
@@ -3721,12 +3806,13 @@ impl std::fmt::Display for BasicEnum {
Self::ElevatorMode(enm) => write!(f, "ElevatorMode.{}", enm),
Self::EntityState(enm) => write!(f, "EntityState.{}", enm),
Self::GasType(enm) => write!(f, "GasType.{}", enm),
Self::GasTypeRocketMode(enm) => write!(f, "GasType_RocketMode.{}", enm),
Self::LogicSlotType(enm) => write!(f, "LogicSlotType.{}", enm),
Self::LogicType(enm) => write!(f, "LogicType.{}", enm),
Self::PowerMode(enm) => write!(f, "PowerMode.{}", enm),
Self::PrinterInstruction(enm) => write!(f, "PrinterInstruction.{}", enm),
Self::ReEntryProfile(enm) => write!(f, "ReEntryProfile.{}", enm),
Self::RobotMode(enm) => write!(f, "RobotMode.{}", enm),
Self::RocketMode(enm) => write!(f, "RocketMode.{}", enm),
Self::SlotClass(enm) => write!(f, "SlotClass.{}", enm),
Self::SorterInstruction(enm) => write!(f, "SorterInstruction.{}", enm),
Self::SortingClass(enm) => write!(f, "SortingClass.{}", enm),

View File

@@ -709,6 +709,11 @@ The <link=Norsec><color=#0080FFFF>Norsec-designed</color></link> K-cops 10-10 so
)
)]
ItemWrench = -1886261558i32,
#[strum(
serialize = "SeedBag_SugarCane",
props(name = r#"Sugarcane Seeds"#, desc = r#""#, value = "-1884103228")
)]
SeedBagSugarCane = -1884103228i32,
#[strum(
serialize = "ItemSoundCartridgeBass",
props(name = r#"Sound Cartridge Bass"#, desc = r#""#, value = "-1883441704")
@@ -1986,15 +1991,6 @@ Able to store up to 9000001 watts of power, there are no practical limits to its
props(name = r#"Kit (Tables)"#, desc = r#""#, value = "-1361598922")
)]
ItemKitTables = -1361598922i32,
#[strum(
serialize = "ItemResearchCapsuleGreen",
props(
name = r#"Research Capsule Green"#,
desc = r#""#,
value = "-1352732550"
)
)]
ItemResearchCapsuleGreen = -1352732550i32,
#[strum(
serialize = "StructureLargeHangerDoor",
props(
@@ -2041,6 +2037,11 @@ Able to store up to 9000001 watts of power, there are no practical limits to its
)
)]
StructureChuteDigitalValveRight = -1337091041i32,
#[strum(
serialize = "ItemSugarCane",
props(name = r#"Sugarcane"#, desc = r#""#, value = "-1335056202")
)]
ItemSugarCane = -1335056202i32,
#[strum(
serialize = "ItemKitSmallDirectHeatExchanger",
props(
@@ -2635,6 +2636,11 @@ Just bolt it to a <link=ThingStructureBench><color=green>Powered Bench</color></
)
)]
StructureCompositeFloorGrating3 = -1113471627i32,
#[strum(
serialize = "ItemPlainCake",
props(name = r#"Cake"#, desc = r#""#, value = "-1108244510")
)]
ItemPlainCake = -1108244510i32,
#[strum(
serialize = "ItemWreckageStructureWeatherStation004",
props(
@@ -3293,11 +3299,6 @@ Like most <link=Recurso><color=#0080FFFF>Recurso</color></link>-designed systems
props(name = r#"Kit (Liquid Tank)"#, desc = r#""#, value = "-799849305")
)]
ItemKitLiquidTank = -799849305i32,
#[strum(
serialize = "StructureResearchMachine",
props(name = r#"Research Machine"#, desc = r#""#, value = "-796627526")
)]
StructureResearchMachine = -796627526i32,
#[strum(
serialize = "StructureCompositeDoor",
props(
@@ -4448,6 +4449,11 @@ Be there, even when you're not."#,
)
)]
StructureLiquidPipeHeater = -287495560i32,
#[strum(
serialize = "ItemChocolateCake",
props(name = r#"Chocolate Cake"#, desc = r#""#, value = "-261575861")
)]
ItemChocolateCake = -261575861i32,
#[strum(
serialize = "StructureStirlingEngine",
props(
@@ -5599,6 +5605,11 @@ You can refill a <link=ThingItemGasCanisterWater><color=green>Liquid Canister (W
)
)]
KitStructureCombustionCentrifuge = 231903234i32,
#[strum(
serialize = "ItemChocolateBar",
props(name = r#"Chocolate Bar"#, desc = r#""#, value = "234601764")
)]
ItemChocolateBar = 234601764i32,
#[strum(
serialize = "ItemExplosive",
props(name = r#"Remote Explosive"#, desc = r#""#, value = "235361649")
@@ -6208,6 +6219,11 @@ Fertilizer is produced at a 1:3 ratio of fertilizer to ingredients. The fertiliz
props(name = r#"Kit (Insulated Pipe)"#, desc = r#""#, value = "452636699")
)]
ItemKitInsulatedPipe = 452636699i32,
#[strum(
serialize = "ItemCocoaPowder",
props(name = r#"Cocoa Powder"#, desc = r#""#, value = "457286516")
)]
ItemCocoaPowder = 457286516i32,
#[strum(
serialize = "AccessCardPurple",
props(name = r#"Access Card (Purple)"#, desc = r#""#, value = "459843265")
@@ -6631,6 +6647,11 @@ Normal coil has a maximum wattage of 5kW. For higher-current applications, use <
props(name = r#"Remote Detonator"#, desc = r#""#, value = "678483886")
)]
ItemRemoteDetonator = 678483886i32,
#[strum(
serialize = "ItemCocoaTree",
props(name = r#"Cocoa"#, desc = r#""#, value = "680051921")
)]
ItemCocoaTree = 680051921i32,
#[strum(
serialize = "ItemKitAirlockGate",
props(name = r#"Kit (Hangar Door)"#, desc = r#""#, value = "682546947")
@@ -6743,11 +6764,6 @@ Output = 1 exporting items inside and eventually the main item."#,
props(name = r#"Kit (Railing)"#, desc = r#""#, value = "750176282")
)]
ItemKitRailing = 750176282i32,
#[strum(
serialize = "ItemResearchCapsuleYellow",
props(name = r#"Research Capsule Yellow"#, desc = r#""#, value = "750952701")
)]
ItemResearchCapsuleYellow = 750952701i32,
#[strum(
serialize = "StructureFridgeSmall",
props(
@@ -6879,11 +6895,6 @@ A completed console displays all devices connected to the current power network.
props(name = r#"Landingpad Gas Input"#, desc = r#""#, value = "817945707")
)]
LandingpadGasConnectorInwardPiece = 817945707i32,
#[strum(
serialize = "ItemResearchCapsule",
props(name = r#"Research Capsule Blue"#, desc = r#""#, value = "819096942")
)]
ItemResearchCapsule = 819096942i32,
#[strum(
serialize = "StructureElevatorShaft",
props(name = r#"Elevator Shaft (Cabled)"#, desc = r#""#, value = "826144419")
@@ -6993,6 +7004,11 @@ Note that transformers also operate as data isolators, preventing data flowing i
)
)]
ItemCrowbar = 856108234i32,
#[strum(
serialize = "ItemChocolateCerealBar",
props(name = r#"Chocolate Cereal Bar"#, desc = r#""#, value = "860793245")
)]
ItemChocolateCerealBar = 860793245i32,
#[strum(
serialize = "Rover_MkI_build_states",
props(name = r#"Rover MKI"#, desc = r#""#, value = "861674123")
@@ -7218,11 +7234,6 @@ As the N Flow-P is a passive system, it equalizes pressure across the entire of
)
)]
StructurePictureFrameThickMountLandscapeLarge = 950004659i32,
#[strum(
serialize = "ItemResearchCapsuleRed",
props(name = r#"Research Capsule Red"#, desc = r#""#, value = "954947943")
)]
ItemResearchCapsuleRed = 954947943i32,
#[strum(
serialize = "StructureTankSmallAir",
props(name = r#"Small Tank (Air)"#, desc = r#""#, value = "955744474")
@@ -7643,6 +7654,11 @@ Normal coil has a maximum wattage of 5kW. For higher-current applications, use <
)
)]
ItemPillHeal = 1118069417i32,
#[strum(
serialize = "SeedBag_Cocoa",
props(name = r#"Cocoa Seeds"#, desc = r#""#, value = "1139887531")
)]
SeedBagCocoa = 1139887531i32,
#[strum(
serialize = "StructureMediumRocketLiquidFuelTank",
props(
@@ -8663,6 +8679,11 @@ The ProKompile can stack a wide variety of things such as <link=IngotPage><color
props(name = r#"Kit (Power Umbilical)"#, desc = r#""#, value = "1603046970")
)]
ItemKitElectricUmbilical = 1603046970i32,
#[strum(
serialize = "ItemJetpackTurbine",
props(name = r#"Turbine Jetpack"#, desc = r#""#, value = "1604261183")
)]
ItemJetpackTurbine = 1604261183i32,
#[strum(
serialize = "Lander",
props(name = r#"Lander"#, desc = r#""#, value = "1605130615")
@@ -10058,6 +10079,11 @@ The speed of heat gain or loss will depend on the liquid in question. Adding mul
)
)]
ItemRocketMiningDrillHead = 2109945337i32,
#[strum(
serialize = "ItemSugar",
props(name = r#"Sugar"#, desc = r#""#, value = "2111910840")
)]
ItemSugar = 2111910840i32,
#[strum(
serialize = "DynamicMKIILiquidCanisterEmpty",
props(

View File

@@ -2276,4 +2276,12 @@ pub enum LogicType {
)
)]
BestContactFilter = 267u16,
#[strum(
serialize = "NameHash",
props(
docs = r#"Provides the hash value for the name of the object as a 32 bit integer."#,
value = "268"
)
)]
NameHash = 268u16,
}

View File

@@ -429,6 +429,12 @@ pub enum InstructionOp {
operands = "1"
))]
Clr,
#[strum(props(
example = "clrd id(r?|num)",
desc = "Seeks directly for the provided device id and clears the stack memory of that device",
operands = "1"
))]
Clrd,
#[strum(props(
example = "cos r? a(r?|num)",
desc = "Returns the cosine of the specified angle (radians)",
@@ -970,6 +976,7 @@ impl InstructionOp {
Self::Brnez => ic.execute_brnez(vm, &operands[0], &operands[1]),
Self::Ceil => ic.execute_ceil(vm, &operands[0], &operands[1]),
Self::Clr => ic.execute_clr(vm, &operands[0]),
Self::Clrd => ic.execute_clrd(vm, &operands[0]),
Self::Cos => ic.execute_cos(vm, &operands[0], &operands[1]),
Self::Define => ic.execute_define(vm, &operands[0], &operands[1]),
Self::Div => ic.execute_div(vm, &operands[0], &operands[1], &operands[2]),

View File

@@ -7,6 +7,8 @@ use crate::vm::instructions::enums::InstructionOp;
use serde_derive::{Deserialize, Serialize};
use strum::EnumProperty;
use super::traits::IntegratedCircuit;
#[derive(PartialEq, Eq, Debug, Clone, Copy, Serialize, Deserialize)]
pub enum Device {
Db,
@@ -57,9 +59,9 @@ pub enum Operand {
}
impl Operand {
pub fn as_value(
pub fn as_value<IC: IntegratedCircuit>(
&self,
ic: &interpreter::IC,
ic: &IC,
inst: InstructionOp,
index: u32,
) -> Result<f64, ICError> {
@@ -121,9 +123,9 @@ impl Operand {
}
}
pub fn as_value_i64(
pub fn as_value_i64<IC: IntegratedCircuit>(
&self,
ic: &interpreter::IC,
ic: &IC,
signed: bool,
inst: InstructionOp,
index: u32,
@@ -142,9 +144,9 @@ impl Operand {
}
}
}
pub fn as_value_i32(
pub fn as_value_i32<IC: IntegratedCircuit>(
&self,
ic: &interpreter::IC,
ic: &IC,
signed: bool,
inst: InstructionOp,
index: u32,
@@ -153,9 +155,9 @@ impl Operand {
Self::Number(num) => Ok(num.value_i64(signed) as i32),
_ => {
let val = self.as_value(ic, inst, index)?;
if val < -2147483648.0 {
if val < i32::MIN as f64 {
Err(ICError::ShiftUnderflowI32)
} else if val <= 2147483647.0 {
} else if val <= i32::MAX as f64 {
Ok(val as i32)
} else {
Err(ICError::ShiftOverflowI32)
@@ -164,9 +166,9 @@ impl Operand {
}
}
pub fn as_register(
pub fn as_register<IC: IntegratedCircuit>(
&self,
ic: &interpreter::IC,
ic: &IC,
inst: InstructionOp,
index: u32,
) -> Result<RegisterSpec, ICError> {
@@ -181,9 +183,9 @@ impl Operand {
}
}
pub fn as_device(
pub fn as_device<IC: IntegratedCircuit>(
&self,
ic: &interpreter::IC,
ic: &IC,
inst: InstructionOp,
index: u32,
) -> Result<(Option<u32>, Option<usize>), ICError> {
@@ -222,9 +224,9 @@ impl Operand {
}
}
pub fn as_logic_type(
pub fn as_logic_type<IC: IntegratedCircuit>(
&self,
ic: &interpreter::IC,
ic: &IC,
inst: InstructionOp,
index: u32,
) -> Result<LogicType, ICError> {
@@ -237,9 +239,9 @@ impl Operand {
}
}
pub fn as_slot_logic_type(
pub fn as_slot_logic_type<IC: IntegratedCircuit>(
&self,
ic: &interpreter::IC,
ic: &IC,
inst: InstructionOp,
index: u32,
) -> Result<LogicSlotType, ICError> {
@@ -252,9 +254,9 @@ impl Operand {
}
}
pub fn as_batch_mode(
pub fn as_batch_mode<IC: IntegratedCircuit>(
&self,
ic: &interpreter::IC,
ic: &IC,
inst: InstructionOp,
index: u32,
) -> Result<BatchMode, ICError> {
@@ -267,9 +269,9 @@ impl Operand {
}
}
pub fn as_reagent_mode(
pub fn as_reagent_mode<IC: IntegratedCircuit>(
&self,
ic: &interpreter::IC,
ic: &IC,
inst: InstructionOp,
index: u32,
) -> Result<ReagentMode, ICError> {
@@ -282,7 +284,7 @@ impl Operand {
}
}
pub fn translate_alias(&self, ic: &interpreter::IC) -> Self {
pub fn translate_alias<IC: IntegratedCircuit>(&self, ic: &IC) -> Self {
match &self {
Operand::Identifier(id) | Operand::Type { identifier: id, .. } => {
if let Some(alias) = ic.aliases.borrow().get(&id.name) {

View File

@@ -13,19 +13,27 @@ use crate::errors::ICError;
use crate::vm::object::traits::{Logicable, MemoryWritable, SourceCode};
use std::collections::BTreeMap;
pub trait IntegratedCircuit: Logicable + MemoryWritable + SourceCode {
fn get_instruciton_pointer(&self) -> usize;
fn set_next_instruction(&mut self, next_instruction: usize);
fn get_instruction_pointer(&self) -> f64;
fn set_next_instruction(&mut self, next_instruction: f64);
fn set_next_instruction_relative(&mut self, offset: f64) {
self.set_next_instruction(self.get_instruction_pointer() + offset);
}
fn reset(&mut self);
fn get_real_target(&self, indirection: u32, target: u32) -> Result<f64, ICError>;
fn get_register(&self, indirection: u32, target: u32) -> Result<f64, ICError>;
fn set_register(&mut self, indirection: u32, target: u32, val: f64) -> Result<f64, ICError>;
fn set_return_address(&mut self, addr: f64);
fn al(&mut self) {
self.set_return_address(self.get_instruction_pointer() + 1.0);
}
fn push_stack(&mut self, val: f64) -> Result<f64, ICError>;
fn pop_stack(&mut self) -> Result<f64, ICError>;
fn peek_stack(&self) -> Result<f64, ICError>;
fn get_stack(&self, addr: f64) -> Result<f64, ICError>;
fn put_stack(&self, addr: f64, val: f64) -> Result<f64, ICError>;
fn get_aliases(&self) -> &BTreeMap<String, crate::vm::instructions::operands::Operand>;
fn get_defines(&self) -> &BTreeMap<String, f64>;
fn get_lables(&self) -> &BTreeMap<String, u32>;
fn get_labels(&self) -> &BTreeMap<String, u32>;
}
pub trait AbsInstruction: IntegratedCircuit {
/// abs r? a(r?|num)
@@ -60,7 +68,7 @@ pub trait AliasInstruction: IntegratedCircuit {
fn execute_alias(
&mut self,
vm: &crate::vm::VM,
str: &crate::vm::instructions::operands::Operand,
string: &crate::vm::instructions::operands::Operand,
r: &crate::vm::instructions::operands::Operand,
) -> Result<(), crate::errors::ICError>;
}
@@ -659,6 +667,14 @@ pub trait ClrInstruction: IntegratedCircuit {
d: &crate::vm::instructions::operands::Operand,
) -> Result<(), crate::errors::ICError>;
}
pub trait ClrdInstruction: IntegratedCircuit {
/// clrd id(r?|num)
fn execute_clrd(
&mut self,
vm: &crate::vm::VM,
id: &crate::vm::instructions::operands::Operand,
) -> Result<(), crate::errors::ICError>;
}
pub trait CosInstruction: IntegratedCircuit {
/// cos r? a(r?|num)
fn execute_cos(
@@ -673,7 +689,7 @@ pub trait DefineInstruction: IntegratedCircuit {
fn execute_define(
&mut self,
vm: &crate::vm::VM,
str: &crate::vm::instructions::operands::Operand,
string: &crate::vm::instructions::operands::Operand,
num: &crate::vm::instructions::operands::Operand,
) -> Result<(), crate::errors::ICError>;
}
@@ -769,7 +785,7 @@ pub trait LabelInstruction: IntegratedCircuit {
&mut self,
vm: &crate::vm::VM,
d: &crate::vm::instructions::operands::Operand,
str: &crate::vm::instructions::operands::Operand,
string: &crate::vm::instructions::operands::Operand,
) -> Result<(), crate::errors::ICError>;
}
pub trait LbInstruction: IntegratedCircuit {
@@ -1450,6 +1466,7 @@ pub trait ICInstructable:
+ BrnezInstruction
+ CeilInstruction
+ ClrInstruction
+ ClrdInstruction
+ CosInstruction
+ DefineInstruction
+ DivInstruction
@@ -1595,6 +1612,7 @@ impl<T> ICInstructable for T where
+ BrnezInstruction
+ CeilInstruction
+ ClrInstruction
+ ClrdInstruction
+ CosInstruction
+ DefineInstruction
+ DivInstruction

View File

@@ -1,4 +1,4 @@
use std::{cell::RefCell, ops::Deref, rc::Rc};
use std::{cell::RefCell, ops::Deref, rc::Rc, str::FromStr};
use macro_rules_attribute::derive;
use serde_derive::{Deserialize, Serialize};
@@ -14,6 +14,8 @@ use traits::*;
use crate::vm::enums::{basic_enums::Class as SlotClass, script_enums::LogicSlotType};
use super::enums::prefabs::StationpediaPrefab;
pub type ObjectID = u32;
pub type BoxedObject = Rc<RefCell<dyn Object<ID = ObjectID>>>;
@@ -51,6 +53,24 @@ impl Name {
hash: const_crc32::crc32(name.as_bytes()) as i32,
}
}
pub fn from_prefab_name(name: &str) -> Self {
Name {
value: name.to_string(),
hash: StationpediaPrefab::from_str(name)
.map(|prefab| prefab as i32)
.unwrap_or_else(|_| const_crc32::crc32(name.as_bytes()) as i32),
}
}
pub fn from_prefab_hash(hash: i32) -> Option<Self> {
if let Some(prefab) = StationpediaPrefab::from_repr(hash) {
Some(Name {
value: prefab.to_string(),
hash: hash,
})
} else {
None
}
}
pub fn set(&mut self, name: &str) {
self.value = name.to_owned();
self.hash = const_crc32::crc32(name.as_bytes()) as i32;
@@ -72,6 +92,9 @@ pub struct LogicField {
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
pub struct Slot {
pub parent: ObjectID,
pub index: usize,
pub name: String,
pub typ: SlotClass,
pub enabled_logic: Vec<LogicSlotType>,
pub occupant: Option<ObjectID>,

View File

@@ -1,3 +1,22 @@
macro_rules! GWStorage {
(
$( #[$attr:meta] )*
$viz:vis struct $struct:ident {
$($body:tt)*
}
) => {
impl GWStorage for $struct {
fn slots(&self) -> &Vec<Slot> {
&self.slots
}
fn slots_mut(&mut self) -> &mut Vec<Slot> {
&mut self.slots
}
}
};
}
pub(crate) use GWStorage;
macro_rules! GWLogicable {
(
$( #[$attr:meta] )*
@@ -6,21 +25,12 @@ macro_rules! GWLogicable {
}
) => {
impl GWLogicable for $struct {
fn name(&self) -> &Option<Name> {
&self.name
}
fn fields(&self) -> &BTreeMap<LogicType, LogicField> {
&self.fields
}
fn fields_mut(&mut self) -> &mut BTreeMap<LogicType, LogicField> {
&mut self.fields
}
fn slots(&self) -> &Vec<Slot> {
&self.slots
}
fn slots_mut(&mut self) -> &mut Vec<Slot> {
&mut self.slots
}
}
};
}
@@ -73,3 +83,22 @@ macro_rules! GWDevice {
};
}
pub(crate) use GWDevice;
macro_rules! GWItem {
(
$( #[$attr:meta] )*
$viz:vis struct $struct:ident {
$($body:tt)*
}
) => {
impl GWItem for $struct {
fn item_info(&self) -> &ItemInfo {
&self.item_info
}
fn parent_slot(&self) -> Option<ParentSlotInfo> {
self.parent_slot
}
}
};
}
pub(crate) use GWItem;

View File

@@ -2,92 +2,160 @@ use super::{macros::*, traits::*};
use crate::vm::{
enums::script_enums::LogicType,
object::{macros::ObjectInterface, traits::*, LogicField, Name, ObjectID, Slot},
object::{
macros::ObjectInterface, templates::ItemInfo, traits::*, LogicField, Name, ObjectID, Slot,
},
};
use macro_rules_attribute::derive;
use std::{collections::BTreeMap, usize};
use std::collections::BTreeMap;
#[derive(ObjectInterface!)]
#[custom(implements(Object { }))]
pub struct Generic {
#[custom(object_id)]
id: ObjectID,
pub id: ObjectID,
#[custom(object_prefab)]
prefab: Name,
pub prefab: Name,
#[custom(object_name)]
pub name: Name,
}
#[derive(ObjectInterface!, GWLogicable!)]
#[custom(implements(Object { Logicable }))]
#[derive(ObjectInterface!, GWStorage!)]
#[custom(implements(Object { Storage }))]
pub struct GenericStorage {
#[custom(object_id)]
pub id: ObjectID,
#[custom(object_prefab)]
pub prefab: Name,
#[custom(object_name)]
pub name: Name,
pub slots: Vec<Slot>,
}
#[derive(ObjectInterface!, GWStorage!, GWLogicable!)]
#[custom(implements(Object { Storage, Logicable }))]
pub struct GenericLogicable {
#[custom(object_id)]
id: ObjectID,
pub id: ObjectID,
#[custom(object_prefab)]
prefab: Name,
name: Option<Name>,
fields: BTreeMap<LogicType, LogicField>,
slots: Vec<Slot>,
pub prefab: Name,
#[custom(object_name)]
pub name: Name,
pub fields: BTreeMap<LogicType, LogicField>,
pub slots: Vec<Slot>,
}
#[derive(ObjectInterface!, GWLogicable!, GWDevice!)]
#[custom(implements(Object { Logicable, Device }))]
#[derive(ObjectInterface!, GWStorage!, GWLogicable!, GWDevice!)]
#[custom(implements(Object { Storage, Logicable, Device }))]
pub struct GenericLogicableDevice {
#[custom(object_id)]
id: ObjectID,
pub id: ObjectID,
#[custom(object_prefab)]
prefab: Name,
name: Option<Name>,
fields: BTreeMap<LogicType, LogicField>,
slots: Vec<Slot>,
pub prefab: Name,
#[custom(object_name)]
pub name: Name,
pub fields: BTreeMap<LogicType, LogicField>,
pub slots: Vec<Slot>,
}
#[derive(ObjectInterface!, GWLogicable!, GWMemoryReadable!)]
#[custom(implements(Object { Logicable, MemoryReadable }))]
pub struct GenericLogicableMemoryReadable {
#[custom(object_id)]
id: ObjectID,
#[custom(object_prefab)]
prefab: Name,
name: Option<Name>,
fields: BTreeMap<LogicType, LogicField>,
slots: Vec<Slot>,
memory: Vec<f64>,
}
#[derive(ObjectInterface!, GWLogicable!, GWMemoryReadable!, GWMemoryWritable!)]
#[custom(implements(Object { Logicable, MemoryReadable, MemoryWritable }))]
pub struct GenericLogicableMemoryReadWritable {
#[custom(object_id)]
id: ObjectID,
#[custom(object_prefab)]
prefab: Name,
name: Option<Name>,
fields: BTreeMap<LogicType, LogicField>,
slots: Vec<Slot>,
memory: Vec<f64>,
}
#[derive(ObjectInterface!, GWLogicable!, GWDevice!, GWMemoryReadable!, GWMemoryWritable!)]
#[custom(implements(Object { Logicable, Device, MemoryReadable }))]
#[derive(ObjectInterface!, GWStorage!, GWLogicable!, GWDevice!, GWMemoryReadable!, GWMemoryWritable!)]
#[custom(implements(Object { Storage, Logicable, Device, MemoryReadable }))]
pub struct GenericLogicableDeviceMemoryReadable {
#[custom(object_id)]
id: ObjectID,
pub id: ObjectID,
#[custom(object_prefab)]
prefab: Name,
name: Option<Name>,
fields: BTreeMap<LogicType, LogicField>,
slots: Vec<Slot>,
memory: Vec<f64>,
pub prefab: Name,
#[custom(object_name)]
pub name: Name,
pub fields: BTreeMap<LogicType, LogicField>,
pub slots: Vec<Slot>,
pub memory: Vec<f64>,
}
#[derive(ObjectInterface!, GWLogicable!, GWDevice!, GWMemoryReadable!, GWMemoryWritable!)]
#[custom(implements(Object { Logicable, Device, MemoryReadable, MemoryWritable }))]
pub struct GenericLogicableDeviceMemoryReadWriteablable {
#[derive(ObjectInterface!, GWStorage!, GWLogicable!, GWDevice!, GWMemoryReadable!, GWMemoryWritable!)]
#[custom(implements(Object { Storage, Logicable, Device, MemoryReadable, MemoryWritable }))]
pub struct GenericLogicableDeviceMemoryReadWriteable {
#[custom(object_id)]
id: ObjectID,
pub id: ObjectID,
#[custom(object_prefab)]
prefab: Name,
name: Option<Name>,
fields: BTreeMap<LogicType, LogicField>,
slots: Vec<Slot>,
memory: Vec<f64>,
pub prefab: Name,
#[custom(object_name)]
pub name: Name,
pub fields: BTreeMap<LogicType, LogicField>,
pub slots: Vec<Slot>,
pub memory: Vec<f64>,
}
#[derive(ObjectInterface!, GWItem!)]
#[custom(implements(Object { Item }))]
pub struct GenericItem {
#[custom(object_id)]
pub id: ObjectID,
#[custom(object_prefab)]
pub prefab: Name,
#[custom(object_name)]
pub name: Name,
pub item_info: ItemInfo,
pub parent_slot: Option<ParentSlotInfo>,
}
#[derive(ObjectInterface!, GWItem!, GWStorage! )]
#[custom(implements(Object { Item, Storage }))]
pub struct GenericItemStorage {
#[custom(object_id)]
pub id: ObjectID,
#[custom(object_prefab)]
pub prefab: Name,
#[custom(object_name)]
pub name: Name,
pub item_info: ItemInfo,
pub parent_slot: Option<ParentSlotInfo>,
pub slots: Vec<Slot>,
}
#[derive(ObjectInterface!, GWItem!, GWStorage!, GWLogicable! )]
#[custom(implements(Object { Item, Storage, Logicable }))]
pub struct GenericItemLogicable {
#[custom(object_id)]
pub id: ObjectID,
#[custom(object_prefab)]
pub prefab: Name,
#[custom(object_name)]
pub name: Name,
pub item_info: ItemInfo,
pub parent_slot: Option<ParentSlotInfo>,
pub fields: BTreeMap<LogicType, LogicField>,
pub slots: Vec<Slot>,
}
#[derive(ObjectInterface!, GWItem!, GWStorage!, GWLogicable!, GWMemoryReadable! )]
#[custom(implements(Object { Item, Storage, Logicable, MemoryReadable }))]
pub struct GenericItemLogicableMemoryReadable {
#[custom(object_id)]
pub id: ObjectID,
#[custom(object_prefab)]
pub prefab: Name,
#[custom(object_name)]
pub name: Name,
pub item_info: ItemInfo,
pub parent_slot: Option<ParentSlotInfo>,
pub fields: BTreeMap<LogicType, LogicField>,
pub slots: Vec<Slot>,
pub memory: Vec<f64>,
}
#[derive(ObjectInterface!, GWItem!, GWStorage!, GWLogicable!, GWMemoryReadable!, GWMemoryWritable! )]
#[custom(implements(Object { Item, Storage, Logicable, MemoryReadable, MemoryWritable }))]
pub struct GenericItemLogicableMemoryReadWriteable {
#[custom(object_id)]
pub id: ObjectID,
#[custom(object_prefab)]
pub prefab: Name,
#[custom(object_name)]
pub name: Name,
pub item_info: ItemInfo,
pub parent_slot: Option<ParentSlotInfo>,
pub fields: BTreeMap<LogicType, LogicField>,
pub slots: Vec<Slot>,
pub memory: Vec<f64>,
}

View File

@@ -1,41 +1,47 @@
use crate::vm::{
enums::script_enums::{LogicSlotType, LogicType},
enums::{
basic_enums::{Class as SlotClass, GasType, SortingClass},
script_enums::{LogicSlotType, LogicType},
},
object::{
errors::{LogicError, MemoryError},
templates::ItemInfo,
traits::*,
LogicField, MemoryAccess, Name, Slot,
LogicField, MemoryAccess, Slot,
},
VM,
};
use std::{collections::BTreeMap, usize};
use strum::IntoEnumIterator;
pub trait GWLogicable {
fn name(&self) -> &Option<Name>;
fn fields(&self) -> &BTreeMap<LogicType, LogicField>;
fn fields_mut(&mut self) -> &mut BTreeMap<LogicType, LogicField>;
pub trait GWStorage {
fn slots(&self) -> &Vec<Slot>;
fn slots_mut(&mut self) -> &mut Vec<Slot>;
}
pub trait GWMemoryReadable {
fn memory_size(&self) -> usize;
fn memory(&self) -> &Vec<f64>;
}
pub trait GWMemoryWritable: GWMemoryReadable {
fn memory_mut(&mut self) -> &mut Vec<f64>;
impl<T: GWStorage + Object> Storage for T {
fn slots_count(&self) -> usize {
self.slots().len()
}
fn get_slot(&self, index: usize) -> Option<&Slot> {
self.slots().get(index)
}
fn get_slot_mut(&mut self, index: usize) -> Option<&mut Slot> {
self.slots_mut().get_mut(index)
}
}
pub trait GWDevice: GWLogicable {}
pub trait GWCircuitHolder: GWLogicable {}
pub trait GWLogicable: Storage {
fn fields(&self) -> &BTreeMap<LogicType, LogicField>;
fn fields_mut(&mut self) -> &mut BTreeMap<LogicType, LogicField>;
}
impl<T: GWLogicable + Object> Logicable for T {
fn prefab_hash(&self) -> i32 {
self.prefab().hash
}
fn name_hash(&self) -> i32 {
self.name().as_ref().map(|name| name.hash).unwrap_or(0)
self.name().hash
}
fn is_logic_readable(&self) -> bool {
LogicType::iter().any(|lt| self.can_logic_read(lt))
@@ -90,15 +96,6 @@ impl<T: GWLogicable + Object> Logicable for T {
_ => Err(LogicError::CantWrite(lt)),
})
}
fn slots_count(&self) -> usize {
self.slots().len()
}
fn get_slot(&self, index: usize) -> Option<&Slot> {
self.slots().get(index)
}
fn get_slot_mut(&mut self, index: usize) -> Option<&mut Slot> {
self.slots_mut().get_mut(index)
}
fn can_slot_logic_read(&self, slt: LogicSlotType, index: usize) -> bool {
self.get_slot(index)
.map(|slot| slot.enabled_logic.contains(&slt))
@@ -111,7 +108,7 @@ impl<T: GWLogicable + Object> Logicable for T {
_vm: &VM,
) -> Result<f64, LogicError> {
self.get_slot(index)
.ok_or_else(|| LogicError::SlotIndexOutOfRange(index, self.slots().len()))
.ok_or_else(|| LogicError::SlotIndexOutOfRange(index, self.slots_count()))
.and_then(|slot| {
if slot.enabled_logic.contains(&slt) {
match slot.occupant {
@@ -128,6 +125,11 @@ impl<T: GWLogicable + Object> Logicable for T {
}
}
pub trait GWMemoryReadable {
fn memory_size(&self) -> usize;
fn memory(&self) -> &Vec<f64>;
}
impl<T: GWMemoryReadable + Object> MemoryReadable for T {
fn memory_size(&self) -> usize {
self.memory_size()
@@ -142,12 +144,17 @@ impl<T: GWMemoryReadable + Object> MemoryReadable for T {
}
}
}
pub trait GWMemoryWritable: MemoryReadable {
fn memory_mut(&mut self) -> &mut Vec<f64>;
}
impl<T: GWMemoryWritable + MemoryReadable + Object> MemoryWritable for T {
fn set_memory(&mut self, index: i32, val: f64) -> Result<(), MemoryError> {
if index < 0 {
Err(MemoryError::StackUnderflow(index, self.memory().len()))
} else if index as usize >= self.memory().len() {
Err(MemoryError::StackOverflow(index, self.memory().len()))
Err(MemoryError::StackUnderflow(index, self.memory_size()))
} else if index as usize >= self.memory_size() {
Err(MemoryError::StackOverflow(index, self.memory_size()))
} else {
self.memory_mut()[index as usize] = val;
Ok(())
@@ -159,4 +166,40 @@ impl<T: GWMemoryWritable + MemoryReadable + Object> MemoryWritable for T {
}
}
pub trait GWDevice: Logicable {}
impl<T: GWDevice + Object> Device for T {}
pub trait GWItem {
fn item_info(&self) -> &ItemInfo;
fn parent_slot(&self) -> Option<ParentSlotInfo>;
}
impl<T: GWItem + Object> Item for T {
fn consumable(&self) -> bool {
self.item_info().consumable
}
fn filter_type(&self) -> Option<GasType> {
self.item_info().filter_type
}
fn ingredient(&self) -> bool {
self.item_info().ingredient
}
fn max_quantity(&self) -> u32 {
self.item_info().max_quantity
}
fn reagents(&self) -> Option<&BTreeMap<String, f64>> {
self.item_info().reagents.as_ref()
}
fn slot_class(&self) -> SlotClass {
self.item_info().slot_class
}
fn sorting_class(&self) -> SortingClass {
self.item_info().sorting_class
}
fn parent_slot(&self) -> Option<ParentSlotInfo> {
self.parent_slot()
}
}
pub trait GWCircuitHolder: Logicable {}

View File

@@ -11,6 +11,7 @@ macro_rules! object_trait {
type ID;
fn id(&self) -> &Self::ID;
fn prefab(&self) -> &crate::vm::object::Name;
fn name(&self) -> &crate::vm::object::Name;
fn type_name(&self) -> &str;
@@ -47,11 +48,12 @@ pub(crate) use object_trait;
macro_rules! ObjectInterface {
{
@final
@body_id_prefab_name
@trt $trait_name:ident; $struct:ident;
@impls $($trt:path),*;
@id $id_field:ident: $id_typ:ty;
@prefab $prefab_field:ident: $prefab_typ:ty;
@name $name_field:ident: $name_typ:ty;
} => {
impl $trait_name for $struct {
type ID = $id_typ;
@@ -60,10 +62,14 @@ macro_rules! ObjectInterface {
&self.$id_field
}
fn prefab(&self) -> &crate::vm::object::Name {
fn prefab(&self) -> &$prefab_typ {
&self.$prefab_field
}
fn name(&self) -> &$name_typ {
&self.$name_field
}
fn type_name(&self) -> &str {
std::any::type_name::<Self>()
}
@@ -92,6 +98,209 @@ macro_rules! ObjectInterface {
}
};
{
@body_id_name
@trt $trait_name:ident; $struct:ident;
@impls $($trt:path),*;
@id $id_field:ident: $id_typ:ty;
@name $name_field:ident: $name_typ:ty;
#[custom(object_prefab)]
$(#[$prefab_attr:meta])*
$prefab_viz:vis $prefab_field:ident: $prefab_typ:ty,
$( $rest:tt )*
} => {
$crate::vm::object::macros::ObjectInterface!{
@body_id_prefab_name
@trt $trait_name; $struct;
@impls $($trt),*;
@id $id_field: $id_typ;
@prefab $prefab_field: $prefab_typ;
@name $name_field: $name_typ;
}
};
{
@body_id_name
@trt $trait_name:ident; $struct:ident;
@impls $($trt:path),*;
@id $id_field:ident: $id_typ:ty;
@name $name_field:ident: $name_typ:ty;
$(#[#field:meta])*
$field_viz:vis
$field_name:ident : $field_ty:ty,
$( $rest:tt )*
} => {
$crate::vm::object::macros::ObjectInterface!{
@body_id_name
@trt $trait_name; $struct;
@impls $($trt),*;
@id $id_field: $id_typ;
@name $name_field: $name_typ;
$( $rest )*
}
};
{
@body_id_prefab
@trt $trait_name:ident; $struct:ident;
@impls $($trt:path),*;
@id $id_field:ident: $id_typ:ty;
@prefab $prefab_field:ident: $prefab_typ:ty;
#[custom(object_name)]
$(#[$name_attr:meta])*
$name_viz:vis $name_field:ident: $name_typ:ty,
$( $rest:tt )*
} => {
$crate::vm::object::macros::ObjectInterface!{
@body_id_prefab_name
@trt $trait_name; $struct;
@impls $($trt),*;
@id $id_field: $id_typ;
@prefab $prefab_field: $prefab_typ;
@name $name_field: $name_typ;
}
};
{
@body_id_prefab
@trt $trait_name:ident; $struct:ident;
@impls $($trt:path),*;
@id $id_field:ident: $id_typ:ty;
@prefab $prefab_field:ident: $prefab_typ:ty;
$(#[#field:meta])*
$field_viz:vis
$field_name:ident : $field_ty:ty,
$( $rest:tt )*
} => {
$crate::vm::object::macros::ObjectInterface!{
@body_id_prefab
@trt $trait_name; $struct;
@impls $($trt),*;
@id $id_field: $id_typ;
@prefab $prefab_field: $prefab_typ;
$( $rest )*
}
};
{
@body_prefab_name
@trt $trait_name:ident; $struct:ident;
@impls $($trt:path),*;
@prefab $prefab_field:ident: $prefab_typ:ty;
@name $name_field:ident: $name_typ:ty;
#[custom(object_id)]
$(#[$id_attr:meta])*
$id_viz:vis $id_field:ident: $id_typ:ty,
$( $rest:tt )*
} => {
$crate::vm::object::macros::ObjectInterface!{
@body_id_prefab_name
@trt $trait_name; $struct;
@impls $($trt),*;
@prefab $prefab_field: $prefab_typ;
@name $name_field: $name_typ;
}
};
{
@body_prefab_name
@trt $trait_name:ident; $struct:ident;
@impls $($trt:path),*;
@prefab $prefab_field:ident: $prefab_typ:ty;
@name $name_field:ident: $name_typ:ty;
$(#[#field:meta])*
$field_viz:vis
$field_name:ident : $field_ty:ty,
$( $rest:tt )*
} => {
$crate::vm::object::macros::ObjectInterface!{
@body_prefab_name
@trt $trait_name; $struct;
@impls $($trt),*;
@prefab $prefab_field: $prefab_typ;
@name $name_field: $name_typ;
$( $rest )*
}
};
{
@body_name
@trt $trait_name:ident; $struct:ident;
@impls $($trt:path),*;
@name $name_field:ident: $name_typ:ty;
#[custom(object_prefab)]
$(#[$prefab_attr:meta])*
$prefab_viz:vis $prefab_field:ident: $prefab_typ:ty,
$( $rest:tt )*
} => {
$crate::vm::object::macros::ObjectInterface!{
@body_prefab_name
@trt $trait_name; $struct;
@impls $($trt),*;
@prefab $prefab_field: $prefab_typ;
@name $name_field: $name_typ;
$( $rest )*
}
};
{
@body_name
@trt $trait_name:ident; $struct:ident;
@impls $($trt:path),*;
@name $name_field:ident: $name_typ:ty;
#[custom(object_id)]
$(#[$id_attr:meta])*
$id_viz:vis $id_field:ident: $id_typ:ty,
$( $rest:tt )*
} => {
$crate::vm::object::macros::ObjectInterface!{
@body_id_name
@trt $trait_name; $struct;
@impls $($trt),*;
@id $id_field: $id_typ;
@name $name_field: $name_typ;
$( $rest )*
}
};
{
@body_name
@trt $trait_name:ident; $struct:ident;
@impls $($trt:path),*;
@name $name_field:ident: $name_typ:ty;
$(#[#field:meta])*
$field_viz:vis
$field_name:ident : $field_ty:ty,
$( $rest:tt )*
} => {
$crate::vm::object::macros::ObjectInterface!{
@body_name
@trt $trait_name; $struct;
@impls $($trt),*;
@name $name_field: $name_typ;
$( $rest )*
}
};
{
@body_id
@trt $trait_name:ident; $struct:ident;
@impls $($trt:path),*;
@id $id_field:ident: $id_typ:ty;
#[custom(object_name)]
$(#[$name_attr:meta])*
$name_viz:vis $name_field:ident: $name_typ:ty,
$( $rest:tt )*
} => {
$crate::vm::object::macros::ObjectInterface!{
@body_id_name
@trt $trait_name; $struct;
@impls $($trt),*;
@id $id_field: $id_typ;
@name $name_field: $name_typ;
$( $rest )*
}
};
{
@body_id
@trt $trait_name:ident; $struct:ident;
@@ -103,11 +312,12 @@ macro_rules! ObjectInterface {
$( $rest:tt )*
} => {
$crate::vm::object::macros::ObjectInterface!{
@final
@body_id_prefab
@trt $trait_name; $struct;
@impls $($trt),*;
@id $id_field: $id_typ;
@prefab $prefab_field: $prefab_typ;
$( $rest )*
}
};
{
@@ -128,6 +338,26 @@ macro_rules! ObjectInterface {
$( $rest )*
}
};
{
@body_prefab
@trt $trait_name:ident; $struct:ident;
@impls $($trt:path),*;
@prefab $prefab_field:ident: $prefab_typ:ty;
#[custom(object_name)]
$(#[$name_attr:meta])*
$name_viz:vis $name_field:ident: $name_typ:ty,
$( $rest:tt )*
} => {
$crate::vm::object::macros::ObjectInterface!{
@body_prefab_name
@trt $trait_name; $struct;
@impls $($trt),*;
@prefab $prefab_field: $prefab_typ;
@name $name_field: $name_typ;
$( $rest )*
}
};
{
@body_prefab
@trt $trait_name:ident; $struct:ident;
@@ -140,11 +370,12 @@ macro_rules! ObjectInterface {
} => {
$crate::vm::object::macros::ObjectInterface!{
@final
@body_id_prefab
@trt $trait_name; $struct;
@impls $($trt),*;
@id $id_field: $id_typ;
@prefab $prefab_field: $prefab_typ;
$( $rest )*
}
};
{
@@ -166,6 +397,24 @@ macro_rules! ObjectInterface {
$( $rest )*
}
};
{
@body
@trt $trait_name:ident; $struct:ident;
@impls $($trt:path),*;
#[custom(object_name)]
$(#[$name_attr:meta])*
$name_viz:vis $name_field:ident: $name_typ:ty,
$( $rest:tt )*
} => {
$crate::vm::object::macros::ObjectInterface!{
@body_name
@trt $trait_name; $struct;
@impls $($trt),*;
@name $name_field: $name_typ;
$( $rest )*
}
};
{
@body
@trt $trait_name:ident; $struct:ident;

View File

@@ -1,22 +1,18 @@
use std::str::FromStr;
use crate::vm::enums::prefabs::StationpediaPrefab;
use crate::vm::object::VMObject;
#[allow(unused)]
pub enum PrefabTemplate {
Hash(i32),
Name(String),
}
use super::templates::ObjectTemplate;
use super::ObjectID;
pub mod structs;
#[allow(unused)]
pub fn object_from_prefab_template(template: &PrefabTemplate) -> Option<VMObject> {
let prefab = match template {
PrefabTemplate::Hash(hash) => StationpediaPrefab::from_repr(*hash),
PrefabTemplate::Name(name) => StationpediaPrefab::from_str(name).ok(),
};
pub fn object_from_prefab_template(template: &ObjectTemplate, id: ObjectID) -> Option<VMObject> {
let prefab = StationpediaPrefab::from_repr(template.prefab().prefab_hash);
match prefab {
// Some(StationpediaPrefab::ItemIntegratedCircuit10) => Some()
Some(StationpediaPrefab::ItemIntegratedCircuit10) => {
Some(VMObject::new(structs::ItemIntegratedCircuit10))
}
// Some(StationpediaPrefab::StructureCircuitHousing) => Some()
// Some(StationpediaPrefab::StructureRocketCircuitHousing) => Some()
_ => None,

View File

@@ -0,0 +1,3 @@
mod integrated_circuit;
pub use integrated_circuit::ItemIntegratedCircuit10;

File diff suppressed because it is too large Load Diff

View File

@@ -2,14 +2,26 @@ use std::collections::BTreeMap;
use crate::{
network::{ConnectionRole, ConnectionType},
vm::enums::{
basic_enums::{Class as SlotClass, GasType, SortingClass},
script_enums::{LogicSlotType, LogicType},
vm::{
enums::{
basic_enums::{Class as SlotClass, GasType, SortingClass},
script_enums::{LogicSlotType, LogicType},
},
object::{
generic::structs::{
Generic, GenericItem, GenericItemLogicable,
GenericItemLogicableMemoryReadWriteable, GenericItemLogicableMemoryReadable,
GenericItemStorage, GenericLogicable, GenericLogicableDevice,
GenericLogicableDeviceMemoryReadWriteable, GenericLogicableDeviceMemoryReadable,
GenericStorage,
},
LogicField, Name, Slot,
},
},
};
use serde_derive::{Deserialize, Serialize};
use super::{MemoryAccess, ObjectID};
use super::{stationpedia, MemoryAccess, ObjectID, VMObject};
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
#[serde(untagged)]
@@ -26,7 +38,7 @@ pub enum ObjectTemplate {
}
impl ObjectTemplate {
fn prefab(&self) -> &PrefabInfo {
pub fn prefab(&self) -> &PrefabInfo {
use ObjectTemplate::*;
match self {
Structure(s) => &s.prefab,
@@ -40,6 +52,354 @@ impl ObjectTemplate {
ItemLogicMemory(i) => &i.prefab,
}
}
fn build(&self, id: ObjectID) -> VMObject {
if let Some(obj) = stationpedia::object_from_prefab_template(&self, id) {
obj
} else {
self.build_generic(id)
}
}
fn build_generic(&self, id: ObjectID) -> VMObject {
use ObjectTemplate::*;
match self {
Structure(s) => VMObject::new(Generic {
id,
prefab: Name::from_prefab_name(&s.prefab.prefab_name),
name: Name::new(&s.prefab.name),
}),
StructureSlots(s) => VMObject::new(GenericStorage {
id,
prefab: Name::from_prefab_name(&s.prefab.prefab_name),
name: Name::new(&s.prefab.name),
slots: s
.slots
.iter()
.enumerate()
.map(|(index, info)| Slot {
parent: id,
index,
name: info.name.clone(),
typ: info.typ,
enabled_logic: Vec::new(),
occupant: None,
})
.collect(),
}),
StructureLogic(s) => VMObject::new(GenericLogicable {
id,
prefab: Name::from_prefab_name(&s.prefab.prefab_name),
name: Name::new(&s.prefab.name),
fields: s
.logic
.logic_types
.types
.iter()
.map(|(key, access)| {
(
*key,
LogicField {
field_type: *access,
value: 0.0,
},
)
})
.collect(),
slots: s
.slots
.iter()
.enumerate()
.map(|(index, info)| Slot {
parent: id,
index,
name: info.name.clone(),
typ: info.typ,
enabled_logic: s
.logic
.logic_slot_types
.get(&(index as u32))
.map(|s_info| s_info.slot_types.keys().copied().collect::<Vec<_>>())
.unwrap_or_else(|| Vec::new()),
occupant: None,
})
.collect(),
}),
StructureLogicDevice(s) => VMObject::new(GenericLogicableDevice {
id,
prefab: Name::from_prefab_name(&s.prefab.prefab_name),
name: Name::new(&s.prefab.name),
fields: s
.logic
.logic_types
.types
.iter()
.map(|(key, access)| {
(
*key,
LogicField {
field_type: *access,
value: 0.0,
},
)
})
.collect(),
slots: s
.slots
.iter()
.enumerate()
.map(|(index, info)| Slot {
parent: id,
index,
name: info.name.clone(),
typ: info.typ,
enabled_logic: s
.logic
.logic_slot_types
.get(&(index as u32))
.map(|s_info| s_info.slot_types.keys().copied().collect::<Vec<_>>())
.unwrap_or_else(|| Vec::new()),
occupant: None,
})
.collect(),
}),
StructureLogicDeviceMemory(s)
if matches!(s.memory.memory_access, MemoryAccess::Read) =>
{
VMObject::new(GenericLogicableDeviceMemoryReadable {
id,
prefab: Name::from_prefab_name(&s.prefab.prefab_name),
name: Name::new(&s.prefab.name),
fields: s
.logic
.logic_types
.types
.iter()
.map(|(key, access)| {
(
*key,
LogicField {
field_type: *access,
value: 0.0,
},
)
})
.collect(),
slots: s
.slots
.iter()
.enumerate()
.map(|(index, info)| Slot {
parent: id,
index,
name: info.name.clone(),
typ: info.typ,
enabled_logic: s
.logic
.logic_slot_types
.get(&(index as u32))
.map(|s_info| s_info.slot_types.keys().copied().collect::<Vec<_>>())
.unwrap_or_else(|| Vec::new()),
occupant: None,
})
.collect(),
memory: vec![0.0; s.memory.memory_size as usize],
})
}
StructureLogicDeviceMemory(s) => {
VMObject::new(GenericLogicableDeviceMemoryReadWriteable {
id,
prefab: Name::from_prefab_name(&s.prefab.prefab_name),
name: Name::new(&s.prefab.name),
fields: s
.logic
.logic_types
.types
.iter()
.map(|(key, access)| {
(
*key,
LogicField {
field_type: *access,
value: 0.0,
},
)
})
.collect(),
slots: s
.slots
.iter()
.enumerate()
.map(|(index, info)| Slot {
parent: id,
index,
name: info.name.clone(),
typ: info.typ,
enabled_logic: s
.logic
.logic_slot_types
.get(&(index as u32))
.map(|s_info| s_info.slot_types.keys().copied().collect::<Vec<_>>())
.unwrap_or_else(|| Vec::new()),
occupant: None,
})
.collect(),
memory: vec![0.0; s.memory.memory_size as usize],
})
}
Item(i) => VMObject::new(GenericItem {
id,
prefab: Name::from_prefab_name(&i.prefab.prefab_name),
name: Name::new(&i.prefab.name),
item_info: i.item.clone(),
parent_slot: None,
}),
ItemSlots(i) => VMObject::new(GenericItemStorage {
id,
prefab: Name::from_prefab_name(&i.prefab.prefab_name),
name: Name::new(&i.prefab.name),
item_info: i.item.clone(),
parent_slot: None,
slots: i
.slots
.iter()
.enumerate()
.map(|(index, info)| Slot {
parent: id,
index,
name: info.name.clone(),
typ: info.typ,
enabled_logic: Vec::new(),
occupant: None,
})
.collect(),
}),
ItemLogic(i) => VMObject::new(GenericItemLogicable {
id,
prefab: Name::from_prefab_name(&i.prefab.prefab_name),
name: Name::new(&i.prefab.name),
item_info: i.item.clone(),
parent_slot: None,
fields: i
.logic
.logic_types
.types
.iter()
.map(|(key, access)| {
(
*key,
LogicField {
field_type: *access,
value: 0.0,
},
)
})
.collect(),
slots: i
.slots
.iter()
.enumerate()
.map(|(index, info)| Slot {
parent: id,
index,
name: info.name.clone(),
typ: info.typ,
enabled_logic: i
.logic
.logic_slot_types
.get(&(index as u32))
.map(|s_info| s_info.slot_types.keys().copied().collect::<Vec<_>>())
.unwrap_or_else(|| Vec::new()),
occupant: None,
})
.collect(),
}),
ItemLogicMemory(i) if matches!(i.memory.memory_access, MemoryAccess::Read) => {
VMObject::new(GenericItemLogicableMemoryReadable {
id,
prefab: Name::from_prefab_name(&i.prefab.prefab_name),
name: Name::new(&i.prefab.name),
item_info: i.item.clone(),
parent_slot: None,
fields: i
.logic
.logic_types
.types
.iter()
.map(|(key, access)| {
(
*key,
LogicField {
field_type: *access,
value: 0.0,
},
)
})
.collect(),
slots: i
.slots
.iter()
.enumerate()
.map(|(index, info)| Slot {
parent: id,
index,
name: info.name.clone(),
typ: info.typ,
enabled_logic: i
.logic
.logic_slot_types
.get(&(index as u32))
.map(|s_info| s_info.slot_types.keys().copied().collect::<Vec<_>>())
.unwrap_or_else(|| Vec::new()),
occupant: None,
})
.collect(),
memory: vec![0.0; i.memory.memory_size as usize],
})
}
ItemLogicMemory(i) => VMObject::new(GenericItemLogicableMemoryReadWriteable {
id,
prefab: Name::from_prefab_name(&i.prefab.prefab_name),
name: Name::new(&i.prefab.name),
item_info: i.item.clone(),
parent_slot: None,
fields: i
.logic
.logic_types
.types
.iter()
.map(|(key, access)| {
(
*key,
LogicField {
field_type: *access,
value: 0.0,
},
)
})
.collect(),
slots: i
.slots
.iter()
.enumerate()
.map(|(index, info)| Slot {
parent: id,
index,
name: info.name.clone(),
typ: info.typ,
enabled_logic: i
.logic
.logic_slot_types
.get(&(index as u32))
.map(|s_info| s_info.slot_types.keys().copied().collect::<Vec<_>>())
.unwrap_or_else(|| Vec::new()),
occupant: None,
})
.collect(),
memory: vec![0.0; i.memory.memory_size as usize],
}),
}
}
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
@@ -62,7 +422,7 @@ pub struct ObjectInfo {
#[serde(rename_all = "camelCase")]
pub struct SlotInfo {
pub name: String,
pub typ: String,
pub typ: SlotClass,
}
#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
@@ -96,7 +456,7 @@ pub struct ItemInfo {
#[serde(skip_serializing_if = "Option::is_none")]
pub filter_type: Option<GasType>,
pub ingredient: bool,
pub max_quantity: f64,
pub max_quantity: u32,
#[serde(skip_serializing_if = "Option::is_none")]
pub reagents: Option<BTreeMap<String, f64>>,
pub slot_class: SlotClass,
@@ -271,7 +631,6 @@ mod tests {
pub prefabs: BTreeMap<String, ObjectTemplate>,
}
#[test]
fn all_database_prefabs_parse() -> color_eyre::Result<()> {
setup();

View File

@@ -1,7 +1,12 @@
use serde_derive::{Deserialize, Serialize};
use crate::{
errors::ICError,
vm::{
enums::script_enums::{LogicSlotType, LogicType},
enums::{
basic_enums::{Class as SlotClass, GasType, SortingClass},
script_enums::{LogicSlotType, LogicType},
},
instructions::Instruction,
object::{
errors::{LogicError, MemoryError},
@@ -12,7 +17,13 @@ use crate::{
},
};
use std::fmt::Debug;
use std::{collections::BTreeMap, fmt::Debug};
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct ParentSlotInfo {
pub parent: ObjectID,
pub slot: usize,
}
tag_object_traits! {
#![object_trait(Object: Debug)]
@@ -27,7 +38,13 @@ tag_object_traits! {
fn clear_memory(&mut self) -> Result<(), MemoryError>;
}
pub trait Logicable {
pub trait Storage {
fn slots_count(&self) -> usize;
fn get_slot(&self, index: usize) -> Option<&Slot>;
fn get_slot_mut(&mut self, index: usize) -> Option<&mut Slot>;
}
pub trait Logicable: Storage {
fn prefab_hash(&self) -> i32;
/// returns 0 if not set
fn name_hash(&self) -> i32;
@@ -38,9 +55,6 @@ tag_object_traits! {
fn set_logic(&mut self, lt: LogicType, value: f64, force: bool) -> Result<(), LogicError>;
fn get_logic(&self, lt: LogicType) -> Result<f64, LogicError>;
fn slots_count(&self) -> usize;
fn get_slot(&self, index: usize) -> Option<&Slot>;
fn get_slot_mut(&mut self, index: usize) -> Option<&mut Slot>;
fn can_slot_logic_read(&self, slt: LogicSlotType, index: usize) -> bool;
fn get_slot_logic(&self, slt: LogicSlotType, index: usize, vm: &VM) -> Result<f64, LogicError>;
}
@@ -83,7 +97,16 @@ tag_object_traits! {
}
pub trait Item {
fn consumable(&self) -> bool;
fn filter_type(&self) -> Option<GasType>;
fn ingredient(&self) -> bool;
fn max_quantity(&self) -> u32;
fn reagents(&self) -> Option<&BTreeMap<String, f64>>;
fn slot_class(&self) -> SlotClass;
fn sorting_class(&self) -> SortingClass;
fn parent_slot(&self) -> Option<ParentSlotInfo>;
}
}

View File

@@ -469,7 +469,7 @@ pub struct ItemInfo {
#[serde(skip_serializing_if = "Option::is_none")]
pub filter_type: Option<String>,
pub ingredient: bool,
pub max_quantity: f64,
pub max_quantity: u32,
#[serde(skip_serializing_if = "Option::is_none")]
pub reagents: Option<BTreeMap<String, f64>>,
pub slot_class: String,
@@ -482,7 +482,7 @@ impl From<&stationpedia::Item> for ItemInfo {
consumable: item.consumable.unwrap_or(false),
filter_type: item.filter_type.clone(),
ingredient: item.ingredient.unwrap_or(false),
max_quantity: item.max_quantity.unwrap_or(1.0),
max_quantity: item.max_quantity.unwrap_or(1.0) as u32,
reagents: item
.reagents
.as_ref()

View File

@@ -138,9 +138,13 @@ fn write_instruction_trait<T: std::io::Write>(
let operands = operand_names(&info.example)
.iter()
.map(|name| {
let mut n: &str = name;
if n == "str" {
n = "string";
}
format!(
"{}: &crate::vm::instructions::operands::Operand",
name.to_case(Case::Snake)
n.to_case(Case::Snake)
)
})
.collect::<Vec<_>>()
@@ -176,19 +180,27 @@ fn write_instruction_interface_trait<T: std::io::Write>(writer: &mut T) -> color
use crate::vm::object::traits::{{Logicable, MemoryWritable, SourceCode}};\n\
use crate::errors::ICError; \n\
pub trait IntegratedCircuit: Logicable + MemoryWritable + SourceCode {{\n \
fn get_instruciton_pointer(&self) -> usize;\n \
fn set_next_instruction(&mut self, next_instruction: usize);\n \
fn get_instruction_pointer(&self) -> f64;\n \
fn set_next_instruction(&mut self, next_instruction: f64);\n \
fn set_next_instruction_relative(&mut self, offset: f64) {{\n \
self.set_next_instruction(self.get_instruction_pointer() + offset);\n \
}}\n \
fn reset(&mut self);\n \
fn get_real_target(&self, indirection: u32, target: u32) -> Result<f64, ICError>;\n \
fn get_register(&self, indirection: u32, target: u32) -> Result<f64, ICError>;\n \
fn set_register(&mut self, indirection: u32, target: u32, val: f64) -> Result<f64, ICError>;\n \
fn set_return_address(&mut self, addr: f64);\n \
fn al(&mut self) {{\n \
self.set_return_address(self.get_instruction_pointer() + 1.0);\n \
}}\n \
fn push_stack(&mut self, val: f64) -> Result<f64, ICError>;\n \
fn pop_stack(&mut self) -> Result<f64, ICError>;\n \
fn peek_stack(&self) -> Result<f64, ICError>;\n \
fn get_stack(&self, addr: f64) -> Result<f64, ICError>;\n \
fn put_stack(&self, addr: f64, val: f64) -> Result<f64, ICError>;\n \
fn get_aliases(&self) -> &BTreeMap<String, crate::vm::instructions::operands::Operand>;\n \
fn get_defines(&self) -> &BTreeMap<String, f64>;\n \
fn get_lables(&self) -> &BTreeMap<String, u32>;\n\
fn get_labels(&self) -> &BTreeMap<String, u32>;\n\
}}\n\
"
)?;