@@ -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
@@ -182,12 +182,16 @@ def parallel_state_details(self):
182182 branches = self .state .branches
183183 if branches :
184184 if self .get_actions :
185+ self .state_machine .get_state (state_name ).initial = []
185186 for branch in branches :
186187 if hasattr (branch , "actions" ) and branch .actions :
187188 branch_name = branch .name
188189 self .state_machine .get_state (state_name ).add_substates (
189190 NestedState (branch_name )
190191 )
192+ self .state_machine .get_state (state_name ).initial .append (
193+ branch_name
194+ )
191195 branch_state = self .state_machine .get_state (
192196 state_name
193197 ).states [branch .name ]
@@ -196,12 +200,6 @@ def parallel_state_details(self):
196200 state_name = f"{ state_name } .{ branch_name } " ,
197201 actions = branch .actions ,
198202 )
199- self .generate_composite_state (
200- branch_state ,
201- f"{ state_name } .{ branch_name } " ,
202- branch .actions ,
203- "sequential" ,
204- )
205203
206204 def event_based_switch_state_details (self ): ...
207205
@@ -242,119 +240,130 @@ def callback_state_details(self):
242240 actions = [action ],
243241 )
244242
245- 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 (
246296 self ,
247297 machine_state : NestedState ,
248298 state_name : str ,
249299 actions : List [Dict [str , Any ]],
250300 action_mode : str = "sequential" ,
251301 ):
252302 parallel_states = []
253-
254303 if actions :
304+ new_subflows_names = self .get_subflow_state (
305+ machine_state = machine_state , state_name = state_name , actions = actions
306+ )
255307 for i , action in enumerate (actions ):
256- fn_name = (
257- self .get_function_name (action .functionRef )
258- if isinstance (action .functionRef , str )
259- else (
260- action .functionRef .refName
261- if isinstance (action .functionRef , FunctionRef )
262- 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+ )
263318 )
264- )
265- if fn_name :
266- if fn_name not in machine_state .states .keys ():
267- 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 :
268324 if action_mode == "sequential" :
269325 if i < len (actions ) - 1 :
270- next_fn_name = (
271- self .get_function_name (actions [i + 1 ].functionRef )
272- if isinstance (actions [i + 1 ].functionRef , str )
273- else (
274- actions [i + 1 ].functionRef .refName
275- if isinstance (
276- 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
277338 )
278- else None
279339 )
280- )
281- if (
282- next_fn_name
283- not in self .state_machine .get_state (
284- state_name
285- ).states .keys ()
286- ):
287- 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 )
288349 self .state_machine .add_transition (
289350 trigger = "" ,
290- source = f"{ state_name } .{ fn_name } " ,
291- dest = f"{ state_name } .{ next_fn_name } " ,
351+ source = f"{ state_name } .{ name } " ,
352+ dest = f"{ state_name } .{ next_name } " ,
292353 )
293354 if i == 0 :
294- machine_state .initial = fn_name
355+ machine_state .initial = name
295356 elif action_mode == "parallel" :
296- parallel_states .append (fn_name )
357+ parallel_states .append (name )
297358 if action_mode == "parallel" :
298359 machine_state .initial = parallel_states
299360
300- def generate_actions_info (
301- self ,
302- machine_state : NestedState ,
303- state_name : str ,
304- actions : List [Action ],
305- action_mode : str = "sequential" ,
306- ):
307- if actions :
308- if self .get_actions :
309- self .generate_composite_state (
310- machine_state ,
311- state_name ,
312- actions ,
313- action_mode ,
314- )
315- for action in actions :
316- if action .subFlowRef :
317- if isinstance (action .subFlowRef , str ):
318- workflow_id = action .subFlowRef
319- workflow_version = None
320- else :
321- workflow_id = action .subFlowRef .workflowId
322- workflow_version = action .subFlowRef .version
323- none_found = True
324- for sf in self .subflows :
325- if sf .id == workflow_id and (
326- (workflow_version and sf .version == workflow_version )
327- or not workflow_version
328- ):
329- none_found = False
330- new_machine = HierarchicalMachine (
331- model = None , initial = None , auto_transitions = False
332- )
333-
334- # Generate the state machine for the subflow
335- for index , state in enumerate (sf .states ):
336- StateMachineGenerator (
337- state = state ,
338- state_machine = new_machine ,
339- is_first_state = index == 0 ,
340- get_actions = self .get_actions ,
341- subflows = self .subflows ,
342- ).source_code ()
343-
344- # Convert the new_machine into a NestedState
345- nested_state = NestedState (
346- action .name
347- if action .name
348- else f"{ sf .id } /{ sf .version .replace (NestedState .separator , '-' )} "
349- )
350- self .state_machine_to_nested_state (
351- state_machine = new_machine , nested_state = nested_state
352- )
353- if none_found :
354- warnings .warn (
355- f"Specified subflow [{ workflow_id } { workflow_version if workflow_version else '' } ] not found." ,
356- category = UserWarning ,
357- )
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+ )
358367
359368 def add_all_sub_states (
360369 cls ,
@@ -366,12 +375,14 @@ def add_all_sub_states(
366375 for substate in original_state .states .values ():
367376 new_state .add_substate (ns := NestedState (substate .name ))
368377 cls .add_all_sub_states (substate , ns )
378+ new_state .initial = original_state .initial
369379
370380 def state_machine_to_nested_state (
371- self , state_machine : HierarchicalMachine , nested_state : NestedState
381+ self ,
382+ state_name : str ,
383+ state_machine : HierarchicalMachine ,
384+ nested_state : NestedState ,
372385 ) -> NestedState :
373- self .state_machine .get_state (self .state .name ).add_substate (nested_state )
374-
375386 self .add_all_sub_states (state_machine , nested_state )
376387
377388 for trigger , event in state_machine .events .items ():
@@ -381,8 +392,8 @@ def state_machine_to_nested_state(
381392 dest = transition .dest
382393 self .state_machine .add_transition (
383394 trigger = trigger ,
384- source = f"{ self . state . name } .{ nested_state .name } .{ source } " ,
385- dest = f"{ self . state . name } .{ nested_state .name } .{ dest } " ,
395+ source = f"{ state_name } .{ nested_state .name } .{ source } " ,
396+ dest = f"{ state_name } .{ nested_state .name } .{ dest } " ,
386397 )
387398
388399 def get_function_name (
0 commit comments