diff --git a/README.md b/README.md index 47b3463..cd05581 100644 --- a/README.md +++ b/README.md @@ -680,6 +680,45 @@ import optional "github.com/duke-git/lancet/v2/datastructure/optional" [[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/datastructure/optional.md)] +
创建EventBus实例。
+ +函数签名: + +```go +func NewEventBus[T any]() *EventBus[T] +``` + +示例:[运行](todo) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + receivedData := 0 + listener := func(eventData int) { + receivedData = eventData + } + + eb.Subscribe("event1", listener, false, 0, nil) + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + + fmt.Println(receivedData) + + // Output: + // 1 +} +``` + +### Subscribe + +订阅具有特定事件主题和监听函数的事件。支持异步,事件优先级,事件过滤器。
+ +函数签名: + +```go +func (eb *EventBus[T]) Subscribe(topic string, listener func(eventData T), async bool, priority int, filter func(eventData T) bool) +``` + +示例:[运行](todo) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + receivedData := 0 + listener := func(eventData int) { + receivedData = eventData + } + + filter := func(eventData int) bool { + return eventData == 1 + } + + eb.Subscribe("event1", listener, false, 0, filter) + + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + eb.Publish(Event[int]{Topic: "event1", Payload: 2}) + + fmt.Println(receivedData) + + // Output: + // 1 +} +``` + +### Unsubscribe + +取消订阅具有特定事件主题的事件。
+ +函数签名: + +```go +func (eb *EventBus[T]) Unsubscribe(topic string, listener func(eventData T)) +``` + +示例:[运行](todo) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + receivedData := 0 + listener := func(eventData int) { + receivedData = eventData + } + + eb.Subscribe("event1", listener, false, 0, nil) + eb.Unsubscribe("event1", listener) + + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + + fmt.Println(receivedData) + + // Output: + // 0 +} +``` + +### Publish + +发布一个带有特定事件主题和数据负载的事件。
+ +函数签名: + +```go +func (eb *EventBus[T]) Publish(event Event[T]) +``` + +示例:[运行](todo) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + eb.Subscribe("event1", func(eventData int) { + fmt.Println(eventData) + }, false, 0, nil) + + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + + // Output: + // 1 +} +``` + +### ClearListeners + +清空所有事件监听器。
+ +函数签名: + +```go +func (eb *EventBus[T]) ClearListeners() +``` + +示例:[运行](todo) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + receivedData := 0 + listener := func(eventData int) { + receivedData = eventData + } + + eb.Subscribe("event1", listener, false, 0, nil) + eb.ClearListeners() + + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + + fmt.Println(receivedData) + + // Output: + // 0 +} +``` + +### ClearListenersByTopic + +清空特定事件监听器。
+ +函数签名: + +```go +func (eb *EventBus[T]) ClearListenersByTopic(topic string) +``` + +示例:[运行](todo) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + receivedData := 0 + listener := func(eventData int) { + receivedData = eventData + } + + eb.Subscribe("event1", listener, false, 0, nil) + eb.ClearListenersByTopic("event1") + + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + + fmt.Println(receivedData) + + // Output: + // 0 +} +``` + +### GetListenersCount + +获取特定事件的监听器数量。
+ +函数签名: + +```go +func (eb *EventBus[T]) GetListenersCount(topic string) int +``` + +示例:[运行](todo) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + eb.Subscribe("event1", func(eventData int) {}, false, 0, nil) + eb.Subscribe("event1", func(eventData int) {}, false, 0, nil) + + count := eb.GetListenersCount("event1") + + fmt.Println(count) + + // Output: + // 2 +} +``` + +### GetAllListenersCount + +获取所有事件的监听器数量。
+ +函数签名: + +```go +func (eb *EventBus[T]) GetAllListenersCount() int +``` + +示例:[运行](todo) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + eb.Subscribe("event1", func(eventData int) {}, false, 0, nil) + eb.Subscribe("event2", func(eventData int) {}, false, 0, nil) + + count := eb.GetAllListenersCount() + + fmt.Println(count) + + // Output: + // 2 +} +``` + +### GetEvents + +获取所有事件的topic。
+ +函数签名: + +```go +func (eb *EventBus[T]) GetEvents() []string +``` + +示例:[运行](todo) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + eb.Subscribe("event1", func(eventData int) {}, false, 0, nil) + eb.Subscribe("event2", func(eventData int) {}, false, 0, nil) + + events := eb.GetEvents() + + for _, event := range events { + fmt.Println(event) + } + + // Output: + // event1 + // event2 +} +``` + +### SetErrorHandler + +设置事件的错误处理函数。
+ +函数签名: + +```go +func (eb *EventBus[T]) SetErrorHandler(handler func(err error)) +``` + +示例:[运行](todo) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + eb.SetErrorHandler(func(err error) { + fmt.Println(err) + }) + + eb.Subscribe("event1", func(eventData int) { + panic("error") + }, false, 0, nil) + + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + + // Output: + // error +} +``` \ No newline at end of file diff --git a/docs/en/api/packages/eventbus.md b/docs/en/api/packages/eventbus.md new file mode 100644 index 0000000..08a27ff --- /dev/null +++ b/docs/en/api/packages/eventbus.md @@ -0,0 +1,401 @@ +# EventBus + +EventBus is an event bus used for handling events within an application. + + + +## Source: + +- [https://github.com/duke-git/lancet/blob/main/eventbus/eventbus.go](https://github.com/duke-git/lancet/blob/main/eventbus/eventbus.go) + + + +## Usage: + +```go +import ( + "github.com/duke-git/lancet/v2/eventbus" +) +``` + + + +## Index + +- [NewEventBus](#NewEventBus) +- [Subscribe](#Subscribe) +- [Unsubscribe](#Unsubscribe) +- [Publish](#Publish) +- [ClearListeners](#ClearListeners) +- [ClearListenersByTopic](#ClearListenersByTopic) +- [GetListenersCount](#GetListenersCount) +- [GetAllListenersCount](#GetAllListenersCount) +- [GetEvents](#GetEvents) +- [SetErrorHandler](#SetErrorHandler) + + + + +## Documentation + +### NewEventBus + +Create an EventBus instance.
+ +Signature: + +```go +func NewEventBus[T any]() *EventBus[T] +``` + +Example:[Run](todo) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + receivedData := 0 + listener := func(eventData int) { + receivedData = eventData + } + + eb.Subscribe("event1", listener, false, 0, nil) + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + + fmt.Println(receivedData) + + // Output: + // 1 +} +``` + +### Subscribe + +Subscribes to an event with a specific event topic and listener function.
+ +Signature: + +```go +func (eb *EventBus[T]) Subscribe(topic string, listener func(eventData T), async bool, priority int, filter func(eventData T) bool) +``` + +Example:[Run](todo) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + receivedData := 0 + listener := func(eventData int) { + receivedData = eventData + } + + filter := func(eventData int) bool { + return eventData == 1 + } + + eb.Subscribe("event1", listener, false, 0, filter) + + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + eb.Publish(Event[int]{Topic: "event1", Payload: 2}) + + fmt.Println(receivedData) + + // Output: + // 1 +} +``` + +### Unsubscribe + +Unsubscribes from an event with a specific event topic and listener function.
+ +Signature: + +```go +func (eb *EventBus[T]) Unsubscribe(topic string, listener func(eventData T)) +``` + +Example:[Run](todo) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + receivedData := 0 + listener := func(eventData int) { + receivedData = eventData + } + + eb.Subscribe("event1", listener, false, 0, nil) + eb.Unsubscribe("event1", listener) + + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + + fmt.Println(receivedData) + + // Output: + // 0 +} +``` + +### Publish + +Publishes an event with a specific event topic and data payload.
+ +Signature: + +```go +func (eb *EventBus[T]) Publish(event Event[T]) +``` + +Example:[Run](todo) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + eb.Subscribe("event1", func(eventData int) { + fmt.Println(eventData) + }, false, 0, nil) + + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + + // Output: + // 1 +} +``` + +### ClearListeners + +Clears all the listeners.
+ +Signature: + +```go +func (eb *EventBus[T]) ClearListeners() +``` + +Example:[Run](todo) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + receivedData := 0 + listener := func(eventData int) { + receivedData = eventData + } + + eb.Subscribe("event1", listener, false, 0, nil) + eb.ClearListeners() + + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + + fmt.Println(receivedData) + + // Output: + // 0 +} +``` + +### ClearListenersByTopic + +Clears all the listeners by topic.
+ +Signature: + +```go +func (eb *EventBus[T]) ClearListenersByTopic(topic string) +``` + +Example:[Run](todo) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + receivedData := 0 + listener := func(eventData int) { + receivedData = eventData + } + + eb.Subscribe("event1", listener, false, 0, nil) + eb.ClearListenersByTopic("event1") + + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + + fmt.Println(receivedData) + + // Output: + // 0 +} +``` + +### GetListenersCount + +Returns the number of listeners for a specific event topic.
+ +Signature: + +```go +func (eb *EventBus[T]) GetListenersCount(topic string) int +``` + +Example:[Run](todo) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + eb.Subscribe("event1", func(eventData int) {}, false, 0, nil) + eb.Subscribe("event1", func(eventData int) {}, false, 0, nil) + + count := eb.GetListenersCount("event1") + + fmt.Println(count) + + // Output: + // 2 +} +``` + +### GetAllListenersCount + +Returns the total number of all listeners.
+ +Signature: + +```go +func (eb *EventBus[T]) GetAllListenersCount() int +``` + +Example:[Run](todo) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + eb.Subscribe("event1", func(eventData int) {}, false, 0, nil) + eb.Subscribe("event2", func(eventData int) {}, false, 0, nil) + + count := eb.GetAllListenersCount() + + fmt.Println(count) + + // Output: + // 2 +} +``` + +### GetEvents + +Returns all the events topics.
+ +Signature: + +```go +func (eb *EventBus[T]) GetEvents() []string +``` + +Example:[Run](todo) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + eb.Subscribe("event1", func(eventData int) {}, false, 0, nil) + eb.Subscribe("event2", func(eventData int) {}, false, 0, nil) + + events := eb.GetEvents() + + for _, event := range events { + fmt.Println(event) + } + + // Output: + // event1 + // event2 +} +``` + +### SetErrorHandler + +Sets the error handler function.
+ +Signature: + +```go +func (eb *EventBus[T]) SetErrorHandler(handler func(err error)) +``` + +Example:[Run](todo) + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/eventbus" +) + +func main() { + eb := eventbus.NewEventBus[int]() + + eb.SetErrorHandler(func(err error) { + fmt.Println(err) + }) + + eb.Subscribe("event1", func(eventData int) { + panic("error") + }, false, 0, nil) + + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + + // Output: + // error +} +``` \ No newline at end of file diff --git a/eventbus/eventbus.go b/eventbus/eventbus.go index d6377e0..93b55fc 100644 --- a/eventbus/eventbus.go +++ b/eventbus/eventbus.go @@ -33,6 +33,7 @@ type EventListener[T any] struct { } // NewEventBus creates a new EventBus. +// Play: todo func NewEventBus[T any]() *EventBus[T] { return &EventBus[T]{ listeners: sync.Map{}, @@ -40,6 +41,7 @@ func NewEventBus[T any]() *EventBus[T] { } // Subscribe subscribes to an event with a specific event topic and listener function. +// Play: todo func (eb *EventBus[T]) Subscribe(topic string, listener func(eventData T), async bool, priority int, filter func(eventData T) bool) { eb.mu.Lock() defer eb.mu.Unlock() @@ -63,6 +65,7 @@ func (eb *EventBus[T]) Subscribe(topic string, listener func(eventData T), async } // Unsubscribe unsubscribes from an event with a specific event topic and listener function. +// Play: todo func (eb *EventBus[T]) Unsubscribe(topic string, listener func(eventData T)) { eb.mu.Lock() defer eb.mu.Unlock() @@ -86,6 +89,7 @@ func (eb *EventBus[T]) Unsubscribe(topic string, listener func(eventData T)) { } // Publish publishes an event with a specific event topic and data payload. +// Play: todo func (eb *EventBus[T]) Publish(event Event[T]) { eb.mu.RLock() defer eb.mu.RUnlock() @@ -126,6 +130,7 @@ func (eb *EventBus[T]) SetErrorHandler(handler func(err error)) { } // ClearListeners clears all the listeners. +// Play: todo func (eb *EventBus[T]) ClearListeners() { eb.mu.Lock() defer eb.mu.Unlock() @@ -134,6 +139,7 @@ func (eb *EventBus[T]) ClearListeners() { } // ClearListenersByTopic clears all the listeners by topic. +// Play: todo func (eb *EventBus[T]) ClearListenersByTopic(topic string) { eb.mu.Lock() defer eb.mu.Unlock() @@ -142,6 +148,7 @@ func (eb *EventBus[T]) ClearListenersByTopic(topic string) { } // GetListenersCount returns the number of listeners for a specific event topic. +// Play: todo func (eb *EventBus[T]) GetListenersCount(topic string) int { eb.mu.RLock() defer eb.mu.RUnlock() @@ -156,6 +163,7 @@ func (eb *EventBus[T]) GetListenersCount(topic string) int { } // GetAllListenersCount returns the total number of listeners. +// Play: todo func (eb *EventBus[T]) GetAllListenersCount() int { eb.mu.RLock() defer eb.mu.RUnlock() @@ -170,6 +178,7 @@ func (eb *EventBus[T]) GetAllListenersCount() int { } // GetEvents returns all the events topics. +// Play: todo func (eb *EventBus[T]) GetEvents() []string { eb.mu.RLock() defer eb.mu.RUnlock() diff --git a/eventbus/eventbus_example_test.go b/eventbus/eventbus_example_test.go new file mode 100644 index 0000000..870b019 --- /dev/null +++ b/eventbus/eventbus_example_test.go @@ -0,0 +1,229 @@ +package eventbus + +import ( + "fmt" + "sync" + "time" +) + +func ExampleEventBus_Subscribe() { + eb := NewEventBus[string]() + eb.Subscribe("event1", func(eventData string) { + fmt.Println(eventData) + }, false, 0, nil) + + eb.Publish(Event[string]{Topic: "event1", Payload: "hello"}) + + // Output: + // hello +} + +func ExampleEventBus_Unsubscribe() { + eb := NewEventBus[int]() + + receivedData := 0 + listener := func(eventData int) { + receivedData = eventData + } + + eb.Subscribe("event1", listener, false, 0, nil) + eb.Unsubscribe("event1", listener) + + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + + fmt.Println(receivedData) + + // Output: + // 0 +} + +func ExampleEventBus_Subscribe_WithFilter() { + eb := NewEventBus[int]() + + receivedData := 0 + listener := func(eventData int) { + receivedData = eventData + } + + filter := func(eventData int) bool { + return eventData == 1 + } + + eb.Subscribe("event1", listener, false, 0, filter) + + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + eb.Publish(Event[int]{Topic: "event1", Payload: 2}) + + fmt.Println(receivedData) + + // Output: + // 1 +} + +func ExampleEventBus_Subscribe_WithPriority() { + eb := NewEventBus[int]() + + eb.Subscribe("event1", func(eventData int) { + fmt.Println(eventData) + }, false, 0, nil) + + eb.Subscribe("event1", func(eventData int) { + fmt.Println(eventData) + }, false, 1, nil) + + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + + // Output: + // 1 + // 1 +} + +func ExampleEventBus_Subscribe_Async() { + eb := NewEventBus[int]() + + var wg sync.WaitGroup + wg.Add(1) + + eb.Subscribe("event1", func(eventData int) { + time.Sleep(100 * time.Millisecond) + fmt.Println(eventData) + wg.Done() + }, true, 1, nil) + + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + wg.Wait() + + // Output: + // 1 +} + +func ExampleEventBus_Publish() { + eb := NewEventBus[int]() + + eb.Subscribe("event1", func(eventData int) { + fmt.Println(eventData) + }, false, 0, nil) + + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + + // Output: + // 1 +} + +func ExampleEventBus() { + eb := NewEventBus[int]() + + receivedData := 0 + listener := func(eventData int) { + receivedData = eventData + } + + eb.Subscribe("event1", listener, false, 0, nil) + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + + fmt.Println(receivedData) + + // Output: + // 1 +} + +func ExampleEventBus_ClearListeners() { + eb := NewEventBus[int]() + + receivedData := 0 + listener := func(eventData int) { + receivedData = eventData + } + + eb.Subscribe("event1", listener, false, 0, nil) + eb.ClearListeners() + + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + + fmt.Println(receivedData) + + // Output: + // 0 +} + +func ExampleEventBus_ClearListenersByTopic() { + eb := NewEventBus[int]() + + receivedData := 0 + listener := func(eventData int) { + receivedData = eventData + } + + eb.Subscribe("event1", listener, false, 0, nil) + eb.ClearListenersByTopic("event1") + + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + + fmt.Println(receivedData) + + // Output: + // 0 +} + +func ExampleEventBus_GetListenersCount() { + eb := NewEventBus[int]() + + eb.Subscribe("event1", func(eventData int) {}, false, 0, nil) + eb.Subscribe("event1", func(eventData int) {}, false, 0, nil) + + count := eb.GetListenersCount("event1") + + fmt.Println(count) + + // Output: + // 2 +} + +func ExampleEventBus_SetErrorHandler() { + eb := NewEventBus[int]() + + eb.SetErrorHandler(func(err error) { + fmt.Println(err) + }) + + eb.Subscribe("event1", func(eventData int) { + panic("error") + }, false, 0, nil) + + eb.Publish(Event[int]{Topic: "event1", Payload: 1}) + + // Output: + // error +} + +func ExampleEventBus_GetAllListenersCount() { + + eb := NewEventBus[int]() + + eb.Subscribe("event1", func(eventData int) {}, false, 0, nil) + eb.Subscribe("event2", func(eventData int) {}, false, 0, nil) + + count := eb.GetAllListenersCount() + + fmt.Println(count) + + // Output: + // 2 +} + +func ExampleEventBus_GetEvents() { + eb := NewEventBus[int]() + + eb.Subscribe("event1", func(eventData int) {}, false, 0, nil) + eb.Subscribe("event2", func(eventData int) {}, false, 0, nil) + + events := eb.GetEvents() + + for _, event := range events { + fmt.Println(event) + } + + // Output: + // event1 + // event2 +}