feat: fight.TurnBased 支持监听回合变更以及刷新当前操作回合超时时间
This commit is contained in:
parent
378f855992
commit
ba2f3af398
|
@ -8,9 +8,14 @@ import (
|
|||
|
||||
const (
|
||||
signalFinish = 1 + iota // 操作结束信号
|
||||
signalStop // 停止回合制信号
|
||||
signalRefresh // 刷新操作超时时间信号
|
||||
)
|
||||
|
||||
type signal struct {
|
||||
sign byte
|
||||
data any
|
||||
}
|
||||
|
||||
// NewTurnBased 创建一个新的回合制
|
||||
// - calcNextTurnDuration 将返回下一次行动时间间隔,适用于按照速度计算下一次行动时间间隔的情况。当返回 0 时,将使用默认的行动超时时间
|
||||
func NewTurnBased[CampID, EntityID comparable, Camp generic.IdR[CampID], Entity generic.IdR[EntityID]](calcNextTurnDuration func(Camp, Entity) time.Duration) *TurnBased[CampID, EntityID, Camp, Entity] {
|
||||
|
@ -39,7 +44,7 @@ type TurnBased[CampID, EntityID comparable, Camp generic.IdR[CampID], Entity gen
|
|||
calcNextTurnDuration func(Camp, Entity) time.Duration // 下一次行动时间间隔
|
||||
actionTimeoutHandler func(Camp, Entity) time.Duration // 行动超时时间
|
||||
|
||||
signal chan byte // 信号
|
||||
signal chan signal // 信号
|
||||
round int // 当前回合数
|
||||
currCamp Camp // 当前操作阵营
|
||||
currEntity Entity // 当前操作实体
|
||||
|
@ -77,7 +82,7 @@ func (slf *TurnBased[CampID, EntityID, Camp, Entity]) SetActionTimeout(actionTim
|
|||
// Run 运行
|
||||
func (slf *TurnBased[CampID, EntityID, Camp, Entity]) Run() {
|
||||
slf.round = 1
|
||||
slf.signal = make(chan byte, 1)
|
||||
slf.signal = make(chan signal, 1)
|
||||
var actionDuration = make(map[EntityID]time.Duration)
|
||||
var actionSubmit = func() {
|
||||
slf.actionMutex.Lock()
|
||||
|
@ -141,24 +146,34 @@ func (slf *TurnBased[CampID, EntityID, Camp, Entity]) Run() {
|
|||
}
|
||||
breakListen:
|
||||
for {
|
||||
wait:
|
||||
select {
|
||||
case <-slf.actionWaitTicker.C:
|
||||
actionSubmit()
|
||||
slf.OnTurnBasedEntityActionTimeoutEvent(slf.controller)
|
||||
break breakListen
|
||||
case sign := <-slf.signal:
|
||||
switch sign {
|
||||
switch sign.sign {
|
||||
case signalFinish:
|
||||
actionSubmit()
|
||||
slf.OnTurnBasedEntityActionFinishEvent(slf.controller)
|
||||
break breakListen
|
||||
case signalRefresh:
|
||||
slf.actionWaitTicker.Reset(sign.data.(time.Duration))
|
||||
goto wait
|
||||
}
|
||||
}
|
||||
}
|
||||
slf.OnTurnBasedEntityActionSubmitEvent(slf.controller)
|
||||
if len(actionDuration) == 0 {
|
||||
slf.round++
|
||||
}
|
||||
|
||||
slf.closeMutex.Lock()
|
||||
if slf.closed {
|
||||
if len(actionDuration) == 0 {
|
||||
slf.round--
|
||||
}
|
||||
if slf.ticker != nil {
|
||||
slf.ticker.Stop()
|
||||
slf.ticker = nil
|
||||
|
@ -173,12 +188,10 @@ func (slf *TurnBased[CampID, EntityID, Camp, Entity]) Run() {
|
|||
}
|
||||
slf.closeMutex.Unlock()
|
||||
break
|
||||
} else if len(actionDuration) == 0 {
|
||||
slf.OnTurnBasedRoundChangeEvent(slf.controller)
|
||||
}
|
||||
slf.closeMutex.Unlock()
|
||||
|
||||
if len(actionDuration) == 0 {
|
||||
slf.round++
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,8 @@ type TurnBasedControllerAction[CampID, EntityID comparable, Camp generic.IdR[Cam
|
|||
TurnBasedControllerInfo[CampID, EntityID, Camp, Entity]
|
||||
// Finish 结束当前操作,将立即切换到下一个操作实体
|
||||
Finish()
|
||||
// Refresh 刷新当前操作实体的行动超时时间并返回新的行动超时时间
|
||||
Refresh(duration time.Duration) time.Time
|
||||
}
|
||||
|
||||
// TurnBasedController 回合制控制器
|
||||
|
@ -69,7 +71,7 @@ func (slf *TurnBasedController[CampID, EntityID, Camp, Entity]) Finish() {
|
|||
defer slf.tb.actionMutex.Unlock()
|
||||
if slf.tb.actioning {
|
||||
slf.tb.actioning = false
|
||||
slf.tb.signal <- signalFinish
|
||||
slf.tb.signal <- signal{sign: signalFinish}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,3 +79,16 @@ func (slf *TurnBasedController[CampID, EntityID, Camp, Entity]) Finish() {
|
|||
func (slf *TurnBasedController[CampID, EntityID, Camp, Entity]) Stop() {
|
||||
slf.tb.Close()
|
||||
}
|
||||
|
||||
// Refresh 刷新当前操作实体的行动超时时间
|
||||
// - 当不在行动阶段时,将返回 time.Time 零值
|
||||
func (slf *TurnBasedController[CampID, EntityID, Camp, Entity]) Refresh(duration time.Duration) time.Time {
|
||||
slf.tb.actionMutex.Lock()
|
||||
defer slf.tb.actionMutex.Unlock()
|
||||
if slf.tb.actioning {
|
||||
slf.tb.actioning = false
|
||||
slf.tb.signal <- signal{sign: signalRefresh, data: duration}
|
||||
return time.Now().Add(duration)
|
||||
}
|
||||
return time.Time{}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ type (
|
|||
TurnBasedEntityActionTimeoutEventHandler[CampID, EntityID comparable, Camp generic.IdR[CampID], Entity generic.IdR[EntityID]] func(controller TurnBasedControllerInfo[CampID, EntityID, Camp, Entity])
|
||||
TurnBasedEntityActionFinishEventHandler[CampID, EntityID comparable, Camp generic.IdR[CampID], Entity generic.IdR[EntityID]] func(controller TurnBasedControllerInfo[CampID, EntityID, Camp, Entity])
|
||||
TurnBasedEntityActionSubmitEventHandler[CampID, EntityID comparable, Camp generic.IdR[CampID], Entity generic.IdR[EntityID]] func(controller TurnBasedControllerInfo[CampID, EntityID, Camp, Entity])
|
||||
TurnBasedRoundChangeEventHandler[CampID, EntityID comparable, Camp generic.IdR[CampID], Entity generic.IdR[EntityID]] func(controller TurnBasedControllerInfo[CampID, EntityID, Camp, Entity])
|
||||
)
|
||||
|
||||
type turnBasedEvents[CampID, EntityID comparable, Camp generic.IdR[CampID], Entity generic.IdR[EntityID]] struct {
|
||||
|
@ -14,6 +15,7 @@ type turnBasedEvents[CampID, EntityID comparable, Camp generic.IdR[CampID], Enti
|
|||
actionTimeoutEventHandlers []TurnBasedEntityActionTimeoutEventHandler[CampID, EntityID, Camp, Entity]
|
||||
actionFinishEventHandlers []TurnBasedEntityActionFinishEventHandler[CampID, EntityID, Camp, Entity]
|
||||
actionSubmitEventHandlers []TurnBasedEntityActionSubmitEventHandler[CampID, EntityID, Camp, Entity]
|
||||
roundChangeEventHandlers []TurnBasedRoundChangeEventHandler[CampID, EntityID, Camp, Entity]
|
||||
}
|
||||
|
||||
// RegTurnBasedEntitySwitchEvent 注册回合制实体切换事件处理函数,该处理函数将在切换到实体切换为操作时机时触发
|
||||
|
@ -70,3 +72,15 @@ func (slf *turnBasedEvents[CampID, EntityID, Camp, Entity]) OnTurnBasedEntityAct
|
|||
handler(controller)
|
||||
}
|
||||
}
|
||||
|
||||
// RegTurnBasedRoundChangeEvent 注册回合制回合变更事件处理函数,该处理函数将在回合变更时触发
|
||||
func (slf *turnBasedEvents[CampID, EntityID, Camp, Entity]) RegTurnBasedRoundChangeEvent(handler TurnBasedRoundChangeEventHandler[CampID, EntityID, Camp, Entity]) {
|
||||
slf.roundChangeEventHandlers = append(slf.roundChangeEventHandlers, handler)
|
||||
}
|
||||
|
||||
// OnTurnBasedRoundChangeEvent 触发回合制回合变更事件
|
||||
func (slf *turnBasedEvents[CampID, EntityID, Camp, Entity]) OnTurnBasedRoundChangeEvent(controller TurnBasedControllerInfo[CampID, EntityID, Camp, Entity]) {
|
||||
for _, handler := range slf.roundChangeEventHandlers {
|
||||
handler(controller)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,10 @@ func TestTurnBased_Run(t *testing.T) {
|
|||
t.Log("时间", time.Now().Unix(), "回合", controller.GetRound(), "阵营", controller.GetCamp().GetId(), "实体", controller.GetEntity().GetId(), "超时")
|
||||
})
|
||||
|
||||
tbi.RegTurnBasedRoundChangeEvent(func(controller fight.TurnBasedControllerInfo[string, string, *Camp, *Entity]) {
|
||||
t.Log("时间", time.Now().Unix(), "回合", controller.GetRound(), "回合切换")
|
||||
})
|
||||
|
||||
tbi.RegTurnBasedEntitySwitchEvent(func(controller fight.TurnBasedControllerAction[string, string, *Camp, *Entity]) {
|
||||
switch controller.GetEntity().GetId() {
|
||||
case "1":
|
||||
|
@ -44,6 +48,8 @@ func TestTurnBased_Run(t *testing.T) {
|
|||
controller.Finish()
|
||||
}()
|
||||
case "2":
|
||||
controller.Refresh(time.Second)
|
||||
case "4":
|
||||
controller.Stop()
|
||||
}
|
||||
t.Log("时间", time.Now().Unix(), "回合", controller.GetRound(), "阵营", controller.GetCamp().GetId(), "实体", controller.GetEntity().GetId(), "开始行动")
|
||||
|
|
Loading…
Reference in New Issue