Skip to content

Commit bae1011

Browse files
authored
Change ids when copying a module (#201)
* Add methodId to extra state of mrc_class_method_def block. * Add componentId to extra state of mrc_component block. * Add eventId to extra state of mrc_event block. Fixed indentation in onBlockChanged and getEvent methods. * Add mechanismId to extra state of mrc_mechanism block. * Rename blockId to methodId in Method. Rename blockId to mechanismId in MechanismInRobot. Rename blockId to componentId in Component. Rename blockId to eventId in Event. In parseModuleContentText rename blockId fields when parsing old text. Add changeIds to change the ids stored in mechanisms, components, events, and methods of ModuleContent. Update blocks by calling mrcChangeIds on blocks that implement it. * In mrc_call_python_function.ts: Update comments that describe otherBlockId. Change component.blockId to component.componentId. Change robotMethod.blockId to robotMethod.methodId. Change mechanismMethod.blockId to mechanismMethod.methodId. Change mechanismInRobot.blockId to mechanismInRobot.mechanismId. Change method.blockId to method.methodId. Change event.blockId to event.eventId. Change renameMethodCaller function parameter blockId to id. Change getMethodCallers function parameter otherBlockId to id. Change renameMethodCallers function parameter blockId to id. Change mutateMethodCallers function parameter blockId to id. Add mrcChangeIds to change mrcBlockId and mrcMechanismBlockId. * In project.ts renameOrCopyModule function to change the ids in the copy. * In mrc_event_handler.ts: Update comments that describe otherBlockId. Change robotEvent.blockId to robotEvent.eventId. Change event.blockId to event.eventId. Add mrcChangeIds to change mrcBlockId and mrcMechanismBlockId. * Fixed errors. * Updated mrc_event_handler.ts: In EventHandlerMixin: Changed mrcOtherBlockId to mrcEventId and mrcMechanismBlockId to mrcMechanismId. In EventHandlerExtraState: Changed otherBlockId to eventId and mechanismBlockId to mechanismId. Updated mrc_call_python_function.ts: In CallPythonFunctionMixin: Changed mrcOtherBlockId to multiple fields mrcMethodId, mrcComponentId, and mrcEventId. Changed mrcMechanismBlockId to mrcMechanismId. In CallPythonFunctionExtraState: Changed otherBlockId to multiple fields methodId, componentId, and eventId. Changed mechanismBlockId to mechanismId. * Removed ids from modules starter blocks. * Added comment about handling when a mechansim, component, or event is removed from the holder. * Moved code that register a custom toolbox categories into the function that returns the category. Pass the editor to getToolboxJSON and other toolbox functions that need the editor or the blockly workspace or the current module type. * Fixed ModuleContent.changeIds.
1 parent a23ce38 commit bae1011

19 files changed

+680
-504
lines changed

src/blocks/mrc_call_python_function.ts

Lines changed: 141 additions & 101 deletions
Large diffs are not rendered by default.

src/blocks/mrc_class_method_def.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ type Parameter = {
4646

4747
export type ClassMethodDefBlock = Blockly.Block & ClassMethodDefMixin & Blockly.BlockSvg;
4848
interface ClassMethodDefMixin extends ClassMethodDefMixinType {
49+
mrcMethodId: string,
4950
mrcCanChangeSignature: boolean,
5051
mrcCanBeCalledWithinClass: boolean,
5152
mrcCanBeCalledOutsideClass: boolean,
@@ -58,6 +59,10 @@ type ClassMethodDefMixinType = typeof CLASS_METHOD_DEF;
5859

5960
/** Extra state for serialising call_python_* blocks. */
6061
type ClassMethodDefExtraState = {
62+
/**
63+
* The id that identifies this method definition.
64+
*/
65+
methodId?: string,
6166
/**
6267
* Can change name and parameters and return type
6368
*/
@@ -109,6 +114,7 @@ const CLASS_METHOD_DEF = {
109114
saveExtraState: function (
110115
this: ClassMethodDefBlock): ClassMethodDefExtraState {
111116
const extraState: ClassMethodDefExtraState = {
117+
methodId: this.mrcMethodId,
112118
canChangeSignature: this.mrcCanChangeSignature,
113119
canBeCalledWithinClass: this.mrcCanBeCalledWithinClass,
114120
canBeCalledOutsideClass: this.mrcCanBeCalledOutsideClass,
@@ -134,6 +140,7 @@ const CLASS_METHOD_DEF = {
134140
this: ClassMethodDefBlock,
135141
extraState: ClassMethodDefExtraState
136142
): void {
143+
this.mrcMethodId = extraState.methodId ? extraState.methodId : this.id;
137144
this.mrcCanChangeSignature = extraState.canChangeSignature;
138145
this.mrcCanBeCalledWithinClass = extraState.canBeCalledWithinClass;
139146
this.mrcCanBeCalledOutsideClass = extraState.canBeCalledOutsideClass;
@@ -196,7 +203,7 @@ const CLASS_METHOD_DEF = {
196203
if (this.mrcCanBeCalledWithinClass) {
197204
const methodForWithin = this.getMethodForWithin();
198205
if (methodForWithin) {
199-
mutateMethodCallers(this.workspace, this.id, methodForWithin);
206+
mutateMethodCallers(this.workspace, this.mrcMethodId, methodForWithin);
200207
}
201208
}
202209
},
@@ -263,13 +270,13 @@ const CLASS_METHOD_DEF = {
263270
const oldName = nameField.getValue();
264271
if (oldName && oldName !== name && oldName !== legalName) {
265272
// Rename any callers.
266-
renameMethodCallers(this.workspace, this.id, legalName);
273+
renameMethodCallers(this.workspace, this.mrcMethodId, legalName);
267274
}
268275
return legalName;
269276
},
270277
getMethod: function (this: ClassMethodDefBlock): storageModuleContent.Method | null {
271278
const method: storageModuleContent.Method = {
272-
blockId: this.id,
279+
methodId: this.mrcMethodId,
273280
visibleName: this.getFieldValue(FIELD_METHOD_NAME),
274281
pythonName: this.mrcFuncName ? this.mrcFuncName : '',
275282
returnType: this.mrcReturnType,
@@ -307,6 +314,14 @@ const CLASS_METHOD_DEF = {
307314
getMethodName: function (this: ClassMethodDefBlock): string {
308315
return this.getFieldValue(FIELD_METHOD_NAME);
309316
},
317+
/**
318+
* mrcChangeIds is called when a module is copied so that the copy has different ids than the original.
319+
*/
320+
mrcChangeIds: function (this: ClassMethodDefBlock, oldIdToNewId: { [oldId: string]: string }): void {
321+
if (this.mrcMethodId in oldIdToNewId) {
322+
this.mrcMethodId = oldIdToNewId[this.mrcMethodId];
323+
}
324+
},
310325
};
311326

312327
/**

src/blocks/mrc_component.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ type ConstructorArg = {
4949
};
5050

5151
type ComponentExtraState = {
52+
componentId?: string,
5253
importModule?: string,
5354
// If staticFunctionName is not present, generate the constructor.
5455
staticFunctionName?: string,
@@ -57,6 +58,7 @@ type ComponentExtraState = {
5758

5859
export type ComponentBlock = Blockly.Block & ComponentMixin;
5960
interface ComponentMixin extends ComponentMixinType {
61+
mrcComponentId: string,
6062
mrcArgs: ConstructorArg[],
6163
mrcImportModule: string,
6264
mrcStaticFunctionName: string,
@@ -84,6 +86,7 @@ const COMPONENT = {
8486
*/
8587
saveExtraState: function (this: ComponentBlock): ComponentExtraState {
8688
const extraState: ComponentExtraState = {
89+
componentId: this.mrcComponentId,
8790
};
8891
extraState.params = [];
8992
if (this.mrcArgs){
@@ -106,6 +109,7 @@ const COMPONENT = {
106109
* Applies the given state to this block.
107110
*/
108111
loadExtraState: function (this: ComponentBlock, extraState: ComponentExtraState): void {
112+
this.mrcComponentId = extraState.componentId ? extraState.componentId : this.id;
109113
this.mrcImportModule = extraState.importModule ? extraState.importModule : '';
110114
this.mrcStaticFunctionName = extraState.staticFunctionName ? extraState.staticFunctionName : '';
111115
this.mrcArgs = [];
@@ -146,7 +150,7 @@ const COMPONENT = {
146150
const oldName = nameField.getValue();
147151
if (oldName && oldName !== name && oldName !== legalName) {
148152
// Rename any callers.
149-
renameMethodCallers(this.workspace, this.id, legalName);
153+
renameMethodCallers(this.workspace, this.mrcComponentId, legalName);
150154
}
151155
return legalName;
152156
},
@@ -156,7 +160,7 @@ const COMPONENT = {
156160
const ports: {[port: string]: string} = {};
157161
this.getComponentPorts(ports);
158162
return {
159-
blockId: this.id,
163+
componentId: this.mrcComponentId,
160164
name: componentName,
161165
className: componentType,
162166
ports: ports,
@@ -172,7 +176,15 @@ const COMPONENT = {
172176
ports[argName] = this.mrcArgs[i].type;
173177
}
174178
},
175-
}
179+
/**
180+
* mrcChangeIds is called when a module is copied so that the copy has different ids than the original.
181+
*/
182+
mrcChangeIds: function (this: ComponentBlock, oldIdToNewId: { [oldId: string]: string }): void {
183+
if (this.mrcComponentId in oldIdToNewId) {
184+
this.mrcComponentId = oldIdToNewId[this.mrcComponentId];
185+
}
186+
},
187+
};
176188

177189
export const setup = function () {
178190
Blockly.Blocks[BLOCK_NAME] = COMPONENT;

src/blocks/mrc_event.ts

Lines changed: 49 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -41,20 +41,22 @@ type Parameter = {
4141
};
4242

4343
type EventExtraState = {
44+
eventId?: string,
4445
params?: Parameter[],
4546
}
4647

4748
export type EventBlock = Blockly.Block & EventMixin & Blockly.BlockSvg;
4849

4950
interface EventMixin extends EventMixinType {
51+
mrcEventId: string,
5052
mrcParameters: Parameter[],
5153
}
5254
type EventMixinType = typeof EVENT;
5355

5456
const EVENT = {
5557
/**
56-
* Block initialization.
57-
*/
58+
* Block initialization.
59+
*/
5860
init: function (this: EventBlock): void {
5961
this.setStyle(MRC_STYLE_EVENTS);
6062
this.appendDummyInput("TITLE")
@@ -66,10 +68,11 @@ const EVENT = {
6668
},
6769

6870
/**
69-
* Returns the state of this block as a JSON serializable object.
70-
*/
71+
* Returns the state of this block as a JSON serializable object.
72+
*/
7173
saveExtraState: function (this: EventBlock): EventExtraState {
7274
const extraState: EventExtraState = {
75+
eventId: this.mrcEventId,
7376
};
7477
extraState.params = [];
7578
if (this.mrcParameters) {
@@ -83,9 +86,10 @@ const EVENT = {
8386
return extraState;
8487
},
8588
/**
86-
* Applies the given state to this block.
87-
*/
89+
* Applies the given state to this block.
90+
*/
8891
loadExtraState: function (this: EventBlock, extraState: EventExtraState): void {
92+
this.mrcEventId = extraState.eventId ? extraState.eventId : this.id;
8993
this.mrcParameters = [];
9094

9195
if (extraState.params) {
@@ -100,8 +104,8 @@ const EVENT = {
100104
this.updateBlock_();
101105
},
102106
/**
103-
* Update the block to reflect the newly loaded extra state.
104-
*/
107+
* Update the block to reflect the newly loaded extra state.
108+
*/
105109
updateBlock_: function (this: EventBlock): void {
106110
const name = this.getFieldValue(FIELD_EVENT_NAME);
107111
const input = this.getInput('TITLE');
@@ -136,7 +140,7 @@ const EVENT = {
136140
paramBlock.nextConnection && paramBlock.nextConnection.targetBlock();
137141
}
138142
this.mrcUpdateParams();
139-
mutateMethodCallers(this.workspace, this.id, this.getEvent());
143+
mutateMethodCallers(this.workspace, this.mrcEventId, this.getEvent());
140144
},
141145
decompose: function (this: EventBlock, workspace: Blockly.Workspace) {
142146
// This is a special sub-block that only gets created in the mutator UI.
@@ -189,42 +193,50 @@ const EVENT = {
189193
const oldName = nameField.getValue();
190194
if (oldName && oldName !== name && oldName !== legalName) {
191195
// Rename any callers.
192-
renameMethodCallers(this.workspace, this.id, legalName);
196+
renameMethodCallers(this.workspace, this.mrcEventId, legalName);
193197
}
194198
return legalName;
195199
},
196200
onBlockChanged(block: Blockly.BlockSvg, blockEvent: Blockly.Events.BlockBase): void {
197-
const blockBlock = block as Blockly.Block;
201+
const blockBlock = block as Blockly.Block;
198202

199-
if (blockEvent.type === Blockly.Events.BLOCK_MOVE) {
200-
const parent = ChangeFramework.getParentOfType(block, MRC_MECHANISM_COMPONENT_HOLDER);
203+
if (blockEvent.type === Blockly.Events.BLOCK_MOVE) {
204+
const parent = ChangeFramework.getParentOfType(block, MRC_MECHANISM_COMPONENT_HOLDER);
201205

202-
if (parent) {
203-
// If it is, we allow it to stay.
204-
blockBlock.setWarningText(null);
205-
return;
206-
}
207-
// If we end up here it shouldn't be allowed
208-
block.unplug(true);
209-
blockBlock.setWarningText('Events can only go in the events section of the robot or mechanism');
210-
blockBlock.getIcon(Blockly.icons.IconType.WARNING)!.setBubbleVisible(true);
206+
if (parent) {
207+
// If it is, we allow it to stay.
208+
blockBlock.setWarningText(null);
209+
return;
211210
}
212-
},
213-
getEvent: function (this: EventBlock): storageModuleContent.Event {
214-
const event: storageModuleContent.Event = {
215-
blockId: this.id,
216-
name: this.getFieldValue(FIELD_EVENT_NAME),
217-
args: [],
218-
};
219-
this.mrcParameters.forEach(param => {
220-
event.args.push({
221-
name: param.name,
222-
type: param.type ? param.type : '',
223-
});
211+
// If we end up here it shouldn't be allowed
212+
block.unplug(true);
213+
blockBlock.setWarningText('Events can only go in the events section of the robot or mechanism');
214+
blockBlock.getIcon(Blockly.icons.IconType.WARNING)!.setBubbleVisible(true);
215+
}
216+
},
217+
getEvent: function (this: EventBlock): storageModuleContent.Event {
218+
const event: storageModuleContent.Event = {
219+
eventId: this.mrcEventId,
220+
name: this.getFieldValue(FIELD_EVENT_NAME),
221+
args: [],
222+
};
223+
this.mrcParameters.forEach(param => {
224+
event.args.push({
225+
name: param.name,
226+
type: param.type ? param.type : '',
224227
});
225-
return event;
226-
},
227-
}
228+
});
229+
return event;
230+
},
231+
/**
232+
* mrcChangeIds is called when a module is copied so that the copy has different ids than the original.
233+
*/
234+
mrcChangeIds: function (this: EventBlock, oldIdToNewId: { [oldId: string]: string }): void {
235+
if (this.mrcEventId in oldIdToNewId) {
236+
this.mrcEventId = oldIdToNewId[this.mrcEventId];
237+
}
238+
},
239+
};
228240

229241
export const setup = function () {
230242
Blockly.Blocks[BLOCK_NAME] = EVENT;

0 commit comments

Comments
 (0)