make sure device pins can be set and fix device update events for device removal
This commit is contained in:
@@ -59,7 +59,8 @@ export type VMDeviceMixinSubscription =
|
||||
| "ic"
|
||||
| "active-ic"
|
||||
| { field: LogicType }
|
||||
| { slot: number };
|
||||
| { slot: number }
|
||||
| "visible-devices";
|
||||
|
||||
export const VMDeviceMixin = <T extends Constructor<LitElement>>(
|
||||
superClass: T,
|
||||
@@ -124,6 +125,10 @@ export const VMDeviceMixin = <T extends Constructor<LitElement>>(
|
||||
"vm-device-id-change",
|
||||
this._handleDeviceIdChange.bind(this),
|
||||
);
|
||||
vm.addEventListener(
|
||||
"vm-devices-removed",
|
||||
this._handleDevicesRemoved.bind(this),
|
||||
)
|
||||
});
|
||||
this.updateDevice();
|
||||
return root;
|
||||
@@ -143,6 +148,10 @@ export const VMDeviceMixin = <T extends Constructor<LitElement>>(
|
||||
"vm-device-id-change",
|
||||
this._handleDeviceIdChange.bind(this),
|
||||
);
|
||||
vm.removeEventListener(
|
||||
"vm-devices-removed",
|
||||
this._handleDevicesRemoved.bind(this),
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -156,6 +165,13 @@ export const VMDeviceMixin = <T extends Constructor<LitElement>>(
|
||||
this.deviceSubscriptions.includes("active-ic")
|
||||
) {
|
||||
this.updateDevice();
|
||||
this.requestUpdate();
|
||||
} else if (this.deviceSubscriptions.includes("visible-devices")) {
|
||||
const visibleDevices = window.VM.vm.visibleDeviceIds(this.deviceID);
|
||||
if (visibleDevices.includes(id)) {
|
||||
this.updateDevice();
|
||||
this.requestUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,17 +180,39 @@ export const VMDeviceMixin = <T extends Constructor<LitElement>>(
|
||||
const ids = e.detail;
|
||||
if (ids.includes(this.deviceID)) {
|
||||
this.updateDevice();
|
||||
if (this.deviceSubscriptions.includes("visible-devices")) {
|
||||
this.requestUpdate();
|
||||
}
|
||||
} else if (
|
||||
ids.includes(activeIcId) &&
|
||||
this.deviceSubscriptions.includes("active-ic")
|
||||
) {
|
||||
this.updateDevice();
|
||||
this.requestUpdate();
|
||||
} else if (this.deviceSubscriptions.includes("visible-devices")) {
|
||||
const visibleDevices = window.VM.vm.visibleDeviceIds(this.deviceID);
|
||||
if (ids.some( id => visibleDevices.includes(id))) {
|
||||
this.updateDevice();
|
||||
this.requestUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_handleDeviceIdChange(e: CustomEvent<{ old: number; new: number }>) {
|
||||
if (this.deviceID === e.detail.old) {
|
||||
this.deviceID = e.detail.new;
|
||||
} else if (this.deviceSubscriptions.includes("visible-devices")) {
|
||||
const visibleDevices = window.VM.vm.visibleDeviceIds(this.deviceID);
|
||||
if (visibleDevices.some(id => id === e.detail.old || id === e.detail.new)) {
|
||||
this.requestUpdate()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_handleDevicesRemoved(e: CustomEvent<number[]>) {
|
||||
const _ids = e.detail;
|
||||
if (this.deviceSubscriptions.includes("visible-devices")) {
|
||||
this.requestUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import SlInput from "@shoelace-style/shoelace/dist/components/input/input.compon
|
||||
import SlDialog from "@shoelace-style/shoelace/dist/components/dialog/dialog.component.js";
|
||||
import "./slot";
|
||||
import "./fields";
|
||||
import "./pins";
|
||||
import { until } from "lit/directives/until.js";
|
||||
import { repeat } from "lit/directives/repeat.js";
|
||||
|
||||
@@ -238,24 +239,12 @@ export class VMDeviceCard extends VMDeviceDBMixin(VMDeviceMixin(BaseElement)) {
|
||||
}
|
||||
|
||||
renderPins() {
|
||||
const pins = this.pins;
|
||||
const visibleDevices = window.VM.vm.visibleDevices(this.deviceID);
|
||||
const pinsHtml = pins?.map(
|
||||
(pin, index) =>
|
||||
html`
|
||||
<sl-select hoist placement="top" clearable key=${index} value=${pin} @sl-change=${this._handleChangePin}>
|
||||
<span slot="prefix">d${index}</span>
|
||||
${visibleDevices.map(
|
||||
(device, _index) =>
|
||||
html`
|
||||
<sl-option value=${device.id}>
|
||||
Device ${device.id} : ${device.name ?? device.prefabName}
|
||||
</sl-option>
|
||||
`,
|
||||
)}
|
||||
</sl-select>`,
|
||||
return this.delayRenderTab(
|
||||
"pins",
|
||||
html`<div class="pins">
|
||||
<vm-device-pins .deviceID=${this.deviceID}></vm-device-pins>
|
||||
</div>`
|
||||
);
|
||||
return this.delayRenderTab("pins", html`<div class="pins">${pinsHtml}</div>`);
|
||||
}
|
||||
|
||||
private tabsShown: CardTab[] = ["fields"];
|
||||
@@ -306,7 +295,7 @@ export class VMDeviceCard extends VMDeviceDBMixin(VMDeviceMixin(BaseElement)) {
|
||||
<sl-tab slot="nav" panel="slots">Slots</sl-tab>
|
||||
<sl-tab slot="nav" panel="reagents" disabled>Reagents</sl-tab>
|
||||
<sl-tab slot="nav" panel="networks">Networks</sl-tab>
|
||||
<sl-tab slot="nav" panel="pins" ?disabled=${!this.pins}>Pins</sl-tab>
|
||||
<sl-tab slot="nav" panel="pins" ?disabled=${!this.device.pins}>Pins</sl-tab>
|
||||
|
||||
<sl-tab-panel name="fields" active>
|
||||
${until(this.renderFields(), html`<sl-spinner></sl-spinner>`)}
|
||||
@@ -320,7 +309,7 @@ export class VMDeviceCard extends VMDeviceDBMixin(VMDeviceMixin(BaseElement)) {
|
||||
<sl-tab-panel name="networks">
|
||||
${until(this.renderNetworks(), html`<sl-spinner></sl-spinner>`)}
|
||||
</sl-tab-panel>
|
||||
<sl-tab-panel name="pins"> ${this.renderPins()} </sl-tab-panel>
|
||||
<sl-tab-panel name="pins">${until(this.renderPins(), html`<sl-spinner></sl-spinner>`)} </sl-tab-panel>
|
||||
</sl-tab-group>
|
||||
</ic10-details>
|
||||
<sl-dialog class="remove-device-dialog" no-header @sl-request-close=${this._preventOverlayClose}>
|
||||
@@ -399,11 +388,4 @@ export class VMDeviceCard extends VMDeviceDBMixin(VMDeviceMixin(BaseElement)) {
|
||||
this.updateDevice();
|
||||
}
|
||||
|
||||
_handleChangePin(e: CustomEvent) {
|
||||
const select = e.target as SlSelect;
|
||||
const pin = parseInt(select.getAttribute("key")!);
|
||||
const val = select.value ? parseInt(select.value as string) : undefined;
|
||||
window.VM.get().then((vm) => vm.setDevicePin(this.deviceID, pin, val));
|
||||
this.updateDevice();
|
||||
}
|
||||
}
|
||||
|
||||
44
www/src/ts/virtual_machine/device/pins.ts
Normal file
44
www/src/ts/virtual_machine/device/pins.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
|
||||
import { html, css } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
import { BaseElement, defaultCss } from "components";
|
||||
import { VMDeviceDBMixin, VMDeviceMixin } from "virtual_machine/base_device";
|
||||
import SlSelect from "@shoelace-style/shoelace/dist/components/select/select.component.js";
|
||||
|
||||
@customElement("vm-device-pins")
|
||||
export class VMDevicePins extends VMDeviceMixin(VMDeviceDBMixin(BaseElement)) {
|
||||
constructor() {
|
||||
super();
|
||||
this.subscribe("ic", "visible-devices");
|
||||
}
|
||||
|
||||
render() {
|
||||
const pins = this.pins;
|
||||
const visibleDevices = window.VM.vm.visibleDevices(this.deviceID);
|
||||
const pinsHtml = pins?.map(
|
||||
(pin, index) =>
|
||||
html`
|
||||
<sl-select hoist placement="top" clearable key=${index} value=${pin} @sl-change=${this._handleChangePin}>
|
||||
<span slot="prefix">d${index}</span>
|
||||
${visibleDevices.map(
|
||||
(device, _index) =>
|
||||
html`
|
||||
<sl-option value=${device.id}>
|
||||
Device ${device.id} : ${device.name ?? device.prefabName}
|
||||
</sl-option>
|
||||
`,
|
||||
)}
|
||||
</sl-select>`,
|
||||
);
|
||||
return pinsHtml;
|
||||
}
|
||||
|
||||
_handleChangePin(e: CustomEvent) {
|
||||
const select = e.target as SlSelect;
|
||||
const pin = parseInt(select.getAttribute("key")!);
|
||||
const val = select.value ? parseInt(select.value as string) : undefined;
|
||||
window.VM.get().then((vm) => vm.setDevicePin(this.deviceID, pin, val));
|
||||
this.updateDevice();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -119,8 +119,14 @@ class VirtualMachine extends EventTarget {
|
||||
return ids.map((id, _index) => this._devices.get(id)!);
|
||||
}
|
||||
|
||||
visibleDeviceIds(source: number) {
|
||||
const ids = Array.from(this.ic10vm.visibleDevices(source));
|
||||
return ids;
|
||||
}
|
||||
|
||||
updateDevices() {
|
||||
var update_flag = false;
|
||||
const removedDevices = [];
|
||||
const device_ids = this.ic10vm.devices;
|
||||
for (const id of device_ids) {
|
||||
if (!this._devices.has(id)) {
|
||||
@@ -132,6 +138,7 @@ class VirtualMachine extends EventTarget {
|
||||
if (!device_ids.includes(id)) {
|
||||
this._devices.delete(id);
|
||||
update_flag = true;
|
||||
removedDevices.push(id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,6 +167,13 @@ class VirtualMachine extends EventTarget {
|
||||
detail: ids,
|
||||
}),
|
||||
);
|
||||
if (removedDevices.length > 0) {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("vm-devices-removed", {
|
||||
detail: removedDevices,
|
||||
}),
|
||||
);
|
||||
}
|
||||
this.app.session.save();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user