forked from Gurpartap/statemachine-go
-
Notifications
You must be signed in to change notification settings - Fork 2
/
machine_builder.go
117 lines (94 loc) · 3.97 KB
/
machine_builder.go
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
package statemachine
// MachineBuildable implementation is able to consume the result of building
// features from dsl.MachineBuilder. MachineBuildable is oblivious to Machine or
// it's implementation.
type MachineBuildable interface {
SetMachineDef(def *MachineDef)
}
// MachineBuilder provides the ability to define all features of the state
// machine, including states, events, event transitions, and transition
// callbacks. MachineBuilder is oblivious to Machine or it's implementation.
type MachineBuilder interface {
// Build plugs the collected feature definitions into any object
// that understands them (implements MachineBuildable). Use this method
// if you're not using Machine.Build() to define the state machine.
Build(machine MachineBuildable)
SetEventDef(event string, def *EventDef)
ID(id string)
// States pre-defines the set of known states. This is optional because
// all known states will be identified from other definitions.
States(states ...string)
// InitialState defines the state that the machine initializes with.
// Initial state must be defined for every state machine.
InitialState(state string)
Submachine(state string, submachineBuilderFn func(submachineBuilder MachineBuilder))
// Event provides the ability to define possible transitions for an event.
Event(name string, eventBuilderFn ...func(eventBuilder EventBuilder)) EventBuilder
BeforeTransition() TransitionCallbackBuilder
AroundTransition() TransitionCallbackBuilder
AfterTransition() TransitionCallbackBuilder
AfterFailure() EventCallbackBuilder
}
// NewMachineBuilder returns a zero-valued instance of machineBuilder, which
// implements MachineBuilder.
func NewMachineBuilder() MachineBuilder {
return &machineBuilder{
def: NewMachineDef(),
}
}
// machineBuilder implements MachineBuilder.
type machineBuilder struct {
def *MachineDef
}
var _ MachineBuilder = (*machineBuilder)(nil)
func (m *machineBuilder) ID(id string) {
m.def.SetID(id)
}
func (m *machineBuilder) States(states ...string) {
m.def.SetStates(states...)
}
func (m *machineBuilder) InitialState(state string) {
m.def.SetInitialState(state)
}
func (m *machineBuilder) Submachine(state string, submachineBuilderFn func(submachineBuilder MachineBuilder)) {
submachineBuilder := &machineBuilder{def: NewMachineDef()}
submachineBuilderFn(submachineBuilder)
m.def.SetSubmachine(state, submachineBuilder.def)
}
func (m *machineBuilder) Event(name string, eventBuilderFuncs ...func(eventBuilder EventBuilder)) EventBuilder {
// TODO: Restrict public use of .Build(...) on this instance of eventBuilder.
eventBuilder := NewEventBuilder(name)
for _, eventBuilderFunc := range eventBuilderFuncs {
eventBuilderFunc(eventBuilder)
}
e := newEventImpl()
eventBuilder.Build(e)
m.def.AddEvent(name, e.def)
return eventBuilder
}
func (m *machineBuilder) BeforeTransition() TransitionCallbackBuilder {
transitionCallbackDef := &TransitionCallbackDef{validateFor: "BeforeTransition"}
m.def.AddBeforeCallback(transitionCallbackDef)
return newTransitionCallbackBuilder(transitionCallbackDef)
}
func (m *machineBuilder) AroundTransition() TransitionCallbackBuilder {
transitionCallbackDef := &TransitionCallbackDef{validateFor: "AroundTransition"}
m.def.AddAroundCallback(transitionCallbackDef)
return newTransitionCallbackBuilder(transitionCallbackDef)
}
func (m *machineBuilder) AfterTransition() TransitionCallbackBuilder {
transitionCallbackDef := &TransitionCallbackDef{validateFor: "AfterTransition"}
m.def.AddAfterCallback(transitionCallbackDef)
return newTransitionCallbackBuilder(transitionCallbackDef)
}
func (m *machineBuilder) AfterFailure() EventCallbackBuilder {
transitionCallbackDef := &EventCallbackDef{validateFor: "AfterFailure"}
m.def.AddFailureCallback(transitionCallbackDef)
return newEventCallbackBuilder(transitionCallbackDef)
}
func (m *machineBuilder) Build(machine MachineBuildable) {
machine.SetMachineDef(m.def)
}
func (m *machineBuilder) SetEventDef(event string, def *EventDef) {
m.def.AddEvent(event, def)
}