eventbus #
Event Bus
A module to provide eventing capabilities using pub/sub.
API
new[T]()
- create a newEventBus
EventBus.new[T]()
- create a newEventBus
Structs:
EventBus:
publish(name T, sender voidptr, args voidptr)
- publish an event with providedParams & name2.clear_all()
- clear all subscribershas_subscriber(name T)
- check if a subscriber to an event exists
Subscriber:
subscribe(name T, handler EventHandlerFn)
- subscribe to an eventsubscribe_once(name T, handler EventHandlerFn)
- subscribe only once to an eventsubscribe_method(name T, handler EventHandlerFn, receiver voidptr)
- subscribe toan event and also set thereceiver
as a parameter. Since it's not yet possible to send methods as parameters, this is a workaround.4.is_subscribed(name T)
- check if we are subscribed to an eventunsubscribe(name T)
- unsubscribe from an event
Event Handler Signature:
The function given to subscribe
, subscribe_method
and subscribe_once
must match this:
fn cb(receiver voidptr, args voidptr, sender voidptr) {
}
// Since V can map structs to voidptr, this also works
struct ClickEvent {
x int
y int
}
// Example case where publisher sends ClickEvent as args.
fn on_press(receiver voidptr, e &ClickEvent, sender voidptr) {
println(e.x)
// your code here...
}
Usage
For usage across modules check the example.
Note > As a general rule, you will need to subscribe before publishing.
main.v
module main
import eventbus
// initialize it globally
const eb = eventbus.new[string]()
fn main() {
// get a mutable reference to the subscriber
mut sub := eb.subscriber
// subscribe to the 'error' event
sub.subscribe('error', on_error)
// start the work
do_work()
}
// the event handler
fn on_error(receiver voidptr, e &Error, work &Work) {
println('error occurred on ${work.hours}. Error: ${e.message}')
}
work.v
module main
import eventbus
const eb = eventbus.new[string]()
struct Work {
hours int
}
struct AnError {
message string
}
fn do_work() {
work := Work{20}
// get a mutable Params instance & put some data into it
error := &AnError{'Error: no internet connection.'}
// publish the event
eb.publish('error', work, error)
}
Notes:
- Each
EventBus
instance has it's own registry (i.e. there is no global event registryso you can't just subscribe to an event wherever you are.2. EachEventBus
has aSubscriber
instance which will need to be either exposed or you can makesmall public helper functions specific to your module like (onPress
,onError
) and etc.3. Theeventbus
module has some helpers to ease getting/setting of Params(since V doesn't support empty interfaces yet or reflection) so use them (see usage above).
The rationale behind separating Subscriber & Publisher:
This is mainly for security because if publisher & subscriber are both passed around, a client can easily publish events acting as the server. So a client should only be able to use the Subscriber methods.
fn new #
fn new[T]() &EventBus[T]
new[T] create a new eventbus with event type T.
fn EventBus.new #
fn EventBus.new[T]() &EventBus[T]
EventBus.new[T] create a new eventbus with event type T.
fn (EventBus[T]) publish #
fn (eb &EventBus[T]) publish(name T, sender voidptr, args voidptr)
publish publishes an event with provided Params & name.
fn (EventBus[T]) clear_all #
fn (eb &EventBus[T]) clear_all()
clear_all clears all subscribers.
fn (EventBus[T]) has_subscriber #
fn (eb &EventBus[T]) has_subscriber(name T) bool
has_subscriber check if a subscriber to an event exists.
type EventHandlerFn #
type EventHandlerFn = fn (receiver voidptr, args voidptr, sender voidptr)
fn (Subscriber[T]) subscribe #
fn (mut s Subscriber[T]) subscribe(name T, handler EventHandlerFn)
subscribe subscribe to an event name
.
fn (Subscriber[T]) subscribe_method #
fn (mut s Subscriber[T]) subscribe_method(name T, handler EventHandlerFn, receiver voidptr)
subscribe_method subscribe to an event name
and also set the receiver
as a parameter.
fn (Subscriber[T]) unsubscribe_method #
fn (mut s Subscriber[T]) unsubscribe_method(name T, receiver voidptr)
unsubscribe_method unsubscribe a receiver for only one method.
fn (Subscriber[T]) unsubscribe_receiver #
fn (mut s Subscriber[T]) unsubscribe_receiver(receiver voidptr)
unsubscribe_receiver unsubscribes a receiver from all events.
fn (Subscriber[T]) subscribe_once #
fn (mut s Subscriber[T]) subscribe_once(name T, handler EventHandlerFn)
subscribe_once subscribe only once to an event name
.
fn (Subscriber[T]) is_subscribed #
fn (s &Subscriber[T]) is_subscribed(name T) bool
is_subscribed check if we are subscribed to an event name
.
fn (Subscriber[T]) is_subscribed_method #
fn (s &Subscriber[T]) is_subscribed_method(name T, receiver voidptr) bool
is_subscribed_method checks whether a receiver was already subscribed for any events.
fn (Subscriber[T]) unsubscribe #
fn (mut s Subscriber[T]) unsubscribe(name T, handler EventHandlerFn)
unsubscribe unsubscribe from an event name
.
struct EventBus #
struct EventBus[T] {
pub mut:
registry &Registry[T] = unsafe { nil }
publisher &Publisher[T] = unsafe { nil }
subscriber &Subscriber[T] = unsafe { nil }
}
struct Publisher #
struct Publisher[T] {
mut:
registry &Registry[T] = unsafe { nil }
}
struct Subscriber #
struct Subscriber[T] {
mut:
registry &Registry[T] = unsafe { nil }
}