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