Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions src/blocks/mrc_call_python_function.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { getClassData, getAllowedTypesForSetCheck, getOutputCheck } from './util
import { FunctionData, findSuperFunctionData } from './utils/python_json_types';
import * as value from './utils/value';
import * as variable from './utils/variable';
import { Editor } from '../editor/editor';
import { ExtendedPythonGenerator } from '../editor/extended_python_generator';
import { createFieldDropdown } from '../fields/FieldDropdown';
import { createFieldNonEditableText } from '../fields/FieldNonEditableText';
Expand Down Expand Up @@ -542,9 +543,13 @@ const CALL_PYTHON_FUNCTION = {
break;
}
case FunctionKind.INSTANCE_COMPONENT: {
// TODO: We need the list of component names for this.mrcComponentClassName so we can
let componentNames: string[] = [];
// Get the list of component names whose type matches this.mrcComponentClassName so we can
// create a dropdown that has the appropriate component names.
const componentNames: string[] = [];
const editor = Editor.getEditorForBlocklyWorkspace(this.workspace);
if (editor) {
componentNames = editor.getComponentNames(this.mrcComponentClassName);
}
const componentName = this.getComponentName();
if (!componentNames.includes(componentName)) {
componentNames.push(componentName);
Expand Down
29 changes: 28 additions & 1 deletion src/blocks/mrc_mechanism_component_holder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { MRC_STYLE_MECHANISMS } from '../themes/styles';
import * as ChangeFramework from './utils/change_framework';
import { getLegalName } from './utils/python';
import { ExtendedPythonGenerator } from '../editor/extended_python_generator';
import * as commonStorage from '../storage/common_storage';
import { OUTPUT_NAME as MECHANISM_OUTPUT } from './mrc_mechanism';
import { BLOCK_NAME as MRC_MECHANISM_NAME } from './mrc_mechanism';
import { BLOCK_NAME as MRC_COMPONENT_NAME } from './mrc_component';
Expand Down Expand Up @@ -127,7 +128,33 @@ const MECHANISM_COMPONENT_HOLDER = {
}
}
},
getComponents: function (this: MechanismComponentHolderBlock): commonStorage.Component[] {
const components: commonStorage.Component[] = []

// Get component blocks from the COMPONENTS input
const componentsInput = this.getInput('COMPONENTS');
if (componentsInput && componentsInput.connection) {
// Walk through all connected component blocks.
let componentBlock = componentsInput.connection.targetBlock();
while (componentBlock) {
if (componentBlock.type === 'mrc_component') {
const componentName = componentBlock.getFieldValue('NAME');
const componentType = componentBlock.getFieldValue('TYPE');

if (componentName && componentType) {
components.push({
name: componentName,
className: componentType,
});
}
}
// Move to the next block in the chain
componentBlock = componentBlock.getNextBlock();
}
}

return components;
},
}

let toolboxUpdateTimeout: NodeJS.Timeout | null = null;
Expand Down Expand Up @@ -190,4 +217,4 @@ export const pythonFromBlock = function (
pythonFromBlockInMechanism(block, generator);
}
return ''
}
}
52 changes: 49 additions & 3 deletions src/editor/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import * as Blockly from 'blockly/core';
import { extendedPythonGenerator } from './extended_python_generator';
import { GeneratorContext } from './generator_context';
import * as commonStorage from '../storage/common_storage';

import * as mechanismComponentHolder from '../blocks/mrc_mechanism_component_holder';
//import { testAllBlocksInToolbox } from '../toolbox/toolbox_tests';
import { MethodsCategory} from '../toolbox/methods_category';
import { EventsCategory} from '../toolbox/event_category';
Expand Down Expand Up @@ -151,7 +151,7 @@ export class Editor {
);
this.moduleContent = moduleContents[this.modulePath];
if (this.robotPath === this.modulePath) {
this.robotContent = this.moduleContent
this.robotContent = this.moduleContent;
} else {
this.robotContent = moduleContents[this.robotPath];
}
Expand Down Expand Up @@ -233,7 +233,14 @@ export class Editor {
const components: commonStorage.Component[] = [];
if (this.currentModule?.moduleType === commonStorage.MODULE_TYPE_ROBOT ||
this.currentModule?.moduleType === commonStorage.MODULE_TYPE_MECHANISM) {
// TODO(lizlooney): Fill the components array.
// Get the holder block and ask it for the components.
const holderBlocks = this.blocklyWorkspace.getBlocksByType(mechanismComponentHolder.BLOCK_NAME);
holderBlocks.forEach(holderBlock => {
const componentsFromHolder: commonStorage.Component[] = holderBlock.getComponents();
componentsFromHolder.forEach(component => {
components.push(component);
});
});
}
return components;
}
Expand All @@ -247,4 +254,43 @@ export class Editor {
throw e;
}
}

/**
* Returns the names of components defined in the robot that have the given component class name.
*/
// TODO: what about components defined in a mechanism?
public getComponentNames(componentClassName: string): string[] {
let components: commonStorage.Component[];

if (this.currentModule?.moduleType === commonStorage.MODULE_TYPE_ROBOT) {
components = this.getComponents();
} else {
if (!this.robotContent) {
throw new Error('getComponentNames: this.robotContent is null.');
}
components = commonStorage.extractComponents(this.robotContent);
}

const componentNames: string[] = [];
components.forEach((component) => {
if (component.className === componentClassName) {
componentNames.push(component.name);
}
});
return componentNames;
}

public static getEditorForBlocklyWorkspace(workspace: Blockly.Workspace): Editor | null {
if (workspace.id in Editor.workspaceIdToEditor) {
return Editor.workspaceIdToEditor[workspace.id];
}

// If the workspace id was not found, it might be because the workspace is associated with the
// toolbox flyout, not a real workspace. In that case, use the first editor.
const allEditors = Object.values(Editor.workspaceIdToEditor);
if (allEditors.length) {
return allEditors[0];
}
return null;
}
}
40 changes: 13 additions & 27 deletions src/toolbox/hardware_category.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import * as Blockly from 'blockly/core';
import * as commonStorage from '../storage/common_storage';
import { getAllPossibleMechanisms } from './blocks_mechanisms';
import { getAllPossibleComponents, getBlocks } from './blocks_components';
import * as MechanismComponentHolder from '../blocks/mrc_mechanism_component_holder';
import * as mechanismComponentHolder from '../blocks/mrc_mechanism_component_holder';

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

holderBlocks.forEach(holderBlock => {
// Get component blocks from the COMPONENTS input
const componentsInput = holderBlock.getInput('COMPONENTS');
if (componentsInput && componentsInput.connection) {
let componentBlock = componentsInput.connection.targetBlock();

// Walk through all connected component blocks
while (componentBlock) {
if (componentBlock.type === 'mrc_component') {
const componentName = componentBlock.getFieldValue('NAME');
const componentType = componentBlock.getFieldValue('TYPE');

if (componentName && componentType) {
// Get the blocks for this specific component
contents.push({
kind: 'category',
name: componentName,
contents: getBlocks(componentType, componentName),
});
}
}
// Move to the next block in the chain
componentBlock = componentBlock.getNextBlock();
}
}
const componentsFromHolder: commonStorage.Component[] = holderBlock.getComponents();
componentsFromHolder.forEach(component => {
// Get the blocks for this specific component
contents.push({
kind: 'category',
name: component.name,
contents: getBlocks(component.className, component.name),
});
});
});
}
return {
kind: 'category',
name: 'Components',
contents,
};
}
}