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  }