329 lines
8.3 KiB
Go
329 lines
8.3 KiB
Go
package q5
|
|
|
|
import "time"
|
|
|
|
const CONFIG_BASE_SMALL = false
|
|
const TVN_BITS = 6
|
|
const TVR_BITS = 8
|
|
const TVN_SIZE = 1 << TVN_BITS
|
|
const TVR_SIZE = 1 << TVR_BITS
|
|
const TVN_MASK = TVN_SIZE - 1
|
|
const TVR_MASK = TVR_SIZE - 1
|
|
|
|
const (
|
|
DEADLINE_TIMER = 0
|
|
REPEAT_TIMER = iota
|
|
FIXED_TIMER = iota
|
|
)
|
|
|
|
type Timer struct {
|
|
freeTimerNum int32
|
|
freeTimer ListHead
|
|
runningTimer *TimerList
|
|
timerTick int64
|
|
getTickCount func () int64
|
|
context interface{}
|
|
gcTime int32
|
|
cacheTimerNum int32
|
|
tv1 [TVR_SIZE]ListHead
|
|
tv2 [TVN_SIZE]ListHead
|
|
tv3 [TVN_SIZE]ListHead
|
|
tv4 [TVN_SIZE]ListHead
|
|
tv5 [TVN_SIZE]ListHead
|
|
}
|
|
|
|
func (this *Timer) Init(
|
|
getTickCount func () int64,
|
|
context interface{},
|
|
gcTime int32,
|
|
cacheTimerNum int32) {
|
|
this.freeTimer.Init()
|
|
for i := 0; i < TVN_SIZE; i += 1 {
|
|
this.tv2[i].Init()
|
|
this.tv3[i].Init()
|
|
this.tv4[i].Init()
|
|
this.tv5[i].Init()
|
|
}
|
|
for i := 0; i < TVR_SIZE; i += 1 {
|
|
this.tv1[i].Init()
|
|
}
|
|
|
|
this.timerTick = getTickCount()
|
|
this.context = context
|
|
this.getTickCount = getTickCount
|
|
this.gcTime = gcTime
|
|
this.cacheTimerNum = cacheTimerNum
|
|
this.AddRepeatTimer(
|
|
this.gcTime,
|
|
func (params *XParams) {
|
|
|
|
},
|
|
this.gcTimerFunc)
|
|
}
|
|
|
|
func (this *Timer) UnInit() {
|
|
this.clear()
|
|
}
|
|
|
|
func (this *Timer) clear() {
|
|
freeTimers := func (head *ListHead) {
|
|
for !head.Empty() {
|
|
timerList := head.FirstEntry().(*TimerList)
|
|
this.detachTimer(timerList)
|
|
if !timerList.attachEntry.Empty() {
|
|
timerList.attachEntry.DelInit()
|
|
}
|
|
}
|
|
}
|
|
for i := 0; i < TVN_SIZE; i += 1 {
|
|
freeTimers(&this.tv2[i])
|
|
freeTimers(&this.tv3[i])
|
|
freeTimers(&this.tv4[i])
|
|
freeTimers(&this.tv5[i])
|
|
}
|
|
for i := 0; i < TVR_SIZE; i += 1 {
|
|
freeTimers(&this.tv1[i])
|
|
}
|
|
freeTimers(&this.freeTimer)
|
|
}
|
|
|
|
func (this *Timer) Update() {
|
|
for this.getTickCount() >= this.timerTick {
|
|
index := uint32(this.timerTick & TVR_MASK)
|
|
|
|
if index != 0 &&
|
|
this.cascade(&this.tv2, this.getTimerIndex(0)) != 0 &&
|
|
this.cascade(&this.tv3, this.getTimerIndex(1)) != 0 &&
|
|
this.cascade(&this.tv4, this.getTimerIndex(2)) != 0 {
|
|
this.cascade(&this.tv5, this.getTimerIndex(3))
|
|
}
|
|
this.timerTick += 1
|
|
|
|
var workList ListHead
|
|
this.tv1[index].ReplaceInit(&workList)
|
|
for !workList.Empty() {
|
|
timer_list := workList.FirstEntry().(*TimerList)
|
|
this.runningTimer = timer_list
|
|
if timer_list.timerFunc != nil {
|
|
timer_list.timerFunc(&timer_list.params)
|
|
}
|
|
if timer_list.timerAfterFunc != nil {
|
|
timer_list.timerAfterFunc(&timer_list.params)
|
|
}
|
|
if this.runningTimer != nil {
|
|
switch this.runningTimer.timerType {
|
|
case REPEAT_TIMER, FIXED_TIMER:
|
|
if timer_list.timerType == FIXED_TIMER {
|
|
timer_list.fixedTimierExecuteTimes += 1
|
|
}
|
|
this.ModifyTimer(timer_list, timer_list.milliSeconds)
|
|
case DEADLINE_TIMER:
|
|
this.detachTimer(timer_list)
|
|
if timer_list.attachEntry.Empty() {
|
|
timer_list.attachEntry.DelInit()
|
|
}
|
|
this.addToFreeList(timer_list)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
this.runningTimer = nil
|
|
}
|
|
|
|
func (this *Timer) AddDeadLineTimer(
|
|
milli_seconds int32,
|
|
init_func func (params* XParams),
|
|
timer_func func (params* XParams)) *TimerList {
|
|
return this.AddDeadLineTimerEx(milli_seconds, init_func, timer_func, nil)
|
|
}
|
|
|
|
func (this *Timer) AddDeadLineTimerEx(
|
|
milli_seconds int32,
|
|
init_func func (params* XParams),
|
|
timer_func func (params* XParams),
|
|
install_func func (timerList *TimerList, params* XParams)) *TimerList {
|
|
timerList := this.newTimerList()
|
|
timerList.params.Reset()
|
|
if init_func != nil {
|
|
init_func(&timerList.params)
|
|
}
|
|
timerList.InitTimerList(this, DEADLINE_TIMER, milli_seconds, timer_func)
|
|
if install_func != nil {
|
|
install_func(timerList, &timerList.params)
|
|
}
|
|
this.ModifyTimer(timerList, milli_seconds)
|
|
return timerList
|
|
}
|
|
|
|
func (this *Timer) AddRepeatTimer(
|
|
milli_seconds int32,
|
|
init_func func (params* XParams),
|
|
timer_func func (params* XParams)) *TimerList {
|
|
return this.AddRepeatTimerEx(milli_seconds, init_func, timer_func, nil)
|
|
}
|
|
|
|
func (this *Timer) AddRepeatTimerEx(
|
|
milli_seconds int32,
|
|
init_func func (params* XParams),
|
|
timer_func func (params* XParams),
|
|
install_func func (timer_list *TimerList, params* XParams)) *TimerList {
|
|
timerList := this.newTimerList()
|
|
if init_func != nil {
|
|
init_func(&timerList.params)
|
|
}
|
|
timerList.InitTimerList(this, REPEAT_TIMER, milli_seconds, timer_func)
|
|
if install_func != nil {
|
|
install_func(timerList, &timerList.params)
|
|
}
|
|
this.ModifyTimer(timerList, milli_seconds)
|
|
return timerList
|
|
}
|
|
|
|
func (this *Timer) AddFixedTimer(
|
|
milli_seconds int32,
|
|
init_func func (params* XParams),
|
|
timer_func func (params* XParams)) *TimerList {
|
|
return this.AddFixedTimerEx(milli_seconds, init_func, timer_func, nil)
|
|
}
|
|
|
|
func (this *Timer) AddFixedTimerEx(
|
|
milli_seconds int32,
|
|
init_func func (params* XParams),
|
|
timer_func func (params* XParams),
|
|
install_func func (timer_list *TimerList, params* XParams)) *TimerList {
|
|
timerList := this.newTimerList()
|
|
if init_func != nil {
|
|
init_func(&timerList.params)
|
|
}
|
|
timerList.InitTimerList(this, FIXED_TIMER, milli_seconds, timer_func)
|
|
if install_func != nil {
|
|
install_func(timerList, &timerList.params)
|
|
}
|
|
this.ModifyTimer(timerList, milli_seconds)
|
|
return timerList
|
|
}
|
|
|
|
func (this *Timer) ModifyTimer(timerList *TimerList, milliSeconds int32) {
|
|
this.detachTimer(timerList)
|
|
timerList.milliSeconds = milliSeconds
|
|
if timerList.timerType == FIXED_TIMER {
|
|
tick := this.getTickCount()
|
|
nowTime := time.Now().Unix()
|
|
todayPassedSeconds := nowTime - GetDaySeconds(nowTime)
|
|
timerList.expires = (tick - todayPassedSeconds * 1000) + int64(milliSeconds)
|
|
if timerList.fixedTimierExecuteTimes > 0 {
|
|
if timerList.expires <= tick {
|
|
timerList.expires += 1000 * 3600 * 24
|
|
}
|
|
}
|
|
} else {
|
|
timerList.expires = this.getTickCount() + int64(milliSeconds)
|
|
}
|
|
this.internalAddTimer(timerList)
|
|
}
|
|
|
|
func (this *Timer) DeleteTimer(timerList *TimerList) {
|
|
}
|
|
|
|
func (this *Timer) GetTimerByAtttach(attachEntry *ListHead) *TimerList {
|
|
return nil
|
|
}
|
|
|
|
func (this *Timer) MutableParams(timerList *TimerList) *XParams {
|
|
return nil
|
|
}
|
|
|
|
func (this *Timer) GetRemainTime(timerList *TimerList) int64 {
|
|
return 0
|
|
}
|
|
|
|
func (this *Timer) GetRunningTimer() *TimerList {
|
|
return nil
|
|
}
|
|
|
|
func (this *Timer) GetIdleMilliSeconds() int64 {
|
|
return 0
|
|
}
|
|
|
|
func (this *Timer) detachTimer(timerList *TimerList) {
|
|
if !timerList.entry.Empty() {
|
|
timerList.entry.DelInit()
|
|
}
|
|
}
|
|
|
|
func (this *Timer) addToFreeList(timerList *TimerList) {
|
|
this.freeTimer.AddTail(&timerList.entry)
|
|
this.freeTimerNum += 1
|
|
}
|
|
|
|
func (this *Timer) cascade(tv *[TVN_SIZE]ListHead, index uint32) uint32 {
|
|
var cascadeList ListHead
|
|
tv[index].ReplaceInit(&cascadeList)
|
|
|
|
if !cascadeList.Empty() {
|
|
pos := cascadeList.next
|
|
next := pos.next
|
|
for pos != &cascadeList {
|
|
this.internalAddTimer(pos.data.(*TimerList))
|
|
pos = next
|
|
next = pos.next
|
|
}
|
|
}
|
|
cascadeList.Init()
|
|
return index
|
|
}
|
|
|
|
func (this *Timer) internalAddTimer(timer_list *TimerList) {
|
|
timer_list.entry.data = timer_list
|
|
expires := timer_list.expires
|
|
idx := expires - this.timerTick
|
|
var vec *ListHead
|
|
var index uint32
|
|
|
|
if idx < 0 {
|
|
index = (uint32)(this.timerTick & TVR_MASK)
|
|
vec = &this.tv1[index]
|
|
} else if idx < TVR_SIZE {
|
|
index = (uint32)(expires & TVR_MASK)
|
|
vec = &this.tv1[index]
|
|
} else if idx < (1 << (TVR_BITS + TVN_BITS)) {
|
|
index = (uint32)((expires >> TVR_BITS) & TVN_MASK)
|
|
vec = &this.tv2[index]
|
|
} else if idx < (1 << (TVR_BITS + 2 * TVN_BITS)) {
|
|
index = (uint32)((expires >> (TVR_BITS + 1 * TVN_BITS)) & TVN_MASK)
|
|
vec = &this.tv3[index]
|
|
} else if idx < (1 << (TVR_BITS + 3 * TVN_BITS)) {
|
|
index = (uint32)((expires >> (TVR_BITS + 2 * TVN_BITS)) & TVN_MASK)
|
|
vec = &this.tv4[index]
|
|
} else {
|
|
index = (uint32)((expires >> (TVR_BITS + 3 * TVN_BITS)) & TVN_MASK)
|
|
vec = &this.tv5[index]
|
|
}
|
|
vec.AddTail(&timer_list.entry)
|
|
}
|
|
|
|
func (this *Timer) getTimerIndex(index uint32) uint32 {
|
|
return (uint32)((this.timerTick >> (TVR_BITS + index * TVN_BITS)) & TVN_MASK);
|
|
}
|
|
|
|
func (this *Timer) newTimerList() *TimerList {
|
|
if !this.freeTimer.Empty() {
|
|
timerList := this.freeTimer.FirstEntry().(*TimerList)
|
|
timerList.entry.DelInit()
|
|
this.freeTimerNum -= 1
|
|
return timerList
|
|
} else {
|
|
timerList := new(TimerList)
|
|
timerList.entry.Init()
|
|
return timerList
|
|
}
|
|
}
|
|
|
|
func (this *Timer) gcTimerFunc(params *XParams) {
|
|
for i := 0; !this.freeTimer.Empty() && this.freeTimerNum > this.cacheTimerNum && i < 1000; i += 1 {
|
|
timerList := this.freeTimer.FirstEntry().(*TimerList)
|
|
timerList.entry.DelInit()
|
|
this.freeTimerNum -= 1
|
|
}
|
|
}
|