@@ -29,25 +29,80 @@ import { ExtendedPythonGenerator } from '../editor/extended_python_generator';
2929export const BLOCK_NAME = 'mrc_port' ;
3030export const OUTPUT_NAME = 'mrc_port' ;
3131
32+ export type MrcPortType = {
33+ portType : string ,
34+ portNumber : number ,
35+ } ;
3236
3337type PortBlock = Blockly . Block & PortMixin ;
3438interface PortMixin extends PortMixinType {
39+ ports_ : MrcPortType [ ] ,
3540}
3641type PortMixinType = typeof PORT ;
3742
43+ type PortExtraState = {
44+ /**
45+ * The ports.
46+ * For instance methods, args[0].name is the self label and args[0].type is
47+ * the self type.
48+ */
49+ ports : MrcPortType [ ] ,
50+ }
51+
3852const PORT = {
3953 /**
4054 * Block initialization.
4155 */
4256 init : function ( this : PortBlock ) : void {
4357 this . setStyle ( MRC_STYLE_PORTS ) ;
44- this . appendDummyInput ( )
45- . appendField ( createFieldNonEditableText ( '' ) , 'TYPE' )
46- . appendField ( new Blockly . FieldTextInput ( '' ) , 'PORT_NUM' ) ;
47-
48- //this.setOutput(true, OUTPUT_NAME);
4958 this . setOutput ( true ) ;
5059 } ,
60+
61+ /**
62+ * Save the ports to the block's extra state.
63+ */
64+ saveExtraState : function ( this : PortBlock ) : PortExtraState {
65+ const state : PortExtraState = {
66+ ports : this . ports_
67+ } ;
68+
69+ return state ;
70+ } ,
71+
72+ /**
73+ * Load the ports from the block's extra state.
74+ */
75+ loadExtraState : function ( this : PortBlock , state : PortExtraState ) : void {
76+ this . ports_ = state . ports || [ ] ;
77+ this . updateShape_ ( ) ;
78+ } ,
79+
80+ /**
81+ * Update the block's shape based on the current ports.
82+ */
83+ updateShape_ : function ( this : PortBlock ) : void {
84+ // Remove all existing inputs
85+ for ( let i = this . inputList . length - 1 ; i >= 0 ; i -- ) {
86+ const input = this . inputList [ i ] ;
87+ if ( input && ( input . name . startsWith ( 'PORT_' ) ) ) {
88+ this . removeInput ( input . name , true ) ;
89+ }
90+ }
91+
92+ // Initialize ports if not set
93+ if ( ! this . ports_ ) {
94+ this . ports_ = [ { portType : '' , portNumber : 0 } ] ;
95+ }
96+
97+ // Add inputs for each port
98+ for ( let i = 0 ; i < this . ports_ . length ; i ++ ) {
99+ const port = this . ports_ [ i ] ;
100+ this . appendDummyInput ( 'PORT_' + i )
101+ . appendField ( createFieldNonEditableText ( port . portType ) , 'TYPE_' + i )
102+ . appendField ( new Blockly . FieldTextInput ( port . portNumber . toString ( ) ) , 'PORT_NUM_' + i )
103+ . setAlign ( Blockly . inputs . Align . RIGHT ) ;
104+ }
105+ } ,
51106}
52107
53108export const setup = function ( ) {
@@ -57,19 +112,56 @@ export const setup = function () {
57112export const pythonFromBlock = function (
58113 block : PortBlock ,
59114 _generator : ExtendedPythonGenerator ) {
60- // TODO (Alan) : Specify the type here as well
61- let code = block . getFieldValue ( 'PORT_NUM' ) ;
62-
115+ const ports : string [ ] = [ ] ;
116+
117+ for ( let i = 0 ; i < block . inputList . length ; i ++ ) {
118+ const input = block . inputList [ i ] ;
119+ if ( input . name . startsWith ( 'PORT_' ) ) {
120+ const portNumField = input . fieldRow . find ( field => field . name === 'PORT_NUM_' + i ) ;
121+ if ( portNumField ) {
122+ ports . push ( portNumField . getValue ( ) as string ) ;
123+ }
124+ }
125+ }
126+
127+ const code = ports . length === 1 ? ports [ 0 ] : `[${ ports . join ( ', ' ) } ]` ;
63128 return [ code , Order . ATOMIC ] ;
64129}
65130
66- export function createPortShadow ( portType : string , portNum : Number ) {
131+ export function createPortShadow ( portType : string ) {
132+ //TODO: Based off of the port type, create the right number and type of ports
133+ const ports : MrcPortType [ ] = [ ] ;
134+ switch ( portType ) {
135+ case 'I2C_PORT' :
136+ ports . push ( { portType : 'i2c' , portNumber : 1 } ) ;
137+ break ;
138+ case 'SMART_IO_PORT' :
139+ ports . push ( { portType : 'smartio' , portNumber : 1 } ) ;
140+ break ;
141+ case 'EXPANSION_MOTOR_PORT' :
142+ ports . push ( { portType : 'usb' , portNumber : 1 } ) ;
143+ ports . push ( { portType : 'motor' , portNumber : 1 } ) ;
144+ break ;
145+ case 'EXPANSION_SERVO_PORT' :
146+ ports . push ( { portType : 'usb' , portNumber : 1 } ) ;
147+ ports . push ( { portType : 'servo' , portNumber : 1 } ) ;
148+ break ;
149+ case 'SMART_MOTOR_PORT' :
150+ ports . push ( { portType : 'MotionCore port' , portNumber : 1 } ) ;
151+ break ;
152+ case 'SERVO_PORT' :
153+ ports . push ( { portType : 'servo' , portNumber : 1 } ) ;
154+ break ;
155+ }
156+
67157 return {
68158 shadow : {
69159 type : 'mrc_port' ,
70- fields : {
71- TYPE : portType ,
72- PORT_NUM : portNum ,
160+ extraState : {
161+ ports : ports . map ( port => ( {
162+ portType : port . portType ,
163+ portNumber : port . portNumber
164+ } ) )
73165 } ,
74166 } ,
75167 } ;
0 commit comments