@@ -47,7 +47,7 @@ def __init__(
47
47
"The provided state machine can not be of the HierarchicalMachine type."
48
48
)
49
49
50
- def source_code (self ):
50
+ def generate (self ):
51
51
self .definitions ()
52
52
self .transitions ()
53
53
@@ -182,12 +182,16 @@ def parallel_state_details(self):
182
182
branches = self .state .branches
183
183
if branches :
184
184
if self .get_actions :
185
+ self .state_machine .get_state (state_name ).initial = []
185
186
for branch in branches :
186
187
if hasattr (branch , "actions" ) and branch .actions :
187
188
branch_name = branch .name
188
189
self .state_machine .get_state (state_name ).add_substates (
189
190
NestedState (branch_name )
190
191
)
192
+ self .state_machine .get_state (state_name ).initial .append (
193
+ branch_name
194
+ )
191
195
branch_state = self .state_machine .get_state (
192
196
state_name
193
197
).states [branch .name ]
@@ -196,12 +200,6 @@ def parallel_state_details(self):
196
200
state_name = f"{ state_name } .{ branch_name } " ,
197
201
actions = branch .actions ,
198
202
)
199
- self .generate_composite_state (
200
- branch_state ,
201
- f"{ state_name } .{ branch_name } " ,
202
- branch .actions ,
203
- "sequential" ,
204
- )
205
203
206
204
def event_based_switch_state_details (self ): ...
207
205
@@ -242,119 +240,130 @@ def callback_state_details(self):
242
240
actions = [action ],
243
241
)
244
242
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 (
246
296
self ,
247
297
machine_state : NestedState ,
248
298
state_name : str ,
249
299
actions : List [Dict [str , Any ]],
250
300
action_mode : str = "sequential" ,
251
301
):
252
302
parallel_states = []
253
-
254
303
if actions :
304
+ new_subflows_names = self .get_subflow_state (
305
+ machine_state = machine_state , state_name = state_name , actions = actions
306
+ )
255
307
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
+ )
263
318
)
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 :
268
324
if action_mode == "sequential" :
269
325
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
277
338
)
278
- else None
279
339
)
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 )
288
349
self .state_machine .add_transition (
289
350
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 } " ,
292
353
)
293
354
if i == 0 :
294
- machine_state .initial = fn_name
355
+ machine_state .initial = name
295
356
elif action_mode == "parallel" :
296
- parallel_states .append (fn_name )
357
+ parallel_states .append (name )
297
358
if action_mode == "parallel" :
298
359
machine_state .initial = parallel_states
299
360
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
+ )
358
367
359
368
def add_all_sub_states (
360
369
cls ,
@@ -366,12 +375,14 @@ def add_all_sub_states(
366
375
for substate in original_state .states .values ():
367
376
new_state .add_substate (ns := NestedState (substate .name ))
368
377
cls .add_all_sub_states (substate , ns )
378
+ new_state .initial = original_state .initial
369
379
370
380
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 ,
372
385
) -> NestedState :
373
- self .state_machine .get_state (self .state .name ).add_substate (nested_state )
374
-
375
386
self .add_all_sub_states (state_machine , nested_state )
376
387
377
388
for trigger , event in state_machine .events .items ():
@@ -381,8 +392,8 @@ def state_machine_to_nested_state(
381
392
dest = transition .dest
382
393
self .state_machine .add_transition (
383
394
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 } " ,
386
397
)
387
398
388
399
def get_function_name (
0 commit comments