github.com/jmigpin/editor@v1.6.0/util/uiutil/mousefilter/movefilter.go (about)

     1  package mousefilter
     2  
     3  import (
     4  	"sync"
     5  	"time"
     6  )
     7  
     8  type MoveFilter struct {
     9  	fps      int
    10  	emitFn   func(interface{})
    11  	isMoveFn func(interface{}) bool
    12  
    13  	last struct {
    14  		sync.Mutex
    15  		timer  *time.Timer
    16  		sent   time.Time
    17  		moveEv interface{}
    18  	}
    19  }
    20  
    21  func NewMoveFilter(fps int, emitFn func(interface{}), isMoveFn func(interface{}) bool) *MoveFilter {
    22  	return &MoveFilter{fps: fps, emitFn: emitFn, isMoveFn: isMoveFn}
    23  }
    24  
    25  func (movef *MoveFilter) Filter(ev interface{}) {
    26  	if movef.isMoveFn(ev) {
    27  		movef.keepMoveEv(ev)
    28  	} else {
    29  		movef.sendMoveEv()
    30  		movef.emitFn(ev)
    31  	}
    32  }
    33  
    34  func (movef *MoveFilter) keepMoveEv(moveEv interface{}) {
    35  	frameDur := time.Second / time.Duration(movef.fps)
    36  	movef.last.Lock()
    37  	defer movef.last.Unlock()
    38  	if movef.last.timer != nil {
    39  		// Filter by discarding sequential old move events. Just update to send the last one received when it is time.
    40  		movef.last.moveEv = moveEv
    41  	} else {
    42  		// Send event immediately if the frame duration already passed
    43  		now := time.Now()
    44  		if now.Sub(movef.last.sent) >= frameDur {
    45  			movef.last.sent = now
    46  			movef.emitFn(moveEv)
    47  		} else {
    48  			movef.last.moveEv = moveEv // set ev to send later
    49  			d := frameDur - now.Sub(movef.last.sent)
    50  			movef.last.timer = time.AfterFunc(d, movef.sendMoveEv)
    51  		}
    52  	}
    53  }
    54  
    55  func (movef *MoveFilter) sendMoveEv() {
    56  	movef.last.Lock()
    57  	defer movef.last.Unlock()
    58  	if movef.last.moveEv != nil {
    59  		movef.last.sent = time.Now()
    60  		movef.emitFn(movef.last.moveEv)
    61  		movef.last.moveEv = nil
    62  	}
    63  	if movef.last.timer != nil {
    64  		movef.last.timer.Stop()
    65  		movef.last.timer = nil
    66  	}
    67  }