refactor(vm): impl circuit holder, impl ObjectRef/Mut
This commit is contained in:
@@ -77,6 +77,11 @@ impl Program {
|
||||
self.instructions.len()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
|
||||
pub fn try_from_code(code: &str) -> Result<Self, ICError> {
|
||||
let parse_tree = grammar::parse(code)?;
|
||||
let mut labels_set = HashSet::new();
|
||||
|
||||
@@ -865,10 +865,10 @@ impl<T: IC10Marker> BdseInstruction for T {
|
||||
let a = a.as_value(self)?;
|
||||
if self
|
||||
.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(self.get_id()))?
|
||||
.ok_or(ICError::NoCircuitHolder(*self.get_id()))?
|
||||
.borrow()
|
||||
.as_circuit_holder()
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(self.get_id()))?
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(*self.get_id()))?
|
||||
.get_logicable_from_index(device, connection)
|
||||
.is_some()
|
||||
{
|
||||
@@ -885,10 +885,10 @@ impl<T: IC10Marker> BdsealInstruction for T {
|
||||
let a = a.as_value(self)?;
|
||||
if self
|
||||
.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(self.get_id()))?
|
||||
.ok_or(ICError::NoCircuitHolder(*self.get_id()))?
|
||||
.borrow()
|
||||
.as_circuit_holder()
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(self.get_id()))?
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(*self.get_id()))?
|
||||
.get_logicable_from_index(device, connection)
|
||||
.is_some()
|
||||
{
|
||||
@@ -906,10 +906,10 @@ impl<T: IC10Marker> BrdseInstruction for T {
|
||||
let a = a.as_value(self)?;
|
||||
if self
|
||||
.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(self.get_id()))?
|
||||
.ok_or(ICError::NoCircuitHolder(*self.get_id()))?
|
||||
.borrow()
|
||||
.as_circuit_holder()
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(self.get_id()))?
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(*self.get_id()))?
|
||||
.get_logicable_from_index(device, connection)
|
||||
.is_some()
|
||||
{
|
||||
@@ -926,10 +926,10 @@ impl<T: IC10Marker> BdnsInstruction for T {
|
||||
let a = a.as_value(self)?;
|
||||
if self
|
||||
.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(self.get_id()))?
|
||||
.ok_or(ICError::NoCircuitHolder(*self.get_id()))?
|
||||
.borrow()
|
||||
.as_circuit_holder()
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(self.get_id()))?
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(*self.get_id()))?
|
||||
.get_logicable_from_index(device, connection)
|
||||
.is_none()
|
||||
{
|
||||
@@ -946,10 +946,10 @@ impl<T: IC10Marker> BdnsalInstruction for T {
|
||||
let a = a.as_value(self)?;
|
||||
if self
|
||||
.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(self.get_id()))?
|
||||
.ok_or(ICError::NoCircuitHolder(*self.get_id()))?
|
||||
.borrow()
|
||||
.as_circuit_holder()
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(self.get_id()))?
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(*self.get_id()))?
|
||||
.get_logicable_from_index(device, connection)
|
||||
.is_none()
|
||||
{
|
||||
@@ -967,10 +967,10 @@ impl<T: IC10Marker> BrdnsInstruction for T {
|
||||
let a = a.as_value(self)?;
|
||||
if self
|
||||
.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(self.get_id()))?
|
||||
.ok_or(ICError::NoCircuitHolder(*self.get_id()))?
|
||||
.borrow()
|
||||
.as_circuit_holder()
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(self.get_id()))?
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(*self.get_id()))?
|
||||
.get_logicable_from_index(device, connection)
|
||||
.is_none()
|
||||
{
|
||||
@@ -1341,14 +1341,16 @@ impl<T: IC10Marker> SdseInstruction for T {
|
||||
target,
|
||||
} = r.as_register(self)?;
|
||||
let (device, connection) = d.as_device(self)?;
|
||||
let obj = self
|
||||
.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(self.get_id()))?
|
||||
.borrow()
|
||||
.as_circuit_holder()
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(self.get_id()))?
|
||||
.get_logicable_from_index(device, connection);
|
||||
self.set_register(indirection, target, if obj.is_some() { 1.0 } else { 0.0 })?;
|
||||
let is_some = {
|
||||
self.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(*self.get_id()))?
|
||||
.borrow()
|
||||
.as_circuit_holder()
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(*self.get_id()))?
|
||||
.get_logicable_from_index(device, connection)
|
||||
.is_some()
|
||||
};
|
||||
self.set_register(indirection, target, if is_some { 1.0 } else { 0.0 })?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -1360,14 +1362,16 @@ impl<T: IC10Marker> SdnsInstruction for T {
|
||||
target,
|
||||
} = r.as_register(self)?;
|
||||
let (device, connection) = d.as_device(self)?;
|
||||
let obj = self
|
||||
.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(self.get_id()))?
|
||||
.borrow()
|
||||
.as_circuit_holder()
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(self.get_id()))?
|
||||
.get_logicable_from_index(device, connection);
|
||||
self.set_register(indirection, target, if obj.is_none() { 1.0 } else { 0.0 })?;
|
||||
let is_none = {
|
||||
self.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(*self.get_id()))?
|
||||
.borrow()
|
||||
.as_circuit_holder()
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(*self.get_id()))?
|
||||
.get_logicable_from_index(device, connection)
|
||||
.is_none()
|
||||
};
|
||||
self.set_register(indirection, target, if is_none { 1.0 } else { 0.0 })?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -1988,19 +1992,22 @@ impl<T: IC10Marker> GetInstruction for T {
|
||||
} = r.as_register(self)?;
|
||||
let address = address.as_value(self)?;
|
||||
let (device, connection) = d.as_device(self)?;
|
||||
let obj = self
|
||||
.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(self.get_id()))?
|
||||
self.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(*self.get_id()))?
|
||||
.borrow()
|
||||
.as_circuit_holder()
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(self.get_id()))?
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(*self.get_id()))?
|
||||
.get_logicable_from_index(device, connection)
|
||||
.ok_or(ICError::DeviceNotSet)?;
|
||||
let obj_ref = obj.borrow();
|
||||
let memory = obj_ref
|
||||
.as_memory_readable()
|
||||
.ok_or(MemoryError::NotReadable)?;
|
||||
self.set_register(indirection, target, memory.get_memory(address as i32)?)?;
|
||||
.ok_or(ICError::DeviceNotSet)
|
||||
.and_then(|obj| {
|
||||
obj.map(|obj_ref| {
|
||||
let val = obj_ref
|
||||
.as_memory_readable()
|
||||
.ok_or(MemoryError::NotWriteable)?
|
||||
.get_memory(address as i32)?;
|
||||
self.set_register(indirection, target, val)
|
||||
})
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -2019,19 +2026,22 @@ impl<T: IC10Marker> GetdInstruction for T {
|
||||
} = r.as_register(self)?;
|
||||
let id = id.as_value(self)?;
|
||||
let address = address.as_value(self)?;
|
||||
let obj = self
|
||||
.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(self.get_id()))?
|
||||
self.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(*self.get_id()))?
|
||||
.borrow()
|
||||
.as_circuit_holder()
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(self.get_id()))?
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(*self.get_id()))?
|
||||
.get_logicable_from_id(id as ObjectID, None)
|
||||
.ok_or(ICError::DeviceNotSet)?;
|
||||
let obj_ref = obj.borrow();
|
||||
let memory = obj_ref
|
||||
.as_memory_readable()
|
||||
.ok_or(MemoryError::NotReadable)?;
|
||||
self.set_register(indirection, target, memory.get_memory(address as i32)?)?;
|
||||
.ok_or(ICError::DeviceNotSet)
|
||||
.and_then(|obj| {
|
||||
obj.map(|obj_ref| {
|
||||
let val = obj_ref
|
||||
.as_memory_readable()
|
||||
.ok_or(MemoryError::NotWriteable)?
|
||||
.get_memory(address as i32)?;
|
||||
self.set_register(indirection, target, val)
|
||||
})
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -2047,19 +2057,22 @@ impl<T: IC10Marker> PutInstruction for T {
|
||||
let (device, connection) = d.as_device(self)?;
|
||||
let address = address.as_value(self)?;
|
||||
let value = value.as_value(self)?;
|
||||
let obj = self
|
||||
.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(self.get_id()))?
|
||||
.borrow()
|
||||
.as_circuit_holder()
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(self.get_id()))?
|
||||
.get_logicable_from_index(device, connection)
|
||||
.ok_or(ICError::DeviceNotSet)?;
|
||||
let mut obj_ref = obj.borrow_mut();
|
||||
let memory = obj_ref
|
||||
.as_mut_memory_writable()
|
||||
.ok_or(MemoryError::NotWriteable)?;
|
||||
memory.set_memory(address as i32, value)?;
|
||||
self.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(*self.get_id()))?
|
||||
.borrow_mut()
|
||||
.as_mut_circuit_holder()
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(*self.get_id()))?
|
||||
.get_logicable_from_index_mut(device, connection)
|
||||
.ok_or(ICError::DeviceNotSet)
|
||||
.and_then(|mut obj| {
|
||||
obj.map(|obj_ref| {
|
||||
obj_ref
|
||||
.as_mut_memory_writable()
|
||||
.ok_or(MemoryError::NotWriteable)?
|
||||
.set_memory(address as i32, value)
|
||||
.map_err(Into::into)
|
||||
})
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -2075,19 +2088,22 @@ impl<T: IC10Marker> PutdInstruction for T {
|
||||
let id = id.as_value(self)?;
|
||||
let address = address.as_value(self)?;
|
||||
let value = value.as_value(self)?;
|
||||
let obj = self
|
||||
.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(self.get_id()))?
|
||||
.borrow()
|
||||
.as_circuit_holder()
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(self.get_id()))?
|
||||
.get_logicable_from_id(id as ObjectID, None)
|
||||
.ok_or(ICError::DeviceNotSet)?;
|
||||
let mut obj_ref = obj.borrow_mut();
|
||||
let memory = obj_ref
|
||||
.as_mut_memory_writable()
|
||||
.ok_or(MemoryError::NotWriteable)?;
|
||||
memory.set_memory(address as i32, value)?;
|
||||
self.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(*self.get_id()))?
|
||||
.borrow_mut()
|
||||
.as_mut_circuit_holder()
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(*self.get_id()))?
|
||||
.get_logicable_from_id_mut(id as ObjectID, None)
|
||||
.ok_or(ICError::DeviceNotSet)
|
||||
.and_then(|mut obj| {
|
||||
obj.map(|obj_ref| {
|
||||
obj_ref
|
||||
.as_mut_memory_writable()
|
||||
.ok_or(MemoryError::NotWriteable)?
|
||||
.set_memory(address as i32, value)
|
||||
.map_err(Into::into)
|
||||
})
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -2096,19 +2112,22 @@ impl<T: IC10Marker> ClrInstruction for T {
|
||||
/// clr d?
|
||||
fn execute_inner(&mut self, d: &InstOperand) -> Result<(), ICError> {
|
||||
let (device, connection) = d.as_device(self)?;
|
||||
let obj = self
|
||||
.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(self.get_id()))?
|
||||
.borrow()
|
||||
.as_circuit_holder()
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(self.get_id()))?
|
||||
.get_logicable_from_index(device, connection)
|
||||
.ok_or(ICError::DeviceNotSet)?;
|
||||
let mut obj_ref = obj.borrow_mut();
|
||||
let memory = obj_ref
|
||||
.as_mut_memory_writable()
|
||||
.ok_or(MemoryError::NotWriteable)?;
|
||||
memory.clear_memory()?;
|
||||
self.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(*self.get_id()))?
|
||||
.borrow_mut()
|
||||
.as_mut_circuit_holder()
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(*self.get_id()))?
|
||||
.get_logicable_from_index_mut(device, connection)
|
||||
.ok_or(ICError::DeviceNotSet)
|
||||
.and_then(|mut obj| {
|
||||
obj.map(|obj_ref| {
|
||||
obj_ref
|
||||
.as_mut_memory_writable()
|
||||
.ok_or(MemoryError::NotWriteable)?
|
||||
.clear_memory()
|
||||
.map_err(Into::into)
|
||||
})
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -2116,19 +2135,22 @@ impl<T: IC10Marker> ClrdInstruction for T {
|
||||
/// clrd id(r?|num)
|
||||
fn execute_inner(&mut self, id: &InstOperand) -> Result<(), ICError> {
|
||||
let id = id.as_value(self)?;
|
||||
let obj = self
|
||||
.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(self.get_id()))?
|
||||
.borrow()
|
||||
.as_circuit_holder()
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(self.get_id()))?
|
||||
.get_logicable_from_id(id as ObjectID, None)
|
||||
.ok_or(ICError::DeviceNotSet)?;
|
||||
let mut obj_ref = obj.borrow_mut();
|
||||
let memory = obj_ref
|
||||
.as_mut_memory_writable()
|
||||
.ok_or(MemoryError::NotWriteable)?;
|
||||
memory.clear_memory()?;
|
||||
self.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(*self.get_id()))?
|
||||
.borrow_mut()
|
||||
.as_mut_circuit_holder()
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(*self.get_id()))?
|
||||
.get_logicable_from_id_mut(id as ObjectID, None)
|
||||
.ok_or(ICError::DeviceNotSet)
|
||||
.and_then(|mut obj| {
|
||||
obj.map(|obj_ref| {
|
||||
obj_ref
|
||||
.as_mut_memory_writable()
|
||||
.ok_or(MemoryError::NotWriteable)?
|
||||
.clear_memory()
|
||||
.map_err(Into::into)
|
||||
})
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -2144,23 +2166,30 @@ impl<T: IC10Marker> SInstruction for T {
|
||||
let (device, connection) = d.as_device(self)?;
|
||||
let logic_type = logic_type.as_logic_type(self)?;
|
||||
let val = r.as_value(self)?;
|
||||
let obj = self
|
||||
.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(self.get_id()))?
|
||||
.borrow()
|
||||
.as_circuit_holder()
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(self.get_id()))?
|
||||
.get_logicable_from_index(device, connection)
|
||||
.ok_or(ICError::DeviceNotSet)?;
|
||||
let mut obj_ref = obj.borrow_mut();
|
||||
let device_id = obj_ref.get_id();
|
||||
let logicable = obj_ref
|
||||
.as_mut_logicable()
|
||||
.ok_or(ICError::NotLogicable(device_id))?;
|
||||
if !logicable.can_logic_write(logic_type) {
|
||||
return Err(LogicError::CantWrite(logic_type).into());
|
||||
}
|
||||
logicable.set_logic(logic_type, val, false)?;
|
||||
self.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(*self.get_id()))?
|
||||
.borrow_mut()
|
||||
.as_mut_circuit_holder()
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(*self.get_id()))?
|
||||
.get_logicable_from_index_mut(device, connection)
|
||||
.ok_or(ICError::DeviceNotSet)
|
||||
.and_then(|mut obj| {
|
||||
let obj_id = obj.get_id();
|
||||
obj.map(|obj_ref| {
|
||||
obj_ref
|
||||
.as_mut_logicable()
|
||||
.ok_or(ICError::NotLogicable(obj_id))
|
||||
.and_then(|logicable| {
|
||||
if !logicable.can_logic_write(logic_type) {
|
||||
Err(LogicError::CantWrite(logic_type).into())
|
||||
} else {
|
||||
logicable
|
||||
.set_logic(logic_type, val, false)
|
||||
.map_err(Into::into)
|
||||
}
|
||||
})
|
||||
})
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -2176,23 +2205,30 @@ impl<T: IC10Marker> SdInstruction for T {
|
||||
let id = id.as_value(self)?;
|
||||
let logic_type = logic_type.as_logic_type(self)?;
|
||||
let val = r.as_value(self)?;
|
||||
let obj = self
|
||||
.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(self.get_id()))?
|
||||
.borrow()
|
||||
.as_circuit_holder()
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(self.get_id()))?
|
||||
.get_logicable_from_id(id as ObjectID, None)
|
||||
.ok_or(ICError::DeviceNotSet)?;
|
||||
let mut obj_ref = obj.borrow_mut();
|
||||
let device_id = obj_ref.get_id();
|
||||
let logicable = obj_ref
|
||||
.as_mut_logicable()
|
||||
.ok_or(ICError::NotLogicable(device_id))?;
|
||||
if !logicable.can_logic_write(logic_type) {
|
||||
return Err(LogicError::CantWrite(logic_type).into());
|
||||
}
|
||||
logicable.set_logic(logic_type, val, false)?;
|
||||
self.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(*self.get_id()))?
|
||||
.borrow_mut()
|
||||
.as_mut_circuit_holder()
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(*self.get_id()))?
|
||||
.get_logicable_from_id_mut(id as ObjectID, None)
|
||||
.ok_or(ICError::DeviceNotSet)
|
||||
.and_then(|mut obj| {
|
||||
let obj_id = obj.get_id();
|
||||
obj.map(|obj_ref| {
|
||||
obj_ref
|
||||
.as_mut_logicable()
|
||||
.ok_or(ICError::NotLogicable(obj_id))
|
||||
.and_then(|logicable| {
|
||||
if !logicable.can_logic_write(logic_type) {
|
||||
Err(LogicError::CantWrite(logic_type).into())
|
||||
} else {
|
||||
logicable
|
||||
.set_logic(logic_type, val, false)
|
||||
.map_err(Into::into)
|
||||
}
|
||||
})
|
||||
})
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -2210,27 +2246,30 @@ impl<T: IC10Marker> SsInstruction for T {
|
||||
let slot_index = slot_index.as_value(self)?;
|
||||
let logic_slot_type = logic_slot_type.as_slot_logic_type(self)?;
|
||||
let val = r.as_value(self)?;
|
||||
let obj = self
|
||||
.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(self.get_id()))?
|
||||
.borrow()
|
||||
.as_circuit_holder()
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(self.get_id()))?
|
||||
.get_logicable_from_index(device, connection)
|
||||
.ok_or(ICError::DeviceNotSet)?;
|
||||
let mut obj_ref = obj.borrow_mut();
|
||||
let device_id = obj_ref.get_id();
|
||||
let logicable = obj_ref
|
||||
.as_mut_logicable()
|
||||
.ok_or(ICError::NotLogicable(device_id))?;
|
||||
let device_id = logicable.get_id();
|
||||
let device = logicable
|
||||
.as_mut_device()
|
||||
.ok_or(ICError::NotSlotWriteable(device_id))?;
|
||||
if !device.can_slot_logic_write(logic_slot_type, slot_index) {
|
||||
return Err(LogicError::CantSlotWrite(logic_slot_type, slot_index).into());
|
||||
}
|
||||
device.set_slot_logic(logic_slot_type, slot_index, val, false)?;
|
||||
self.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(*self.get_id()))?
|
||||
.borrow_mut()
|
||||
.as_mut_circuit_holder()
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(*self.get_id()))?
|
||||
.get_logicable_from_index_mut(device, connection)
|
||||
.ok_or(ICError::DeviceNotSet)
|
||||
.and_then(|mut obj| {
|
||||
let obj_id = obj.get_id();
|
||||
obj.map(|obj_ref| {
|
||||
obj_ref
|
||||
.as_mut_device()
|
||||
.ok_or(ICError::NotLogicable(obj_id))
|
||||
.and_then(|logicable| {
|
||||
if !logicable.can_slot_logic_write(logic_slot_type, slot_index) {
|
||||
Err(LogicError::CantSlotWrite(logic_slot_type, slot_index).into())
|
||||
} else {
|
||||
logicable
|
||||
.set_slot_logic(logic_slot_type, slot_index, val, false)
|
||||
.map_err(Into::into)
|
||||
}
|
||||
})
|
||||
})
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -2248,7 +2287,7 @@ impl<T: IC10Marker> SbInstruction for T {
|
||||
let logic_type = logic_type.as_logic_type(self)?;
|
||||
let val = r.as_value(self)?;
|
||||
self.get_vm()
|
||||
.set_batch_device_field(self.get_id(), prefab, logic_type, val, false)?;
|
||||
.set_batch_device_field(*self.get_id(), prefab, logic_type, val, false)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -2268,7 +2307,7 @@ impl<T: IC10Marker> SbsInstruction for T {
|
||||
let logic_slot_type = logic_slot_type.as_slot_logic_type(self)?;
|
||||
let val = r.as_value(self)?;
|
||||
self.get_vm().set_batch_device_slot_field(
|
||||
self.get_id(),
|
||||
*self.get_id(),
|
||||
prefab,
|
||||
slot_index,
|
||||
logic_slot_type,
|
||||
@@ -2294,7 +2333,7 @@ impl<T: IC10Marker> SbnInstruction for T {
|
||||
let logic_type = logic_type.as_logic_type(self)?;
|
||||
let val = r.as_value(self)?;
|
||||
self.get_vm().set_batch_name_device_field(
|
||||
self.get_id(),
|
||||
*self.get_id(),
|
||||
prefab,
|
||||
name,
|
||||
logic_type,
|
||||
@@ -2320,22 +2359,29 @@ impl<T: IC10Marker> LInstruction for T {
|
||||
} = r.as_register(self)?;
|
||||
let (device, connection) = d.as_device(self)?;
|
||||
let logic_type = logic_type.as_logic_type(self)?;
|
||||
let obj = self
|
||||
let val = self
|
||||
.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(self.get_id()))?
|
||||
.ok_or(ICError::NoCircuitHolder(*self.get_id()))?
|
||||
.borrow()
|
||||
.as_circuit_holder()
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(self.get_id()))?
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(*self.get_id()))?
|
||||
.get_logicable_from_index(device, connection)
|
||||
.ok_or(ICError::DeviceNotSet)?;
|
||||
let obj_ref = obj.borrow();
|
||||
let logicable = obj_ref
|
||||
.as_logicable()
|
||||
.ok_or(ICError::NotLogicable(obj_ref.get_id()))?;
|
||||
if !logicable.can_logic_read(logic_type) {
|
||||
return Err(LogicError::CantRead(logic_type).into());
|
||||
}
|
||||
self.set_register(indirection, target, logicable.get_logic(logic_type)?)?;
|
||||
.ok_or(ICError::DeviceNotSet)
|
||||
.and_then(|obj| {
|
||||
obj.map(|obj_ref| {
|
||||
obj_ref
|
||||
.as_logicable()
|
||||
.ok_or(ICError::NotLogicable(*obj_ref.get_id()))
|
||||
.and_then(|logicable| {
|
||||
if !logicable.can_logic_read(logic_type) {
|
||||
Err(LogicError::CantRead(logic_type).into())
|
||||
} else {
|
||||
logicable.get_logic(logic_type).map_err(Into::into)
|
||||
}
|
||||
})
|
||||
})
|
||||
})?;
|
||||
self.set_register(indirection, target, val)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -2354,22 +2400,29 @@ impl<T: IC10Marker> LdInstruction for T {
|
||||
} = r.as_register(self)?;
|
||||
let id = id.as_value(self)?;
|
||||
let logic_type = logic_type.as_logic_type(self)?;
|
||||
let obj = self
|
||||
let val = self
|
||||
.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(self.get_id()))?
|
||||
.ok_or(ICError::NoCircuitHolder(*self.get_id()))?
|
||||
.borrow()
|
||||
.as_circuit_holder()
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(self.get_id()))?
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(*self.get_id()))?
|
||||
.get_logicable_from_id(id as ObjectID, None)
|
||||
.ok_or(ICError::DeviceNotSet)?;
|
||||
let obj_ref = obj.borrow();
|
||||
let logicable = obj_ref
|
||||
.as_logicable()
|
||||
.ok_or(ICError::NotLogicable(obj_ref.get_id()))?;
|
||||
if !logicable.can_logic_read(logic_type) {
|
||||
return Err(LogicError::CantRead(logic_type).into());
|
||||
}
|
||||
self.set_register(indirection, target, logicable.get_logic(logic_type)?)?;
|
||||
.ok_or(ICError::DeviceNotSet)
|
||||
.and_then(|obj| {
|
||||
obj.map(|obj_ref| {
|
||||
obj_ref
|
||||
.as_logicable()
|
||||
.ok_or(ICError::NotLogicable(*obj_ref.get_id()))
|
||||
.and_then(|logicable| {
|
||||
if !logicable.can_logic_read(logic_type) {
|
||||
Err(LogicError::CantRead(logic_type).into())
|
||||
} else {
|
||||
logicable.get_logic(logic_type).map_err(Into::into)
|
||||
}
|
||||
})
|
||||
})
|
||||
})?;
|
||||
self.set_register(indirection, target, val)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -2390,26 +2443,31 @@ impl<T: IC10Marker> LsInstruction for T {
|
||||
let (device, connection) = d.as_device(self)?;
|
||||
let slot_index = slot_index.as_value(self)?;
|
||||
let logic_slot_type = logic_slot_type.as_slot_logic_type(self)?;
|
||||
let obj = self
|
||||
let val = self
|
||||
.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(self.get_id()))?
|
||||
.ok_or(ICError::NoCircuitHolder(*self.get_id()))?
|
||||
.borrow()
|
||||
.as_circuit_holder()
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(self.get_id()))?
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(*self.get_id()))?
|
||||
.get_logicable_from_index(device, connection)
|
||||
.ok_or(ICError::DeviceNotSet)?;
|
||||
let obj_ref = obj.borrow();
|
||||
let logicable = obj_ref
|
||||
.as_logicable()
|
||||
.ok_or(ICError::NotLogicable(obj_ref.get_id()))?;
|
||||
if !logicable.can_slot_logic_read(logic_slot_type, slot_index) {
|
||||
return Err(LogicError::CantSlotRead(logic_slot_type, slot_index).into());
|
||||
}
|
||||
self.set_register(
|
||||
indirection,
|
||||
target,
|
||||
logicable.get_slot_logic(logic_slot_type, slot_index)?,
|
||||
)?;
|
||||
.ok_or(ICError::DeviceNotSet)
|
||||
.and_then(|obj| {
|
||||
obj.map(|obj_ref| {
|
||||
obj_ref
|
||||
.as_logicable()
|
||||
.ok_or(ICError::NotLogicable(*obj_ref.get_id()))
|
||||
.and_then(|logicable| {
|
||||
if !logicable.can_slot_logic_read(logic_slot_type, slot_index) {
|
||||
Err(LogicError::CantSlotRead(logic_slot_type, slot_index).into())
|
||||
} else {
|
||||
logicable
|
||||
.get_slot_logic(logic_slot_type, slot_index)
|
||||
.map_err(Into::into)
|
||||
}
|
||||
})
|
||||
})
|
||||
})?;
|
||||
self.set_register(indirection, target, val)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -2430,66 +2488,70 @@ impl<T: IC10Marker> LrInstruction for T {
|
||||
let (device, connection) = d.as_device(self)?;
|
||||
let reagent_mode = reagent_mode.as_reagent_mode(self)?;
|
||||
let int = int.as_value(self)?;
|
||||
let obj = self
|
||||
let val = self
|
||||
.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(self.get_id()))?
|
||||
.ok_or(ICError::NoCircuitHolder(*self.get_id()))?
|
||||
.borrow()
|
||||
.as_circuit_holder()
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(self.get_id()))?
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(*self.get_id()))?
|
||||
.get_logicable_from_index(device, connection)
|
||||
.ok_or(ICError::DeviceNotSet)?;
|
||||
let obj_ref = obj.borrow();
|
||||
let logicable = obj_ref
|
||||
.as_logicable()
|
||||
.ok_or(ICError::NotLogicable(obj_ref.get_id()))?;
|
||||
|
||||
let result = match reagent_mode {
|
||||
LogicReagentMode::Contents => {
|
||||
let device = logicable
|
||||
.as_device()
|
||||
.ok_or(ICError::NotReagentReadable(logicable.get_id()))?;
|
||||
device
|
||||
.get_reagents()
|
||||
.iter()
|
||||
.find(|(hash, _)| *hash as f64 == int)
|
||||
.map(|(_, quantity)| *quantity)
|
||||
.unwrap_or(0.0)
|
||||
}
|
||||
LogicReagentMode::TotalContents => {
|
||||
let device = logicable
|
||||
.as_device()
|
||||
.ok_or(ICError::NotReagentReadable(logicable.get_id()))?;
|
||||
device
|
||||
.get_reagents()
|
||||
.iter()
|
||||
.map(|(_, quantity)| quantity)
|
||||
.sum()
|
||||
}
|
||||
LogicReagentMode::Required => {
|
||||
let reagent_interface = logicable
|
||||
.as_reagent_interface()
|
||||
.ok_or(ICError::NotReagentReadable(logicable.get_id()))?;
|
||||
reagent_interface
|
||||
.get_current_required()
|
||||
.iter()
|
||||
.find(|(hash, _)| *hash as f64 == int)
|
||||
.map(|(_, quantity)| *quantity)
|
||||
.unwrap_or(0.0)
|
||||
}
|
||||
LogicReagentMode::Recipe => {
|
||||
let reagent_interface = logicable
|
||||
.as_reagent_interface()
|
||||
.ok_or(ICError::NotReagentReadable(logicable.get_id()))?;
|
||||
reagent_interface
|
||||
.get_current_recipie()
|
||||
.iter()
|
||||
.find(|(hash, _)| *hash as f64 == int)
|
||||
.map(|(_, quantity)| *quantity)
|
||||
.unwrap_or(0.0)
|
||||
}
|
||||
};
|
||||
|
||||
self.set_register(indirection, target, result)?;
|
||||
.ok_or(ICError::DeviceNotSet)
|
||||
.and_then(|obj| {
|
||||
obj.map(|obj_ref| {
|
||||
obj_ref
|
||||
.as_logicable()
|
||||
.ok_or(ICError::NotLogicable(*obj_ref.get_id()))
|
||||
.and_then(|logicable| {
|
||||
let result = match reagent_mode {
|
||||
LogicReagentMode::Contents => {
|
||||
let device = logicable
|
||||
.as_device()
|
||||
.ok_or(ICError::NotReagentReadable(*logicable.get_id()))?;
|
||||
device
|
||||
.get_reagents()
|
||||
.iter()
|
||||
.find(|(hash, _)| *hash as f64 == int)
|
||||
.map(|(_, quantity)| *quantity)
|
||||
.unwrap_or(0.0)
|
||||
}
|
||||
LogicReagentMode::TotalContents => {
|
||||
let device = logicable
|
||||
.as_device()
|
||||
.ok_or(ICError::NotReagentReadable(*logicable.get_id()))?;
|
||||
device
|
||||
.get_reagents()
|
||||
.iter()
|
||||
.map(|(_, quantity)| quantity)
|
||||
.sum()
|
||||
}
|
||||
LogicReagentMode::Required => {
|
||||
let reagent_interface = logicable
|
||||
.as_reagent_interface()
|
||||
.ok_or(ICError::NotReagentReadable(*logicable.get_id()))?;
|
||||
reagent_interface
|
||||
.get_current_required()
|
||||
.iter()
|
||||
.find(|(hash, _)| *hash as f64 == int)
|
||||
.map(|(_, quantity)| *quantity)
|
||||
.unwrap_or(0.0)
|
||||
}
|
||||
LogicReagentMode::Recipe => {
|
||||
let reagent_interface = logicable
|
||||
.as_reagent_interface()
|
||||
.ok_or(ICError::NotReagentReadable(*logicable.get_id()))?;
|
||||
reagent_interface
|
||||
.get_current_recipie()
|
||||
.iter()
|
||||
.find(|(hash, _)| *hash as f64 == int)
|
||||
.map(|(_, quantity)| *quantity)
|
||||
.unwrap_or(0.0)
|
||||
}
|
||||
};
|
||||
Ok(result)
|
||||
})
|
||||
})
|
||||
})?;
|
||||
self.set_register(indirection, target, val)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -2513,7 +2575,7 @@ impl<T: IC10Marker> LbInstruction for T {
|
||||
let batch_mode = batch_mode.as_batch_mode(self)?;
|
||||
let val =
|
||||
self.get_vm()
|
||||
.get_batch_device_field(self.get_id(), prefab, logic_type, batch_mode)?;
|
||||
.get_batch_device_field(*self.get_id(), prefab, logic_type, batch_mode)?;
|
||||
self.set_register(indirection, target, val)?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -2539,7 +2601,7 @@ impl<T: IC10Marker> LbnInstruction for T {
|
||||
let logic_type = logic_type.as_logic_type(self)?;
|
||||
let batch_mode = batch_mode.as_batch_mode(self)?;
|
||||
let val = self.get_vm().get_batch_name_device_field(
|
||||
self.get_id(),
|
||||
*self.get_id(),
|
||||
prefab,
|
||||
name,
|
||||
logic_type,
|
||||
@@ -2572,7 +2634,7 @@ impl<T: IC10Marker> LbnsInstruction for T {
|
||||
let logic_slot_type = logic_slot_type.as_slot_logic_type(self)?;
|
||||
let batch_mode = batch_mode.as_batch_mode(self)?;
|
||||
let val = self.get_vm().get_batch_name_device_slot_field(
|
||||
self.get_id(),
|
||||
*self.get_id(),
|
||||
prefab,
|
||||
name,
|
||||
slot_index,
|
||||
@@ -2604,7 +2666,7 @@ impl<T: IC10Marker> LbsInstruction for T {
|
||||
let logic_slot_type = logic_slot_type.as_slot_logic_type(self)?;
|
||||
let batch_mode = batch_mode.as_batch_mode(self)?;
|
||||
let val = self.get_vm().get_batch_device_slot_field(
|
||||
self.get_id(),
|
||||
*self.get_id(),
|
||||
prefab,
|
||||
slot_index,
|
||||
logic_slot_type,
|
||||
@@ -2618,12 +2680,14 @@ impl<T: IC10Marker> LbsInstruction for T {
|
||||
impl<T: IC10Marker> HcfInstruction for T {
|
||||
/// hcf
|
||||
fn execute_inner(&mut self) -> Result<(), ICError> {
|
||||
self.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(self.get_id()))?
|
||||
.borrow_mut()
|
||||
.as_mut_circuit_holder()
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(self.get_id()))?
|
||||
.hault_and_catch_fire();
|
||||
{
|
||||
self.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(*self.get_id()))?
|
||||
.borrow_mut()
|
||||
.as_mut_circuit_holder()
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(*self.get_id()))?
|
||||
.hault_and_catch_fire();
|
||||
}
|
||||
self.set_state(ICState::HasCaughtFire);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -235,11 +235,11 @@ impl Storage for CableNetwork {
|
||||
fn get_slot_mut(&mut self, _index: usize) -> Option<&mut crate::vm::object::Slot> {
|
||||
None
|
||||
}
|
||||
fn get_slots(&self) -> &[crate::vm::object::Slot] {
|
||||
&[]
|
||||
fn get_slots(&self) -> Vec<&crate::vm::object::Slot> {
|
||||
vec![]
|
||||
}
|
||||
fn get_slots_mut(&mut self) -> &mut [crate::vm::object::Slot] {
|
||||
&mut []
|
||||
fn get_slots_mut(&mut self) -> Vec<&mut crate::vm::object::Slot> {
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -422,7 +422,7 @@ where
|
||||
impl From<NetworkRef<'_>> for FrozenCableNetwork {
|
||||
fn from(value: NetworkRef) -> Self {
|
||||
FrozenCableNetwork {
|
||||
id: value.get_id(),
|
||||
id: *value.get_id(),
|
||||
devices: value.get_devices(),
|
||||
power_only: value.get_power_only(),
|
||||
channels: *value.get_channel_data(),
|
||||
|
||||
@@ -617,7 +617,7 @@ impl VM {
|
||||
) -> Result<(), ICError> {
|
||||
self.batch_device(source, prefab, None)
|
||||
.map(|device| {
|
||||
self.set_modified(device.borrow().get_id());
|
||||
self.set_modified(*device.borrow().get_id());
|
||||
device
|
||||
.borrow_mut()
|
||||
.as_mut_device()
|
||||
@@ -639,7 +639,7 @@ impl VM {
|
||||
) -> Result<(), ICError> {
|
||||
self.batch_device(source, prefab, None)
|
||||
.map(|device| {
|
||||
self.set_modified(device.borrow().get_id());
|
||||
self.set_modified(*device.borrow().get_id());
|
||||
device
|
||||
.borrow_mut()
|
||||
.as_mut_device()
|
||||
@@ -661,7 +661,7 @@ impl VM {
|
||||
) -> Result<(), ICError> {
|
||||
self.batch_device(source, prefab, Some(name))
|
||||
.map(|device| {
|
||||
self.set_modified(device.borrow().get_id());
|
||||
self.set_modified(*device.borrow().get_id());
|
||||
device
|
||||
.borrow_mut()
|
||||
.as_mut_device()
|
||||
|
||||
@@ -41,11 +41,11 @@ impl<T: GWStorage + Object> Storage for T {
|
||||
fn get_slot_mut(&mut self, index: usize) -> Option<&mut Slot> {
|
||||
self.slots_mut().get_mut(index)
|
||||
}
|
||||
fn get_slots(&self) -> &[Slot] {
|
||||
self.slots()
|
||||
fn get_slots(&self) -> Vec<&Slot> {
|
||||
self.slots().iter().collect()
|
||||
}
|
||||
fn get_slots_mut(&mut self) -> &mut [Slot] {
|
||||
self.slots_mut()
|
||||
fn get_slots_mut(&mut self) -> Vec<&mut Slot> {
|
||||
self.slots_mut().iter_mut().collect()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,57 +63,77 @@ impl<T: GWLogicable + Object> Logicable for T {
|
||||
self.get_name().hash
|
||||
}
|
||||
fn is_logic_readable(&self) -> bool {
|
||||
LogicType::iter().any(|lt| self.can_logic_read(lt))
|
||||
true
|
||||
}
|
||||
fn is_logic_writeable(&self) -> bool {
|
||||
LogicType::iter().any(|lt| self.can_logic_write(lt))
|
||||
}
|
||||
fn can_logic_read(&self, lt: LogicType) -> bool {
|
||||
self.fields()
|
||||
.get(<)
|
||||
.map(|field| {
|
||||
matches!(
|
||||
field.field_type,
|
||||
MemoryAccess::Read | MemoryAccess::ReadWrite
|
||||
)
|
||||
})
|
||||
.unwrap_or(false)
|
||||
match lt {
|
||||
LogicType::PrefabHash | LogicType::NameHash | LogicType::ReferenceId => true,
|
||||
_ => self
|
||||
.fields()
|
||||
.get(<)
|
||||
.map(|field| {
|
||||
matches!(
|
||||
field.field_type,
|
||||
MemoryAccess::Read | MemoryAccess::ReadWrite
|
||||
)
|
||||
})
|
||||
.unwrap_or(false),
|
||||
}
|
||||
}
|
||||
fn can_logic_write(&self, lt: LogicType) -> bool {
|
||||
self.fields()
|
||||
.get(<)
|
||||
.map(|field| {
|
||||
matches!(
|
||||
field.field_type,
|
||||
MemoryAccess::Write | MemoryAccess::ReadWrite
|
||||
)
|
||||
})
|
||||
.unwrap_or(false)
|
||||
match lt {
|
||||
LogicType::PrefabHash | LogicType::NameHash | LogicType::ReferenceId => false,
|
||||
_ => self
|
||||
.fields()
|
||||
.get(<)
|
||||
.map(|field| {
|
||||
matches!(
|
||||
field.field_type,
|
||||
MemoryAccess::Write | MemoryAccess::ReadWrite
|
||||
)
|
||||
})
|
||||
.unwrap_or(false),
|
||||
}
|
||||
}
|
||||
fn get_logic(&self, lt: LogicType) -> Result<f64, LogicError> {
|
||||
self.fields()
|
||||
.get(<)
|
||||
.and_then(|field| match field.field_type {
|
||||
MemoryAccess::Read | MemoryAccess::ReadWrite => Some(field.value),
|
||||
_ => None,
|
||||
})
|
||||
.ok_or(LogicError::CantRead(lt))
|
||||
match lt {
|
||||
LogicType::PrefabHash => Ok(self.get_prefab().hash as f64),
|
||||
LogicType::NameHash => Ok(self.get_name().hash as f64),
|
||||
LogicType::ReferenceId => Ok(*self.get_id() as f64),
|
||||
_ => self
|
||||
.fields()
|
||||
.get(<)
|
||||
.and_then(|field| match field.field_type {
|
||||
MemoryAccess::Read | MemoryAccess::ReadWrite => Some(field.value),
|
||||
_ => None,
|
||||
})
|
||||
.ok_or(LogicError::CantRead(lt)),
|
||||
}
|
||||
}
|
||||
fn set_logic(&mut self, lt: LogicType, value: f64, force: bool) -> Result<(), LogicError> {
|
||||
self.fields_mut()
|
||||
.get_mut(<)
|
||||
.ok_or(LogicError::CantWrite(lt))
|
||||
.and_then(|field| match field.field_type {
|
||||
MemoryAccess::Write | MemoryAccess::ReadWrite => {
|
||||
field.value = value;
|
||||
Ok(())
|
||||
}
|
||||
_ if force => {
|
||||
field.value = value;
|
||||
Ok(())
|
||||
}
|
||||
_ => Err(LogicError::CantWrite(lt)),
|
||||
})
|
||||
match lt {
|
||||
LogicType::PrefabHash | LogicType::NameHash | LogicType::ReferenceId => {
|
||||
Err(LogicError::CantWrite(lt))
|
||||
}
|
||||
_ => self
|
||||
.fields_mut()
|
||||
.get_mut(<)
|
||||
.ok_or(LogicError::CantWrite(lt))
|
||||
.and_then(|field| match field.field_type {
|
||||
MemoryAccess::Write | MemoryAccess::ReadWrite => {
|
||||
field.value = value;
|
||||
Ok(())
|
||||
}
|
||||
_ if force => {
|
||||
field.value = value;
|
||||
Ok(())
|
||||
}
|
||||
_ => Err(LogicError::CantWrite(lt)),
|
||||
}),
|
||||
}
|
||||
}
|
||||
fn can_slot_logic_read(&self, slt: LogicSlotType, index: f64) -> bool {
|
||||
if index < 0.0 {
|
||||
@@ -200,7 +220,7 @@ impl<T: GWLogicable + Object> Logicable for T {
|
||||
}
|
||||
ReferenceId => {
|
||||
if let Some(occupant) = occupant {
|
||||
Ok(occupant.borrow().get_id() as f64)
|
||||
Ok(*occupant.borrow().get_id() as f64)
|
||||
} else {
|
||||
Ok(0.0)
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ macro_rules! object_trait {
|
||||
}
|
||||
};
|
||||
(@body $trait_name:ident { $($trt:ident),* }; ) => {
|
||||
fn get_id(&self) -> crate::vm::object::ObjectID;
|
||||
fn get_id(&self) -> &crate::vm::object::ObjectID;
|
||||
fn set_id(&mut self, id: crate::vm::object::ObjectID);
|
||||
fn get_prefab(&self) -> &crate::vm::object::Name;
|
||||
fn get_mut_prefab(&mut self) -> &mut crate::vm::object::Name;
|
||||
@@ -53,6 +53,74 @@ macro_rules! object_trait {
|
||||
}
|
||||
}
|
||||
|
||||
pub enum [<$trait_name Ref>]<'a> {
|
||||
DynRef(&'a dyn $trait_name),
|
||||
VMObject(crate::vm::object::VMObject),
|
||||
}
|
||||
|
||||
impl<'a> [<$trait_name Ref>]<'a> {
|
||||
pub fn from_ref(reference: &'a dyn $trait_name) -> Self {
|
||||
Self::DynRef(reference)
|
||||
}
|
||||
pub fn from_vm_object(obj: crate::vm::object::VMObject) -> Self {
|
||||
Self::VMObject(obj)
|
||||
}
|
||||
pub fn get_id(&self) -> u32 {
|
||||
match self {
|
||||
Self::DynRef(reference) => *reference.get_id(),
|
||||
Self::VMObject(obj) => *obj.borrow().get_id(),
|
||||
|
||||
}
|
||||
}
|
||||
/// call func on the dyn refrence or a borrow of the vm object
|
||||
pub fn map<F, R>(&self, mut func: F ) -> R
|
||||
where
|
||||
F: std::ops::FnMut(& dyn $trait_name) -> R
|
||||
{
|
||||
match self {
|
||||
Self::DynRef(reference) => func(*reference),
|
||||
Self::VMObject(obj) => {
|
||||
let obj_ref = obj.borrow();
|
||||
func(&*obj_ref)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum [<$trait_name RefMut>]<'a> {
|
||||
DynRef(&'a mut dyn $trait_name),
|
||||
VMObject(crate::vm::object::VMObject),
|
||||
}
|
||||
|
||||
impl<'a> [<$trait_name RefMut>]<'a> {
|
||||
pub fn from_ref(reference: &'a mut dyn $trait_name) -> Self {
|
||||
Self::DynRef(reference)
|
||||
}
|
||||
pub fn from_vm_object(obj: crate::vm::object::VMObject) -> Self {
|
||||
Self::VMObject(obj)
|
||||
}
|
||||
pub fn get_id(&self) -> u32 {
|
||||
match self {
|
||||
Self::DynRef(refrence) => *refrence.get_id(),
|
||||
Self::VMObject(obj) => *obj.borrow().get_id(),
|
||||
|
||||
}
|
||||
}
|
||||
/// call func on the dyn refrence or a borrow of the vm object
|
||||
pub fn map<F, R>(&mut self, mut func: F ) -> R
|
||||
where
|
||||
F: std::ops::FnMut(&mut dyn $trait_name) -> R
|
||||
{
|
||||
match self {
|
||||
Self::DynRef(reference) => func(*reference),
|
||||
Self::VMObject(obj) => {
|
||||
let mut obj_ref = obj.borrow_mut();
|
||||
func(&mut *obj_ref)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
( $trait_name:ident $(: $($bound:tt)* )? {$($trt:ident),*}) => {
|
||||
@@ -95,8 +163,8 @@ macro_rules! ObjectInterface {
|
||||
} => {
|
||||
impl $trait_name for $struct {
|
||||
|
||||
fn get_id(&self) -> crate::vm::object::ObjectID {
|
||||
self.$id_field
|
||||
fn get_id(&self) -> &crate::vm::object::ObjectID {
|
||||
&self.$id_field
|
||||
}
|
||||
|
||||
fn set_id(&mut self, id: crate::vm::object::ObjectID) {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
mod integrated_circuit;
|
||||
mod circuit_holder;
|
||||
|
||||
pub use integrated_circuit::ItemIntegratedCircuit10;
|
||||
|
||||
426
ic10emu/src/vm/object/stationpedia/structs/circuit_holder.rs
Normal file
426
ic10emu/src/vm/object/stationpedia/structs/circuit_holder.rs
Normal file
@@ -0,0 +1,426 @@
|
||||
use crate::{
|
||||
network::{CableConnectionType, Connection, ConnectionRole},
|
||||
vm::{
|
||||
enums::{
|
||||
basic_enums::Class as SlotClass,
|
||||
prefabs::StationpediaPrefab,
|
||||
script_enums::{LogicSlotType, LogicType},
|
||||
},
|
||||
object::{
|
||||
errors::LogicError, macros::ObjectInterface, traits::*, Name, ObjectID, Slot, VMObject,
|
||||
},
|
||||
VM,
|
||||
},
|
||||
};
|
||||
use macro_rules_attribute::derive;
|
||||
use std::rc::Rc;
|
||||
use strum::EnumProperty;
|
||||
|
||||
#[derive(ObjectInterface!)]
|
||||
#[custom(implements(Object { Structure, Device, Storage, Logicable, CircuitHolder }))]
|
||||
pub struct StructureCircuitHousing {
|
||||
#[custom(object_id)]
|
||||
pub id: ObjectID,
|
||||
#[custom(object_prefab)]
|
||||
pub prefab: Name,
|
||||
#[custom(object_name)]
|
||||
pub name: Name,
|
||||
#[custom(object_vm_ref)]
|
||||
pub vm: Rc<VM>,
|
||||
pub error: i32,
|
||||
pub on: bool,
|
||||
pub setting: f64,
|
||||
pub slot: Slot,
|
||||
pub pins: [Option<ObjectID>; 6],
|
||||
pub connections: [crate::network::Connection; 2],
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl StructureCircuitHousing {
|
||||
pub fn new(id: ObjectID, vm: Rc<VM>) -> Self {
|
||||
StructureCircuitHousing {
|
||||
id,
|
||||
prefab: Name {
|
||||
value: StationpediaPrefab::StructureCircuitHousing.to_string(),
|
||||
hash: StationpediaPrefab::StructureCircuitHousing as i32,
|
||||
},
|
||||
name: Name::new(
|
||||
StationpediaPrefab::StructureCircuitHousing
|
||||
.get_str("name")
|
||||
.unwrap(),
|
||||
),
|
||||
vm,
|
||||
error: 0,
|
||||
on: true,
|
||||
setting: 0.0,
|
||||
slot: Slot {
|
||||
parent: id,
|
||||
index: 0,
|
||||
name: "Programmable Chip".to_string(),
|
||||
typ: SlotClass::ProgrammableChip,
|
||||
readable_logic: vec![
|
||||
LogicSlotType::Class,
|
||||
LogicSlotType::Damage,
|
||||
LogicSlotType::LineNumber,
|
||||
LogicSlotType::MaxQuantity,
|
||||
LogicSlotType::OccupantHash,
|
||||
LogicSlotType::Occupied,
|
||||
LogicSlotType::PrefabHash,
|
||||
LogicSlotType::Quantity,
|
||||
LogicSlotType::ReferenceId,
|
||||
LogicSlotType::SortingClass,
|
||||
],
|
||||
writeable_logic: vec![],
|
||||
occupant: None,
|
||||
quantity: 0,
|
||||
},
|
||||
pins: [None, None, None, None, None, None],
|
||||
connections: [
|
||||
Connection::CableNetwork {
|
||||
net: None,
|
||||
typ: CableConnectionType::Data,
|
||||
role: ConnectionRole::Input,
|
||||
},
|
||||
Connection::CableNetwork {
|
||||
net: None,
|
||||
typ: CableConnectionType::Power,
|
||||
role: ConnectionRole::None,
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Structure for StructureCircuitHousing {
|
||||
fn is_small_grid(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl Storage for StructureCircuitHousing {
|
||||
fn slots_count(&self) -> usize {
|
||||
1
|
||||
}
|
||||
fn get_slot(&self, index: usize) -> Option<&Slot> {
|
||||
if index != 0 {
|
||||
None
|
||||
} else {
|
||||
Some(&self.slot)
|
||||
}
|
||||
}
|
||||
fn get_slot_mut(&mut self, index: usize) -> Option<&mut Slot> {
|
||||
if index != 0 {
|
||||
None
|
||||
} else {
|
||||
Some(&mut self.slot)
|
||||
}
|
||||
}
|
||||
fn get_slots(&self) -> Vec<&Slot> {
|
||||
vec![&self.slot]
|
||||
}
|
||||
fn get_slots_mut(&mut self) -> Vec<&mut Slot> {
|
||||
vec![&mut self.slot]
|
||||
}
|
||||
}
|
||||
|
||||
impl Logicable for StructureCircuitHousing {
|
||||
fn prefab_hash(&self) -> i32 {
|
||||
self.get_prefab().hash
|
||||
}
|
||||
fn name_hash(&self) -> i32 {
|
||||
self.get_name().hash
|
||||
}
|
||||
fn is_logic_readable(&self) -> bool {
|
||||
true
|
||||
}
|
||||
fn is_logic_writeable(&self) -> bool {
|
||||
true
|
||||
}
|
||||
fn can_logic_read(&self, lt: LogicType) -> bool {
|
||||
use LogicType::*;
|
||||
matches!(lt, Error | LineNumber | NameHash | On | Power | PrefabHash | ReferenceId
|
||||
| RequiredPower | Setting)
|
||||
}
|
||||
fn can_logic_write(&self, lt: LogicType) -> bool {
|
||||
use LogicType::*;
|
||||
matches!(lt, LineNumber | On | Setting)
|
||||
}
|
||||
fn get_logic(&self, lt: LogicType) -> Result<f64, LogicError> {
|
||||
match lt {
|
||||
LogicType::PrefabHash => Ok(self.get_prefab().hash as f64),
|
||||
LogicType::NameHash => Ok(self.get_name().hash as f64),
|
||||
LogicType::ReferenceId => Ok(*self.get_id() as f64),
|
||||
LogicType::Error => Ok(self.error as f64),
|
||||
LogicType::LineNumber => {
|
||||
let result = self
|
||||
.slot
|
||||
.occupant
|
||||
.and_then(|id| {
|
||||
self.vm
|
||||
.get_object(id)
|
||||
.and_then(|obj| {
|
||||
obj.borrow()
|
||||
.as_logicable()
|
||||
.map(|logicable| logicable.get_logic(LogicType::LineNumber))
|
||||
})
|
||||
});
|
||||
result.unwrap_or(Ok(0.0))
|
||||
}
|
||||
LogicType::On => Ok(self.on as i32 as f64),
|
||||
LogicType::Power => {
|
||||
if let Connection::CableNetwork { net, .. } = self.connections[1] {
|
||||
if net.is_some() {
|
||||
Ok(1.0)
|
||||
} else {
|
||||
Ok(0.0)
|
||||
}
|
||||
} else {
|
||||
Ok(0.0)
|
||||
}
|
||||
}
|
||||
LogicType::RequiredPower => {
|
||||
if let Connection::CableNetwork { net, .. } = self.connections[1] {
|
||||
if net.is_some() {
|
||||
if self.on {
|
||||
Ok(10.0)
|
||||
} else {
|
||||
Ok(0.0)
|
||||
}
|
||||
} else {
|
||||
Ok(-1.0)
|
||||
}
|
||||
} else {
|
||||
Ok(-1.0)
|
||||
}
|
||||
} // 10 if on
|
||||
LogicType::Setting => Ok(self.setting),
|
||||
_ => Err(LogicError::CantRead(lt)),
|
||||
}
|
||||
}
|
||||
fn set_logic(&mut self, lt: LogicType, value: f64, force: bool) -> Result<(), LogicError> {
|
||||
match lt {
|
||||
LogicType::LineNumber => self
|
||||
.slot
|
||||
.occupant
|
||||
.and_then(|id| {
|
||||
self.vm
|
||||
.get_object(id)
|
||||
.and_then(|obj| {
|
||||
obj.borrow_mut().as_mut_logicable().map(|logicable| {
|
||||
logicable.set_logic(LogicType::LineNumber, value, force)
|
||||
})
|
||||
})
|
||||
})
|
||||
.unwrap_or(Err(LogicError::CantWrite(lt))),
|
||||
LogicType::On => {
|
||||
self.on = value != 0.0;
|
||||
Ok(())
|
||||
}
|
||||
LogicType::Setting => {
|
||||
self.setting = value;
|
||||
Ok(())
|
||||
}
|
||||
_ => Err(LogicError::CantWrite(lt)),
|
||||
}
|
||||
}
|
||||
fn can_slot_logic_read(&self, _slt: LogicSlotType, _indexx: f64) -> bool {
|
||||
false
|
||||
}
|
||||
fn get_slot_logic(&self, _slt: LogicSlotType, index: f64) -> Result<f64, LogicError> {
|
||||
Err(LogicError::SlotIndexOutOfRange(index, self.slots_count()))
|
||||
}
|
||||
fn valid_logic_types(&self) -> Vec<LogicType> {
|
||||
use LogicType::*;
|
||||
vec![
|
||||
Error,
|
||||
LineNumber,
|
||||
NameHash,
|
||||
On,
|
||||
Power,
|
||||
PrefabHash,
|
||||
ReferenceId,
|
||||
RequiredPower,
|
||||
Setting,
|
||||
]
|
||||
}
|
||||
fn known_modes(&self) -> Option<Vec<(u32, String)>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl Device for StructureCircuitHousing {
|
||||
fn has_reagents(&self) -> bool {
|
||||
false
|
||||
}
|
||||
fn has_atmosphere(&self) -> bool {
|
||||
false
|
||||
}
|
||||
fn has_lock_state(&self) -> bool {
|
||||
false
|
||||
}
|
||||
fn has_mode_state(&self) -> bool {
|
||||
false
|
||||
}
|
||||
fn has_open_state(&self) -> bool {
|
||||
false
|
||||
}
|
||||
fn has_color_state(&self) -> bool {
|
||||
false
|
||||
}
|
||||
fn has_activate_state(&self) -> bool {
|
||||
false
|
||||
}
|
||||
fn has_on_off_state(&self) -> bool {
|
||||
true
|
||||
}
|
||||
fn get_reagents(&self) -> Vec<(i32, f64)> {
|
||||
vec![]
|
||||
}
|
||||
fn set_reagents(&mut self, _reagents: &[(i32, f64)]) {
|
||||
// nope
|
||||
}
|
||||
fn add_reagents(&mut self, _reagents: &[(i32, f64)]) {
|
||||
// nope
|
||||
}
|
||||
fn connection_list(&self) -> &[crate::network::Connection] {
|
||||
&self.connections
|
||||
}
|
||||
fn connection_list_mut(&mut self) -> &mut [crate::network::Connection] {
|
||||
&mut self.connections
|
||||
}
|
||||
fn device_pins(&self) -> Option<&[Option<ObjectID>]> {
|
||||
Some(&self.pins)
|
||||
}
|
||||
fn device_pins_mut(&mut self) -> Option<&mut [Option<ObjectID>]> {
|
||||
Some(&mut self.pins)
|
||||
}
|
||||
fn can_slot_logic_write(&self, _slt: LogicSlotType, _index: f64) -> bool {
|
||||
false
|
||||
}
|
||||
fn set_slot_logic(
|
||||
&mut self,
|
||||
slt: LogicSlotType,
|
||||
index: f64,
|
||||
_value: f64,
|
||||
_force: bool,
|
||||
) -> Result<(), LogicError> {
|
||||
Err(LogicError::CantSlotWrite(slt, index))
|
||||
}
|
||||
}
|
||||
|
||||
impl CircuitHolder for StructureCircuitHousing {
|
||||
fn clear_error(&mut self) {
|
||||
self.error = 0
|
||||
}
|
||||
fn set_error(&mut self, state: i32) {
|
||||
self.error = state;
|
||||
}
|
||||
/// i32::MAX is db
|
||||
fn get_logicable_from_index(
|
||||
&self,
|
||||
device: i32,
|
||||
connection: Option<usize>,
|
||||
) -> Option<ObjectRef> {
|
||||
if device == i32::MAX {
|
||||
// self
|
||||
if let Some(connection) = connection {
|
||||
self.connections.get(connection).and_then(|conn| {
|
||||
if let Connection::CableNetwork { net: Some(net), .. } = conn {
|
||||
self.vm
|
||||
.get_network(*net)
|
||||
.map(ObjectRef::from_vm_object)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
} else {
|
||||
Some(ObjectRef::from_ref(self.as_object()))
|
||||
}
|
||||
} else {
|
||||
if device < 0 {
|
||||
return None;
|
||||
}
|
||||
self.pins.get(device as usize).and_then(|pin| {
|
||||
pin.and_then(|id| {
|
||||
self.vm
|
||||
.get_object(id).map(ObjectRef::from_vm_object)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
/// i32::MAX is db
|
||||
fn get_logicable_from_index_mut(
|
||||
&mut self,
|
||||
device: i32,
|
||||
connection: Option<usize>,
|
||||
) -> Option<ObjectRefMut> {
|
||||
if device == i32::MAX {
|
||||
// self
|
||||
if let Some(connection) = connection {
|
||||
self.connections.get(connection).and_then(|conn| {
|
||||
if let Connection::CableNetwork { net: Some(net), .. } = conn {
|
||||
self.vm
|
||||
.get_network(*net)
|
||||
.map(ObjectRefMut::from_vm_object)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
} else {
|
||||
Some(ObjectRefMut::from_ref(self.as_mut_object()))
|
||||
}
|
||||
} else {
|
||||
if device < 0 {
|
||||
return None;
|
||||
}
|
||||
self.pins.get(device as usize).and_then(|pin| {
|
||||
pin.and_then(|id| {
|
||||
self.vm
|
||||
.get_object(id).map(ObjectRefMut::from_vm_object)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn get_logicable_from_id(
|
||||
&self,
|
||||
device: ObjectID,
|
||||
connection: Option<usize>,
|
||||
) -> Option<ObjectRef> {
|
||||
if connection.is_some() {
|
||||
return None; // this functionality is disabled in the game, no network access via ReferenceId
|
||||
}
|
||||
if device == self.id {
|
||||
return Some(ObjectRef::from_ref(self.as_object()));
|
||||
}
|
||||
self.vm
|
||||
.get_object(device).map(ObjectRef::from_vm_object)
|
||||
}
|
||||
|
||||
fn get_logicable_from_id_mut(
|
||||
&mut self,
|
||||
device: ObjectID,
|
||||
connection: Option<usize>,
|
||||
) -> Option<ObjectRefMut> {
|
||||
if connection.is_some() {
|
||||
return None; // this functionality is disabled in the game, no network access via ReferenceId
|
||||
}
|
||||
if device == self.id {
|
||||
return Some(ObjectRefMut::from_ref(self.as_mut_object()));
|
||||
}
|
||||
self.vm
|
||||
.get_object(device).map(ObjectRefMut::from_vm_object)
|
||||
}
|
||||
|
||||
fn get_ic(&self) -> Option<VMObject> {
|
||||
self.slot.occupant.and_then(|id| self.vm.get_object(id))
|
||||
}
|
||||
|
||||
fn get_ic_mut(&self) -> Option<VMObject> {
|
||||
self.slot.occupant.and_then(|id| self.vm.get_object(id))
|
||||
}
|
||||
|
||||
fn hault_and_catch_fire(&mut self) {
|
||||
// TODO: do something here??
|
||||
}
|
||||
}
|
||||
@@ -97,11 +97,11 @@ impl Storage for ItemIntegratedCircuit10 {
|
||||
fn get_slot_mut(&mut self, _index: usize) -> Option<&mut Slot> {
|
||||
None
|
||||
}
|
||||
fn get_slots(&self) -> &[Slot] {
|
||||
&[]
|
||||
fn get_slots(&self) -> Vec<&Slot> {
|
||||
vec![]
|
||||
}
|
||||
fn get_slots_mut(&mut self) -> &mut [Slot] {
|
||||
&mut []
|
||||
fn get_slots_mut(&mut self) -> Vec<&mut Slot> {
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,11 +165,11 @@ impl Logicable for ItemIntegratedCircuit10 {
|
||||
_ => Err(LogicError::CantWrite(lt)),
|
||||
})
|
||||
}
|
||||
fn can_slot_logic_read(&self, _slt: LogicSlotType,_indexx: f64) -> bool {
|
||||
fn can_slot_logic_read(&self, _slt: LogicSlotType, _indexx: f64) -> bool {
|
||||
false
|
||||
}
|
||||
fn get_slot_logic(&self, _slt: LogicSlotType, index: f64) -> Result<f64, LogicError> {
|
||||
return Err(LogicError::SlotIndexOutOfRange(index, self.slots_count()));
|
||||
Err(LogicError::SlotIndexOutOfRange(index, self.slots_count()))
|
||||
}
|
||||
fn valid_logic_types(&self) -> Vec<LogicType> {
|
||||
self.fields.keys().copied().collect()
|
||||
@@ -235,8 +235,7 @@ impl SourceCode for ItemIntegratedCircuit10 {
|
||||
impl IntegratedCircuit for ItemIntegratedCircuit10 {
|
||||
fn get_circuit_holder(&self) -> Option<VMObject> {
|
||||
self.get_parent_slot()
|
||||
.map(|parent_slot| self.get_vm().get_object(parent_slot.parent))
|
||||
.flatten()
|
||||
.and_then(|parent_slot| self.get_vm().get_object(parent_slot.parent))
|
||||
}
|
||||
fn get_instruction_pointer(&self) -> f64 {
|
||||
self.ip as f64
|
||||
@@ -371,7 +370,7 @@ impl IC10Marker for ItemIntegratedCircuit10 {}
|
||||
|
||||
impl Programmable for ItemIntegratedCircuit10 {
|
||||
fn step(&mut self, advance_ip_on_err: bool) -> Result<(), crate::errors::ICError> {
|
||||
if matches!(&self.state, ICState::HasCaughtFire ) {
|
||||
if matches!(&self.state, ICState::HasCaughtFire) {
|
||||
return Ok(());
|
||||
}
|
||||
if matches!(&self.state, ICState::Error(_)) && !advance_ip_on_err {
|
||||
@@ -394,7 +393,7 @@ impl Programmable for ItemIntegratedCircuit10 {
|
||||
return Err(ICError::SleepDurationError(*sleep_for));
|
||||
}
|
||||
}
|
||||
if self.ip >= self.program.len() || self.program.len() == 0 {
|
||||
if self.ip >= self.program.len() || self.program.is_empty() {
|
||||
self.state = ICState::Ended;
|
||||
return Ok(());
|
||||
}
|
||||
@@ -403,17 +402,34 @@ impl Programmable for ItemIntegratedCircuit10 {
|
||||
let line = self.program.get_line(self.ip)?.clone();
|
||||
let operands = &line.operands;
|
||||
let instruction = line.instruction;
|
||||
instruction.execute(self, operands)?;
|
||||
self.ip = self.next_ip;
|
||||
if self.ip >= self.program.len() {
|
||||
self.state = ICState::Ended;
|
||||
let result = instruction.execute(self, operands);
|
||||
|
||||
let was_error = if let Err(_err) = result {
|
||||
self.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(self.id))?
|
||||
.borrow_mut()
|
||||
.as_mut_circuit_holder()
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(self.id))?
|
||||
.set_error(1);
|
||||
true
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
if !was_error || advance_ip_on_err {
|
||||
self.ip = self.next_ip;
|
||||
if self.ip >= self.program.len() {
|
||||
self.state = ICState::Ended;
|
||||
}
|
||||
}
|
||||
|
||||
self.get_circuit_holder()
|
||||
.ok_or(ICError::NoCircuitHolder(self.id))?
|
||||
.borrow_mut()
|
||||
.as_mut_logicable()
|
||||
.ok_or(ICError::CircuitHolderNotLogicable(self.id))?
|
||||
.set_logic(LogicType::LineNumber, self.ip as f64, true)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1167,7 +1167,7 @@ impl ObjectTemplate {
|
||||
logic: logic.into(),
|
||||
memory: mem_r.into(),
|
||||
})),
|
||||
_ => Err(TemplateError::NonConformingObject(obj_ref.get_id())),
|
||||
_ => Err(TemplateError::NonConformingObject(*obj_ref.get_id())),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1243,7 +1243,7 @@ impl From<&VMObject> for ObjectInfo {
|
||||
let obj_ref = obj.borrow();
|
||||
ObjectInfo {
|
||||
name: Some(obj_ref.get_name().value.clone()),
|
||||
id: Some(obj_ref.get_id()),
|
||||
id: Some(*obj_ref.get_id()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ pub struct ParentSlotInfo {
|
||||
pub parent: ObjectID,
|
||||
pub slot: usize,
|
||||
}
|
||||
|
||||
tag_object_traits! {
|
||||
#![object_trait(Object: Debug)]
|
||||
|
||||
@@ -34,8 +33,8 @@ tag_object_traits! {
|
||||
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 get_slots(&self) -> &[Slot];
|
||||
fn get_slots_mut(&mut self) -> &mut [Slot];
|
||||
fn get_slots(&self) -> Vec<&Slot>;
|
||||
fn get_slots_mut(&mut self) -> Vec<&mut Slot>;
|
||||
}
|
||||
|
||||
pub trait MemoryReadable {
|
||||
@@ -80,16 +79,25 @@ tag_object_traits! {
|
||||
&self,
|
||||
device: i32,
|
||||
connection: Option<usize>,
|
||||
) -> Option<VMObject>;
|
||||
) -> Option<ObjectRef>;
|
||||
/// i32::MAX is db
|
||||
fn get_logicable_from_index_mut(
|
||||
&mut self,
|
||||
device: i32,
|
||||
connection: Option<usize>,
|
||||
) -> Option<ObjectRefMut>;
|
||||
fn get_logicable_from_id(
|
||||
&self,
|
||||
device: ObjectID,
|
||||
connection: Option<usize>,
|
||||
) -> Option<VMObject>;
|
||||
fn get_source_code(&self) -> String;
|
||||
fn set_source_code(&self, code: String);
|
||||
fn get_ic(&self) -> Option<ObjectID>;
|
||||
) -> Option<ObjectRef>;
|
||||
fn get_logicable_from_id_mut(
|
||||
&mut self,
|
||||
device: ObjectID,
|
||||
connection: Option<usize>,
|
||||
) -> Option<ObjectRefMut>;
|
||||
fn get_ic(&self) -> Option<VMObject>;
|
||||
fn get_ic_mut(&self) -> Option<VMObject>;
|
||||
fn hault_and_catch_fire(&mut self);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user