包调整、非同步map
This commit is contained in:
parent
a2429d5b99
commit
4565edb6d7
|
@ -2,6 +2,7 @@ package builtin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/kercylan98/minotaur/game"
|
"github.com/kercylan98/minotaur/game"
|
||||||
|
"github.com/kercylan98/minotaur/utils/hash"
|
||||||
"github.com/kercylan98/minotaur/utils/log"
|
"github.com/kercylan98/minotaur/utils/log"
|
||||||
"github.com/kercylan98/minotaur/utils/synchronization"
|
"github.com/kercylan98/minotaur/utils/synchronization"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
@ -43,7 +44,7 @@ func (slf *Room[PlayerID, Player]) GetPlayer(id PlayerID) Player {
|
||||||
return slf.players.Get(id)
|
return slf.players.Get(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (slf *Room[PlayerID, Player]) GetPlayers() synchronization.MapReadonly[PlayerID, Player] {
|
func (slf *Room[PlayerID, Player]) GetPlayers() hash.MapReadonly[PlayerID, Player] {
|
||||||
return slf.players
|
return slf.players
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package builtin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/kercylan98/minotaur/game"
|
"github.com/kercylan98/minotaur/game"
|
||||||
|
"github.com/kercylan98/minotaur/utils/hash"
|
||||||
"github.com/kercylan98/minotaur/utils/log"
|
"github.com/kercylan98/minotaur/utils/log"
|
||||||
"github.com/kercylan98/minotaur/utils/synchronization"
|
"github.com/kercylan98/minotaur/utils/synchronization"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
@ -56,7 +57,7 @@ func (slf *World[PlayerID, Player]) GetPlayer(id PlayerID) Player {
|
||||||
return slf.players.Get(id)
|
return slf.players.Get(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (slf *World[PlayerID, Player]) GetPlayers() synchronization.MapReadonly[PlayerID, Player] {
|
func (slf *World[PlayerID, Player]) GetPlayers() hash.MapReadonly[PlayerID, Player] {
|
||||||
return slf.players
|
return slf.players
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +65,7 @@ func (slf *World[PlayerID, Player]) GetActor(guid int64) game.Actor {
|
||||||
return slf.actors.Get(guid)
|
return slf.actors.Get(guid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (slf *World[PlayerID, Player]) GetActors() synchronization.MapReadonly[int64, game.Actor] {
|
func (slf *World[PlayerID, Player]) GetActors() hash.MapReadonly[int64, game.Actor] {
|
||||||
return slf.actors
|
return slf.actors
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +76,7 @@ func (slf *World[PlayerID, Player]) GetPlayerActor(id PlayerID, guid int64) game
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (slf *World[PlayerID, Player]) GetPlayerActors(id PlayerID) synchronization.MapReadonly[int64, game.Actor] {
|
func (slf *World[PlayerID, Player]) GetPlayerActors(id PlayerID) hash.MapReadonly[int64, game.Actor] {
|
||||||
return slf.playerActors.Get(id)
|
return slf.playerActors.Get(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package game
|
package game
|
||||||
|
|
||||||
import "github.com/kercylan98/minotaur/utils/synchronization"
|
import (
|
||||||
|
"github.com/kercylan98/minotaur/utils/hash"
|
||||||
|
)
|
||||||
|
|
||||||
// Room 房间类似于简版的游戏世界,不过没有游戏实体
|
// Room 房间类似于简版的游戏世界,不过没有游戏实体
|
||||||
type Room[PlayerID comparable, P Player[PlayerID]] interface {
|
type Room[PlayerID comparable, P Player[PlayerID]] interface {
|
||||||
|
@ -11,7 +13,7 @@ type Room[PlayerID comparable, P Player[PlayerID]] interface {
|
||||||
// GetPlayer 根据玩家id获取玩家
|
// GetPlayer 根据玩家id获取玩家
|
||||||
GetPlayer(id PlayerID) P
|
GetPlayer(id PlayerID) P
|
||||||
// GetPlayers 获取房间中的所有玩家
|
// GetPlayers 获取房间中的所有玩家
|
||||||
GetPlayers() synchronization.MapReadonly[PlayerID, P]
|
GetPlayers() hash.MapReadonly[PlayerID, P]
|
||||||
// GetPlayerCount 获取玩家数量
|
// GetPlayerCount 获取玩家数量
|
||||||
GetPlayerCount() int
|
GetPlayerCount() int
|
||||||
// IsExistPlayer 检查房间中是否存在特定玩家
|
// IsExistPlayer 检查房间中是否存在特定玩家
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package game
|
package game
|
||||||
|
|
||||||
import "github.com/kercylan98/minotaur/utils/synchronization"
|
import (
|
||||||
|
"github.com/kercylan98/minotaur/utils/hash"
|
||||||
|
)
|
||||||
|
|
||||||
// World 游戏世界接口定义
|
// World 游戏世界接口定义
|
||||||
type World[PlayerID comparable, P Player[PlayerID]] interface {
|
type World[PlayerID comparable, P Player[PlayerID]] interface {
|
||||||
|
@ -11,15 +13,15 @@ type World[PlayerID comparable, P Player[PlayerID]] interface {
|
||||||
// GetPlayer 根据玩家id获取玩家
|
// GetPlayer 根据玩家id获取玩家
|
||||||
GetPlayer(id PlayerID) P
|
GetPlayer(id PlayerID) P
|
||||||
// GetPlayers 获取世界中的所有玩家
|
// GetPlayers 获取世界中的所有玩家
|
||||||
GetPlayers() synchronization.MapReadonly[PlayerID, P]
|
GetPlayers() hash.MapReadonly[PlayerID, P]
|
||||||
// GetActor 根据唯一标识符获取世界中的游戏对象
|
// GetActor 根据唯一标识符获取世界中的游戏对象
|
||||||
GetActor(guid int64) Actor
|
GetActor(guid int64) Actor
|
||||||
// GetActors 获取世界中的所有游戏对象
|
// GetActors 获取世界中的所有游戏对象
|
||||||
GetActors() synchronization.MapReadonly[int64, Actor]
|
GetActors() hash.MapReadonly[int64, Actor]
|
||||||
// GetPlayerActor 获取游戏世界中归属特定玩家的特定游戏对象
|
// GetPlayerActor 获取游戏世界中归属特定玩家的特定游戏对象
|
||||||
GetPlayerActor(id PlayerID, guid int64) Actor
|
GetPlayerActor(id PlayerID, guid int64) Actor
|
||||||
// GetPlayerActors 获取游戏世界中归属特定玩家的所有游戏对象
|
// GetPlayerActors 获取游戏世界中归属特定玩家的所有游戏对象
|
||||||
GetPlayerActors(id PlayerID) synchronization.MapReadonly[int64, Actor]
|
GetPlayerActors(id PlayerID) hash.MapReadonly[int64, Actor]
|
||||||
// IsExistPlayer 检查游戏世界中是否存在特定玩家
|
// IsExistPlayer 检查游戏世界中是否存在特定玩家
|
||||||
IsExistPlayer(id PlayerID) bool
|
IsExistPlayer(id PlayerID) bool
|
||||||
// IsExistActor 检查游戏世界中是否存在特定游戏对象
|
// IsExistActor 检查游戏世界中是否存在特定游戏对象
|
||||||
|
|
|
@ -0,0 +1,194 @@
|
||||||
|
package asynchronization
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewMap[Key comparable, value any]() *Map[Key, value] {
|
||||||
|
return &Map[Key, value]{
|
||||||
|
data: make(map[Key]value),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map 非并发安全的字典数据结构
|
||||||
|
// - 可用于对 synchronization.Map 的替代
|
||||||
|
type Map[Key comparable, Value any] struct {
|
||||||
|
data map[Key]Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slf *Map[Key, Value]) Set(key Key, value Value) {
|
||||||
|
slf.data[key] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slf *Map[Key, Value]) Get(key Key) Value {
|
||||||
|
return slf.data[key]
|
||||||
|
}
|
||||||
|
|
||||||
|
// AtomGetSet 原子方式获取一个值并在之后进行赋值
|
||||||
|
func (slf *Map[Key, Value]) AtomGetSet(key Key, handle func(value Value, exist bool) (newValue Value, isSet bool)) {
|
||||||
|
value, exist := slf.data[key]
|
||||||
|
if newValue, isSet := handle(value, exist); isSet {
|
||||||
|
slf.data[key] = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Atom 原子操作
|
||||||
|
func (slf *Map[Key, Value]) Atom(handle func(m *Map[Key, Value])) {
|
||||||
|
handle(slf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slf *Map[Key, Value]) Exist(key Key) bool {
|
||||||
|
_, exist := slf.data[key]
|
||||||
|
return exist
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slf *Map[Key, Value]) GetExist(key Key) (Value, bool) {
|
||||||
|
value, exist := slf.data[key]
|
||||||
|
return value, exist
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slf *Map[Key, Value]) Length() int {
|
||||||
|
return len(slf.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slf *Map[Key, Value]) Delete(key Key) {
|
||||||
|
delete(slf.data, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slf *Map[Key, Value]) DeleteGet(key Key) Value {
|
||||||
|
v := slf.data[key]
|
||||||
|
delete(slf.data, key)
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slf *Map[Key, Value]) DeleteGetExist(key Key) (Value, bool) {
|
||||||
|
v, exist := slf.data[key]
|
||||||
|
delete(slf.data, key)
|
||||||
|
return v, exist
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slf *Map[Key, Value]) DeleteExist(key Key) bool {
|
||||||
|
if _, exist := slf.data[key]; !exist {
|
||||||
|
return exist
|
||||||
|
}
|
||||||
|
delete(slf.data, key)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slf *Map[Key, Value]) Clear() {
|
||||||
|
for k := range slf.data {
|
||||||
|
delete(slf.data, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slf *Map[Key, Value]) ClearHandle(handle func(key Key, value Value)) {
|
||||||
|
for k, v := range slf.data {
|
||||||
|
handle(k, v)
|
||||||
|
delete(slf.data, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slf *Map[Key, Value]) Range(handle func(key Key, value Value)) {
|
||||||
|
for k, v := range slf.data {
|
||||||
|
key, value := k, v
|
||||||
|
handle(key, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slf *Map[Key, Value]) RangeSkip(handle func(key Key, value Value) bool) {
|
||||||
|
for k, v := range slf.data {
|
||||||
|
key, value := k, v
|
||||||
|
if !handle(key, value) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slf *Map[Key, Value]) RangeBreakout(handle func(key Key, value Value) bool) {
|
||||||
|
slf.rangeBreakout(handle)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slf *Map[Key, Value]) rangeBreakout(handle func(key Key, value Value) bool) bool {
|
||||||
|
for k, v := range slf.data {
|
||||||
|
key, value := k, v
|
||||||
|
if !handle(key, value) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slf *Map[Key, Value]) RangeFree(handle func(key Key, value Value, skip func(), breakout func())) {
|
||||||
|
slf.rangeFree(handle)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slf *Map[Key, Value]) rangeFree(handle func(key Key, value Value, skip func(), breakout func())) bool {
|
||||||
|
var skipExec, breakoutExec bool
|
||||||
|
var skip = func() {
|
||||||
|
skipExec = true
|
||||||
|
}
|
||||||
|
var breakout = func() {
|
||||||
|
breakoutExec = true
|
||||||
|
}
|
||||||
|
for k, v := range slf.data {
|
||||||
|
key, value := k, v
|
||||||
|
handle(key, value, skip, breakout)
|
||||||
|
if skipExec {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if breakoutExec {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return breakoutExec
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slf *Map[Key, Value]) Keys() []Key {
|
||||||
|
var s = make([]Key, 0, len(slf.data))
|
||||||
|
for k, _ := range slf.data {
|
||||||
|
s = append(s, k)
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slf *Map[Key, Value]) Slice() []Value {
|
||||||
|
var s = make([]Value, 0, len(slf.data))
|
||||||
|
for _, v := range slf.data {
|
||||||
|
s = append(s, v)
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slf *Map[Key, Value]) Map() map[Key]Value {
|
||||||
|
var m = make(map[Key]Value)
|
||||||
|
for k, v := range slf.data {
|
||||||
|
m[k] = v
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slf *Map[Key, Value]) Size() int {
|
||||||
|
return len(slf.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetOne 获取一个
|
||||||
|
func (slf *Map[Key, Value]) GetOne() (value Value) {
|
||||||
|
for _, v := range slf.data {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slf *Map[Key, Value]) MarshalJSON() ([]byte, error) {
|
||||||
|
m := slf.Map()
|
||||||
|
return json.Marshal(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slf *Map[Key, Value]) UnmarshalJSON(bytes []byte) error {
|
||||||
|
var m = make(map[Key]Value)
|
||||||
|
if err := json.Unmarshal(bytes, &m); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
slf.data = m
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package synchronization
|
package hash
|
||||||
|
|
||||||
// MapReadonly 并发安全的只读字典接口
|
// MapReadonly 并发安全的只读字典接口
|
||||||
type MapReadonly[Key comparable, Value any] interface {
|
type MapReadonly[Key comparable, Value any] interface {
|
Loading…
Reference in New Issue