refactor: fsm 包状态机事件优化,新增部分获取状态机信息的函数
This commit is contained in:
parent
8b92921230
commit
0fad0417c7
104
game/fsm/fsm.go
104
game/fsm/fsm.go
|
@ -2,54 +2,116 @@ package fsm
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/kercylan98/minotaur/utils/hash"
|
||||
)
|
||||
|
||||
// NewFSM 创建一个新的状态机
|
||||
func NewFSM[S comparable, Data any](data Data) *FSM[S, Data] {
|
||||
return &FSM[S, Data]{
|
||||
states: map[S]*State[S, Data]{},
|
||||
func NewFSM[State comparable, Data any](data Data) *FSM[State, Data] {
|
||||
return &FSM[State, Data]{
|
||||
states: map[State]struct{}{},
|
||||
data: data,
|
||||
}
|
||||
}
|
||||
|
||||
// FSM 状态机
|
||||
type FSM[S comparable, Data any] struct {
|
||||
current S
|
||||
type FSM[State comparable, Data any] struct {
|
||||
prev *State
|
||||
current *State
|
||||
data Data
|
||||
states map[S]*State[S, Data]
|
||||
states map[State]struct{}
|
||||
|
||||
enterBeforeEventHandles map[State][]func(state *FSM[State, Data])
|
||||
enterAfterEventHandles map[State][]func(state *FSM[State, Data])
|
||||
updateEventHandles map[State][]func(state *FSM[State, Data])
|
||||
exitBeforeEventHandles map[State][]func(state *FSM[State, Data])
|
||||
exitAfterEventHandles map[State][]func(state *FSM[State, Data])
|
||||
}
|
||||
|
||||
// Update 触发当前状态
|
||||
func (slf *FSM[S, Data]) Update() {
|
||||
state := slf.states[slf.current]
|
||||
state.Update(slf.data)
|
||||
func (slf *FSM[State, Data]) Update() {
|
||||
if slf.current == nil {
|
||||
return
|
||||
}
|
||||
for _, event := range slf.updateEventHandles[*slf.current] {
|
||||
event(slf)
|
||||
}
|
||||
}
|
||||
|
||||
// Register 注册状态
|
||||
func (slf *FSM[S, Data]) Register(state *State[S, Data]) {
|
||||
slf.states[state.GetState()] = state
|
||||
func (slf *FSM[State, Data]) Register(state State, options ...Option[State, Data]) {
|
||||
slf.states[state] = struct{}{}
|
||||
for _, option := range options {
|
||||
option(slf, state)
|
||||
}
|
||||
}
|
||||
|
||||
// Unregister 反注册状态
|
||||
func (slf *FSM[S, Data]) Unregister(state S) {
|
||||
func (slf *FSM[State, Data]) Unregister(state State) {
|
||||
if !slf.HasState(state) {
|
||||
return
|
||||
}
|
||||
delete(slf.states, state)
|
||||
delete(slf.enterBeforeEventHandles, state)
|
||||
delete(slf.enterAfterEventHandles, state)
|
||||
delete(slf.updateEventHandles, state)
|
||||
delete(slf.exitBeforeEventHandles, state)
|
||||
delete(slf.exitAfterEventHandles, state)
|
||||
}
|
||||
|
||||
// HasState 检查状态机是否存在特定状态
|
||||
func (slf *FSM[S, Data]) HasState(state S) bool {
|
||||
_, has := slf.states[state]
|
||||
return has
|
||||
func (slf *FSM[State, Data]) HasState(state State) bool {
|
||||
return hash.Exist(slf.states, state)
|
||||
}
|
||||
|
||||
// Change 改变状态机状态到新的状态
|
||||
func (slf *FSM[S, Data]) Change(state S) {
|
||||
current := slf.states[slf.current]
|
||||
current.Exit(slf.data)
|
||||
func (slf *FSM[State, Data]) Change(state State) {
|
||||
if !slf.IsZero() {
|
||||
for _, event := range slf.exitBeforeEventHandles[*slf.current] {
|
||||
event(slf)
|
||||
}
|
||||
}
|
||||
|
||||
next := slf.states[state]
|
||||
if next == nil {
|
||||
slf.prev = slf.current
|
||||
slf.current = &state
|
||||
|
||||
if !slf.PrevIsZero() {
|
||||
for _, event := range slf.exitAfterEventHandles[*slf.prev] {
|
||||
event(slf)
|
||||
}
|
||||
}
|
||||
|
||||
if !slf.HasState(state) {
|
||||
panic(fmt.Errorf("FSM object is attempting to switch to an invalid / undefined state: %v", state))
|
||||
}
|
||||
|
||||
next.Enter(slf.data)
|
||||
for _, event := range slf.enterBeforeEventHandles[*slf.current] {
|
||||
event(slf)
|
||||
}
|
||||
|
||||
for _, event := range slf.enterAfterEventHandles[*slf.current] {
|
||||
event(slf)
|
||||
}
|
||||
}
|
||||
|
||||
// Current 获取当前状态
|
||||
func (slf *FSM[State, Data]) Current() (state State) {
|
||||
if slf.current == nil {
|
||||
return
|
||||
}
|
||||
return *slf.current
|
||||
}
|
||||
|
||||
// GetData 获取状态机数据
|
||||
func (slf *FSM[State, Data]) GetData() Data {
|
||||
return slf.data
|
||||
}
|
||||
|
||||
// IsZero 检查状态机是否无状态
|
||||
func (slf *FSM[State, Data]) IsZero() bool {
|
||||
return slf.current == nil
|
||||
}
|
||||
|
||||
// PrevIsZero 检查状态机上一个状态是否无状态
|
||||
func (slf *FSM[State, Data]) PrevIsZero() bool {
|
||||
return slf.prev == nil
|
||||
}
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
package fsm
|
||||
|
||||
type (
|
||||
StateEnterHandle[Data any] func(data Data)
|
||||
StateUpdateHandle[Data any] func(data Data)
|
||||
StateExitHandle[Data any] func(data Data)
|
||||
)
|
||||
|
||||
func NewFSMState[S comparable, Data any](state S, enter StateEnterHandle[Data], update StateUpdateHandle[Data], exit StateExitHandle[Data]) *State[S, Data] {
|
||||
return &State[S, Data]{
|
||||
enter: enter,
|
||||
update: update,
|
||||
exit: exit,
|
||||
}
|
||||
}
|
||||
|
||||
type State[S comparable, Data any] struct {
|
||||
state S
|
||||
enter StateEnterHandle[Data]
|
||||
update StateUpdateHandle[Data]
|
||||
exit StateExitHandle[Data]
|
||||
}
|
||||
|
||||
func (slf *State[S, Data]) GetState() S {
|
||||
return slf.state
|
||||
}
|
||||
|
||||
func (slf *State[S, Data]) Enter(data Data) {
|
||||
slf.enter(data)
|
||||
}
|
||||
|
||||
func (slf *State[S, Data]) Update(data Data) {
|
||||
slf.update(data)
|
||||
}
|
||||
|
||||
func (slf *State[S, Data]) Exit(data Data) {
|
||||
slf.exit(data)
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package fsm
|
||||
|
||||
type Option[State comparable, Data any] func(fsm *FSM[State, Data], state State)
|
||||
|
||||
// WithEnterBeforeEvent 设置状态进入前的回调
|
||||
// - 在首次设置状态时,状态机本身的当前状态为零值状态
|
||||
func WithEnterBeforeEvent[State comparable, Data any](fn func(state *FSM[State, Data])) Option[State, Data] {
|
||||
return func(fsm *FSM[State, Data], state State) {
|
||||
if fsm.enterBeforeEventHandles == nil {
|
||||
fsm.enterBeforeEventHandles = map[State][]func(state *FSM[State, Data]){}
|
||||
}
|
||||
fsm.enterBeforeEventHandles[state] = append(fsm.enterBeforeEventHandles[state], fn)
|
||||
}
|
||||
}
|
||||
|
||||
// WithEnterAfterEvent 设置状态进入后的回调
|
||||
func WithEnterAfterEvent[State comparable, Data any](fn func(state *FSM[State, Data])) Option[State, Data] {
|
||||
return func(fsm *FSM[State, Data], state State) {
|
||||
if fsm.enterAfterEventHandles == nil {
|
||||
fsm.enterAfterEventHandles = map[State][]func(state *FSM[State, Data]){}
|
||||
}
|
||||
fsm.enterAfterEventHandles[state] = append(fsm.enterAfterEventHandles[state], fn)
|
||||
}
|
||||
}
|
||||
|
||||
// WithUpdateEvent 设置状态内刷新的回调
|
||||
func WithUpdateEvent[State comparable, Data any](fn func(state *FSM[State, Data])) Option[State, Data] {
|
||||
return func(fsm *FSM[State, Data], state State) {
|
||||
if fsm.updateEventHandles == nil {
|
||||
fsm.updateEventHandles = map[State][]func(state *FSM[State, Data]){}
|
||||
}
|
||||
fsm.updateEventHandles[state] = append(fsm.updateEventHandles[state], fn)
|
||||
}
|
||||
}
|
||||
|
||||
// WithExitBeforeEvent 设置状态退出前的回调
|
||||
// - 该阶段状态机的状态为退出前的状态,而非新的状态
|
||||
func WithExitBeforeEvent[State comparable, Data any](fn func(state *FSM[State, Data])) Option[State, Data] {
|
||||
return func(fsm *FSM[State, Data], state State) {
|
||||
if fsm.exitBeforeEventHandles == nil {
|
||||
fsm.exitBeforeEventHandles = map[State][]func(state *FSM[State, Data]){}
|
||||
}
|
||||
fsm.exitBeforeEventHandles[state] = append(fsm.exitBeforeEventHandles[state], fn)
|
||||
}
|
||||
}
|
||||
|
||||
// WithExitAfterEvent 设置状态退出后的回调
|
||||
// - 该阶段状态机的状态为新的状态,而非退出前的状态
|
||||
func WithExitAfterEvent[State comparable, Data any](fn func(state *FSM[State, Data])) Option[State, Data] {
|
||||
return func(fsm *FSM[State, Data], state State) {
|
||||
if fsm.exitAfterEventHandles == nil {
|
||||
fsm.exitAfterEventHandles = map[State][]func(state *FSM[State, Data]){}
|
||||
}
|
||||
fsm.exitAfterEventHandles[state] = append(fsm.exitAfterEventHandles[state], fn)
|
||||
}
|
||||
}
|
|
@ -21,8 +21,8 @@ type (
|
|||
PlayerSeatSetEventHandle[PID comparable, P game.Player[PID], R Room] func(room R, player P, seat int)
|
||||
// PlayerSeatCancelEventHandle 玩家座位取消事件处理函数
|
||||
PlayerSeatCancelEventHandle[PID comparable, P game.Player[PID], R Room] func(room R, player P, seat int)
|
||||
// RoomCreateEventHandle 房间创建事件处理函数
|
||||
RoomCreateEventHandle[PID comparable, P game.Player[PID], R Room] func(room R, helper *Helper[PID, P, R])
|
||||
// CreateEventHandle 房间创建事件处理函数
|
||||
CreateEventHandle[PID comparable, P game.Player[PID], R Room] func(room R, helper *Helper[PID, P, R])
|
||||
)
|
||||
|
||||
func newEvent[PID comparable, P game.Player[PID], R Room]() *event[PID, P, R] {
|
||||
|
@ -57,7 +57,7 @@ type event[PID comparable, P game.Player[PID], R Room] struct {
|
|||
playerSeatSetEventRoomHandles map[int64][]PlayerSeatSetEventHandle[PID, P, R]
|
||||
playerSeatCancelEventHandles []PlayerSeatCancelEventHandle[PID, P, R]
|
||||
playerSeatCancelEventRoomHandles map[int64][]PlayerSeatCancelEventHandle[PID, P, R]
|
||||
roomCreateEventHandles []RoomCreateEventHandle[PID, P, R]
|
||||
roomCreateEventHandles []CreateEventHandle[PID, P, R]
|
||||
}
|
||||
|
||||
func (slf *event[PID, P, R]) unReg(guid int64) {
|
||||
|
@ -254,7 +254,7 @@ func (slf *event[PID, P, R]) OnPlayerSeatCancelEvent(room R, player P, seat int)
|
|||
}
|
||||
|
||||
// RegRoomCreateEvent 房间创建时将立即执行被注册的事件处理函数
|
||||
func (slf *event[PID, P, R]) RegRoomCreateEvent(handle RoomCreateEventHandle[PID, P, R]) {
|
||||
func (slf *event[PID, P, R]) RegRoomCreateEvent(handle CreateEventHandle[PID, P, R]) {
|
||||
slf.roomCreateEventHandles = append(slf.roomCreateEventHandles, handle)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue