Skip to content

Commit

Permalink
feat: add event package
Browse files Browse the repository at this point in the history
  • Loading branch information
MarvinJWendt committed Sep 1, 2024
1 parent 9ade776 commit 3c3937b
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 2 deletions.
52 changes: 52 additions & 0 deletions event.go
Original file line number Diff line number Diff line change
@@ -1 +1,53 @@
package event

import "sync"

// Event represents an event system that can handle multiple listeners.
type Event[T any] struct {
listeners []chan T
mu sync.Mutex
}

func New[T any]() *Event[T] {
return &Event[T]{
listeners: []chan T{},
}
}

// Trigger triggers the event and notifies all listeners.
func (e *Event[T]) Trigger(value T) {
e.mu.Lock()
defer e.mu.Unlock()

for _, listener := range e.listeners {
go func(l chan T) {
l <- value
}(listener)
}
}

// Listen gets called when the event is triggered.
func (e *Event[T]) Listen(f func(T)) {

Check failure on line 30 in event.go

View workflow job for this annotation

GitHub Actions / lint

parameter name 'f' is too short for the scope of its usage (varnamelen)
ch := make(chan T)

Check failure on line 31 in event.go

View workflow job for this annotation

GitHub Actions / lint

variable name 'ch' is too short for the scope of its usage (varnamelen)

e.mu.Lock()
e.listeners = append(e.listeners, ch)
e.mu.Unlock()

go func() {
for v := range ch {
f(v)
}
}()
}

func (e *Event[T]) Close() {
e.mu.Lock()
defer e.mu.Unlock()

for _, listener := range e.listeners {
close(listener)
}

e.listeners = nil
}
34 changes: 32 additions & 2 deletions examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,39 @@ package event_test

import (
"fmt"
"time"

"atomicgo.dev/event"
)

type Player struct {
Name string
}

var PlayerJoinEvent = event.New[Player]()

func Example_demo() {
fmt.Println("Hello, World!")
// Output: Hello, World!
// Listen to the event as many times as you want
PlayerJoinEvent.Listen(func(p Player) {
fmt.Printf("Player %q joined the game\n", p.Name)
})

PlayerJoinEvent.Listen(func(p Player) {

Check warning on line 22 in examples_test.go

View workflow job for this annotation

GitHub Actions / lint

unused-parameter: parameter 'p' seems to be unused, consider removing or renaming it as _ (revive)

Check warning on line 22 in examples_test.go

View workflow job for this annotation

GitHub Actions / lint

unused-parameter: parameter 'p' seems to be unused, consider removing or renaming it as _ (revive)
// Do something else
})

// ...

// Trigger the event somewhere - can be in a different function or package
PlayerJoinEvent.Trigger(Player{Name: "Marvin"})
PlayerJoinEvent.Trigger(Player{Name: "Bob"})
PlayerJoinEvent.Trigger(Player{Name: "Alice"})

// Keep the program alive
time.Sleep(time.Second)

// Output:
// Player "Marvin" joined the game
// Player "Bob" joined the game
// Player "Alice" joined the game
}

0 comments on commit 3c3937b

Please sign in to comment.