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