link error field, enhance networks, improve device update envents
This commit is contained in:
@@ -107,7 +107,7 @@ pub enum ICError {
|
||||
#[error("connection specifier missing")]
|
||||
MissingConnectionSpecifier,
|
||||
#[error("no data network on connection '{0}'")]
|
||||
NotDataConnection(usize),
|
||||
NotACableConnection(usize),
|
||||
#[error("network not connected on connection '{0}'")]
|
||||
NetworkNotConnected(usize),
|
||||
#[error("bad network Id '{0}'")]
|
||||
|
||||
@@ -16,6 +16,8 @@ use itertools::Itertools;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::interpreter::ICState;
|
||||
|
||||
#[derive(Error, Debug, Serialize, Deserialize)]
|
||||
pub enum VMError {
|
||||
#[error("device with id '{0}' does not exist")]
|
||||
@@ -226,9 +228,20 @@ impl Slot {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy, Serialize, Deserialize)]
|
||||
pub enum CableConnectionType {
|
||||
Power,
|
||||
Data,
|
||||
#[default]
|
||||
PowerAndData,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy, Serialize, Deserialize)]
|
||||
pub enum Connection {
|
||||
CableNetwork(Option<u32>),
|
||||
CableNetwork {
|
||||
net: Option<u32>,
|
||||
typ: CableConnectionType,
|
||||
},
|
||||
#[default]
|
||||
Other,
|
||||
}
|
||||
@@ -282,9 +295,18 @@ impl Connection {
|
||||
| ConnectionType::LandingPad
|
||||
| ConnectionType::LaunchPad
|
||||
| ConnectionType::PipeLiquid => Self::Other,
|
||||
ConnectionType::Data | ConnectionType::Power | ConnectionType::PowerAndData => {
|
||||
Self::CableNetwork(None)
|
||||
}
|
||||
ConnectionType::Data => Self::CableNetwork {
|
||||
net: None,
|
||||
typ: CableConnectionType::Data,
|
||||
},
|
||||
ConnectionType::Power => Self::CableNetwork {
|
||||
net: None,
|
||||
typ: CableConnectionType::Power,
|
||||
},
|
||||
ConnectionType::PowerAndData => Self::CableNetwork {
|
||||
net: None,
|
||||
typ: CableConnectionType::PowerAndData,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -352,6 +374,7 @@ pub struct Device {
|
||||
pub reagents: HashMap<ReagentMode, HashMap<i32, f64>>,
|
||||
pub ic: Option<u32>,
|
||||
pub connections: Vec<Connection>,
|
||||
pub on: bool,
|
||||
fields: HashMap<LogicType, LogicField>,
|
||||
}
|
||||
|
||||
@@ -467,7 +490,11 @@ impl Device {
|
||||
slots: Vec::new(),
|
||||
reagents: HashMap::new(),
|
||||
ic: None,
|
||||
connections: vec![Connection::CableNetwork(None)],
|
||||
on: true,
|
||||
connections: vec![Connection::CableNetwork {
|
||||
net: None,
|
||||
typ: CableConnectionType::default(),
|
||||
}],
|
||||
};
|
||||
device.fields.insert(
|
||||
LogicType::ReferenceId,
|
||||
@@ -482,24 +509,19 @@ impl Device {
|
||||
pub fn with_ic(id: u32, ic: u32) -> Self {
|
||||
let mut device = Device::new(id);
|
||||
device.ic = Some(ic);
|
||||
device.connections = vec![Connection::CableNetwork(None), Connection::Other];
|
||||
device.connections = vec![
|
||||
Connection::CableNetwork {
|
||||
net: None,
|
||||
typ: CableConnectionType::Data,
|
||||
},
|
||||
Connection::CableNetwork {
|
||||
net: None,
|
||||
typ: CableConnectionType::Power,
|
||||
},
|
||||
];
|
||||
device.prefab_name = Some("StructureCircuitHousing".to_owned());
|
||||
device.prefab_hash = Some(-128473777);
|
||||
device.fields.extend(vec![
|
||||
(
|
||||
LogicType::Power,
|
||||
LogicField {
|
||||
field_type: FieldType::Read,
|
||||
value: 1.0,
|
||||
},
|
||||
),
|
||||
(
|
||||
LogicType::Error,
|
||||
LogicField {
|
||||
field_type: FieldType::ReadWrite,
|
||||
value: 0.0,
|
||||
},
|
||||
),
|
||||
(
|
||||
LogicType::Setting,
|
||||
LogicField {
|
||||
@@ -507,13 +529,6 @@ impl Device {
|
||||
value: 0.0,
|
||||
},
|
||||
),
|
||||
(
|
||||
LogicType::On,
|
||||
LogicField {
|
||||
field_type: FieldType::ReadWrite,
|
||||
value: 0.0,
|
||||
},
|
||||
),
|
||||
(
|
||||
LogicType::RequiredPower,
|
||||
LogicField {
|
||||
@@ -528,20 +543,6 @@ impl Device {
|
||||
value: -128473777.0,
|
||||
},
|
||||
),
|
||||
(
|
||||
LogicType::LineNumber,
|
||||
LogicField {
|
||||
field_type: FieldType::ReadWrite,
|
||||
value: 0.0,
|
||||
},
|
||||
),
|
||||
(
|
||||
LogicType::ReferenceId,
|
||||
LogicField {
|
||||
field_type: FieldType::Read,
|
||||
value: id as f64,
|
||||
},
|
||||
),
|
||||
]);
|
||||
device.slots.push(Slot::with_occupant(
|
||||
SlotType::ProgramableChip,
|
||||
@@ -563,7 +564,35 @@ impl Device {
|
||||
value: ic.ip as f64,
|
||||
},
|
||||
);
|
||||
copy.insert(
|
||||
LogicType::Error,
|
||||
LogicField {
|
||||
field_type: FieldType::Read,
|
||||
value: match ic.state {
|
||||
ICState::Error(_) => 1.0,
|
||||
_ => 0.0,
|
||||
},
|
||||
},
|
||||
);
|
||||
}
|
||||
copy.insert(
|
||||
LogicType::On,
|
||||
LogicField {
|
||||
field_type: FieldType::ReadWrite,
|
||||
value: if self.on && self.has_power() {
|
||||
1.0
|
||||
} else {
|
||||
0.0
|
||||
},
|
||||
},
|
||||
);
|
||||
copy.insert(
|
||||
LogicType::Power,
|
||||
LogicField {
|
||||
field_type: FieldType::Read,
|
||||
value: if self.has_power() { 1.0 } else { 0.0 },
|
||||
},
|
||||
);
|
||||
copy
|
||||
}
|
||||
|
||||
@@ -573,14 +602,17 @@ impl Device {
|
||||
connection,
|
||||
self.connections.len(),
|
||||
))
|
||||
} else if let Connection::CableNetwork(network_id) = self.connections[connection] {
|
||||
} else if let Connection::CableNetwork {
|
||||
net: network_id, ..
|
||||
} = self.connections[connection]
|
||||
{
|
||||
if let Some(network_id) = network_id {
|
||||
Ok(network_id)
|
||||
} else {
|
||||
Err(ICError::NetworkNotConnected(connection))
|
||||
}
|
||||
} else {
|
||||
Err(ICError::NotDataConnection(connection))
|
||||
Err(ICError::NotACableConnection(connection))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -598,7 +630,7 @@ impl Device {
|
||||
// when reading it's own IC
|
||||
Ok(0.0)
|
||||
}
|
||||
} else if let Some(field) = self.fields.get(&typ) {
|
||||
} else if let Some(field) = self.get_fields(vm).get(&typ) {
|
||||
if field.field_type == FieldType::Read || field.field_type == FieldType::ReadWrite {
|
||||
Ok(field.value)
|
||||
} else {
|
||||
@@ -610,7 +642,10 @@ impl Device {
|
||||
}
|
||||
|
||||
pub fn set_field(&mut self, typ: LogicType, val: f64, vm: &VM) -> Result<(), ICError> {
|
||||
if typ == LogicType::LineNumber && self.ic.is_some() {
|
||||
if typ == LogicType::On {
|
||||
self.on = val != 0.0;
|
||||
Ok(())
|
||||
} else if typ == LogicType::LineNumber && self.ic.is_some() {
|
||||
// try borrow to set ip, we shoudl only fail if the ic is in us aka is is *our* ic
|
||||
// in game trying to set your own ic's LineNumber appears to be a Nop so this is fine.
|
||||
if let Ok(mut ic) = vm
|
||||
@@ -754,6 +789,20 @@ impl Device {
|
||||
self.name_hash = Some((const_crc32::crc32(name.as_bytes()) as i32).into());
|
||||
self.name = Some(name.to_owned());
|
||||
}
|
||||
|
||||
pub fn has_power(&self) -> bool {
|
||||
self.connections.iter().any(|conn| {
|
||||
if let Connection::CableNetwork { net, typ } = conn {
|
||||
net.is_some()
|
||||
&& matches!(
|
||||
typ,
|
||||
CableConnectionType::Power | CableConnectionType::PowerAndData
|
||||
)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for VM {
|
||||
@@ -809,8 +858,12 @@ impl VM {
|
||||
}
|
||||
let mut device = self.new_device();
|
||||
if let Some(first_network) = device.connections.iter_mut().find_map(|c| {
|
||||
if let Connection::CableNetwork(c) = c {
|
||||
Some(c)
|
||||
if let Connection::CableNetwork {
|
||||
net,
|
||||
typ: CableConnectionType::Data | CableConnectionType::PowerAndData,
|
||||
} = c
|
||||
{
|
||||
Some(net)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@@ -828,19 +881,22 @@ impl VM {
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find_map(|(index, conn)| match conn {
|
||||
Connection::CableNetwork(_) => Some(index),
|
||||
Connection::Other => None,
|
||||
Connection::CableNetwork {
|
||||
typ: CableConnectionType::Data | CableConnectionType::PowerAndData,
|
||||
..
|
||||
} => Some(index),
|
||||
_ => None,
|
||||
});
|
||||
self.devices.insert(id, Rc::new(RefCell::new(device)));
|
||||
if let Some(first_data_network) = first_data_network {
|
||||
let _ = self.add_device_to_network(
|
||||
let _ = self.set_device_connection(
|
||||
id,
|
||||
if let Some(network) = network {
|
||||
network
|
||||
} else {
|
||||
self.default_network
|
||||
},
|
||||
first_data_network,
|
||||
if let Some(network) = network {
|
||||
Some(network)
|
||||
} else {
|
||||
Some(self.default_network)
|
||||
},
|
||||
);
|
||||
}
|
||||
Ok(id)
|
||||
@@ -854,8 +910,12 @@ impl VM {
|
||||
}
|
||||
let (mut device, ic) = self.new_ic();
|
||||
if let Some(first_network) = device.connections.iter_mut().find_map(|c| {
|
||||
if let Connection::CableNetwork(c) = c {
|
||||
Some(c)
|
||||
if let Connection::CableNetwork {
|
||||
net,
|
||||
typ: CableConnectionType::Data | CableConnectionType::PowerAndData,
|
||||
} = c
|
||||
{
|
||||
Some(net)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@@ -873,20 +933,23 @@ impl VM {
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find_map(|(index, conn)| match conn {
|
||||
Connection::CableNetwork(_) => Some(index),
|
||||
Connection::Other => None,
|
||||
Connection::CableNetwork {
|
||||
typ: CableConnectionType::Data | CableConnectionType::PowerAndData,
|
||||
..
|
||||
} => Some(index),
|
||||
_ => None,
|
||||
});
|
||||
self.devices.insert(id, Rc::new(RefCell::new(device)));
|
||||
self.ics.insert(ic_id, Rc::new(RefCell::new(ic)));
|
||||
if let Some(first_data_network) = first_data_network {
|
||||
let _ = self.add_device_to_network(
|
||||
let _ = self.set_device_connection(
|
||||
id,
|
||||
if let Some(network) = network {
|
||||
network
|
||||
} else {
|
||||
self.default_network
|
||||
},
|
||||
first_data_network,
|
||||
if let Some(network) = network {
|
||||
Some(network)
|
||||
} else {
|
||||
Some(self.default_network)
|
||||
},
|
||||
);
|
||||
}
|
||||
Ok(id)
|
||||
@@ -1120,32 +1183,56 @@ impl VM {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_device_to_network(
|
||||
pub fn set_device_connection(
|
||||
&self,
|
||||
id: u32,
|
||||
network_id: u32,
|
||||
connection: usize,
|
||||
target_net: Option<u32>,
|
||||
) -> Result<bool, VMError> {
|
||||
if let Some(network) = self.networks.get(&network_id) {
|
||||
let Some(device) = self.devices.get(&id) else {
|
||||
return Err(VMError::UnknownId(id));
|
||||
};
|
||||
if connection >= device.borrow().connections.len() {
|
||||
let conn_len = device.borrow().connections.len();
|
||||
return Err(ICError::ConnectionIndexOutOfRange(connection, conn_len).into());
|
||||
}
|
||||
let Connection::CableNetwork(ref mut conn) =
|
||||
device.borrow_mut().connections[connection]
|
||||
else {
|
||||
return Err(ICError::NotDataConnection(connection).into());
|
||||
};
|
||||
*conn = Some(network_id);
|
||||
|
||||
network.borrow_mut().add(id);
|
||||
Ok(true)
|
||||
} else {
|
||||
Err(VMError::InvalidNetwork(network_id))
|
||||
let Some(device) = self.devices.get(&id) else {
|
||||
return Err(VMError::UnknownId(id));
|
||||
};
|
||||
if connection >= device.borrow().connections.len() {
|
||||
let conn_len = device.borrow().connections.len();
|
||||
return Err(ICError::ConnectionIndexOutOfRange(connection, conn_len).into());
|
||||
}
|
||||
|
||||
{
|
||||
// scope this borrow
|
||||
let connections = &device.borrow().connections;
|
||||
let Connection::CableNetwork { net, .. } = & connections[connection] else {
|
||||
return Err(ICError::NotACableConnection(connection).into());
|
||||
};
|
||||
// remove from current network
|
||||
if let Some(net) = net {
|
||||
if let Some(network) = self.networks.get(net) {
|
||||
// if there is no other connection to this network
|
||||
if connections.clone().iter().enumerate().all(|(index, conn)| {
|
||||
if let Connection::CableNetwork { net: other_net, .. } = conn {
|
||||
!(other_net.is_some_and(|id| id == *net) && index != connection)
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}) {
|
||||
network.borrow_mut().remove(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut device_ref = device.borrow_mut();
|
||||
let connections = &mut device_ref.connections;
|
||||
let Connection::CableNetwork { ref mut net, .. } = connections[connection] else {
|
||||
return Err(ICError::NotACableConnection(connection).into());
|
||||
};
|
||||
if let Some(target_net) = target_net {
|
||||
if let Some(network) = self.networks.get(&target_net) {
|
||||
network.borrow_mut().add(id);
|
||||
} else {
|
||||
return Err(VMError::InvalidNetwork(target_net));
|
||||
}
|
||||
}
|
||||
*net = target_net;
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
pub fn remove_device_from_network(&self, id: u32, network_id: u32) -> Result<bool, VMError> {
|
||||
@@ -1156,9 +1243,9 @@ impl VM {
|
||||
let mut device_ref = device.borrow_mut();
|
||||
|
||||
for conn in device_ref.connections.iter_mut() {
|
||||
if let Connection::CableNetwork(conn) = conn {
|
||||
if conn.is_some_and(|id| id == network_id) {
|
||||
*conn = None;
|
||||
if let Connection::CableNetwork { net, .. } = conn {
|
||||
if net.is_some_and(|id| id == network_id) {
|
||||
*net = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,10 +2,7 @@
|
||||
mod utils;
|
||||
mod types;
|
||||
|
||||
use ic10emu::{
|
||||
grammar::{LogicType, SlotLogicType},
|
||||
Connection,
|
||||
};
|
||||
use ic10emu::grammar::{LogicType, SlotLogicType};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use types::{Registers, Stack};
|
||||
|
||||
@@ -311,32 +308,11 @@ impl DeviceRef {
|
||||
|
||||
#[wasm_bindgen(js_name = "setConnection")]
|
||||
pub fn set_connection(&self, conn: usize, net: Option<u32>) -> Result<(), JsError> {
|
||||
let mut device_ref = self.device.borrow_mut();
|
||||
let conn_len = device_ref.connections.len();
|
||||
let conn_ref = device_ref
|
||||
.connections
|
||||
.get_mut(conn)
|
||||
.ok_or(BindingError::OutOfBounds(conn, conn_len))?;
|
||||
match conn_ref {
|
||||
&mut Connection::CableNetwork(ref mut net_ref) => *net_ref = net,
|
||||
_ => {
|
||||
*conn_ref = Connection::CableNetwork(net);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = "addDeviceToNetwork")]
|
||||
pub fn add_device_to_network(
|
||||
&self,
|
||||
network_id: u32,
|
||||
connection: usize,
|
||||
) -> Result<bool, JsError> {
|
||||
let id = self.device.borrow().id;
|
||||
Ok(self
|
||||
.vm
|
||||
let device_id = self.device.borrow().id;
|
||||
self.vm
|
||||
.borrow()
|
||||
.add_device_to_network(id, network_id, connection)?)
|
||||
.set_device_connection(device_id, conn, net)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = "removeDeviceFromNetwork")]
|
||||
@@ -438,17 +414,17 @@ impl VM {
|
||||
self.vm.borrow().visible_devices(source)
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = "addDeviceToNetwork")]
|
||||
pub fn add_device_to_network(
|
||||
#[wasm_bindgen(js_name = "setDeviceConnection")]
|
||||
pub fn set_device_connection(
|
||||
&self,
|
||||
id: u32,
|
||||
network_id: u32,
|
||||
connection: usize,
|
||||
network_id: Option<u32>,
|
||||
) -> Result<bool, JsError> {
|
||||
Ok(self
|
||||
.vm
|
||||
.borrow()
|
||||
.add_device_to_network(id, network_id, connection)?)
|
||||
.set_device_connection(id, connection, network_id)?)
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = "removeDeviceFromNetwork")]
|
||||
|
||||
@@ -56,7 +56,9 @@ export interface Slot {
|
||||
|
||||
export type Reagents = Map<string, Map<number, number>>;
|
||||
|
||||
export type Connection = { CableNetwork: number } | "Other";
|
||||
export type Connection =
|
||||
| { readonly CableNetwork: { readonly net: number; readonly typ: string } }
|
||||
| "Other";
|
||||
|
||||
export type RegisterSpec = {
|
||||
readonly RegisterSpec: {
|
||||
@@ -67,14 +69,14 @@ export type RegisterSpec = {
|
||||
export type DeviceSpec = {
|
||||
readonly DeviceSpec: {
|
||||
readonly device:
|
||||
| "Db"
|
||||
| { readonly Numbered: number }
|
||||
| {
|
||||
readonly Indirect: {
|
||||
readonly indirection: number;
|
||||
readonly target: number;
|
||||
};
|
||||
};
|
||||
| "Db"
|
||||
| { readonly Numbered: number }
|
||||
| {
|
||||
readonly Indirect: {
|
||||
readonly indirection: number;
|
||||
readonly target: number;
|
||||
};
|
||||
};
|
||||
};
|
||||
readonly connection: number | undefined;
|
||||
};
|
||||
@@ -93,12 +95,12 @@ export type NumberEnum = { readonly Enum: number };
|
||||
|
||||
export type NumberOperand = {
|
||||
Number:
|
||||
| NumberFloat
|
||||
| NumberBinary
|
||||
| NumberHexadecimal
|
||||
| NumberConstant
|
||||
| NumberString
|
||||
| NumberEnum;
|
||||
| NumberFloat
|
||||
| NumberBinary
|
||||
| NumberHexadecimal
|
||||
| NumberConstant
|
||||
| NumberString
|
||||
| NumberEnum;
|
||||
};
|
||||
export type Operand =
|
||||
| RegisterSpec
|
||||
|
||||
@@ -117,8 +117,11 @@ export class Session extends EventTarget {
|
||||
}
|
||||
|
||||
setActiveLine(id: number, line: number) {
|
||||
this._activeLines.set(id, line);
|
||||
this._fireOnActiveLine(id);
|
||||
const last = this._activeLines.get(id);
|
||||
if (last !== line) {
|
||||
this._activeLines.set(id, line);
|
||||
this._fireOnActiveLine(id);
|
||||
}
|
||||
}
|
||||
|
||||
set activeLine(line: number) {
|
||||
|
||||
@@ -24,7 +24,6 @@ import "@shoelace-style/shoelace/dist/components/icon/icon.js";
|
||||
import SlInput from "@shoelace-style/shoelace/dist/components/input/input.js";
|
||||
import { parseNumber, structuralEqual } from "../utils";
|
||||
import SlSelect from "@shoelace-style/shoelace/dist/components/select/select.js";
|
||||
import SlDetails from "@shoelace-style/shoelace/dist/components/details/details.js";
|
||||
import SlDrawer from "@shoelace-style/shoelace/dist/components/drawer/drawer.js";
|
||||
import { DeviceDB, DeviceDBEntry } from "./device_db";
|
||||
|
||||
@@ -250,15 +249,16 @@ export class VMDeviceCard extends VMDeviceMixin(BaseElement) {
|
||||
placement="top"
|
||||
clearable
|
||||
key=${index}
|
||||
value=${conn}
|
||||
value=${conn?.net}
|
||||
?disabled=${conn === null}
|
||||
@sl-change=${this._handleChangeConnection}
|
||||
>
|
||||
<span slot="prefix">Connection:${index}</span>
|
||||
<span slot="prefix">Connection:${index} </span>
|
||||
${vmNetworks.map(
|
||||
(net) =>
|
||||
html`<sl-option value=${net}>Network ${net}</sl-option>`,
|
||||
)}
|
||||
<span slot="prefix"> ${conn?.typ} </span>
|
||||
</sl-select>
|
||||
`;
|
||||
})}
|
||||
@@ -340,23 +340,8 @@ export class VMDeviceCard extends VMDeviceMixin(BaseElement) {
|
||||
_handleChangeConnection(e: CustomEvent) {
|
||||
const select = e.target as SlSelect;
|
||||
const conn = parseInt(select.getAttribute("key")!);
|
||||
const last = this.device.connections[conn];
|
||||
const val = select.value ? parseInt(select.value as string) : undefined;
|
||||
if (typeof last === "object" && typeof last.CableNetwork === "number") {
|
||||
// is there no other connection to the previous network?
|
||||
if (
|
||||
!this.device.connections.some((other_conn, index) => {
|
||||
structuralEqual(last, other_conn) && index !== conn;
|
||||
})
|
||||
) {
|
||||
this.device.removeDeviceFromNetwork(last.CableNetwork);
|
||||
}
|
||||
}
|
||||
if (typeof val !== "undefined") {
|
||||
this.device.addDeviceToNetwork(conn, val);
|
||||
} else {
|
||||
this.device.setConnection(conn, val);
|
||||
}
|
||||
this.device.setConnection(conn, val);
|
||||
|
||||
this.updateDevice();
|
||||
}
|
||||
@@ -378,7 +363,7 @@ export class VMDeviceList extends BaseElement {
|
||||
...defaultCss,
|
||||
css`
|
||||
.header {
|
||||
margin-botton: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
margin-right: 2rem;
|
||||
padding: 0.25rem 0.25rem;
|
||||
align-items: center;
|
||||
@@ -686,11 +671,11 @@ export class VmDeviceTemplate extends BaseElement {
|
||||
}
|
||||
|
||||
renderSlot(slot: Slot, slotIndex: number): HTMLTemplateResult {
|
||||
return html` <sl-card class="slot-card"> </sl-card> `;
|
||||
return html`<sl-card class="slot-card"> </sl-card>`;
|
||||
}
|
||||
|
||||
renderSlots(): HTMLTemplateResult {
|
||||
return html` <div clas="slots"></div> `;
|
||||
return html`<div clas="slots"></div>`;
|
||||
}
|
||||
|
||||
renderReagents(): HTMLTemplateResult {
|
||||
@@ -699,12 +684,12 @@ export class VmDeviceTemplate extends BaseElement {
|
||||
|
||||
renderNetworks(): HTMLTemplateResult {
|
||||
const vmNetworks = window.VM!.networks;
|
||||
return html` <div class="networks"></div> `;
|
||||
return html`<div class="networks"></div>`;
|
||||
}
|
||||
|
||||
renderPins(): HTMLTemplateResult {
|
||||
const device = this.deviceDB.db[this.name];
|
||||
return html` <div class="pins"></div> `;
|
||||
return html`<div class="pins"></div>`;
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -724,8 +709,8 @@ export class VmDeviceTemplate extends BaseElement {
|
||||
<span class="prefab-hash">${device.hash}</span>
|
||||
</div>
|
||||
<sl-button class="ms-auto" pill variant="success"
|
||||
>Add <sl-icon slot="prefix" name="plus-lg"></sl-icon
|
||||
></sl-button>
|
||||
>Add <sl-icon slot="prefix" name="plus-lg"></sl-icon>
|
||||
</sl-button>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<sl-tab-group>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { DeviceRef, VM, init } from "ic10emu_wasm";
|
||||
import { DeviceDB } from "./device_db"
|
||||
import { DeviceDB } from "./device_db";
|
||||
import "./base_device";
|
||||
|
||||
declare global {
|
||||
@@ -8,14 +8,13 @@ declare global {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class VirtualMachine extends EventTarget {
|
||||
ic10vm: VM;
|
||||
_devices: Map<number, DeviceRef>;
|
||||
_ics: Map<number, DeviceRef>;
|
||||
|
||||
accessor db: DeviceDB;
|
||||
dbPromise: Promise<{ default: DeviceDB }>
|
||||
dbPromise: Promise<{ default: DeviceDB }>;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@@ -29,7 +28,7 @@ class VirtualMachine extends EventTarget {
|
||||
this._ics = new Map();
|
||||
|
||||
this.dbPromise = import("../../../data/database.json");
|
||||
this.dbPromise.then((module) => this.setupDeviceDatabase(module.default))
|
||||
this.dbPromise.then((module) => this.setupDeviceDatabase(module.default));
|
||||
|
||||
this.updateDevices();
|
||||
this.updateCode();
|
||||
@@ -179,17 +178,23 @@ class VirtualMachine extends EventTarget {
|
||||
);
|
||||
}
|
||||
}, this);
|
||||
const ic = this.activeIC!;
|
||||
window.App!.session.setActiveLine(window.App!.session.activeIC, ic.ip!);
|
||||
this.updateDevice(this.activeIC)
|
||||
}
|
||||
|
||||
updateDevice(device: DeviceRef) {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("vm-device-modified", { detail: device.id }),
|
||||
);
|
||||
if (typeof device.ic !== "undefined") {
|
||||
window.App!.session.setActiveLine(device.id, device.ip!);
|
||||
}
|
||||
}
|
||||
|
||||
setRegister(index: number, val: number) {
|
||||
const ic = this.activeIC!;
|
||||
try {
|
||||
ic.setRegister(index, val);
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("vm-device-modified", { detail: ic.id }),
|
||||
);
|
||||
this.updateDevice(ic);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
@@ -199,9 +204,7 @@ class VirtualMachine extends EventTarget {
|
||||
const ic = this.activeIC!;
|
||||
try {
|
||||
ic!.setStack(addr, val);
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("vm-device-modified", { detail: ic.id }),
|
||||
);
|
||||
this.updateDevice(ic);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
@@ -222,9 +225,7 @@ class VirtualMachine extends EventTarget {
|
||||
if (device) {
|
||||
try {
|
||||
device.setField(field, val);
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("vm-device-modified", { detail: id }),
|
||||
);
|
||||
this.updateDevice(device);
|
||||
return true;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
@@ -238,9 +239,7 @@ class VirtualMachine extends EventTarget {
|
||||
if (device) {
|
||||
try {
|
||||
device.setSlotField(slot, field, val);
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("vm-device-modified", { detail: id }),
|
||||
);
|
||||
this.updateDevice(device);
|
||||
return true;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
|
||||
Reference in New Issue
Block a user