eventbus: refactoring; add unsubscribe_method and unsubscribe_receiver (#9443)
parent
d1fadaf30c
commit
205fb88d90
|
@ -35,11 +35,7 @@ pub fn new() &EventBus {
|
||||||
registry := &Registry{
|
registry := &Registry{
|
||||||
events: []
|
events: []
|
||||||
}
|
}
|
||||||
return &EventBus{
|
return &EventBus{registry, &Publisher{registry}, &Subscriber{registry}}
|
||||||
registry,&Publisher{
|
|
||||||
registry},&Subscriber{
|
|
||||||
registry}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EventBus Methods
|
// EventBus Methods
|
||||||
|
@ -59,43 +55,46 @@ pub fn (eb &EventBus) has_subscriber(name string) bool {
|
||||||
|
|
||||||
// Publisher Methods
|
// Publisher Methods
|
||||||
fn (mut pb Publisher) publish(name string, sender voidptr, args voidptr) {
|
fn (mut pb Publisher) publish(name string, sender voidptr, args voidptr) {
|
||||||
for i, event in pb.registry.events {
|
for event in pb.registry.events {
|
||||||
if event.name == name {
|
if event.name == name {
|
||||||
if event.once {
|
|
||||||
pb.registry.events.delete(i)
|
|
||||||
}
|
|
||||||
event.handler(event.receiver, args, sender)
|
event.handler(event.receiver, args, sender)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pb.registry.events = pb.registry.events.filter(!(it.name == name && it.once))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut p Publisher) clear_all() {
|
fn (mut p Publisher) clear_all() {
|
||||||
if p.registry.events.len == 0 {
|
p.registry.events.clear()
|
||||||
return
|
|
||||||
}
|
|
||||||
for i := p.registry.events.len - 1; i >= 0; i-- {
|
|
||||||
p.registry.events.delete(i)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Subscriber Methods
|
// Subscriber Methods
|
||||||
pub fn (mut s Subscriber) subscribe(name string, handler EventHandlerFn) {
|
pub fn (mut s Subscriber) subscribe(name string, handler EventHandlerFn) {
|
||||||
s.registry.events << EventHandler {
|
s.registry.events << EventHandler{
|
||||||
name: name
|
name: name
|
||||||
handler: handler
|
handler: handler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut s Subscriber) subscribe_method(name string, handler EventHandlerFn, receiver voidptr) {
|
pub fn (mut s Subscriber) subscribe_method(name string, handler EventHandlerFn, receiver voidptr) {
|
||||||
s.registry.events << EventHandler {
|
s.registry.events << EventHandler{
|
||||||
name: name
|
name: name
|
||||||
handler: handler
|
handler: handler
|
||||||
receiver: receiver
|
receiver: receiver
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// unsubscribe_method unsubscribe a receiver for only one method
|
||||||
|
pub fn (mut s Subscriber) unsubscribe_method(name string, receiver voidptr) {
|
||||||
|
s.registry.events = s.registry.events.filter(!(it.name == name && it.receiver == receiver))
|
||||||
|
}
|
||||||
|
|
||||||
|
// unsubscribe_receiver unsubscribes a receiver from all events
|
||||||
|
pub fn (mut s Subscriber) unsubscribe_receiver(receiver voidptr) {
|
||||||
|
s.registry.events = s.registry.events.filter(it.receiver != receiver)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn (mut s Subscriber) subscribe_once(name string, handler EventHandlerFn) {
|
pub fn (mut s Subscriber) subscribe_once(name string, handler EventHandlerFn) {
|
||||||
s.registry.events << EventHandler {
|
s.registry.events << EventHandler{
|
||||||
name: name
|
name: name
|
||||||
handler: handler
|
handler: handler
|
||||||
once: true
|
once: true
|
||||||
|
@ -106,23 +105,19 @@ pub fn (s &Subscriber) is_subscribed(name string) bool {
|
||||||
return s.registry.check_subscriber(name)
|
return s.registry.check_subscriber(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// is_subscribed_method checks whether a receiver was already subscribed for any events
|
||||||
|
pub fn (s &Subscriber) is_subscribed_method(name string, receiver voidptr) bool {
|
||||||
|
return s.registry.events.any(it.name == name && it.receiver == receiver)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn (mut s Subscriber) unsubscribe(name string, handler EventHandlerFn) {
|
pub fn (mut s Subscriber) unsubscribe(name string, handler EventHandlerFn) {
|
||||||
// v := voidptr(handler)
|
// v := voidptr(handler)
|
||||||
for i, event in s.registry.events {
|
s.registry.events = s.registry.events.filter(!(it.name == name && it.handler == handler))
|
||||||
if event.name == name {
|
|
||||||
if event.handler == handler {
|
|
||||||
s.registry.events.delete(i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Registry Methods
|
// Registry Methods
|
||||||
fn (r &Registry) check_subscriber(name string) bool {
|
fn (r &Registry) check_subscriber(name string) bool {
|
||||||
for event in r.events {
|
return r.events.any(it.name == name)
|
||||||
if event.name == name {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,10 @@ struct EventData {
|
||||||
data string
|
data string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct FakeReceiver {
|
||||||
|
ok bool
|
||||||
|
}
|
||||||
|
|
||||||
fn test_eventbus() {
|
fn test_eventbus() {
|
||||||
ev_data := &EventData{'hello'}
|
ev_data := &EventData{'hello'}
|
||||||
mut eb := eventbus.new()
|
mut eb := eventbus.new()
|
||||||
|
@ -21,8 +25,85 @@ fn test_eventbus() {
|
||||||
assert !eb.subscriber.is_subscribed('on_test')
|
assert !eb.subscriber.is_subscribed('on_test')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_subscribe_method() {
|
||||||
|
// Does not really test subscribe_method idinvidually though
|
||||||
|
// given
|
||||||
|
mut eb := eventbus.new()
|
||||||
|
r := FakeReceiver{}
|
||||||
|
|
||||||
|
assert !eb.subscriber.is_subscribed_method('on_test_with_receiver', r)
|
||||||
|
// when
|
||||||
|
eb.subscriber.subscribe_method('on_test_with_receiver', on_test_with_receiver, r)
|
||||||
|
|
||||||
|
// then
|
||||||
|
assert eb.subscriber.is_subscribed_method('on_test_with_receiver', r)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_unsubscribe_method() {
|
||||||
|
// given
|
||||||
|
mut eb := eventbus.new()
|
||||||
|
r := FakeReceiver{}
|
||||||
|
r2 := FakeReceiver{}
|
||||||
|
|
||||||
|
// when
|
||||||
|
eb.subscriber.subscribe_method('on_test_with_receiver', on_test_with_receiver, r)
|
||||||
|
eb.subscriber.subscribe_method('on_test_with_receiver', on_test_with_receiver, r2)
|
||||||
|
eb.subscriber.unsubscribe_method('on_test_with_receiver', r)
|
||||||
|
|
||||||
|
// then
|
||||||
|
assert !eb.subscriber.is_subscribed_method('on_test_with_receiver', r)
|
||||||
|
assert eb.subscriber.is_subscribed_method('on_test_with_receiver', r2)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_publish() {
|
||||||
|
// given
|
||||||
|
ev_data := &EventData{'hello'}
|
||||||
|
mut eb := eventbus.new()
|
||||||
|
|
||||||
|
// when
|
||||||
|
eb.subscriber.subscribe_once('on_test', on_test)
|
||||||
|
eb.subscriber.subscribe_once('on_test', on_test)
|
||||||
|
eb.publish('on_test', eb, ev_data)
|
||||||
|
|
||||||
|
// then
|
||||||
|
assert !eb.subscriber.is_subscribed('on_test')
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_publish_with_receiver() {
|
||||||
|
// given
|
||||||
|
mut eb := eventbus.new()
|
||||||
|
ev_data := &EventData{'hello'}
|
||||||
|
r := FakeReceiver{}
|
||||||
|
|
||||||
|
// when
|
||||||
|
eb.subscriber.subscribe_method('on_test_with_receiver', on_test_with_receiver, r)
|
||||||
|
eb.publish('on_test_with_receiver', eb, ev_data)
|
||||||
|
|
||||||
|
// then asserts are in on_test_with_receiver, don't know how to be sure
|
||||||
|
// that it has been properly called...
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_unsubscribe_reveiver() {
|
||||||
|
// given
|
||||||
|
mut eb := eventbus.new()
|
||||||
|
r := &FakeReceiver{}
|
||||||
|
|
||||||
|
// when
|
||||||
|
eb.subscriber.subscribe_method('on_test_with_receiver', on_test_with_receiver, r)
|
||||||
|
eb.subscriber.subscribe_method('on_test', on_test, r)
|
||||||
|
eb.subscriber.unsubscribe_receiver(r)
|
||||||
|
assert !eb.subscriber.is_subscribed_method('on_test_with_receiver', r)
|
||||||
|
assert !eb.subscriber.is_subscribed_method('on_test', r)
|
||||||
|
}
|
||||||
|
|
||||||
fn on_test(receiver voidptr, ev &EventData, sender voidptr) {
|
fn on_test(receiver voidptr, ev &EventData, sender voidptr) {
|
||||||
assert receiver == 0
|
assert receiver == 0
|
||||||
assert sender != 0
|
assert sender != 0
|
||||||
assert ev.data == 'hello'
|
assert ev.data == 'hello'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_test_with_receiver(receiver &FakeReceiver, ev &EventData, sender voidptr) {
|
||||||
|
assert receiver.ok == false
|
||||||
|
assert sender != 0
|
||||||
|
assert ev.data == 'hello'
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue