diff --git a/ic10emu_wasm/src/types.ts b/ic10emu_wasm/src/types.ts index 8c97f7f..b630cc9 100644 --- a/ic10emu_wasm/src/types.ts +++ b/ic10emu_wasm/src/types.ts @@ -57,9 +57,14 @@ export interface Slot { export type Reagents = Map>; -export type Connection = - | { readonly CableNetwork: { readonly net: number; readonly typ: string } } - | "Other"; +export interface ConnectionCableNetwork { + CableNetwork: { + net: number | undefined; + typ: string; + }; +} + +export type Connection = ConnectionCableNetwork | "Other"; export type RegisterSpec = { readonly RegisterSpec: { @@ -70,14 +75,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; }; @@ -96,12 +101,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 @@ -174,5 +179,5 @@ export interface DeviceTemplate { } export interface VM { - addDeviceFromTemplate(template: DeviceTemplate): number + addDeviceFromTemplate(template: DeviceTemplate): number; } diff --git a/www/src/ts/virtual_machine/device.ts b/www/src/ts/virtual_machine/device.ts index 954d2ea..47c7c60 100644 --- a/www/src/ts/virtual_machine/device.ts +++ b/www/src/ts/virtual_machine/device.ts @@ -1,4 +1,16 @@ -import { Slot } from "ic10emu_wasm"; +import { + Connection, + DeviceTemplate, + LogicField, + LogicFields, + LogicType, + Slot, + SlotTemplate, + SlotOccupant, + SlotOccupantTemplate, + SlotLogicType, + ConnectionCableNetwork, +} from "ic10emu_wasm"; import { html, css, HTMLTemplateResult } from "lit"; import { customElement, property, query, state } from "lit/decorators.js"; import { BaseElement, defaultCss } from "../components"; @@ -26,6 +38,7 @@ import { parseNumber, structuralEqual } from "../utils"; import SlSelect from "@shoelace-style/shoelace/dist/components/select/select.js"; import SlDrawer from "@shoelace-style/shoelace/dist/components/drawer/drawer.js"; import { DeviceDB, DeviceDBEntry } from "./device_db"; +import { connectionFromDeviceDBConnection } from "./utils"; @customElement("vm-device-card") export class VMDeviceCard extends VMDeviceMixin(BaseElement) { @@ -116,51 +129,23 @@ export class VMDeviceCard extends VMDeviceMixin(BaseElement) { }, this); return html` - +
- + Id - + Name - + - + Hash - + ${badges.map((badge) => badge)}
@@ -172,20 +157,12 @@ export class VMDeviceCard extends VMDeviceMixin(BaseElement) { const inputIdBase = `vmDeviceCard${this.deviceID}Field`; return html` ${fields.map(([name, field], _index, _fields) => { - return html` - ${name} - - ${field.field_type} - `; + return html` + ${name} + + ${field.field_type} + `; })} `; } @@ -196,28 +173,17 @@ export class VMDeviceCard extends VMDeviceMixin(BaseElement) { const inputIdBase = `vmDeviceCard${this.deviceID}Slot${slotIndex}Field`; return html` - ${slotIndex} : ${slot.typ} + ${slotIndex} : ${slot.typ}
${fields.map( - ([name, field], _index, _fields) => html` - - ${name} - - ${field.field_type} - - `, + ([name, field], _index, _fields) => html` + + ${name} + + ${field.field_type} + + `, )}
@@ -241,26 +207,19 @@ export class VMDeviceCard extends VMDeviceMixin(BaseElement) { return html`
${this.connections.map((connection, index, _conns) => { - const conn = - typeof connection === "object" ? connection.CableNetwork : null; - return html` - - Connection:${index} - ${vmNetworks.map( - (net) => - html`Network ${net}`, - )} - ${conn?.typ} - - `; + const conn = + typeof connection === "object" ? connection.CableNetwork : null; + return html` + + Connection:${index} + ${vmNetworks.map( + (net) => + html`Network ${net}`, + )} + ${conn?.typ} + + `; })}
`; @@ -271,23 +230,16 @@ export class VMDeviceCard extends VMDeviceMixin(BaseElement) { return html`
${pins?.map( - (pin, index) => - html` - d${index} - ${visibleDevices.map( - (device, _index) => - html` - Device ${device.id} : ${device.name ?? device.prefabName} - `, - )} - `, + (pin, index) => + html` + d${index} + ${visibleDevices.map( + (device, _index) => + html` + Device ${device.id} : ${device.name ?? device.prefabName} + `, + )} + `, )}
`; @@ -416,10 +368,7 @@ export class VMDeviceList extends BaseElement { protected render(): HTMLTemplateResult { const deviceCards: HTMLTemplateResult[] = this.devices.map( (id, _index, _ids) => - html``, + html``, ); const result = html`
@@ -545,43 +494,27 @@ export class VMAddDeviceButton extends BaseElement { renderSearchResults(): HTMLTemplateResult { const renderedResults: HTMLTemplateResult[] = this._searchResults?.map( (result) => - html``, + html``, ); return html`${renderedResults}`; } render() { return html` - + Add Device - + Search Structures "
${this.renderSearchResults()}
- { - this.drawer.hide(); + { + this.drawer.hide(); }} - > + > Close
@@ -607,8 +540,8 @@ export class VMAddDeviceButton extends BaseElement { @customElement("vm-device-template") export class VmDeviceTemplate extends BaseElement { - @property({ type: String }) accessor name: string; - + _prefab_name: string; + dbDevice: DeviceDBEntry; private _deviceDB: DeviceDB; private image_err: boolean = false; @@ -640,6 +573,13 @@ export class VmDeviceTemplate extends BaseElement { `, ]; + @state() fields: { [key in LogicType]?: LogicField }; + @state() slots: SlotTemplate[]; + @state() template: DeviceTemplate; + @state() device_id: number | undefined; + @state() device_name: string | undefined; + @state() connections: Connection[]; + constructor() { super(); this.deviceDB = window.VM!.db; @@ -652,6 +592,63 @@ export class VmDeviceTemplate extends BaseElement { @state() set deviceDB(val: DeviceDB) { this._deviceDB = val; + this.setupState(); + } + + get prefab_name() { + return this._prefab_name; + } + + @property({ type: String }) + set prefab_name(val: string) { + this._prefab_name = val; + + this.dbDevice = this.deviceDB.db[this._prefab_name]; + this.setupState(); + } + + setupState() { + const slotlogicmap: { [key: number]: SlotLogicType[] } = {}; + for (const [slt, slotIndexes] of Object.entries( + this.dbDevice.slotlogic ?? {}, + )) { + for (const slotIndex of slotIndexes) { + const list = slotlogicmap[slotIndex] ?? []; + list.push(slt as SlotLogicType); + slotlogicmap[slotIndex] = list; + } + } + + this.fields = Object.fromEntries( + Object.entries(this.dbDevice.logic ?? {}).map(([lt, ft]) => [ + lt, + { field_type: ft, value: 0.0 } as LogicField, + ]), + ); + + this.slots = + this.dbDevice.slots.map( + (slot, _index) => + ({ + typ: slot.typ, + }) as SlotTemplate, + ) ?? []; + + const connections = Object.entries(this.dbDevice.conn ?? {}).map( + ([index, conn]) => + [index, connectionFromDeviceDBConnection(conn)] as const, + ); + connections.sort((a, b) => { + if (a[0] < b[0]) { + return -1; + } else if (a[0] > b[0]) { + return 1; + } else { + return 0; + } + }); + + this.connections = connections.map((conn) => conn[1]); } connectedCallback(): void { @@ -673,14 +670,13 @@ export class VmDeviceTemplate extends BaseElement { } renderFields(): HTMLTemplateResult { - const device = this.deviceDB.db[this.name]; - const fields = device.logic ? Object.entries(device.logic) : []; + const fields = Object.entries(this.fields); return html` ${fields.map(([name, field_type], _index, _fields) => { - return html` - ${name} - ${field_type} - `; + return html` + ${name} + ${field_type} + `; })} `; } @@ -699,32 +695,53 @@ export class VmDeviceTemplate extends BaseElement { renderNetworks(): HTMLTemplateResult { const vmNetworks = window.VM!.networks; - return html`
`; + const connections = this.connections; + return html` +
+ ${connections.map((connection, index, _conns) => { + const conn = + typeof connection === "object" ? connection.CableNetwork : null; + return html` + + Connection:${index} + ${vmNetworks.map( + (net) => + html`Network ${net}`, + )} + ${conn?.typ} + + `; + })} +
+ `; + } + + _handleChangeConnection(e: CustomEvent) { + const select = e.target as SlSelect; + const conn = parseInt(select.getAttribute("key")!); + const val = select.value ? parseInt(select.value as string) : undefined; + (this.connections[conn] as ConnectionCableNetwork).CableNetwork.net = val; } renderPins(): HTMLTemplateResult { - const device = this.deviceDB.db[this.name]; + const device = this.deviceDB.db[this.prefab_name]; return html`
`; } render() { - const device = this.deviceDB.db[this.name]; + const device = this.deviceDB.db[this.prefab_name]; return html`
- +
${device.name} ${device.hash}
- Add + Add
@@ -737,16 +754,18 @@ export class VmDeviceTemplate extends BaseElement { ${this.renderFields()} ${this.renderSlots()} - ${this.renderReagents()} - ${this.renderNetworks()} + ${this.renderReagents()} + ${this.renderNetworks()} ${this.renderPins()}
`; } + _handleAddButtonClick() { + + + // TODO: Actualy add Device + this.setupState(); + } } diff --git a/www/src/ts/virtual_machine/device_db.ts b/www/src/ts/virtual_machine/device_db.ts index e335905..7136793 100644 --- a/www/src/ts/virtual_machine/device_db.ts +++ b/www/src/ts/virtual_machine/device_db.ts @@ -1,3 +1,5 @@ +import { LogicType, SlotLogicType } from "ic10emu_wasm"; + export type SortingClass = | "Default" | "Kits" @@ -69,310 +71,8 @@ export type ConnectionRole = | "Output" | "Output2" | "Waste"; + export type FieldType = "Read" | "Write" | "ReadWrite"; -export type LogicType = - | "Acceleration" - | "Activate" - | "AirRelease" - | "AlignmentError" - | "Apex" - | "AutoLand" - | "AutoShutOff" - | "Bpm" - | "BurnTimeRemaining" - | "Bypass" - | "CelestialHash" - | "CelestialParentHash" - | "Channel" - | "Channel0" - | "Channel1" - | "Channel2" - | "Channel3" - | "Channel4" - | "Channel5" - | "Channel6" - | "Channel7" - | "Charge" - | "Chart" - | "ChartedNavPoints" - | "ClearMemory" - | "CollectableGoods" - | "Color" - | "Combustion" - | "CombustionInput" - | "CombustionInput2" - | "CombustionLimiter" - | "CombustionOutput" - | "CombustionOutput2" - | "CompletionRatio" - | "ContactTypeId" - | "CurrentCode" - | "CurrentResearchPodType" - | "Density" - | "DestinationCode" - | "Discover" - | "DistanceAu" - | "DistanceKm" - | "DrillCondition" - | "DryMass" - | "Eccentricity" - | "ElevatorLevel" - | "ElevatorSpeed" - | "EntityState" - | "EnvironmentEfficiency" - | "Error" - | "ExhaustVelocity" - | "ExportCount" - | "ExportQuantity" - | "ExportSlotHash" - | "ExportSlotOccupant" - | "Filtration" - | "FlightControlRule" - | "Flush" - | "ForceWrite" - | "ForwardX" - | "ForwardY" - | "ForwardZ" - | "Fuel" - | "Harvest" - | "Horizontal" - | "HorizontalRatio" - | "Idle" - | "ImportCount" - | "ImportQuantity" - | "ImportSlotHash" - | "ImportSlotOccupant" - | "Inclination" - | "Index" - | "InterrogationProgress" - | "LineNumber" - | "Lock" - | "ManualResearchRequiredPod" - | "Mass" - | "Maximum" - | "MinWattsToContact" - | "MineablesInQueue" - | "MineablesInVicinity" - | "MinedQuantity" - | "MinimumWattsToContact" - | "Mode" - | "NavPoints" - | "NextWeatherEventTime" - | "None" - | "On" - | "Open" - | "OperationalTemperatureEfficiency" - | "OrbitPeriod" - | "Orientation" - | "Output" - | "OverShootTarget" - | "PassedMoles" - | "Plant" - | "PlantEfficiency1" - | "PlantEfficiency2" - | "PlantEfficiency3" - | "PlantEfficiency4" - | "PlantGrowth1" - | "PlantGrowth2" - | "PlantGrowth3" - | "PlantGrowth4" - | "PlantHash1" - | "PlantHash2" - | "PlantHash3" - | "PlantHash4" - | "PlantHealth1" - | "PlantHealth2" - | "PlantHealth3" - | "PlantHealth4" - | "PositionX" - | "PositionY" - | "PositionZ" - | "Power" - | "PowerActual" - | "PowerGeneration" - | "PowerPotential" - | "PowerRequired" - | "PrefabHash" - | "Pressure" - | "PressureEfficiency" - | "PressureExternal" - | "PressureInput" - | "PressureInput2" - | "PressureInternal" - | "PressureOutput" - | "PressureOutput2" - | "PressureSetting" - | "Progress" - | "Quantity" - | "Ratio" - | "RatioCarbonDioxide" - | "RatioCarbonDioxideInput" - | "RatioCarbonDioxideInput2" - | "RatioCarbonDioxideOutput" - | "RatioCarbonDioxideOutput2" - | "RatioHydrogen" - | "RatioLiquidCarbonDioxide" - | "RatioLiquidCarbonDioxideInput" - | "RatioLiquidCarbonDioxideInput2" - | "RatioLiquidCarbonDioxideOutput" - | "RatioLiquidCarbonDioxideOutput2" - | "RatioLiquidHydrogen" - | "RatioLiquidNitrogen" - | "RatioLiquidNitrogenInput" - | "RatioLiquidNitrogenInput2" - | "RatioLiquidNitrogenOutput" - | "RatioLiquidNitrogenOutput2" - | "RatioLiquidNitrousOxide" - | "RatioLiquidNitrousOxideInput" - | "RatioLiquidNitrousOxideInput2" - | "RatioLiquidNitrousOxideOutput" - | "RatioLiquidNitrousOxideOutput2" - | "RatioLiquidOxygen" - | "RatioLiquidOxygenInput" - | "RatioLiquidOxygenInput2" - | "RatioLiquidOxygenOutput" - | "RatioLiquidOxygenOutput2" - | "RatioLiquidPollutant" - | "RatioLiquidPollutantInput" - | "RatioLiquidPollutantInput2" - | "RatioLiquidPollutantOutput" - | "RatioLiquidPollutantOutput2" - | "RatioLiquidVolatiles" - | "RatioLiquidVolatilesInput" - | "RatioLiquidVolatilesInput2" - | "RatioLiquidVolatilesOutput" - | "RatioLiquidVolatilesOutput2" - | "RatioNitrogen" - | "RatioNitrogenInput" - | "RatioNitrogenInput2" - | "RatioNitrogenOutput" - | "RatioNitrogenOutput2" - | "RatioNitrousOxide" - | "RatioNitrousOxideInput" - | "RatioNitrousOxideInput2" - | "RatioNitrousOxideOutput" - | "RatioNitrousOxideOutput2" - | "RatioOxygen" - | "RatioOxygenInput" - | "RatioOxygenInput2" - | "RatioOxygenOutput" - | "RatioOxygenOutput2" - | "RatioPollutant" - | "RatioPollutantInput" - | "RatioPollutantInput2" - | "RatioPollutantOutput" - | "RatioPollutantOutput2" - | "RatioPollutedWater" - | "RatioSteam" - | "RatioSteamInput" - | "RatioSteamInput2" - | "RatioSteamOutput" - | "RatioSteamOutput2" - | "RatioVolatiles" - | "RatioVolatilesInput" - | "RatioVolatilesInput2" - | "RatioVolatilesOutput" - | "RatioVolatilesOutput2" - | "RatioWater" - | "RatioWaterInput" - | "RatioWaterInput2" - | "RatioWaterOutput" - | "RatioWaterOutput2" - | "ReEntryAltitude" - | "Reagents" - | "RecipeHash" - | "ReferenceId" - | "RequestHash" - | "RequiredPower" - | "ReturnFuelCost" - | "Richness" - | "Rpm" - | "SemiMajorAxis" - | "Setting" - | "SettingInput" - | "SettingInputHash" - | "SettingOutput" - | "SettingOutputHash" - | "SignalID" - | "SignalStrength" - | "Sites" - | "Size" - | "SizeX" - | "SizeY" - | "SizeZ" - | "SolarAngle" - | "SolarConstant" - | "SolarIrradiance" - | "SoundAlert" - | "Stress" - | "Survey" - | "TargetPadIndex" - | "TargetX" - | "TargetY" - | "TargetZ" - | "Temperature" - | "TemperatureDifferentialEfficiency" - | "TemperatureExternal" - | "TemperatureInput" - | "TemperatureInput2" - | "TemperatureOutput" - | "TemperatureOutput2" - | "TemperatureSetting" - | "Throttle" - | "Thrust" - | "ThrustToWeight" - | "Time" - | "TimeToDestination" - | "TotalMoles" - | "TotalMolesInput" - | "TotalMolesInput2" - | "TotalMolesOutput" - | "TotalMolesOutput2" - | "TotalQuantity" - | "TrueAnomaly" - | "Unknown" - | "VelocityMagnitude" - | "VelocityRelativeX" - | "VelocityRelativeY" - | "VelocityRelativeZ" - | "VelocityX" - | "VelocityY" - | "VelocityZ" - | "Vertical" - | "VerticalRatio" - | "Volume" - | "VolumeOfLiquid" - | "WattsReachingContact" - | "Weight" - | "WorkingGasEfficiency"; -export type SlotLogicType = - | "Charge" - | "ChargeRatio" - | "Class" - | "Damage" - | "Efficiency" - | "FilterType" - | "Growth" - | "Health" - | "LineNumber" - | "Lock" - | "Mature" - | "MaxQuantity" - | "None" - | "OccupantHash" - | "Occupied" - | "On" - | "Open" - | "PrefabHash" - | "Pressure" - | "PressureAir" - | "PressureWaste" - | "Quantity" - | "ReferenceId" - | "Seeding" - | "SortingClass" - | "Temperature" - | "Volume"; export type ReagentMode = "Contents" | "Recipe" | "Required" | "TotalContents"; @@ -396,8 +96,8 @@ export interface DeviceDBDevice { } export interface DeviceDBConnection { - typ: string; - role: string; + typ: NetworkType; + role: ConnectionRole; name: string; } diff --git a/www/src/ts/virtual_machine/utils.ts b/www/src/ts/virtual_machine/utils.ts new file mode 100644 index 0000000..03ce621 --- /dev/null +++ b/www/src/ts/virtual_machine/utils.ts @@ -0,0 +1,16 @@ +import { Connection } from "ic10emu_wasm"; +import { DeviceDBConnection } from "./device_db"; + +const CableNetworkTypes: readonly string[] = Object.freeze(["Power", "Data", "PowerAndData"]); +export function connectionFromDeviceDBConnection(conn: DeviceDBConnection): Connection { + if (CableNetworkTypes.includes(conn.typ)) { + return { + CableNetwork: { + net: undefined, + typ: conn.role + } + }; + } else { + return "Other"; + } +} diff --git a/www/tsconfig.json b/www/tsconfig.json index 2722070..234c590 100644 --- a/www/tsconfig.json +++ b/www/tsconfig.json @@ -11,6 +11,7 @@ "esModuleInterop": true, "isolatedModules": true, "experimentalDecorators": true, + "useDefineForClassFields": false, "types": ["@types/wicg-file-system-access", "@types/ace"], "plugins": [ {