Appearance
CallbackHandler-1.0
CallbackHandler-1.0 is the small dispatch engine that powers the "callback" and "message" systems across the Ace suite: AceEvent-3.0, AceComm-3.0, AceBucket-3.0, AceDB-3.0's profile callbacks, and AceConfigRegistry-3.0 all build on it. You rarely call it directly, but understanding it explains how those callbacks behave.
It has two sides: addon authors register handlers on a library that exposes CallbackHandler methods, and library authors create a registry to fire events into.
For addon authors
When a library is "powered by CallbackHandler", it exposes registration methods, by convention RegisterCallback, UnregisterCallback, and UnregisterAllCallbacks. These are called with a dot and an explicit first argument (your object, or a string addon id) that identifies you as the owner of the registration:
lua
-- e.g. AceDB exposes these on the db object
self.db.RegisterCallback(self, "OnProfileChanged", "RefreshConfig")
function MyAddon:RefreshConfig(event, ...)
-- event == "OnProfileChanged", followed by any args the library fired
endWhy the dot, and the explicit self
RegisterCallback is not called with :; you pass your self (or an "addonId" string) explicitly as the first argument. CallbackHandler uses it both as the self for method-style handlers and as the key to unregister you later. Calling it as lib:RegisterCallback(...) (passing the library as self) is an error.
How your handler is invoked:
methodas a string → called asself[method](self, event, ...).methodas a function → called asmethod(event, ...).- If you supplied an
arg, it is inserted before the event name:self[method](self, arg, event, ...)/method(arg, event, ...).
The first value your handler receives is always the event name (handy for sharing one handler across several events); the firing library's own arguments follow.
RegisterCallback
method#
lua
obj.RegisterCallback(self, eventname, method?, arg?)Register a handler for an event on a CallbackHandler-powered object. Called with a dot and an explicit self/addon id (see above).
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
self | table | string | Your object (used as the handler's self and as the unregister key), or an "addonId" string when registering a plain function. | |
eventname | string | The event/message to listen for. | |
method (optional) | string | function | A method name on self, or a function reference. Defaults to eventname (i.e. a method named after the event). | |
arg (optional) | any | Optional value passed to the handler before the event name. |
UnregisterCallback
method#
lua
obj.UnregisterCallback(self, eventname)Remove a previously registered handler for eventname.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
self | table | string | The same object/addon id used to register. | |
eventname | string | The event to stop listening for. |
UnregisterAllCallbacks
method#
lua
obj.UnregisterAllCallbacks(self)Remove every callback registered by the given owner. A library may choose not to publish this method.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
self | table | string | The object/addon id whose registrations should all be removed. |
For library authors
Embed the registration API into your library and get back a registry to fire events through.
New
method#
lua
CallbackHandler:New(target, RegisterName?, UnregisterName?, UnregisterAllName?)Create a callback registry and embed RegisterName/UnregisterName/UnregisterAllName onto target.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
target | table | The object to embed the public registration methods into. | |
RegisterName (optional) | string | RegisterCallback | Name of the register method to publish. |
UnregisterName (optional) | string | UnregisterCallback | Name of the unregister method to publish. |
UnregisterAllName (optional) | string | boolean | UnregisterAllCallbacks | Name of the unregister-all method, or false to not publish it. |
Returns
| Type | Description |
|---|---|
table | The registry object (with :Fire, and optional OnUsed/OnUnused hooks you can set). |
Example
lua
local CallbackHandler = LibStub("CallbackHandler-1.0")
local MyLib = {}
MyLib.callbacks = CallbackHandler:New(MyLib)
-- MyLib.RegisterCallback / UnregisterCallback / UnregisterAllCallbacks now existFire
method#
lua
registry:Fire(eventname, ...)Fire an event into the registry, invoking every handler registered for eventname.
Registering or unregistering from inside a handler is safe: CallbackHandler queues the change and applies it once the current dispatch finishes.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
eventname | string | The event/message to dispatch. | |
... | any | Arguments forwarded to every registered handler (after the event name). |
Example
lua
function MyLib:DoThing()
self.callbacks:Fire("OnThingDone", "some", "data")
end
-- a listener's handler receives: (event, "some", "data")Lazy activation hooks
The registry exposes two optional hooks you can assign. They let a library do expensive setup only while something is actually listening; this is how AceEvent only registers a game event with the client while at least one handler wants it:
registry.OnUsed(registry, target, eventname): called wheneventnamegets its first handler.registry.OnUnused(registry, target, eventname): called wheneventnameloses its last handler.
lua
function MyLib.callbacks:OnUsed(target, eventname)
-- start producing eventname (e.g. hook a frame, register a game event)
end
function MyLib.callbacks:OnUnused(target, eventname)
-- stop producing eventname
end