Skip to content

Commit 833b509

Browse files
authored
Moved code that iterates through the components blocks in a holder block from hardware_category.ts to mrc_mechanism_component_holder.ts. (#145)
Added code to editor.ts to get the names of components from the robot. Added code to mrc_call_python_function.ts to populate the dropdown in blocks that call component instance methods.
1 parent f9cb123 commit 833b509

File tree

4 files changed

+97
-33
lines changed

4 files changed

+97
-33
lines changed

src/blocks/mrc_call_python_function.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import { getClassData, getAllowedTypesForSetCheck, getOutputCheck } from './util
2828
import { FunctionData, findSuperFunctionData } from './utils/python_json_types';
2929
import * as value from './utils/value';
3030
import * as variable from './utils/variable';
31+
import { Editor } from '../editor/editor';
3132
import { ExtendedPythonGenerator } from '../editor/extended_python_generator';
3233
import { createFieldDropdown } from '../fields/FieldDropdown';
3334
import { createFieldNonEditableText } from '../fields/FieldNonEditableText';
@@ -542,9 +543,13 @@ const CALL_PYTHON_FUNCTION = {
542543
break;
543544
}
544545
case FunctionKind.INSTANCE_COMPONENT: {
545-
// TODO: We need the list of component names for this.mrcComponentClassName so we can
546+
let componentNames: string[] = [];
547+
// Get the list of component names whose type matches this.mrcComponentClassName so we can
546548
// create a dropdown that has the appropriate component names.
547-
const componentNames: string[] = [];
549+
const editor = Editor.getEditorForBlocklyWorkspace(this.workspace);
550+
if (editor) {
551+
componentNames = editor.getComponentNames(this.mrcComponentClassName);
552+
}
548553
const componentName = this.getComponentName();
549554
if (!componentNames.includes(componentName)) {
550555
componentNames.push(componentName);

src/blocks/mrc_mechanism_component_holder.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { MRC_STYLE_MECHANISMS } from '../themes/styles';
2525
import * as ChangeFramework from './utils/change_framework';
2626
import { getLegalName } from './utils/python';
2727
import { ExtendedPythonGenerator } from '../editor/extended_python_generator';
28+
import * as commonStorage from '../storage/common_storage';
2829
import { OUTPUT_NAME as MECHANISM_OUTPUT } from './mrc_mechanism';
2930
import { BLOCK_NAME as MRC_MECHANISM_NAME } from './mrc_mechanism';
3031
import { BLOCK_NAME as MRC_COMPONENT_NAME } from './mrc_component';
@@ -127,7 +128,33 @@ const MECHANISM_COMPONENT_HOLDER = {
127128
}
128129
}
129130
},
131+
getComponents: function (this: MechanismComponentHolderBlock): commonStorage.Component[] {
132+
const components: commonStorage.Component[] = []
133+
134+
// Get component blocks from the COMPONENTS input
135+
const componentsInput = this.getInput('COMPONENTS');
136+
if (componentsInput && componentsInput.connection) {
137+
// Walk through all connected component blocks.
138+
let componentBlock = componentsInput.connection.targetBlock();
139+
while (componentBlock) {
140+
if (componentBlock.type === 'mrc_component') {
141+
const componentName = componentBlock.getFieldValue('NAME');
142+
const componentType = componentBlock.getFieldValue('TYPE');
143+
144+
if (componentName && componentType) {
145+
components.push({
146+
name: componentName,
147+
className: componentType,
148+
});
149+
}
150+
}
151+
// Move to the next block in the chain
152+
componentBlock = componentBlock.getNextBlock();
153+
}
154+
}
130155

156+
return components;
157+
},
131158
}
132159

133160
let toolboxUpdateTimeout: NodeJS.Timeout | null = null;
@@ -190,4 +217,4 @@ export const pythonFromBlock = function (
190217
pythonFromBlockInMechanism(block, generator);
191218
}
192219
return ''
193-
}
220+
}

src/editor/editor.ts

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import * as Blockly from 'blockly/core';
2424
import { extendedPythonGenerator } from './extended_python_generator';
2525
import { GeneratorContext } from './generator_context';
2626
import * as commonStorage from '../storage/common_storage';
27-
27+
import * as mechanismComponentHolder from '../blocks/mrc_mechanism_component_holder';
2828
//import { testAllBlocksInToolbox } from '../toolbox/toolbox_tests';
2929
import { MethodsCategory} from '../toolbox/methods_category';
3030
import { EventsCategory} from '../toolbox/event_category';
@@ -151,7 +151,7 @@ export class Editor {
151151
);
152152
this.moduleContent = moduleContents[this.modulePath];
153153
if (this.robotPath === this.modulePath) {
154-
this.robotContent = this.moduleContent
154+
this.robotContent = this.moduleContent;
155155
} else {
156156
this.robotContent = moduleContents[this.robotPath];
157157
}
@@ -233,7 +233,14 @@ export class Editor {
233233
const components: commonStorage.Component[] = [];
234234
if (this.currentModule?.moduleType === commonStorage.MODULE_TYPE_ROBOT ||
235235
this.currentModule?.moduleType === commonStorage.MODULE_TYPE_MECHANISM) {
236-
// TODO(lizlooney): Fill the components array.
236+
// Get the holder block and ask it for the components.
237+
const holderBlocks = this.blocklyWorkspace.getBlocksByType(mechanismComponentHolder.BLOCK_NAME);
238+
holderBlocks.forEach(holderBlock => {
239+
const componentsFromHolder: commonStorage.Component[] = holderBlock.getComponents();
240+
componentsFromHolder.forEach(component => {
241+
components.push(component);
242+
});
243+
});
237244
}
238245
return components;
239246
}
@@ -247,4 +254,43 @@ export class Editor {
247254
throw e;
248255
}
249256
}
257+
258+
/**
259+
* Returns the names of components defined in the robot that have the given component class name.
260+
*/
261+
// TODO: what about components defined in a mechanism?
262+
public getComponentNames(componentClassName: string): string[] {
263+
let components: commonStorage.Component[];
264+
265+
if (this.currentModule?.moduleType === commonStorage.MODULE_TYPE_ROBOT) {
266+
components = this.getComponents();
267+
} else {
268+
if (!this.robotContent) {
269+
throw new Error('getComponentNames: this.robotContent is null.');
270+
}
271+
components = commonStorage.extractComponents(this.robotContent);
272+
}
273+
274+
const componentNames: string[] = [];
275+
components.forEach((component) => {
276+
if (component.className === componentClassName) {
277+
componentNames.push(component.name);
278+
}
279+
});
280+
return componentNames;
281+
}
282+
283+
public static getEditorForBlocklyWorkspace(workspace: Blockly.Workspace): Editor | null {
284+
if (workspace.id in Editor.workspaceIdToEditor) {
285+
return Editor.workspaceIdToEditor[workspace.id];
286+
}
287+
288+
// If the workspace id was not found, it might be because the workspace is associated with the
289+
// toolbox flyout, not a real workspace. In that case, use the first editor.
290+
const allEditors = Object.values(Editor.workspaceIdToEditor);
291+
if (allEditors.length) {
292+
return allEditors[0];
293+
}
294+
return null;
295+
}
250296
}

src/toolbox/hardware_category.ts

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import * as Blockly from 'blockly/core';
2929
import * as commonStorage from '../storage/common_storage';
3030
import { getAllPossibleMechanisms } from './blocks_mechanisms';
3131
import { getAllPossibleComponents, getBlocks } from './blocks_components';
32-
import * as MechanismComponentHolder from '../blocks/mrc_mechanism_component_holder';
32+
import * as mechanismComponentHolder from '../blocks/mrc_mechanism_component_holder';
3333

3434
export function getHardwareCategory(currentModule: commonStorage.Module) {
3535
if (currentModule.moduleType === commonStorage.MODULE_TYPE_OPMODE) {
@@ -254,38 +254,24 @@ function getComponentsBlocks(currentModule: commonStorage.Module, hideParams : b
254254
// Get components from the current workspace
255255
const workspace = Blockly.getMainWorkspace();
256256
if (workspace) {
257-
const holderBlocks = workspace.getBlocksByType(MechanismComponentHolder.BLOCK_NAME);
257+
// Get the holder block and ask it for the components.
258+
const holderBlocks = workspace.getBlocksByType(mechanismComponentHolder.BLOCK_NAME);
258259

259260
holderBlocks.forEach(holderBlock => {
260-
// Get component blocks from the COMPONENTS input
261-
const componentsInput = holderBlock.getInput('COMPONENTS');
262-
if (componentsInput && componentsInput.connection) {
263-
let componentBlock = componentsInput.connection.targetBlock();
264-
265-
// Walk through all connected component blocks
266-
while (componentBlock) {
267-
if (componentBlock.type === 'mrc_component') {
268-
const componentName = componentBlock.getFieldValue('NAME');
269-
const componentType = componentBlock.getFieldValue('TYPE');
270-
271-
if (componentName && componentType) {
272-
// Get the blocks for this specific component
273-
contents.push({
274-
kind: 'category',
275-
name: componentName,
276-
contents: getBlocks(componentType, componentName),
277-
});
278-
}
279-
}
280-
// Move to the next block in the chain
281-
componentBlock = componentBlock.getNextBlock();
282-
}
283-
}
261+
const componentsFromHolder: commonStorage.Component[] = holderBlock.getComponents();
262+
componentsFromHolder.forEach(component => {
263+
// Get the blocks for this specific component
264+
contents.push({
265+
kind: 'category',
266+
name: component.name,
267+
contents: getBlocks(component.className, component.name),
268+
});
269+
});
284270
});
285271
}
286272
return {
287273
kind: 'category',
288274
name: 'Components',
289275
contents,
290276
};
291-
}
277+
}

0 commit comments

Comments
 (0)