Skip to content

Commit 88683ec

Browse files
committed
In mrc_call_python_function.ts:
Added INSTANCE_MECHANISM to FunctionKind enum to represent calling a mechanism instance method from the robot or from an OpMode. In renameMethodCaller, added code to update a block calling a component instance method if the component name is changed, and to update a block calling a mechanism instance method if the mechanism name or method name/signature is changed. Added functions addInstanceMechanismBlocks and createInstanceMechanismBlock. In mrc_component.ts: Added validator to the name field so we can call renameMethodCallers when the user changes the component name. Removed hideParams and mrcHideParams. Instead use module type to decide whether to hide parameters. Replaced getNewPort method with getArgName method, which uses both the component name and the arg name so the users knows what kind of ports (or other arguments) they are passing in. In mrc_mechanism.ts: Added validator to the name field so we can call renameMethodCallers when the user changes the mechanism name. In editor.ts: Added getMechanism method to get the Mechanism that correponds to the given MechanismInRobot. In common_storage.ts: Added some comments on className fields. In hardware_category.ts: Added code to getRobotMechanismsCategory to add a toolbox category with the methods for each mechanism that was added to the Robot. In methods_category.ts: Removed duplicate 'register_event' value.
1 parent c4e4e89 commit 88683ec

File tree

7 files changed

+305
-189
lines changed

7 files changed

+305
-189
lines changed

src/blocks/mrc_call_python_function.ts

Lines changed: 225 additions & 22 deletions
Large diffs are not rendered by default.

src/blocks/mrc_component.ts

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,15 @@ import { Order } from 'blockly/python';
2424

2525
import { MRC_STYLE_COMPONENTS } from '../themes/styles'
2626
import { createFieldNonEditableText } from '../fields/FieldNonEditableText';
27+
import { Editor } from '../editor/editor';
2728
import { ExtendedPythonGenerator } from '../editor/extended_python_generator';
2829
import { getAllowedTypesForSetCheck, getClassData, getModuleData, getSubclassNames } from './utils/python';
2930
import * as toolboxItems from '../toolbox/items';
3031
import * as commonStorage from '../storage/common_storage';
3132
import { createPortShadow } from './mrc_port';
3233
import { createNumberShadowValue } from './utils/value';
3334
import { ClassData, FunctionData } from './utils/python_json_types';
35+
import { renameMethodCallers } from './mrc_call_python_function'
3436

3537

3638
export const BLOCK_NAME = 'mrc_component';
@@ -48,14 +50,12 @@ type ComponentExtraState = {
4850
importModule?: string,
4951
// If staticFunctionName is not present, generate the constructor.
5052
staticFunctionName?: string,
51-
hideParams?: boolean,
5253
params?: ConstructorArg[],
5354
}
5455

