diff --git a/server_python_scripts/blocks_base_classes/robot_base.py b/server_python_scripts/blocks_base_classes/robot_base.py index a7080d57..51b10ed3 100644 --- a/server_python_scripts/blocks_base_classes/robot_base.py +++ b/server_python_scripts/blocks_base_classes/robot_base.py @@ -7,6 +7,10 @@ def __init__(self): self.hardware = [] # In self.event_handlers, the keys are the event names, the values are a list of handlers. self.event_handlers = {} + self.define_hardware() + + def define_hardware(self): + pass def register_event_handler(self, event_name: str, event_handler: Callable) -> None: if event_name in self.event_handlers: diff --git a/src/blocks/mrc_mechanism_component_holder.ts b/src/blocks/mrc_mechanism_component_holder.ts index bf98c6ad..b0932bdf 100644 --- a/src/blocks/mrc_mechanism_component_holder.ts +++ b/src/blocks/mrc_mechanism_component_holder.ts @@ -1,7 +1,7 @@ /** * @license * Copyright 2025 Porpoiseful LLC - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -64,7 +64,7 @@ function setName(block: Blockly.BlockSvg){ otherNames.push(variableBlock.getFieldValue('NAME')); } }); - const currentName = block.getFieldValue('NAME'); + const currentName = block.getFieldValue('NAME'); block.setFieldValue(getLegalName(currentName, otherNames), 'NAME'); } } @@ -205,8 +205,8 @@ function pythonFromBlockInRobot(block: MechanismComponentHolderBlock, generator: const body = mechanisms + components; if (body != '') { code += body; - generator.addClassMethodDefinition('define_hardware', code); - } + generator.addClassMethodDefinition('define_hardware', code); + } } function pythonFromBlockInMechanism(block: MechanismComponentHolderBlock, generator: ExtendedPythonGenerator) { @@ -218,19 +218,20 @@ function pythonFromBlockInMechanism(block: MechanismComponentHolderBlock, genera if (components != '') { code += components; - generator.addClassMethodDefinition('define_hardware', code); + generator.addClassMethodDefinition('define_hardware', code); } } export const pythonFromBlock = function ( block: MechanismComponentHolderBlock, - generator: ExtendedPythonGenerator, -) { - if (block.getInput(INPUT_MECHANISMS)) { - pythonFromBlockInRobot(block, generator); - } - else { - pythonFromBlockInMechanism(block, generator); + generator: ExtendedPythonGenerator) { + switch (generator.getModuleType()) { + case commonStorage.MODULE_TYPE_ROBOT: + pythonFromBlockInRobot(block, generator); + break; + case commonStorage.MODULE_TYPE_MECHANISM: + pythonFromBlockInMechanism(block, generator); + break; } return '' } diff --git a/src/editor/extended_python_generator.ts b/src/editor/extended_python_generator.ts index 0be37b49..5bed38b1 100644 --- a/src/editor/extended_python_generator.ts +++ b/src/editor/extended_python_generator.ts @@ -29,6 +29,7 @@ import { CLASS_NAME_OPMODE, getClassData, } from '../blocks/utils/python'; +import * as commonStorage from '../storage/common_storage'; export class OpModeDetails { constructor(private name: string, private group : string, private enabled : boolean, private type : string) {} @@ -70,7 +71,7 @@ export class ExtendedPythonGenerator extends PythonGenerator { private workspace: Blockly.Workspace | null = null; private context: GeneratorContext | null = null; - // Has components or mechanisms (ie, needs to call self.define_hardware in __init__) + // Has components or mechanisms (ie, might need to call self.define_hardware in __init__) private hasHardware = false; private ports: {[key: string]: string} = Object.create(null); @@ -112,10 +113,20 @@ export class ExtendedPythonGenerator extends PythonGenerator { let initStatements = ''; if (this.hasHardware) { - initStatements += this.INDENT + "self.define_hardware("; - initStatements += this.getListOfPorts(true); - initStatements += ')\n'; + switch (this.getModuleType()) { + case commonStorage.MODULE_TYPE_ROBOT: + // The RobotBase __init__ method already calls self.define_robot(), so + // we don't need to generate that call here. + break; + case commonStorage.MODULE_TYPE_MECHANISM: + // For mechanisms + initStatements += this.INDENT + "self.define_hardware("; + initStatements += this.getListOfPorts(true); + initStatements += ')\n'; + break; + } } + if (this.hasEventHandler) { initStatements += this.INDENT + "self.register_event_handlers()\n"; } @@ -225,7 +236,14 @@ export class ExtendedPythonGenerator extends PythonGenerator { } classMethods.push(code); } + // Generate the __init__ method first. + if ('__init__' in this.classMethods) { + classMethods.push(this.classMethods['__init__']) + } for (const name in this.classMethods) { + if (name === '__init__') { + continue; + } classMethods.push(this.classMethods[name]) } this.eventHandlers = Object.create(null);