Files
bl/logic/service/space/space.go

72 lines
1.9 KiB
Go
Raw Normal View History

package space
import (
"blazing/common/data/entity"
"blazing/modules/blazing/model"
"sync"
)
// Space 针对Player的并发安全map键为uint32类型
type Space struct {
mu sync.RWMutex // 读写锁,读多写少场景更高效
data map[uint32]*entity.Player // 存储玩家数据的map键为玩家ID
CanRefresh bool //是否能够刷怪
ID uint32 // 地图ID
Name string //地图名称
DefaultPos model.Pos //默认位置DefaultPos
Positions map[uint32]model.Pos //从上一个地图跳转后默认位置
}
// NewSyncMap 创建一个新的玩家同步map
func NewSpace() *Space {
return &Space{
data: make(map[uint32]*entity.Player),
}
}
// Get 根据玩家ID获取玩家实例
// 读操作使用RLock允许多个goroutine同时读取
func (m *Space) Get(playerID uint32) (*entity.Player, bool) {
m.mu.RLock()
defer m.mu.RUnlock()
val, exists := m.data[playerID]
return val, exists
}
// Set 存储玩家实例按ID
// 写操作使用Lock独占锁保证数据一致性
func (m *Space) Set(playerID uint32, player *entity.Player) {
m.mu.Lock()
defer m.mu.Unlock()
m.data[playerID] = player
}
// Delete 根据玩家ID删除玩家实例
// 写操作使用Lock
func (m *Space) Delete(playerID uint32) {
m.mu.Lock()
defer m.mu.Unlock()
delete(m.data, playerID)
}
// Len 获取当前玩家数量
// 读操作使用RLock
func (m *Space) Len() int {
m.mu.RLock()
defer m.mu.RUnlock()
return len(m.data)
}
// Range 遍历所有玩家并执行回调函数
// 读操作使用RLock遍历过程中不会阻塞其他读操作
func (m *Space) Range(f func(playerID uint32, player *entity.Player) bool) {
m.mu.RLock()
defer m.mu.RUnlock()
for id, player := range m.data {
// 若回调返回false则停止遍历
if !f(id, player) {
break
}
}
}