Allow the Id of a device to be changed, toast errors
This commit is contained in:
@@ -52,6 +52,7 @@ export class VMICControls extends VMActiveICMixin(BaseElement) {
|
||||
sl-button[variant="success"] {
|
||||
/* Changes the success theme color to purple using primitives */
|
||||
--sl-color-success-600: var(--sl-color-purple-700);
|
||||
--sl-color-success-500: var(--sl-color-purple-600);
|
||||
}
|
||||
sl-button[variant="primary"] {
|
||||
/* Changes the success theme color to purple using primitives */
|
||||
|
||||
@@ -62,7 +62,7 @@ export class VMDeviceCard extends VMDeviceMixin(BaseElement) {
|
||||
width: 10rem;
|
||||
}
|
||||
.device-id::part(input) {
|
||||
width: 2rem;
|
||||
width: 7rem;
|
||||
}
|
||||
.device-name-hash::part(input) {
|
||||
width: 7rem;
|
||||
@@ -129,7 +129,7 @@ export class VMDeviceCard extends VMDeviceMixin(BaseElement) {
|
||||
size="small"
|
||||
pill
|
||||
value=${this.deviceID}
|
||||
disabled
|
||||
@sl-change=${this._handleChangeID}
|
||||
>
|
||||
<span slot="prefix">Id</span>
|
||||
<sl-copy-button slot="suffix" value=${this.deviceID}></sl-copy-button>
|
||||
@@ -314,6 +314,16 @@ export class VMDeviceCard extends VMDeviceMixin(BaseElement) {
|
||||
`;
|
||||
}
|
||||
|
||||
_handleChangeID(e: CustomEvent) {
|
||||
const input = e.target as SlInput;
|
||||
const val = input.valueAsNumber;
|
||||
if (!isNaN(val)) {
|
||||
window.VM.changeDeviceId(this.deviceID, val);
|
||||
} else {
|
||||
input.value = this.deviceID.toString();
|
||||
}
|
||||
}
|
||||
|
||||
_handleChangeName(e: CustomEvent) {
|
||||
const input = e.target as SlInput;
|
||||
window.VM?.setDeviceName(this.deviceID, input.value);
|
||||
@@ -404,7 +414,14 @@ export class VMDeviceList extends BaseElement {
|
||||
}
|
||||
|
||||
protected render(): HTMLTemplateResult {
|
||||
return html`
|
||||
const deviceCards: HTMLTemplateResult[] = this.devices.map(
|
||||
(id, _index, _ids) =>
|
||||
html`<vm-device-card
|
||||
.deviceID=${id}
|
||||
class="device-list-card"
|
||||
></vm-device-card>`,
|
||||
);
|
||||
const result = html`
|
||||
<div class="header">
|
||||
<span>
|
||||
Devices:
|
||||
@@ -413,15 +430,11 @@ export class VMDeviceList extends BaseElement {
|
||||
<vm-add-device-button class="ms-auto"></vm-add-device-button>
|
||||
</div>
|
||||
<div class="device-list">
|
||||
${this.devices.map(
|
||||
(id, _index, _ids) =>
|
||||
html`<vm-device-card
|
||||
.deviceID=${id}
|
||||
class="device-list-card"
|
||||
></vm-device-card>`,
|
||||
)}
|
||||
${deviceCards}
|
||||
</div>
|
||||
`;
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -386,7 +386,7 @@ export type DeviceDBEntry = {
|
||||
slotlogic?: { [key in SlotLogicType]: number[] };
|
||||
slots?: { name: string; typ: SlotClass }[];
|
||||
modes?: { [key: string]: string };
|
||||
conn?: { [key in SlotLogicType]: [NetworkType, ConnectionRole] };
|
||||
conn?: { [key: number]: [NetworkType, ConnectionRole] };
|
||||
slotclass?: SlotClass;
|
||||
sorting?: SortingClass;
|
||||
pins?: number;
|
||||
@@ -403,3 +403,30 @@ export type DeviceDB = {
|
||||
};
|
||||
names_by_hash: { [key: number]: string };
|
||||
};
|
||||
|
||||
|
||||
export type PreCastDeviceDBEntry = {
|
||||
name: string;
|
||||
hash: number;
|
||||
desc: string;
|
||||
logic?: { [key in LogicType]?: string };
|
||||
slotlogic?: { [key in SlotLogicType]?: number[] };
|
||||
slots?: { name: string; typ: string }[];
|
||||
modes?: { [key: string]: string };
|
||||
conn?: { [key: number]: string[] };
|
||||
slotclass?: string;
|
||||
sorting?: string;
|
||||
pins?: number;
|
||||
};
|
||||
|
||||
export type PreCastDeviceDB = {
|
||||
logic_enabled: string[];
|
||||
slot_logic_enabled: string[];
|
||||
devices: string[];
|
||||
items: string[];
|
||||
structures: string[];
|
||||
db: {
|
||||
[key: string]: PreCastDeviceDBEntry;
|
||||
};
|
||||
names_by_hash: { [key: number]: string };
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { DeviceRef, VM, init } from "ic10emu_wasm";
|
||||
import { DeviceDB } from "./device_db";
|
||||
import { DeviceDB, PreCastDeviceDB } from "./device_db";
|
||||
import "./base_device";
|
||||
|
||||
declare global {
|
||||
@@ -8,13 +8,21 @@ declare global {
|
||||
}
|
||||
}
|
||||
|
||||
export interface ToastMessage {
|
||||
variant: "warning" | "danger" | "success" | "primary" | "neutral";
|
||||
icon: string;
|
||||
title: string;
|
||||
msg: string;
|
||||
id: string;
|
||||
}
|
||||
|
||||
class VirtualMachine extends EventTarget {
|
||||
ic10vm: VM;
|
||||
_devices: Map<number, DeviceRef>;
|
||||
_ics: Map<number, DeviceRef>;
|
||||
|
||||
accessor db: DeviceDB;
|
||||
dbPromise: Promise<{ default: DeviceDB }>;
|
||||
dbPromise: Promise<{ default: PreCastDeviceDB }>;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@@ -28,7 +36,9 @@ 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 as DeviceDB),
|
||||
);
|
||||
|
||||
this.updateDevices();
|
||||
this.updateCode();
|
||||
@@ -78,7 +88,6 @@ class VirtualMachine extends EventTarget {
|
||||
}
|
||||
for (const id of this._devices.keys()) {
|
||||
if (!device_ids.includes(id)) {
|
||||
this._devices.get(id)!.free();
|
||||
this._devices.delete(id);
|
||||
update_flag = true;
|
||||
}
|
||||
@@ -102,7 +111,9 @@ class VirtualMachine extends EventTarget {
|
||||
|
||||
if (update_flag) {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("vm-devices-update", { detail: device_ids }),
|
||||
new CustomEvent("vm-devices-update", {
|
||||
detail: Array.from(device_ids),
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -122,8 +133,8 @@ class VirtualMachine extends EventTarget {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("vm-device-modified", { detail: id }),
|
||||
);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} catch (err) {
|
||||
this.handleVmError(err);
|
||||
}
|
||||
console.timeEnd(`CompileProgram_${id}_${attempt}`);
|
||||
}
|
||||
@@ -136,8 +147,8 @@ class VirtualMachine extends EventTarget {
|
||||
if (ic) {
|
||||
try {
|
||||
ic.step(false);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} catch (err) {
|
||||
this.handleVmError(err);
|
||||
}
|
||||
this.update();
|
||||
this.dispatchEvent(
|
||||
@@ -151,8 +162,8 @@ class VirtualMachine extends EventTarget {
|
||||
if (ic) {
|
||||
try {
|
||||
ic.run(false);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} catch (err) {
|
||||
this.handleVmError(err);
|
||||
}
|
||||
this.update();
|
||||
this.dispatchEvent(
|
||||
@@ -178,7 +189,7 @@ class VirtualMachine extends EventTarget {
|
||||
);
|
||||
}
|
||||
}, this);
|
||||
this.updateDevice(this.activeIC)
|
||||
this.updateDevice(this.activeIC);
|
||||
}
|
||||
|
||||
updateDevice(device: DeviceRef) {
|
||||
@@ -190,13 +201,37 @@ class VirtualMachine extends EventTarget {
|
||||
}
|
||||
}
|
||||
|
||||
handleVmError(err: Error) {
|
||||
console.log("Error in Virtual Machine", err);
|
||||
const message: ToastMessage = {
|
||||
variant: "danger",
|
||||
icon: "bug",
|
||||
title: `Error in Virtual Machine ${err.name}`,
|
||||
msg: err.message,
|
||||
id: Date.now().toString(16),
|
||||
};
|
||||
this.dispatchEvent(new CustomEvent("vm-message", { detail: message }));
|
||||
}
|
||||
|
||||
changeDeviceId(old_id: number, new_id: number) {
|
||||
try {
|
||||
this.ic10vm.changeDeviceId(old_id, new_id);
|
||||
this.updateDevices();
|
||||
if (window.App.session.activeIC === old_id) {
|
||||
window.App.session.activeIC = new_id;
|
||||
}
|
||||
} catch (err) {
|
||||
this.handleVmError(err);
|
||||
}
|
||||
}
|
||||
|
||||
setRegister(index: number, val: number) {
|
||||
const ic = this.activeIC!;
|
||||
try {
|
||||
ic.setRegister(index, val);
|
||||
this.updateDevice(ic);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} catch (err) {
|
||||
this.handleVmError(err);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,8 +240,8 @@ class VirtualMachine extends EventTarget {
|
||||
try {
|
||||
ic!.setStack(addr, val);
|
||||
this.updateDevice(ic);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} catch (err) {
|
||||
this.handleVmError(err);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,8 +262,8 @@ class VirtualMachine extends EventTarget {
|
||||
device.setField(field, val);
|
||||
this.updateDevice(device);
|
||||
return true;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} catch (err) {
|
||||
this.handleVmError(err);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -241,8 +276,8 @@ class VirtualMachine extends EventTarget {
|
||||
device.setSlotField(slot, field, val);
|
||||
this.updateDevice(device);
|
||||
return true;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} catch (err) {
|
||||
this.handleVmError(err);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
import { HTMLTemplateResult, html, css } from "lit";
|
||||
import { customElement, property, query } from "lit/decorators.js";
|
||||
import { customElement, property, query, state } from "lit/decorators.js";
|
||||
import { BaseElement, defaultCss } from "../components";
|
||||
import "@shoelace-style/shoelace/dist/components/details/details.js";
|
||||
import "@shoelace-style/shoelace/dist/components/tab/tab.js";
|
||||
import "@shoelace-style/shoelace/dist/components/tab-panel/tab-panel.js";
|
||||
import "@shoelace-style/shoelace/dist/components/tab-group/tab-group.js";
|
||||
import "@shoelace-style/shoelace/dist/components/alert/alert.js";
|
||||
|
||||
import "./controls";
|
||||
import "./registers";
|
||||
import "./stack";
|
||||
import "./device";
|
||||
import { ToastMessage } from ".";
|
||||
|
||||
@customElement("vm-ui")
|
||||
export class VMUI extends BaseElement {
|
||||
@@ -34,16 +36,39 @@ export class VMUI extends BaseElement {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
.side-container {
|
||||
height: 100%
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
connectedCallback(): void {
|
||||
super.connectedCallback();
|
||||
window.VM.addEventListener("vm-message", this._handleVMMessage.bind(this) )
|
||||
}
|
||||
|
||||
_handleVMMessage(e: CustomEvent) {
|
||||
const msg: ToastMessage = e.detail;
|
||||
const alert = Object.assign(document.createElement('sl-alert'), {
|
||||
variant: msg.variant,
|
||||
closable: true,
|
||||
// duration: 5000,
|
||||
innerHTML: `
|
||||
<sl-icon slot="icon" name="${msg.icon}"></sl-icon>
|
||||
<strong>${msg.title}</strong><br />
|
||||
${msg.msg}
|
||||
`
|
||||
});
|
||||
|
||||
document.body.append(alert);
|
||||
alert.toast();
|
||||
}
|
||||
|
||||
protected render() {
|
||||
return html`
|
||||
<div class="side-container">
|
||||
|
||||
Reference in New Issue
Block a user