159 lines
5.9 KiB
Go
159 lines
5.9 KiB
Go
package activity
|
|
|
|
import (
|
|
"github.com/kercylan98/minotaur/utils/generic"
|
|
"reflect"
|
|
"sync"
|
|
)
|
|
|
|
type none byte
|
|
|
|
// DefineNoneDataActivity 声明无数据的活动类型
|
|
func DefineNoneDataActivity[Type, ID generic.Basic](activityType Type) NoneDataActivityController[Type, ID, *none, none, *none] {
|
|
return regController(&Controller[Type, ID, *none, none, *none]{
|
|
t: activityType,
|
|
})
|
|
}
|
|
|
|
// DefineGlobalDataActivity 声明拥有全局数据的活动类型
|
|
func DefineGlobalDataActivity[Type, ID generic.Basic, Data any](activityType Type) GlobalDataActivityController[Type, ID, Data, none, *none] {
|
|
return regController(&Controller[Type, ID, Data, none, *none]{
|
|
t: activityType,
|
|
})
|
|
}
|
|
|
|
// DefineEntityDataActivity 声明拥有实体数据的活动类型
|
|
func DefineEntityDataActivity[Type, ID, EntityID generic.Basic, EntityData any](activityType Type) EntityDataActivityController[Type, ID, *none, EntityID, EntityData] {
|
|
return regController(&Controller[Type, ID, *none, EntityID, EntityData]{
|
|
t: activityType,
|
|
})
|
|
}
|
|
|
|
// DefineGlobalAndEntityDataActivity 声明拥有全局数据和实体数据的活动类型
|
|
func DefineGlobalAndEntityDataActivity[Type, ID generic.Basic, Data any, EntityID generic.Basic, EntityData any](activityType Type) GlobalAndEntityDataActivityController[Type, ID, Data, EntityID, EntityData] {
|
|
return regController(&Controller[Type, ID, Data, EntityID, EntityData]{
|
|
t: activityType,
|
|
})
|
|
}
|
|
|
|
// Controller 活动控制器
|
|
type Controller[Type, ID generic.Basic, Data any, EntityID generic.Basic, EntityData any] struct {
|
|
t Type // 活动类型
|
|
activities map[ID]*Activity[Type, ID] // 活动列表
|
|
globalData map[ID]*DataMeta[Data] // 全局数据
|
|
entityData map[ID]map[EntityID]*EntityDataMeta[EntityData] // 实体数据
|
|
entityTof reflect.Type // 实体数据类型
|
|
globalInit func(activityId ID, data *DataMeta[Data]) // 全局数据初始化函数
|
|
entityInit func(activityId ID, entityId EntityID, data *EntityDataMeta[EntityData]) // 实体数据初始化函数
|
|
mutex sync.RWMutex
|
|
}
|
|
|
|
// GetGlobalData 获取特定活动全局数据
|
|
func (slf *Controller[Type, ID, Data, EntityID, EntityData]) GetGlobalData(activityId ID) Data {
|
|
slf.mutex.RLock()
|
|
defer slf.mutex.RUnlock()
|
|
global := slf.globalData[activityId]
|
|
if slf.globalInit != nil {
|
|
global.once.Do(func() {
|
|
slf.globalInit(activityId, global)
|
|
})
|
|
}
|
|
return global.Data
|
|
}
|
|
|
|
// GetEntityData 获取特定活动实体数据
|
|
func (slf *Controller[Type, ID, Data, EntityID, EntityData]) GetEntityData(activityId ID, entityId EntityID) EntityData {
|
|
slf.mutex.RLock()
|
|
defer slf.mutex.RUnlock()
|
|
entities, exist := slf.entityData[activityId]
|
|
if !exist {
|
|
entities = make(map[EntityID]*EntityDataMeta[EntityData])
|
|
slf.entityData[activityId] = entities
|
|
}
|
|
entity, exist := entities[entityId]
|
|
if !exist {
|
|
entity = &EntityDataMeta[EntityData]{
|
|
Data: reflect.New(slf.entityTof).Interface().(EntityData),
|
|
}
|
|
entities[entityId] = entity
|
|
}
|
|
if slf.entityInit != nil {
|
|
entity.once.Do(func() {
|
|
slf.entityInit(activityId, entityId, entity)
|
|
})
|
|
}
|
|
return entity.Data
|
|
}
|
|
|
|
// IsOpen 活动是否开启
|
|
func (slf *Controller[Type, ID, Data, EntityID, EntityData]) IsOpen(activityId ID) bool {
|
|
slf.mutex.RLock()
|
|
activity, exist := slf.activities[activityId]
|
|
slf.mutex.RUnlock()
|
|
if !exist {
|
|
return false
|
|
}
|
|
activity.mutex.RLock()
|
|
defer activity.mutex.RUnlock()
|
|
return activity.state == stateStarted
|
|
}
|
|
|
|
// IsShow 活动是否展示
|
|
func (slf *Controller[Type, ID, Data, EntityID, EntityData]) IsShow(activityId ID) bool {
|
|
slf.mutex.RLock()
|
|
activity, exist := slf.activities[activityId]
|
|
slf.mutex.RUnlock()
|
|
if !exist {
|
|
return false
|
|
}
|
|
activity.mutex.RLock()
|
|
defer activity.mutex.RUnlock()
|
|
return activity.state == stateUpcoming || (activity.state == stateEnded && activity.options.Tl.HasState(stateExtendedShowEnded))
|
|
}
|
|
|
|
// IsOpenOrShow 活动是否开启或展示
|
|
func (slf *Controller[Type, ID, Data, EntityID, EntityData]) IsOpenOrShow(activityId ID) bool {
|
|
slf.mutex.RLock()
|
|
activity, exist := slf.activities[activityId]
|
|
slf.mutex.RUnlock()
|
|
if !exist {
|
|
return false
|
|
}
|
|
|
|
activity.mutex.RLock()
|
|
defer activity.mutex.RUnlock()
|
|
return activity.state == stateStarted || activity.state == stateUpcoming || (activity.state == stateEnded && activity.options.Tl.HasState(stateExtendedShowEnded))
|
|
}
|
|
|
|
// Refresh 刷新活动
|
|
func (slf *Controller[Type, ID, Data, EntityID, EntityData]) Refresh(activityId ID) {
|
|
slf.mutex.RLock()
|
|
activity, exist := slf.activities[activityId]
|
|
slf.mutex.RUnlock()
|
|
if !exist {
|
|
return
|
|
}
|
|
activity.refresh()
|
|
}
|
|
|
|
func (slf *Controller[Type, ID, Data, EntityID, EntityData]) InitializeNoneData(handler func(activityId ID, data *DataMeta[Data])) NoneDataActivityController[Type, ID, Data, EntityID, EntityData] {
|
|
slf.globalInit = handler
|
|
return slf
|
|
}
|
|
|
|
func (slf *Controller[Type, ID, Data, EntityID, EntityData]) InitializeGlobalData(handler func(activityId ID, data *DataMeta[Data])) GlobalDataActivityController[Type, ID, Data, EntityID, EntityData] {
|
|
slf.globalInit = handler
|
|
return slf
|
|
}
|
|
|
|
func (slf *Controller[Type, ID, Data, EntityID, EntityData]) InitializeEntityData(handler func(activityId ID, entityId EntityID, data *EntityDataMeta[EntityData])) EntityDataActivityController[Type, ID, Data, EntityID, EntityData] {
|
|
slf.entityInit = handler
|
|
return slf
|
|
}
|
|
|
|
func (slf *Controller[Type, ID, Data, EntityID, EntityData]) InitializeGlobalAndEntityData(handler func(activityId ID, data *DataMeta[Data]), entityHandler func(activityId ID, entityId EntityID, data *EntityDataMeta[EntityData])) GlobalAndEntityDataActivityController[Type, ID, Data, EntityID, EntityData] {
|
|
slf.globalInit = handler
|
|
slf.entityInit = entityHandler
|
|
return slf
|
|
}
|