refactor(frontend) fix template searching, update database images
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
@@ -15,18 +15,20 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%matplotlib widget\n",
|
||||
"import json\n",
|
||||
"\n",
|
||||
"database = {}\n",
|
||||
"\n",
|
||||
"with open(\"data/database.json\", \"r\") as f:\n",
|
||||
" database = json.load(f)\n",
|
||||
"with open(\"src/ts/virtualMachine/prefabDatabase.ts\", \"r\") as f:\n",
|
||||
" contents = f.read().removeprefix(\"export default \").removesuffix(\" as const\")\n",
|
||||
" database = json.loads(contents)\n",
|
||||
"\n",
|
||||
"db = database[\"db\"]"
|
||||
"db = database[\"prefabs\"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -38,7 +40,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -58,7 +60,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -80,7 +82,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"execution_count": 35,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -105,9 +107,9 @@
|
||||
" better_matches = []\n",
|
||||
" for can in filtered_matches:\n",
|
||||
" name, match, mapping = can\n",
|
||||
" if mapping.startswith(\"Item\") and mapping in name:\n",
|
||||
" if mapping.startswith(\"Item\") and mapping in name or mapping.lower() in name:\n",
|
||||
" better_matches.append((name, match, mapping))\n",
|
||||
" elif mapping.startswith(\"Structure\") and mapping in name:\n",
|
||||
" elif mapping.startswith(\"Structure\") and mapping in name or mapping.lower() in name:\n",
|
||||
" better_matches.append((name, match, mapping))\n",
|
||||
" if len(better_matches) > 0:\n",
|
||||
" filtered_matches = better_matches\n",
|
||||
@@ -127,7 +129,7 @@
|
||||
" direct = []\n",
|
||||
" for can in filtered_matches:\n",
|
||||
" name, match, mapping = can\n",
|
||||
" if f\"{match}-\" in name:\n",
|
||||
" if f\"{match}-\" in name or f\"{match.lower()}-\" in name:\n",
|
||||
" direct.append((name, match, mapping))\n",
|
||||
" if len(direct) > 0:\n",
|
||||
" filtered_matches = direct\n",
|
||||
@@ -154,7 +156,7 @@
|
||||
" continue\n",
|
||||
" elif name.startswith(\"Kit\") and not mapping.startswith(\"Kit\"):\n",
|
||||
" continue\n",
|
||||
" elif not name.startswith(match):\n",
|
||||
" elif not (name.startswith(match) or name.startswith(match.lower())):\n",
|
||||
" continue\n",
|
||||
" not_worse.append((name, match, mapping))\n",
|
||||
" if len(not_worse) > 0:\n",
|
||||
@@ -171,14 +173,15 @@
|
||||
"\n",
|
||||
"for entry in db.values():\n",
|
||||
" candidates = []\n",
|
||||
" entry_name = entry[\"prefab\"][\"prefab_name\"]\n",
|
||||
" for name in names:\n",
|
||||
" if entry[\"name\"] in name:\n",
|
||||
" candidates.append((name, entry[\"name\"], entry[\"name\"]))\n",
|
||||
" if entry[\"name\"].removeprefix(\"Item\") in name:\n",
|
||||
" candidates.append((name, entry[\"name\"].removeprefix(\"Item\"), entry[\"name\"]))\n",
|
||||
" if entry[\"name\"].removeprefix(\"Structure\") in name:\n",
|
||||
" candidates.append((name, entry[\"name\"].removeprefix(\"Structure\"), entry[\"name\"]))\n",
|
||||
" image_candidates[entry[\"name\"]] = filter_candidates(candidates)"
|
||||
" if entry_name in name or entry_name.lower() in name:\n",
|
||||
" candidates.append((name, entry_name, entry_name))\n",
|
||||
" if entry_name.removeprefix(\"Item\") in name or entry_name.removeprefix(\"Item\").lower() in name:\n",
|
||||
" candidates.append((name, entry_name.removeprefix(\"Item\"), entry_name))\n",
|
||||
" if entry_name.removeprefix(\"Structure\") in name or entry_name.removeprefix(\"Structure\").lower() in name:\n",
|
||||
" candidates.append((name, entry_name.removeprefix(\"Structure\"), entry_name))\n",
|
||||
" image_candidates[entry_name] = filter_candidates(candidates)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -190,7 +193,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 17,
|
||||
"execution_count": 36,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -206,12 +209,12 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Prepare out List of file copies. at this point a few items will never have a match. and one or two will have two choices but those choices will be arbitrary."
|
||||
"Prepare out List of file copies. at this point a few items will never have a match. and one or two will have two choices but those choices will be filtered again by passing them through some extra function."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 18,
|
||||
"execution_count": 40,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
@@ -227,25 +230,87 @@
|
||||
"ItemHorticultureBelt []\n",
|
||||
"ItemKitLiquidRegulator []\n",
|
||||
"ItemKitPortablesConnector []\n",
|
||||
"ItemMushroom ['ItemMushroom-resources.assets-3022.png', 'ItemMushroom-resources.assets-9304.png']\n",
|
||||
"ItemPlantEndothermic_Creative []\n",
|
||||
"ItemPlantThermogenic_Creative []\n",
|
||||
"ItemSuitModCryogenicUpgrade []\n",
|
||||
"Landingpad_GasConnectorInwardPiece []\n",
|
||||
"Landingpad_LiquidConnectorInwardPiece []\n",
|
||||
"StructureBlocker []\n",
|
||||
"StructureElevatorLevelIndustrial []\n",
|
||||
"StructureLogicSorter []\n",
|
||||
"StructurePlinth []\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%matplotlib widget\n",
|
||||
"to_copy = []\n",
|
||||
"\n",
|
||||
"from IPython.display import Image, display\n",
|
||||
"\n",
|
||||
"gases = [(\"Oxygen\", \"White\"), (\"Nitrogen\", \"Black\"), (\"CarbonDioxide\", \"Yellow\"), (\"Fuel\", \"Orange\")]\n",
|
||||
"\n",
|
||||
"colors = [\"White\", \"Black\", \"Gray\", \"Khaki\", \"Brown\", \"Orange\", \"Yellow\", \"Red\", \"Green\", \"Blue\", \"Purple\"]\n",
|
||||
"\n",
|
||||
"def split_gas(name):\n",
|
||||
" for gas, color in gases:\n",
|
||||
" if name.endswith(gas):\n",
|
||||
" return (name.removesuffix(gas), gas, color)\n",
|
||||
" elif name.lower().endswith(gas):\n",
|
||||
" return (name.lower().removesuffix(gas), gas, color)\n",
|
||||
" elif name.lower().endswith(gas.lower()):\n",
|
||||
" return (name.lower().removesuffix(gas.lower()), gas.lower(), color.lower())\n",
|
||||
" return [name, None, None]\n",
|
||||
"\n",
|
||||
"def match_gas_color(name, candidates):\n",
|
||||
" mat, gas, color = split_gas(name)\n",
|
||||
" seek = f\"{mat}_{color}\"\n",
|
||||
" if gas is not None:\n",
|
||||
" for candidate in candidates:\n",
|
||||
" if seek in candidate or seek.lower() in candidate:\n",
|
||||
" return candidate\n",
|
||||
" return None\n",
|
||||
"\n",
|
||||
"def prefer_direct(name, candidates):\n",
|
||||
" for candidate in candidates:\n",
|
||||
" if f\"{name}-\" in candidate or f\"{name.lower()}-\" in candidate:\n",
|
||||
" return candidate\n",
|
||||
" return None\n",
|
||||
"\n",
|
||||
"def prefer_uncolored(name, candidates):\n",
|
||||
" for candidate in candidates:\n",
|
||||
" for color in colors:\n",
|
||||
" if f\"_{color}\" not in candidate and f\"_{color.lower()}\" not in candidate:\n",
|
||||
" return candidate\n",
|
||||
" return None\n",
|
||||
"\n",
|
||||
"def prefer_lower_match(name, candidates):\n",
|
||||
" for candidate in candidates:\n",
|
||||
" if f\"{name.lower()}-\" in candidate:\n",
|
||||
" return candidate\n",
|
||||
" return None\n",
|
||||
"\n",
|
||||
"filter_funcs = [prefer_lower_match, prefer_direct, match_gas_color, prefer_uncolored]\n",
|
||||
"\n",
|
||||
"for name, candidates in image_candidates.items():\n",
|
||||
" if len(candidates) != 1:\n",
|
||||
" found = False\n",
|
||||
" for func in filter_funcs:\n",
|
||||
" candidate = func(name, candidates)\n",
|
||||
" if candidate is not None:\n",
|
||||
" to_copy.append((name, candidate))\n",
|
||||
" found = True\n",
|
||||
" if found:\n",
|
||||
" continue\n",
|
||||
" print(name, candidates)\n",
|
||||
" if len(candidates) > 1:\n",
|
||||
" for candidate in candidates:\n",
|
||||
" print(candidate)\n",
|
||||
" display(Image(datapath / candidate))\n",
|
||||
" \n",
|
||||
" #take first as fallback\n",
|
||||
" to_copy.append((name, candidates[0]))\n",
|
||||
" # to_copy.append((name, candidates[0]))\n",
|
||||
" raise StopExecution\n",
|
||||
" else:\n",
|
||||
" # print(name, candidates)\n",
|
||||
" to_copy.append((name, candidates[0]))\n"
|
||||
@@ -253,7 +318,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 21,
|
||||
"execution_count": 41,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
@@ -334,14 +399,28 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 22,
|
||||
"execution_count": 42,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "3497a8d33d6a45879586d4c7441e3f60",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
"text/plain": [
|
||||
"IntProgress(value=0, max=1288)"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"1266 of 1266 | 100.00% \n",
|
||||
"1288 of 1288 | 100.00% \n",
|
||||
"Done\n"
|
||||
]
|
||||
}
|
||||
@@ -352,6 +431,12 @@
|
||||
"destpath = Path(\"img/stationpedia\")\n",
|
||||
"total_files = len(to_copy)\n",
|
||||
"\n",
|
||||
"from ipywidgets import IntProgress\n",
|
||||
"from IPython.display import display\n",
|
||||
"import time\n",
|
||||
"\n",
|
||||
"f = IntProgress(min=0, max=total_files)\n",
|
||||
"display(f)\n",
|
||||
"count = 0\n",
|
||||
"print ( f\"{count} of {total_files} | { count / total_files * 100}\", end=\"\\r\")\n",
|
||||
"for name, file in to_copy:\n",
|
||||
@@ -359,6 +444,7 @@
|
||||
" dest = destpath / f\"{name}.png\"\n",
|
||||
" shutil.copy(source, dest)\n",
|
||||
" count += 1\n",
|
||||
" f.value = count\n",
|
||||
" print ( f\"{count} of {total_files} | { (count / total_files) * 100 :.2f}% \", end=\"\\r\")\n",
|
||||
"print()\n",
|
||||
"print(\"Done\")\n",
|
||||
@@ -382,7 +468,7 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.12.2"
|
||||
"version": "3.12.5"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
||||
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
BIN
www/img/stationpedia/ItemAdhesiveInsulation.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 11 KiB |
BIN
www/img/stationpedia/ItemCerealBarBag.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
www/img/stationpedia/ItemCerealBarBox.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
www/img/stationpedia/ItemChocolateBar.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
www/img/stationpedia/ItemChocolateCake.png
Normal file
|
After Width: | Height: | Size: 9.6 KiB |
BIN
www/img/stationpedia/ItemChocolateCerealBar.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
www/img/stationpedia/ItemCocoaPowder.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
www/img/stationpedia/ItemCocoaTree.png
Normal file
|
After Width: | Height: | Size: 7.0 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 16 KiB |
BIN
www/img/stationpedia/ItemEmergencySuppliesBox.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
www/img/stationpedia/ItemInsulatedCanisterPackage.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
www/img/stationpedia/ItemKitInsulatedPipeUtility.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
www/img/stationpedia/ItemKitInsulatedPipeUtilityLiquid.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
www/img/stationpedia/ItemKitLinearRail.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 15 KiB |
BIN
www/img/stationpedia/ItemKitRobotArmDoor.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
www/img/stationpedia/ItemKitRoboticArm.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
www/img/stationpedia/ItemMiningPackage.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
www/img/stationpedia/ItemPlainCake.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
www/img/stationpedia/ItemPortablesPackage.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
www/img/stationpedia/ItemResidentialPackage.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
www/img/stationpedia/ItemSugar.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
www/img/stationpedia/ItemSugarCane.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
www/img/stationpedia/ItemWaterBottleBag.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
www/img/stationpedia/ItemWaterBottlePackage.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
www/img/stationpedia/SeedBag_Cocoa.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
www/img/stationpedia/SeedBag_SugarCane.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
www/img/stationpedia/StructureChuteExportBin.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
www/img/stationpedia/StructureCompositeWindowShutter.png
Normal file
|
After Width: | Height: | Size: 9.3 KiB |
|
After Width: | Height: | Size: 7.1 KiB |
|
After Width: | Height: | Size: 17 KiB |
BIN
www/img/stationpedia/StructureComputerUpright.png
Normal file
|
After Width: | Height: | Size: 9.8 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 3.7 KiB |
BIN
www/img/stationpedia/StructureInsulatedInLineTankGas1x1.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
www/img/stationpedia/StructureInsulatedInLineTankGas1x2.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
www/img/stationpedia/StructureInsulatedInLineTankLiquid1x1.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
www/img/stationpedia/StructureInsulatedInLineTankLiquid1x2.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 11 KiB |
BIN
www/img/stationpedia/StructurePipeLiquidOneWayValveLever.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
www/img/stationpedia/StructurePipeOneWayValveLever.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
www/img/stationpedia/StructureReinforcedWall.png
Normal file
|
After Width: | Height: | Size: 7.4 KiB |
BIN
www/img/stationpedia/StructureRobotArmDoor.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
www/img/stationpedia/StructureRoboticArmDock.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
www/img/stationpedia/StructureRoboticArmRailCorner.png
Normal file
|
After Width: | Height: | Size: 8.9 KiB |
BIN
www/img/stationpedia/StructureRoboticArmRailCornerStop.png
Normal file
|
After Width: | Height: | Size: 9.6 KiB |
BIN
www/img/stationpedia/StructureRoboticArmRailInnerCorner.png
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
BIN
www/img/stationpedia/StructureRoboticArmRailOuterCorner.png
Normal file
|
After Width: | Height: | Size: 7.8 KiB |
BIN
www/img/stationpedia/StructureRoboticArmRailStraight.png
Normal file
|
After Width: | Height: | Size: 7.6 KiB |
BIN
www/img/stationpedia/StructureRoboticArmRailStraightStop.png
Normal file
|
After Width: | Height: | Size: 8.5 KiB |
|
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 12 KiB |
@@ -55,7 +55,7 @@ export function crc32(str: string): number {
|
||||
|
||||
export function numberToString(n: number): string {
|
||||
if (isZeroNegative(n)) return "-0";
|
||||
return n.toString();
|
||||
return n?.toString() ?? `${n}`;
|
||||
}
|
||||
export function displayNumber(n: number): string {
|
||||
return numberToString(n).replace("Infinity", "∞");
|
||||
|
||||
@@ -76,7 +76,7 @@ export class VMICControls extends VMObjectMixin(SignalWatcher(BaseElement)) {
|
||||
}
|
||||
this.selectUpdateTimeout = setTimeout(() => {
|
||||
if (this.activeICSelect.value != null) {
|
||||
this.activeICSelect.value.value = this.activeIC.value.toString();
|
||||
this.activeICSelect.value.value = this.activeIC.value?.toString() ?? "";
|
||||
this.activeICSelect.value.handleValueChange();
|
||||
}
|
||||
}, 100);
|
||||
|
||||
@@ -54,7 +54,7 @@ export class VMAddDeviceButton extends VMObjectMixin(BaseElement) {
|
||||
let last: Map<string, LogicableStructureTemplate> = null
|
||||
return computed(() => {
|
||||
const next = new Map(
|
||||
Array.from(Object.values(this.templateDB.value ?? {})).flatMap((template) => {
|
||||
Array.from(this.templateDB.value?.values() ?? []).flatMap((template) => {
|
||||
if ("structure" in template && "logic" in template) {
|
||||
return [[template.prefab.prefab_name, template]] as [
|
||||
string,
|
||||
@@ -244,7 +244,7 @@ export class VMAddDeviceButton extends VMObjectMixin(BaseElement) {
|
||||
(result) =>
|
||||
html`
|
||||
<vm-device-template
|
||||
prefab_name=${result.entry.prefab.prefab_name}
|
||||
prefabName=${result.entry.prefab.prefab_name}
|
||||
class="card"
|
||||
@add-device-template=${this._handleDeviceAdd}
|
||||
>
|
||||
|
||||
@@ -81,7 +81,7 @@ export class VMDevicePins extends VMObjectMixin(BaseElement) {
|
||||
}
|
||||
);
|
||||
});
|
||||
return pinsHtml;
|
||||
return html`${watch(pinsHtml)}`;
|
||||
}
|
||||
|
||||
_handleChangePin(e: CustomEvent) {
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
ItemInfo,
|
||||
ObjectInfo,
|
||||
ObjectTemplate,
|
||||
TemplateDatabase,
|
||||
} from "ic10emu_wasm";
|
||||
import { computed, ReadonlySignal, signal, Signal, watch } from "@lit-labs/preact-signals";
|
||||
import { repeat } from "lit/directives/repeat.js";
|
||||
@@ -47,7 +48,7 @@ export class VMSlotAddDialog extends VMObjectMixin(BaseElement) {
|
||||
this._filter.value = val;
|
||||
}
|
||||
|
||||
templateDB = computed(() => {
|
||||
templateDB = computed((): TemplateDatabase => {
|
||||
return this.vm.value?.state.templateDB.value ?? null;
|
||||
});
|
||||
|
||||
@@ -55,7 +56,7 @@ export class VMSlotAddDialog extends VMObjectMixin(BaseElement) {
|
||||
let last: { [k: string]: SlotableItemTemplate } = null;
|
||||
return computed(() => {
|
||||
const next = Object.fromEntries(
|
||||
Array.from(Object.values(this.templateDB.value ?? {})).flatMap((template) => {
|
||||
Array.from(this.templateDB.value?.values() ?? []).flatMap((template) => {
|
||||
if ("item" in template) {
|
||||
return [[template.prefab.prefab_name, template]] as [
|
||||
string,
|
||||
@@ -82,7 +83,7 @@ export class VMSlotAddDialog extends VMObjectMixin(BaseElement) {
|
||||
if (isSome(obj)) {
|
||||
const template = obj.template;
|
||||
const slot = "slots" in template ? template.slots[this.slotIndex.value] : null;
|
||||
const typ = slot.typ;
|
||||
const typ = slot?.typ;
|
||||
|
||||
if (typeof typ === "string" && typ !== "None") {
|
||||
filtered = Array.from(Object.values(this.items.value)).filter(
|
||||
@@ -238,10 +239,6 @@ export class VMSlotAddDialog extends VMObjectMixin(BaseElement) {
|
||||
const div = e.currentTarget as HTMLDivElement;
|
||||
const key = parseInt(div.getAttribute("key"));
|
||||
const entry = this.templateDB.value.get(key) as SlotableItemTemplate;
|
||||
const obj = window.VM.vm.state.getObject(this.objectID);
|
||||
const dbTemplate = obj.peek().template;
|
||||
console.log("using entry", dbTemplate);
|
||||
|
||||
const template: FrozenObject = {
|
||||
obj_info: {
|
||||
prefab: entry.prefab.prefab_name,
|
||||
@@ -301,8 +298,8 @@ export class VMSlotAddDialog extends VMObjectMixin(BaseElement) {
|
||||
}
|
||||
|
||||
_handleDialogHide() {
|
||||
this.objectID = undefined;
|
||||
this.slotIndex = undefined;
|
||||
this.objectIDSignal.value = null;
|
||||
this.slotIndex.value = null;
|
||||
}
|
||||
|
||||
private slotIndex: Signal<number> = signal(0);
|
||||
|
||||
@@ -20,7 +20,7 @@ import { customElement, property, query, state } from "lit/decorators.js";
|
||||
import { BaseElement, defaultCss } from "components";
|
||||
|
||||
import { connectionFromConnectionInfo } from "./dbutils";
|
||||
import { crc32, displayNumber, parseNumber, structuralEqual } from "utils";
|
||||
import { crc32, displayNumber, isSome, parseNumber, structuralEqual } from "utils";
|
||||
import SlInput from "@shoelace-style/shoelace/dist/components/input/input.component.js";
|
||||
import SlSelect from "@shoelace-style/shoelace/dist/components/select/select.component.js";
|
||||
import { VMDeviceCard } from "./card";
|
||||
@@ -76,16 +76,16 @@ export class VmObjectTemplate extends VMObjectMixin(BaseElement) {
|
||||
`,
|
||||
];
|
||||
|
||||
fields: Signal<Record<LogicType, number>>;
|
||||
slots: Signal<SlotTemplate[]>;
|
||||
pins: Signal<(ObjectID | undefined)[]>;
|
||||
template: Signal<FrozenObject>;
|
||||
objectId: Signal<number | undefined>;
|
||||
objectName: Signal<string | undefined>;
|
||||
connections: Signal<Connection[]>;
|
||||
fields: Signal<Record<LogicType, number>> = signal(null);
|
||||
slots: Signal<SlotTemplate[]> = signal([]);
|
||||
pins: Signal<(ObjectID | null)[]> = signal(null);
|
||||
template: Signal<FrozenObject> = signal(null);
|
||||
objectId: Signal<number | null> = signal(null);
|
||||
objectName: Signal<string | null> = signal(null);
|
||||
connections: Signal<Connection[]> = signal([]);
|
||||
|
||||
private prefabNameSignal = signal(null);
|
||||
private prefabHashSignal = computed(() => crc32(this.prefabNameSignal.value));
|
||||
private prefabHashSignal = computed(() => crc32(this.prefabNameSignal.value ?? ""));
|
||||
|
||||
get prefabName(): string {
|
||||
return this.prefabNameSignal.peek();
|
||||
@@ -114,6 +114,10 @@ export class VmObjectTemplate extends VMObjectMixin(BaseElement) {
|
||||
constructor() {
|
||||
super();
|
||||
this.dbTemplate.subscribe(() => this.setupState())
|
||||
this.prefabNameSignal.subscribe(() => this.setupState());
|
||||
this.networkOptions.subscribe((_) => {
|
||||
this.forceSelectUpdate(this.networksSelectRef);
|
||||
})
|
||||
}
|
||||
|
||||
setupState() {
|
||||
@@ -122,8 +126,8 @@ export class VmObjectTemplate extends VMObjectMixin(BaseElement) {
|
||||
this.fields.value = Object.fromEntries(
|
||||
(
|
||||
Array.from(
|
||||
"logic" in dbTemplate
|
||||
? Object.entries(dbTemplate.logic.logic_types)
|
||||
isSome(dbTemplate) && "logic" in dbTemplate
|
||||
? dbTemplate.logic.logic_types.entries()
|
||||
: [],
|
||||
) as [LogicType, MemoryAccess][]
|
||||
).map(([lt, access]) => {
|
||||
@@ -134,7 +138,7 @@ export class VmObjectTemplate extends VMObjectMixin(BaseElement) {
|
||||
) as Record<LogicType, number>;
|
||||
|
||||
this.slots.value = (
|
||||
("slots" in dbTemplate ? dbTemplate.slots ?? [] : []) as SlotInfo[]
|
||||
(isSome(dbTemplate) && "slots" in dbTemplate ? dbTemplate.slots ?? [] : []) as SlotInfo[]
|
||||
).map(
|
||||
(slot, _index) =>
|
||||
({
|
||||
@@ -144,7 +148,7 @@ export class VmObjectTemplate extends VMObjectMixin(BaseElement) {
|
||||
);
|
||||
|
||||
const connections = (
|
||||
"device" in dbTemplate
|
||||
isSome(dbTemplate) && "device" in dbTemplate
|
||||
? dbTemplate.device.connection_list
|
||||
: ([] as ConnectionInfo[])
|
||||
).map(
|
||||
@@ -163,27 +167,30 @@ export class VmObjectTemplate extends VMObjectMixin(BaseElement) {
|
||||
this.connections.value = connections.map((conn) => conn[1]);
|
||||
|
||||
const numPins =
|
||||
"device" in dbTemplate ? dbTemplate.device.device_pins_length : 0;
|
||||
isSome(dbTemplate) && "device" in dbTemplate ? dbTemplate.device.device_pins_length : 0;
|
||||
this.pins.value = new Array(numPins).fill(undefined);
|
||||
}
|
||||
|
||||
renderFields(): HTMLTemplateResult {
|
||||
const fields = Object.entries(this.fields);
|
||||
return html`
|
||||
${fields.map(([name, field], _index, _fields) => {
|
||||
fieldsHtml = computed(() => {
|
||||
const fields = Object.entries(this.fields.value);
|
||||
fields.map(([name, field], _index, _fields) => {
|
||||
return html`
|
||||
<sl-input
|
||||
key="${name}"
|
||||
value="${displayNumber(field.value)}"
|
||||
value="${displayNumber(field)}"
|
||||
size="small"
|
||||
@sl-change=${this._handleChangeField}
|
||||
?disabled=${name === "PrefabHash"}
|
||||
>
|
||||
<span slot="prefix">${name}</span>
|
||||
<span slot="suffix">${field.field_type}</span>
|
||||
</sl-input>
|
||||
`;
|
||||
})}
|
||||
});
|
||||
});
|
||||
|
||||
renderFields(): HTMLTemplateResult {
|
||||
return html`
|
||||
${watch(this.fieldsHtml)}
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -191,7 +198,7 @@ export class VmObjectTemplate extends VMObjectMixin(BaseElement) {
|
||||
const input = e.target as SlInput;
|
||||
const field = input.getAttribute("key")! as LogicType;
|
||||
const val = parseNumber(input.value);
|
||||
this.fields.value = { ...this.fields.value, [field]: val};
|
||||
this.fields.value = { ...this.fields.value, [field]: val };
|
||||
if (field === "ReferenceId" && val !== 0) {
|
||||
this.objectIDSignal.value = val;
|
||||
}
|
||||
@@ -224,38 +231,34 @@ export class VmObjectTemplate extends VMObjectMixin(BaseElement) {
|
||||
return vm?.state.networkIds.value.map(net => html`<sl-option value=${net}>Network ${net}</sl-option>`);
|
||||
});
|
||||
|
||||
renderNetworks() {
|
||||
const vm = window.VM.vm;
|
||||
this.networkOptions.subscribe((_) => {
|
||||
this.forceSelectUpdate(this.networksSelectRef);
|
||||
})
|
||||
const connections = computed(() => {
|
||||
this.connections.value.map((connection, index, _conns) => {
|
||||
const conn =
|
||||
typeof connection === "object" && "CableNetwork" in connection
|
||||
? connection.CableNetwork
|
||||
: null;
|
||||
return html`
|
||||
<sl-select
|
||||
hoist
|
||||
placement="top"
|
||||
clearable
|
||||
key=${index}
|
||||
value=${conn?.net}
|
||||
?disabled=${conn === null}
|
||||
@sl-change=${this._handleChangeConnection}
|
||||
${ref(this.networksSelectRef)}
|
||||
>
|
||||
<span slot="prefix">Connection:${index} </span>
|
||||
${watch(this.networkOptions)}
|
||||
<span slot="prefix"> ${conn?.typ} </span>
|
||||
</sl-select>
|
||||
`;
|
||||
});
|
||||
connectionsHtml = computed(() => {
|
||||
this.connections.value?.map((connection, index, _conns) => {
|
||||
const conn =
|
||||
typeof connection === "object" && "CableNetwork" in connection
|
||||
? connection.CableNetwork
|
||||
: null;
|
||||
return html`
|
||||
<sl-select
|
||||
hoist
|
||||
placement="top"
|
||||
clearable
|
||||
key=${index}
|
||||
value=${conn?.net}
|
||||
?disabled=${conn === null}
|
||||
@sl-change=${this._handleChangeConnection}
|
||||
${ref(this.networksSelectRef)}
|
||||
>
|
||||
<span slot="prefix">Connection:${index} </span>
|
||||
${watch(this.networkOptions)}
|
||||
<span slot="prefix"> ${conn?.typ} </span>
|
||||
</sl-select>
|
||||
`;
|
||||
});
|
||||
});
|
||||
renderNetworks() {
|
||||
return html`
|
||||
<div class="networks">
|
||||
${watch(connections)}
|
||||
${watch(this.connectionsHtml)}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
@@ -271,7 +274,7 @@ export class VmObjectTemplate extends VMObjectMixin(BaseElement) {
|
||||
|
||||
private _pinsSelectRefMap: Map<number, Ref<SlSelect>> = new Map();
|
||||
|
||||
getPinRef(index: number) : Ref<SlSelect> {
|
||||
getPinRef(index: number): Ref<SlSelect> {
|
||||
if (!this._pinsSelectRefMap.has(index)) {
|
||||
this._pinsSelectRefMap.set(index, createRef());
|
||||
}
|
||||
@@ -359,8 +362,8 @@ export class VmObjectTemplate extends VMObjectMixin(BaseElement) {
|
||||
|
||||
render() {
|
||||
const device = this.dbTemplate;
|
||||
const prefabName = computed(() => device.value.prefab.prefab_name);
|
||||
const name = computed(() => device.value.prefab.name);
|
||||
const prefabName = computed(() => device.value?.prefab.prefab_name ?? "");
|
||||
const name = computed(() => device.value?.prefab.name ?? "");
|
||||
return html`
|
||||
<sl-card class="template-card">
|
||||
<div class="header h-20 w-96" slot="header">
|
||||
|
||||
@@ -526,7 +526,12 @@ export class VMState {
|
||||
if (!this.signalCacheHas(key)) {
|
||||
const s = computed((): number => {
|
||||
const obj = this.getObject(id).value;
|
||||
return [...obj?.obj_info.device_pins?.keys() ?? []].length;
|
||||
const template = obj?.template;
|
||||
let numPins = [...obj?.obj_info.device_pins?.keys() ?? []].length;
|
||||
if (isSome(template) && "device" in template) {
|
||||
numPins = template.device.device_pins_length ?? 0;
|
||||
}
|
||||
return numPins;
|
||||
});
|
||||
this.signalCacheSet(key, s);
|
||||
return s;
|
||||
|
||||