commit de5eea1809ad05e71312899f669ed25141c1ed89
Author: Yongbin Kim <iam@yongbin.kim>
Date: Fri, 3 Nov 2023 12:52:56 +0900
First commit
Diffstat:
A | .gitignore | | | 23 | +++++++++++++++++++++++ |
A | LICENSE | | | 15 | +++++++++++++++ |
A | eve.go | | | 65 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | go.mod | | | 5 | +++++ |
A | go.sum | | | 2 | ++ |
5 files changed, 110 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1,23 @@
+# Allowlisting gitignore template for GO projects prevents us
+# from adding various unwanted local files, such as generated
+# files, developer configurations or IDE-specific files etc.
+#
+# Recommended: Go.AllowList.gitignore
+
+# Ignore everything
+*
+
+# But not these files...
+!/.gitignore
+
+!*.go
+!go.sum
+!go.mod
+
+!README.md
+!LICENSE
+
+# !Makefile
+
+# ...even if they are in subdirectories
+!*/
diff --git a/LICENSE b/LICENSE
@@ -0,0 +1,15 @@
+ISC License
+
+Copyright (c) 2023 Yongbin Kim
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
diff --git a/eve.go b/eve.go
@@ -0,0 +1,65 @@
+package eve
+
+import (
+ "context"
+ "sync"
+
+ "go.uber.org/multierr"
+)
+
+type (
+ eventFn[E any] func(ctx context.Context, e E) error
+ eventMap[E any] map[uint64]eventFn[E]
+)
+
+type Event[E any] interface {
+ On(fn eventFn[E]) func()
+ Emit(ctx context.Context, event E) error
+}
+
+type event[E any] struct {
+ mu sync.Mutex
+ acc uint64
+ handlers map[uint64]eventFn[E]
+}
+
+func New[E any]() Event[E] {
+ return &event[E]{
+ handlers: make(eventMap[E]),
+ }
+}
+
+func (e *event[E]) On(fn eventFn[E]) func() {
+ e.mu.Lock()
+
+ id := e.acc
+ e.acc++
+
+ e.handlers[id] = fn
+
+ e.mu.Unlock()
+
+ canceled := false
+ return func() {
+ if canceled {
+ return
+ }
+
+ e.mu.Lock()
+ delete(e.handlers, id)
+ e.mu.Unlock()
+ }
+}
+
+func (e *event[E]) Emit(ctx context.Context, event E) error {
+ e.mu.Lock()
+ defer e.mu.Unlock()
+
+ var err error
+
+ for _, fn := range e.handlers {
+ multierr.Append(err, fn(ctx, event))
+ }
+
+ return err
+}
diff --git a/go.mod b/go.mod
@@ -0,0 +1,5 @@
+module go.lair.cx/eve
+
+go 1.21.2
+
+require go.uber.org/multierr v1.11.0 // indirect
diff --git a/go.sum b/go.sum
@@ -0,0 +1,2 @@
+go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
+go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=