@@ -25,6 +25,7 @@ import { MRC_STYLE_MECHANISMS } from '../themes/styles';
2525import * as ChangeFramework from './utils/change_framework' ;
2626import { getLegalName } from './utils/python' ;
2727import { ExtendedPythonGenerator } from '../editor/extended_python_generator' ;
28+ import { Editor } from '../editor/editor' ;
2829import * as storageModule from '../storage/module' ;
2930import * as storageModuleContent from '../storage/module_content' ;
3031import { BLOCK_NAME as MRC_MECHANISM_NAME } from './mrc_mechanism' ;
@@ -41,17 +42,20 @@ export const BLOCK_NAME = 'mrc_mechanism_component_holder';
4142
4243const INPUT_MECHANISMS = 'MECHANISMS' ;
4344const INPUT_COMPONENTS = 'COMPONENTS' ;
45+ const INPUT_PRIVATE_COMPONENTS = 'PRIVATE_COMPONENTS' ;
4446const INPUT_EVENTS = 'EVENTS' ;
4547
4648export const TOOLBOX_UPDATE_EVENT = 'toolbox-update-requested' ;
4749
4850type MechanismComponentHolderExtraState = {
4951 hideMechanisms ?: boolean ;
52+ hidePrivateComponents ?: boolean ;
5053}
5154
5255export type MechanismComponentHolderBlock = Blockly . Block & MechanismComponentHolderMixin ;
5356interface MechanismComponentHolderMixin extends MechanismComponentHolderMixinType {
5457 mrcHideMechanisms : boolean ;
58+ mrcHidePrivateComponents : boolean ;
5559}
5660type MechanismComponentHolderMixinType = typeof MECHANISM_COMPONENT_HOLDER ;
5761
@@ -78,9 +82,9 @@ const MECHANISM_COMPONENT_HOLDER = {
7882 this . setInputsInline ( false ) ;
7983 this . appendStatementInput ( INPUT_MECHANISMS ) . setCheck ( MECHANISM_OUTPUT ) . appendField ( Blockly . Msg . MECHANISMS ) ;
8084 this . appendStatementInput ( INPUT_COMPONENTS ) . setCheck ( COMPONENT_OUTPUT ) . appendField ( Blockly . Msg . COMPONENTS ) ;
85+ this . appendStatementInput ( INPUT_PRIVATE_COMPONENTS ) . setCheck ( COMPONENT_OUTPUT ) . appendField ( Blockly . Msg . PRIVATE_COMPONENTS ) ;
8186 this . appendStatementInput ( INPUT_EVENTS ) . setCheck ( EVENT_OUTPUT ) . appendField ( Blockly . Msg . EVENTS ) ;
8287
83-
8488 this . setOutput ( false ) ;
8589 this . setStyle ( MRC_STYLE_MECHANISMS ) ;
8690 ChangeFramework . registerCallback ( MRC_COMPONENT_NAME , [ Blockly . Events . BLOCK_MOVE , Blockly . Events . BLOCK_CHANGE ] , this . onBlockChanged ) ;
@@ -95,30 +99,48 @@ const MECHANISM_COMPONENT_HOLDER = {
9599 if ( this . mrcHideMechanisms == true ) {
96100 extraState . hideMechanisms = this . mrcHideMechanisms ;
97101 }
102+ if ( this . mrcHidePrivateComponents == true ) {
103+ extraState . hidePrivateComponents = this . mrcHidePrivateComponents ;
104+ }
98105 return extraState ;
99106 } ,
100107 /**
101108 * Applies the given state to this block.
102109 */
103110 loadExtraState : function ( this : MechanismComponentHolderBlock , extraState : MechanismComponentHolderExtraState ) : void {
104111 this . mrcHideMechanisms = ( extraState . hideMechanisms == undefined ) ? false : extraState . hideMechanisms ;
112+ this . mrcHidePrivateComponents = ( extraState . hidePrivateComponents == undefined ) ? false : extraState . hidePrivateComponents ;
105113 this . updateBlock_ ( ) ;
106114 } ,
107115 /**
108116 * Update the block to reflect the newly loaded extra state.
109117 */
110118 updateBlock_ : function ( this : MechanismComponentHolderBlock ) : void {
119+ // Handle mechanisms input visibility
111120 if ( this . mrcHideMechanisms ) {
112121 if ( this . getInput ( INPUT_MECHANISMS ) ) {
113122 this . removeInput ( INPUT_MECHANISMS )
114123 }
115124 }
116125 else {
117126 if ( this . getInput ( INPUT_MECHANISMS ) == null ) {
118- this . appendStatementInput ( INPUT_MECHANISMS ) . setCheck ( MECHANISM_OUTPUT ) . appendField ( 'Mechanisms' ) ;
127+ this . appendStatementInput ( INPUT_MECHANISMS ) . setCheck ( MECHANISM_OUTPUT ) . appendField ( Blockly . Msg . MECHANISMS ) ;
119128 this . moveInputBefore ( INPUT_MECHANISMS , INPUT_COMPONENTS )
120129 }
121130 }
131+
132+ // Handle private components input visibility
133+ if ( this . mrcHidePrivateComponents ) {
134+ if ( this . getInput ( INPUT_PRIVATE_COMPONENTS ) ) {
135+ this . removeInput ( INPUT_PRIVATE_COMPONENTS )
136+ }
137+ }
138+ else {
139+ if ( this . getInput ( INPUT_PRIVATE_COMPONENTS ) == null ) {
140+ this . appendStatementInput ( INPUT_PRIVATE_COMPONENTS ) . setCheck ( COMPONENT_OUTPUT ) . appendField ( Blockly . Msg . PRIVATE_COMPONENTS ) ;
141+ this . moveInputBefore ( INPUT_PRIVATE_COMPONENTS , INPUT_EVENTS )
142+ }
143+ }
122144 } ,
123145 onBlockChanged : function ( block : Blockly . BlockSvg , blockEvent : Blockly . Events . BlockBase ) {
124146 if ( blockEvent . type == Blockly . Events . BLOCK_MOVE ) {
@@ -179,6 +201,28 @@ const MECHANISM_COMPONENT_HOLDER = {
179201
180202 return components ;
181203 } ,
204+ getPrivateComponents : function ( this : MechanismComponentHolderBlock ) : storageModuleContent . Component [ ] {
205+ const components : storageModuleContent . Component [ ] = [ ]
206+
207+ // Get component blocks from the PRIVATE_COMPONENTS input
208+ const privateComponentsInput = this . getInput ( INPUT_PRIVATE_COMPONENTS ) ;
209+ if ( privateComponentsInput && privateComponentsInput . connection ) {
210+ // Walk through all connected component blocks.
211+ let componentBlock = privateComponentsInput . connection . targetBlock ( ) ;
212+ while ( componentBlock ) {
213+ if ( componentBlock . type === MRC_COMPONENT_NAME ) {
214+ const component = ( componentBlock as ComponentBlock ) . getComponent ( ) ;
215+ if ( component ) {
216+ components . push ( component ) ;
217+ }
218+ }
219+ // Move to the next block in the chain
220+ componentBlock = componentBlock . getNextBlock ( ) ;
221+ }
222+ }
223+
224+ return components ;
225+ } ,
182226 getEvents : function ( this : MechanismComponentHolderBlock ) : storageModuleContent . Event [ ] {
183227 const events : storageModuleContent . Event [ ] = [ ]
184228
@@ -243,9 +287,11 @@ function pythonFromBlockInMechanism(block: MechanismComponentHolderBlock, genera
243287 code += '):\n' ;
244288
245289 const components = generator . statementToCode ( block , INPUT_COMPONENTS ) ;
290+ const privateComponents = generator . statementToCode ( block , INPUT_PRIVATE_COMPONENTS ) ;
246291
247- if ( components ) {
248- code += components ;
292+ const body = components + privateComponents ;
293+ if ( body ) {
294+ code += body ;
249295 generator . addClassMethodDefinition ( 'define_hardware' , code ) ;
250296 }
251297}
@@ -272,6 +318,7 @@ export const pythonFromBlock = function (
272318 */
273319export function hasAnyComponents ( workspace : Blockly . Workspace ) : boolean {
274320 for ( const block of workspace . getBlocksByType ( BLOCK_NAME ) ) {
321+ // Check regular components
275322 const componentsInput = block . getInput ( INPUT_COMPONENTS ) ;
276323 if ( componentsInput && componentsInput . connection ) {
277324 // Walk through all connected component blocks.
@@ -284,6 +331,20 @@ export function hasAnyComponents(workspace: Blockly.Workspace): boolean {
284331 componentBlock = componentBlock . getNextBlock ( ) ;
285332 }
286333 }
334+
335+ // Check private components
336+ const privateComponentsInput = block . getInput ( INPUT_PRIVATE_COMPONENTS ) ;
337+ if ( privateComponentsInput && privateComponentsInput . connection ) {
338+ // Walk through all connected private component blocks.
339+ let componentBlock = privateComponentsInput . connection . targetBlock ( ) ;
340+ while ( componentBlock ) {
341+ if ( componentBlock . type === MRC_COMPONENT_NAME && componentBlock . isEnabled ( ) ) {
342+ return true ;
343+ }
344+ // Move to the next block in the chain
345+ componentBlock = componentBlock . getNextBlock ( ) ;
346+ }
347+ }
287348 }
288349 return false ;
289350}
@@ -305,6 +366,20 @@ export function getComponentPorts(workspace: Blockly.Workspace, ports: {[key: st
305366 componentBlock = componentBlock . getNextBlock ( ) ;
306367 }
307368 }
369+
370+ // Also include private components for port collection
371+ const privateComponentsInput = block . getInput ( INPUT_PRIVATE_COMPONENTS ) ;
372+ if ( privateComponentsInput && privateComponentsInput . connection ) {
373+ // Walk through all connected private component blocks.
374+ let componentBlock = privateComponentsInput . connection . targetBlock ( ) ;
375+ while ( componentBlock ) {
376+ if ( componentBlock . type === MRC_COMPONENT_NAME && componentBlock . isEnabled ( ) ) {
377+ ( componentBlock as ComponentBlock ) . getComponentPorts ( ports ) ;
378+ }
379+ // Move to the next block in the chain
380+ componentBlock = componentBlock . getNextBlock ( ) ;
381+ }
382+ }
308383 } ) ;
309384}
310385
@@ -330,6 +405,25 @@ export function getComponents(
330405 } ) ;
331406}
332407
408+ export function getPrivateComponents (
409+ workspace : Blockly . Workspace ,
410+ components : storageModuleContent . Component [ ] ) : void {
411+ // Get the holder block and ask it for the private components.
412+ workspace . getBlocksByType ( BLOCK_NAME ) . forEach ( block => {
413+ const privateComponentsFromHolder : storageModuleContent . Component [ ] =
414+ ( block as MechanismComponentHolderBlock ) . getPrivateComponents ( ) ;
415+ components . push ( ...privateComponentsFromHolder ) ;
416+ } ) ;
417+ }
418+
419+ export function getAllComponents (
420+ workspace : Blockly . Workspace ,
421+ components : storageModuleContent . Component [ ] ) : void {
422+ // Get both regular and private components for when creating a mechanism
423+ getComponents ( workspace , components ) ;
424+ getPrivateComponents ( workspace , components ) ;
425+ }
426+
333427export function getEvents (
334428 workspace : Blockly . Workspace ,
335429 events : storageModuleContent . Event [ ] ) : void {
0 commit comments