-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuilder.go
More file actions
722 lines (620 loc) · 22 KB
/
builder.go
File metadata and controls
722 lines (620 loc) · 22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
package statekit
import (
"time"
"go.klarlabs.de/statekit/internal/ir"
)
// MachineBuilder provides a fluent API for constructing state machines
type MachineBuilder[C any] struct {
id string
initial StateID
context C
states []*StateBuilder[C]
actions map[ActionType]Action[C]
guards map[GuardType]Guard[C]
services map[ServiceType]Service[C] // v3.0: Invoked services
childMachines map[string]ir.ChildMachineFactory[C] // v0.14: Child machine factories
}
// StateBuilder provides a fluent API for constructing states
type StateBuilder[C any] struct {
machine *MachineBuilder[C]
parent *StateBuilder[C] // Parent state for nested states
region *RegionBuilder[C] // Parent region for states in parallel regions (v2.0)
id StateID
stateType StateType
initial StateID // Initial child state (for compound states)
children []*StateBuilder[C]
entry []ActionType
exit []ActionType
transitions []*TransitionBuilder[C]
always []*TransitionBuilder[C] // eventless transitions (v1.x)
tags []string // state tags (v1.x)
// History state fields (v2.0)
historyType HistoryType
historyDefault StateID
// Invoked services (v3.0)
invocations []*InvokeBuilder[C]
// Invoked child machines (v0.14)
machineInvocations []*MachineInvokeBuilder[C]
}
// InvokeBuilder provides a fluent API for constructing service invocations (v3.0)
//
// The name is kept for backward compatibility; use the
// InvokeServiceBuilder alias for clearer intent next to
// InvokeMachineBuilder.
type InvokeBuilder[C any] struct {
state *StateBuilder[C]
id string
src ServiceType
onDoneTarget StateID
onDoneAction ActionType
onErrTarget StateID
onErrAction ActionType
}
// InvokeServiceBuilder is a clearer alias for InvokeBuilder. Prefer
// this name in new code — it parallels InvokeMachineBuilder so the
// two service/machine invocation paths are self-documenting.
type InvokeServiceBuilder[C any] = InvokeBuilder[C]
// MachineInvokeBuilder provides a fluent API for constructing child machine invocations (v0.14)
//
// The name is kept for backward compatibility; use the
// InvokeMachineBuilder alias for clearer intent next to
// InvokeServiceBuilder.
type MachineInvokeBuilder[C any] struct {
state *StateBuilder[C]
id string
machineRef string
onDoneTarget StateID
onDoneAction ActionType
onErrTarget StateID
onErrAction ActionType
autoForward []EventType
}
// InvokeMachineBuilder is a clearer alias for MachineInvokeBuilder.
// Prefer this name in new code — it parallels InvokeServiceBuilder so
// the two service/machine invocation paths are self-documenting.
type InvokeMachineBuilder[C any] = MachineInvokeBuilder[C]
// HistoryBuilder provides a fluent API for constructing history states
type HistoryBuilder[C any] struct {
parent *StateBuilder[C] // Parent compound state
id StateID
historyType HistoryType
defaultID StateID
}
// RegionBuilder provides a fluent API for constructing parallel regions (v2.0)
type RegionBuilder[C any] struct {
parallel *StateBuilder[C] // Parent parallel state
id StateID
initial StateID
children []*StateBuilder[C]
}
// TransitionBuilder provides a fluent API for constructing transitions
type TransitionBuilder[C any] struct {
state *StateBuilder[C]
event EventType
target StateID
guard GuardType
actions []ActionType
// Delayed transition fields (v2.0)
delay time.Duration
// Eventless ("always") transition flag (v1.x)
eventless bool
// Raised internal events (v1.x)
raise []EventType
// Internal transition flag — run actions without exit/entry (v1.x)
internal bool
}
// NewMachine creates a new MachineBuilder with the given ID
func NewMachine[C any](id string) *MachineBuilder[C] {
return &MachineBuilder[C]{
id: id,
actions: make(map[ActionType]Action[C]),
guards: make(map[GuardType]Guard[C]),
services: make(map[ServiceType]Service[C]),
childMachines: make(map[string]ir.ChildMachineFactory[C]),
}
}
// WithInitial sets the initial state ID
func (b *MachineBuilder[C]) WithInitial(initial StateID) *MachineBuilder[C] {
b.initial = initial
return b
}
// WithContext sets the initial context value
func (b *MachineBuilder[C]) WithContext(ctx C) *MachineBuilder[C] {
b.context = ctx
return b
}
// WithAction registers a named action
func (b *MachineBuilder[C]) WithAction(name ActionType, action Action[C]) *MachineBuilder[C] {
b.actions[name] = action
return b
}
// WithGuard registers a named guard
func (b *MachineBuilder[C]) WithGuard(name GuardType, guard Guard[C]) *MachineBuilder[C] {
b.guards[name] = guard
return b
}
// WithService registers a named service (v3.0)
func (b *MachineBuilder[C]) WithService(name ServiceType, service Service[C]) *MachineBuilder[C] {
b.services[name] = service
return b
}
// WithChildMachine registers a child machine factory for machine composition (v0.14).
// The factory creates a child interpreter when the machine is invoked.
func (b *MachineBuilder[C]) WithChildMachine(name string, factory ir.ChildMachineFactory[C]) *MachineBuilder[C] {
b.childMachines[name] = factory
return b
}
// State starts building a new state with the given ID
func (b *MachineBuilder[C]) State(id StateID) *StateBuilder[C] {
sb := &StateBuilder[C]{
machine: b,
parent: nil,
id: id,
stateType: StateTypeAtomic,
}
b.states = append(b.states, sb)
return sb
}
// Build constructs the final MachineConfig from the builder
func (b *MachineBuilder[C]) Build() (*ir.MachineConfig[C], error) {
machine := ir.NewMachineConfig(b.id, b.initial, b.context)
// Copy actions and guards (convert from statekit types to ir types)
for name, action := range b.actions {
machine.Actions[name] = ir.Action[C](action)
}
for name, guard := range b.guards {
machine.Guards[name] = ir.Guard[C](guard)
}
// Copy services (v3.0)
for name, service := range b.services {
machine.Services[name] = service
}
// Copy child machine factories (v0.14)
for name, factory := range b.childMachines {
machine.ChildMachines[name] = factory
}
// Build states recursively
for _, sb := range b.states {
buildStateRecursive(sb, "", machine)
}
// Validate the machine configuration
if err := ir.Validate(machine); err != nil {
return nil, err
}
return machine, nil
}
// buildStateRecursive adds a state and its children to the machine config
func buildStateRecursive[C any](sb *StateBuilder[C], parentID ir.StateID, machine *ir.MachineConfig[C]) {
// Determine state type
stateType := sb.stateType
if len(sb.children) > 0 && sb.stateType == StateTypeAtomic {
stateType = ir.StateTypeCompound
}
state := ir.NewStateConfig(sb.id, stateType)
state.Parent = parentID
// Set initial for compound states
if len(sb.children) > 0 {
state.Initial = sb.initial
for _, child := range sb.children {
state.Children = append(state.Children, child.id)
}
}
// Set history state fields (v2.0)
if stateType == ir.StateTypeHistory {
state.HistoryType = sb.historyType
state.HistoryDefault = sb.historyDefault
}
// Convert entry/exit actions
state.Entry = append(state.Entry, sb.entry...)
state.Exit = append(state.Exit, sb.exit...)
// Copy state tags (v1.x)
state.Tags = append(state.Tags, sb.tags...)
// Build transitions
for _, tb := range sb.transitions {
trans := ir.NewTransitionConfig(tb.event, tb.target)
trans.Guard = tb.guard
trans.Actions = append(trans.Actions, tb.actions...)
trans.Delay = tb.delay // Delayed transitions (v2.0)
trans.Raise = append(trans.Raise, tb.raise...)
trans.Internal = tb.internal // Internal transitions (v1.x)
state.Transitions = append(state.Transitions, trans)
}
// Build eventless ("always") transitions (v1.x)
for _, tb := range sb.always {
trans := ir.NewTransitionConfig("", tb.target)
trans.Guard = tb.guard
trans.Actions = append(trans.Actions, tb.actions...)
trans.Raise = append(trans.Raise, tb.raise...)
state.Always = append(state.Always, trans)
}
// Build invocations (v3.0)
for _, ib := range sb.invocations {
invoke := &ir.InvokeConfig{
ID: ib.id,
Src: ib.src,
}
if ib.onDoneTarget != "" {
invoke.OnDone = ir.NewTransitionConfig("", ib.onDoneTarget)
if ib.onDoneAction != "" {
invoke.OnDone.Actions = append(invoke.OnDone.Actions, ib.onDoneAction)
}
}
if ib.onErrTarget != "" {
invoke.OnError = ir.NewTransitionConfig("", ib.onErrTarget)
if ib.onErrAction != "" {
invoke.OnError.Actions = append(invoke.OnError.Actions, ib.onErrAction)
}
}
state.Invocations = append(state.Invocations, invoke)
}
// Build machine invocations (v0.14)
for _, mib := range sb.machineInvocations {
machineInvoke := &ir.MachineInvokeConfig{
ID: mib.id,
MachineRef: mib.machineRef,
AutoForward: mib.autoForward,
}
if mib.onDoneTarget != "" {
machineInvoke.OnDone = ir.NewTransitionConfig("", mib.onDoneTarget)
if mib.onDoneAction != "" {
machineInvoke.OnDone.Actions = append(machineInvoke.OnDone.Actions, mib.onDoneAction)
}
}
if mib.onErrTarget != "" {
machineInvoke.OnError = ir.NewTransitionConfig("", mib.onErrTarget)
if mib.onErrAction != "" {
machineInvoke.OnError.Actions = append(machineInvoke.OnError.Actions, mib.onErrAction)
}
}
state.MachineInvocations = append(state.MachineInvocations, machineInvoke)
}
machine.States[sb.id] = state
// Recursively build children
for _, child := range sb.children {
buildStateRecursive(child, sb.id, machine)
}
}
// --- StateBuilder methods ---
// Final marks this state as a final state
func (b *StateBuilder[C]) Final() *StateBuilder[C] {
b.stateType = StateTypeFinal
return b
}
// OnEntry adds an entry action to the state
func (b *StateBuilder[C]) OnEntry(action ActionType) *StateBuilder[C] {
b.entry = append(b.entry, action)
return b
}
// OnExit adds an exit action to the state
func (b *StateBuilder[C]) OnExit(action ActionType) *StateBuilder[C] {
b.exit = append(b.exit, action)
return b
}
// WithInitial sets the initial child state for a compound state
func (b *StateBuilder[C]) WithInitial(initial StateID) *StateBuilder[C] {
b.initial = initial
return b
}
// State starts building a nested child state
func (b *StateBuilder[C]) State(id StateID) *StateBuilder[C] {
child := &StateBuilder[C]{
machine: b.machine,
parent: b,
id: id,
stateType: StateTypeAtomic,
}
b.children = append(b.children, child)
return child
}
// On starts building a new transition triggered by the given event
func (b *StateBuilder[C]) On(event EventType) *TransitionBuilder[C] {
tb := &TransitionBuilder[C]{
state: b,
event: event,
}
b.transitions = append(b.transitions, tb)
return tb
}
// Always starts building an eventless ("always") transition (v1.x). It is
// evaluated when the state is entered and after every transition, in
// declaration order; the first whose guard passes is taken. A target is
// required. Use multiple Always() calls to express guarded routing with a
// final guardless fallback.
func (b *StateBuilder[C]) Always() *TransitionBuilder[C] {
tb := &TransitionBuilder[C]{
state: b,
eventless: true,
}
b.always = append(b.always, tb)
return tb
}
// Tags attaches one or more tags to the state for lightweight querying via
// Interpreter.HasTag (v1.x).
func (b *StateBuilder[C]) Tags(tags ...string) *StateBuilder[C] {
b.tags = append(b.tags, tags...)
return b
}
// Done completes the state definition and returns the root MachineBuilder.
//
// Watch out: when called from a nested StateBuilder, Done() teleports the
// chain all the way back to the machine root, skipping any intermediate
// parent states. This is rarely what you want for nested states. Prefer
// End() for "back one level" or EndMachine() for "back to the root" — both
// are clearer at a glance.
func (b *StateBuilder[C]) Done() *MachineBuilder[C] {
return b.machine
}
// EndMachine completes the state definition and returns the root
// MachineBuilder. Equivalent to Done() but its name makes the intent
// unambiguous when reading nested-state-builder chains.
func (b *StateBuilder[C]) EndMachine() *MachineBuilder[C] {
return b.machine
}
// End completes a nested state and returns to the parent StateBuilder
// Use this instead of Done() when building nested states
func (b *StateBuilder[C]) End() *StateBuilder[C] {
if b.parent != nil {
return b.parent
}
// If no parent, this is a programming error, but we'll return nil
return nil
}
// EndState completes a state within a region and returns to the RegionBuilder (v2.0)
// Use this instead of End() when building states inside parallel regions
func (b *StateBuilder[C]) EndState() *RegionBuilder[C] {
return b.region
}
// History starts building a history state within this compound state (v2.0)
// History states remember the last active child and transition back to it
func (b *StateBuilder[C]) History(id StateID) *HistoryBuilder[C] {
return &HistoryBuilder[C]{
parent: b,
id: id,
historyType: HistoryTypeShallow,
}
}
// Parallel marks this state as a parallel state (v2.0)
// Use Region() to add orthogonal regions that execute simultaneously
func (b *StateBuilder[C]) Parallel() *StateBuilder[C] {
b.stateType = StateTypeParallel
return b
}
// Region starts building a new region within this parallel state (v2.0)
func (b *StateBuilder[C]) Region(id StateID) *RegionBuilder[C] {
return &RegionBuilder[C]{
parallel: b,
id: id,
}
}
// After starts building a delayed transition that triggers automatically
// after the specified duration (v2.0)
func (b *StateBuilder[C]) After(d time.Duration) *TransitionBuilder[C] {
tb := &TransitionBuilder[C]{
state: b,
delay: d,
}
b.transitions = append(b.transitions, tb)
return tb
}
// Invoke starts building a service invocation for this state (v3.0)
// The service is started when entering the state and cancelled when exiting
func (b *StateBuilder[C]) Invoke(src ServiceType) *InvokeBuilder[C] {
ib := &InvokeBuilder[C]{
state: b,
src: src,
id: string(src), // Default ID is the service name
}
b.invocations = append(b.invocations, ib)
return ib
}
// InvokeMachine starts building a child machine invocation for this state (v0.14).
// The child machine is spawned when entering the state and stopped when exiting.
// The machineRef must match a name registered with WithChildMachine.
func (b *StateBuilder[C]) InvokeMachine(machineRef string) *MachineInvokeBuilder[C] {
mib := &MachineInvokeBuilder[C]{
state: b,
machineRef: machineRef,
id: machineRef, // Default ID is the machine reference
}
b.machineInvocations = append(b.machineInvocations, mib)
return mib
}
// --- InvokeBuilder methods (v3.0) ---
// ID sets a custom ID for this invocation
func (b *InvokeBuilder[C]) ID(id string) *InvokeBuilder[C] {
b.id = id
return b
}
// OnDone sets the transition target when the service completes successfully
func (b *InvokeBuilder[C]) OnDone(target StateID) *InvokeBuilder[C] {
b.onDoneTarget = target
return b
}
// OnDoneAction sets an action to execute when the service completes successfully
func (b *InvokeBuilder[C]) OnDoneAction(action ActionType) *InvokeBuilder[C] {
b.onDoneAction = action
return b
}
// OnError sets the transition target when the service fails
func (b *InvokeBuilder[C]) OnError(target StateID) *InvokeBuilder[C] {
b.onErrTarget = target
return b
}
// OnErrorAction sets an action to execute when the service fails
func (b *InvokeBuilder[C]) OnErrorAction(action ActionType) *InvokeBuilder[C] {
b.onErrAction = action
return b
}
// End completes the invocation definition and returns to the StateBuilder
func (b *InvokeBuilder[C]) End() *StateBuilder[C] {
return b.state
}
// Done completes the state definition and returns to the machine builder
func (b *InvokeBuilder[C]) Done() *MachineBuilder[C] {
return b.state.Done()
}
// --- MachineInvokeBuilder methods (v0.14) ---
// ID sets a custom ID for this machine invocation
func (b *MachineInvokeBuilder[C]) ID(id string) *MachineInvokeBuilder[C] {
b.id = id
return b
}
// OnDone sets the transition target when the child machine reaches a final state
func (b *MachineInvokeBuilder[C]) OnDone(target StateID) *MachineInvokeBuilder[C] {
b.onDoneTarget = target
return b
}
// OnDoneAction sets an action to execute when the child machine completes
func (b *MachineInvokeBuilder[C]) OnDoneAction(action ActionType) *MachineInvokeBuilder[C] {
b.onDoneAction = action
return b
}
// OnError sets the transition target when the child machine encounters an error
func (b *MachineInvokeBuilder[C]) OnError(target StateID) *MachineInvokeBuilder[C] {
b.onErrTarget = target
return b
}
// OnErrorAction sets an action to execute when the child machine fails
func (b *MachineInvokeBuilder[C]) OnErrorAction(action ActionType) *MachineInvokeBuilder[C] {
b.onErrAction = action
return b
}
// AutoForward adds event types that should be auto-forwarded to the child machine
func (b *MachineInvokeBuilder[C]) AutoForward(events ...EventType) *MachineInvokeBuilder[C] {
b.autoForward = append(b.autoForward, events...)
return b
}
// End completes the machine invocation definition and returns to the StateBuilder
func (b *MachineInvokeBuilder[C]) End() *StateBuilder[C] {
return b.state
}
// Done completes the state definition and returns to the machine builder
func (b *MachineInvokeBuilder[C]) Done() *MachineBuilder[C] {
return b.state.Done()
}
// --- HistoryBuilder methods (v2.0) ---
// Shallow sets the history type to shallow (remembers immediate child)
func (b *HistoryBuilder[C]) Shallow() *HistoryBuilder[C] {
b.historyType = HistoryTypeShallow
return b
}
// Deep sets the history type to deep (remembers full leaf path)
func (b *HistoryBuilder[C]) Deep() *HistoryBuilder[C] {
b.historyType = HistoryTypeDeep
return b
}
// Default sets the default target state if no history is recorded
func (b *HistoryBuilder[C]) Default(target StateID) *HistoryBuilder[C] {
b.defaultID = target
return b
}
// End completes the history state definition and returns to the parent StateBuilder
func (b *HistoryBuilder[C]) End() *StateBuilder[C] {
// Create a StateBuilder for the history state
historyState := &StateBuilder[C]{
machine: b.parent.machine,
parent: b.parent,
id: b.id,
stateType: StateTypeHistory,
historyType: b.historyType,
historyDefault: b.defaultID,
}
b.parent.children = append(b.parent.children, historyState)
return b.parent
}
// --- RegionBuilder methods (v2.0) ---
// WithInitial sets the initial state for this region
func (b *RegionBuilder[C]) WithInitial(initial StateID) *RegionBuilder[C] {
b.initial = initial
return b
}
// State starts building a state within this region
func (b *RegionBuilder[C]) State(id StateID) *StateBuilder[C] {
child := &StateBuilder[C]{
machine: b.parallel.machine,
parent: nil,
region: b, // Set region reference so End() returns to region
id: id,
stateType: StateTypeAtomic,
}
b.children = append(b.children, child)
return child
}
// EndRegion completes the region and returns to the parent parallel state
func (b *RegionBuilder[C]) EndRegion() *StateBuilder[C] {
// Create a StateBuilder for the region (as a compound state)
regionState := &StateBuilder[C]{
machine: b.parallel.machine,
parent: b.parallel,
id: b.id,
stateType: StateTypeCompound,
initial: b.initial,
children: b.children,
}
// Fix the parent references for all children
for _, child := range b.children {
child.parent = regionState
}
b.parallel.children = append(b.parallel.children, regionState)
return b.parallel
}
// --- TransitionBuilder methods ---
// Target sets the target state for the transition
func (b *TransitionBuilder[C]) Target(target StateID) *TransitionBuilder[C] {
b.target = target
return b
}
// Guard sets the guard condition for the transition
func (b *TransitionBuilder[C]) Guard(guard GuardType) *TransitionBuilder[C] {
b.guard = guard
return b
}
// Do adds an action to be executed during the transition
func (b *TransitionBuilder[C]) Do(action ActionType) *TransitionBuilder[C] {
b.actions = append(b.actions, action)
return b
}
// Raise enqueues internal events emitted when this transition is taken (v1.x).
// Raised events are processed in the same macrostep — before control returns
// to the caller and before any externally sent event.
func (b *TransitionBuilder[C]) Raise(events ...EventType) *TransitionBuilder[C] {
b.raise = append(b.raise, events...)
return b
}
// Internal marks the transition as internal (v1.x): its actions run without
// exiting or re-entering the source state — entry/exit hooks do not fire and
// the active state does not change. Target is optional; when set it must be
// the owning state. Contrast with an external self-transition (a plain
// Target back to the same state), which does exit and re-enter.
func (b *TransitionBuilder[C]) Internal() *TransitionBuilder[C] {
b.internal = true
return b
}
// On starts a new transition on the same state (chainable)
func (b *TransitionBuilder[C]) On(event EventType) *TransitionBuilder[C] {
return b.state.On(event)
}
// After starts a new delayed transition on the same state (chainable) (v2.0)
func (b *TransitionBuilder[C]) After(d time.Duration) *TransitionBuilder[C] {
return b.state.After(d)
}
// Done completes the state definition and returns to the machine builder
func (b *TransitionBuilder[C]) Done() *MachineBuilder[C] {
return b.state.Done()
}
// EndMachine completes the state definition and returns to the
// MachineBuilder. Equivalent to Done() but its name makes the intent
// unambiguous in nested-state-builder chains.
func (b *TransitionBuilder[C]) EndMachine() *MachineBuilder[C] {
return b.state.Done()
}
// End completes the transition and returns to the parent StateBuilder
// Use this instead of Done() when building transitions in nested states
func (b *TransitionBuilder[C]) End() *StateBuilder[C] {
return b.state
}
// EndState completes the transition and returns to the RegionBuilder (v2.0)
// Use this when building transitions in states inside parallel regions
func (b *TransitionBuilder[C]) EndState() *RegionBuilder[C] {
return b.state.region
}