Skip to content

Commit 92b3ec7

Browse files
authored
Merge pull request wpilibsuite#17 from lizlooney/pr_try_steps_block
Addressed most of my comments on PR 291
2 parents 2d53e0b + dfd03a4 commit 92b3ec7

File tree

2 files changed

+60
-42
lines changed

2 files changed

+60
-42
lines changed

src/blocks/mrc_steps.ts

Lines changed: 58 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,14 @@ import { ExtendedPythonGenerator } from '../editor/extended_python_generator';
2727
import { createStepFieldFlydown } from '../fields/field_flydown';
2828
import { BLOCK_NAME as MRC_JUMP_TO_STEP } from './mrc_jump_to_step';
2929
import * as stepContainer from './mrc_step_container'
30+
import * as value from './utils/value';
31+
import * as toolboxItems from '../toolbox/items';
3032

3133
export const BLOCK_NAME = 'mrc_steps';
3234

35+
const INPUT_CONDITION_PREFIX = 'CONDITION_';
36+
const INPUT_STEP_PREFIX = 'STEP_';
37+
3338
/** Extra state for serialising mrc_steps blocks. */
3439
type StepsExtraState = {
3540
/**
@@ -49,7 +54,7 @@ const STEPS = {
4954
* Block initialization.
5055
*/
5156
init: function (this: StepsBlock): void {
52-
this.mrcStepNames = ["0"];
57+
this.mrcStepNames = [];
5358
this.appendDummyInput()
5459
.appendField(Blockly.Msg.STEPS);
5560
this.setInputsInline(false);
@@ -63,10 +68,8 @@ const STEPS = {
6368
};
6469
},
6570
loadExtraState: function (this: StepsBlock, state: StepsExtraState): void {
66-
if (state && state.stepNames) {
67-
this.mrcStepNames = state.stepNames;
68-
this.updateShape_();
69-
}
71+
this.mrcStepNames = state.stepNames;
72+
this.updateShape_();
7073
},
7174
compose: function (this: StepsBlock, containerBlock: Blockly.Block) {
7275
if (containerBlock.type !== stepContainer.STEP_CONTAINER_BLOCK_NAME) {
@@ -96,6 +99,21 @@ const STEPS = {
9699
});
97100

98101
this.updateShape_();
102+
103+
// Add a shadow True block to each empty condition input.
104+
for (var i = 0; i < this.mrcStepNames.length; i++) {
105+
const conditionInput = this.getInput(INPUT_CONDITION_PREFIX + i);
106+
if (conditionInput && !conditionInput.connection?.targetConnection) {
107+
const shadowBlock = this.workspace.newBlock('logic_boolean') as Blockly.BlockSvg;
108+
shadowBlock.setShadow(true);
109+
shadowBlock.setFieldValue('TRUE', 'BOOL');
110+
if (this.workspace.rendered) {
111+
shadowBlock.initSvg();
112+
shadowBlock.render();
113+
}
114+
conditionInput.connection?.connect(shadowBlock.outputConnection!);
115+
}
116+
}
99117
},
100118
decompose: function (this: StepsBlock, workspace: Blockly.Workspace) {
101119
const stepNames: string[] = [];
@@ -151,8 +169,8 @@ const STEPS = {
151169
// Build a map of step names to their current input indices
152170
const currentStepMap: { [stepName: string]: number } = {};
153171
let i = 0;
154-
while (this.getInput('CONDITION_' + i)) {
155-
const conditionInput = this.getInput('CONDITION_' + i);
172+
while (this.getInput(INPUT_CONDITION_PREFIX + i)) {
173+
const conditionInput = this.getInput(INPUT_CONDITION_PREFIX + i);
156174
const field = conditionInput?.fieldRow[0];
157175
if (field) {
158176
currentStepMap[field.getValue()] = i;
@@ -167,39 +185,43 @@ const STEPS = {
167185

168186
if (currentIndex !== undefined && currentIndex !== j) {
169187
// Step exists but is at wrong position - move it
170-
const conditionConnection = this.getInput('CONDITION_' + currentIndex)?.connection?.targetConnection;
171-
const stepConnection = this.getInput('STEP_' + currentIndex)?.connection?.targetConnection;
188+
const conditionConnection = this.getInput(INPUT_CONDITION_PREFIX + currentIndex)?.connection?.targetConnection;
189+
const stepConnection = this.getInput(INPUT_STEP_PREFIX + currentIndex)?.connection?.targetConnection;
172190

173191
// Temporarily disconnect
174-
if (conditionConnection) conditionConnection.disconnect();
175-
if (stepConnection) stepConnection.disconnect();
192+
if (conditionConnection) {
193+
conditionConnection.disconnect();
194+
}
195+
if (stepConnection) {
196+
stepConnection.disconnect();
197+
}
176198

177199
// Remove old inputs
178-
this.removeInput('CONDITION_' + currentIndex, false);
179-
this.removeInput('STEP_' + currentIndex, false);
200+
this.removeInput(INPUT_CONDITION_PREFIX + currentIndex, false);
201+
this.removeInput(INPUT_STEP_PREFIX + currentIndex, false);
180202

181203
// Create new inputs at correct position
182204
const fieldFlydown = createStepFieldFlydown(stepName, true);
183205
fieldFlydown.setValidator(this.mrcUpdateStepName.bind(this, j));
184206

185-
this.appendValueInput('CONDITION_' + j)
207+
this.appendValueInput(INPUT_CONDITION_PREFIX + j)
186208
.appendField(fieldFlydown)
187209
.setCheck('Boolean')
188210
.appendField(Blockly.Msg.REPEAT_UNTIL);
189-
this.appendStatementInput('STEP_' + j);
211+
this.appendStatementInput(INPUT_STEP_PREFIX + j);
190212

191213
// Reconnect
192214
if (conditionConnection) {
193-
this.getInput('CONDITION_' + j)?.connection?.connect(conditionConnection);
215+
this.getInput(INPUT_CONDITION_PREFIX + j)?.connection?.connect(conditionConnection);
194216
}
195217
if (stepConnection) {
196-
this.getInput('STEP_' + j)?.connection?.connect(stepConnection);
218+
this.getInput(INPUT_STEP_PREFIX + j)?.connection?.connect(stepConnection);
197219
}
198220

199221
delete currentStepMap[stepName];
200222
} else if (currentIndex !== undefined) {
201223
// Step is at correct position - just update the field
202-
const conditionInput = this.getInput('CONDITION_' + j);
224+
const conditionInput = this.getInput(INPUT_CONDITION_PREFIX + j);
203225
const field = conditionInput?.fieldRow[0];
204226
if (field && field.getValue() !== stepName) {
205227
field.setValue(stepName);
@@ -210,31 +232,19 @@ const STEPS = {
210232
const fieldFlydown = createStepFieldFlydown(stepName, true);
211233
fieldFlydown.setValidator(this.mrcUpdateStepName.bind(this, j));
212234

213-
const conditionInput = this.appendValueInput('CONDITION_' + j)
235+
this.appendValueInput(INPUT_CONDITION_PREFIX + j)
214236
.appendField(fieldFlydown)
215237
.setCheck('Boolean')
216238
.appendField(Blockly.Msg.REPEAT_UNTIL);
217-
this.appendStatementInput('STEP_' + j);
218-
219-
// Add shadow True block to the new condition input
220-
if (this.workspace) {
221-
const shadowBlock = this.workspace.newBlock('logic_boolean') as Blockly.BlockSvg;
222-
shadowBlock.setShadow(true);
223-
shadowBlock.setFieldValue('TRUE', 'BOOL');
224-
if (this.workspace.rendered){
225-
shadowBlock.initSvg();
226-
shadowBlock.render();
227-
}
228-
conditionInput.connection?.connect(shadowBlock.outputConnection!);
229-
}
239+
this.appendStatementInput(INPUT_STEP_PREFIX + j);
230240
}
231241
}
232242

233243
// Remove any leftover inputs (steps that were deleted)
234244
for (const stepName in currentStepMap) {
235245
const index = currentStepMap[stepName];
236-
this.removeInput('CONDITION_' + index, false);
237-
this.removeInput('STEP_' + index, false);
246+
this.removeInput(INPUT_CONDITION_PREFIX + index, false);
247+
this.removeInput(INPUT_STEP_PREFIX + index, false);
238248
}
239249
},
240250
mrcGetStepNames: function (this: StepsBlock): string[] {
@@ -256,7 +266,7 @@ export const pythonFromBlock = function (
256266
generator: ExtendedPythonGenerator,
257267
) {
258268
let code = 'def steps(self):\n';
259-
code += generator.INDENT + 'if not self._initialized_steps:\n';
269+
code += generator.INDENT + 'if not hasattr(self, "_initialized_steps"):\n';
260270
code += generator.INDENT.repeat(2) + 'self._current_step = "' + block.mrcStepNames[0] + '"\n';
261271
code += generator.INDENT.repeat(2) + 'self._initialized_steps = True\n\n';
262272
code += generator.INDENT + 'if self._current_step == None:\n';
@@ -266,11 +276,11 @@ export const pythonFromBlock = function (
266276
code += generator.INDENT + 'match self._current_step:\n';
267277
block.mrcStepNames.forEach((stepName, index) => {
268278
code += generator.INDENT.repeat(2) + `case "${stepName}":\n`;
269-
let stepCode = generator.statementToCode(block, 'STEP_' + index);
279+
let stepCode = generator.statementToCode(block, INPUT_STEP_PREFIX + index);
270280
if (stepCode !== '') {
271281
code += generator.prefixLines(stepCode, generator.INDENT.repeat(2));
272282
}
273-
let conditionCode = generator.valueToCode(block, 'CONDITION_' + index, Order.NONE) || 'False';
283+
let conditionCode = generator.valueToCode(block, INPUT_CONDITION_PREFIX + index, Order.NONE) || 'False';
274284
code += generator.INDENT.repeat(3) + 'if ' + conditionCode + ':\n';
275285
if (index === block.mrcStepNames.length - 1) {
276286
code += generator.INDENT.repeat(4) + 'self._current_step = None\n';
@@ -282,4 +292,14 @@ export const pythonFromBlock = function (
282292
generator.addClassMethodDefinition('steps', code);
283293

284294
return ''
285-
}
295+
}
296+
297+
export function createStepsBlock(): toolboxItems.Block {
298+
const extraState: StepsExtraState = {
299+
stepNames: ['0'],
300+
};
301+
const fields: {[key: string]: any} = {};
302+
const inputs: {[key: string]: any} = {};
303+
inputs[INPUT_CONDITION_PREFIX + 0] = value.createBooleanShadowValue(true);
304+
return new toolboxItems.Block(BLOCK_NAME, extraState, fields, inputs);
305+
}

src/toolbox/methods_category.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import { MRC_CATEGORY_STYLE_METHODS } from '../themes/styles';
2727
import { CLASS_NAME_ROBOT_BASE, CLASS_NAME_OPMODE, CLASS_NAME_MECHANISM } from '../blocks/utils/python';
2828
import { addInstanceWithinBlocks } from '../blocks/mrc_call_python_function';
2929
import { createCustomMethodBlock, getBaseClassBlocks, FIELD_METHOD_NAME, createCustomMethodBlockWithReturn } from '../blocks/mrc_class_method_def';
30+
import { createStepsBlock } from '../blocks/mrc_steps';
3031
import { Editor } from '../editor/editor';
3132

3233

@@ -101,10 +102,7 @@ class MethodsCategory {
101102
case storageModule.ModuleType.OPMODE:
102103
const hasSteps = editor.isStepsInWorkspace();
103104
if (!hasSteps) {
104-
contents.push({
105-
kind: 'block',
106-
type: 'mrc_steps',
107-
});
105+
contents.push(createStepsBlock());
108106
}
109107
// Add the methods for an OpMode.
110108
this.addClassBlocksForCurrentModule(

0 commit comments

Comments
 (0)