Skip to content
Closed
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
122 changes: 55 additions & 67 deletions src/blocks/mrc_port.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,28 @@ import { createFieldNumberDropdown } from '../fields/field_number_dropdown';
export const BLOCK_NAME = 'mrc_port';
export const OUTPUT_NAME = 'mrc_port';

export type MrcPortType = {
const FIELD_PREFIX_TYPE = 'TYPE_';
const FIELD_PREFIX_PORT_NUM = 'PORT_NUM_';

const VISIBLE_PORT_TYPE_CAN = 'can';
const VISIBLE_PORT_TYPE_SMART_IO = 'smartio';
const VISIBLE_PORT_TYPE_SMART_MOTOR = 'MotionCore port';
const VISIBLE_PORT_TYPE_I2C = 'i2c';
const VISIBLE_PORT_TYPE_USB = 'usb';
const VISIBLE_PORT_TYPE_MOTOR = 'motor';
const VISIBLE_PORT_TYPE_SERVO = 'servo';
const VISIBLE_PORT_TYPE_USB_HUB_IN = 'usb in';
const VISIBLE_PORT_TYPE_USB_HUB_OUT = 'usb out';

type MrcPortType = {
portType: string,
portNumber: number,
};

type PortBlock = Blockly.Block & PortMixin;
interface PortMixin extends PortMixinType {
portType_ : string,
ports_ : MrcPortType[],
mrcPortType: string,
mrcPorts: MrcPortType[],
}
type PortMixinType = typeof PORT;

Expand All @@ -62,8 +75,8 @@ const PORT = {
*/
saveExtraState: function (this: PortBlock): PortExtraState {
const state: PortExtraState = {
portType: this.portType_,
ports: this.ports_
portType: this.mrcPortType,
ports: this.mrcPorts
};

return state;
Expand All @@ -73,34 +86,15 @@ const PORT = {
* Load the ports from the block's extra state.
*/
loadExtraState: function (this: PortBlock, state: PortExtraState): void {
this.portType_ = state.portType || '';
this.ports_ = state.ports || [];
this.updateShape_();
},

/**
* Update the block's shape based on the current ports.
*/
updateShape_: function (this: PortBlock): void {
// Remove all existing inputs
for (let i = this.inputList.length - 1; i >= 0; i--) {
const input = this.inputList[i];
if (input && (input.name.startsWith('PORT_'))) {
this.removeInput(input.name, true);
}
}

// Initialize ports if not set
if (!this.ports_) {
this.ports_ = [{ portType: '', portNumber: 0 }];
}

// Add inputs for each port
for (let i = 0; i < this.ports_.length; i++) {
const port = this.ports_[i];
this.appendDummyInput('PORT_' + i)
.appendField(createFieldNonEditableText(port.portType), 'TYPE_' + i)
.appendField(createFieldDropdownForPortType(port.portType, port.portNumber), 'PORT_NUM_' + i)
this.mrcPortType = state.portType || '';
this.mrcPorts = state.ports || [];

// Add an input for each port.
for (let i = 0; i < this.mrcPorts.length; i++) {
const port = this.mrcPorts[i];
this.appendDummyInput()
.appendField(createFieldNonEditableText(port.portType), FIELD_PREFIX_TYPE + i)
.appendField(createFieldDropdownForPortType(port.portType, port.portNumber), FIELD_PREFIX_PORT_NUM + i)
.setAlign(Blockly.inputs.Align.RIGHT);
}
},
Expand All @@ -117,25 +111,19 @@ export const pythonFromBlock = function (

const ports: string[] = [];

for (let i = 0; i < block.inputList.length; i++) {
const input = block.inputList[i];
if (input.name.startsWith('PORT_')) {
const portNumField = input.fieldRow.find(field => field.name === 'PORT_NUM_' + i);
if (portNumField) {
ports.push(portNumField.getValue() as string);
}
}
for (let i = 0; i < block.mrcPorts.length; i++) {
ports.push(block.getFieldValue(FIELD_PREFIX_PORT_NUM + i));
}
let code = 'port.';

if (ports.length === 1) {
code += `SimplePort(port_type = port.PortType.${block.portType_}, location = ${ports[0]})`;
code += `SimplePort(port_type = port.PortType.${block.mrcPortType}, location = ${ports[0]})`;

} else if (ports.length === 2) {
let port1Type = 'UNKNOWN';
let port2Type = 'UNKNOWN';

switch (block.portType_) {
switch (block.mrcPortType) {
case 'USB_HUB':
port1Type = 'USB_PORT';
port2Type = 'USB_PORT';
Expand All @@ -149,29 +137,29 @@ export const pythonFromBlock = function (
port2Type = 'EXPANSION_HUB_SERVO_PORT';
break;
}
code += `CompoundPort(port_type = port.PortType.${block.portType_},`;
code += `\\ \n${generator.INDENT}port1 = port.SimplePort(port_type = port.PortType.${port1Type}, location = ${ports[0]}), `;
code += `\\ \n${generator.INDENT}port2 = port.SimplePort(port_type = port.PortType.${port2Type}, location = ${ports[1]}))`;
code += `CompoundPort(port_type = port.PortType.${block.mrcPortType},\n`;
code += `${generator.INDENT}port1 = port.SimplePort(port_type = port.PortType.${port1Type}, location = ${ports[0]}),\n`;
code += `${generator.INDENT}port2 = port.SimplePort(port_type = port.PortType.${port2Type}, location = ${ports[1]}))`;
}

return [code, Order.ATOMIC];
}

function createFieldDropdownForPortType(portType: string, defaultVal: number): Blockly.Field {
switch (portType) {
case 'can':
case VISIBLE_PORT_TYPE_CAN:
return createFieldNumberDropdown(0, 4, defaultVal);
case 'smartio':
case VISIBLE_PORT_TYPE_SMART_IO:
return createFieldNumberDropdown(0, 5, defaultVal);
case 'MotionCore port':
case VISIBLE_PORT_TYPE_SMART_MOTOR:
return createFieldNumberDropdown(1, 6, defaultVal);
case 'i2c':
case VISIBLE_PORT_TYPE_I2C:
return createFieldNumberDropdown(0, 1, defaultVal);
case 'usb in':
case VISIBLE_PORT_TYPE_USB_HUB_IN:
return createFieldNumberDropdown(0, 3, defaultVal);
case 'motor':
case VISIBLE_PORT_TYPE_MOTOR:
return createFieldNumberDropdown(1, 6, defaultVal);
case 'servo':
case VISIBLE_PORT_TYPE_SERVO:
return createFieldNumberDropdown(1, 6, defaultVal);
default:
return createFieldNumberDropdown(0, 99, defaultVal);
Expand All @@ -183,40 +171,40 @@ export function createPort(portType: string) {
const ports: MrcPortType[] = [];
switch (portType) {
case 'CAN_PORT':
ports.push({ portType: 'can', portNumber: 1 });
ports.push({ portType: VISIBLE_PORT_TYPE_CAN, portNumber: 1 });
break;
case 'SMART_IO_PORT':
ports.push({ portType: 'smartio', portNumber: 1 });
ports.push({ portType: VISIBLE_PORT_TYPE_SMART_IO, portNumber: 1 });
break;
case 'SMART_MOTOR_PORT':
ports.push({ portType: 'MotionCore port', portNumber: 1 });
ports.push({ portType: VISIBLE_PORT_TYPE_SMART_MOTOR, portNumber: 1 });
break;
case 'SERVO_PORT':
ports.push({ portType: 'servo', portNumber: 1 });
ports.push({ portType: VISIBLE_PORT_TYPE_SERVO, portNumber: 1 });
break;
case 'I2C_PORT':
ports.push({ portType: 'i2c', portNumber: 1 });
ports.push({ portType: VISIBLE_PORT_TYPE_I2C, portNumber: 1 });
break;
case 'USB_PORT':
ports.push({ portType: 'usb', portNumber: 1 });
ports.push({ portType: VISIBLE_PORT_TYPE_USB, portNumber: 1 });
break;
case 'EXPANSION_HUB_MOTOR_PORT':
ports.push({ portType: 'motor', portNumber: 1 });
ports.push({ portType: VISIBLE_PORT_TYPE_MOTOR, portNumber: 1 });
break;
case 'EXPANSION_HUB_SERVO_PORT':
ports.push({ portType: 'servo', portNumber: 1 });
ports.push({ portType: VISIBLE_PORT_TYPE_SERVO, portNumber: 1 });
break;
case 'USB_HUB':
ports.push({ portType: 'usb in', portNumber: 1 });
ports.push({ portType: 'usb out', portNumber: 1 });
ports.push({ portType: VISIBLE_PORT_TYPE_USB_HUB_IN, portNumber: 1 });
ports.push({ portType: VISIBLE_PORT_TYPE_USB_HUB_OUT, portNumber: 1 });
break;
case 'EXPANSION_HUB_MOTOR':
ports.push({ portType: 'usb in', portNumber: 1 });
ports.push({ portType: 'motor', portNumber: 1 });
ports.push({ portType: VISIBLE_PORT_TYPE_USB_HUB_IN, portNumber: 1 });
ports.push({ portType: VISIBLE_PORT_TYPE_MOTOR, portNumber: 1 });
break;
case 'EXPANSION_HUB_SERVO':
ports.push({ portType: 'usb in', portNumber: 1 });
ports.push({ portType: 'servo', portNumber: 1 });
ports.push({ portType: VISIBLE_PORT_TYPE_USB_HUB_IN, portNumber: 1 });
ports.push({ portType: VISIBLE_PORT_TYPE_SERVO, portNumber: 1 });
break;
default:
ports.push({ portType: 'unknown' + portType, portNumber: 1 });
Expand Down