CallbackHandler-1.0
From WowAce Wiki
CallbackHandler is a back-end utility library that makes it easy for a library to fire its events to interested parties. It removes the need for addons to be aware of e.g. AceEvent.
CallbackHandler should not be a required dependency for addons wanting to use your library. Rather, embed it in your library. CallbackHandler is small enough that a few libraries pulling it in has no real impact. We (the Ace3 core team) would like to simplify the library inclusion process so that usually all you have to do is pull in the one single library you're interested in, rather than having to fullfill several dependencies to make it work.
Contents |
Mixing in the CallbackHandler functions in your library
MyLib.events = MyLib.events or
LibStub("CallbackHandler-1.0"):New(MyLib)
This adds 3 methods to your library:
- MyLib:RegisterEvent("eventName"[, method, [arg]])
- MyLib:UnregisterEvent("eventname")
- MyLib:UnregisterAllEvents()
The "MyLib.events" object is the callback registry itself, which you need to keep track of across library upgrades.
Firing events
Assuming your callback registry is "MyLib.events", firing named events is as easy as:
MyLib.events:Fire("EventName", arg1, arg2, ...)
All arguments supplied to :Fire() are passed to the functions listening to the event.
Advanced uses
Renaming the methods
You can specify your own names for the methods installed by CallbackHandler:
MyLib.events = MyLib.events or
LibStub("CallbackHandler-1.0"):New(MyLib,
"MyRegisterFunc", "MyUnregisterFunc", "MyUnregisterAllFunc" or false)
Giving false as the name for UnregisterAll means that you do not want to give users access to that API at all - it will not be installed.
Tracking events being used
In some cases, it makes sense to know which events are being requested by your users. Perhaps to enable/disable code needed to track them.
CallbackHandler will always call registry:OnUsed() and :OnUnused() when an event starts/stops being used:
function MyLib.events:OnUsed(target, eventname)
-- "target" is == MyLib here
print("Someone just registered for "..eventname.."!")
end
function MyLib.events:OnUnused(target, eventname)
print("Noone wants "..eventname.." any more")
end
"OnUsed" is only called if the event was previously unused. "OnUnused" is only called when the last user unregisters from an event. In other words, you won't see an "OnUnused" unless "OnUsed" has been called for an event. And you won't ever see two "OnUsed" in a row without "OnUnused" in between for an event.
Multiple event registries
As you may or may not know, CallbackHandler is the workhorse of AceEvent. It is used twice in AceEvent: once for in-game events, which cannot be fired by users, and once for "messages", which can be fired by users.
Providing multiple registries in AceEvent was as easy as:
AceEvent.events = AceEvent.events or
LibStub("CallbackHandler-1.0"):New(AceEvent,
"RegisterEvent", "UnregisterEvent", "UnregisterAllEvents")
AceEvent.messages = AceEvent.messages or
LibStub("CallbackHandler-1.0"):New(AceEvent,
"RegisterMessage", "UnregisterMessage", "UnregisterAllMessages")
AceEvent.SendMessage = AceEvent.messages.Fire
Of course, there is also some code in AceEvent to do the actual driving of in-game events (using OnUsed and OnUnused), but this is really the core of it.
User API
The below documentation is automatically pulled in, using the template
{{:CallbackHandler-1.0/User API|RegisterEvent|UnregisterEvent|UnregisterAllEvents}}. Rather than pointing library users here, pull it into your own library documentation - your library users shouldn't even have to know about CallbackHandler! See CallbackHandler-1.0/User API for template usage documentation.
:RegisterEvent()
myAddon:RegisterEvent("eventName"[, method[, arg]])
library.RegisterEvent(myTable, "eventName"[, method[, arg]])
library.RegisterEvent("myAddonId", "eventName"[, method[, arg]])
- "eventName"
- (string) - the name of the event you want to listen to
- method
- (string or function) - which method to call. If string, self["method"] will be called. If left out (nil), self["eventName"] will be called.
- arg
- (optional) - If present (even nil), this value will be passed to the receiving function.
Registrations are always associated with the supplied self. This means that you'll want to embed the library, or do the call like .RegisterEvent(myTable, ...). Note the use of " . " (period) rather than " : " (colon).
If you do not have a sane self table to associate your registrations with, you can substitute it for a string. Note the use of "." rather than ":".
-
library.RegisterEvent("myAddonId", "eventName", ...)
This string variant of a self will not be passed to the receiving function.
Callback arguments
If the method is a plain function, it will be called as:
-
method("eventName", (arguments to the event)) - or, with an arg specified when registering:
-
method(arg, "eventName", (arguments to the event))
If the method is a string (method name), it will be called as:
-
self["method"](self, "eventName", (arguments to the event)) - or, with an arg specified when registering:
-
self["method"](self, arg, "eventName", (arguments to the event))
:UnregisterEvent()
myAddon:UnregisterEvent("eventName")
library.UnregisterEvent(myTable, "eventName")
library.UnregisterEvent("myAddonId", "eventName")
- "eventName"
- the name of the event that you no longer wish to receive.
Note that the supplied self must match the self supplied to :RegisterEvent(), or nothing will be unregistered.
:UnregisterAllEvents()
:UnregisterAllEvents()
library.UnregisterAllEvents("myAddonId", myTable, ...)
UnregisterAllEvents will unregister all events associated with the given self, as well as with additional arguments given.

