1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- // License: GPLv3 Copyright: 2022, Kovid Goyal, <kovid at kovidgoyal.net>
- package loop
- import (
- "fmt"
- "slices"
- "time"
- "kitty/tools/tty"
- "kitty/tools/utils"
- )
- var debugprintln = tty.DebugPrintln
- var _ = debugprintln
- type timer struct {
- interval time.Duration
- deadline time.Time
- repeats bool
- id IdType
- callback TimerCallback
- }
- func (self *timer) update_deadline(now time.Time) {
- self.deadline = now.Add(self.interval)
- }
- func (self timer) String() string {
- return fmt.Sprintf("Timer(id=%d, callback=%s, deadline=%s, repeats=%v)", self.id, utils.FunctionName(self.callback), time.Until(self.deadline), self.repeats)
- }
- func (self *Loop) add_timer(interval time.Duration, repeats bool, callback TimerCallback) (IdType, error) {
- if self.timers == nil {
- return 0, fmt.Errorf("Cannot add timers before starting the run loop, add them in OnInitialize instead")
- }
- self.timer_id_counter++
- t := timer{interval: interval, repeats: repeats, callback: callback, id: self.timer_id_counter}
- t.update_deadline(time.Now())
- self.timers = append(self.timers, &t)
- self.sort_timers()
- return t.id, nil
- }
- func (self *Loop) remove_timer(id IdType) bool {
- if self.timers == nil {
- return false
- }
- for i := 0; i < len(self.timers); i++ {
- if self.timers[i].id == id {
- self.timers = append(self.timers[:i], self.timers[i+1:]...)
- return true
- }
- }
- return false
- }
- func (self *Loop) dispatch_timers(now time.Time) error {
- self.timers_temp = self.timers_temp[:0]
- self.timers, self.timers_temp = self.timers_temp, self.timers
- dispatched := false
- for _, t := range self.timers_temp {
- if now.After(t.deadline) {
- dispatched = true
- err := t.callback(t.id)
- if err != nil {
- return err
- }
- if t.repeats {
- t.update_deadline(now)
- self.timers = append(self.timers, t)
- }
- } else {
- self.timers = append(self.timers, t)
- }
- }
- if dispatched {
- self.sort_timers() // needed because a timer callback could have added a new timer
- }
- return nil
- }
- func (self *Loop) sort_timers() {
- slices.SortStableFunc(self.timers, func(a, b *timer) int { return a.deadline.Compare(b.deadline) })
- }
|