Skip to content

Commit 9672b8e

Browse files
authored
Merge pull request #5 from singchia/sync
add non async emit
2 parents bc1d20e + da64ded commit 9672b8e

File tree

1 file changed

+73
-8
lines changed

1 file changed

+73
-8
lines changed

yafsm.go

+73-8
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,21 @@ func WithAsync() FSMOption {
7070
}
7171
}
7272

73+
func WithInSeq() FSMOption {
74+
return func(fsm *FSM) {
75+
fsm.inseq = true
76+
}
77+
}
78+
7379
type FSM struct {
7480
state string
7581
states map[string]*State
7682
events map[string]*list.List
7783

78-
async bool
79-
mutex sync.RWMutex
80-
pq *prioqueue.PrioQueue
81-
cancel context.CancelFunc
84+
async, inseq bool
85+
mutex sync.RWMutex
86+
pq *prioqueue.PrioQueue
87+
cancel context.CancelFunc
8288
}
8389

8490
func NewFSM(opts ...FSMOption) *FSM {
@@ -182,6 +188,49 @@ func (fsm *FSM) emitOne() {
182188
}
183189
}
184190

191+
func (fsm *FSM) emitOneInSeq() {
192+
fsm.mutex.Lock()
193+
defer fsm.mutex.Unlock()
194+
195+
data := fsm.pq.PopSync()
196+
if data == nil {
197+
return
198+
}
199+
switch ec := data.(type) {
200+
case *eventchan:
201+
et := (*Event)(nil)
202+
etList, ok := fsm.events[ec.event]
203+
if !ok {
204+
ec.ch <- ErrEventNotExist
205+
close(ec.ch)
206+
return
207+
}
208+
for elem := etList.Front(); elem != nil; elem = elem.Next() {
209+
tmp := elem.Value.(*Event)
210+
if tmp.From.State == fsm.state {
211+
et = tmp
212+
}
213+
}
214+
if et == nil {
215+
ec.ch <- ErrIllegalStateForEvent
216+
close(ec.ch)
217+
return
218+
}
219+
fsm.state = et.To.State
220+
for _, left := range et.From.lefts {
221+
left(et.From)
222+
}
223+
for _, handler := range et.handlers {
224+
handler(et)
225+
}
226+
for _, enter := range et.To.enters {
227+
enter(et.To)
228+
}
229+
ec.ch <- nil
230+
close(ec.ch)
231+
}
232+
}
233+
185234
func (fsm *FSM) SetState(state string) bool {
186235
fsm.mutex.Lock()
187236
defer fsm.mutex.Unlock()
@@ -411,7 +460,11 @@ func (fsm *FSM) EmitEvent(event string) error {
411460
return err
412461
}
413462
if !fsm.async {
414-
fsm.emitOne()
463+
if fsm.inseq {
464+
fsm.emitOneInSeq()
465+
} else {
466+
fsm.emitOne()
467+
}
415468
}
416469
err = <-ch
417470
return err
@@ -438,7 +491,11 @@ func (fsm *FSM) EmitEventAsync(event string) <-chan error {
438491
return ch
439492
}
440493
if !fsm.async {
441-
fsm.emitOne()
494+
if fsm.inseq {
495+
fsm.emitOneInSeq()
496+
} else {
497+
fsm.emitOne()
498+
}
442499
}
443500
return ch
444501
}
@@ -462,7 +519,11 @@ func (fsm *FSM) EmitPrioEvent(prio int, event string) error {
462519
return err
463520
}
464521
if !fsm.async {
465-
fsm.emitOne()
522+
if fsm.inseq {
523+
fsm.emitOneInSeq()
524+
} else {
525+
fsm.emitOne()
526+
}
466527
}
467528
err = <-ch
468529
return err
@@ -489,7 +550,11 @@ func (fsm *FSM) EmitPrioEventAsync(prio int, event string) <-chan error {
489550
return ch
490551
}
491552
if !fsm.async {
492-
fsm.emitOne()
553+
if fsm.inseq {
554+
fsm.emitOneInSeq()
555+
} else {
556+
fsm.emitOne()
557+
}
493558
}
494559
return ch
495560
}

0 commit comments

Comments
 (0)