@@ -47,7 +47,7 @@ def __init__(
4747 "The provided state machine can not be of the HierarchicalMachine type."
4848 )
4949
50- def source_code (self ):
50+ def generate (self ):
5151 self .definitions ()
5252 self .transitions ()
5353
@@ -240,122 +240,130 @@ def callback_state_details(self):
240240 actions = [action ],
241241 )
242242
243- def generate_composite_state (
243+ def get_subflow_state (
244+ self , machine_state : NestedState , state_name : str , actions : List [Action ]
245+ ):
246+ added_states = {}
247+ for i , action in enumerate (actions ):
248+ if action .subFlowRef :
249+ if isinstance (action .subFlowRef , str ):
250+ workflow_id = action .subFlowRef
251+ workflow_version = None
252+ else :
253+ workflow_id = action .subFlowRef .workflowId
254+ workflow_version = action .subFlowRef .version
255+ none_found = True
256+ for sf in self .subflows :
257+ if sf .id == workflow_id and (
258+ (workflow_version and sf .version == workflow_version )
259+ or not workflow_version
260+ ):
261+ none_found = False
262+ new_machine = HierarchicalMachine (
263+ model = None , initial = None , auto_transitions = False
264+ )
265+
266+ # Generate the state machine for the subflow
267+ for index , state in enumerate (sf .states ):
268+ StateMachineGenerator (
269+ state = state ,
270+ state_machine = new_machine ,
271+ is_first_state = index == 0 ,
272+ get_actions = self .get_actions ,
273+ subflows = self .subflows ,
274+ ).generate ()
275+
276+ # Convert the new_machine into a NestedState
277+ added_states [i ] = self .subflow_state_name (
278+ action = action , subflow = sf
279+ )
280+ nested_state = NestedState (added_states [i ])
281+ machine_state .add_substate (nested_state )
282+ self .state_machine_to_nested_state (
283+ state_name = state_name ,
284+ state_machine = new_machine ,
285+ nested_state = nested_state ,
286+ )
287+
288+ if none_found :
289+ warnings .warn (
290+ f"Specified subflow [{ workflow_id } { workflow_version if workflow_version else '' } ] not found." ,
291+ category = UserWarning ,
292+ )
293+ return added_states
294+
295+ def generate_actions_info (
244296 self ,
245297 machine_state : NestedState ,
246298 state_name : str ,
247299 actions : List [Dict [str , Any ]],
248300 action_mode : str = "sequential" ,
249301 ):
250302 parallel_states = []
251-
252303 if actions :
304+ new_subflows_names = self .get_subflow_state (
305+ machine_state = machine_state , state_name = state_name , actions = actions
306+ )
253307 for i , action in enumerate (actions ):
254- fn_name = (
255- self .get_function_name (action .functionRef )
256- if isinstance (action .functionRef , str )
257- else (
258- action .functionRef .refName
259- if isinstance (action .functionRef , FunctionRef )
260- else None
308+ name = None
309+ if action .functionRef :
310+ name = (
311+ self .get_function_name (action .functionRef )
312+ if isinstance (action .functionRef , str )
313+ else (
314+ action .functionRef .refName
315+ if isinstance (action .functionRef , FunctionRef )
316+ else None
317+ )
261318 )
262- )
263- if fn_name :
264- if fn_name not in machine_state .states .keys ():
265- machine_state .add_substate (NestedState (fn_name ))
319+ if name not in machine_state .states .keys ():
320+ machine_state .add_substate (NestedState (name ))
321+ elif action .subFlowRef :
322+ name = new_subflows_names .get (i )
323+ if name :
266324 if action_mode == "sequential" :
267325 if i < len (actions ) - 1 :
268- next_fn_name = (
269- self .get_function_name (actions [i + 1 ].functionRef )
270- if isinstance (actions [i + 1 ].functionRef , str )
271- else (
272- actions [i + 1 ].functionRef .refName
273- if isinstance (
274- actions [i + 1 ].functionRef , FunctionRef
326+ # get next name
327+ next_name = None
328+ if actions [i + 1 ].functionRef :
329+ next_name = (
330+ self .get_function_name (actions [i + 1 ].functionRef )
331+ if isinstance (actions [i + 1 ].functionRef , str )
332+ else (
333+ actions [i + 1 ].functionRef .refName
334+ if isinstance (
335+ actions [i + 1 ].functionRef , FunctionRef
336+ )
337+ else None
275338 )
276- else None
277339 )
278- )
279- if (
280- next_fn_name
281- not in self .state_machine .get_state (
282- state_name
283- ).states .keys ()
284- ):
285- machine_state .add_substate (NestedState (next_fn_name ))
340+ if (
341+ next_name
342+ not in self .state_machine .get_state (
343+ state_name
344+ ).states .keys ()
345+ ):
346+ machine_state .add_substate (NestedState (next_name ))
347+ elif actions [i + 1 ].subFlowRef :
348+ next_name = new_subflows_names .get (i + 1 )
286349 self .state_machine .add_transition (
287350 trigger = "" ,
288- source = f"{ state_name } .{ fn_name } " ,
289- dest = f"{ state_name } .{ next_fn_name } " ,
351+ source = f"{ state_name } .{ name } " ,
352+ dest = f"{ state_name } .{ next_name } " ,
290353 )
291354 if i == 0 :
292- machine_state .initial = fn_name
355+ machine_state .initial = name
293356 elif action_mode == "parallel" :
294- parallel_states .append (fn_name )
357+ parallel_states .append (name )
295358 if action_mode == "parallel" :
296359 machine_state .initial = parallel_states
297360
298- def generate_actions_info (
299- self ,
300- machine_state : NestedState ,
301- state_name : str ,
302- actions : List [Action ],
303- action_mode : str = "sequential" ,
304- ):
305- if actions :
306- if self .get_actions :
307- self .generate_composite_state (
308- machine_state ,
309- state_name ,
310- actions ,
311- action_mode ,
312- )
313- for action in actions :
314- if action .subFlowRef :
315- if isinstance (action .subFlowRef , str ):
316- workflow_id = action .subFlowRef
317- workflow_version = None
318- else :
319- workflow_id = action .subFlowRef .workflowId
320- workflow_version = action .subFlowRef .version
321- none_found = True
322- for sf in self .subflows :
323- if sf .id == workflow_id and (
324- (workflow_version and sf .version == workflow_version )
325- or not workflow_version
326- ):
327- none_found = False
328- new_machine = HierarchicalMachine (
329- model = None , initial = None , auto_transitions = False
330- )
331-
332- # Generate the state machine for the subflow
333- for index , state in enumerate (sf .states ):
334- StateMachineGenerator (
335- state = state ,
336- state_machine = new_machine ,
337- is_first_state = index == 0 ,
338- get_actions = self .get_actions ,
339- subflows = self .subflows ,
340- ).source_code ()
341-
342- # Convert the new_machine into a NestedState
343- nested_state = NestedState (
344- action .name
345- if action .name
346- else f"{ sf .id } /{ sf .version .replace (NestedState .separator , '-' )} "
347- )
348- self .state_machine_to_nested_state (
349- machine_state = machine_state ,
350- state_name = state_name ,
351- state_machine = new_machine ,
352- nested_state = nested_state ,
353- )
354- if none_found :
355- warnings .warn (
356- f"Specified subflow [{ workflow_id } { workflow_version if workflow_version else '' } ] not found." ,
357- category = UserWarning ,
358- )
361+ def subflow_state_name (self , action : Action , subflow : Workflow ):
362+ return (
363+ action .name
364+ if action .name
365+ else f"{ subflow .id } /{ subflow .version .replace (NestedState .separator , '-' )} "
366+ )
359367
360368 def add_all_sub_states (
361369 cls ,
@@ -367,15 +375,14 @@ def add_all_sub_states(
367375 for substate in original_state .states .values ():
368376 new_state .add_substate (ns := NestedState (substate .name ))
369377 cls .add_all_sub_states (substate , ns )
378+ new_state .initial = original_state .initial
370379
371380 def state_machine_to_nested_state (
372381 self ,
373- machine_state : NestedState ,
374382 state_name : str ,
375383 state_machine : HierarchicalMachine ,
376384 nested_state : NestedState ,
377385 ) -> NestedState :
378- machine_state .add_substate (nested_state )
379386 self .add_all_sub_states (state_machine , nested_state )
380387
381388 for trigger , event in state_machine .events .items ():
0 commit comments