package q5 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 freeTimerList ListHead runningTimer *TimerList timerTick int64 getTickCount func (interface{}) int64 getFixedTimerExpires func (interface{}, int32, int32, int64) int64 context interface{} 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 (interface{}) int64, getFixedTimerExpires func (interface{}, int32, int32, int64) int64, context interface{}, gcTime int32, cacheTimerNum int32) { initListHeadFunc := func (data interface{}) { head := data.(*ListHead) head.Init() } initListHeadFunc(&this.freeTimerList) TraverseArray(&this.tv1, initListHeadFunc) TraverseArray(&this.tv2, initListHeadFunc) TraverseArray(&this.tv3, initListHeadFunc) TraverseArray(&this.tv4, initListHeadFunc) TraverseArray(&this.tv5, initListHeadFunc) this.timerTick = getTickCount(context) this.context = context this.getTickCount = getTickCount this.getFixedTimerExpires = getFixedTimerExpires this.cacheTimerNum = cacheTimerNum this.AddRepeatTimer( gcTime, func (params *XParams) { }, this.gcTimerFunc) } func (this *Timer) UnInit() { this.clear() } func (this *Timer) clear() { freeTimerFunc := func (data interface{}) { head := data.(*ListHead) for !head.Empty() { timerList := head.FirstEntry().(*TimerList) this.detachTimer(timerList) if !timerList.attachEntry.Empty() { timerList.attachEntry.DelInit() } } } freeTimerFunc(&this.freeTimerList) TraverseArray(&this.tv1, freeTimerFunc) TraverseArray(&this.tv2, freeTimerFunc) TraverseArray(&this.tv3, freeTimerFunc) TraverseArray(&this.tv4, freeTimerFunc) TraverseArray(&this.tv5, freeTimerFunc) } func (this *Timer) Update() { for this.getTickCount(this.context) >= 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++ 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++ } 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(this.context) timerList.expires = this.getFixedTimerExpires( this.context, timerList.fixedTimierExecuteTimes, milliSeconds, tick) } else { timerList.expires = this.getTickCount(this.context) + 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.freeTimerList.AddTail(&timerList.entry) this.freeTimerNum++ } 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.freeTimerList.Empty() { timerList := this.freeTimerList.FirstEntry().(*TimerList) timerList.entry.DelInit() this.freeTimerNum-- return timerList } else { timerList := new(TimerList) timerList.entry.Init() return timerList } } func (this *Timer) gcTimerFunc(params *XParams) { for i := 0; !this.freeTimerList.Empty() && this.freeTimerNum > this.cacheTimerNum && i < 1000; i++ { timerList := this.freeTimerList.FirstEntry().(*TimerList) timerList.entry.DelInit() this.freeTimerNum-- } }