排名改变事件优化、增加排行榜清理前事件
This commit is contained in:
parent
4e75282d01
commit
4cf4e7a83e
|
@ -7,7 +7,7 @@ import (
|
||||||
"github.com/kercylan98/minotaur/utils/synchronization"
|
"github.com/kercylan98/minotaur/utils/synchronization"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewRankingList 创建一个排行榜
|
// NewRankingList 创建一个排名从0开始的排行榜
|
||||||
func NewRankingList[CompetitorID comparable, Score generic.Ordered](options ...RankingListOption[CompetitorID, Score]) *RankingList[CompetitorID, Score] {
|
func NewRankingList[CompetitorID comparable, Score generic.Ordered](options ...RankingListOption[CompetitorID, Score]) *RankingList[CompetitorID, Score] {
|
||||||
rankingList := &RankingList[CompetitorID, Score]{
|
rankingList := &RankingList[CompetitorID, Score]{
|
||||||
rankCount: 100,
|
rankCount: 100,
|
||||||
|
@ -25,7 +25,8 @@ type RankingList[CompetitorID comparable, Score generic.Ordered] struct {
|
||||||
competitors *synchronization.Map[CompetitorID, Score]
|
competitors *synchronization.Map[CompetitorID, Score]
|
||||||
scores []*scoreItem[CompetitorID, Score] // CompetitorID, Score
|
scores []*scoreItem[CompetitorID, Score] // CompetitorID, Score
|
||||||
|
|
||||||
rankChangeEventHandles []game.RankChangeEventHandle[CompetitorID, Score]
|
rankChangeEventHandles []game.RankChangeEventHandle[CompetitorID, Score]
|
||||||
|
rankClearBeforeEventHandles []game.RankClearBeforeEventHandle[CompetitorID, Score]
|
||||||
}
|
}
|
||||||
|
|
||||||
type scoreItem[CompetitorID comparable, Score generic.Ordered] struct {
|
type scoreItem[CompetitorID comparable, Score generic.Ordered] struct {
|
||||||
|
@ -46,16 +47,9 @@ func (slf *RankingList[CompetitorID, Score]) Competitor(competitorId CompetitorI
|
||||||
slf.scores = append(slf.scores[0:rank], slf.scores[rank+1:]...)
|
slf.scores = append(slf.scores[0:rank], slf.scores[rank+1:]...)
|
||||||
slf.competitors.Delete(competitorId)
|
slf.competitors.Delete(competitorId)
|
||||||
if slf.Cmp(score, v) > 0 {
|
if slf.Cmp(score, v) > 0 {
|
||||||
slf.competitor(competitorId, score, 0, rank-1)
|
slf.competitor(competitorId, v, rank, score, 0, rank-1)
|
||||||
} else {
|
} else {
|
||||||
slf.competitor(competitorId, score, rank, len(slf.scores)-1)
|
slf.competitor(competitorId, v, rank, score, rank, len(slf.scores)-1)
|
||||||
}
|
|
||||||
if len(slf.rankChangeEventHandles) > 0 {
|
|
||||||
newRank, err := slf.GetRank(competitorId)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
slf.OnRankChangeEvent(competitorId, rank, newRank, v, score)
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if slf.rankCount > 0 && len(slf.scores) >= slf.rankCount {
|
if slf.rankCount > 0 && len(slf.scores) >= slf.rankCount {
|
||||||
|
@ -64,14 +58,7 @@ func (slf *RankingList[CompetitorID, Score]) Competitor(competitorId CompetitorI
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
slf.competitor(competitorId, score, 0, len(slf.scores)-1)
|
slf.competitor(competitorId, v, -1, score, 0, len(slf.scores)-1)
|
||||||
if len(slf.rankChangeEventHandles) > 0 {
|
|
||||||
newRank, err := slf.GetRank(competitorId)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
slf.OnRankChangeEvent(competitorId, newRank, newRank, score, score)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,8 +80,11 @@ func (slf *RankingList[CompetitorID, Score]) RemoveCompetitor(competitorId Compe
|
||||||
slf.competitors.Delete(competitorId)
|
slf.competitors.Delete(competitorId)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
oldScore := slf.scores[rank].Score
|
||||||
|
slf.OnRankChangeEvent(competitorId, rank, -1, oldScore, oldScore)
|
||||||
slf.scores = append(slf.scores[0:rank], slf.scores[rank+1:]...)
|
slf.scores = append(slf.scores[0:rank], slf.scores[rank+1:]...)
|
||||||
slf.competitors.Delete(competitorId)
|
slf.competitors.Delete(competitorId)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (slf *RankingList[CompetitorID, Score]) Size() int {
|
func (slf *RankingList[CompetitorID, Score]) Size() int {
|
||||||
|
@ -178,6 +168,7 @@ func (slf *RankingList[CompetitorID, Score]) GetAllCompetitor() []CompetitorID {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (slf *RankingList[CompetitorID, Score]) Clear() {
|
func (slf *RankingList[CompetitorID, Score]) Clear() {
|
||||||
|
slf.OnRankClearBeforeEvent()
|
||||||
slf.competitors.Clear()
|
slf.competitors.Clear()
|
||||||
slf.scores = make([]*scoreItem[CompetitorID, Score], 0)
|
slf.scores = make([]*scoreItem[CompetitorID, Score], 0)
|
||||||
}
|
}
|
||||||
|
@ -198,7 +189,7 @@ func (slf *RankingList[CompetitorID, Score]) Cmp(s1, s2 Score) int {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (slf *RankingList[CompetitorID, Score]) competitor(competitorId CompetitorID, score Score, low, high int) {
|
func (slf *RankingList[CompetitorID, Score]) competitor(competitorId CompetitorID, oldScore Score, oldRank int, score Score, low, high int) {
|
||||||
for low <= high {
|
for low <= high {
|
||||||
mid := (low + high) / 2
|
mid := (low + high) / 2
|
||||||
data := slf.scores[mid]
|
data := slf.scores[mid]
|
||||||
|
@ -223,12 +214,12 @@ func (slf *RankingList[CompetitorID, Score]) competitor(competitorId CompetitorI
|
||||||
|
|
||||||
slf.scores = append(slf.scores, &scoreItem[CompetitorID, Score]{CompetitorId: competitorId, Score: score})
|
slf.scores = append(slf.scores, &scoreItem[CompetitorID, Score]{CompetitorId: competitorId, Score: score})
|
||||||
slf.competitors.Set(competitorId, score)
|
slf.competitors.Set(competitorId, score)
|
||||||
|
slf.OnRankChangeEvent(competitorId, oldRank, len(slf.scores)-1, oldScore, score)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
si := &scoreItem[CompetitorID, Score]{competitorId, score}
|
si := &scoreItem[CompetitorID, Score]{competitorId, score}
|
||||||
|
|
||||||
//队首
|
|
||||||
if low == 0 {
|
if low == 0 {
|
||||||
slf.scores = append([]*scoreItem[CompetitorID, Score]{si}, slf.scores...)
|
slf.scores = append([]*scoreItem[CompetitorID, Score]{si}, slf.scores...)
|
||||||
} else {
|
} else {
|
||||||
|
@ -236,12 +227,14 @@ func (slf *RankingList[CompetitorID, Score]) competitor(competitorId CompetitorI
|
||||||
slf.scores = append(slf.scores[0:low], tmp...)
|
slf.scores = append(slf.scores[0:low], tmp...)
|
||||||
}
|
}
|
||||||
slf.competitors.Set(competitorId, score)
|
slf.competitors.Set(competitorId, score)
|
||||||
|
slf.OnRankChangeEvent(competitorId, oldRank, low, oldScore, score)
|
||||||
if slf.rankCount <= 0 || len(slf.scores) <= slf.rankCount {
|
if slf.rankCount <= 0 || len(slf.scores) <= slf.rankCount {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
count = len(slf.scores) - 1
|
count = len(slf.scores) - 1
|
||||||
si = slf.scores[count]
|
si = slf.scores[count]
|
||||||
|
slf.OnRankChangeEvent(si.CompetitorId, count, -1, si.Score, si.Score)
|
||||||
slf.competitors.Delete(si.CompetitorId)
|
slf.competitors.Delete(si.CompetitorId)
|
||||||
slf.scores = slf.scores[0:count]
|
slf.scores = slf.scores[0:count]
|
||||||
}
|
}
|
||||||
|
@ -281,6 +274,16 @@ func (slf *RankingList[CompetitorID, Score]) RegRankChangeEvent(handle game.Rank
|
||||||
|
|
||||||
func (slf *RankingList[CompetitorID, Score]) OnRankChangeEvent(competitorId CompetitorID, oldRank, newRank int, oldScore, newScore Score) {
|
func (slf *RankingList[CompetitorID, Score]) OnRankChangeEvent(competitorId CompetitorID, oldRank, newRank int, oldScore, newScore Score) {
|
||||||
for _, handle := range slf.rankChangeEventHandles {
|
for _, handle := range slf.rankChangeEventHandles {
|
||||||
handle(competitorId, oldRank, newRank, oldScore, newScore)
|
handle(slf, competitorId, oldRank, newRank, oldScore, newScore)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slf *RankingList[CompetitorID, Score]) RegRankClearBeforeEvent(handle game.RankClearBeforeEventHandle[CompetitorID, Score]) {
|
||||||
|
slf.rankClearBeforeEventHandles = append(slf.rankClearBeforeEventHandles, handle)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slf *RankingList[CompetitorID, Score]) OnRankClearBeforeEvent() {
|
||||||
|
for _, handle := range slf.rankClearBeforeEventHandles {
|
||||||
|
handle(slf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,11 +29,15 @@ type RankingList[CompetitorID comparable, Score generic.Ordered] interface {
|
||||||
Clear()
|
Clear()
|
||||||
|
|
||||||
// RegRankChangeEvent 排名改变时将立即执行注册的事件处理函数
|
// RegRankChangeEvent 排名改变时将立即执行注册的事件处理函数
|
||||||
// - 当竞争者为新加入时,oldRank 和 oldScore 均与 newRank 和 newScore 相同
|
// - 排名为-1时表示未上榜
|
||||||
RegRankChangeEvent(handle RankChangeEventHandle[CompetitorID, Score])
|
RegRankChangeEvent(handle RankChangeEventHandle[CompetitorID, Score])
|
||||||
OnRankChangeEvent(competitorId CompetitorID, oldRank, newRank int, oldScore, newScore Score)
|
OnRankChangeEvent(competitorId CompetitorID, oldRank, newRank int, oldScore, newScore Score)
|
||||||
|
// RegRankClearBeforeEvent 在排行榜被清空前执行被注册的事件处理函数
|
||||||
|
RegRankClearBeforeEvent(handle RankClearBeforeEventHandle[CompetitorID, Score])
|
||||||
|
OnRankClearBeforeEvent()
|
||||||
}
|
}
|
||||||
|
|
||||||
type (
|
type (
|
||||||
RankChangeEventHandle[CompetitorID comparable, Score generic.Ordered] func(competitorId CompetitorID, oldRank, newRank int, oldScore, newScore Score)
|
RankChangeEventHandle[CompetitorID comparable, Score generic.Ordered] func(rankingList RankingList[CompetitorID, Score], competitorId CompetitorID, oldRank, newRank int, oldScore, newScore Score)
|
||||||
|
RankClearBeforeEventHandle[CompetitorID comparable, Score generic.Ordered] func(rankingList RankingList[CompetitorID, Score])
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue