Initial project import
This commit is contained in:
commit
23f2d29e32
11957 files changed
+1754577
No files matched your search
@@ -0,0 +1,154 @@
|
||||
module eventbus
|
||||
|
||||
pub type EventHandlerFn = fn (receiver voidptr, args voidptr, sender voidptr)
|
||||
|
||||
pub struct Publisher[T] {
|
||||
mut:
|
||||
registry &Registry[T] = unsafe { nil }
|
||||
}
|
||||
|
||||
pub struct Subscriber[T] {
|
||||
mut:
|
||||
registry &Registry[T] = unsafe { nil }
|
||||
}
|
||||
|
||||
pub struct Registry[T] {
|
||||
mut:
|
||||
events []EventHandler[T]
|
||||
}
|
||||
|
||||
pub struct EventHandler[T] {
|
||||
name T
|
||||
handler EventHandlerFn = unsafe { nil }
|
||||
receiver voidptr = unsafe { nil }
|
||||
once bool
|
||||
}
|
||||
|
||||
pub struct EventBus[T] {
|
||||
pub mut:
|
||||
registry &Registry[T] = unsafe { nil }
|
||||
publisher &Publisher[T] = unsafe { nil }
|
||||
subscriber &Subscriber[T] = unsafe { nil }
|
||||
}
|
||||
|
||||
// EventBus.new[T] create a new eventbus with event type T.
|
||||
pub fn EventBus.new[T]() &EventBus[T] {
|
||||
registry := &Registry[T]{
|
||||
events: []
|
||||
}
|
||||
return &EventBus[T]{registry, &Publisher[T]{registry}, &Subscriber[T]{registry}}
|
||||
}
|
||||
|
||||
// new[T] create a new eventbus with event type T.
|
||||
pub fn new[T]() &EventBus[T] {
|
||||
registry := &Registry[T]{
|
||||
events: []
|
||||
}
|
||||
return &EventBus[T]{registry, &Publisher[T]{registry}, &Subscriber[T]{registry}}
|
||||
}
|
||||
|
||||
// publish publishes an event with provided Params & name.
|
||||
pub fn (eb &EventBus[T]) publish(name T, sender voidptr, args voidptr) {
|
||||
mut publisher := eb.publisher
|
||||
publisher.publish(name, sender, args)
|
||||
}
|
||||
|
||||
// clear_all clears all subscribers.
|
||||
pub fn (eb &EventBus[T]) clear_all() {
|
||||
mut publisher := eb.publisher
|
||||
publisher.clear_all()
|
||||
}
|
||||
|
||||
// has_subscriber check if a subscriber to an event exists.
|
||||
pub fn (eb &EventBus[T]) has_subscriber(name T) bool {
|
||||
return eb.registry.check_subscriber(name)
|
||||
}
|
||||
|
||||
const dedup_buffer_len = 20
|
||||
|
||||
// publish an event with provided Params & name.
|
||||
fn (mut pb Publisher[T]) publish(name T, sender voidptr, args voidptr) {
|
||||
// println('Publisher.publish(name=${name} sender=${sender} args=${args})')
|
||||
invalid := 0
|
||||
mut handled_receivers := unsafe { [dedup_buffer_len]voidptr{init: &invalid} } // handle duplicate bugs TODO fix properly + perf
|
||||
mut j := 0
|
||||
mut found_onces := 0
|
||||
for event in pb.registry.events {
|
||||
if event.name == name {
|
||||
if event.once {
|
||||
found_onces++
|
||||
}
|
||||
if event.receiver in handled_receivers {
|
||||
continue
|
||||
}
|
||||
event.handler(event.receiver, args, sender)
|
||||
handled_receivers[j] = event.receiver
|
||||
j = (j + 1) % dedup_buffer_len
|
||||
}
|
||||
}
|
||||
if found_onces > 0 {
|
||||
pb.registry.events = pb.registry.events.filter(!(it.name == name && it.once))
|
||||
}
|
||||
}
|
||||
|
||||
// clear_all clear all subscribers.
|
||||
fn (mut p Publisher[T]) clear_all() {
|
||||
p.registry.events.clear()
|
||||
}
|
||||
|
||||
// subscribe subscribe to an event `name`.
|
||||
pub fn (mut s Subscriber[T]) subscribe(name T, handler EventHandlerFn) {
|
||||
s.registry.events << EventHandler[T]{
|
||||
name: name
|
||||
handler: handler
|
||||
}
|
||||
}
|
||||
|
||||
// subscribe_method subscribe to an event `name` and also set the `receiver` as a parameter.
|
||||
pub fn (mut s Subscriber[T]) subscribe_method(name T, handler EventHandlerFn, receiver voidptr) {
|
||||
s.registry.events << EventHandler[T]{
|
||||
name: name
|
||||
handler: handler
|
||||
receiver: receiver
|
||||
}
|
||||
}
|
||||
|
||||
// unsubscribe_method unsubscribe a receiver for only one method.
|
||||
pub fn (mut s Subscriber[T]) unsubscribe_method(name T, 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[T]) unsubscribe_receiver(receiver voidptr) {
|
||||
s.registry.events = s.registry.events.filter(it.receiver != receiver)
|
||||
}
|
||||
|
||||
// subscribe_once subscribe only once to an event `name`.
|
||||
pub fn (mut s Subscriber[T]) subscribe_once(name T, handler EventHandlerFn) {
|
||||
s.registry.events << EventHandler[T]{
|
||||
name: name
|
||||
handler: handler
|
||||
once: true
|
||||
}
|
||||
}
|
||||
|
||||
// is_subscribed check if we are subscribed to an event `name`.
|
||||
pub fn (s &Subscriber[T]) is_subscribed(name T) bool {
|
||||
return s.registry.check_subscriber(name)
|
||||
}
|
||||
|
||||
// is_subscribed_method checks whether a receiver was already subscribed for any events.
|
||||
pub fn (s &Subscriber[T]) is_subscribed_method(name T, receiver voidptr) bool {
|
||||
return s.registry.events.any(it.name == name && it.receiver == receiver)
|
||||
}
|
||||
|
||||
// unsubscribe unsubscribe from an event `name`.
|
||||
pub fn (mut s Subscriber[T]) unsubscribe(name T, handler EventHandlerFn) {
|
||||
// v := voidptr(handler)
|
||||
s.registry.events = s.registry.events.filter(!(it.name == name && it.handler == handler))
|
||||
}
|
||||
|
||||
// Registry Methods
|
||||
fn (r &Registry[T]) check_subscriber(name T) bool {
|
||||
return r.events.any(it.name == name)
|
||||
}
|
||||
Reference in new issue
Block a user