Event listeners must be created from the event manager class. Therefore, you first need to create an event manager. To do this, import the EventManager
class from the MayronEvents
package using the MayronObjects
framework:
local obj = MayronObjects:GetFramework(); ---@type MayronObjects
local C_EventManager = obj:Import("Pkg-MayronEvents.EventManager");
When using MayronObjects, it is conventional to include the C_
prefix for class variables.
You can then create an instance of an event manager from this class:
local eventManager = C_EventManager();
To create event listeners from the event manager, you can use one of the following event manager methods:
- CreateEventListener
- CreateEventListenerWithID
The event listener's SetID
method lets you assign an ID at any point, so the CreateEventListenerWithID
is only a helper method that allows you to skip this step. By assigning an ID to an event listener, you can easily retrieve, trigger, enable, disable, and destroy the listener using its event manager by supply its ID used as a reference.
2.1 Event Listener Callback Functions
Each CreateEventListener
method expects a callback function to be passed to it:
local function myCallback(self, event, customArg1, ...)
print("Event: ", event);
assert(customArg1 == "Hello"); -- will pass
print("Blizzard event args: ", ...);
end
local listener = eventManager:CreateEventListenerByID("MyListener", myCallback);
listener:SetCallbackArgs("Hello");
listener:RegisterEvent("PLAYER_ENTERING_WORLD");
Usually, the callback function would be declared inline with the call to the create method, but for simplicity the code snippet assigns the callback function to the myCallback
local variable and then passes it to the create method.
Line 8 shows how to specify custyom callback arguments to pass to your callback function. The custom arguments are always added after the name of the event (the 2nd parameter) and before the variable argument list of extra event arguments.
Line 9 shows how to register a basic Blizzard event. There are several other methods available for registering event. Below is the full list of methods used to register events (see section 4 for more details for each method):
- RegisterEvent: Register 1 Blizzard event.
- RegisterEvents: A helper method to register multiple Blizzard events.
- RegisterUnitEvent: Register 1 Blizzard unit event with a list of units.
- RegisterUnitEvents: A helper method to register multiple Blizzard unit events for the same list of units passed to this method.
- RegisterCustomEvent: Register a custom (non-Blizzard) addon event.
- RegisterCustomEvents: A helper method to register multiple custom addon events.
There are also several unregister methods:
- UnregisterEvent: Unregisters 1 Blizzard event (can be a unit event).
- UnregisterEvents: A helper method to unregister multiple Blizzard events.
- UnregisterCustomEvent: Unregister a custom (non-Blizzard) addon event.
- UnregisterCustomEvents: A helper metod to unregister multiple custom events.
- UnregisterAllEvents: Unregister all events. By default it will unregister all Blizzard events and custom addon events, but cna be passed
false
to the includeCustomEvents
parameter to only unregister Blizzard events.
2.2 Custom AddOn Events
Unlike Blizzard events that are fired by World of Warcraft, custom addon events must be fired manually by the event manager. The FireCustomEvent
event manager method also accepts a number of custom event arguments, which are sent to each callback function for event listeners who have registered the cutom event. Custom event arguments are included after the list of event listener specific arguments defined using SetCallbackArgs
, as demonstrated in section 2.1.
local listener;
local function callback(self, event, customArg1, eventArg1, eventArg2)
-- each of these will pass:
assert(self == listener);
assert(event == "MY_CUSTOM_EVENT");
assert(customArg1 == "Hello");
assert(eventArg1 == "Foo");
assert(eventArg1 == "Bar");
end
listener = eventManager:CreateEventListener(callback);
listener:SetCallbackArgs("Hello");
listener:RegisterCustomEvent("MY_CUSTOM_EVENT");
-- Fire the custom event from the manager:
eventManager:FireCustomEvent("MY_CUSTOM_EVENT", "Foo", "Bar");
The above code snippet shows how to pass custom event arguments to each event listener's callback function after their own custom arguments. You cannot register a custom event using RegisterEvent
as this is for Blizzard-only events to be registered with a Blizzard frame. Custom events cannot be registered with a frame as this would result in an "Unknown event name" Lua error.
Similarly, you cannot fire Blizzard events manually, using FireCustomEvent
as this would potentially cause addon bugs to occur by tricking addons into believing that a specific Blizzard event has fired. However, you can execute the callback function manually by using one of the following trigger methods. The only difference is that the event
parameter will be set to nil
and the World of Warcraft API will not be able to provide the usual event arguments:
- TriggerEventListenerByID: Reference the event listener using its ID to execute its callback function.
- TriggerEventListener: Pass the event listener object directly to this method to execute its callback function.
Each of these trigger methods also accepts an optional list of arguments to be passed to the targetted event listener's callback function, as shown below:
local function callback(self, event, message)
-- triggering it manually will set this to nil.
-- because no event was fired.
assert(event == nil);
assert(message = "Triggered Manually");
end
local listener = eventManager:CreateEventListenerWithID(
"MyEventListener", callback);
local message = "Triggered Manually";
-- both of these will execute the callback function:
eventManager:TriggerEventListener(listener, message);
eventManager:TriggerEventListenerByID("MyEventListener", message);
2.3 Enabling, Disabling, and Destroying Event Listeners
In addition to being able to trigger the event listener's callback function using the ID as a reference, you can also use this ID to enable, disable, and destroy the event listener. By disabling an event listener, even if one of its registered events fires, the event manager will not locate and trigger its callback function. By default, the event listener will be enabled and so you do not need to manually enable it.
Unlike a disabled event listener, a destoryed event listener can never be re-enabled. You can not create an event listener with the same ID as another event listener already registered with the targetted event manager unless the original event listener was destroyed. Therefore, iof you ever need to "re-enable" a destroyed event listener, you would need to recreate it with the same ID and callback function. It is much simpler to simply disable and re-enable the same event listener rather than destroying it and recreating it. You should only destroy an event listener if it should never execute its callback function again.
Sometimes, callback functions should only ever execute once. For these typical scenarios, you would unregister the event straight after it executes. You can still do this, but a better solution would be to destroy the event listener, which also unregisters all of its events during the destruction process:
local listener = eventManager:CreateEventListener(function(self)
print("Hello, World");
-- destroys the event listener and unregisters all of its events
-- Ensures the callback function will never execute again
self:Destroy();
end);
listener:RegisterEvent("PLAYER_ENTERING_WORLD");
You can also mark the listener to be executed only once. If marked as "execute once", MayronEvents will automatically destroy it for you, which achieves the same results as the previous code snippet:
local listener = eventManager:CreateEventListener(function(self)
print("Hello, World");
end);
listener:RegisterEvent("PLAYER_ENTERING_WORLD");
-- destroys event listener after the callback functions first execution:
listener:SetExecuteOnce(true);