Skip to content

Commit e54d696

Browse files
committed
Updates jump correctly
1 parent 1b55055 commit e54d696

File tree

1 file changed

+101
-16
lines changed

1 file changed

+101
-16
lines changed

src/blocks/mrc_steps.ts

Lines changed: 101 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { Order } from 'blockly/python';
2525
import { MRC_STYLE_STEPS } from '../themes/styles';
2626
import { ExtendedPythonGenerator } from '../editor/extended_python_generator';
2727
import { createStepFieldFlydown } from '../fields/field_flydown';
28+
import { BLOCK_NAME as MRC_JUMP_TO_STEP } from './mrc_jump_to_step';
2829
import * as stepContainer from './mrc_step_container'
2930

3031
export const BLOCK_NAME = 'mrc_steps';
@@ -76,11 +77,27 @@ const STEPS = {
7677
const stepContainerBlock = containerBlock as stepContainer.StepContainerBlock;
7778
const stepItemBlocks: stepContainer.StepItemBlock[] = stepContainerBlock.getStepItemBlocks();
7879

80+
const oldStepNames = [...this.mrcStepNames];
7981
this.mrcStepNames = [];
8082
stepItemBlocks.forEach((stepItemBlock) => {
8183
this.mrcStepNames.push(stepItemBlock.getName());
8284
});
83-
// TODO: Update any jump blocks to have the correct name
85+
86+
// Update jump blocks for any renamed steps
87+
const workspace = this.workspace;
88+
const jumpBlocks = workspace.getBlocksByType(MRC_JUMP_TO_STEP, false);
89+
stepItemBlocks.forEach((stepItemBlock, index) => {
90+
const oldName = stepItemBlock.getOriginalName();
91+
const newName = stepItemBlock.getName();
92+
if (oldName && oldName !== newName) {
93+
jumpBlocks.forEach((jumpBlock) => {
94+
if (jumpBlock.getFieldValue('STEP_NAME') === oldName) {
95+
jumpBlock.setFieldValue(newName, 'STEP_NAME');
96+
}
97+
});
98+
}
99+
});
100+
84101
this.updateShape_();
85102
},
86103
decompose: function (this: StepsBlock, workspace: Blockly.Workspace) {
@@ -100,6 +117,7 @@ const STEPS = {
100117

101118
},
102119
mrcUpdateStepName: function (this: StepsBlock, step: number, newName: string): string {
120+
const oldName = this.mrcStepNames[step];
103121
const otherNames = this.mrcStepNames.filter((_name, index) => index !== step);
104122
let currentName = newName;
105123

@@ -118,29 +136,96 @@ const STEPS = {
118136
}
119137
}
120138
this.mrcStepNames[step] = currentName;
121-
// TODO: Rename any jump blocks that refer to this step
122-
139+
140+
// Update all mrc_jump_to_step blocks that reference the old name
141+
if (oldName !== currentName) {
142+
const workspace = this.workspace;
143+
const jumpBlocks = workspace.getBlocksByType(MRC_JUMP_TO_STEP, false);
144+
jumpBlocks.forEach((jumpBlock) => {
145+
if (jumpBlock.getFieldValue('STEP_NAME') === oldName) {
146+
jumpBlock.setFieldValue(currentName, 'STEP_NAME');
147+
}
148+
});
149+
}
123150

124151
return currentName;
125152
},
126153
updateShape_: function (this: StepsBlock): void {
127-
// some way of knowing what was there before and what is there now
128-
let success = true;
154+
// Build a map of step names to their current input indices
155+
const currentStepMap: { [stepName: string]: number } = {};
129156
let i = 0;
130-
while (success) {
131-
success = this.removeInput('CONDITION_' + i, true);
132-
success = this.removeInput('STEP_' + i, true);
157+
while (this.getInput('CONDITION_' + i)) {
158+
const conditionInput = this.getInput('CONDITION_' + i);
159+
const field = conditionInput?.fieldRow[0];
160+
if (field) {
161+
currentStepMap[field.getValue()] = i;
162+
}
133163
i++;
134164
}
165+
166+
// For each new step position, find where it currently is (if it exists)
135167
for (let j = 0; j < this.mrcStepNames.length; j++) {
136-
const fieldFlydown = createStepFieldFlydown(this.mrcStepNames[j], true);
137-
138-
fieldFlydown.setValidator(this.mrcUpdateStepName.bind(this, j));
139-
this.appendValueInput('CONDITION_' + j)
140-
.appendField(fieldFlydown)
141-
.setCheck('Boolean')
142-
.appendField(Blockly.Msg.REPEAT_UNTIL);
143-
this.appendStatementInput('STEP_' + j);
168+
const stepName = this.mrcStepNames[j];
169+
const currentIndex = currentStepMap[stepName];
170+
171+
if (currentIndex !== undefined && currentIndex !== j) {
172+
// Step exists but is at wrong position - move it
173+
const conditionConnection = this.getInput('CONDITION_' + currentIndex)?.connection?.targetConnection;
174+
const stepConnection = this.getInput('STEP_' + currentIndex)?.connection?.targetConnection;
175+
176+
// Temporarily disconnect
177+
if (conditionConnection) conditionConnection.disconnect();
178+
if (stepConnection) stepConnection.disconnect();
179+
180+
// Remove old inputs
181+
this.removeInput('CONDITION_' + currentIndex, false);
182+
this.removeInput('STEP_' + currentIndex, false);
183+
184+
// Create new inputs at correct position
185+
const fieldFlydown = createStepFieldFlydown(stepName, true);
186+
fieldFlydown.setValidator(this.mrcUpdateStepName.bind(this, j));
187+
188+
this.appendValueInput('CONDITION_' + j)
189+
.appendField(fieldFlydown)
190+
.setCheck('Boolean')
191+
.appendField(Blockly.Msg.REPEAT_UNTIL);
192+
this.appendStatementInput('STEP_' + j);
193+
194+
// Reconnect
195+
if (conditionConnection) {
196+
this.getInput('CONDITION_' + j)?.connection?.connect(conditionConnection);
197+
}
198+
if (stepConnection) {
199+
this.getInput('STEP_' + j)?.connection?.connect(stepConnection);
200+
}
201+
202+
delete currentStepMap[stepName];
203+
} else if (currentIndex !== undefined) {
204+
// Step is at correct position - just update the field
205+
const conditionInput = this.getInput('CONDITION_' + j);
206+
const field = conditionInput?.fieldRow[0];
207+
if (field && field.getValue() !== stepName) {
208+
field.setValue(stepName);
209+
}
210+
delete currentStepMap[stepName];
211+
} else {
212+
// Step doesn't exist - create it
213+
const fieldFlydown = createStepFieldFlydown(stepName, true);
214+
fieldFlydown.setValidator(this.mrcUpdateStepName.bind(this, j));
215+
216+
this.appendValueInput('CONDITION_' + j)
217+
.appendField(fieldFlydown)
218+
.setCheck('Boolean')
219+
.appendField(Blockly.Msg.REPEAT_UNTIL);
220+
this.appendStatementInput('STEP_' + j);
221+
}
222+
}
223+
224+
// Remove any leftover inputs (steps that were deleted)
225+
for (const stepName in currentStepMap) {
226+
const index = currentStepMap[stepName];
227+
this.removeInput('CONDITION_' + index, false);
228+
this.removeInput('STEP_' + index, false);
144229
}
145230
},
146231
mrcGetStepNames: function (this: StepsBlock): string[] {

0 commit comments

Comments
 (0)