From 800256298798396a9cd6c5af74f93b75afebc275 Mon Sep 17 00:00:00 2001 From: Liz Looney Date: Sat, 22 Nov 2025 13:48:37 -0800 Subject: [PATCH 1/2] Update MechanismBlock.checkMechanism to update port blocks. If necessary, existing port blocks are reconnected to the appropriate input and new port blocks are created for empty input sockets. --- src/blocks/mrc_mechanism.ts | 92 ++++++++++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) diff --git a/src/blocks/mrc_mechanism.ts b/src/blocks/mrc_mechanism.ts index fe42fe38..e9fac644 100644 --- a/src/blocks/mrc_mechanism.ts +++ b/src/blocks/mrc_mechanism.ts @@ -285,7 +285,23 @@ const MECHANISM = { if (this.mrcImportModule !== importModule) { this.mrcImportModule = importModule; } + + // Save the old parameters and the blocks that are connected to their sockets. + const oldParameters: Parameter[] = []; + const oldConnectedBlocks: (Blockly.Block | null)[] = []; + for (let i = 0; i < this.mrcParameters.length; i++) { + oldParameters[i] = this.mrcParameters[i]; + const argInput = this.getInput('ARG' + i); + if (argInput && argInput.connection && argInput.connection.targetBlock()) { + oldConnectedBlocks[i] = argInput.connection.targetBlock(); + } else { + oldConnectedBlocks[i] = null; + } + } + + // Regenerate mrc_parameters and create new inputs if necessary. this.mrcParameters = []; + let i = 0; components.forEach(component => { let componentPortsIndex = 0; for (const port in component.ports) { @@ -295,10 +311,84 @@ const MECHANISM = { componentId: component.componentId, componentPortsIndex, }); + let argInput = this.getInput('ARG' + i); + const argField = this.getField('ARGNAME' + i); + if (argInput && argField) { + argField.setValue(port); + } else { + // Add new input. + argInput = this.appendValueInput('ARG' + i) + .setAlign(Blockly.inputs.Align.RIGHT) + .appendField(port, 'ARGNAME' + i); + } + // Look in oldParameters to find the matching parameter. + let foundOldParameterIndex = -1; + for (let j = 0; j < oldParameters.length; j++) { + if (oldParameters[j].componentId === this.mrcParameters[i].componentId && + oldParameters[j].componentPortsIndex === this.mrcParameters[i].componentPortsIndex) { + foundOldParameterIndex = j; + break; + } + } + if (foundOldParameterIndex !== -1) { + if (foundOldParameterIndex === i) { + // The old connected block is already connected to this input. + oldConnectedBlocks[foundOldParameterIndex] = null; + } else { + // Move the old connected block to this input. + const oldConnectedBlock = oldConnectedBlocks[foundOldParameterIndex]; + if (oldConnectedBlock && oldConnectedBlock.outputConnection && argInput.connection) { + argInput.connection.connect(oldConnectedBlock.outputConnection); + oldConnectedBlocks[foundOldParameterIndex] = null; + } + } + } + argInput.setCheck(getAllowedTypesForSetCheck(this.mrcParameters[i].type)); + componentPortsIndex++; + i++; } }); - this.updateBlock_(); + + // Remove deleted inputs. + for (let i = this.mrcParameters.length; this.getInput('ARG' + i); i++) { + this.removeInput('ARG' + i); + } + + // Remove old blocks that are no longer connected to input sockets. + for (let i = 0; i < oldConnectedBlocks.length; i++) { + const oldConnectedBlock = oldConnectedBlocks[i]; + if (oldConnectedBlock && oldConnectedBlock.outputConnection) { + if (!oldConnectedBlock.outputConnection.isConnected()) { + oldConnectedBlock.dispose(); + } + } + } + + // Add port blocks to any empty inputs. + for (let i = 0; i < this.mrcParameters.length; i++) { + let argInput = this.getInput('ARG' + i); + if (argInput && argInput.connection && !argInput.connection.targetBlock()) { + // The input is empty. Create a port block and connect it to the input. + const portBlockState = createPort(this.mrcParameters[i].type); + const portBlock = this.workspace.newBlock(portBlockState.type) as Blockly.BlockSvg; + if (portBlockState.extraState && portBlock.loadExtraState) { + portBlock.loadExtraState(portBlockState.extraState); + } + if (portBlockState.fields) { + const keys = Object.keys(portBlockState.fields); + for (let i = 0; i < keys.length; i++) { + const fieldName = keys[i]; + const field = portBlock.getField(fieldName); + if (field) { + field.loadState(portBlockState.fields[fieldName]); + } + } + } + portBlock.initSvg(); + argInput.connection.connect(portBlock.outputConnection); + } + } } else { // Did not find the mechanism. warnings.push(Blockly.Msg['MECHANISM_NOT_FOUND_WARNING']); From 2fd57df396f751eb5a8d691b83fe5d3216700149 Mon Sep 17 00:00:00 2001 From: Liz Looney Date: Sun, 23 Nov 2025 20:58:00 -0800 Subject: [PATCH 2/2] Rename i parametersIndex. --- src/blocks/mrc_mechanism.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/blocks/mrc_mechanism.ts b/src/blocks/mrc_mechanism.ts index dab2d1af..5ebbfd6b 100644 --- a/src/blocks/mrc_mechanism.ts +++ b/src/blocks/mrc_mechanism.ts @@ -301,7 +301,7 @@ const MECHANISM = { // Regenerate mrc_parameters and create new inputs if necessary. this.mrcParameters = []; - let i = 0; + let parametersIndex = 0; components.forEach(component => { let componentPortsIndex = 0; for (const port in component.ports) { @@ -311,27 +311,27 @@ const MECHANISM = { componentId: component.componentId, componentPortsIndex, }); - let argInput = this.getInput('ARG' + i); - const argField = this.getField('ARGNAME' + i); + let argInput = this.getInput('ARG' + parametersIndex); + const argField = this.getField('ARGNAME' + parametersIndex); if (argInput && argField) { argField.setValue(port); } else { // Add new input. - argInput = this.appendValueInput('ARG' + i) + argInput = this.appendValueInput('ARG' + parametersIndex) .setAlign(Blockly.inputs.Align.RIGHT) - .appendField(port, 'ARGNAME' + i); + .appendField(port, 'ARGNAME' + parametersIndex); } // Look in oldParameters to find the matching parameter. let foundOldParameterIndex = -1; for (let j = 0; j < oldParameters.length; j++) { - if (oldParameters[j].componentId === this.mrcParameters[i].componentId && - oldParameters[j].componentPortsIndex === this.mrcParameters[i].componentPortsIndex) { + if (oldParameters[j].componentId === this.mrcParameters[parametersIndex].componentId && + oldParameters[j].componentPortsIndex === this.mrcParameters[parametersIndex].componentPortsIndex) { foundOldParameterIndex = j; break; } } if (foundOldParameterIndex !== -1) { - if (foundOldParameterIndex === i) { + if (foundOldParameterIndex === parametersIndex) { // The old connected block is already connected to this input. oldConnectedBlocks[foundOldParameterIndex] = null; } else { @@ -343,10 +343,10 @@ const MECHANISM = { } } } - argInput.setCheck(getAllowedTypesForSetCheck(this.mrcParameters[i].type)); + argInput.setCheck(getAllowedTypesForSetCheck(this.mrcParameters[parametersIndex].type)); componentPortsIndex++; - i++; + parametersIndex++; } });