docs: 增加 space 包 README.md 文档,优化 room 相关内容可读性
This commit is contained in:
parent
05aeed05a1
commit
9d9f7a3854
|
@ -0,0 +1,54 @@
|
|||
# Space
|
||||
|
||||
[](https://pkg.go.dev/github.com/kercylan98/minotaur/game/space)
|
||||
|
||||
计划提供游戏中常见的空间设计,例如房间、地图等。开发者可以使用它来快速构建游戏中的常见空间,例如多人房间、地图等。
|
||||
|
||||
## Room [`房间`]((https://pkg.go.dev/github.com/kercylan98/minotaur/game/space#RoomManager))
|
||||
房间在 `Minotaur` 中仅仅只是一个可以为任意可比较类型的 `ID`,当需要将现有或新设计的房间纳入 [`RoomManager`](https://pkg.go.dev/github.com/kercylan98/minotaur/game/space#RoomManager) 管理时,需要实现 [`Room`](https://pkg.go.dev/github.com/kercylan98/minotaur/game/space#RoomManager) 管理时,仅需要实现 [`generic.IdR`](https://pkg.go.dev/github.com/kercylan98/minotaur/utils/generic#IdR) 接口即可。
|
||||
|
||||
该功能由
|
||||
[`RoomManager`](https://pkg.go.dev/github.com/kercylan98/minotaur/game/space#RoomManager)、
|
||||
[`RoomController`](https://pkg.go.dev/github.com/kercylan98/minotaur/game/space#RoomController)
|
||||
组成。
|
||||
|
||||
当创建一个新的房间并纳入 [`RoomManager`](https://pkg.go.dev/github.com/kercylan98/minotaur/game/space#RoomManager) 管理后,将会得到一个 [`RoomController`](https://pkg.go.dev/github.com/kercylan98/minotaur/game/space#RoomController)。通过 [`RoomController`](https://pkg.go.dev/github.com/kercylan98/minotaur/game/space#RoomController) 可以对房间进行管理,例如:获取房间信息、加入房间、退出房间等。
|
||||
|
||||
### 使用示例
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/kercylan98/minotaur/game/space"
|
||||
)
|
||||
|
||||
type Room struct {
|
||||
Id int64
|
||||
}
|
||||
|
||||
func (r *Room) GetId() int64 {
|
||||
return r.Id
|
||||
}
|
||||
|
||||
type Player struct {
|
||||
Id string
|
||||
}
|
||||
|
||||
func (p *Player) GetId() string {
|
||||
return p.Id
|
||||
}
|
||||
|
||||
func main() {
|
||||
var rm = space.NewRoomManager[string, int64, *Player, *Room]()
|
||||
var room = &Room{Id: 1}
|
||||
var controller = rm.AssumeControl(room)
|
||||
|
||||
if err := controller.AddEntity(&Player{Id: "1"}); err != nil {
|
||||
// 房间密码不匹配或者房间已满
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Println(controller.GetEntityCount()) // 1
|
||||
}
|
||||
```
|
|
@ -0,0 +1,2 @@
|
|||
// Package space 游戏中常见的空间设计,例如房间、地图等
|
||||
package space
|
|
@ -36,59 +36,59 @@ type RoomController[EntityID comparable, RoomID comparable, Entity generic.IdR[E
|
|||
|
||||
// JoinSeat 设置特定对象加入座位,当具体的座位不存在的时候,将会自动分配座位
|
||||
// - 当目标座位存在玩家或未添加到房间中的时候,将会返回错误
|
||||
func (slf *RoomController[EntityID, RoomID, Entity, Room]) JoinSeat(entityId EntityID, seat ...int) error {
|
||||
slf.entitiesRWMutex.Lock()
|
||||
defer slf.entitiesRWMutex.Unlock()
|
||||
_, exist := slf.entities[entityId]
|
||||
func (rc *RoomController[EntityID, RoomID, Entity, Room]) JoinSeat(entityId EntityID, seat ...int) error {
|
||||
rc.entitiesRWMutex.Lock()
|
||||
defer rc.entitiesRWMutex.Unlock()
|
||||
_, exist := rc.entities[entityId]
|
||||
if !exist {
|
||||
return ErrNotInRoom
|
||||
}
|
||||
var targetSeat int
|
||||
if len(seat) > 0 {
|
||||
targetSeat = seat[0]
|
||||
if targetSeat < len(slf.seat) && slf.seat[targetSeat] != nil {
|
||||
if targetSeat < len(rc.seat) && rc.seat[targetSeat] != nil {
|
||||
return ErrSeatNotEmpty
|
||||
}
|
||||
} else {
|
||||
if len(slf.vacancy) > 0 {
|
||||
targetSeat = slf.vacancy[0]
|
||||
slf.vacancy = slf.vacancy[1:]
|
||||
if len(rc.vacancy) > 0 {
|
||||
targetSeat = rc.vacancy[0]
|
||||
rc.vacancy = rc.vacancy[1:]
|
||||
} else {
|
||||
targetSeat = len(slf.seat)
|
||||
targetSeat = len(rc.seat)
|
||||
}
|
||||
}
|
||||
|
||||
if targetSeat >= len(slf.seat) {
|
||||
slf.seat = append(slf.seat, make([]*EntityID, targetSeat-len(slf.seat)+1)...)
|
||||
if targetSeat >= len(rc.seat) {
|
||||
rc.seat = append(rc.seat, make([]*EntityID, targetSeat-len(rc.seat)+1)...)
|
||||
}
|
||||
|
||||
slf.seat[targetSeat] = &entityId
|
||||
rc.seat[targetSeat] = &entityId
|
||||
return nil
|
||||
}
|
||||
|
||||
// LeaveSeat 离开座位
|
||||
func (slf *RoomController[EntityID, RoomID, Entity, Room]) LeaveSeat(entityId EntityID) {
|
||||
slf.entitiesRWMutex.Lock()
|
||||
defer slf.entitiesRWMutex.Unlock()
|
||||
slf.leaveSeat(entityId)
|
||||
func (rc *RoomController[EntityID, RoomID, Entity, Room]) LeaveSeat(entityId EntityID) {
|
||||
rc.entitiesRWMutex.Lock()
|
||||
defer rc.entitiesRWMutex.Unlock()
|
||||
rc.leaveSeat(entityId)
|
||||
}
|
||||
|
||||
// leaveSeat 离开座位(无锁)
|
||||
func (slf *RoomController[EntityID, RoomID, Entity, Room]) leaveSeat(entityId EntityID) {
|
||||
for i, seat := range slf.seat {
|
||||
func (rc *RoomController[EntityID, RoomID, Entity, Room]) leaveSeat(entityId EntityID) {
|
||||
for i, seat := range rc.seat {
|
||||
if seat != nil && *seat == entityId {
|
||||
slf.seat[i] = nil
|
||||
slf.vacancy = append(slf.vacancy, i)
|
||||
rc.seat[i] = nil
|
||||
rc.vacancy = append(rc.vacancy, i)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GetSeat 获取座位
|
||||
func (slf *RoomController[EntityID, RoomID, Entity, Room]) GetSeat(entityId EntityID) int {
|
||||
slf.entitiesRWMutex.RLock()
|
||||
defer slf.entitiesRWMutex.RUnlock()
|
||||
for i, seat := range slf.seat {
|
||||
func (rc *RoomController[EntityID, RoomID, Entity, Room]) GetSeat(entityId EntityID) int {
|
||||
rc.entitiesRWMutex.RLock()
|
||||
defer rc.entitiesRWMutex.RUnlock()
|
||||
for i, seat := range rc.seat {
|
||||
if seat != nil && *seat == entityId {
|
||||
return i
|
||||
}
|
||||
|
@ -97,11 +97,11 @@ func (slf *RoomController[EntityID, RoomID, Entity, Room]) GetSeat(entityId Enti
|
|||
}
|
||||
|
||||
// GetNotEmptySeat 获取非空座位
|
||||
func (slf *RoomController[EntityID, RoomID, Entity, Room]) GetNotEmptySeat() []int {
|
||||
slf.entitiesRWMutex.RLock()
|
||||
defer slf.entitiesRWMutex.RUnlock()
|
||||
func (rc *RoomController[EntityID, RoomID, Entity, Room]) GetNotEmptySeat() []int {
|
||||
rc.entitiesRWMutex.RLock()
|
||||
defer rc.entitiesRWMutex.RUnlock()
|
||||
var seats []int
|
||||
for i, player := range slf.seat {
|
||||
for i, player := range rc.seat {
|
||||
if player != nil {
|
||||
seats = append(seats, i)
|
||||
}
|
||||
|
@ -111,21 +111,21 @@ func (slf *RoomController[EntityID, RoomID, Entity, Room]) GetNotEmptySeat() []i
|
|||
|
||||
// GetEmptySeat 获取空座位
|
||||
// - 空座位需要在有对象离开座位后才可能出现
|
||||
func (slf *RoomController[EntityID, RoomID, Entity, Room]) GetEmptySeat() []int {
|
||||
return slice.Copy(slf.vacancy)
|
||||
func (rc *RoomController[EntityID, RoomID, Entity, Room]) GetEmptySeat() []int {
|
||||
return slice.Copy(rc.vacancy)
|
||||
}
|
||||
|
||||
// HasSeat 判断是否有座位
|
||||
func (slf *RoomController[EntityID, RoomID, Entity, Room]) HasSeat(entityId EntityID) bool {
|
||||
return slf.GetSeat(entityId) != -1
|
||||
func (rc *RoomController[EntityID, RoomID, Entity, Room]) HasSeat(entityId EntityID) bool {
|
||||
return rc.GetSeat(entityId) != -1
|
||||
}
|
||||
|
||||
// GetSeatEntityCount 获取座位上的实体数量
|
||||
func (slf *RoomController[EntityID, RoomID, Entity, Room]) GetSeatEntityCount() int {
|
||||
slf.entitiesRWMutex.RLock()
|
||||
defer slf.entitiesRWMutex.RUnlock()
|
||||
func (rc *RoomController[EntityID, RoomID, Entity, Room]) GetSeatEntityCount() int {
|
||||
rc.entitiesRWMutex.RLock()
|
||||
defer rc.entitiesRWMutex.RUnlock()
|
||||
var count int
|
||||
for _, seat := range slf.seat {
|
||||
for _, seat := range rc.seat {
|
||||
if seat != nil {
|
||||
count++
|
||||
}
|
||||
|
@ -134,213 +134,219 @@ func (slf *RoomController[EntityID, RoomID, Entity, Room]) GetSeatEntityCount()
|
|||
}
|
||||
|
||||
// GetSeatEntities 获取座位上的实体
|
||||
func (slf *RoomController[EntityID, RoomID, Entity, Room]) GetSeatEntities() map[EntityID]Entity {
|
||||
slf.entitiesRWMutex.RLock()
|
||||
defer slf.entitiesRWMutex.RUnlock()
|
||||
func (rc *RoomController[EntityID, RoomID, Entity, Room]) GetSeatEntities() map[EntityID]Entity {
|
||||
rc.entitiesRWMutex.RLock()
|
||||
defer rc.entitiesRWMutex.RUnlock()
|
||||
var entities = make(map[EntityID]Entity)
|
||||
for _, entityId := range slf.seat {
|
||||
for _, entityId := range rc.seat {
|
||||
if entityId != nil {
|
||||
entities[*entityId] = slf.entities[*entityId]
|
||||
entities[*entityId] = rc.entities[*entityId]
|
||||
}
|
||||
}
|
||||
return entities
|
||||
}
|
||||
|
||||
// GetSeatEntitiesByOrdered 有序的获取座位上的实体
|
||||
func (slf *RoomController[EntityID, RoomID, Entity, Room]) GetSeatEntitiesByOrdered() []Entity {
|
||||
slf.entitiesRWMutex.RLock()
|
||||
defer slf.entitiesRWMutex.RUnlock()
|
||||
var entities = make([]Entity, 0, len(slf.seat))
|
||||
for _, entityId := range slf.seat {
|
||||
func (rc *RoomController[EntityID, RoomID, Entity, Room]) GetSeatEntitiesByOrdered() []Entity {
|
||||
rc.entitiesRWMutex.RLock()
|
||||
defer rc.entitiesRWMutex.RUnlock()
|
||||
var entities = make([]Entity, 0, len(rc.seat))
|
||||
for _, entityId := range rc.seat {
|
||||
if entityId != nil {
|
||||
entities = append(entities, slf.entities[*entityId])
|
||||
entities = append(entities, rc.entities[*entityId])
|
||||
}
|
||||
}
|
||||
return entities
|
||||
}
|
||||
|
||||
// GetSeatEntitiesByOrderedAndContainsEmpty 获取有序的座位上的实体,包含空座位
|
||||
func (slf *RoomController[EntityID, RoomID, Entity, Room]) GetSeatEntitiesByOrderedAndContainsEmpty() []Entity {
|
||||
slf.entitiesRWMutex.RLock()
|
||||
defer slf.entitiesRWMutex.RUnlock()
|
||||
var entities = make([]Entity, len(slf.seat))
|
||||
for i, entityId := range slf.seat {
|
||||
func (rc *RoomController[EntityID, RoomID, Entity, Room]) GetSeatEntitiesByOrderedAndContainsEmpty() []Entity {
|
||||
rc.entitiesRWMutex.RLock()
|
||||
defer rc.entitiesRWMutex.RUnlock()
|
||||
var entities = make([]Entity, len(rc.seat))
|
||||
for i, entityId := range rc.seat {
|
||||
if entityId != nil {
|
||||
entities[i] = slf.entities[*entityId]
|
||||
entities[i] = rc.entities[*entityId]
|
||||
}
|
||||
}
|
||||
return entities
|
||||
}
|
||||
|
||||
// GetSeatEntity 获取座位上的实体
|
||||
func (slf *RoomController[EntityID, RoomID, Entity, Room]) GetSeatEntity(seat int) (entity Entity) {
|
||||
slf.entitiesRWMutex.RLock()
|
||||
defer slf.entitiesRWMutex.RUnlock()
|
||||
if seat < len(slf.seat) {
|
||||
eid := slf.seat[seat]
|
||||
func (rc *RoomController[EntityID, RoomID, Entity, Room]) GetSeatEntity(seat int) (entity Entity) {
|
||||
rc.entitiesRWMutex.RLock()
|
||||
defer rc.entitiesRWMutex.RUnlock()
|
||||
if seat < len(rc.seat) {
|
||||
eid := rc.seat[seat]
|
||||
if eid != nil {
|
||||
return slf.entities[*eid]
|
||||
return rc.entities[*eid]
|
||||
}
|
||||
}
|
||||
return entity
|
||||
}
|
||||
|
||||
// ContainEntity 房间内是否包含实体
|
||||
func (slf *RoomController[EntityID, RoomID, Entity, Room]) ContainEntity(id EntityID) bool {
|
||||
slf.entitiesRWMutex.RLock()
|
||||
defer slf.entitiesRWMutex.RUnlock()
|
||||
_, exist := slf.entities[id]
|
||||
func (rc *RoomController[EntityID, RoomID, Entity, Room]) ContainEntity(id EntityID) bool {
|
||||
rc.entitiesRWMutex.RLock()
|
||||
defer rc.entitiesRWMutex.RUnlock()
|
||||
_, exist := rc.entities[id]
|
||||
return exist
|
||||
}
|
||||
|
||||
// GetRoom 获取原始房间实例
|
||||
func (slf *RoomController[EntityID, RoomID, Entity, Room]) GetRoom() Room {
|
||||
return slf.room
|
||||
// GetRoom 获取原始房间实例,该实例为被接管的房间的原始实例
|
||||
func (rc *RoomController[EntityID, RoomID, Entity, Room]) GetRoom() Room {
|
||||
return rc.room
|
||||
}
|
||||
|
||||
// GetEntities 获取所有实体
|
||||
func (slf *RoomController[EntityID, RoomID, Entity, Room]) GetEntities() map[EntityID]Entity {
|
||||
slf.entitiesRWMutex.RLock()
|
||||
defer slf.entitiesRWMutex.RUnlock()
|
||||
return hash.Copy(slf.entities)
|
||||
func (rc *RoomController[EntityID, RoomID, Entity, Room]) GetEntities() map[EntityID]Entity {
|
||||
rc.entitiesRWMutex.RLock()
|
||||
defer rc.entitiesRWMutex.RUnlock()
|
||||
return hash.Copy(rc.entities)
|
||||
}
|
||||
|
||||
// HasEntity 判断是否有实体
|
||||
func (slf *RoomController[EntityID, RoomID, Entity, Room]) HasEntity(id EntityID) bool {
|
||||
slf.entitiesRWMutex.RLock()
|
||||
defer slf.entitiesRWMutex.RUnlock()
|
||||
_, exist := slf.entities[id]
|
||||
func (rc *RoomController[EntityID, RoomID, Entity, Room]) HasEntity(id EntityID) bool {
|
||||
rc.entitiesRWMutex.RLock()
|
||||
defer rc.entitiesRWMutex.RUnlock()
|
||||
_, exist := rc.entities[id]
|
||||
return exist
|
||||
}
|
||||
|
||||
// GetEntity 获取实体
|
||||
func (slf *RoomController[EntityID, RoomID, Entity, Room]) GetEntity(id EntityID) Entity {
|
||||
slf.entitiesRWMutex.RLock()
|
||||
defer slf.entitiesRWMutex.RUnlock()
|
||||
return slf.entities[id]
|
||||
func (rc *RoomController[EntityID, RoomID, Entity, Room]) GetEntity(id EntityID) Entity {
|
||||
rc.entitiesRWMutex.RLock()
|
||||
defer rc.entitiesRWMutex.RUnlock()
|
||||
return rc.entities[id]
|
||||
}
|
||||
|
||||
// GetEntityIDs 获取所有实体ID
|
||||
func (slf *RoomController[EntityID, RoomID, Entity, Room]) GetEntityIDs() []EntityID {
|
||||
slf.entitiesRWMutex.RLock()
|
||||
defer slf.entitiesRWMutex.RUnlock()
|
||||
return hash.KeyToSlice(slf.entities)
|
||||
func (rc *RoomController[EntityID, RoomID, Entity, Room]) GetEntityIDs() []EntityID {
|
||||
rc.entitiesRWMutex.RLock()
|
||||
defer rc.entitiesRWMutex.RUnlock()
|
||||
return hash.KeyToSlice(rc.entities)
|
||||
}
|
||||
|
||||
// GetEntityCount 获取实体数量
|
||||
func (slf *RoomController[EntityID, RoomID, Entity, Room]) GetEntityCount() int {
|
||||
slf.entitiesRWMutex.RLock()
|
||||
defer slf.entitiesRWMutex.RUnlock()
|
||||
return len(slf.entities)
|
||||
func (rc *RoomController[EntityID, RoomID, Entity, Room]) GetEntityCount() int {
|
||||
rc.entitiesRWMutex.RLock()
|
||||
defer rc.entitiesRWMutex.RUnlock()
|
||||
return len(rc.entities)
|
||||
}
|
||||
|
||||
// ChangePassword 修改房间密码
|
||||
// - 当房间密码为 nil 时,将会取消密码
|
||||
func (slf *RoomController[EntityID, RoomID, Entity, Room]) ChangePassword(password *string) {
|
||||
old := slf.options.password
|
||||
slf.options.password = password
|
||||
slf.manager.OnRoomChangePasswordEvent(slf, old, slf.options.password)
|
||||
func (rc *RoomController[EntityID, RoomID, Entity, Room]) ChangePassword(password *string) {
|
||||
old := rc.options.password
|
||||
rc.options.password = password
|
||||
rc.manager.OnRoomChangePasswordEvent(rc, old, rc.options.password)
|
||||
}
|
||||
|
||||
// AddEntity 添加实体
|
||||
func (slf *RoomController[EntityID, RoomID, Entity, Room]) AddEntity(entity Entity) error {
|
||||
if slf.options.password != nil {
|
||||
// AddEntity 添加实体,如果房间存在密码,应使用 AddEntityByPassword 函数进行添加,否则将始终返回 ErrRoomPasswordNotMatch 错误
|
||||
// - 当房间已满时,将会返回 ErrRoomFull 错误
|
||||
func (rc *RoomController[EntityID, RoomID, Entity, Room]) AddEntity(entity Entity) error {
|
||||
if rc.options.password != nil {
|
||||
return ErrRoomPasswordNotMatch
|
||||
}
|
||||
slf.entitiesRWMutex.Lock()
|
||||
defer slf.entitiesRWMutex.Unlock()
|
||||
rc.entitiesRWMutex.Lock()
|
||||
defer rc.entitiesRWMutex.Unlock()
|
||||
|
||||
if slf.options.maxEntityCount != nil && len(slf.entities) > *slf.options.maxEntityCount {
|
||||
if rc.options.maxEntityCount != nil && len(rc.entities) > *rc.options.maxEntityCount {
|
||||
return ErrRoomFull
|
||||
}
|
||||
slf.entities[entity.GetId()] = entity
|
||||
rc.entities[entity.GetId()] = entity
|
||||
|
||||
slf.manager.OnRoomAddEntityEvent(slf, entity)
|
||||
rc.manager.OnRoomAddEntityEvent(rc, entity)
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddEntityByPassword 通过房间密码添加实体
|
||||
func (slf *RoomController[EntityID, RoomID, Entity, Room]) AddEntityByPassword(entity Entity, password string) error {
|
||||
if slf.options.password == nil || *slf.options.password != password {
|
||||
// AddEntityByPassword 通过房间密码添加实体到该房间中
|
||||
// - 当未设置房间密码时,password 参数将会被忽略
|
||||
// - 当房间密码不匹配时,将会返回 ErrRoomPasswordNotMatch 错误
|
||||
// - 当房间已满时,将会返回 ErrRoomFull 错误
|
||||
func (rc *RoomController[EntityID, RoomID, Entity, Room]) AddEntityByPassword(entity Entity, password string) error {
|
||||
if rc.options.password == nil || *rc.options.password != password {
|
||||
return ErrRoomPasswordNotMatch
|
||||
}
|
||||
slf.entitiesRWMutex.Lock()
|
||||
defer slf.entitiesRWMutex.Unlock()
|
||||
rc.entitiesRWMutex.Lock()
|
||||
defer rc.entitiesRWMutex.Unlock()
|
||||
|
||||
if slf.options.maxEntityCount != nil && len(slf.entities) > *slf.options.maxEntityCount {
|
||||
if rc.options.maxEntityCount != nil && len(rc.entities) > *rc.options.maxEntityCount {
|
||||
return ErrRoomFull
|
||||
}
|
||||
slf.entities[entity.GetId()] = entity
|
||||
rc.entities[entity.GetId()] = entity
|
||||
|
||||
slf.manager.OnRoomAddEntityEvent(slf, entity)
|
||||
rc.manager.OnRoomAddEntityEvent(rc, entity)
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemoveEntity 移除实体
|
||||
// - 当实体被移除时如果实体在座位上,将会自动离开座位
|
||||
func (slf *RoomController[EntityID, RoomID, Entity, Room]) RemoveEntity(id EntityID) {
|
||||
slf.entitiesRWMutex.RLock()
|
||||
defer slf.entitiesRWMutex.RUnlock()
|
||||
slf.removeEntity(id)
|
||||
func (rc *RoomController[EntityID, RoomID, Entity, Room]) RemoveEntity(id EntityID) {
|
||||
rc.entitiesRWMutex.RLock()
|
||||
defer rc.entitiesRWMutex.RUnlock()
|
||||
rc.removeEntity(id)
|
||||
}
|
||||
|
||||
// removeEntity 移除实体(无锁)
|
||||
func (slf *RoomController[EntityID, RoomID, Entity, Room]) removeEntity(id EntityID) {
|
||||
slf.leaveSeat(id)
|
||||
entity, exist := slf.entities[id]
|
||||
delete(slf.entities, id)
|
||||
func (rc *RoomController[EntityID, RoomID, Entity, Room]) removeEntity(id EntityID) {
|
||||
rc.leaveSeat(id)
|
||||
entity, exist := rc.entities[id]
|
||||
delete(rc.entities, id)
|
||||
if !exist {
|
||||
return
|
||||
}
|
||||
slf.manager.OnRoomRemoveEntityEvent(slf, entity)
|
||||
rc.manager.OnRoomRemoveEntityEvent(rc, entity)
|
||||
}
|
||||
|
||||
// RemoveAllEntities 移除所有实体
|
||||
func (slf *RoomController[EntityID, RoomID, Entity, Room]) RemoveAllEntities() {
|
||||
slf.entitiesRWMutex.Lock()
|
||||
defer slf.entitiesRWMutex.Unlock()
|
||||
for id := range slf.entities {
|
||||
slf.removeEntity(id)
|
||||
delete(slf.entities, id)
|
||||
// RemoveAllEntities 移除该房间中的所有实体
|
||||
// - 当实体被移除时如果实体在座位上,将会自动离开座位
|
||||
func (rc *RoomController[EntityID, RoomID, Entity, Room]) RemoveAllEntities() {
|
||||
rc.entitiesRWMutex.Lock()
|
||||
defer rc.entitiesRWMutex.Unlock()
|
||||
for id := range rc.entities {
|
||||
rc.removeEntity(id)
|
||||
delete(rc.entities, id)
|
||||
}
|
||||
}
|
||||
|
||||
// Destroy 销毁房间
|
||||
func (slf *RoomController[EntityID, RoomID, Entity, Room]) Destroy() {
|
||||
slf.manager.roomsRWMutex.Lock()
|
||||
defer slf.manager.roomsRWMutex.Unlock()
|
||||
// Destroy 销毁房间,房间会从 RoomManager 中移除,同时所有房间的实体、座位等数据都会被清空
|
||||
// - 该函数与 RoomManager.DestroyRoom 相同,RoomManager.DestroyRoom 函数为该函数的快捷方式
|
||||
func (rc *RoomController[EntityID, RoomID, Entity, Room]) Destroy() {
|
||||
rc.manager.roomsRWMutex.Lock()
|
||||
defer rc.manager.roomsRWMutex.Unlock()
|
||||
|
||||
delete(slf.manager.rooms, slf.room.GetId())
|
||||
slf.manager.OnRoomDestroyEvent(slf)
|
||||
delete(rc.manager.rooms, rc.room.GetId())
|
||||
rc.manager.OnRoomDestroyEvent(rc)
|
||||
|
||||
slf.entitiesRWMutex.Lock()
|
||||
defer slf.entitiesRWMutex.Unlock()
|
||||
rc.entitiesRWMutex.Lock()
|
||||
defer rc.entitiesRWMutex.Unlock()
|
||||
|
||||
for eid := range slf.entities {
|
||||
slf.removeEntity(eid)
|
||||
delete(slf.entities, eid)
|
||||
for eid := range rc.entities {
|
||||
rc.removeEntity(eid)
|
||||
delete(rc.entities, eid)
|
||||
}
|
||||
|
||||
slf.entities = make(map[EntityID]Entity)
|
||||
slf.seat = slf.seat[:]
|
||||
slf.vacancy = slf.vacancy[:]
|
||||
rc.entities = make(map[EntityID]Entity)
|
||||
rc.seat = rc.seat[:]
|
||||
rc.vacancy = rc.vacancy[:]
|
||||
}
|
||||
|
||||
// GetRoomManager 获取房间管理器
|
||||
func (slf *RoomController[EntityID, RoomID, Entity, Room]) GetRoomManager() *RoomManager[EntityID, RoomID, Entity, Room] {
|
||||
return slf.manager
|
||||
// GetRoomManager 获取该房间控制器所属的房间管理器
|
||||
func (rc *RoomController[EntityID, RoomID, Entity, Room]) GetRoomManager() *RoomManager[EntityID, RoomID, Entity, Room] {
|
||||
return rc.manager
|
||||
}
|
||||
|
||||
// GetRoomID 获取房间ID
|
||||
func (slf *RoomController[EntityID, RoomID, Entity, Room]) GetRoomID() RoomID {
|
||||
return slf.room.GetId()
|
||||
// GetRoomID 获取房间 ID
|
||||
func (rc *RoomController[EntityID, RoomID, Entity, Room]) GetRoomID() RoomID {
|
||||
return rc.room.GetId()
|
||||
}
|
||||
|
||||
// Broadcast 广播消息
|
||||
func (slf *RoomController[EntityID, RoomID, Entity, Room]) Broadcast(handler func(Entity), conditions ...func(Entity) bool) {
|
||||
slf.entitiesRWMutex.RLock()
|
||||
entities := hash.Copy(slf.entities)
|
||||
slf.entitiesRWMutex.RUnlock()
|
||||
// Broadcast 广播,该函数会将所有房间中满足 conditions 的对象传入 handler 中进行处理
|
||||
func (rc *RoomController[EntityID, RoomID, Entity, Room]) Broadcast(handler func(Entity), conditions ...func(Entity) bool) {
|
||||
rc.entitiesRWMutex.RLock()
|
||||
entities := hash.Copy(rc.entities)
|
||||
rc.entitiesRWMutex.RUnlock()
|
||||
for _, entity := range entities {
|
||||
for _, condition := range conditions {
|
||||
if !condition(entity) {
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"sync"
|
||||
)
|
||||
|
||||
// NewRoomManager 创建房间管理器
|
||||
// NewRoomManager 创建房间管理器 RoomManager 的实例
|
||||
func NewRoomManager[EntityID comparable, RoomID comparable, Entity generic.IdR[EntityID], Room generic.IdR[RoomID]]() *RoomManager[EntityID, RoomID, Entity, Room] {
|
||||
return &RoomManager[EntityID, RoomID, Entity, Room]{
|
||||
roomManagerEvents: new(roomManagerEvents[EntityID, RoomID, Entity, Room]),
|
||||
|
@ -14,64 +14,68 @@ func NewRoomManager[EntityID comparable, RoomID comparable, Entity generic.IdR[E
|
|||
}
|
||||
}
|
||||
|
||||
// RoomManager 房间管理器
|
||||
// RoomManager 房间管理器是用于对房间进行管理的基本单元,通过该实例可以对房间进行增删改查等操作
|
||||
// - 该实例是线程安全的
|
||||
type RoomManager[EntityID comparable, RoomID comparable, Entity generic.IdR[EntityID], Room generic.IdR[RoomID]] struct {
|
||||
*roomManagerEvents[EntityID, RoomID, Entity, Room]
|
||||
roomsRWMutex sync.RWMutex
|
||||
rooms map[RoomID]*RoomController[EntityID, RoomID, Entity, Room]
|
||||
}
|
||||
|
||||
// AssumeControl 将房间控制权交由 RoomManager 接管
|
||||
func (slf *RoomManager[EntityID, RoomID, Entity, Room]) AssumeControl(room Room, options ...*RoomControllerOptions) *RoomController[EntityID, RoomID, Entity, Room] {
|
||||
controller := newRoomController(slf, room, mergeRoomControllerOptions(options...))
|
||||
slf.OnRoomAssumeControlEvent(controller)
|
||||
// AssumeControl 将房间控制权交由 RoomManager 接管,返回 RoomController 实例
|
||||
// - 当任何房间需要被 RoomManager 管理时,都应该调用该方法获取到 RoomController 实例后进行操作
|
||||
// - 房间被接管后需要在释放房间控制权时调用 RoomController.Destroy 方法,否则将会导致 RoomManager 一直持有房间资源
|
||||
func (rm *RoomManager[EntityID, RoomID, Entity, Room]) AssumeControl(room Room, options ...*RoomControllerOptions) *RoomController[EntityID, RoomID, Entity, Room] {
|
||||
controller := newRoomController(rm, room, mergeRoomControllerOptions(options...))
|
||||
rm.OnRoomAssumeControlEvent(controller)
|
||||
return controller
|
||||
}
|
||||
|
||||
// DestroyRoom 销毁房间
|
||||
func (slf *RoomManager[EntityID, RoomID, Entity, Room]) DestroyRoom(id RoomID) {
|
||||
slf.roomsRWMutex.Lock()
|
||||
room, exist := slf.rooms[id]
|
||||
slf.roomsRWMutex.Unlock()
|
||||
// DestroyRoom 销毁房间,该函数为 RoomController.Destroy 的快捷方式
|
||||
func (rm *RoomManager[EntityID, RoomID, Entity, Room]) DestroyRoom(id RoomID) {
|
||||
rm.roomsRWMutex.Lock()
|
||||
room, exist := rm.rooms[id]
|
||||
rm.roomsRWMutex.Unlock()
|
||||
if !exist {
|
||||
return
|
||||
}
|
||||
room.Destroy()
|
||||
}
|
||||
|
||||
// GetRoom 获取房间
|
||||
func (slf *RoomManager[EntityID, RoomID, Entity, Room]) GetRoom(id RoomID) *RoomController[EntityID, RoomID, Entity, Room] {
|
||||
slf.roomsRWMutex.RLock()
|
||||
defer slf.roomsRWMutex.RUnlock()
|
||||
return slf.rooms[id]
|
||||
// GetRoom 通过房间 ID 获取对应房间的控制器 RoomController,当房间不存在时将返回 nil
|
||||
func (rm *RoomManager[EntityID, RoomID, Entity, Room]) GetRoom(id RoomID) *RoomController[EntityID, RoomID, Entity, Room] {
|
||||
rm.roomsRWMutex.RLock()
|
||||
defer rm.roomsRWMutex.RUnlock()
|
||||
return rm.rooms[id]
|
||||
}
|
||||
|
||||
// GetRooms 获取所有房间
|
||||
func (slf *RoomManager[EntityID, RoomID, Entity, Room]) GetRooms() map[RoomID]*RoomController[EntityID, RoomID, Entity, Room] {
|
||||
slf.roomsRWMutex.RLock()
|
||||
defer slf.roomsRWMutex.RUnlock()
|
||||
return hash.Copy(slf.rooms)
|
||||
// GetRooms 获取包含所有房间 ID 到对应控制器 RoomController 的映射
|
||||
// - 返回值的 map 为拷贝对象,可安全的对其进行增删等操作
|
||||
func (rm *RoomManager[EntityID, RoomID, Entity, Room]) GetRooms() map[RoomID]*RoomController[EntityID, RoomID, Entity, Room] {
|
||||
rm.roomsRWMutex.RLock()
|
||||
defer rm.roomsRWMutex.RUnlock()
|
||||
return hash.Copy(rm.rooms)
|
||||
}
|
||||
|
||||
// GetRoomCount 获取房间数量
|
||||
func (slf *RoomManager[EntityID, RoomID, Entity, Room]) GetRoomCount() int {
|
||||
slf.roomsRWMutex.RLock()
|
||||
defer slf.roomsRWMutex.RUnlock()
|
||||
return len(slf.rooms)
|
||||
// GetRoomCount 获取房间管理器接管的房间数量
|
||||
func (rm *RoomManager[EntityID, RoomID, Entity, Room]) GetRoomCount() int {
|
||||
rm.roomsRWMutex.RLock()
|
||||
defer rm.roomsRWMutex.RUnlock()
|
||||
return len(rm.rooms)
|
||||
}
|
||||
|
||||
// GetRoomIDs 获取所有房间ID
|
||||
func (slf *RoomManager[EntityID, RoomID, Entity, Room]) GetRoomIDs() []RoomID {
|
||||
slf.roomsRWMutex.RLock()
|
||||
defer slf.roomsRWMutex.RUnlock()
|
||||
return hash.KeyToSlice(slf.rooms)
|
||||
// GetRoomIDs 获取房间管理器接管的所有房间 ID
|
||||
func (rm *RoomManager[EntityID, RoomID, Entity, Room]) GetRoomIDs() []RoomID {
|
||||
rm.roomsRWMutex.RLock()
|
||||
defer rm.roomsRWMutex.RUnlock()
|
||||
return hash.KeyToSlice(rm.rooms)
|
||||
}
|
||||
|
||||
// HasEntity 判断特定对象是否在任一房间中
|
||||
func (slf *RoomManager[EntityID, RoomID, Entity, Room]) HasEntity(entityId EntityID) bool {
|
||||
slf.roomsRWMutex.RLock()
|
||||
rooms := hash.Copy(slf.rooms)
|
||||
slf.roomsRWMutex.RUnlock()
|
||||
// HasEntity 判断特定对象是否在任一房间中,当对象不在任一房间中时将返回 false
|
||||
func (rm *RoomManager[EntityID, RoomID, Entity, Room]) HasEntity(entityId EntityID) bool {
|
||||
rm.roomsRWMutex.RLock()
|
||||
rooms := hash.Copy(rm.rooms)
|
||||
rm.roomsRWMutex.RUnlock()
|
||||
for _, room := range rooms {
|
||||
if room.HasEntity(entityId) {
|
||||
return true
|
||||
|
@ -80,11 +84,12 @@ func (slf *RoomManager[EntityID, RoomID, Entity, Room]) HasEntity(entityId Entit
|
|||
return false
|
||||
}
|
||||
|
||||
// GetEntityRooms 获取特定对象所在的房间
|
||||
func (slf *RoomManager[EntityID, RoomID, Entity, Room]) GetEntityRooms(entityId EntityID) map[RoomID]*RoomController[EntityID, RoomID, Entity, Room] {
|
||||
slf.roomsRWMutex.RLock()
|
||||
rooms := hash.Copy(slf.rooms)
|
||||
slf.roomsRWMutex.RUnlock()
|
||||
// GetEntityRooms 获取特定对象所在的房间,返回值为房间 ID 到对应控制器 RoomController 的映射
|
||||
// - 由于一个对象可能在多个房间中,因此返回值为 map 类型
|
||||
func (rm *RoomManager[EntityID, RoomID, Entity, Room]) GetEntityRooms(entityId EntityID) map[RoomID]*RoomController[EntityID, RoomID, Entity, Room] {
|
||||
rm.roomsRWMutex.RLock()
|
||||
rooms := hash.Copy(rm.rooms)
|
||||
rm.roomsRWMutex.RUnlock()
|
||||
var result = make(map[RoomID]*RoomController[EntityID, RoomID, Entity, Room])
|
||||
for id, room := range rooms {
|
||||
if room.HasEntity(entityId) {
|
||||
|
@ -94,11 +99,11 @@ func (slf *RoomManager[EntityID, RoomID, Entity, Room]) GetEntityRooms(entityId
|
|||
return result
|
||||
}
|
||||
|
||||
// Broadcast 向所有房间对象广播消息
|
||||
func (slf *RoomManager[EntityID, RoomID, Entity, Room]) Broadcast(handler func(Entity), conditions ...func(Entity) bool) {
|
||||
slf.roomsRWMutex.RLock()
|
||||
rooms := hash.Copy(slf.rooms)
|
||||
slf.roomsRWMutex.RUnlock()
|
||||
// Broadcast 向所有房间对象广播消息,该方法将会遍历所有房间控制器并调用 RoomController.Broadcast 方法
|
||||
func (rm *RoomManager[EntityID, RoomID, Entity, Room]) Broadcast(handler func(Entity), conditions ...func(Entity) bool) {
|
||||
rm.roomsRWMutex.RLock()
|
||||
rooms := hash.Copy(rm.rooms)
|
||||
rm.roomsRWMutex.RUnlock()
|
||||
for _, room := range rooms {
|
||||
room.Broadcast(handler, conditions...)
|
||||
}
|
||||
|
|
|
@ -19,61 +19,61 @@ type roomManagerEvents[EntityID comparable, RoomID comparable, Entity generic.Id
|
|||
}
|
||||
|
||||
// RegRoomAssumeControlEvent 注册房间接管事件
|
||||
func (slf *roomManagerEvents[EntityID, RoomID, Entity, Room]) RegRoomAssumeControlEvent(handle RoomAssumeControlEventHandle[EntityID, RoomID, Entity, Room]) {
|
||||
slf.roomAssumeControlEventHandles = append(slf.roomAssumeControlEventHandles, handle)
|
||||
func (rme *roomManagerEvents[EntityID, RoomID, Entity, Room]) RegRoomAssumeControlEvent(handle RoomAssumeControlEventHandle[EntityID, RoomID, Entity, Room]) {
|
||||
rme.roomAssumeControlEventHandles = append(rme.roomAssumeControlEventHandles, handle)
|
||||
}
|
||||
|
||||
// OnRoomAssumeControlEvent 房间接管事件
|
||||
func (slf *roomManagerEvents[EntityID, RoomID, Entity, Room]) OnRoomAssumeControlEvent(controller *RoomController[EntityID, RoomID, Entity, Room]) {
|
||||
for _, handle := range slf.roomAssumeControlEventHandles {
|
||||
func (rme *roomManagerEvents[EntityID, RoomID, Entity, Room]) OnRoomAssumeControlEvent(controller *RoomController[EntityID, RoomID, Entity, Room]) {
|
||||
for _, handle := range rme.roomAssumeControlEventHandles {
|
||||
handle(controller)
|
||||
}
|
||||
}
|
||||
|
||||
// RegRoomDestroyEvent 注册房间销毁事件
|
||||
func (slf *roomManagerEvents[EntityID, RoomID, Entity, Room]) RegRoomDestroyEvent(handle RoomDestroyEventHandle[EntityID, RoomID, Entity, Room]) {
|
||||
slf.roomDestroyEventHandles = append(slf.roomDestroyEventHandles, handle)
|
||||
func (rme *roomManagerEvents[EntityID, RoomID, Entity, Room]) RegRoomDestroyEvent(handle RoomDestroyEventHandle[EntityID, RoomID, Entity, Room]) {
|
||||
rme.roomDestroyEventHandles = append(rme.roomDestroyEventHandles, handle)
|
||||
}
|
||||
|
||||
// OnRoomDestroyEvent 房间销毁事件
|
||||
func (slf *roomManagerEvents[EntityID, RoomID, Entity, Room]) OnRoomDestroyEvent(controller *RoomController[EntityID, RoomID, Entity, Room]) {
|
||||
for _, handle := range slf.roomDestroyEventHandles {
|
||||
func (rme *roomManagerEvents[EntityID, RoomID, Entity, Room]) OnRoomDestroyEvent(controller *RoomController[EntityID, RoomID, Entity, Room]) {
|
||||
for _, handle := range rme.roomDestroyEventHandles {
|
||||
handle(controller)
|
||||
}
|
||||
}
|
||||
|
||||
// RegRoomAddEntityEvent 注册房间添加对象事件
|
||||
func (slf *roomManagerEvents[EntityID, RoomID, Entity, Room]) RegRoomAddEntityEvent(handle RoomAddEntityEventHandle[EntityID, RoomID, Entity, Room]) {
|
||||
slf.roomAddEntityEventHandles = append(slf.roomAddEntityEventHandles, handle)
|
||||
func (rme *roomManagerEvents[EntityID, RoomID, Entity, Room]) RegRoomAddEntityEvent(handle RoomAddEntityEventHandle[EntityID, RoomID, Entity, Room]) {
|
||||
rme.roomAddEntityEventHandles = append(rme.roomAddEntityEventHandles, handle)
|
||||
}
|
||||
|
||||
// OnRoomAddEntityEvent 房间添加对象事件
|
||||
func (slf *roomManagerEvents[EntityID, RoomID, Entity, Room]) OnRoomAddEntityEvent(controller *RoomController[EntityID, RoomID, Entity, Room], entity Entity) {
|
||||
for _, handle := range slf.roomAddEntityEventHandles {
|
||||
func (rme *roomManagerEvents[EntityID, RoomID, Entity, Room]) OnRoomAddEntityEvent(controller *RoomController[EntityID, RoomID, Entity, Room], entity Entity) {
|
||||
for _, handle := range rme.roomAddEntityEventHandles {
|
||||
handle(controller, entity)
|
||||
}
|
||||
}
|
||||
|
||||
// RegRoomRemoveEntityEvent 注册房间移除对象事件
|
||||
func (slf *roomManagerEvents[EntityID, RoomID, Entity, Room]) RegRoomRemoveEntityEvent(handle RoomRemoveEntityEventHandle[EntityID, RoomID, Entity, Room]) {
|
||||
slf.roomRemoveEntityEventHandles = append(slf.roomRemoveEntityEventHandles, handle)
|
||||
func (rme *roomManagerEvents[EntityID, RoomID, Entity, Room]) RegRoomRemoveEntityEvent(handle RoomRemoveEntityEventHandle[EntityID, RoomID, Entity, Room]) {
|
||||
rme.roomRemoveEntityEventHandles = append(rme.roomRemoveEntityEventHandles, handle)
|
||||
}
|
||||
|
||||
// OnRoomRemoveEntityEvent 房间移除对象事件
|
||||
func (slf *roomManagerEvents[EntityID, RoomID, Entity, Room]) OnRoomRemoveEntityEvent(controller *RoomController[EntityID, RoomID, Entity, Room], entity Entity) {
|
||||
for _, handle := range slf.roomRemoveEntityEventHandles {
|
||||
func (rme *roomManagerEvents[EntityID, RoomID, Entity, Room]) OnRoomRemoveEntityEvent(controller *RoomController[EntityID, RoomID, Entity, Room], entity Entity) {
|
||||
for _, handle := range rme.roomRemoveEntityEventHandles {
|
||||
handle(controller, entity)
|
||||
}
|
||||
}
|
||||
|
||||
// RegRoomChangePasswordEvent 注册房间修改密码事件
|
||||
func (slf *roomManagerEvents[EntityID, RoomID, Entity, Room]) RegRoomChangePasswordEvent(handle RoomChangePasswordEventHandle[EntityID, RoomID, Entity, Room]) {
|
||||
slf.roomChangePasswordEventHandles = append(slf.roomChangePasswordEventHandles, handle)
|
||||
func (rme *roomManagerEvents[EntityID, RoomID, Entity, Room]) RegRoomChangePasswordEvent(handle RoomChangePasswordEventHandle[EntityID, RoomID, Entity, Room]) {
|
||||
rme.roomChangePasswordEventHandles = append(rme.roomChangePasswordEventHandles, handle)
|
||||
}
|
||||
|
||||
// OnRoomChangePasswordEvent 房间修改密码事件
|
||||
func (slf *roomManagerEvents[EntityID, RoomID, Entity, Room]) OnRoomChangePasswordEvent(controller *RoomController[EntityID, RoomID, Entity, Room], oldPassword, password *string) {
|
||||
for _, handle := range slf.roomChangePasswordEventHandles {
|
||||
func (rme *roomManagerEvents[EntityID, RoomID, Entity, Room]) OnRoomChangePasswordEvent(controller *RoomController[EntityID, RoomID, Entity, Room], oldPassword, password *string) {
|
||||
for _, handle := range rme.roomChangePasswordEventHandles {
|
||||
handle(controller, oldPassword, password)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
package space_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/kercylan98/minotaur/game/space"
|
||||
)
|
||||
|
||||
type Room struct {
|
||||
Id int64
|
||||
}
|
||||
|
||||
func (r *Room) GetId() int64 {
|
||||
return r.Id
|
||||
}
|
||||
|
||||
type Player struct {
|
||||
Id string
|
||||
}
|
||||
|
||||
func (p *Player) GetId() string {
|
||||
return p.Id
|
||||
}
|
||||
|
||||
func ExampleNewRoomManager() {
|
||||
var rm = space.NewRoomManager[string, int64, *Player, *Room]()
|
||||
fmt.Println(rm == nil)
|
||||
|
||||
// Output:
|
||||
// false
|
||||
}
|
||||
|
||||
func ExampleRoomManager_AssumeControl() {
|
||||
var rm = space.NewRoomManager[string, int64, *Player, *Room]()
|
||||
var room = &Room{Id: 1}
|
||||
var controller = rm.AssumeControl(room)
|
||||
|
||||
if err := controller.AddEntity(&Player{Id: "1"}); err != nil {
|
||||
// 房间密码不匹配或者房间已满
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Println(controller.GetEntityCount())
|
||||
|
||||
// Output:
|
||||
// 1
|
||||
}
|
|
@ -22,17 +22,17 @@ type RoomControllerOptions struct {
|
|||
}
|
||||
|
||||
// WithMaxEntityCount 设置房间最大实体数量
|
||||
func (slf *RoomControllerOptions) WithMaxEntityCount(maxEntityCount int) *RoomControllerOptions {
|
||||
func (rco *RoomControllerOptions) WithMaxEntityCount(maxEntityCount int) *RoomControllerOptions {
|
||||
if maxEntityCount > 0 {
|
||||
slf.maxEntityCount = &maxEntityCount
|
||||
rco.maxEntityCount = &maxEntityCount
|
||||
}
|
||||
return slf
|
||||
return rco
|
||||
}
|
||||
|
||||
// WithPassword 设置房间密码
|
||||
func (slf *RoomControllerOptions) WithPassword(password string) *RoomControllerOptions {
|
||||
func (rco *RoomControllerOptions) WithPassword(password string) *RoomControllerOptions {
|
||||
if password != "" {
|
||||
slf.password = &password
|
||||
rco.password = &password
|
||||
}
|
||||
return slf
|
||||
return rco
|
||||
}
|
||||
|
|
|
@ -15,23 +15,25 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
type StartBeforeEventHandler func(srv *Server)
|
||||
type StartFinishEventHandler func(srv *Server)
|
||||
type StopEventHandler func(srv *Server)
|
||||
type ConnectionReceivePacketEventHandler func(srv *Server, conn *Conn, packet []byte)
|
||||
type ConnectionOpenedEventHandler func(srv *Server, conn *Conn)
|
||||
type ConnectionClosedEventHandler func(srv *Server, conn *Conn, err any)
|
||||
type MessageErrorEventHandler func(srv *Server, message *Message, err error)
|
||||
type MessageLowExecEventHandler func(srv *Server, message *Message, cost time.Duration)
|
||||
type ConsoleCommandEventHandler func(srv *Server, command string, params ConsoleParams)
|
||||
type ConnectionOpenedAfterEventHandler func(srv *Server, conn *Conn)
|
||||
type ConnectionWritePacketBeforeEventHandler func(srv *Server, conn *Conn, packet []byte) []byte
|
||||
type ShuntChannelCreatedEventHandler func(srv *Server, guid int64)
|
||||
type ShuntChannelClosedEventHandler func(srv *Server, guid int64)
|
||||
type ConnectionPacketPreprocessEventHandler func(srv *Server, conn *Conn, packet []byte, abort func(), usePacket func(newPacket []byte))
|
||||
type MessageExecBeforeEventHandler func(srv *Server, message *Message) bool
|
||||
type MessageReadyEventHandler func(srv *Server)
|
||||
type OnDeadlockDetectEventHandler func(srv *Server, message *Message)
|
||||
type (
|
||||
StartBeforeEventHandler func(srv *Server)
|
||||
StartFinishEventHandler func(srv *Server)
|
||||
StopEventHandler func(srv *Server)
|
||||
ConnectionReceivePacketEventHandler func(srv *Server, conn *Conn, packet []byte)
|
||||
ConnectionOpenedEventHandler func(srv *Server, conn *Conn)
|
||||
ConnectionClosedEventHandler func(srv *Server, conn *Conn, err any)
|
||||
MessageErrorEventHandler func(srv *Server, message *Message, err error)
|
||||
MessageLowExecEventHandler func(srv *Server, message *Message, cost time.Duration)
|
||||
ConsoleCommandEventHandler func(srv *Server, command string, params ConsoleParams)
|
||||
ConnectionOpenedAfterEventHandler func(srv *Server, conn *Conn)
|
||||
ConnectionWritePacketBeforeEventHandler func(srv *Server, conn *Conn, packet []byte) []byte
|
||||
ShuntChannelCreatedEventHandler func(srv *Server, guid int64)
|
||||
ShuntChannelClosedEventHandler func(srv *Server, guid int64)
|
||||
ConnectionPacketPreprocessEventHandler func(srv *Server, conn *Conn, packet []byte, abort func(), usePacket func(newPacket []byte))
|
||||
MessageExecBeforeEventHandler func(srv *Server, message *Message) bool
|
||||
MessageReadyEventHandler func(srv *Server)
|
||||
OnDeadlockDetectEventHandler func(srv *Server, message *Message)
|
||||
)
|
||||
|
||||
func newEvent(srv *Server) *event {
|
||||
return &event{
|
||||
|
@ -51,7 +53,7 @@ func newEvent(srv *Server) *event {
|
|||
connectionPacketPreprocessEventHandlers: slice.NewPriority[ConnectionPacketPreprocessEventHandler](),
|
||||
messageExecBeforeEventHandlers: slice.NewPriority[MessageExecBeforeEventHandler](),
|
||||
messageReadyEventHandlers: slice.NewPriority[MessageReadyEventHandler](),
|
||||
dedeadlockDetectEventHandlers: slice.NewPriority[OnDeadlockDetectEventHandler](),
|
||||
deadlockDetectEventHandlers: slice.NewPriority[OnDeadlockDetectEventHandler](),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -72,7 +74,7 @@ type event struct {
|
|||
connectionPacketPreprocessEventHandlers *slice.Priority[ConnectionPacketPreprocessEventHandler]
|
||||
messageExecBeforeEventHandlers *slice.Priority[MessageExecBeforeEventHandler]
|
||||
messageReadyEventHandlers *slice.Priority[MessageReadyEventHandler]
|
||||
dedeadlockDetectEventHandlers *slice.Priority[OnDeadlockDetectEventHandler]
|
||||
deadlockDetectEventHandlers *slice.Priority[OnDeadlockDetectEventHandler]
|
||||
|
||||
consoleCommandEventHandlers map[string]*slice.Priority[ConsoleCommandEventHandler]
|
||||
consoleCommandEventHandlerInitOnce sync.Once
|
||||
|
@ -440,11 +442,11 @@ func (slf *event) OnMessageReadyEvent() {
|
|||
|
||||
// RegDeadlockDetectEvent 在死锁检测触发时立即执行被注册的事件处理函数
|
||||
func (slf *event) RegDeadlockDetectEvent(handler OnDeadlockDetectEventHandler, priority ...int) {
|
||||
slf.dedeadlockDetectEventHandlers.Append(handler, slice.GetValue(priority, 0))
|
||||
slf.deadlockDetectEventHandlers.Append(handler, slice.GetValue(priority, 0))
|
||||
}
|
||||
|
||||
func (slf *event) OnDeadlockDetectEvent(message *Message) {
|
||||
if slf.dedeadlockDetectEventHandlers.Len() == 0 {
|
||||
if slf.deadlockDetectEventHandlers.Len() == 0 {
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
|
@ -453,7 +455,7 @@ func (slf *event) OnDeadlockDetectEvent(message *Message) {
|
|||
debug.PrintStack()
|
||||
}
|
||||
}()
|
||||
slf.dedeadlockDetectEventHandlers.RangeValue(func(index int, value OnDeadlockDetectEventHandler) bool {
|
||||
slf.deadlockDetectEventHandlers.RangeValue(func(index int, value OnDeadlockDetectEventHandler) bool {
|
||||
value(slf.Server, message)
|
||||
return true
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue