58 lines
1.3 KiB
Go
58 lines
1.3 KiB
Go
|
package fsmcore
|
||
|
|
||
|
import (
|
||
|
"gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/handler/fsm/fsmcontract"
|
||
|
)
|
||
|
|
||
|
type (
|
||
|
MachineErrorHandler func(fsmcontract.Machine, fsmcontract.Context, error)
|
||
|
NewContextFunc func() fsmcontract.Context
|
||
|
)
|
||
|
|
||
|
type Machine struct {
|
||
|
ctx *AtomicValue[fsmcontract.Context]
|
||
|
entryState fsmcontract.State
|
||
|
state *AtomicValue[fsmcontract.State]
|
||
|
newContextFunc NewContextFunc
|
||
|
errHandler MachineErrorHandler
|
||
|
}
|
||
|
|
||
|
func NewMachine(ctx fsmcontract.Context, entryState fsmcontract.State,
|
||
|
newContextFunc NewContextFunc, errHandler MachineErrorHandler) *Machine {
|
||
|
return &Machine{
|
||
|
ctx: NewAtomicValue[fsmcontract.Context](ctx),
|
||
|
entryState: entryState,
|
||
|
state: NewAtomicValue[fsmcontract.State](entryState),
|
||
|
newContextFunc: newContextFunc,
|
||
|
errHandler: errHandler,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (m *Machine) Handle() {
|
||
|
ctx := m.ctx.Load()
|
||
|
state := m.state.Load()
|
||
|
next, newCtx, err := state.Handle(ctx)
|
||
|
if err != nil {
|
||
|
m.HandleError(err)
|
||
|
}
|
||
|
if next != state {
|
||
|
m.state.Store(next)
|
||
|
}
|
||
|
m.ctx.Store(newCtx)
|
||
|
}
|
||
|
|
||
|
func (m *Machine) Reset() {
|
||
|
var ctx fsmcontract.Context
|
||
|
if m.newContextFunc != nil {
|
||
|
ctx = m.newContextFunc()
|
||
|
}
|
||
|
m.ctx.Store(ctx)
|
||
|
m.state.Store(m.entryState)
|
||
|
}
|
||
|
|
||
|
func (m *Machine) HandleError(err error) {
|
||
|
if m.errHandler != nil {
|
||
|
m.errHandler(m, m.ctx.Load(), err)
|
||
|
}
|
||
|
}
|