fix: component port labels showing wrong name after editing blueprint
The label lookup in drawComponentGate read from gate.component (potentially stale copy) while gateOutputCount read from state.customComponents (updated definition), causing a mismatch — fewer ports but old outputIds, so the first (deleted) output's label was shown instead of the surviving one. Three fixes: - renderer: use customComponents as authoritative source for label lookup - saveLoad: re-link gate.component refs to customComponents after loading - components: update existing instances even when a "new" component overwrites an existing definition with the same name Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -285,12 +285,15 @@ export function exitComponentEditor(name, shouldSave) {
|
|||||||
// Save the component (works for both new and edited)
|
// Save the component (works for both new and edited)
|
||||||
const result = saveComponentFromCircuit(name);
|
const result = saveComponentFromCircuit(name);
|
||||||
|
|
||||||
// If editing an existing component, update all placed instances in the main circuit
|
// Update all placed instances of this component in the main circuit.
|
||||||
if (editingId && result.success && state.savedMainCircuit) {
|
// Handles both: editing existing component (editingId matches) AND
|
||||||
|
// creating a "new" component that overwrites an existing one (same sanitized name).
|
||||||
|
if (result.success && state.savedMainCircuit) {
|
||||||
const updatedComp = state.customComponents[result.component.id];
|
const updatedComp = state.customComponents[result.component.id];
|
||||||
if (updatedComp) {
|
if (updatedComp) {
|
||||||
|
const matchId = editingId || result.component.id;
|
||||||
for (const gate of state.savedMainCircuit.gates) {
|
for (const gate of state.savedMainCircuit.gates) {
|
||||||
if (gate.component && gate.component.id === editingId) {
|
if (gate.component && gate.component.id === matchId) {
|
||||||
gate.component = updatedComp;
|
gate.component = updatedComp;
|
||||||
// Clear persisted internal state so it re-initializes from updated blueprint
|
// Clear persisted internal state so it re-initializes from updated blueprint
|
||||||
delete gate._internalGates;
|
delete gate._internalGates;
|
||||||
|
|||||||
@@ -325,8 +325,10 @@ function drawComponentGate(gate) {
|
|||||||
ctx.fillStyle = '#444';
|
ctx.fillStyle = '#444';
|
||||||
ctx.fillText(getGateLabel(gate), gate.x + w / 2, gate.y + h - 6);
|
ctx.fillText(getGateLabel(gate), gate.x + w / 2, gate.y + h - 6);
|
||||||
|
|
||||||
// Get port labels from the component definition
|
// Get port labels from the authoritative component definition (customComponents)
|
||||||
const comp = gate.component;
|
// This must match the source used by gateOutputCount/gateInputCount for port counts
|
||||||
|
const compId = gate.type.substring(10);
|
||||||
|
const comp = state.customComponents?.[compId] || gate.component;
|
||||||
const inputLabels = [];
|
const inputLabels = [];
|
||||||
const outputLabels = [];
|
const outputLabels = [];
|
||||||
if (comp) {
|
if (comp) {
|
||||||
|
|||||||
@@ -56,6 +56,16 @@ export function loadState(data) {
|
|||||||
state.customComponents = JSON.parse(JSON.stringify(data.components));
|
state.customComponents = JSON.parse(JSON.stringify(data.components));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Re-link gate.component references to customComponents (authoritative source)
|
||||||
|
for (const gate of state.gates) {
|
||||||
|
if (gate.type.startsWith('COMPONENT:')) {
|
||||||
|
const compId = gate.type.substring(10);
|
||||||
|
if (state.customComponents[compId]) {
|
||||||
|
gate.component = state.customComponents[compId];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Load progress
|
// Load progress
|
||||||
if (data.progress) {
|
if (data.progress) {
|
||||||
progress.unlockedLevels = data.progress.unlockedLevels || ['buffer'];
|
progress.unlockedLevels = data.progress.unlockedLevels || ['buffer'];
|
||||||
|
|||||||
Reference in New Issue
Block a user