github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/builtins/events/onSecondsElapsed/timer.go (about) 1 package onsecondselapsed 2 3 import ( 4 "errors" 5 "strconv" 6 "sync" 7 "time" 8 9 "github.com/lmorg/murex/builtins/events" 10 "github.com/lmorg/murex/lang" 11 "github.com/lmorg/murex/lang/ref" 12 ) 13 14 const eventType = "onSecondsElapsed" 15 16 func init() { 17 t := newTimer() 18 events.AddEventType(eventType, t, nil) 19 go t.init() 20 } 21 22 type timer struct { 23 mutex sync.Mutex 24 events []timeEvent 25 } 26 27 type timeEvent struct { 28 Name string 29 Interval int 30 Block []rune 31 state int 32 FileRef *ref.File 33 } 34 35 func newTimer() (t *timer) { 36 t = new(timer) 37 t.events = make([]timeEvent, 0) 38 return 39 } 40 41 func (t *timer) init() { 42 for { 43 time.Sleep(1 * time.Second) 44 45 t.mutex.Lock() 46 for i := range t.events { 47 t.events[i].state++ 48 if t.events[i].state == t.events[i].Interval { 49 t.events[i].state = 0 50 go events.Callback( 51 t.events[i].Name, 52 t.events[i].Interval, 53 t.events[i].Block, 54 t.events[i].FileRef, 55 lang.ShellProcess.Stdout, 56 true, 57 ) 58 } 59 } 60 t.mutex.Unlock() 61 } 62 } 63 64 // Add a path to the watch event list 65 func (t *timer) Add(name, interrupt string, block []rune, fileRef *ref.File) (err error) { 66 interval, err := strconv.Atoi(interrupt) 67 if err != nil { 68 return errors.New("interrupt should be an integer for `" + eventType + "` events") 69 } 70 71 t.mutex.Lock() 72 defer t.mutex.Unlock() 73 74 for i := range t.events { 75 if t.events[i].Name == name { 76 t.events[i].Interval = interval 77 t.events[i].Block = block 78 return nil 79 } 80 } 81 82 t.events = append(t.events, timeEvent{ 83 Name: name, 84 Interval: interval, 85 Block: block, 86 FileRef: fileRef, 87 }) 88 89 return 90 } 91 92 // Remove a path to the watch event list 93 func (t *timer) Remove(name string) (err error) { 94 t.mutex.Lock() 95 defer t.mutex.Unlock() 96 97 if len(t.events) == 0 { 98 return errors.New("no events have been created for this listener") 99 } 100 101 for i := range t.events { 102 if t.events[i].Name == name { 103 switch { 104 case len(t.events) == 1: 105 t.events = make([]timeEvent, 0) 106 case i == 0: 107 t.events = t.events[1:] 108 case i == len(t.events)-1: 109 t.events = t.events[:len(t.events)-1] 110 default: 111 t.events = append(t.events[:i], t.events[i+1:]...) 112 } 113 return nil 114 } 115 } 116 117 return errors.New("no event found for this listener with the name `" + name + "`.") 118 } 119 120 // Dump returns all the events in w 121 func (t *timer) Dump() map[string]events.DumpT { 122 dump := make(map[string]events.DumpT) 123 124 t.mutex.Lock() 125 126 for i := range t.events { 127 dump[t.events[i].Name] = events.DumpT{ 128 Interrupt: time.Duration(t.events[i].Interval * int(time.Second)).String(), 129 Block: string(t.events[i].Block), 130 FileRef: t.events[i].FileRef, 131 } 132 } 133 134 t.mutex.Unlock() 135 136 return dump 137 }