refactor(vm): VMObjects should carry around a VM reference
This commit is contained in:
@@ -1,8 +1,12 @@
|
||||
use std::{collections::HashSet, ops::Deref};
|
||||
use std::{collections::HashSet, ops::Deref, rc::Rc};
|
||||
|
||||
use crate::vm::{
|
||||
enums::script_enums::LogicType,
|
||||
object::{errors::LogicError, macros::ObjectInterface, templates::ConnectionInfo, traits::*, Name, ObjectID},
|
||||
object::{
|
||||
errors::LogicError, macros::ObjectInterface, templates::ConnectionInfo, traits::*, Name,
|
||||
ObjectID,
|
||||
},
|
||||
VM,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use macro_rules_attribute::derive;
|
||||
@@ -134,16 +138,68 @@ impl Connection {
|
||||
|
||||
pub fn to_info(&self) -> ConnectionInfo {
|
||||
match self {
|
||||
Self::None => ConnectionInfo { typ:ConnectionType::None, role: ConnectionRole::None, network: None },
|
||||
Self::CableNetwork { net, typ: CableConnectionType::Data, role } => ConnectionInfo { typ: ConnectionType::Data, role, network: net },
|
||||
Self::CableNetwork { net, typ: CableConnectionType::Power, role } => ConnectionInfo { typ: ConnectionType::Power, role, network: net },
|
||||
Self::CableNetwork { net, typ: CableConnectionType::PowerAndData, role } => ConnectionInfo { typ: ConnectionType::PowerAndData, role, network: net },
|
||||
Self::Chute { role } => ConnectionInfo { typ: ConnectionType::Chute, role, network: None },
|
||||
Self::Pipe { role } => ConnectionInfo { typ: ConnectionType::Pipe, role, network: None },
|
||||
Self::PipeLiquid { role } => ConnectionInfo { typ: ConnectionType::PipeLiquid, role, network: None },
|
||||
Self::Elevator { role } => ConnectionInfo { typ: ConnectionType::Elevator, role, network: None },
|
||||
Self::LandingPad { role } => ConnectionInfo { typ: ConnectionType::LandingPad, role, network: None },
|
||||
Self::LaunchPad { role } => ConnectionInfo { typ: ConnectionType::LaunchPad, role, network: None },
|
||||
Self::None => ConnectionInfo {
|
||||
typ: ConnectionType::None,
|
||||
role: ConnectionRole::None,
|
||||
network: None,
|
||||
},
|
||||
Self::CableNetwork {
|
||||
net,
|
||||
typ: CableConnectionType::Data,
|
||||
role,
|
||||
} => ConnectionInfo {
|
||||
typ: ConnectionType::Data,
|
||||
role: *role,
|
||||
network: *net,
|
||||
},
|
||||
Self::CableNetwork {
|
||||
net,
|
||||
typ: CableConnectionType::Power,
|
||||
role,
|
||||
} => ConnectionInfo {
|
||||
typ: ConnectionType::Power,
|
||||
role: *role,
|
||||
network: *net,
|
||||
},
|
||||
Self::CableNetwork {
|
||||
net,
|
||||
typ: CableConnectionType::PowerAndData,
|
||||
role,
|
||||
} => ConnectionInfo {
|
||||
typ: ConnectionType::PowerAndData,
|
||||
role: *role,
|
||||
network: *net,
|
||||
},
|
||||
Self::Chute { role } => ConnectionInfo {
|
||||
typ: ConnectionType::Chute,
|
||||
role: *role,
|
||||
network: None,
|
||||
},
|
||||
Self::Pipe { role } => ConnectionInfo {
|
||||
typ: ConnectionType::Pipe,
|
||||
role: *role,
|
||||
network: None,
|
||||
},
|
||||
Self::PipeLiquid { role } => ConnectionInfo {
|
||||
typ: ConnectionType::PipeLiquid,
|
||||
role: *role,
|
||||
network: None,
|
||||
},
|
||||
Self::Elevator { role } => ConnectionInfo {
|
||||
typ: ConnectionType::Elevator,
|
||||
role: *role,
|
||||
network: None,
|
||||
},
|
||||
Self::LandingPad { role } => ConnectionInfo {
|
||||
typ: ConnectionType::LandingPad,
|
||||
role: *role,
|
||||
network: None,
|
||||
},
|
||||
Self::LaunchPad { role } => ConnectionInfo {
|
||||
typ: ConnectionType::LaunchPad,
|
||||
role: *role,
|
||||
network: None,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -159,6 +215,9 @@ pub struct CableNetwork {
|
||||
#[custom(object_name)]
|
||||
/// required by object interface but atm unused by network
|
||||
pub name: Name,
|
||||
#[custom(object_vm_ref)]
|
||||
#[serde(skip)]
|
||||
pub vm: Option<Rc<VM>>,
|
||||
/// data enabled objects (must be devices)
|
||||
pub devices: HashSet<ObjectID>,
|
||||
/// power only connections
|
||||
@@ -177,10 +236,10 @@ 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) -> &[crate::vm::object::Slot] {
|
||||
&vec![]
|
||||
}
|
||||
fn get_slots_mut(&mut self) -> &mut[crate::vm::object::Slot] {
|
||||
fn get_slots_mut(&mut self) -> &mut [crate::vm::object::Slot] {
|
||||
&mut vec![]
|
||||
}
|
||||
}
|
||||
@@ -258,13 +317,15 @@ impl Logicable for CableNetwork {
|
||||
index: f64,
|
||||
vm: &crate::vm::VM,
|
||||
) -> Result<f64, LogicError> {
|
||||
Err(LogicError::CantSlotRead(slt, index as usize))
|
||||
Err(LogicError::CantSlotRead(slt, index))
|
||||
}
|
||||
fn valid_logic_types(&self) -> Vec<LogicType> {
|
||||
use LogicType::*;
|
||||
vec![Channel0, Channel1, Channel2, Channel3, Channel4, Channel5, Channel6, Channel7]
|
||||
vec![
|
||||
Channel0, Channel1, Channel2, Channel3, Channel4, Channel5, Channel6, Channel7,
|
||||
]
|
||||
}
|
||||
fn known_modes(&self) -> Option<Vec<(u32,String)>> {
|
||||
fn known_modes(&self) -> Option<Vec<(u32, String)>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
@@ -354,6 +415,7 @@ impl From<FrozenNetwork> for CableNetwork {
|
||||
id: value.id,
|
||||
prefab: Name::new(""),
|
||||
name: Name::new(""),
|
||||
vm: None,
|
||||
devices: value.devices.into_iter().collect(),
|
||||
power_only: value.power_only.into_iter().collect(),
|
||||
channels: value.channels,
|
||||
@@ -373,6 +435,7 @@ impl CableNetwork {
|
||||
id,
|
||||
prefab: Name::new(""),
|
||||
name: Name::new(""),
|
||||
vm: None,
|
||||
devices: HashSet::new(),
|
||||
power_only: HashSet::new(),
|
||||
channels: [f64::NAN; 8],
|
||||
|
||||
@@ -28,24 +28,21 @@ pub type ObjectID = u32;
|
||||
pub type BoxedObject = Rc<RefCell<dyn Object>>;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct VMObject {
|
||||
obj: BoxedObject,
|
||||
vm: Rc<VM>,
|
||||
}
|
||||
pub struct VMObject(BoxedObject);
|
||||
|
||||
impl Deref for VMObject {
|
||||
type Target = BoxedObject;
|
||||
|
||||
#[inline(always)]
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.obj
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for VMObject {
|
||||
#[inline(always)]
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.obj
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,18 +51,21 @@ impl VMObject {
|
||||
where
|
||||
T: Object + 'static,
|
||||
{
|
||||
VMObject {
|
||||
obj: Rc::new(RefCell::new(val)),
|
||||
vm,
|
||||
}
|
||||
let mut obj = VMObject(Rc::new(RefCell::new(val)));
|
||||
obj.set_vm(vm);
|
||||
obj
|
||||
}
|
||||
|
||||
pub fn set_vm(&mut self, vm: Rc<VM>) {
|
||||
self.vm = vm;
|
||||
self.borrow_mut().set_vm(vm);
|
||||
}
|
||||
|
||||
pub fn get_vm(&self) -> &Rc<VM> {
|
||||
&self.vm
|
||||
pub fn get_vm(&self) -> Rc<VM> {
|
||||
self
|
||||
.borrow()
|
||||
.get_vm()
|
||||
.expect("VMObject with no VM?")
|
||||
.clone()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ macro_rules! GWLogicable {
|
||||
fn fields_mut(&mut self) -> &mut BTreeMap<LogicType, LogicField> {
|
||||
&mut self.fields
|
||||
}
|
||||
fn modes(&self) -> Option<&BTreeMap<u32, String>> {
|
||||
fn known_modes(&self) -> Option<&BTreeMap<u32, String>> {
|
||||
self.modes.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,10 @@ use crate::{network::Connection, vm::{
|
||||
enums::script_enums::LogicType,
|
||||
object::{
|
||||
macros::ObjectInterface, templates::{DeviceInfo, ItemInfo}, traits::*, LogicField, Name, ObjectID, Slot,
|
||||
},
|
||||
}, VM,
|
||||
}};
|
||||
use macro_rules_attribute::derive;
|
||||
use std::collections::BTreeMap;
|
||||
use std::{collections::BTreeMap, rc::Rc};
|
||||
|
||||
#[derive(ObjectInterface!, GWStructure!)]
|
||||
#[custom(implements(Object { Structure }))]
|
||||
@@ -18,6 +18,8 @@ pub struct Generic {
|
||||
pub prefab: Name,
|
||||
#[custom(object_name)]
|
||||
pub name: Name,
|
||||
#[custom(object_vm_ref)]
|
||||
pub vm: Option<Rc<VM>>,
|
||||
pub small_grid: bool,
|
||||
}
|
||||
|
||||
@@ -30,6 +32,8 @@ pub struct GenericStorage {
|
||||
pub prefab: Name,
|
||||
#[custom(object_name)]
|
||||
pub name: Name,
|
||||
#[custom(object_vm_ref)]
|
||||
pub vm: Option<Rc<VM>>,
|
||||
pub small_grid: bool,
|
||||
pub slots: Vec<Slot>,
|
||||
}
|
||||
@@ -43,6 +47,8 @@ pub struct GenericLogicable {
|
||||
pub prefab: Name,
|
||||
#[custom(object_name)]
|
||||
pub name: Name,
|
||||
#[custom(object_vm_ref)]
|
||||
pub vm: Option<Rc<VM>>,
|
||||
pub small_grid: bool,
|
||||
pub slots: Vec<Slot>,
|
||||
pub fields: BTreeMap<LogicType, LogicField>,
|
||||
@@ -58,6 +64,8 @@ pub struct GenericLogicableDevice {
|
||||
pub prefab: Name,
|
||||
#[custom(object_name)]
|
||||
pub name: Name,
|
||||
#[custom(object_vm_ref)]
|
||||
pub vm: Option<Rc<VM>>,
|
||||
pub small_grid: bool,
|
||||
pub slots: Vec<Slot>,
|
||||
pub fields: BTreeMap<LogicType, LogicField>,
|
||||
@@ -76,6 +84,8 @@ pub struct GenericLogicableDeviceMemoryReadable {
|
||||
pub prefab: Name,
|
||||
#[custom(object_name)]
|
||||
pub name: Name,
|
||||
#[custom(object_vm_ref)]
|
||||
pub vm: Option<Rc<VM>>,
|
||||
pub small_grid: bool,
|
||||
pub slots: Vec<Slot>,
|
||||
pub fields: BTreeMap<LogicType, LogicField>,
|
||||
@@ -95,6 +105,8 @@ pub struct GenericLogicableDeviceMemoryReadWriteable {
|
||||
pub prefab: Name,
|
||||
#[custom(object_name)]
|
||||
pub name: Name,
|
||||
#[custom(object_vm_ref)]
|
||||
pub vm: Option<Rc<VM>>,
|
||||
pub small_grid: bool,
|
||||
pub slots: Vec<Slot>,
|
||||
pub fields: BTreeMap<LogicType, LogicField>,
|
||||
@@ -114,6 +126,8 @@ pub struct GenericItem {
|
||||
pub prefab: Name,
|
||||
#[custom(object_name)]
|
||||
pub name: Name,
|
||||
#[custom(object_vm_ref)]
|
||||
pub vm: Option<Rc<VM>>,
|
||||
pub item_info: ItemInfo,
|
||||
pub parent_slot: Option<ParentSlotInfo>,
|
||||
}
|
||||
@@ -127,6 +141,8 @@ pub struct GenericItemStorage {
|
||||
pub prefab: Name,
|
||||
#[custom(object_name)]
|
||||
pub name: Name,
|
||||
#[custom(object_vm_ref)]
|
||||
pub vm: Option<Rc<VM>>,
|
||||
pub item_info: ItemInfo,
|
||||
pub parent_slot: Option<ParentSlotInfo>,
|
||||
pub slots: Vec<Slot>,
|
||||
@@ -141,6 +157,8 @@ pub struct GenericItemLogicable {
|
||||
pub prefab: Name,
|
||||
#[custom(object_name)]
|
||||
pub name: Name,
|
||||
#[custom(object_vm_ref)]
|
||||
pub vm: Option<Rc<VM>>,
|
||||
pub item_info: ItemInfo,
|
||||
pub parent_slot: Option<ParentSlotInfo>,
|
||||
pub slots: Vec<Slot>,
|
||||
@@ -157,6 +175,8 @@ pub struct GenericItemLogicableMemoryReadable {
|
||||
pub prefab: Name,
|
||||
#[custom(object_name)]
|
||||
pub name: Name,
|
||||
#[custom(object_vm_ref)]
|
||||
pub vm: Option<Rc<VM>>,
|
||||
pub item_info: ItemInfo,
|
||||
pub parent_slot: Option<ParentSlotInfo>,
|
||||
pub slots: Vec<Slot>,
|
||||
@@ -174,6 +194,8 @@ pub struct GenericItemLogicableMemoryReadWriteable {
|
||||
pub prefab: Name,
|
||||
#[custom(object_name)]
|
||||
pub name: Name,
|
||||
#[custom(object_vm_ref)]
|
||||
pub vm: Option<Rc<VM>>,
|
||||
pub item_info: ItemInfo,
|
||||
pub parent_slot: Option<ParentSlotInfo>,
|
||||
pub slots: Vec<Slot>,
|
||||
|
||||
@@ -53,7 +53,7 @@ impl<T: GWStorage + Object> Storage for T {
|
||||
pub trait GWLogicable: Storage {
|
||||
fn fields(&self) -> &BTreeMap<LogicType, LogicField>;
|
||||
fn fields_mut(&mut self) -> &mut BTreeMap<LogicType, LogicField>;
|
||||
fn modes(&self) -> Option<&BTreeMap<u32, String>>;
|
||||
fn known_modes(&self) -> Option<&BTreeMap<u32, String>>;
|
||||
}
|
||||
|
||||
impl<T: GWLogicable + Object> Logicable for T {
|
||||
@@ -148,8 +148,13 @@ impl<T: GWLogicable + Object> Logicable for T {
|
||||
fn valid_logic_types(&self) -> Vec<LogicType> {
|
||||
self.fields().keys().copied().collect()
|
||||
}
|
||||
fn known_modes(&self) -> Option<Vec<(u32,String)>> {
|
||||
self.modes().map(|modes| modes.iter().collect())
|
||||
fn known_modes(&self) -> Option<Vec<(u32, String)>> {
|
||||
self.known_modes().map(|modes| {
|
||||
modes
|
||||
.iter()
|
||||
.map(|(mode, name)| (*mode, name.clone()))
|
||||
.collect()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,7 +176,7 @@ impl<T: GWMemoryReadable + Object> MemoryReadable for T {
|
||||
Ok(self.memory()[index as usize])
|
||||
}
|
||||
}
|
||||
fn get_memory_slice(&self) -> &[f64] {
|
||||
fn get_memory_slice(&self) -> &[f64] {
|
||||
self.memory()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@ macro_rules! object_trait {
|
||||
fn get_mut_prefab(&mut self) -> &mut crate::vm::object::Name;
|
||||
fn get_name(&self) -> &crate::vm::object::Name;
|
||||
fn get_mut_name(&mut self) -> &mut crate::vm::object::Name;
|
||||
fn get_vm(&self) -> Option<&std::rc::Rc<crate::vm::VM>>;
|
||||
fn set_vm(&mut self, vm: std::rc::Rc<crate::vm::VM>);
|
||||
fn type_name(&self) -> &str;
|
||||
fn as_object(&self) -> &dyn $trait_name;
|
||||
fn as_mut_object(&mut self) -> &mut dyn $trait_name;
|
||||
@@ -71,14 +73,25 @@ macro_rules! object_trait {
|
||||
|
||||
pub(crate) use object_trait;
|
||||
|
||||
/// use macro_rules_attribute::derive to apply this macro to a struct
|
||||
///
|
||||
/// use `#[custom(object_id)]`, `#[custom(object_prefab)]`, `#[custom(object_name)]`, and `#[custom(object_vm_ref)]`
|
||||
/// to tag struct fields appropriately
|
||||
///
|
||||
/// the tags for `id`, `prefab`, and `name` may appear in any order but `vm_ref` must come last
|
||||
///
|
||||
/// - `id` must be `crate::vm::object::ObjectID`
|
||||
/// - `prefab` and `name` must be `crate::vm::object::Name`
|
||||
/// - `vm_ref` must be `Option<std::rc::Rc<crate::vm::VM>>`
|
||||
macro_rules! ObjectInterface {
|
||||
{
|
||||
@body_id_prefab_name
|
||||
@body_final
|
||||
@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;
|
||||
@vm_ref $vm_ref_field:ident: $vm_ref_typ:ty;
|
||||
} => {
|
||||
impl $trait_name for $struct {
|
||||
|
||||
@@ -106,6 +119,14 @@ macro_rules! ObjectInterface {
|
||||
&mut self.$name_field
|
||||
}
|
||||
|
||||
fn get_vm(&self) -> Option<&std::rc::Rc<crate::vm::VM>> {
|
||||
self.$vm_ref_field.as_ref()
|
||||
}
|
||||
|
||||
fn set_vm(&mut self, vm: std::rc::Rc<crate::vm::VM>) {
|
||||
self.$vm_ref_field = Some(vm);
|
||||
}
|
||||
|
||||
fn type_name(&self) -> &str {
|
||||
std::any::type_name::<Self>()
|
||||
}
|
||||
@@ -135,301 +156,117 @@ macro_rules! ObjectInterface {
|
||||
}
|
||||
};
|
||||
{
|
||||
@body_id_name
|
||||
@body_final
|
||||
@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 )*
|
||||
|
||||
@vm_ref $vm_ref_field:ident: $vm_ref_typ:ty;
|
||||
} => {
|
||||
$crate::vm::object::macros::ObjectInterface!{
|
||||
@body_id_prefab_name
|
||||
@body_final
|
||||
@trt $trait_name; $struct;
|
||||
@impls $($trt),*;
|
||||
@id $id_field: $id_typ;
|
||||
@prefab $prefab_field: $prefab_typ;
|
||||
@name $name_field: $name_typ;
|
||||
@vm_ref $vm_ref_field: $vm_ref_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
|
||||
@body_final
|
||||
@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 )*
|
||||
@vm_ref $vm_ref_field:ident: $vm_ref_typ:ty;
|
||||
} => {
|
||||
$crate::vm::object::macros::ObjectInterface!{
|
||||
@body_id_name
|
||||
@body_final
|
||||
@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;
|
||||
@impls $($trt:path),*;
|
||||
@id $id_field:ident: $id_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
|
||||
@trt $trait_name; $struct;
|
||||
@impls $($trt),*;
|
||||
@id $id_field: $id_typ;
|
||||
@prefab $prefab_field: $prefab_typ;
|
||||
$( $rest )*
|
||||
}
|
||||
};
|
||||
{
|
||||
@body_id
|
||||
@trt $trait_name:ident; $struct:ident;
|
||||
@impls $($trt:path),*;
|
||||
@id $id_field:ident: $id_typ:ty;
|
||||
$(#[#field:meta])*
|
||||
$field_viz:vis
|
||||
$field_name:ident : $field_ty:ty,
|
||||
$( $rest:tt )*
|
||||
} => {
|
||||
$crate::vm::object::macros::ObjectInterface!{
|
||||
@body_id
|
||||
@trt $trait_name; $struct;
|
||||
@impls $($trt),*;
|
||||
@id $id_field: $id_typ;
|
||||
$( $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 )*
|
||||
@vm_ref $vm_ref_field: $vm_ref_typ;
|
||||
}
|
||||
};
|
||||
{
|
||||
@body_prefab
|
||||
@body_final
|
||||
@trt $trait_name:ident; $struct:ident;
|
||||
@impls $($trt:path),*;
|
||||
@prefab $prefab_field:ident: $prefab_typ:ty;
|
||||
#[custom(object_id)]
|
||||
$(#[$id_attr:meta])*
|
||||
$id_viz:vis $id_field:ident: $id_typ:ty,
|
||||
$( $rest:tt )*
|
||||
|
||||
@id $id_field:ident: $id_typ:ty;
|
||||
@name $name_field:ident: $name_typ:ty;
|
||||
@vm_ref $vm_ref_field:ident: $vm_ref_typ:ty;
|
||||
} => {
|
||||
$crate::vm::object::macros::ObjectInterface!{
|
||||
@body_id_prefab
|
||||
@body_final
|
||||
@trt $trait_name; $struct;
|
||||
@impls $($trt),*;
|
||||
@id $id_field: $id_typ;
|
||||
@prefab $prefab_field: $prefab_typ;
|
||||
$( $rest )*
|
||||
@name $name_field: $name_typ;
|
||||
@vm_ref $vm_ref_field: $vm_ref_typ;
|
||||
}
|
||||
};
|
||||
{
|
||||
@body_prefab
|
||||
@body_final
|
||||
@trt $trait_name:ident; $struct:ident;
|
||||
@impls $($trt:path),*;
|
||||
@name $name_field:ident: $name_typ:ty;
|
||||
@prefab $prefab_field:ident: $prefab_typ:ty;
|
||||
$(#[#field:meta])*
|
||||
$field_viz:vis
|
||||
$field_name:ident : $field_ty:ty,
|
||||
@id $id_field:ident: $id_typ:ty;
|
||||
@vm_ref $vm_ref_field:ident: $vm_ref_typ:ty;
|
||||
} => {
|
||||
$crate::vm::object::macros::ObjectInterface!{
|
||||
@body_final
|
||||
@trt $trait_name; $struct;
|
||||
@impls $($trt),*;
|
||||
@id $id_field: $id_typ;
|
||||
@prefab $prefab_field: $prefab_typ;
|
||||
@name $name_field: $name_typ;
|
||||
@vm_ref $vm_ref_field: $vm_ref_typ;
|
||||
}
|
||||
};
|
||||
{
|
||||
@body_final
|
||||
@trt $trait_name:ident; $struct:ident;
|
||||
@impls $($trt:path),*;
|
||||
@name $name_field:ident: $name_typ:ty;
|
||||
@id $id_field:ident: $id_typ:ty;
|
||||
@prefab $prefab_field:ident: $prefab_typ:ty;
|
||||
@vm_ref $vm_ref_field:ident: $vm_ref_typ:ty;
|
||||
} => {
|
||||
$crate::vm::object::macros::ObjectInterface!{
|
||||
@body_final
|
||||
@trt $trait_name; $struct;
|
||||
@impls $($trt),*;
|
||||
@id $id_field: $id_typ;
|
||||
@prefab $prefab_field: $prefab_typ;
|
||||
@name $name_field: $name_typ;
|
||||
@vm_ref $vm_ref_field: $vm_ref_typ;
|
||||
}
|
||||
};{
|
||||
@body
|
||||
@trt $trait_name:ident; $struct:ident;
|
||||
@impls $($trt:path),*;
|
||||
@tags {
|
||||
$(@$tag:tt $tag_field:ident: $tag_typ:ty;)*
|
||||
};
|
||||
#[custom(object_vm_ref)]
|
||||
$(#[$vm_ref_attr:meta])*
|
||||
$vm_ref_viz:vis $vm_ref_field:ident: $vm_ref_typ:ty,
|
||||
$( $rest:tt )*
|
||||
|
||||
} => {
|
||||
$crate::vm::object::macros::ObjectInterface!{
|
||||
@body_prefab
|
||||
@body
|
||||
@trt $trait_name; $struct;
|
||||
@impls $($trt),*;
|
||||
@prefab $prefab_field: $prefab_typ;
|
||||
@tags {$(@$tag $tag_field: $tag_typ;)* @vm_ref $vm_ref_field: $vm_ref_typ;};
|
||||
$( $rest )*
|
||||
}
|
||||
};
|
||||
@@ -437,6 +274,9 @@ macro_rules! ObjectInterface {
|
||||
@body
|
||||
@trt $trait_name:ident; $struct:ident;
|
||||
@impls $($trt:path),*;
|
||||
@tags {
|
||||
$(@$tag:tt $tag_field:ident: $tag_typ:ty;)*
|
||||
};
|
||||
#[custom(object_name)]
|
||||
$(#[$name_attr:meta])*
|
||||
$name_viz:vis $name_field:ident: $name_typ:ty,
|
||||
@@ -444,10 +284,10 @@ macro_rules! ObjectInterface {
|
||||
|
||||
} => {
|
||||
$crate::vm::object::macros::ObjectInterface!{
|
||||
@body_name
|
||||
@body
|
||||
@trt $trait_name; $struct;
|
||||
@impls $($trt),*;
|
||||
@name $name_field: $name_typ;
|
||||
@tags {$(@$tag $tag_field: $tag_typ;)* @name $name_field: $name_typ;};
|
||||
$( $rest )*
|
||||
}
|
||||
};
|
||||
@@ -455,6 +295,9 @@ macro_rules! ObjectInterface {
|
||||
@body
|
||||
@trt $trait_name:ident; $struct:ident;
|
||||
@impls $($trt:path),*;
|
||||
@tags {
|
||||
$(@$tag:tt $tag_field:ident: $tag_typ:ty;)*
|
||||
};
|
||||
#[custom(object_prefab)]
|
||||
$(#[$prefab_attr:meta])*
|
||||
$prefab_viz:vis $prefab_field:ident: $prefab_typ:ty,
|
||||
@@ -462,10 +305,10 @@ macro_rules! ObjectInterface {
|
||||
|
||||
} => {
|
||||
$crate::vm::object::macros::ObjectInterface!{
|
||||
@body_prefab
|
||||
@body
|
||||
@trt $trait_name; $struct;
|
||||
@impls $($trt),*;
|
||||
@prefab $prefab_field: $prefab_typ;
|
||||
@tags {$(@$tag $tag_field: $tag_typ;)* @prefab $prefab_field: $prefab_typ;};
|
||||
$( $rest )*
|
||||
}
|
||||
};
|
||||
@@ -473,6 +316,9 @@ macro_rules! ObjectInterface {
|
||||
@body
|
||||
@trt $trait_name:ident; $struct:ident;
|
||||
@impls $($trt:path),*;
|
||||
@tags {
|
||||
$(@$tag:tt $tag_field:ident: $tag_typ:ty;)*
|
||||
};
|
||||
#[custom(object_id)]
|
||||
$(#[$id_attr:meta])*
|
||||
$id_viz:vis $id_field:ident: $id_typ:ty,
|
||||
@@ -480,10 +326,10 @@ macro_rules! ObjectInterface {
|
||||
|
||||
} => {
|
||||
$crate::vm::object::macros::ObjectInterface!{
|
||||
@body_id
|
||||
@body
|
||||
@trt $trait_name; $struct;
|
||||
@impls $($trt),*;
|
||||
@id $id_field: $id_typ;
|
||||
@tags {$(@$tag $tag_field: $tag_typ;)* @id $id_field: $id_typ;};
|
||||
$( $rest )*
|
||||
}
|
||||
};
|
||||
@@ -491,7 +337,10 @@ macro_rules! ObjectInterface {
|
||||
@body
|
||||
@trt $trait_name:ident; $struct:ident;
|
||||
@impls $($trt:path),*;
|
||||
$(#[#field:meta])*
|
||||
@tags {
|
||||
$(@$tag:tt $tag_field:ident: $tag_typ:ty;)*
|
||||
};
|
||||
$(#[$field:meta])*
|
||||
$field_viz:vis
|
||||
$field_name:ident : $field_ty:ty,
|
||||
$( $rest:tt )*
|
||||
@@ -501,9 +350,27 @@ macro_rules! ObjectInterface {
|
||||
@body
|
||||
@trt $trait_name; $struct;
|
||||
@impls $($trt),*;
|
||||
@tags {$(@$tag $tag_field: $tag_typ;)*};
|
||||
$( $rest )*
|
||||
}
|
||||
};
|
||||
{
|
||||
@body
|
||||
@trt $trait_name:ident; $struct:ident;
|
||||
@impls $($trt:path),*;
|
||||
@tags {
|
||||
$(@$tag:tt $tag_field:ident: $tag_typ:ty;)*
|
||||
};
|
||||
} => {
|
||||
$crate::vm::object::macros::ObjectInterface!{
|
||||
@body_final
|
||||
@trt $trait_name; $struct;
|
||||
@impls $($trt),*;
|
||||
$(
|
||||
@$tag $tag_field: $tag_typ;
|
||||
)*
|
||||
}
|
||||
};
|
||||
{
|
||||
#[custom(implements($trait_name:ident {$($trt:path),*}))]
|
||||
$( #[$attr:meta] )*
|
||||
@@ -515,6 +382,7 @@ macro_rules! ObjectInterface {
|
||||
@body
|
||||
@trt $trait_name; $struct;
|
||||
@impls $($trt),*;
|
||||
@tags {};
|
||||
$( $body )*
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
use crate::{
|
||||
errors::{ICError, LineError},
|
||||
grammar,
|
||||
interpreter::ICState,
|
||||
vm::{
|
||||
enums::{
|
||||
basic_enums::{Class as SlotClass, GasType, SortingClass},
|
||||
script_enums::LogicType,
|
||||
script_enums::{LogicSlotType, LogicType},
|
||||
},
|
||||
instructions::{
|
||||
enums::InstructionOp,
|
||||
@@ -13,11 +14,10 @@ use crate::{
|
||||
Instruction,
|
||||
},
|
||||
object::{
|
||||
errors::MemoryError,
|
||||
generic::{macros::GWLogicable, traits::GWLogicable},
|
||||
errors::{LogicError, MemoryError},
|
||||
macros::ObjectInterface,
|
||||
traits::*,
|
||||
LogicField, Name, ObjectID, Slot,
|
||||
LogicField, MemoryAccess, Name, ObjectID, Slot,
|
||||
},
|
||||
VM,
|
||||
},
|
||||
@@ -25,7 +25,10 @@ use crate::{
|
||||
use itertools::Itertools;
|
||||
use macro_rules_attribute::derive;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use std::collections::{BTreeMap, HashSet};
|
||||
use std::{
|
||||
collections::{BTreeMap, HashSet},
|
||||
rc::Rc,
|
||||
};
|
||||
use ICError::*;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
@@ -139,20 +142,10 @@ impl Program {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub enum ICState {
|
||||
Start,
|
||||
Running,
|
||||
Yield,
|
||||
Sleep(time::OffsetDateTime, f64),
|
||||
HasCaughtFire,
|
||||
Error(LineError),
|
||||
}
|
||||
|
||||
static RETURN_ADDRESS_INDEX: usize = 17;
|
||||
static STACK_POINTER_INDEX: usize = 16;
|
||||
|
||||
#[derive(ObjectInterface!, GWLogicable!)]
|
||||
#[derive(ObjectInterface!)]
|
||||
#[custom(implements(Object { Item, Storage, Logicable, MemoryReadable, MemoryWritable }))]
|
||||
pub struct ItemIntegratedCircuit10 {
|
||||
#[custom(object_id)]
|
||||
@@ -161,6 +154,8 @@ pub struct ItemIntegratedCircuit10 {
|
||||
pub prefab: Name,
|
||||
#[custom(object_name)]
|
||||
pub name: Name,
|
||||
#[custom(object_vm_ref)]
|
||||
pub vm: Option<Rc<VM>>,
|
||||
pub fields: BTreeMap<LogicType, LogicField>,
|
||||
pub memory: [f64; 512],
|
||||
pub parent_slot: Option<ParentSlotInfo>,
|
||||
@@ -218,13 +213,86 @@ 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) -> &[Slot] {
|
||||
&[]
|
||||
}
|
||||
fn get_slots_mut(&mut self) -> &mut[Slot] {
|
||||
fn get_slots_mut(&mut self) -> &mut [Slot] {
|
||||
&mut []
|
||||
}
|
||||
}
|
||||
impl Logicable for ItemIntegratedCircuit10 {
|
||||
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 {
|
||||
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)
|
||||
}
|
||||
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))
|
||||
}
|
||||
fn set_logic(&mut self, lt: LogicType, value: f64, force: bool) -> Result<(), LogicError> {
|
||||
self.fields
|
||||
.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 {
|
||||
false
|
||||
}
|
||||
fn get_slot_logic(&self, slt: LogicSlotType, index: f64, _vm: &VM) -> Result<f64, LogicError> {
|
||||
return Err(LogicError::SlotIndexOutOfRange(index, self.slots_count()));
|
||||
}
|
||||
fn valid_logic_types(&self) -> Vec<LogicType> {
|
||||
self.fields.keys().copied().collect()
|
||||
}
|
||||
fn known_modes(&self) -> Option<Vec<(u32, String)>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl MemoryReadable for ItemIntegratedCircuit10 {
|
||||
fn memory_size(&self) -> usize {
|
||||
@@ -239,7 +307,7 @@ impl MemoryReadable for ItemIntegratedCircuit10 {
|
||||
Ok(self.memory[index as usize])
|
||||
}
|
||||
}
|
||||
fn get_memory_slice(&self) -> &[f64] {
|
||||
fn get_memory_slice(&self) -> &[f64] {
|
||||
&self.memory
|
||||
}
|
||||
}
|
||||
@@ -280,9 +348,14 @@ impl SourceCode for ItemIntegratedCircuit10 {
|
||||
}
|
||||
|
||||
impl IntegratedCircuit for ItemIntegratedCircuit10 {
|
||||
fn get_circuit_holder(&self, vm: &VM) -> Option<CircuitHolderRef> {
|
||||
// FIXME: implement correctly
|
||||
self.get_parent_slot().map(|parent_slot| parent_slot.parent)
|
||||
fn get_circuit_holder(&self, vm: &Rc<VM>) -> Option<CircuitHolderRef> {
|
||||
self.get_parent_slot()
|
||||
.map(|parent_slot| {
|
||||
vm.get_object(parent_slot.parent)
|
||||
.map(|obj| obj.borrow().as_circuit_holder())
|
||||
.flatten()
|
||||
})
|
||||
.flatten()
|
||||
}
|
||||
fn get_instruction_pointer(&self) -> f64 {
|
||||
self.ip as f64
|
||||
@@ -338,9 +411,9 @@ impl IntegratedCircuit for ItemIntegratedCircuit10 {
|
||||
fn push_stack(&mut self, val: f64) -> Result<f64, ICError> {
|
||||
let sp = (self.registers[STACK_POINTER_INDEX].round()) as i32;
|
||||
if sp < 0 {
|
||||
Err(ICError::StackUnderflow)
|
||||
Err(MemoryError::StackUnderflow(sp, self.memory.len()).into())
|
||||
} else if sp as usize >= self.memory.len() {
|
||||
Err(ICError::StackOverflow)
|
||||
Err(MemoryError::StackOverflow(sp, self.memory.len()).into())
|
||||
} else {
|
||||
let last = self.memory[sp as usize];
|
||||
self.memory[sp as usize] = val;
|
||||
@@ -352,9 +425,9 @@ impl IntegratedCircuit for ItemIntegratedCircuit10 {
|
||||
self.registers[STACK_POINTER_INDEX] -= 1.0;
|
||||
let sp = (self.registers[STACK_POINTER_INDEX].round()) as i32;
|
||||
if sp < 0 {
|
||||
Err(ICError::StackUnderflow)
|
||||
Err(MemoryError::StackUnderflow(sp, self.memory.len()).into())
|
||||
} else if sp as usize >= self.memory.len() {
|
||||
Err(ICError::StackOverflow)
|
||||
Err(MemoryError::StackOverflow(sp, self.memory.len()).into())
|
||||
} else {
|
||||
let last = self.memory[sp as usize];
|
||||
Ok(last)
|
||||
@@ -363,9 +436,9 @@ impl IntegratedCircuit for ItemIntegratedCircuit10 {
|
||||
fn peek_stack(&self) -> Result<f64, ICError> {
|
||||
let sp = (self.registers[STACK_POINTER_INDEX] - 1.0).round() as i32;
|
||||
if sp < 0 {
|
||||
Err(ICError::StackUnderflow)
|
||||
Err(MemoryError::StackUnderflow(sp, self.memory.len()).into())
|
||||
} else if sp as usize >= self.memory.len() {
|
||||
Err(ICError::StackOverflow)
|
||||
Err(MemoryError::StackOverflow(sp, self.memory.len()).into())
|
||||
} else {
|
||||
let last = self.memory[sp as usize];
|
||||
Ok(last)
|
||||
@@ -1325,7 +1398,6 @@ impl BdseInstruction for ItemIntegratedCircuit10 {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// impl BdsealInstruction for ItemIntegratedCircuit10 {
|
||||
// /// bdseal d? a(r?|num)
|
||||
// fn execute_bdseal(&mut self, vm: &VM, d: &Operand, a: &Operand) -> Result<(), ICError>;
|
||||
|
||||
@@ -203,6 +203,7 @@ impl ObjectTemplate {
|
||||
id,
|
||||
prefab: Name::from_prefab_name(&s.prefab.prefab_name),
|
||||
name: Name::new(&s.prefab.name),
|
||||
vm: None,
|
||||
small_grid: s.structure.small_grid,
|
||||
},
|
||||
vm.clone(),
|
||||
@@ -212,6 +213,7 @@ impl ObjectTemplate {
|
||||
id,
|
||||
prefab: Name::from_prefab_name(&s.prefab.prefab_name),
|
||||
name: Name::new(&s.prefab.name),
|
||||
vm: None,
|
||||
small_grid: s.structure.small_grid,
|
||||
slots: s
|
||||
.slots
|
||||
@@ -235,6 +237,7 @@ impl ObjectTemplate {
|
||||
id,
|
||||
prefab: Name::from_prefab_name(&s.prefab.prefab_name),
|
||||
name: Name::new(&s.prefab.name),
|
||||
vm: None,
|
||||
small_grid: s.structure.small_grid,
|
||||
slots: s
|
||||
.slots
|
||||
@@ -314,6 +317,7 @@ impl ObjectTemplate {
|
||||
id,
|
||||
prefab: Name::from_prefab_name(&s.prefab.prefab_name),
|
||||
name: Name::new(&s.prefab.name),
|
||||
vm: None,
|
||||
small_grid: s.structure.small_grid,
|
||||
slots: s
|
||||
.slots
|
||||
@@ -414,6 +418,7 @@ impl ObjectTemplate {
|
||||
id,
|
||||
prefab: Name::from_prefab_name(&s.prefab.prefab_name),
|
||||
name: Name::new(&s.prefab.name),
|
||||
vm: None,
|
||||
small_grid: s.structure.small_grid,
|
||||
slots: s
|
||||
.slots
|
||||
@@ -521,6 +526,7 @@ impl ObjectTemplate {
|
||||
id,
|
||||
prefab: Name::from_prefab_name(&s.prefab.prefab_name),
|
||||
name: Name::new(&s.prefab.name),
|
||||
vm: None,
|
||||
small_grid: s.structure.small_grid,
|
||||
slots: s
|
||||
.slots
|
||||
@@ -623,6 +629,7 @@ impl ObjectTemplate {
|
||||
id,
|
||||
prefab: Name::from_prefab_name(&i.prefab.prefab_name),
|
||||
name: Name::new(&i.prefab.name),
|
||||
vm: None,
|
||||
item_info: i.item.clone(),
|
||||
parent_slot: None,
|
||||
},
|
||||
@@ -633,6 +640,7 @@ impl ObjectTemplate {
|
||||
id,
|
||||
prefab: Name::from_prefab_name(&i.prefab.prefab_name),
|
||||
name: Name::new(&i.prefab.name),
|
||||
vm: None,
|
||||
item_info: i.item.clone(),
|
||||
parent_slot: None,
|
||||
slots: i
|
||||
@@ -657,6 +665,7 @@ impl ObjectTemplate {
|
||||
id,
|
||||
prefab: Name::from_prefab_name(&i.prefab.prefab_name),
|
||||
name: Name::new(&i.prefab.name),
|
||||
vm: None,
|
||||
item_info: i.item.clone(),
|
||||
parent_slot: None,
|
||||
slots: i
|
||||
@@ -738,6 +747,7 @@ impl ObjectTemplate {
|
||||
id,
|
||||
prefab: Name::from_prefab_name(&i.prefab.prefab_name),
|
||||
name: Name::new(&i.prefab.name),
|
||||
vm: None,
|
||||
item_info: i.item.clone(),
|
||||
parent_slot: None,
|
||||
slots: i
|
||||
@@ -824,6 +834,7 @@ impl ObjectTemplate {
|
||||
id,
|
||||
prefab: Name::from_prefab_name(&i.prefab.prefab_name),
|
||||
name: Name::new(&i.prefab.name),
|
||||
vm: None,
|
||||
item_info: i.item.clone(),
|
||||
parent_slot: None,
|
||||
slots: i
|
||||
@@ -1308,7 +1319,7 @@ impl From<LogicableRef<'_>> for LogicInfo {
|
||||
.iter()
|
||||
.filter_map(|lt| match logic.get_logic(*lt) {
|
||||
Ok(val) => Some((*lt, val)),
|
||||
_ => None
|
||||
_ => None,
|
||||
})
|
||||
.collect(),
|
||||
),
|
||||
@@ -1377,9 +1388,15 @@ pub struct DeviceInfo {
|
||||
impl From<DeviceRef<'_>> for DeviceInfo {
|
||||
fn from(device: DeviceRef) -> Self {
|
||||
DeviceInfo {
|
||||
connection_list: device.connection_list().iter().map(|conn| conn.to_info()).collect(),
|
||||
connection_list: device
|
||||
.connection_list()
|
||||
.iter()
|
||||
.map(|conn| conn.to_info())
|
||||
.collect(),
|
||||
device_pins_length: device.device_pins().map(|pins| pins.len()),
|
||||
device_pins: device.device_pins().map(|pins| pins.iter().copied().collect()),
|
||||
device_pins: device
|
||||
.device_pins()
|
||||
.map(|pins| pins.iter().copied().collect()),
|
||||
has_reagents: device.has_reagents(),
|
||||
has_lock_state: device.has_lock_state(),
|
||||
has_mode_state: device.has_mode_state(),
|
||||
|
||||
@@ -15,7 +15,7 @@ use crate::{
|
||||
VM,
|
||||
}
|
||||
};
|
||||
use std::{collections::BTreeMap, fmt::Debug};
|
||||
use std::{collections::BTreeMap, fmt::Debug, rc::Rc};
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
|
||||
pub struct ParentSlotInfo {
|
||||
@@ -99,7 +99,7 @@ tag_object_traits! {
|
||||
}
|
||||
|
||||
pub trait IntegratedCircuit: Logicable + MemoryWritable + SourceCode + Item {
|
||||
fn get_circuit_holder(&self, vm: &VM) -> Option<CircuitHolderRef>;
|
||||
fn get_circuit_holder(&self, vm: &Rc<VM>) -> Option<CircuitHolderRef>;
|
||||
fn get_instruction_pointer(&self) -> f64;
|
||||
fn set_next_instruction(&mut self, next_instruction: f64);
|
||||
fn set_next_instruction_relative(&mut self, offset: f64) {
|
||||
|
||||
Reference in New Issue
Block a user