@@ -285,7 +285,23 @@ const MECHANISM = {
285285 if ( this . mrcImportModule !== importModule ) {
286286 this . mrcImportModule = importModule ;
287287 }
288+
289+ // Save the old parameters and the blocks that are connected to their sockets.
290+ const oldParameters : Parameter [ ] = [ ] ;
291+ const oldConnectedBlocks : ( Blockly . Block | null ) [ ] = [ ] ;
292+ for ( let i = 0 ; i < this . mrcParameters . length ; i ++ ) {
293+ oldParameters [ i ] = this . mrcParameters [ i ] ;
294+ const argInput = this . getInput ( 'ARG' + i ) ;
295+ if ( argInput && argInput . connection && argInput . connection . targetBlock ( ) ) {
296+ oldConnectedBlocks [ i ] = argInput . connection . targetBlock ( ) ;
297+ } else {
298+ oldConnectedBlocks [ i ] = null ;
299+ }
300+ }
301+
302+ // Regenerate mrc_parameters and create new inputs if necessary.
288303 this . mrcParameters = [ ] ;
304+ let i = 0 ;
289305 components . forEach ( component => {
290306 let componentPortsIndex = 0 ;
291307 for ( const port in component . ports ) {
@@ -295,10 +311,84 @@ const MECHANISM = {
295311 componentId : component . componentId ,
296312 componentPortsIndex,
297313 } ) ;
314+ let argInput = this . getInput ( 'ARG' + i ) ;
315+ const argField = this . getField ( 'ARGNAME' + i ) ;
316+ if ( argInput && argField ) {
317+ argField . setValue ( port ) ;
318+ } else {
319+ // Add new input.
320+ argInput = this . appendValueInput ( 'ARG' + i )
321+ . setAlign ( Blockly . inputs . Align . RIGHT )
322+ . appendField ( port , 'ARGNAME' + i ) ;
323+ }
324+ // Look in oldParameters to find the matching parameter.
325+ let foundOldParameterIndex = - 1 ;
326+ for ( let j = 0 ; j < oldParameters . length ; j ++ ) {
327+ if ( oldParameters [ j ] . componentId === this . mrcParameters [ i ] . componentId &&
328+ oldParameters [ j ] . componentPortsIndex === this . mrcParameters [ i ] . componentPortsIndex ) {
329+ foundOldParameterIndex = j ;
330+ break ;
331+ }
332+ }
333+ if ( foundOldParameterIndex !== - 1 ) {
334+ if ( foundOldParameterIndex === i ) {
335+ // The old connected block is already connected to this input.
336+ oldConnectedBlocks [ foundOldParameterIndex ] = null ;
337+ } else {
338+ // Move the old connected block to this input.
339+ const oldConnectedBlock = oldConnectedBlocks [ foundOldParameterIndex ] ;
340+ if ( oldConnectedBlock && oldConnectedBlock . outputConnection && argInput . connection ) {
341+ argInput . connection . connect ( oldConnectedBlock . outputConnection ) ;
342+ oldConnectedBlocks [ foundOldParameterIndex ] = null ;
343+ }
344+ }
345+ }
346+ argInput . setCheck ( getAllowedTypesForSetCheck ( this . mrcParameters [ i ] . type ) ) ;
347+
298348 componentPortsIndex ++ ;
349+ i ++ ;
299350 }
300351 } ) ;
301- this . updateBlock_ ( ) ;
352+
353+ // Remove deleted inputs.
354+ for ( let i = this . mrcParameters . length ; this . getInput ( 'ARG' + i ) ; i ++ ) {
355+ this . removeInput ( 'ARG' + i ) ;
356+ }
357+
358+ // Remove old blocks that are no longer connected to input sockets.
359+ for ( let i = 0 ; i < oldConnectedBlocks . length ; i ++ ) {
360+ const oldConnectedBlock = oldConnectedBlocks [ i ] ;
361+ if ( oldConnectedBlock && oldConnectedBlock . outputConnection ) {
362+ if ( ! oldConnectedBlock . outputConnection . isConnected ( ) ) {
363+ oldConnectedBlock . dispose ( ) ;
364+ }
365+ }
366+ }
367+
368+ // Add port blocks to any empty inputs.
369+ for ( let i = 0 ; i < this . mrcParameters . length ; i ++ ) {
370+ let argInput = this . getInput ( 'ARG' + i ) ;
371+ if ( argInput && argInput . connection && ! argInput . connection . targetBlock ( ) ) {
372+ // The input is empty. Create a port block and connect it to the input.
373+ const portBlockState = createPort ( this . mrcParameters [ i ] . type ) ;
374+ const portBlock = this . workspace . newBlock ( portBlockState . type ) as Blockly . BlockSvg ;
375+ if ( portBlockState . extraState && portBlock . loadExtraState ) {
376+ portBlock . loadExtraState ( portBlockState . extraState ) ;
377+ }
378+ if ( portBlockState . fields ) {
379+ const keys = Object . keys ( portBlockState . fields ) ;
380+ for ( let i = 0 ; i < keys . length ; i ++ ) {
381+ const fieldName = keys [ i ] ;
382+ const field = portBlock . getField ( fieldName ) ;
383+ if ( field ) {
384+ field . loadState ( portBlockState . fields [ fieldName ] ) ;
385+ }
386+ }
387+ }
388+ portBlock . initSvg ( ) ;
389+ argInput . connection . connect ( portBlock . outputConnection ) ;
390+ }
391+ }
302392 } else {
303393 // Did not find the mechanism.
304394 warnings . push ( Blockly . Msg [ 'MECHANISM_NOT_FOUND_WARNING' ] ) ;
0 commit comments