gitee.com/KyleChenSource/lib-robot@v1.0.2/robottest/common/timelist.go (about) 1 package common 2 3 import ( 4 "container/heap" 5 "time" 6 7 ca "gitee.com/KyleChenSource/lib-robot/robottest/common/container" 8 ) 9 10 type ITimer interface { 11 OnTimer(any) 12 } 13 14 type TimeInterface struct { 15 _pre, _next *TimeInterface // 组成逆序链表 16 _tickTime int64 // 根据interval计算的下一次timeCount 17 _interval int64 // 重复的间隔 18 _timeMax int32 // 总共重复的次数,0无限制 19 _times int32 // 当前重复的第几次 20 _data any // 透传参数 21 _cb TimeCallback // ret 如果非0, 会按照这个时间间隔进行下一次调用 22 } 23 24 type TimeCallback func(*TimeInterface, any) int64 // timewheel回调函数, ret:如果返回非0,会直接根据now + ret来进行下一次调用 25 26 func (this *TimeInterface) IsRepeat() bool { 27 return this._interval > 0 && this._timeMax > 0 28 } 29 30 func (this *TimeInterface) IsLastTime() bool { 31 return this._timeMax <= this._times 32 } 33 34 func (this *TimeInterface) Close() { 35 this._pre._next, this._next._pre, this._pre, this._next = this._next, this._pre, nil, nil 36 } 37 38 func (this *TimeInterface) timer() int64 { 39 this._times++ 40 return this._cb(this, this._data) 41 } 42 43 type TimeList struct { 44 _timers *ca.IntHeap64 // 最小堆 45 _timer2Handler map[int64]*TimeInterface 46 _tick *time.Ticker 47 _timeFunc func() int64 // 获取当前时间函数 48 } 49 50 func TimeListNew() *TimeList { 51 ret := &TimeList{ 52 _timers: &ca.IntHeap64{}, 53 _timer2Handler: make(map[int64]*TimeInterface), 54 _tick: time.NewTicker(1000 * time.Second), 55 // _timeFunc: time.Now().UnixMilli, 56 _timeFunc: func() int64 { 57 ret := time.Now().UnixMilli() 58 return ret 59 }, 60 } 61 62 heap.Init(ret._timers) 63 ret._tick.Stop() 64 65 return ret 66 } 67 68 func (this *TimeList) Timer() <-chan time.Time { 69 return this._tick.C 70 } 71 72 func (this *TimeList) addTimer(t *TimeInterface) { 73 timeCount := t._tickTime 74 l, ok := this._timer2Handler[timeCount] 75 if !ok { 76 addHead := &TimeInterface{} 77 addHead._pre, addHead._next = addHead, addHead 78 this._timer2Handler[timeCount] = addHead 79 l = addHead 80 81 if this._timers.Len() == 0 || this._timers.Front() > timeCount { 82 next := timeCount - this._timeFunc() 83 if next <= 0 { 84 next = 1 85 } 86 this._tick.Reset(time.Millisecond * time.Duration(next)) 87 } 88 heap.Push(this._timers, timeCount) 89 } 90 91 tail := l._pre 92 tail._next, tail._next._pre, t._next, t._pre = t, t, tail._next, tail 93 } 94 95 // delay : ms 96 // interval : 后续重复调用的时间间隔ms,0会不重复 97 // times : 重复的总次数,delay后的第一次也算。0,不限制次数 98 // callback: 回调 99 func (this *TimeList) AddTimer(delay int64, interval int64, times int64, callback TimeCallback, data any) (*TimeInterface, error) { 100 timeCount := (this._timeFunc() + delay) 101 102 ret := &TimeInterface{ 103 _tickTime: timeCount, // 实际的时间 104 _interval: interval, 105 _timeMax: int32(times), 106 _data: data, 107 _cb: callback, 108 } 109 110 this.addTimer(ret) 111 return ret, nil 112 } 113 114 func (this *TimeList) DelTimer(timer *TimeInterface) { 115 t := timer._tickTime 116 timer.Close() 117 l, ok := this._timer2Handler[t] 118 if ok && l._pre == l._next { 119 delete(this._timer2Handler, t) 120 if this._timers.Front() == t { 121 // 换一个timer 122 heap.Pop(this._timers) 123 if this._timers.Len() > 0 { 124 this._tick.Reset(time.Millisecond * time.Duration(this._timers.Front()-this._timeFunc())) 125 } 126 } 127 } 128 } 129 130 func (this *TimeList) timerExecute(now int64, t *TimeInterface) { 131 // 由于timewheel一次就update一个slot, 所以不用考虑now之内的问题 132 // 只要有重复,必定是下一次TickOnce才会调用 133 next := t.timer() 134 if next != 0 { 135 t._tickTime = next + now 136 this.addTimer(t) 137 return 138 } 139 140 if !t.IsLastTime() { 141 t._tickTime = now + t._interval 142 this.addTimer(t) 143 return 144 } 145 146 // 直接放弃了,不用 147 } 148 149 func (this *TimeList) Update() { 150 this._tick.Stop() 151 152 for this._timers.Len() > 0 && this._timers.Front() <= this._timeFunc() { 153 tickTime := this._timers.Front() 154 heap.Pop(this._timers) 155 root, ok := this._timer2Handler[tickTime] 156 if ok { 157 l := root 158 for l._next != root { 159 c := l._next 160 c.Close() 161 this.timerExecute(this._timeFunc(), c) 162 } 163 delete(this._timer2Handler, tickTime) 164 } 165 } 166 167 if this._timers.Len() > 0 { 168 n := this._timers.Front() - this._timeFunc() 169 if n <= 0 { 170 n = 1 171 } 172 this._tick.Reset(time.Millisecond * time.Duration(n)) 173 } 174 }