From 3d60ac64852d5e4f163f185340667cd3f065ef50 Mon Sep 17 00:00:00 2001 From: kercylan98 Date: Fri, 26 May 2023 10:49:16 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9C=89=E9=99=90=E7=8A=B6=E6=80=81=E6=9C=BA?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 ++ game/builtin/fsm.go | 49 +++++++++++++++++++++++++++++++++++++++ game/builtin/fsm_state.go | 34 +++++++++++++++++++++++++++ game/fsm.go | 10 ++++++++ game/fsm_state.go | 15 ++++++++++++ 5 files changed, 110 insertions(+) create mode 100644 game/builtin/fsm.go create mode 100644 game/builtin/fsm_state.go create mode 100644 game/fsm.go create mode 100644 game/fsm_state.go diff --git a/.gitignore b/.gitignore index 1492558..176e222 100644 --- a/.gitignore +++ b/.gitignore @@ -164,3 +164,5 @@ Network Trash Folder Temporary Items .apdisk +.refer +.refer/* \ No newline at end of file diff --git a/game/builtin/fsm.go b/game/builtin/fsm.go new file mode 100644 index 0000000..47a70f3 --- /dev/null +++ b/game/builtin/fsm.go @@ -0,0 +1,49 @@ +package builtin + +import ( + "fmt" + "github.com/kercylan98/minotaur/game" +) + +func NewFSM[State comparable, Data any](data Data) *FSM[State, Data] { + return &FSM[State, Data]{ + states: map[State]game.FSMState[State, Data]{}, + data: data, + } +} + +type FSM[State comparable, Data any] struct { + current State + data Data + states map[State]game.FSMState[State, Data] +} + +func (slf *FSM[State, Data]) Update() { + state := slf.states[slf.current] + state.Update(slf.data) +} + +func (slf *FSM[State, Data]) Register(state game.FSMState[State, Data]) { + slf.states[state.GetState()] = state +} + +func (slf *FSM[State, Data]) Unregister(state State) { + delete(slf.states, state) +} + +func (slf *FSM[State, Data]) HasState(state State) bool { + _, has := slf.states[state] + return has +} + +func (slf *FSM[State, Data]) Change(state State) { + current := slf.states[slf.current] + current.Exit(slf.data) + + next := slf.states[state] + if next == nil { + panic(fmt.Errorf("FSM object is attempting to switch to an invalid / undefined state: %v", state)) + } + + next.Enter(slf.data) +} diff --git a/game/builtin/fsm_state.go b/game/builtin/fsm_state.go new file mode 100644 index 0000000..34565b9 --- /dev/null +++ b/game/builtin/fsm_state.go @@ -0,0 +1,34 @@ +package builtin + +import "github.com/kercylan98/minotaur/game" + +func NewFSMState[State comparable, Data any](state State, enter game.FSMStateEnterHandle[Data], update game.FSMStateUpdateHandle[Data], exit game.FSMStateExitHandle[Data]) *FSMState[State, Data] { + return &FSMState[State, Data]{ + enter: enter, + update: update, + exit: exit, + } +} + +type FSMState[State comparable, Data any] struct { + state State + enter game.FSMStateEnterHandle[Data] + update game.FSMStateUpdateHandle[Data] + exit game.FSMStateExitHandle[Data] +} + +func (slf *FSMState[State, Data]) GetState() State { + return slf.state +} + +func (slf *FSMState[State, Data]) Enter(data Data) { + slf.enter(data) +} + +func (slf *FSMState[State, Data]) Update(data Data) { + slf.update(data) +} + +func (slf *FSMState[State, Data]) Exit(data Data) { + slf.exit(data) +} diff --git a/game/fsm.go b/game/fsm.go new file mode 100644 index 0000000..c2a8e8b --- /dev/null +++ b/game/fsm.go @@ -0,0 +1,10 @@ +package game + +// FSM 有限状态机 +type FSM[State comparable, Data comparable] interface { + Update() + Register(state FSMState[State, Data]) + Unregister(state State) + HasState(state State) bool + Change(state State) +} diff --git a/game/fsm_state.go b/game/fsm_state.go new file mode 100644 index 0000000..1de3a91 --- /dev/null +++ b/game/fsm_state.go @@ -0,0 +1,15 @@ +package game + +type ( + FSMStateEnterHandle[Data any] func(data Data) + FSMStateUpdateHandle[Data any] func(data Data) + FSMStateExitHandle[Data any] func(data Data) +) + +// FSMState 有限状态机状态 +type FSMState[State comparable, Data any] interface { + GetState() State + Enter(data Data) + Update(data Data) + Exit(data Data) +}