Skip to content

eventbus #

Event Bus

A module to provide eventing capabilities using pub/sub.


  1. new() - create a new EventBus



  1. publish(name string, sender voidptr, args voidptr) - publish an event with provided Params & name
  2. clear_all() - clear all subscribers
  3. has_subscriber(name string) - check if a subscriber to an event exists


  1. subscribe(name string, handler EventHandlerFn) - subscribe to an event
  2. subscribe_once(name string, handler EventHandlerFn) - subscribe only once to an event
  3. subscribe_method(name string, handler EventHandlerFn, receiver voidptr) - subscribe to an event and also set the receiver as a parameter. Since it's not yet possible to send methods as parameters, this is a workaround.
  4. is_subscribed(name string) - check if we are subscribed to an event
  5. unsubscribe(name string) - 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) {
    // your code here...


For usage across modules check the example.

Note As a general rule, you will need to subscribe before publishing.


module main

import eventbus

// initialize it globally
const (
    eb =

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

// the event handler
fn on_error(receiver voidptr, e &Error, work &Work) {
    println('error occurred on ${work.hours}. Error: ${e.message}')


module main

import eventbus

const eb =

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)


  1. Each EventBus instance has it's own registry (i.e. there is no global event registry so you can't just subscribe to an event wherever you are.
  2. Each EventBus has a Subscriber instance which will need to be either exposed or you can make small public helper functions specific to your module like (onPress, onError) and etc.
  3. The eventbus 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() &EventBus

type EventHandlerFn #

type EventHandlerFn = fn (receiver voidptr, args voidptr, sender voidptr)

struct EventBus #

struct EventBus {
pub mut:
	registry   &Registry   = unsafe { nil }
	publisher  &Publisher  = unsafe { nil }
	subscriber &Subscriber = unsafe { nil }

fn (EventBus) publish #

fn (eb &EventBus) publish(name string, sender voidptr, args voidptr)

EventBus Methods

fn (EventBus) clear_all #

fn (eb &EventBus) clear_all()

fn (EventBus) has_subscriber #

fn (eb &EventBus) has_subscriber(name string) bool

struct Publisher #

struct Publisher {
	registry &Registry = unsafe { nil }

struct Subscriber #

struct Subscriber {
	registry &Registry = unsafe { nil }

fn (Subscriber) subscribe #

fn (mut s Subscriber) subscribe(name string, handler EventHandlerFn)

Subscriber Methods

fn (Subscriber) subscribe_method #

fn (mut s Subscriber) subscribe_method(name string, handler EventHandlerFn, receiver voidptr)

fn (Subscriber) unsubscribe_method #

fn (mut s Subscriber) unsubscribe_method(name string, receiver voidptr)

unsubscribe_method unsubscribe a receiver for only one method

fn (Subscriber) unsubscribe_receiver #

fn (mut s Subscriber) unsubscribe_receiver(receiver voidptr)

unsubscribe_receiver unsubscribes a receiver from all events

fn (Subscriber) subscribe_once #

fn (mut s Subscriber) subscribe_once(name string, handler EventHandlerFn)

fn (Subscriber) is_subscribed #

fn (s &Subscriber) is_subscribed(name string) bool

fn (Subscriber) is_subscribed_method #

fn (s &Subscriber) is_subscribed_method(name string, receiver voidptr) bool

is_subscribed_method checks whether a receiver was already subscribed for any events

fn (Subscriber) unsubscribe #

fn (mut s Subscriber) unsubscribe(name string, handler EventHandlerFn)