From 76bd8e9510180b8a7f6dd1a0fe8ffbaa27f165c5 Mon Sep 17 00:00:00 2001 From: loki5512344 Date: Wed, 30 Sep 2026 11:22:54 +0200 Subject: [PATCH] refactor(hud): split ScriptedTriangulatorHudPanel to 189 lines Rendering moves to ScriptedTriangulatorRenderer, prop maps and cache signatures to scripted/panel/; records and row helpers stay nested so caller references (Panel, Palette, row, rows, idString) keep working. --- .../ScriptedTriangulatorHudPanel.java | 227 ++---------------- .../ScriptedTriangulatorRenderer.java | 75 ++++++ .../panel/ScriptedTriangulatorProps.java | 71 ++++++ .../panel/ScriptedTriangulatorSignatures.java | 143 +++++++++++ 4 files changed, 304 insertions(+), 212 deletions(-) create mode 100644 mod/src/main/java/dev/loki/lovisual/features/gui/hud/draggable/impl/scripted/ScriptedTriangulatorRenderer.java create mode 100644 mod/src/main/java/dev/loki/lovisual/features/gui/hud/draggable/impl/scripted/panel/ScriptedTriangulatorProps.java create mode 100644 mod/src/main/java/dev/loki/lovisual/features/gui/hud/draggable/impl/scripted/panel/ScriptedTriangulatorSignatures.java diff --git a/mod/src/main/java/dev/loki/lovisual/features/gui/hud/draggable/impl/scripted/ScriptedTriangulatorHudPanel.java b/mod/src/main/java/dev/loki/lovisual/features/gui/hud/draggable/impl/scripted/ScriptedTriangulatorHudPanel.java index 617f8e9..995b085 100644 --- a/mod/src/main/java/dev/loki/lovisual/features/gui/hud/draggable/impl/scripted/ScriptedTriangulatorHudPanel.java +++ b/mod/src/main/java/dev/loki/lovisual/features/gui/hud/draggable/impl/scripted/ScriptedTriangulatorHudPanel.java @@ -1,30 +1,31 @@ package dev.loki.lovisual.features.gui.hud.draggable.impl.scripted; import java.util.LinkedHashMap; +import dev.loki.lovisual.features.gui.hud.draggable.impl.scripted.panel.ScriptedTriangulatorProps; +import dev.loki.lovisual.features.gui.hud.draggable.impl.scripted.panel.ScriptedTriangulatorSignatures; import dev.loki.lovisual.features.gui.hud.script.HudScriptLayouts; import dev.loki.lovisual.render.engine.renderer.Renderer2D; -import dev.loki.lovisual.render.engine.renderer.ui.runtime.core.runtime.UiRuntime; -import dev.loki.lovisual.render.engine.renderer.ui.runtime.render.context.UiProjectionMode; -import dev.loki.lovisual.render.engine.renderer.ui.runtime.render.context.UiRenderContext; import dev.loki.lovisual.render.engine.renderer.ui.runtime.script.runtime.CachedUiScriptRuntime; -import dev.loki.lovisual.render.engine.renderer.ui.runtime.script.module.UiScriptModule; import dev.loki.lovisual.render.engine.renderer.ui.runtime.script.module.UiScriptModuleHandle; import dev.loki.lovisual.render.engine.text.render.TextRenderer; -import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.resources.Identifier; import java.util.ArrayList; import java.util.List; -import dev.loki.lovisual.features.gui.hud.draggable.impl.Triangulator; +/** + * Triangulator HUD facade: row/prop helpers and the panel records. Rendering + * lives in {@link ScriptedTriangulatorRenderer}, prop maps and cache + * signatures in the {@code panel} subpackage. + */ public final class ScriptedTriangulatorHudPanel { private static final String LAYOUT_ID = "lovisual:api/hud/draggable/triangulator"; private final UiScriptModuleHandle moduleHandle = HudScriptLayouts.handle(LAYOUT_ID); private final CachedUiScriptRuntime runtime = new CachedUiScriptRuntime(HudScriptLayouts.runtimeReporter()); public static String hex(int argb) { - return String.format("#%08X", argb); + return ScriptedTriangulatorProps.hex(argb); } public static LinkedHashMap row(String key, @@ -60,70 +61,9 @@ public final class ScriptedTriangulatorHudPanel { GuiGraphicsExtractor ctx, float tickDelta, Panel panel) { - if (renderer == null || panel == null || panel.width <= 0.0f || panel.height <= 0.0f) return false; - Minecraft mc = Minecraft.getInstance(); - if (mc == null || mc.getResourceManager() == null) return false; - - HudScriptLayouts.pollReloadCombo(mc); - if (moduleHandle.consumeChanged()) { - runtime.reset(); - } - - UiScriptModule module = ensureModule(mc); - if (module == null) return false; - - TextRenderer fallback = textRenderer != null ? textRenderer : TextRenderer.get(); - LinkedHashMap props = panel.toProps(); - UiRuntime baked = runtime.bake( - moduleHandle, - module, - "triangulator", - panel.treeSignature(), - panel.dataSignature(), - panel.layoutSignature(), - panel.width, - panel.height, - fallback, - panel.x, - panel.y, - panel.width, - panel.height, - () -> props, - panel::patches - ); - if (baked == null) return false; - baked.render(new UiRenderContext(renderer, fallback, ctx, tickDelta, UiProjectionMode.CURRENT)); - return true; + return ScriptedTriangulatorRenderer.render(moduleHandle, runtime, renderer, textRenderer, ctx, tickDelta, panel); } - private UiScriptModule ensureModule(Minecraft mc) { - if (!moduleHandle.ensureLoaded(mc.getResourceManager())) { - HudScriptLayouts.reportLoadError(moduleHandle); - return null; - } - moduleHandle.consumeChanged(); - return moduleHandle.module(); - } - - private static String string(Object value) { - return value instanceof String s ? s : ""; - } - - private static float floatValue(Object value) { - return value instanceof Number n ? n.floatValue() : 0.0f; - } - - private static void putPatch(LinkedHashMap> patches, - String key, - String prop, - Object value) { - LinkedHashMap patch = patches.get(key); - if (patch == null) { - patch = new LinkedHashMap<>(); - patches.put(key, patch); - } - patch.put(prop, value); - } public record Palette(int headerLeft, int headerRight, int bodyLeft, @@ -139,22 +79,7 @@ public final class ScriptedTriangulatorHudPanel { int warn, int danger) { LinkedHashMap toProps() { - LinkedHashMap out = new LinkedHashMap<>(); - out.put("headerLeft", hex(headerLeft)); - out.put("headerRight", hex(headerRight)); - out.put("bodyLeft", hex(bodyLeft)); - out.put("bodyRight", hex(bodyRight)); - out.put("outline", hex(outline)); - out.put("text", hex(text)); - out.put("muted", hex(muted)); - out.put("counter", hex(counter)); - out.put("titleText", hex(titleText)); - out.put("divider", hex(divider)); - out.put("blurTint", hex(blurTint)); - out.put("success", hex(success)); - out.put("warn", hex(warn)); - out.put("danger", hex(danger)); - return out; + return ScriptedTriangulatorProps.paletteProps(this); } } @@ -242,145 +167,23 @@ public final class ScriptedTriangulatorHudPanel { } LinkedHashMap toProps() { - LinkedHashMap out = new LinkedHashMap<>(); - out.put("id", "triangulator"); - out.put("title", "Triangulator"); - out.put("width", width); - out.put("height", height); - out.put("drawScale", drawScale); - out.put("baseScale", baseScale); - out.put("fontScale", fontScale); - out.put("headerTextHeight", headerTextHeight); - out.put("rowTextHeight", rowTextHeight); - out.put("countLabelWidth", countLabelWidth); - out.put("countValueWidth", countValueWidth); - out.put("activeCount", activeCount); - out.put("blur", blur); - out.put("blurAlpha", blurAlpha); - out.put("headerIcon", headerIcon); - out.put("headerIconColor", hex(headerIconColor)); - out.put("clearVisible", clearVisible); - out.put("clearIcon", "x"); - out.put("clearIconColor", hex(clearIconColor)); - out.put("copyVisible", copyVisible); - out.put("copyIcon", "clipboard"); - out.put("copyIconColor", hex(copyIconColor)); - out.put("statusText", statusText); - out.put("primaryLine", primaryLine); - out.put("secondaryLine", secondaryLine); - out.put("confidenceText", confidenceText); - out.put("statusColor", hex(statusColor)); - out.put("palette", palette.toProps()); - out.put("rows", rows.toArray()); - return out; + return ScriptedTriangulatorProps.panelProps(this); } long treeSignature() { - long h = 0xcbf29ce484222325L; - h = CachedUiScriptRuntime.mix(h, width); - h = CachedUiScriptRuntime.mix(h, height); - h = CachedUiScriptRuntime.mix(h, drawScale); - h = CachedUiScriptRuntime.mix(h, baseScale); - h = CachedUiScriptRuntime.mix(h, fontScale); - h = CachedUiScriptRuntime.mix(h, headerTextHeight); - h = CachedUiScriptRuntime.mix(h, rowTextHeight); - h = CachedUiScriptRuntime.mix(h, countLabelWidth); - h = CachedUiScriptRuntime.mix(h, countValueWidth); - h = CachedUiScriptRuntime.mix(h, blur); - h = CachedUiScriptRuntime.mix(h, blurAlpha); - h = CachedUiScriptRuntime.mix(h, clearVisible); - h = CachedUiScriptRuntime.mix(h, copyVisible); - h = CachedUiScriptRuntime.mix(h, String.valueOf(Math.max(0, activeCount)).length()); - h = CachedUiScriptRuntime.mix(h, activeCount); - h = CachedUiScriptRuntime.mix(h, statusText.length()); - h = CachedUiScriptRuntime.mix(h, primaryLine.length()); - h = CachedUiScriptRuntime.mix(h, secondaryLine.length()); - h = CachedUiScriptRuntime.mix(h, confidenceText.length()); - h = CachedUiScriptRuntime.mix(h, rows.size()); - for (LinkedHashMap row : rows) { - h = CachedUiScriptRuntime.mix(h, string(row.get("key"))); - h = CachedUiScriptRuntime.mix(h, string(row.get("label")).length()); - h = CachedUiScriptRuntime.mix(h, string(row.get("value")).length()); - h = CachedUiScriptRuntime.mix(h, Math.round(floatValue(row.get("alpha")) * 100.0f)); - } - return h; + return ScriptedTriangulatorSignatures.treeSignature(this); } long dataSignature() { - long h = 0xcbf29ce484222325L; - h = mixPalette(h); - h = CachedUiScriptRuntime.mix(h, activeCount); - h = CachedUiScriptRuntime.mix(h, headerIcon); - h = CachedUiScriptRuntime.mix(h, headerIconColor); - h = CachedUiScriptRuntime.mix(h, clearIconColor); - h = CachedUiScriptRuntime.mix(h, copyIconColor); - h = CachedUiScriptRuntime.mix(h, statusText); - h = CachedUiScriptRuntime.mix(h, primaryLine); - h = CachedUiScriptRuntime.mix(h, secondaryLine); - h = CachedUiScriptRuntime.mix(h, confidenceText); - h = CachedUiScriptRuntime.mix(h, statusColor); - for (LinkedHashMap row : rows) { - h = CachedUiScriptRuntime.mix(h, string(row.get("key"))); - h = CachedUiScriptRuntime.mix(h, string(row.get("label"))); - h = CachedUiScriptRuntime.mix(h, string(row.get("value"))); - h = CachedUiScriptRuntime.mix(h, string(row.get("labelColor"))); - h = CachedUiScriptRuntime.mix(h, string(row.get("valueColor"))); - h = CachedUiScriptRuntime.mix(h, string(row.get("markerColor"))); - h = CachedUiScriptRuntime.mix(h, string(row.get("dividerColor"))); - } - return h; + return ScriptedTriangulatorSignatures.dataSignature(this); } long layoutSignature() { - long h = 0xcbf29ce484222325L; - h = CachedUiScriptRuntime.mix(h, x); - h = CachedUiScriptRuntime.mix(h, y); - h = CachedUiScriptRuntime.mix(h, width); - h = CachedUiScriptRuntime.mix(h, height); - return h; + return ScriptedTriangulatorSignatures.layoutSignature(this); } LinkedHashMap> patches() { - LinkedHashMap> patches = new LinkedHashMap<>(); - putPatch(patches, "header:count-value", "text", String.valueOf(Math.max(0, activeCount))); - putPatch(patches, "header:icon", "tint", hex(headerIconColor)); - putPatch(patches, "clear:icon", "tint", hex(clearIconColor)); - putPatch(patches, "copy:icon", "tint", hex(copyIconColor)); - putPatch(patches, "summary:status", "text", statusText); - putPatch(patches, "summary:status", "color", hex(statusColor)); - putPatch(patches, "summary:primary", "text", primaryLine); - putPatch(patches, "summary:secondary", "text", secondaryLine); - putPatch(patches, "summary:confidence", "text", confidenceText); - putPatch(patches, "summary:confidence", "color", hex(statusColor)); - for (LinkedHashMap row : rows) { - String key = string(row.get("key")); - String prefix = "row:" + key; - putPatch(patches, prefix + ":marker", "fill", string(row.get("markerColor"))); - putPatch(patches, prefix + ":divider", "fill", string(row.get("dividerColor"))); - putPatch(patches, prefix + ":label", "text", string(row.get("label"))); - putPatch(patches, prefix + ":label", "color", string(row.get("labelColor"))); - putPatch(patches, prefix + ":value", "text", string(row.get("value"))); - putPatch(patches, prefix + ":value", "color", string(row.get("valueColor"))); - } - return patches; - } - - private long mixPalette(long h) { - h = CachedUiScriptRuntime.mix(h, palette.headerLeft); - h = CachedUiScriptRuntime.mix(h, palette.headerRight); - h = CachedUiScriptRuntime.mix(h, palette.bodyLeft); - h = CachedUiScriptRuntime.mix(h, palette.bodyRight); - h = CachedUiScriptRuntime.mix(h, palette.outline); - h = CachedUiScriptRuntime.mix(h, palette.text); - h = CachedUiScriptRuntime.mix(h, palette.muted); - h = CachedUiScriptRuntime.mix(h, palette.counter); - h = CachedUiScriptRuntime.mix(h, palette.titleText); - h = CachedUiScriptRuntime.mix(h, palette.divider); - h = CachedUiScriptRuntime.mix(h, palette.blurTint); - h = CachedUiScriptRuntime.mix(h, palette.success); - h = CachedUiScriptRuntime.mix(h, palette.warn); - h = CachedUiScriptRuntime.mix(h, palette.danger); - return h; + return ScriptedTriangulatorSignatures.patches(this); } } } diff --git a/mod/src/main/java/dev/loki/lovisual/features/gui/hud/draggable/impl/scripted/ScriptedTriangulatorRenderer.java b/mod/src/main/java/dev/loki/lovisual/features/gui/hud/draggable/impl/scripted/ScriptedTriangulatorRenderer.java new file mode 100644 index 0000000..c40c77a --- /dev/null +++ b/mod/src/main/java/dev/loki/lovisual/features/gui/hud/draggable/impl/scripted/ScriptedTriangulatorRenderer.java @@ -0,0 +1,75 @@ +package dev.loki.lovisual.features.gui.hud.draggable.impl.scripted; + +import java.util.LinkedHashMap; +import dev.loki.lovisual.features.gui.hud.script.HudScriptLayouts; +import dev.loki.lovisual.render.engine.renderer.Renderer2D; +import dev.loki.lovisual.render.engine.renderer.ui.runtime.core.runtime.UiRuntime; +import dev.loki.lovisual.render.engine.renderer.ui.runtime.render.context.UiProjectionMode; +import dev.loki.lovisual.render.engine.renderer.ui.runtime.render.context.UiRenderContext; +import dev.loki.lovisual.render.engine.renderer.ui.runtime.script.runtime.CachedUiScriptRuntime; +import dev.loki.lovisual.render.engine.renderer.ui.runtime.script.module.UiScriptModule; +import dev.loki.lovisual.render.engine.renderer.ui.runtime.script.module.UiScriptModuleHandle; +import dev.loki.lovisual.render.engine.text.render.TextRenderer; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphicsExtractor; + +/** + * Bakes and draws the triangulator HUD script layout for a panel. + */ +public final class ScriptedTriangulatorRenderer { + + private ScriptedTriangulatorRenderer() { + } + + public static boolean render(UiScriptModuleHandle moduleHandle, + CachedUiScriptRuntime runtime, + Renderer2D renderer, + TextRenderer textRenderer, + GuiGraphicsExtractor ctx, + float tickDelta, + ScriptedTriangulatorHudPanel.Panel panel) { + if (renderer == null || panel == null || panel.width() <= 0.0f || panel.height() <= 0.0f) return false; + Minecraft mc = Minecraft.getInstance(); + if (mc == null || mc.getResourceManager() == null) return false; + + HudScriptLayouts.pollReloadCombo(mc); + if (moduleHandle.consumeChanged()) { + runtime.reset(); + } + + UiScriptModule module = ensureModule(moduleHandle, mc); + if (module == null) return false; + + TextRenderer fallback = textRenderer != null ? textRenderer : TextRenderer.get(); + LinkedHashMap props = panel.toProps(); + UiRuntime baked = runtime.bake( + moduleHandle, + module, + "triangulator", + panel.treeSignature(), + panel.dataSignature(), + panel.layoutSignature(), + panel.width(), + panel.height(), + fallback, + panel.x(), + panel.y(), + panel.width(), + panel.height(), + () -> props, + panel::patches + ); + if (baked == null) return false; + baked.render(new UiRenderContext(renderer, fallback, ctx, tickDelta, UiProjectionMode.CURRENT)); + return true; + } + + private static UiScriptModule ensureModule(UiScriptModuleHandle moduleHandle, Minecraft mc) { + if (!moduleHandle.ensureLoaded(mc.getResourceManager())) { + HudScriptLayouts.reportLoadError(moduleHandle); + return null; + } + moduleHandle.consumeChanged(); + return moduleHandle.module(); + } +} diff --git a/mod/src/main/java/dev/loki/lovisual/features/gui/hud/draggable/impl/scripted/panel/ScriptedTriangulatorProps.java b/mod/src/main/java/dev/loki/lovisual/features/gui/hud/draggable/impl/scripted/panel/ScriptedTriangulatorProps.java new file mode 100644 index 0000000..c2c2911 --- /dev/null +++ b/mod/src/main/java/dev/loki/lovisual/features/gui/hud/draggable/impl/scripted/panel/ScriptedTriangulatorProps.java @@ -0,0 +1,71 @@ +package dev.loki.lovisual.features.gui.hud.draggable.impl.scripted.panel; + +import java.util.LinkedHashMap; +import dev.loki.lovisual.features.gui.hud.draggable.impl.scripted.ScriptedTriangulatorHudPanel; + +/** + * Script prop maps for the triangulator HUD: palette and panel records are + * converted to the property bags the UI script runtime consumes. + */ +public final class ScriptedTriangulatorProps { + + private ScriptedTriangulatorProps() { + } + + public static String hex(int argb) { + return String.format("#%08X", argb); + } + + public static LinkedHashMap paletteProps(ScriptedTriangulatorHudPanel.Palette palette) { + LinkedHashMap out = new LinkedHashMap<>(); + out.put("headerLeft", hex(palette.headerLeft())); + out.put("headerRight", hex(palette.headerRight())); + out.put("bodyLeft", hex(palette.bodyLeft())); + out.put("bodyRight", hex(palette.bodyRight())); + out.put("outline", hex(palette.outline())); + out.put("text", hex(palette.text())); + out.put("muted", hex(palette.muted())); + out.put("counter", hex(palette.counter())); + out.put("titleText", hex(palette.titleText())); + out.put("divider", hex(palette.divider())); + out.put("blurTint", hex(palette.blurTint())); + out.put("success", hex(palette.success())); + out.put("warn", hex(palette.warn())); + out.put("danger", hex(palette.danger())); + return out; + } + + public static LinkedHashMap panelProps(ScriptedTriangulatorHudPanel.Panel panel) { + LinkedHashMap out = new LinkedHashMap<>(); + out.put("id", "triangulator"); + out.put("title", "Triangulator"); + out.put("width", panel.width()); + out.put("height", panel.height()); + out.put("drawScale", panel.drawScale()); + out.put("baseScale", panel.baseScale()); + out.put("fontScale", panel.fontScale()); + out.put("headerTextHeight", panel.headerTextHeight()); + out.put("rowTextHeight", panel.rowTextHeight()); + out.put("countLabelWidth", panel.countLabelWidth()); + out.put("countValueWidth", panel.countValueWidth()); + out.put("activeCount", panel.activeCount()); + out.put("blur", panel.blur()); + out.put("blurAlpha", panel.blurAlpha()); + out.put("headerIcon", panel.headerIcon()); + out.put("headerIconColor", hex(panel.headerIconColor())); + out.put("clearVisible", panel.clearVisible()); + out.put("clearIcon", "x"); + out.put("clearIconColor", hex(panel.clearIconColor())); + out.put("copyVisible", panel.copyVisible()); + out.put("copyIcon", "clipboard"); + out.put("copyIconColor", hex(panel.copyIconColor())); + out.put("statusText", panel.statusText()); + out.put("primaryLine", panel.primaryLine()); + out.put("secondaryLine", panel.secondaryLine()); + out.put("confidenceText", panel.confidenceText()); + out.put("statusColor", hex(panel.statusColor())); + out.put("palette", paletteProps(panel.palette())); + out.put("rows", panel.rows().toArray()); + return out; + } +} diff --git a/mod/src/main/java/dev/loki/lovisual/features/gui/hud/draggable/impl/scripted/panel/ScriptedTriangulatorSignatures.java b/mod/src/main/java/dev/loki/lovisual/features/gui/hud/draggable/impl/scripted/panel/ScriptedTriangulatorSignatures.java new file mode 100644 index 0000000..640d0ec --- /dev/null +++ b/mod/src/main/java/dev/loki/lovisual/features/gui/hud/draggable/impl/scripted/panel/ScriptedTriangulatorSignatures.java @@ -0,0 +1,143 @@ +package dev.loki.lovisual.features.gui.hud.draggable.impl.scripted.panel; + +import java.util.LinkedHashMap; +import dev.loki.lovisual.features.gui.hud.draggable.impl.scripted.ScriptedTriangulatorHudPanel; +import dev.loki.lovisual.render.engine.renderer.ui.runtime.script.runtime.CachedUiScriptRuntime; + +/** + * Cache signatures and element patches for the triangulator HUD panel. + * Signatures decide whether the baked UI script needs a rebuild. + */ +public final class ScriptedTriangulatorSignatures { + + private ScriptedTriangulatorSignatures() { + } + + public static long treeSignature(ScriptedTriangulatorHudPanel.Panel panel) { + long h = 0xcbf29ce484222325L; + h = CachedUiScriptRuntime.mix(h, panel.width()); + h = CachedUiScriptRuntime.mix(h, panel.height()); + h = CachedUiScriptRuntime.mix(h, panel.drawScale()); + h = CachedUiScriptRuntime.mix(h, panel.baseScale()); + h = CachedUiScriptRuntime.mix(h, panel.fontScale()); + h = CachedUiScriptRuntime.mix(h, panel.headerTextHeight()); + h = CachedUiScriptRuntime.mix(h, panel.rowTextHeight()); + h = CachedUiScriptRuntime.mix(h, panel.countLabelWidth()); + h = CachedUiScriptRuntime.mix(h, panel.countValueWidth()); + h = CachedUiScriptRuntime.mix(h, panel.blur()); + h = CachedUiScriptRuntime.mix(h, panel.blurAlpha()); + h = CachedUiScriptRuntime.mix(h, panel.clearVisible()); + h = CachedUiScriptRuntime.mix(h, panel.copyVisible()); + h = CachedUiScriptRuntime.mix(h, String.valueOf(Math.max(0, panel.activeCount())).length()); + h = CachedUiScriptRuntime.mix(h, panel.activeCount()); + h = CachedUiScriptRuntime.mix(h, panel.statusText().length()); + h = CachedUiScriptRuntime.mix(h, panel.primaryLine().length()); + h = CachedUiScriptRuntime.mix(h, panel.secondaryLine().length()); + h = CachedUiScriptRuntime.mix(h, panel.confidenceText().length()); + h = CachedUiScriptRuntime.mix(h, panel.rows().size()); + for (LinkedHashMap row : panel.rows()) { + h = CachedUiScriptRuntime.mix(h, string(row.get("key"))); + h = CachedUiScriptRuntime.mix(h, string(row.get("label")).length()); + h = CachedUiScriptRuntime.mix(h, string(row.get("value")).length()); + h = CachedUiScriptRuntime.mix(h, Math.round(floatValue(row.get("alpha")) * 100.0f)); + } + return h; + } + + public static long dataSignature(ScriptedTriangulatorHudPanel.Panel panel) { + long h = 0xcbf29ce484222325L; + h = mixPalette(h, panel.palette()); + h = CachedUiScriptRuntime.mix(h, panel.activeCount()); + h = CachedUiScriptRuntime.mix(h, panel.headerIcon()); + h = CachedUiScriptRuntime.mix(h, panel.headerIconColor()); + h = CachedUiScriptRuntime.mix(h, panel.clearIconColor()); + h = CachedUiScriptRuntime.mix(h, panel.copyIconColor()); + h = CachedUiScriptRuntime.mix(h, panel.statusText()); + h = CachedUiScriptRuntime.mix(h, panel.primaryLine()); + h = CachedUiScriptRuntime.mix(h, panel.secondaryLine()); + h = CachedUiScriptRuntime.mix(h, panel.confidenceText()); + h = CachedUiScriptRuntime.mix(h, panel.statusColor()); + for (LinkedHashMap row : panel.rows()) { + h = CachedUiScriptRuntime.mix(h, string(row.get("key"))); + h = CachedUiScriptRuntime.mix(h, string(row.get("label"))); + h = CachedUiScriptRuntime.mix(h, string(row.get("value"))); + h = CachedUiScriptRuntime.mix(h, string(row.get("labelColor"))); + h = CachedUiScriptRuntime.mix(h, string(row.get("valueColor"))); + h = CachedUiScriptRuntime.mix(h, string(row.get("markerColor"))); + h = CachedUiScriptRuntime.mix(h, string(row.get("dividerColor"))); + } + return h; + } + + public static long layoutSignature(ScriptedTriangulatorHudPanel.Panel panel) { + long h = 0xcbf29ce484222325L; + h = CachedUiScriptRuntime.mix(h, panel.x()); + h = CachedUiScriptRuntime.mix(h, panel.y()); + h = CachedUiScriptRuntime.mix(h, panel.width()); + h = CachedUiScriptRuntime.mix(h, panel.height()); + return h; + } + + public static LinkedHashMap> patches(ScriptedTriangulatorHudPanel.Panel panel) { + LinkedHashMap> patches = new LinkedHashMap<>(); + putPatch(patches, "header:count-value", "text", String.valueOf(Math.max(0, panel.activeCount()))); + putPatch(patches, "header:icon", "tint", ScriptedTriangulatorProps.hex(panel.headerIconColor())); + putPatch(patches, "clear:icon", "tint", ScriptedTriangulatorProps.hex(panel.clearIconColor())); + putPatch(patches, "copy:icon", "tint", ScriptedTriangulatorProps.hex(panel.copyIconColor())); + putPatch(patches, "summary:status", "text", panel.statusText()); + putPatch(patches, "summary:status", "color", ScriptedTriangulatorProps.hex(panel.statusColor())); + putPatch(patches, "summary:primary", "text", panel.primaryLine()); + putPatch(patches, "summary:secondary", "text", panel.secondaryLine()); + putPatch(patches, "summary:confidence", "text", panel.confidenceText()); + putPatch(patches, "summary:confidence", "color", ScriptedTriangulatorProps.hex(panel.statusColor())); + for (LinkedHashMap row : panel.rows()) { + String key = string(row.get("key")); + String prefix = "row:" + key; + putPatch(patches, prefix + ":marker", "fill", string(row.get("markerColor"))); + putPatch(patches, prefix + ":divider", "fill", string(row.get("dividerColor"))); + putPatch(patches, prefix + ":label", "text", string(row.get("label"))); + putPatch(patches, prefix + ":label", "color", string(row.get("labelColor"))); + putPatch(patches, prefix + ":value", "text", string(row.get("value"))); + putPatch(patches, prefix + ":value", "color", string(row.get("valueColor"))); + } + return patches; + } + + private static long mixPalette(long h, ScriptedTriangulatorHudPanel.Palette palette) { + h = CachedUiScriptRuntime.mix(h, palette.headerLeft()); + h = CachedUiScriptRuntime.mix(h, palette.headerRight()); + h = CachedUiScriptRuntime.mix(h, palette.bodyLeft()); + h = CachedUiScriptRuntime.mix(h, palette.bodyRight()); + h = CachedUiScriptRuntime.mix(h, palette.outline()); + h = CachedUiScriptRuntime.mix(h, palette.text()); + h = CachedUiScriptRuntime.mix(h, palette.muted()); + h = CachedUiScriptRuntime.mix(h, palette.counter()); + h = CachedUiScriptRuntime.mix(h, palette.titleText()); + h = CachedUiScriptRuntime.mix(h, palette.divider()); + h = CachedUiScriptRuntime.mix(h, palette.blurTint()); + h = CachedUiScriptRuntime.mix(h, palette.success()); + h = CachedUiScriptRuntime.mix(h, palette.warn()); + h = CachedUiScriptRuntime.mix(h, palette.danger()); + return h; + } + + private static String string(Object value) { + return value instanceof String s ? s : ""; + } + + private static float floatValue(Object value) { + return value instanceof Number n ? n.floatValue() : 0.0f; + } + + private static void putPatch(LinkedHashMap> patches, + String key, + String prop, + Object value) { + LinkedHashMap patch = patches.get(key); + if (patch == null) { + patch = new LinkedHashMap<>(); + patches.put(key, patch); + } + patch.put(prop, value); + } +}