5556
export type ComponentBlock = Blockly.Block & ComponentMixin;
5657
interface ComponentMixin extends ComponentMixinType {
5758
mrcArgs: ConstructorArg[],
58-
hideParams: boolean,
5959
mrcImportModule: string,
6060
mrcStaticFunctionName: string,
6161
}
@@ -67,8 +67,10 @@ const COMPONENT = {
6767
*/
6868
init: function (this: ComponentBlock): void {
6969
this.setStyle(MRC_STYLE_COMPONENTS);
70+
const nameField = new Blockly.FieldTextInput('')
71+
nameField.setValidator(this.mrcNameFieldValidator.bind(this, nameField));
7072
this.appendDummyInput()
71-
.appendField(new Blockly.FieldTextInput(''), FIELD_NAME)
73+
.appendField(nameField, FIELD_NAME)
7274
.appendField(Blockly.Msg.OF_TYPE)
7375
.appendField(createFieldNonEditableText(''), FIELD_TYPE);
7476
this.setPreviousStatement(true, OUTPUT_NAME);
@@ -96,9 +98,6 @@ const COMPONENT = {
9698
if (this.mrcStaticFunctionName) {
9799
extraState.staticFunctionName = this.mrcStaticFunctionName;
98100
}
99-
if (this.hideParams) {
100-
extraState.hideParams = this.hideParams;
101-
}
102101
return extraState;
103102
},
104103
/**
@@ -107,7 +106,6 @@ const COMPONENT = {
107106
loadExtraState: function (this: ComponentBlock, extraState: ComponentExtraState): void {
108107
this.mrcImportModule = extraState.importModule ? extraState.importModule : '';
109108
this.mrcStaticFunctionName = extraState.staticFunctionName ? extraState.staticFunctionName : '';
110-
this.hideParams = extraState.hideParams ? extraState.hideParams : false;
111109
this.mrcArgs = [];
112110

113111
if (extraState.params) {
@@ -125,7 +123,8 @@ const COMPONENT = {
125123
* Update the block to reflect the newly loaded extra state.
126124
*/
127125
updateBlock_: function (this: ComponentBlock): void {
128-
if (this.hideParams == false) {
126+
const editor = Editor.getEditorForBlocklyWorkspace(this.workspace);
127+
if (editor && editor.getCurrentModuleType() === commonStorage.MODULE_TYPE_ROBOT) {
129128
// Add input sockets for the arguments.
130129
for (let i = 0; i < this.mrcArgs.length; i++) {
131130
const input = this.appendValueInput('ARG' + i)
@@ -137,6 +136,18 @@ const COMPONENT = {
137136
}
138137
}
139138
},
139+
mrcNameFieldValidator(this: ComponentBlock, nameField: Blockly.FieldTextInput, name: string): string {
140+
// Strip leading and trailing whitespace.
141+
name = name.trim();
142+
143+
const legalName = name;
144+
const oldName = nameField.getValue();
145+
if (oldName && oldName !== name && oldName !== legalName) {
146+
// Rename any callers.
147+
renameMethodCallers(this.workspace, this.id, legalName);
148+
}
149+
return legalName;
150+
},
140151
getComponent: function (this: ComponentBlock): commonStorage.Component | null {
141152
const componentName = this.getFieldValue(FIELD_NAME);
142153
const componentType = this.getFieldValue(FIELD_TYPE);
@@ -149,19 +160,14 @@ const COMPONENT = {
149160
ports: ports,
150161
};
151162
},
152-
getNewPort: function (this: ComponentBlock, i: number): string {
153-
let extension = '';
154-
if (i != 0) {
155-
extension = '_' + (i + 1).toString();
156-
}
157-
return this.getFieldValue(FIELD_NAME) + extension + '_port';
163+
getArgName: function (this: ComponentBlock, i: number): string {
164+
return this.getFieldValue(FIELD_NAME) + '__' + this.mrcArgs[i].name;
158165
},
159-
getComponentPorts: function (this: ComponentBlock, ports: {[key: string]: string}): void {
166+
getComponentPorts: function (this: ComponentBlock, ports: {[argName: string]: string}): void {
160167
// Collect the ports for this component block.
161168
for (let i = 0; i < this.mrcArgs.length; i++) {
162-
const newPort = this.getNewPort(i);
163-
// The key is the port, the value is the type.
164-
ports[newPort] = this.mrcArgs[i].type;
169+
const argName = this.getArgName(i);
170+
ports[argName] = this.mrcArgs[i].type;
165171
}
166172
},
167173
}
@@ -184,14 +190,13 @@ export const pythonFromBlock = function (
184190
code += '(';
185191

186192
for (let i = 0; i < block.mrcArgs.length; i++) {
187-
const fieldName = 'ARG' + i;
188193
if (i != 0) {
189-
code += ', '
194+
code += ', ';
190195
}
191-
if (block.hideParams) {
192-
code += block.mrcArgs[i].name + ' = ' + block.getNewPort(i);
196+
if (generator.getModuleType() === commonStorage.MODULE_TYPE_ROBOT) {
197+
code += block.mrcArgs[i].name + ' = ' + generator.valueToCode(block, 'ARG' + i, Order.NONE);
193198
} else {
194-
code += block.mrcArgs[i].name + ' = ' + generator.valueToCode(block, fieldName, Order.NONE);
199+
code += block.mrcArgs[i].name + ' = ' + block.getArgName(i);
195200
}
196201
}
197202
code += ')\n' + 'self.hardware.append(self.' + block.getFieldValue(FIELD_NAME) + ')\n';
@@ -230,7 +235,6 @@ function createComponentBlock(
230235
importModule: classData.moduleName,
231236
staticFunctionName: staticFunctionData.functionName,
232237
params: [],
233-
hideParams: (moduleType == commonStorage.MODULE_TYPE_MECHANISM),
234238
};
235239
const fields: {[key: string]: any} = {};
236240
fields[FIELD_NAME] = componentName;

src/blocks/mrc_mechanism.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import { getAllowedTypesForSetCheck } from './utils/python';
3030
import * as toolboxItems from '../toolbox/items';
3131
import * as commonStorage from '../storage/common_storage';
3232
import * as value from './utils/value';
33+
import { renameMethodCallers } from './mrc_call_python_function'
3334

3435
export const BLOCK_NAME = 'mrc_mechanism';
3536
export const OUTPUT_NAME = 'mrc_mechansim';
@@ -62,13 +63,14 @@ const MECHANISM = {
6263
*/
6364
init: function (this: MechanismBlock): void {
6465
this.setStyle(MRC_STYLE_MECHANISMS);
66+
const nameField = new Blockly.FieldTextInput('')
67+
nameField.setValidator(this.mrcNameFieldValidator.bind(this, nameField));
6568
this.appendDummyInput()
66-
.appendField(new Blockly.FieldTextInput('my_mech'), FIELD_NAME)
69+
.appendField(nameField, FIELD_NAME)
6770
.appendField(Blockly.Msg.OF_TYPE)
6871
.appendField(createFieldNonEditableText(''), FIELD_TYPE);
6972
this.setPreviousStatement(true, OUTPUT_NAME);
7073
this.setNextStatement(true, OUTPUT_NAME);
71-
//this.setOutput(true, OUTPUT_NAME);
7274
},
7375

7476
/**
@@ -137,6 +139,18 @@ const MECHANISM = {
137139
this.removeInput('ARG' + i);
138140
}
139141
},
142+
mrcNameFieldValidator(this: ComponentBlock, nameField: Blockly.FieldTextInput, name: string): string {
143+
// Strip leading and trailing whitespace.
144+
name = name.trim();
145+
146+
const legalName = name;
147+
const oldName = nameField.getValue();
148+
if (oldName && oldName !== name && oldName !== legalName) {
149+
// Rename any callers.
150+
renameMethodCallers(this.workspace, this.id, legalName);
151+
}
152+
return legalName;
153+
},
140154
getMechanism: function (this: MechanismBlock): commonStorage.MechanismInRobot | null {
141155
const mechanismName = this.getFieldValue(FIELD_NAME);
142156
const mechanismType = this.mrcImportModule + '.' + this.getFieldValue(FIELD_TYPE);

src/editor/editor.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,7 @@ export class Editor {
138138
this.clearBlocklyWorkspace();
139139

140140
if (this.currentModule && this.currentProject) {
141-
// Fetch the content for the current module and the robot.
142-
// TODO: Also fetch the content for the mechanisms?
141+
// Fetch the content for the current module, the robot, and the mechanisms.
143142
const promises: { [modulePath: string]: Promise<string> } = {}; // value is promise of module content.
144143
promises[this.modulePath] = this.storage.fetchModuleContentText(this.modulePath);
145144
if (this.robotPath !== this.modulePath) {
@@ -377,6 +376,20 @@ export class Editor {
377376
return this.currentProject ? this.currentProject.mechanisms : [];
378377
}
379378

379+
/**
380+
* Returns the Mechanism matching the given MechanismInRobot.
381+
*/
382+
public getMechanism(mechanismInRobot: commonStorage.MechanismInRobot): commonStorage.Mechanism | null {
383+
if (this.currentProject) {
384+
for (const mechanism of this.currentProject.mechanisms) {
385+
if (mechanism.moduleName + '.' + mechanism.className === mechanismInRobot.className) {
386+
return mechanism;
387+
}
388+
}
389+
}
390+
return null;
391+
}
392+
380393
/**
381394
* Returns the components defined in the given mechanism.
382395
*/

src/storage/common_storage.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export type Module = {
3434
projectName: string,
3535
moduleName: string,
3636
dateModifiedMillis: number,
37-
className: string,
37+
className: string, // Does not include the module name.
3838
};
3939

4040
export type Robot = Module;
@@ -65,13 +65,13 @@ export type Method = {
6565
export type MechanismInRobot = {
6666
blockId: string, // ID of the mrc_mechanism block that adds the mechanism to the robot.
6767
name: string,
68-
className: string,
68+
className: string, // Includes the module name, for example 'game_piece_shooter.GamePieceShooter'.
6969
}
7070

7171
export type Component = {
7272
blockId: string, // ID of the mrc_component block that adds the component to the robot or to a mechanism.
7373
name: string,
74-
className: string,
74+
className: string, // Includes the module name, for example 'smart_motor.SmartMotor'.
7575
ports: {[port: string]: string}, // The value is the type.
7676
}
7777

0 commit comments

Comments
 (0)