Events
Kiwi has a built-in event bus. Code registers handlers for named events with on, and other code triggers them with emit. The two sides don’t need to know about each other, which makes events a good way to decouple parts of a program.
Handling and emitting
Section titled “Handling and emitting”on "user.login" with (user) do println "Welcome back, ${user["name"]}!"end
emit "user.login" ({name: "Ada"}) # Welcome back, Ada!on "event" do ... endregisters a handler with no parameters.on "event" with (a, b) do ... endregisters a handler that receives arguments.emit "event" (arg1, arg2)runs every matching handler with those arguments. Leave the arguments off to emit without any.
Any number of handlers can listen for the same event. emit returns a list of their return values:
on "price" with (amount) do amount * 1.2end
on "price" with (amount) do amount * 0.9end
println emit "price" (100) # [120, 90]One-time handlers
Section titled “One-time handlers”once registers a handler that runs on the first matching emit only:
once "ready" do println "initialized"end
emit "ready" # initializedemit "ready" # (nothing)Priorities
Section titled “Priorities”An integer after the event name sets a handler’s priority. Higher priorities run first; the default is 0. Handlers with equal priority run in the order they were registered.
on "request" do println "handle"end
on "request", 10 do println "authenticate"end
emit "request"# authenticate# handleWildcards
Section titled “Wildcards”* in an event name matches any text within one dot-separated segment.
on "user.*" with (name) do println "user event: ${name}"end
on "*.error" with (message) do println "error: ${message}"end
emit "user.login" ("ada") # user event: adaemit "db.error" ("timeout") # error: timeoutemit "user.profile.updated" ("ada") # (no match: * doesn't span dots)Removing handlers
Section titled “Removing handlers”off "event" removes every handler registered under that name. To remove one handler, register it as a variable and pass it to off:
log_it = do (x) => println "got ${x}"
on "data" (log_it)emit "data" (1) # got 1
off "data" (log_it)emit "data" (2) # (nothing)Errors in handlers
Section titled “Errors in handlers”If a handler throws, the remaining handlers still run. Afterwards, emit throws a single EventError describing what failed.
on "tick" do throw "broken handler"end
on "tick" do println "still runs"end
try emit "tick"catch e println e["error"] # EventError println e["message"] # Event handler error (tick): broken handlerend