Skip to content

Commit 395c1de

Browse files
committed
Added code to mrc_component.ts and mrc_mechanism.ts to add a warning if the block is not in the holder. Updated code in mrc_event.ts (which already existed) to be similar.
1 parent 1cec386 commit 395c1de

File tree

7 files changed

+124
-33
lines changed

7 files changed

+124
-33
lines changed

src/blocks/mrc_component.ts

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import { getAllowedTypesForSetCheck, getClassData, getSubclassNames } from './ut
3030
import * as toolboxItems from '../toolbox/items';
3131
import * as storageModule from '../storage/module';
3232
import * as storageModuleContent from '../storage/module_content';
33+
import { BLOCK_NAME as MRC_MECHANISM_COMPONENT_HOLDER } from './mrc_mechanism_component_holder';
3334
import { createPort } from './mrc_port';
3435
import { ClassData, FunctionData } from './utils/python_json_types';
3536
import { renameMethodCallers } from './mrc_call_python_function'
@@ -41,6 +42,8 @@ export const OUTPUT_NAME = 'mrc_component';
4142
export const FIELD_NAME = 'NAME';
4243
export const FIELD_TYPE = 'TYPE';
4344

45+
const WARNING_ID_NOT_IN_HOLDER = 'not in holder';
46+
4447
type ConstructorArg = {
4548
name: string,
4649
type: string,
@@ -60,6 +63,15 @@ interface ComponentMixin extends ComponentMixinType {
6063
mrcArgs: ConstructorArg[],
6164
mrcImportModule: string,
6265
mrcStaticFunctionName: string,
66+
67+
/**
68+
* mrcHasNotInHolderWarning is set to true if we set the NOT_IN_HOLDER warning text on the block.
69+
* It is checked to avoid adding a warning if there already is one. Otherwise, if we get two move
70+
* events (one for drag and one for snap), and we call setWarningText for both events, we get a
71+
* detached warning balloon.
72+
* See https://github.com/wpilibsuite/systemcore-blocks-interface/issues/248.
73+
*/
74+
mrcHasNotInHolderWarning: boolean,
6375
}
6476
type ComponentMixinType = typeof COMPONENT;
6577

@@ -68,6 +80,7 @@ const COMPONENT = {
6880
* Block initialization.
6981
*/
7082
init: function (this: ComponentBlock): void {
83+
this.mrcHasNotInHolderWarning = false;
7184
this.setStyle(MRC_STYLE_COMPONENTS);
7285
const nameField = new Blockly.FieldTextInput('')
7386
nameField.setValidator(this.mrcNameFieldValidator.bind(this, nameField));
@@ -90,8 +103,8 @@ const COMPONENT = {
90103
if (this.mrcArgs){
91104
this.mrcArgs.forEach((arg) => {
92105
extraState.params!.push({
93-
'name': arg.name,
94-
'type': arg.type,
106+
name: arg.name,
107+
type: arg.type,
95108
});
96109
});
97110
}
@@ -115,12 +128,11 @@ const COMPONENT = {
115128
if (extraState.params) {
116129
extraState.params.forEach((arg) => {
117130
this.mrcArgs.push({
118-
'name': arg.name,
119-
'type': arg.type,
131+
name: arg.name,
132+
type: arg.type,
120133
});
121134
});
122135
}
123-
this.mrcArgs = extraState.params ? extraState.params : [];
124136
this.updateBlock_();
125137
},
126138
/**
@@ -167,15 +179,45 @@ const COMPONENT = {
167179
getArgName: function (this: ComponentBlock, _: number): string {
168180
return this.getFieldValue(FIELD_NAME) + '__' + 'port';
169181
},
170-
171-
172182
getComponentPorts: function (this: ComponentBlock, ports: {[argName: string]: string}): void {
173183
// Collect the ports for this component block.
174184
for (let i = 0; i < this.mrcArgs.length; i++) {
175185
const argName = this.getArgName(i);
176186
ports[argName] = this.mrcArgs[i].name;
177187
}
178188
},
189+
/**
190+
* mrcOnLoad is called for each ComponentBlock when the blocks are loaded in the blockly workspace.
191+
*/
192+
mrcOnLoad: function(this: ComponentBlock): void {
193+
this.checkBlockIsInHolder();
194+
},
195+
/**
196+
* mrcOnMove is called when a ComponentBlock is moved.
197+
*/
198+
mrcOnMove: function(this: ComponentBlock): void {
199+
this.checkBlockIsInHolder();
200+
},
201+
checkBlockIsInHolder: function(this: ComponentBlock): void {
202+
const rootBlock: Blockly.Block | null = this.getRootBlock();
203+
if (rootBlock && rootBlock.type === MRC_MECHANISM_COMPONENT_HOLDER) {
204+
// If the root block is the mechanism_component_holder, the component block is allowed to stay.
205+
// Remove any previous warning.
206+
this.setWarningText(null, WARNING_ID_NOT_IN_HOLDER);
207+
this.mrcHasNotInHolderWarning = false;
208+
} else {
209+
// Otherwise, add a warning to the block.
210+
this.unplug(true);
211+
if (!this.mrcHasNotInHolderWarning) {
212+
this.setWarningText(Blockly.Msg.WARNING_COMPONENT_NOT_IN_HOLDER, WARNING_ID_NOT_IN_HOLDER);
213+
const icon = this.getIcon(Blockly.icons.IconType.WARNING);
214+
if (icon) {
215+
icon.setBubbleVisible(true);
216+
}
217+
this.mrcHasNotInHolderWarning = true;
218+
}
219+
}
220+
},
179221
/**
180222
* mrcChangeIds is called when a module is copied so that the copy has different ids than the original.
181223
*/
@@ -253,8 +295,8 @@ function createComponentBlock(
253295

254296
if (constructorData.expectedPortType) {
255297
extraState.params!.push({
256-
'name': constructorData.expectedPortType,
257-
'type': 'Port',
298+
name: constructorData.expectedPortType,
299+
type: 'Port',
258300
});
259301
if ( moduleType == storageModule.ModuleType.ROBOT ) {
260302
inputs['ARG0'] = createPort(constructorData.expectedPortType);

src/blocks/mrc_event.ts

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,13 @@ interface EventMixin extends EventMixinType {
5151
mrcParameters: Parameter[],
5252

5353
/**
54-
* mrcHasWarning is set to true if we set the warning text on the block. It is checked to avoid
55-
* adding a warning if there already is one. Otherwise, if we get two move events (one for drag
56-
* and one for snap), and we call setWarningText for both events, we get a detached warning
57-
* balloon. See https://github.com/wpilibsuite/systemcore-blocks-interface/issues/248.
54+
* mrcHasNotInHolderWarning is set to true if we set the NOT_IN_HOLDER warning text on the block.
55+
* It is checked to avoid adding a warning if there already is one. Otherwise, if we get two move
56+
* events (one for drag and one for snap), and we call setWarningText for both events, we get a
57+
* detached warning balloon.
58+
* See https://github.com/wpilibsuite/systemcore-blocks-interface/issues/248.
5859
*/
59-
mrcHasWarning: boolean,
60+
mrcHasNotInHolderWarning: boolean,
6061
}
6162
type EventMixinType = typeof EVENT;
6263

@@ -65,6 +66,7 @@ const EVENT = {
6566
* Block initialization.
6667
*/
6768
init: function (this: EventBlock): void {
69+
this.mrcHasNotInHolderWarning = false;
6870
this.setStyle(MRC_STYLE_EVENTS);
6971
this.appendDummyInput(INPUT_TITLE)
7072
.appendField(new Blockly.FieldTextInput('my_event'), FIELD_EVENT_NAME);
@@ -84,8 +86,8 @@ const EVENT = {
8486
if (this.mrcParameters) {
8587
this.mrcParameters.forEach((arg) => {
8688
extraState.params!.push({
87-
'name': arg.name,
88-
'type': arg.type,
89+
name: arg.name,
90+
type: arg.type,
8991
});
9092
});
9193
}
@@ -97,17 +99,14 @@ const EVENT = {
9799
loadExtraState: function (this: EventBlock, extraState: EventExtraState): void {
98100
this.mrcEventId = extraState.eventId ? extraState.eventId : this.id;
99101
this.mrcParameters = [];
100-
this.mrcHasWarning = false;
101-
102102
if (extraState.params) {
103103
extraState.params.forEach((arg) => {
104104
this.mrcParameters.push({
105-
'name': arg.name,
106-
'type': arg.type,
105+
name: arg.name,
106+
type: arg.type,
107107
});
108108
});
109109
}
110-
this.mrcParameters = extraState.params ? extraState.params : [];
111110
this.updateBlock_();
112111
},
113112
/**
@@ -207,28 +206,31 @@ const EVENT = {
207206
* mrcOnLoad is called for each EventBlock when the blocks are loaded in the blockly workspace.
208207
*/
209208
mrcOnLoad: function(this: EventBlock): void {
210-
this.checkParentIsHolder();
209+
this.checkBlockIsInHolder();
211210
},
212211
/**
213212
* mrcOnMove is called when an EventBlock is moved.
214213
*/
215214
mrcOnMove: function(this: EventBlock): void {
216-
this.checkParentIsHolder();
215+
this.checkBlockIsInHolder();
217216
},
218-
checkParentIsHolder: function(this: EventBlock): void {
219-
const parentBlock = this.getParent();
220-
if (parentBlock && parentBlock.type === MRC_MECHANISM_COMPONENT_HOLDER) {
221-
// If the parent block is the mechanism_component_holder, the event block is allowed to stay.
217+
checkBlockIsInHolder: function(this: EventBlock): void {
218+
const rootBlock: Blockly.Block | null = this.getRootBlock();
219+
if (rootBlock && rootBlock.type === MRC_MECHANISM_COMPONENT_HOLDER) {
220+
// If the root block is the mechanism_component_holder, the event block is allowed to stay.
222221
// Remove any previous warning.
223222
this.setWarningText(null, WARNING_ID_NOT_IN_HOLDER);
224-
this.mrcHasWarning = false;
223+
this.mrcHasNotInHolderWarning = false;
225224
} else {
226225
// Otherwise, add a warning to the block.
227226
this.unplug(true);
228-
if (!this.mrcHasWarning) {
227+
if (!this.mrcHasNotInHolderWarning) {
229228
this.setWarningText(Blockly.Msg.WARNING_EVENT_NOT_IN_HOLDER, WARNING_ID_NOT_IN_HOLDER);
230-
this.getIcon(Blockly.icons.IconType.WARNING)!.setBubbleVisible(true);
231-
this.mrcHasWarning = true;
229+
const icon = this.getIcon(Blockly.icons.IconType.WARNING);
230+
if (icon) {
231+
icon.setBubbleVisible(true);
232+
}
233+
this.mrcHasNotInHolderWarning = true;
232234
}
233235
}
234236
},

src/blocks/mrc_mechanism.ts

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import * as toolboxItems from '../toolbox/items';
3131
import * as storageModule from '../storage/module';
3232
import * as storageModuleContent from '../storage/module_content';
3333
import * as storageNames from '../storage/names';
34+
import { BLOCK_NAME as MRC_MECHANISM_COMPONENT_HOLDER } from './mrc_mechanism_component_holder';
3435
import { renameMethodCallers } from './mrc_call_python_function'
3536
import { renameMechanismName as renameMechanismNameInEventHandlers } from './mrc_event_handler'
3637
import { createPort } from './mrc_port';
@@ -53,6 +54,7 @@ type MechanismExtraState = {
5354
parameters?: Parameter[],
5455
}
5556

57+
const WARNING_ID_NOT_IN_HOLDER = 'not in holder';
5658
const WARNING_ID_MECHANISM_CHANGED = 'mechanism changed';
5759

5860
export type MechanismBlock = Blockly.Block & MechanismMixin & Blockly.BlockSvg;
@@ -61,6 +63,15 @@ interface MechanismMixin extends MechanismMixinType {
6163
mrcMechanismId: string,
6264
mrcImportModule: string,
6365
mrcParameters: Parameter[],
66+
67+
/**
68+
* mrcHasNotInHolderWarning is set to true if we set the NOT_IN_HOLDER warning text on the block.
69+
* It is checked to avoid adding a warning if there already is one. Otherwise, if we get two move
70+
* events (one for drag and one for snap), and we call setWarningText for both events, we get a
71+
* detached warning balloon.
72+
* See https://github.com/wpilibsuite/systemcore-blocks-interface/issues/248.
73+
*/
74+
mrcHasNotInHolderWarning: boolean,
6475
}
6576
type MechanismMixinType = typeof MECHANISM;
6677

@@ -69,6 +80,7 @@ const MECHANISM = {
6980
* Block initialization.
7081
*/
7182
init: function (this: MechanismBlock): void {
83+
this.mrcHasNotInHolderWarning = false;
7284
this.setStyle(MRC_STYLE_MECHANISMS);
7385
const nameField = new Blockly.FieldTextInput('')
7486
nameField.setValidator(this.mrcNameFieldValidator.bind(this, nameField));
@@ -91,8 +103,8 @@ const MECHANISM = {
91103
extraState.parameters = [];
92104
this.mrcParameters.forEach((arg) => {
93105
extraState.parameters!.push({
94-
'name': arg.name,
95-
'type': arg.type,
106+
name: arg.name,
107+
type: arg.type,
96108
});
97109
});
98110
if (this.mrcImportModule) {
@@ -186,8 +198,35 @@ const MECHANISM = {
186198
* workspace.
187199
*/
188200
mrcOnLoad: function(this: MechanismBlock): void {
201+
this.checkBlockIsInHolder();
189202
this.checkMechanism();
190203
},
204+
/**
205+
* mrcOnMove is called when a MechanismBlock is moved.
206+
*/
207+
mrcOnMove: function(this: MechanismBlock): void {
208+
this.checkBlockIsInHolder();
209+
},
210+
checkBlockIsInHolder: function(this: MechanismBlock): void {
211+
const rootBlock: Blockly.Block | null = this.getRootBlock();
212+
if (rootBlock && rootBlock.type === MRC_MECHANISM_COMPONENT_HOLDER) {
213+
// If the root block is the mechanism_component_holder, the mechanism block is allowed to stay.
214+
// Remove any previous warning.
215+
this.setWarningText(null, WARNING_ID_NOT_IN_HOLDER);
216+
this.mrcHasNotInHolderWarning = false;
217+
} else {
218+
// Otherwise, add a warning to the block.
219+
this.unplug(true);
220+
if (!this.mrcHasNotInHolderWarning) {
221+
this.setWarningText(Blockly.Msg.WARNING_MECHANISM_NOT_IN_HOLDER, WARNING_ID_NOT_IN_HOLDER);
222+
const icon = this.getIcon(Blockly.icons.IconType.WARNING);
223+
if (icon) {
224+
icon.setBubbleVisible(true);
225+
}
226+
this.mrcHasNotInHolderWarning = true;
227+
}
228+
}
229+
},
191230
/**
192231
* checkMechanism checks the block, updates it, and/or adds a warning balloon if necessary.
193232
* It is called from mrcOnModuleCurrent and mrcOnLoad above.

src/blocks/tokens.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ export function customTokens(t: (key: string) => string): typeof Blockly.Msg {
103103
CALL_ROBOT_INSTANCE_METHOD_TOOLTIP: t('BLOCKLY.TOOLTIP.CALL_ROBOT_INSTANCE_METHOD'),
104104
CALL_MECHANISM_INSTANCE_METHOD_TOOLTIP: t('BLOCKLY.TOOLTIP.CALL_MECHANISM_INSTANCE_METHOD'),
105105
WARNING_EVENT_NOT_IN_HOLDER: t('BLOCKLY.WARNING.EVENT_NOT_IN_HOLDER'),
106+
WARNING_COMPONENT_NOT_IN_HOLDER: t('BLOCKLY.WARNING.COMPONENT_NOT_IN_HOLDER'),
107+
WARNING_MECHANISM_NOT_IN_HOLDER: t('BLOCKLY.WARNING.MECHANISM_NOT_IN_HOLDER'),
106108
MRC_CATEGORY_HARDWARE: t('BLOCKLY.CATEGORY.HARDWARE'),
107109
MRC_CATEGORY_ROBOT: t('BLOCKLY.CATEGORY.ROBOT'),
108110
MRC_CATEGORY_COMPONENTS: t('BLOCKLY.CATEGORY.COMPONENTS'),

src/i18n/locales/en/translation.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,8 @@
180180
"CALL_MECHANISM_INSTANCE_METHOD_MISSING_METHOD": "This block calls a method that no longer exists in the mechanism.",
181181
"CALL_MECHANISM_INSTANCE_METHOD_MISSING_MECHANISM": "This block calls a method in a mechanism that no longer exists.",
182182
"EVENT_NOT_IN_HOLDER": "This block can only go in the events section of the robot or mechanism.",
183+
"COMPONENT_NOT_IN_HOLDER": "This block can only go in the components section of the robot or mechanism.",
184+
"MECHANISM_NOT_IN_HOLDER": "This block can only go in the mechanisms section of the robot.",
183185
"MECHANISM_NOT_FOUND": "This block refers to a mechanism that no longer exists."
184186
},
185187
"ERROR":{

src/i18n/locales/es/translation.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,8 @@
181181
"CALL_MECHANISM_INSTANCE_METHOD_MISSING_METHOD": "Este bloque llama a un método que ya no existe en el mecanismo.",
182182
"CALL_MECHANISM_INSTANCE_METHOD_MISSING_MECHANISM": "Este bloque llama a un método en un mecanismo que ya no existe.",
183183
"EVENT_NOT_IN_HOLDER": "Este bloque solo puede ir en la sección de eventos del robot o mecanismo.",
184+
"COMPONENT_NOT_IN_HOLDER": "Este bloque solo puede ir en la sección de componentes del robot o mecanismo.",
185+
"MECHANISM_NOT_IN_HOLDER": "Este bloque solo puede ir en la sección de mecanismos del robot.",
184186
"MECHANISM_NOT_FOUND": "Este bloque se refiere a un mecanismo que ya no existe."
185187
},
186188
"ERROR":{

src/i18n/locales/he/translation.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,8 @@
180180
"CALL_MECHANISM_INSTANCE_METHOD_MISSING_METHOD": "בלוק זה קורא למתודה שכבר לא קיימת במנגנון.",
181181
"CALL_MECHANISM_INSTANCE_METHOD_MISSING_MECHANISM": "בלוק זה קורא למתודה במנגנון שכבר לא קיים.",
182182
"EVENT_NOT_IN_HOLDER": "בלוק זה יכול להיכנס רק לאזור האירועים של הרובוט או המנגנון.",
183+
"COMPONENT_NOT_IN_HOLDER": "בלוק זה יכול להיכנס רק לאזור הרכיבים של הרובוט או המנגנון.",
184+
"MECHANISM_NOT_IN_HOLDER": "בלוק זה יכול להיכנס רק לחלק המנגנונים של הרובוט.",
183185
"MECHANISM_NOT_FOUND": "בלוק זה מתייחס למנגנון שכבר לא קיים."
184186
},
185187
"ERROR": {

0 commit comments

Comments
 (0)