Skip to content

Commit

Permalink
Add OnEvery timer event
Browse files Browse the repository at this point in the history
  • Loading branch information
kelindar committed Oct 8, 2023
1 parent ae75898 commit df1be55
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 0 deletions.
32 changes: 32 additions & 0 deletions emit/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package emit
import (
"context"
"math"
"sync/atomic"
"time"

"github.com/kelindar/event"
Expand Down Expand Up @@ -46,6 +47,20 @@ func (e fault) Type() uint32 {
return math.MaxUint32
}

// ----------------------------------------- Timer Event -----------------------------------------

var nextTimerID uint32 = 1 << 30

// timer represents a timer event
type timer struct {
ID uint32
}

// Type returns the type of the event
func (e timer) Type() uint32 {
return e.ID
}

// ----------------------------------------- Subscribe -----------------------------------------

// On subscribes to an event, the type of the event will be automatically
Expand Down Expand Up @@ -74,6 +89,23 @@ func OnError(handler func(err error, about any)) context.CancelFunc {
})
}

// OnEvery creates a timer that fires every 'interval' and calls the handler.
func OnEvery(handler func(now time.Time, elapsed time.Duration) error, interval time.Duration) context.CancelFunc {
id := atomic.AddUint32(&nextTimerID, 1)
if id >= (math.MaxUint32 - 1) {
panic("emit: too many timers created")
}

// Subscribe to the timer event
cancel := OnType[timer](id, func(_ timer, now time.Time, elapsed time.Duration) error {
return handler(now, elapsed)
})

// Start the timer
Every(timer{ID: id}, interval)
return cancel
}

// ----------------------------------------- Publish -----------------------------------------

// Next writes an event during the next tick.
Expand Down
23 changes: 23 additions & 0 deletions emit/event_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package emit

import (
"fmt"
"math"
"sync/atomic"
"testing"
"time"
Expand Down Expand Up @@ -125,6 +126,28 @@ func TestOnTypeError(t *testing.T) {
assert.Equal(t, "OnType()", (<-errors).Error())
}

func TestOnEvery(t *testing.T) {
events := make(chan MyEvent2)
defer OnEvery(func(now time.Time, elapsed time.Duration) error {
events <- MyEvent2{}
return nil
}, 20*time.Millisecond)()

// Emit the event
<-events
<-events
<-events
}

func TestTooManyTimers(t *testing.T) {
assert.Panics(t, func() {
nextTimerID = math.MaxUint32 - 1
defer OnEvery(func(now time.Time, elapsed time.Duration) error {
return nil
}, 200*time.Millisecond)()
})
}

// ------------------------------------- Test Events -------------------------------------

const (
Expand Down

0 comments on commit df1be55

Please sign in to comment.