1717)
1818
1919const (
20- // Default represents the default state of the system.
21- Default StateType = ""
20+ // EmptyState represents the default state of the system.
21+ EmptyState StateType = ""
2222
2323 // NoOp represents a no-op event.
2424 NoOp EventType = "NoOp"
@@ -88,19 +88,19 @@ type StateMachine struct {
8888
8989 // ActionEntryFunc is a function that is called before an action is
9090 // executed.
91- ActionEntryFunc func ()
91+ ActionEntryFunc func (Notification )
9292
9393 // ActionExitFunc is a function that is called after an action is
94- // executed.
95- ActionExitFunc func ()
96-
97- // mutex ensures that only 1 event is processed by the state machine at
98- // any given time.
99- mutex sync.Mutex
94+ // executed, it is called with the EventType returned by the action.
95+ ActionExitFunc func (NextEvent EventType )
10096
10197 // LastActionError is an error set by the last action executed.
10298 LastActionError error
10399
100+ // DefaultObserver is the default observer that is notified when the
101+ // state machine transitions between states.
102+ DefaultObserver * CachedObserver
103+
104104 // previous represents the previous state.
105105 previous StateType
106106
@@ -114,13 +114,35 @@ type StateMachine struct {
114114 // observerMutex ensures that observers are only added or removed
115115 // safely.
116116 observerMutex sync.Mutex
117+
118+ // mutex ensures that only 1 event is processed by the state machine at
119+ // any given time.
120+ mutex sync.Mutex
117121}
118122
119123// NewStateMachine creates a new state machine.
120- func NewStateMachine (states States ) * StateMachine {
124+ func NewStateMachine (states States , observerSize int ) * StateMachine {
125+ return NewStateMachineWithState (states , EmptyState , observerSize )
126+ }
127+
128+ // NewStateMachineWithState creates a new state machine and sets the initial
129+ // state.
130+ func NewStateMachineWithState (states States , current StateType ,
131+ observerSize int ) * StateMachine {
132+
133+ observers := []Observer {}
134+ var defaultObserver * CachedObserver
135+
136+ if observerSize > 0 {
137+ defaultObserver = NewCachedObserver (observerSize )
138+ observers = append (observers , defaultObserver )
139+ }
140+
121141 return & StateMachine {
122- States : states ,
123- observers : make ([]Observer , 0 ),
142+ States : states ,
143+ current : current ,
144+ DefaultObserver : defaultObserver ,
145+ observers : observers ,
124146 }
125147}
126148
@@ -189,18 +211,20 @@ func (s *StateMachine) SendEvent(event EventType, eventCtx EventContext) error {
189211
190212 // Notify the state machine's observers.
191213 s .observerMutex .Lock ()
214+ notification := Notification {
215+ PreviousState : s .previous ,
216+ NextState : s .current ,
217+ Event : event ,
218+ }
219+
192220 for _ , observer := range s .observers {
193- observer .Notify (Notification {
194- PreviousState : s .previous ,
195- NextState : s .current ,
196- Event : event ,
197- })
221+ observer .Notify (notification )
198222 }
199223 s .observerMutex .Unlock ()
200224
201225 // Execute the state machines ActionEntryFunc.
202226 if s .ActionEntryFunc != nil {
203- s .ActionEntryFunc ()
227+ s .ActionEntryFunc (notification )
204228 }
205229
206230 // Execute the current state's entry function
@@ -219,7 +243,7 @@ func (s *StateMachine) SendEvent(event EventType, eventCtx EventContext) error {
219243
220244 // Execute the state machines ActionExitFunc.
221245 if s .ActionExitFunc != nil {
222- s .ActionExitFunc ()
246+ s .ActionExitFunc (nextEvent )
223247 }
224248
225249 // If the next event is a no-op, we're done.
0 commit comments