vegapokerbot/internal/handler/fsm/fsmcore/machine.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)
}
}