Compare commits
No commits in common. "master" and "v1.0.0" have entirely different histories.
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
emitter "git.kingecg.top/kingecg/goemitter"
|
emitter "git.pyer.club/kingecg/goemitter"
|
||||||
)
|
)
|
||||||
|
|
||||||
type St struct {
|
type St struct {
|
||||||
|
|
|
||||||
2
go.mod
2
go.mod
|
|
@ -1,3 +1,3 @@
|
||||||
module git.kingecg.top/kingecg/goemitter
|
module git.pyer.club/kingecg/goemitter
|
||||||
|
|
||||||
go 1.19
|
go 1.19
|
||||||
|
|
|
||||||
60
main.go
60
main.go
|
|
@ -1,46 +1,23 @@
|
||||||
// Package goemitter implements an event emitter pattern similar to Node.js EventEmitter.
|
// Package goemitter
|
||||||
// It provides a way to register event listeners and emit events with data.
|
|
||||||
//
|
|
||||||
// Basic usage example:
|
|
||||||
//
|
|
||||||
// emitter := goemitter.NewEmitter()
|
|
||||||
//
|
|
||||||
// // Register an event listener
|
|
||||||
// handle := emitter.On("userConnected", func(args ...interface{}) {
|
|
||||||
// user := args[0].(string)
|
|
||||||
// fmt.Printf("User connected: %s\n", user)
|
|
||||||
// })
|
|
||||||
//
|
|
||||||
// // Emit an event
|
|
||||||
// emitter.Emit("userConnected", "john_doe")
|
|
||||||
//
|
|
||||||
// // Remove the listener when no longer needed
|
|
||||||
// handle.Remove()
|
|
||||||
package goemitter
|
package goemitter
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
// EventEmitter provides event subscription and publishing functionality.
|
|
||||||
// It is safe for concurrent use thanks to internal synchronization.
|
|
||||||
type EventEmitter struct {
|
type EventEmitter struct {
|
||||||
callbacks map[string]map[int]func(args ...interface{}) // Persistent event callbacks indexed by ID
|
callbacks map[string]map[int]func(args ...interface{})
|
||||||
onceCallbacks map[string][]func(args ...interface{}) // One-time event callbacks
|
onceCallbacks map[string][]func(args ...interface{})
|
||||||
lock sync.Mutex // Mutex to ensure thread safety
|
lock sync.Mutex
|
||||||
counter int // Counter for generating unique callback IDs
|
counter int
|
||||||
}
|
}
|
||||||
|
|
||||||
// EventHandle represents a handle to a registered event listener.
|
|
||||||
// It can be used to remove the listener when it's no longer needed.
|
|
||||||
type EventHandle struct {
|
type EventHandle struct {
|
||||||
id int // Unique identifier for the callback
|
id int
|
||||||
event string // Event name
|
event string
|
||||||
emitter *EventEmitter // Reference to the parent emitter
|
emitter *EventEmitter
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove unregisters the event listener associated with this handle.
|
|
||||||
// After removal, the listener will no longer receive events.
|
|
||||||
func (eh *EventHandle) Remove() {
|
func (eh *EventHandle) Remove() {
|
||||||
eh.emitter.lock.Lock()
|
eh.emitter.lock.Lock()
|
||||||
defer eh.emitter.lock.Unlock()
|
defer eh.emitter.lock.Unlock()
|
||||||
|
|
@ -49,9 +26,6 @@ func (eh *EventHandle) Remove() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// On registers a new event listener for the specified event.
|
|
||||||
// It returns an EventHandle that can be used to remove the listener later.
|
|
||||||
// The callback function can accept any number of arguments passed during event emission.
|
|
||||||
func (e *EventEmitter) On(event string, callback func(args ...interface{})) *EventHandle {
|
func (e *EventEmitter) On(event string, callback func(args ...interface{})) *EventHandle {
|
||||||
e.lock.Lock()
|
e.lock.Lock()
|
||||||
defer e.lock.Unlock()
|
defer e.lock.Unlock()
|
||||||
|
|
@ -67,9 +41,6 @@ func (e *EventEmitter) On(event string, callback func(args ...interface{})) *Eve
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Once registers a one-time event listener for the specified event.
|
|
||||||
// The listener will be automatically removed after being triggered once.
|
|
||||||
// Multiple one-time listeners can be registered for the same event.
|
|
||||||
func (e *EventEmitter) Once(event string, callback func(args ...interface{})) {
|
func (e *EventEmitter) Once(event string, callback func(args ...interface{})) {
|
||||||
e.lock.Lock()
|
e.lock.Lock()
|
||||||
defer e.lock.Unlock()
|
defer e.lock.Unlock()
|
||||||
|
|
@ -81,55 +52,44 @@ func (e *EventEmitter) Once(event string, callback func(args ...interface{})) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emit triggers an event asynchronously with the provided arguments.
|
|
||||||
// All registered callbacks for the event will be executed in separate goroutines.
|
|
||||||
// One-time callbacks are cleared after emission.
|
|
||||||
func (e *EventEmitter) Emit(event string, data ...interface{}) {
|
func (e *EventEmitter) Emit(event string, data ...interface{}) {
|
||||||
e.lock.Lock()
|
e.lock.Lock()
|
||||||
defer e.lock.Unlock()
|
defer e.lock.Unlock()
|
||||||
|
|
||||||
// Execute persistent callbacks asynchronously
|
|
||||||
if callbacks, ok := e.callbacks[event]; ok {
|
if callbacks, ok := e.callbacks[event]; ok {
|
||||||
for _, callback := range callbacks {
|
for _, callback := range callbacks {
|
||||||
go callback(data...)
|
go callback(data...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute and clear one-time callbacks
|
|
||||||
if onceCallbacks, ok := e.onceCallbacks[event]; ok {
|
if onceCallbacks, ok := e.onceCallbacks[event]; ok {
|
||||||
for _, callback := range onceCallbacks {
|
for _, callback := range onceCallbacks {
|
||||||
go callback(data...)
|
go callback(data...)
|
||||||
|
|
||||||
}
|
}
|
||||||
e.onceCallbacks[event] = []func(args ...interface{}){}
|
e.onceCallbacks[event] = []func(args ...interface{}){}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// EmitSync triggers an event synchronously with the provided arguments.
|
|
||||||
// All registered callbacks for the event will be executed in the current goroutine.
|
|
||||||
// One-time callbacks are cleared after emission.
|
|
||||||
func (e *EventEmitter) EmitSync(event string, data ...interface{}) {
|
func (e *EventEmitter) EmitSync(event string, data ...interface{}) {
|
||||||
e.lock.Lock()
|
e.lock.Lock()
|
||||||
defer e.lock.Unlock()
|
defer e.lock.Unlock()
|
||||||
|
|
||||||
// Execute persistent callbacks synchronously
|
|
||||||
if callbacks, ok := e.callbacks[event]; ok {
|
if callbacks, ok := e.callbacks[event]; ok {
|
||||||
for _, callback := range callbacks {
|
for _, callback := range callbacks {
|
||||||
callback(data...)
|
callback(data...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute and clear one-time callbacks
|
|
||||||
if onceCallbacks, ok := e.onceCallbacks[event]; ok {
|
if onceCallbacks, ok := e.onceCallbacks[event]; ok {
|
||||||
for _, callback := range onceCallbacks {
|
for _, callback := range onceCallbacks {
|
||||||
callback(data...)
|
callback(data...)
|
||||||
|
|
||||||
}
|
}
|
||||||
e.onceCallbacks[event] = []func(args ...interface{}){}
|
e.onceCallbacks[event] = []func(args ...interface{}){}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewEmitter creates and initializes a new EventEmitter instance.
|
|
||||||
// It initializes the internal maps for storing callbacks and returns
|
|
||||||
// a pointer to the new instance.
|
|
||||||
func NewEmitter() *EventEmitter {
|
func NewEmitter() *EventEmitter {
|
||||||
ret := &EventEmitter{}
|
ret := &EventEmitter{}
|
||||||
ret.callbacks = make(map[string]map[int]func(args ...interface{}))
|
ret.callbacks = make(map[string]map[int]func(args ...interface{}))
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue