From 02e6f3b595a80064961123e8328179645e475b35 Mon Sep 17 00:00:00 2001 From: Liz Looney Date: Thu, 18 Sep 2025 22:38:49 -0700 Subject: [PATCH 1/2] In blocks that have an mrcOnLoad method, create a method called mrcValidate. Make mrcOnLoad call mrcValidate. In editor.makeCurrent, call the mrcValidate method on all blocks that implement it. --- src/blocks/mrc_call_python_function.ts | 16 +++++++++++++--- src/blocks/mrc_event_handler.ts | 7 +++++++ src/blocks/mrc_mechanism.ts | 13 ++++++++++++- src/editor/editor.ts | 7 +++++++ 4 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/blocks/mrc_call_python_function.ts b/src/blocks/mrc_call_python_function.ts index 460e927a..359703d8 100644 --- a/src/blocks/mrc_call_python_function.ts +++ b/src/blocks/mrc_call_python_function.ts @@ -318,7 +318,7 @@ const CALL_PYTHON_FUNCTION = { this.mrcMechanismId = extraState.mechanismId ? extraState.mechanismId : ''; this.mrcComponentClassName = extraState.componentClassName ? extraState.componentClassName : ''; this.mrcMechanismClassName = extraState.mechanismClassName ? extraState.mechanismClassName : ''; - // Initialize mrcComponentNames and mrcMapComponentNameToId here. They will be filled during mrcOnLoad. + // Initialize mrcComponentNames and mrcMapComponentNameToId here. They will be filled during mrcValidate. this.mrcComponentNames = []; this.mrcMapComponentNameToId = {}; this.updateBlock_(); @@ -405,7 +405,7 @@ const CALL_PYTHON_FUNCTION = { .appendField('.'); } // Here we create a text field for the component name. - // Later, in mrcOnLoad, we will replace it with a dropdown. + // Later, in mrcValidate, we will replace it with a dropdown. titleInput .appendField(createFieldNonEditableText(''), FIELD_COMPONENT_NAME) .appendField('.') @@ -565,8 +565,18 @@ const CALL_PYTHON_FUNCTION = { } return components; }, + /** + * mrcOnLoad is called for each CallPythonFunctionBlock when the blocks are loaded in the blockly + * workspace. + */ mrcOnLoad: function(this: CallPythonFunctionBlock): void { - // mrcOnLoad is called for each CallPythonFunctionBlock when the blocks are loaded in the blockly workspace. + this.mrcValidate(); + }, + /** + * mrcValidate checks the block, updates it, and/or adds a warning balloon if necessary. + * It is called from mrcOnLoad above and from Editor.makeCurrent. + */ + mrcValidate: function(this: CallPythonFunctionBlock): void { const editor = Editor.getEditorForBlocklyWorkspace(this.workspace, true /* returnCurrentIfNotFound */); if (!editor) { return; diff --git a/src/blocks/mrc_event_handler.ts b/src/blocks/mrc_event_handler.ts index a4447c84..e97d2dd9 100644 --- a/src/blocks/mrc_event_handler.ts +++ b/src/blocks/mrc_event_handler.ts @@ -176,6 +176,13 @@ const EVENT_HANDLER = { * workspace. */ mrcOnLoad: function(this: EventHandlerBlock): void { + this.mrcValidate(); + }, + /** + * mrcValidate checks the block, updates it, and/or adds a warning balloon if necessary. + * It is called from mrcOnLoad above and from Editor.makeCurrent. + */ + mrcValidate: function(this: EventHandlerBlock): void { const warnings: string[] = []; const editor = Editor.getEditorForBlocklyWorkspace(this.workspace, true /* returnCurrentIfNotFound */); diff --git a/src/blocks/mrc_mechanism.ts b/src/blocks/mrc_mechanism.ts index a8da1991..ffda819f 100644 --- a/src/blocks/mrc_mechanism.ts +++ b/src/blocks/mrc_mechanism.ts @@ -174,8 +174,19 @@ const MECHANISM = { className: mechanismType, }; }, + + /** + * mrcOnLoad is called for each MechanismBlock when the blocks are loaded in the blockly + * workspace. + */ mrcOnLoad: function(this: MechanismBlock): void { - // mrcOnLoad is called for each MechanismBlock when the blocks are loaded in the blockly workspace. + this.mrcValidate(); + }, + /** + * mrcValidate checks the block, updates it, and/or adds a warning balloon if necessary. + * It is called from mrcOnLoad above and from Editor.makeCurrent. + */ + mrcValidate: function(this: MechanismBlock): void { const warnings: string[] = []; const editor = Editor.getEditorForBlocklyWorkspace(this.workspace, true /* returnCurrentIfNotFound */); diff --git a/src/editor/editor.ts b/src/editor/editor.ts index 7dc1d0e1..922af4f4 100644 --- a/src/editor/editor.ts +++ b/src/editor/editor.ts @@ -129,6 +129,13 @@ export class Editor { // Parse modules since they might have changed. this.parseModules(project, modulePathToContentText); this.updateToolboxImpl(); + + // Go through all the blocks in the workspace and call their mrcValidate method. + this.blocklyWorkspace.getAllBlocks().forEach(block => { + if ('mrcValidate' in block && typeof block.mrcValidate === "function") { + block.mrcValidate(); + } + }); } public abandon(): void { From 1b4031095fe7c74c17b3f9552ac322e7820c3dc3 Mon Sep 17 00:00:00 2001 From: Liz Looney Date: Fri, 19 Sep 2025 09:58:13 -0700 Subject: [PATCH 2/2] Define and use constants for mrcOnLoad and mrcValidate. Changed double quotes to single quotes. --- src/editor/editor.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/editor/editor.ts b/src/editor/editor.ts index 922af4f4..d6af2575 100644 --- a/src/editor/editor.ts +++ b/src/editor/editor.ts @@ -38,6 +38,9 @@ const EMPTY_TOOLBOX: Blockly.utils.toolbox.ToolboxDefinition = { contents: [], }; +const MRC_ON_LOAD = 'mrcOnLoad'; +const MRC_VALIDATE = 'mrcValidate'; + export class Editor { private static workspaceIdToEditor: { [workspaceId: string]: Editor } = {}; private static currentEditor: Editor | null = null; @@ -97,8 +100,8 @@ export class Editor { blockCreateEvent.ids.forEach(id => { const block = this.blocklyWorkspace.getBlockById(id); if (block) { - if ('mrcOnLoad' in block && typeof block.mrcOnLoad === "function") { - block.mrcOnLoad(); + if (MRC_ON_LOAD in block && typeof block[MRC_ON_LOAD] === 'function') { + block[MRC_ON_LOAD](); } } }); @@ -132,8 +135,8 @@ export class Editor { // Go through all the blocks in the workspace and call their mrcValidate method. this.blocklyWorkspace.getAllBlocks().forEach(block => { - if ('mrcValidate' in block && typeof block.mrcValidate === "function") { - block.mrcValidate(); + if (MRC_VALIDATE in block && typeof block[MRC_VALIDATE] === 'function') { + block[MRC_VALIDATE](); } }); } @@ -165,8 +168,8 @@ export class Editor { for (const mechanism of this.mechanisms) { const moduleContent = this.modulePathToModuleContent[mechanism.modulePath]; if (!moduleContent) { - console.error(this.modulePath + " editor.parseModules - modulePathToModuleContent['" + - mechanism.modulePath + "'] is undefined"); + console.error(this.modulePath + ' editor.parseModules - modulePathToModuleContent["' + + mechanism.modulePath + '"] is undefined'); continue; } this.mechanismClassNameToModuleContent[mechanism.className] = moduleContent;