feat: 房间管理器实现
This commit is contained in:
parent
d26ef3aca6
commit
45c855a516
|
@ -0,0 +1,12 @@
|
|||
package room
|
||||
|
||||
import "errors"
|
||||
|
||||
var (
|
||||
// ErrRoomNotExist 房间不存在
|
||||
ErrRoomNotExist = errors.New("room not exist")
|
||||
// ErrRoomPlayerFull 房间人数已满
|
||||
ErrRoomPlayerFull = errors.New("room player full")
|
||||
// ErrPlayerNotExist 玩家不存在
|
||||
ErrPlayerNotExist = errors.New("player not exist")
|
||||
)
|
|
@ -0,0 +1,95 @@
|
|||
package room
|
||||
|
||||
import "github.com/kercylan98/minotaur/game"
|
||||
|
||||
type (
|
||||
// PlayerJoinRoomEventHandle 玩家加入房间事件处理函数
|
||||
PlayerJoinRoomEventHandle[PID comparable, P game.Player[PID], R Room[PID, P]] func(room R, player P)
|
||||
// PlayerLeaveRoomEventHandle 玩家离开房间事件处理函数
|
||||
PlayerLeaveRoomEventHandle[PID comparable, P game.Player[PID], R Room[PID, P]] func(room R, player P)
|
||||
// PlayerKickedOutEventHandle 玩家被踢出房间事件处理函数
|
||||
PlayerKickedOutEventHandle[PID comparable, P game.Player[PID], R Room[PID, P]] func(room R, executor, kicked PID, reason string)
|
||||
)
|
||||
|
||||
func newEvent[PID comparable, P game.Player[PID], R Room[PID, P]]() *event[PID, P, R] {
|
||||
return &event[PID, P, R]{
|
||||
playerJoinRoomEventRoomHandles: make(map[int64][]PlayerJoinRoomEventHandle[PID, P, R]),
|
||||
playerLeaveRoomEventRoomHandles: make(map[int64][]PlayerLeaveRoomEventHandle[PID, P, R]),
|
||||
playerKickedOutEventRoomHandles: make(map[int64][]PlayerKickedOutEventHandle[PID, P, R]),
|
||||
}
|
||||
}
|
||||
|
||||
type event[PID comparable, P game.Player[PID], R Room[PID, P]] struct {
|
||||
playerJoinRoomEventHandles []PlayerJoinRoomEventHandle[PID, P, R]
|
||||
playerJoinRoomEventRoomHandles map[int64][]PlayerJoinRoomEventHandle[PID, P, R]
|
||||
playerLeaveRoomEventHandles []PlayerLeaveRoomEventHandle[PID, P, R]
|
||||
playerLeaveRoomEventRoomHandles map[int64][]PlayerLeaveRoomEventHandle[PID, P, R]
|
||||
playerKickedOutEventHandles []PlayerKickedOutEventHandle[PID, P, R]
|
||||
playerKickedOutEventRoomHandles map[int64][]PlayerKickedOutEventHandle[PID, P, R]
|
||||
}
|
||||
|
||||
func (slf *event[PID, P, R]) unReg(guid int64) {
|
||||
delete(slf.playerJoinRoomEventRoomHandles, guid)
|
||||
delete(slf.playerLeaveRoomEventRoomHandles, guid)
|
||||
delete(slf.playerKickedOutEventRoomHandles, guid)
|
||||
}
|
||||
|
||||
// RegPlayerJoinRoomEvent 玩家进入房间时将立即执行被注册的事件处理函数
|
||||
func (slf *event[PID, P, R]) RegPlayerJoinRoomEvent(handle PlayerJoinRoomEventHandle[PID, P, R]) {
|
||||
slf.playerJoinRoomEventHandles = append(slf.playerJoinRoomEventHandles, handle)
|
||||
}
|
||||
|
||||
// OnPlayerJoinRoomEvent 玩家进入房间时将立即执行被注册的事件处理函数
|
||||
func (slf *event[PID, P, R]) OnPlayerJoinRoomEvent(room R, player P) {
|
||||
for _, handle := range slf.playerJoinRoomEventHandles {
|
||||
handle(room, player)
|
||||
}
|
||||
for _, handle := range slf.playerJoinRoomEventRoomHandles[room.GetGuid()] {
|
||||
handle(room, player)
|
||||
}
|
||||
}
|
||||
|
||||
// RegPlayerJoinRoomEventWithRoom 玩家进入房间时将立即执行被注册的事件处理函数
|
||||
func (slf *event[PID, P, R]) RegPlayerJoinRoomEventWithRoom(room R, handle PlayerJoinRoomEventHandle[PID, P, R]) {
|
||||
slf.playerJoinRoomEventRoomHandles[room.GetGuid()] = append(slf.playerJoinRoomEventRoomHandles[room.GetGuid()], handle)
|
||||
}
|
||||
|
||||
// RegPlayerLeaveRoomEvent 玩家离开房间时将立即执行被注册的事件处理函数
|
||||
func (slf *event[PID, P, R]) RegPlayerLeaveRoomEvent(handle PlayerLeaveRoomEventHandle[PID, P, R]) {
|
||||
slf.playerLeaveRoomEventHandles = append(slf.playerLeaveRoomEventHandles, handle)
|
||||
}
|
||||
|
||||
// RegPlayerLeaveRoomEventWithRoom 玩家离开房间时将立即执行被注册的事件处理函数
|
||||
func (slf *event[PID, P, R]) RegPlayerLeaveRoomEventWithRoom(room R, handle PlayerLeaveRoomEventHandle[PID, P, R]) {
|
||||
slf.playerLeaveRoomEventRoomHandles[room.GetGuid()] = append(slf.playerLeaveRoomEventRoomHandles[room.GetGuid()], handle)
|
||||
}
|
||||
|
||||
// OnPlayerLeaveRoomEvent 玩家离开房间时将立即执行被注册的事件处理函数
|
||||
func (slf *event[PID, P, R]) OnPlayerLeaveRoomEvent(room R, player P) {
|
||||
for _, handle := range slf.playerLeaveRoomEventHandles {
|
||||
handle(room, player)
|
||||
}
|
||||
for _, handle := range slf.playerLeaveRoomEventRoomHandles[room.GetGuid()] {
|
||||
handle(room, player)
|
||||
}
|
||||
}
|
||||
|
||||
// RegPlayerKickedOutEvent 玩家被踢出房间时将立即执行被注册的事件处理函数
|
||||
func (slf *event[PID, P, R]) RegPlayerKickedOutEvent(handle PlayerKickedOutEventHandle[PID, P, R]) {
|
||||
slf.playerKickedOutEventHandles = append(slf.playerKickedOutEventHandles, handle)
|
||||
}
|
||||
|
||||
// RegPlayerKickedOutEventWithRoom 玩家被踢出房间时将立即执行被注册的事件处理函数
|
||||
func (slf *event[PID, P, R]) RegPlayerKickedOutEventWithRoom(room R, handle PlayerKickedOutEventHandle[PID, P, R]) {
|
||||
slf.playerKickedOutEventRoomHandles[room.GetGuid()] = append(slf.playerKickedOutEventRoomHandles[room.GetGuid()], handle)
|
||||
}
|
||||
|
||||
// OnPlayerKickedOutEvent 玩家被踢出房间时将立即执行被注册的事件处理函数
|
||||
func (slf *event[PID, P, R]) OnPlayerKickedOutEvent(room R, executor, kicked PID, reason string) {
|
||||
for _, handle := range slf.playerKickedOutEventHandles {
|
||||
handle(room, executor, kicked, reason)
|
||||
}
|
||||
for _, handle := range slf.playerKickedOutEventRoomHandles[room.GetGuid()] {
|
||||
handle(room, executor, kicked, reason)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package room
|
||||
|
||||
import "github.com/kercylan98/minotaur/game"
|
||||
|
||||
type info[PlayerID comparable, P game.Player[PlayerID], R Room[PlayerID, P]] struct {
|
||||
room R
|
||||
playerLimit int // 玩家人数上限, <= 0 表示无限制
|
||||
}
|
|
@ -0,0 +1,259 @@
|
|||
package room
|
||||
|
||||
import (
|
||||
"github.com/kercylan98/minotaur/game"
|
||||
"github.com/kercylan98/minotaur/utils/concurrent"
|
||||
)
|
||||
|
||||
// NewManager 创建房间管理器
|
||||
func NewManager[PID comparable, P game.Player[PID], R Room[PID, P]]() *Manager[PID, P, R] {
|
||||
manager := &Manager[PID, P, R]{
|
||||
event: newEvent[PID, P, R](),
|
||||
rooms: concurrent.NewBalanceMap[int64, *info[PID, P, R]](),
|
||||
players: concurrent.NewBalanceMap[PID, P](),
|
||||
pr: concurrent.NewBalanceMap[PID, map[int64]struct{}](),
|
||||
}
|
||||
|
||||
return manager
|
||||
}
|
||||
|
||||
// Manager 房间管理器
|
||||
type Manager[PID comparable, P game.Player[PID], R Room[PID, P]] struct {
|
||||
*event[PID, P, R]
|
||||
rooms *concurrent.BalanceMap[int64, *info[PID, P, R]] // 所有房间
|
||||
players *concurrent.BalanceMap[PID, P] // 所有加入房间的玩家
|
||||
pr *concurrent.BalanceMap[PID, map[int64]struct{}] // 玩家所在房间
|
||||
rp *concurrent.BalanceMap[int64, map[PID]struct{}] // 房间中的玩家
|
||||
|
||||
}
|
||||
|
||||
// CreateRoom 创建房间
|
||||
func (slf *Manager[PID, P, R]) CreateRoom(room R) {
|
||||
roomInfo := &info[PID, P, R]{room: room}
|
||||
slf.rooms.Set(room.GetGuid(), roomInfo)
|
||||
}
|
||||
|
||||
// ReleaseRoom 释放房间
|
||||
func (slf *Manager[PID, P, R]) ReleaseRoom(guid int64) {
|
||||
slf.unReg(guid)
|
||||
slf.rooms.Delete(guid)
|
||||
}
|
||||
|
||||
// GetRoom 获取房间
|
||||
func (slf *Manager[PID, P, R]) GetRoom(guid int64) R {
|
||||
return slf.rooms.Get(guid).room
|
||||
}
|
||||
|
||||
// Exist 检查房间是否存在
|
||||
func (slf *Manager[PID, P, R]) Exist(guid int64) bool {
|
||||
return slf.rooms.Exist(guid)
|
||||
}
|
||||
|
||||
// GetRooms 获取所有房间
|
||||
func (slf *Manager[PID, P, R]) GetRooms() map[int64]R {
|
||||
var rooms = make(map[int64]R)
|
||||
slf.rooms.Atom(func(m map[int64]*info[PID, P, R]) {
|
||||
for id, info := range m {
|
||||
rooms[id] = info.room
|
||||
}
|
||||
})
|
||||
return rooms
|
||||
}
|
||||
|
||||
// GetRoomCount 获取房间数量
|
||||
func (slf *Manager[PID, P, R]) GetRoomCount() int {
|
||||
return slf.rooms.Size()
|
||||
}
|
||||
|
||||
// GetRoomPlayerCount 获取房间中玩家数量
|
||||
func (slf *Manager[PID, P, R]) GetRoomPlayerCount(guid int64) int {
|
||||
var count int
|
||||
slf.rp.Atom(func(m map[int64]map[PID]struct{}) {
|
||||
count = len(m[guid])
|
||||
})
|
||||
return count
|
||||
}
|
||||
|
||||
// ExistPlayer 检查玩家是否在任一房间内
|
||||
func (slf *Manager[PID, P, R]) ExistPlayer(id PID) bool {
|
||||
return slf.players.Exist(id)
|
||||
}
|
||||
|
||||
// InRoom 检查玩家是否在指定房间内
|
||||
func (slf *Manager[PID, P, R]) InRoom(id PID, guid int64) bool {
|
||||
var in bool
|
||||
slf.pr.Atom(func(m map[PID]map[int64]struct{}) {
|
||||
rooms, exist := m[id]
|
||||
if !exist {
|
||||
return
|
||||
}
|
||||
_, in = rooms[guid]
|
||||
})
|
||||
return in
|
||||
}
|
||||
|
||||
// GetPlayer 获取玩家
|
||||
func (slf *Manager[PID, P, R]) GetPlayer(id PID) P {
|
||||
return slf.players.Get(id)
|
||||
}
|
||||
|
||||
// GetPlayers 获取所有玩家
|
||||
func (slf *Manager[PID, P, R]) GetPlayers() *concurrent.BalanceMap[PID, P] {
|
||||
return slf.players
|
||||
}
|
||||
|
||||
// GetPlayerCount 获取玩家数量
|
||||
func (slf *Manager[PID, P, R]) GetPlayerCount() int {
|
||||
return slf.players.Size()
|
||||
}
|
||||
|
||||
// GetPlayerRoom 获取玩家所在房间
|
||||
func (slf *Manager[PID, P, R]) GetPlayerRoom(id PID) []R {
|
||||
var result = make([]R, 0)
|
||||
slf.pr.Atom(func(m map[PID]map[int64]struct{}) {
|
||||
rooms, exist := m[id]
|
||||
if !exist {
|
||||
return
|
||||
}
|
||||
for id := range rooms {
|
||||
result = append(result, slf.rooms.Get(id).room)
|
||||
}
|
||||
})
|
||||
return result
|
||||
}
|
||||
|
||||
// GetPlayerRoomCount 获取玩家所在房间数量
|
||||
func (slf *Manager[PID, P, R]) GetPlayerRoomCount(id PID) int {
|
||||
var count int
|
||||
slf.pr.Atom(func(m map[PID]map[int64]struct{}) {
|
||||
count = len(m[id])
|
||||
})
|
||||
return count
|
||||
}
|
||||
|
||||
// GetRoomPlayer 获取房间中的玩家
|
||||
func (slf *Manager[PID, P, R]) GetRoomPlayer(roomId int64, playerId PID) P {
|
||||
var player P
|
||||
slf.rp.Atom(func(m map[int64]map[PID]struct{}) {
|
||||
players, exist := m[roomId]
|
||||
if !exist {
|
||||
return
|
||||
}
|
||||
_, exist = players[playerId]
|
||||
if !exist {
|
||||
return
|
||||
}
|
||||
player = slf.players.Get(playerId)
|
||||
})
|
||||
return player
|
||||
}
|
||||
|
||||
// GetRoomPlayers 获取房间中的玩家
|
||||
func (slf *Manager[PID, P, R]) GetRoomPlayers(guid int64) map[PID]P {
|
||||
var result = make(map[PID]P)
|
||||
slf.rp.Atom(func(m map[int64]map[PID]struct{}) {
|
||||
players, exist := m[guid]
|
||||
if !exist {
|
||||
return
|
||||
}
|
||||
for id := range players {
|
||||
result[id] = slf.players.Get(id)
|
||||
}
|
||||
})
|
||||
return result
|
||||
}
|
||||
|
||||
// GetRoomPlayerLimit 获取房间中的玩家数量上限
|
||||
func (slf *Manager[PID, P, R]) GetRoomPlayerLimit(guid int64) int {
|
||||
return slf.rooms.Get(guid).playerLimit
|
||||
}
|
||||
|
||||
// Leave 使玩家离开房间
|
||||
func (slf *Manager[PID, P, R]) Leave(roomId int64, player P) {
|
||||
slf.rooms.Atom(func(m map[int64]*info[PID, P, R]) {
|
||||
room, exist := m[roomId]
|
||||
if !exist {
|
||||
return
|
||||
}
|
||||
slf.OnPlayerLeaveRoomEvent(room.room, player)
|
||||
slf.pr.Atom(func(m map[PID]map[int64]struct{}) {
|
||||
rooms, exist := m[player.GetID()]
|
||||
if !exist {
|
||||
return
|
||||
}
|
||||
delete(rooms, roomId)
|
||||
})
|
||||
slf.rp.Atom(func(m map[int64]map[PID]struct{}) {
|
||||
players, exist := m[roomId]
|
||||
if !exist {
|
||||
return
|
||||
}
|
||||
delete(players, player.GetID())
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Join 使玩家加入房间
|
||||
func (slf *Manager[PID, P, R]) Join(player P, roomId int64) error {
|
||||
var err error
|
||||
slf.rooms.Atom(func(m map[int64]*info[PID, P, R]) {
|
||||
room, exist := m[roomId]
|
||||
if !exist {
|
||||
err = ErrRoomNotExist
|
||||
return
|
||||
}
|
||||
if room.playerLimit > 0 && room.playerLimit <= slf.GetRoomPlayerCount(roomId) {
|
||||
err = ErrRoomPlayerFull
|
||||
return
|
||||
}
|
||||
slf.pr.Atom(func(m map[PID]map[int64]struct{}) {
|
||||
rooms, exist := m[player.GetID()]
|
||||
if !exist {
|
||||
rooms = make(map[int64]struct{})
|
||||
m[player.GetID()] = rooms
|
||||
}
|
||||
rooms[roomId] = struct{}{}
|
||||
})
|
||||
slf.rp.Atom(func(m map[int64]map[PID]struct{}) {
|
||||
players, exist := m[roomId]
|
||||
if !exist {
|
||||
players = make(map[PID]struct{})
|
||||
m[roomId] = players
|
||||
}
|
||||
players[player.GetID()] = struct{}{}
|
||||
})
|
||||
slf.players.Set(player.GetID(), player)
|
||||
slf.OnPlayerJoinRoomEvent(room.room, player)
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// KickOut 以某种原因踢出特定玩家
|
||||
// - 该函数不会校验任何权限相关的内容,调用后将直接踢出玩家
|
||||
func (slf *Manager[PID, P, R]) KickOut(roomId int64, executor, kicked PID, reason string) error {
|
||||
var err error
|
||||
var room R
|
||||
slf.rp.Atom(func(m map[int64]map[PID]struct{}) {
|
||||
players, exist := m[roomId]
|
||||
if !exist {
|
||||
err = ErrPlayerNotExist
|
||||
return
|
||||
}
|
||||
_, exist = players[executor]
|
||||
if !exist {
|
||||
err = ErrPlayerNotExist
|
||||
return
|
||||
}
|
||||
_, exist = players[kicked]
|
||||
if !exist {
|
||||
return
|
||||
}
|
||||
room = slf.rooms.Get(roomId).room
|
||||
})
|
||||
if err == nil {
|
||||
return err
|
||||
}
|
||||
slf.OnPlayerKickedOutEvent(room, executor, kicked, reason)
|
||||
slf.Leave(roomId, slf.players.Get(kicked))
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package room
|
||||
|
||||
import "github.com/kercylan98/minotaur/game"
|
||||
|
||||
// Room 房间类似于简版的游戏世界(World),不过没有游戏实体
|
||||
type Room[PlayerID comparable, P game.Player[PlayerID]] interface {
|
||||
// GetGuid 获取房间的唯一标识符
|
||||
GetGuid() int64
|
||||
// GetPlayerLimit 获取玩家人数上限
|
||||
GetPlayerLimit() int
|
||||
// GetPlayer 根据玩家id获取玩家
|
||||
GetPlayer(id PlayerID) P
|
||||
// GetPlayers 获取房间中的所有玩家
|
||||
GetPlayers() map[PlayerID]P
|
||||
// GetPlayerCount 获取玩家数量
|
||||
GetPlayerCount() int
|
||||
// IsExistPlayer 检查房间中是否存在特定玩家
|
||||
IsExistPlayer(id PlayerID) bool
|
||||
// IsOwner 检查玩家是否是房主
|
||||
IsOwner(id PlayerID) bool
|
||||
// ChangeOwner 设置玩家为房主
|
||||
ChangeOwner(id PlayerID)
|
||||
|
||||
// Join 使特定玩家加入房间
|
||||
Join(player P) error
|
||||
// Leave 使特定玩家离开房间
|
||||
Leave(id PlayerID)
|
||||
// KickOut 将特定玩家踢出房间
|
||||
KickOut(id, target PlayerID, reason string) error
|
||||
}
|
|
@ -21,150 +21,183 @@ func NewBalanceMap[Key comparable, value any](options ...BalanceMapOption[Key, v
|
|||
type BalanceMap[Key comparable, Value any] struct {
|
||||
lock sync.RWMutex
|
||||
data map[Key]Value
|
||||
atom bool
|
||||
}
|
||||
|
||||
// Set 设置一个值
|
||||
func (slf *BalanceMap[Key, Value]) Set(key Key, value Value) {
|
||||
slf.lock.Lock()
|
||||
defer slf.lock.Unlock()
|
||||
if !slf.atom {
|
||||
slf.lock.Lock()
|
||||
defer slf.lock.Unlock()
|
||||
}
|
||||
slf.data[key] = value
|
||||
}
|
||||
|
||||
// Get 获取一个值
|
||||
func (slf *BalanceMap[Key, Value]) Get(key Key) Value {
|
||||
slf.lock.RLock()
|
||||
defer slf.lock.RUnlock()
|
||||
if !slf.atom {
|
||||
slf.lock.RLock()
|
||||
defer slf.lock.RUnlock()
|
||||
}
|
||||
return slf.data[key]
|
||||
}
|
||||
|
||||
// Atom 原子操作
|
||||
func (slf *BalanceMap[Key, Value]) Atom(handle func(m map[Key]Value)) {
|
||||
slf.lock.Lock()
|
||||
if !slf.atom {
|
||||
slf.lock.Lock()
|
||||
defer slf.lock.Unlock()
|
||||
}
|
||||
handle(slf.data)
|
||||
slf.lock.Unlock()
|
||||
}
|
||||
|
||||
// Exist 判断是否存在
|
||||
func (slf *BalanceMap[Key, Value]) Exist(key Key) bool {
|
||||
slf.lock.RLock()
|
||||
if !slf.atom {
|
||||
slf.lock.RLock()
|
||||
defer slf.lock.RUnlock()
|
||||
}
|
||||
_, exist := slf.data[key]
|
||||
slf.lock.RUnlock()
|
||||
return exist
|
||||
}
|
||||
|
||||
// GetExist 获取一个值并判断是否存在
|
||||
func (slf *BalanceMap[Key, Value]) GetExist(key Key) (Value, bool) {
|
||||
slf.lock.RLock()
|
||||
if !slf.atom {
|
||||
slf.lock.RLock()
|
||||
defer slf.lock.RUnlock()
|
||||
}
|
||||
value, exist := slf.data[key]
|
||||
slf.lock.RUnlock()
|
||||
return value, exist
|
||||
}
|
||||
|
||||
// Delete 删除一个值
|
||||
func (slf *BalanceMap[Key, Value]) Delete(key Key) {
|
||||
slf.lock.Lock()
|
||||
if !slf.atom {
|
||||
slf.lock.Lock()
|
||||
defer slf.lock.Unlock()
|
||||
}
|
||||
delete(slf.data, key)
|
||||
defer slf.lock.Unlock()
|
||||
}
|
||||
|
||||
// DeleteGet 删除一个值并返回
|
||||
func (slf *BalanceMap[Key, Value]) DeleteGet(key Key) Value {
|
||||
slf.lock.Lock()
|
||||
if !slf.atom {
|
||||
slf.lock.Lock()
|
||||
defer slf.lock.Unlock()
|
||||
}
|
||||
v := slf.data[key]
|
||||
delete(slf.data, key)
|
||||
slf.lock.Unlock()
|
||||
return v
|
||||
}
|
||||
|
||||
// DeleteGetExist 删除一个值并返回是否存在
|
||||
func (slf *BalanceMap[Key, Value]) DeleteGetExist(key Key) (Value, bool) {
|
||||
slf.lock.Lock()
|
||||
if !slf.atom {
|
||||
slf.lock.Lock()
|
||||
defer slf.lock.Unlock()
|
||||
}
|
||||
v, exist := slf.data[key]
|
||||
delete(slf.data, key)
|
||||
defer slf.lock.Unlock()
|
||||
return v, exist
|
||||
}
|
||||
|
||||
// DeleteExist 删除一个值并返回是否存在
|
||||
func (slf *BalanceMap[Key, Value]) DeleteExist(key Key) bool {
|
||||
slf.lock.Lock()
|
||||
if !slf.atom {
|
||||
slf.lock.Lock()
|
||||
defer slf.lock.Unlock()
|
||||
}
|
||||
if _, exist := slf.data[key]; !exist {
|
||||
slf.lock.Unlock()
|
||||
return exist
|
||||
}
|
||||
delete(slf.data, key)
|
||||
slf.lock.Unlock()
|
||||
return true
|
||||
}
|
||||
|
||||
// Clear 清空
|
||||
func (slf *BalanceMap[Key, Value]) Clear() {
|
||||
slf.lock.Lock()
|
||||
if !slf.atom {
|
||||
slf.lock.Lock()
|
||||
defer slf.lock.Unlock()
|
||||
}
|
||||
for k := range slf.data {
|
||||
delete(slf.data, k)
|
||||
}
|
||||
slf.lock.Unlock()
|
||||
}
|
||||
|
||||
// ClearHandle 清空并处理
|
||||
func (slf *BalanceMap[Key, Value]) ClearHandle(handle func(key Key, value Value)) {
|
||||
slf.lock.Lock()
|
||||
if !slf.atom {
|
||||
slf.lock.Lock()
|
||||
defer slf.lock.Unlock()
|
||||
}
|
||||
for k, v := range slf.data {
|
||||
handle(k, v)
|
||||
delete(slf.data, k)
|
||||
}
|
||||
slf.lock.Unlock()
|
||||
}
|
||||
|
||||
// Range 遍历所有值,如果 handle 返回 true 则停止遍历
|
||||
func (slf *BalanceMap[Key, Value]) Range(handle func(key Key, value Value) bool) {
|
||||
slf.lock.Lock()
|
||||
if !slf.atom {
|
||||
slf.lock.Lock()
|
||||
defer slf.lock.Unlock()
|
||||
}
|
||||
for k, v := range slf.data {
|
||||
key, value := k, v
|
||||
if handle(key, value) {
|
||||
break
|
||||
}
|
||||
}
|
||||
slf.lock.Unlock()
|
||||
}
|
||||
|
||||
// Keys 获取所有的键
|
||||
func (slf *BalanceMap[Key, Value]) Keys() []Key {
|
||||
slf.lock.RLock()
|
||||
if !slf.atom {
|
||||
slf.lock.RLock()
|
||||
defer slf.lock.RUnlock()
|
||||
}
|
||||
var s = make([]Key, 0, len(slf.data))
|
||||
for k := range slf.data {
|
||||
s = append(s, k)
|
||||
}
|
||||
slf.lock.RUnlock()
|
||||
return s
|
||||
}
|
||||
|
||||
// Slice 获取所有的值
|
||||
func (slf *BalanceMap[Key, Value]) Slice() []Value {
|
||||
slf.lock.RLock()
|
||||
if !slf.atom {
|
||||
slf.lock.RLock()
|
||||
defer slf.lock.RUnlock()
|
||||
}
|
||||
var s = make([]Value, 0, len(slf.data))
|
||||
for _, v := range slf.data {
|
||||
s = append(s, v)
|
||||
}
|
||||
slf.lock.RUnlock()
|
||||
return s
|
||||
}
|
||||
|
||||
// Map 转换为普通 map
|
||||
func (slf *BalanceMap[Key, Value]) Map() map[Key]Value {
|
||||
slf.lock.RLock()
|
||||
if !slf.atom {
|
||||
slf.lock.RLock()
|
||||
defer slf.lock.RUnlock()
|
||||
}
|
||||
var m = make(map[Key]Value)
|
||||
for k, v := range slf.data {
|
||||
m[k] = v
|
||||
}
|
||||
slf.lock.RUnlock()
|
||||
return m
|
||||
}
|
||||
|
||||
// Size 获取数量
|
||||
func (slf *BalanceMap[Key, Value]) Size() int {
|
||||
slf.lock.RLock()
|
||||
defer slf.lock.RUnlock()
|
||||
if !slf.atom {
|
||||
slf.lock.RLock()
|
||||
defer slf.lock.RUnlock()
|
||||
}
|
||||
return len(slf.data)
|
||||
}
|
||||
|
||||
|
@ -175,11 +208,13 @@ func (slf *BalanceMap[Key, Value]) MarshalJSON() ([]byte, error) {
|
|||
|
||||
func (slf *BalanceMap[Key, Value]) UnmarshalJSON(bytes []byte) error {
|
||||
var m = make(map[Key]Value)
|
||||
if !slf.atom {
|
||||
slf.lock.Lock()
|
||||
slf.lock.Unlock()
|
||||
}
|
||||
if err := json.Unmarshal(bytes, &m); err != nil {
|
||||
return err
|
||||
}
|
||||
slf.lock.Lock()
|
||||
slf.data = m
|
||||
slf.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue