Thread Tools Display Modes
05/25/14, 06:32 PM   #1
lyravega
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 93
Event Help Needed

Hello. I was trying to come up with a way to disable some of the features in my little add-on whenever the user is in Cyrodiil.

In my add-on, I register the events IF they are selected, otherwise they don't register. So basically, my RegisterEvents() function has if statements in it. The event "EVENT_ADDON_LOADED" triggers an Initialize() function, which in turn runs this RegisterEvents() function. This event is then unregistered later on.

As far as I can tell, whenever the UI is reloaded, game basically "cleans" itself, and runs these initialize functions and such all over again. However, if the map has changed (you see a loading screen that is not caused by reloadUI so to speak), this is not the case. So I was trying to find a way to make this happen.

I know I can put a check in the functions, but that means less efficiency; less performance as it checks whether or not you are in Cyrodiil everytime. That is why I was trying to put this check in the RegisterEvents() function. However it only checks when the add-on is loaded or UI is reloaded and leaves map changes / loading screens alone.

Is it wise to register events with "EVENT_PLAYER_ACTIVATED"? I am asking this as it may be of help to me. Other suggestions are also welcome. Aim is to keep the actual function codes short and/or efficient, and avoiding registering any event if it is not desired.
  Reply With Quote
05/25/14, 08:17 PM   #2
Garkin
 
Garkin's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 832
So you use something like custom events (callback object) and which functions are registered to certain event is based on player location? It sounds interesting.

I have tested which events occurs when you enter/leave campaign and it seems that mentioned "EVENT_PLAYER_ACTIVATED" is the best choice. There is no campaign event that you can use and "EVENT_ZONE_CHANGED" is triggered way too often (for every point of interest on the map).

To find out if you are in campaign I'd probably use:
Lua Code:
  1. if GetCurrentCampaignId() ~= 0 then
  2.    d("You are in Cyrodiil.")
  3. end
  Reply With Quote
05/25/14, 09:22 PM   #3
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 648
EVENT_PLAYER_ACTIVATED fires after all of the EVENT_ADDON_LOADED events at login/reload. It also fires for every loading screen. (It is the equivalent of WoW's "PLAYER_ENTERING_WORLD" event.)

There is nothing wrong with using this event, especially if you want to check the value of something after each loading screen.
  Reply With Quote
05/26/14, 12:27 AM   #4
lyravega
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 93
Thanks for the replies. I am using this API function: "IsPlayerInAvAWorld()". I don't know if this returns true for anywhere else than Cyrodiil, I don't think so.

Right now I decided to use "EVENT_PLAYER_ACTIVATED" to register some other events; it will check the function above (IsPlayerInAvAWorld) and the user's choice (whether or not to have some features on or off in Cyrodiil), then register the events if they haven't been registered, or unregister them if they have been registered. Otherwise, I'll have to do the same check in the handler functions, which I'm trying to avoid (why do it over and over instead of doing it once)

Something like this (do not mind the order):
Lua Code:
  1. EVENT_MANAGER:RegisterForEvent( "QB" , EVENT_ADD_ON_LOADED , QB_Initialize )
  2.  
  3. local function QB_Initialize()
  4. ...
  5. EVENT_MANAGER:RegisterForEvent( "QB" , EVENT_PLAYER_ACTIVATED , QB_Cyrodiil )
  6. end
  7.  
  8. local function QB_Cyrodiil()
  9. if IsPlayerInAvAWorld()
  10. and QB_DisableFeaturesInCyrodiil
  11. and QB_EventsRegisteredBefore
  12. then UnregisterEvents()
  13. elseif not QB_EventsRegisteredBefore
  14. then RegisterEvents()
  15. else d("DERP, call 911") end
  16. end

I'm thinking this would suffice. Instead of doing the if-checks in the handler functions everytime their events fire, I'll be doing this check whenever "EVENT_PLAYER_ACTIVATED" fires. Wish there were two events called as "EVENT_CAMPAIGN_JOINED" and "EVENT_CAMPAIGN_LEFT" or something similar, that way I could save even more if-checks. Actually, going to add it to the wish list, who knows.

Meanwhile, can I create such a custom event? (Garkin and Seerah, you may now remember my name as I've asked you two how to create custom events, thanks to your helps but I still have no clue for some reason )
  Reply With Quote
05/26/14, 01:51 AM   #5
Wobin
 
Wobin's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 78
If all you're doing is registering and unregistering event handlers, don't stress the EVENT_PLAYER_ACTIVATED repetitiveness. It's definitely not fired as often as an OnUpdate, and isn't too hard on the system in any sense of the matter.
  Reply With Quote
05/26/14, 05:46 AM   #6
Garkin
 
Garkin's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 832
Originally Posted by lyravega View Post
Meanwhile, can I create such a custom event? (Garkin and Seerah, you may now remember my name as I've asked you two how to create custom events, thanks to your helps but I still have no clue for some reason )
You can create something like "EVENT_CAMPAIGN_JOINED"/"EVENT_CAMPAIGN_LEFT". But it is more like function for library, so other addons/objects can listen to that event too.

wiki: How do I generate my own "events" in Lua?

If you want to use global object for events, use CALLBACK_MANAGER. If you want to create your own callback object use yourObject = ZO_CallbackObject:New()
Methods you can use:
Lua Code:
  1. object:RegisterCallback(eventName, callback, arg)
  2. object:UnregisterCallback(eventName, callback)
  3. object:FireCallbacks(eventName, ...)

A good example of callback object is ingame scene. Every time when scene changes its state (SCENE_SHOWN, SCENE_HIDDEN, SCENE_SHOWING, SCENE_HIDING), custom event "StateChange" is fired:
Lua Code:
  1. scene:FireCallbacks("StateChange", oldState, newState)
You can register for that event to do something in your addon:
Lua Code:
  1. scene = SCENE_MANAGER:GetScene("worldMap")
  2. scene:RegisterCallback("StateChange",
  3.    function(oldState, newState)
  4.       if(newState == SCENE_SHOWING) then
  5.          MyAddon:RefreshData()
  6.       end
  7.    end)

Another good example could be inventory. There is just one global event "EVENT_INVENTORY_SINGLE_SLOT_UPDATE" for all inventory types (worn, backpack, bank, guildbank, buyback). All objects working with any inventory needs to do the same check over and over. Inventory manager listents to the event and then using the callback it passes processed information to other objects, so they do not need to that again - eg.:
Lua Code:
  1. CALLBACK_MANAGER:FireCallbacks("BackpackSlotUpdate", slotIndex)
  2. CALLBACK_MANAGER:FireCallbacks("InventorySlotUpdate", GetControl(slot.slotControl, "Button"))
  Reply With Quote
05/26/14, 06:11 PM   #7
Xrystal
caritas omnia vincit
 
Xrystal's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 369
Wow, thanks Garkin. I totally missed this post and just assumed the CallbackManager was for accessing ESO's built in functions etc. Didn't realise it is how you can generate your own events. Will have to see if it is something that can be utilised in gatherer to improve its interaction functionality, which is still glitching out if the mouse moves at the wrong millisecond rofl.

Originally Posted by Garkin View Post
You can create something like "EVENT_CAMPAIGN_JOINED"/"EVENT_CAMPAIGN_LEFT". But it is more like function for library, so other addons/objects can listen to that event too.

wiki: How do I generate my own "events" in Lua?

If you want to use global object for events, use CALLBACK_MANAGER. If you want to create your own callback object use yourObject = ZO_CallbackObject:New()
Methods you can use:
Lua Code:
  1. object:RegisterCallback(eventName, callback, arg)
  2. object:UnregisterCallback(eventName, callback)
  3. object:FireCallbacks(eventName, ...)

A good example of callback object is ingame scene. Every time when scene changes its state (SCENE_SHOWN, SCENE_HIDDEN, SCENE_SHOWING, SCENE_HIDING), custom event "StateChange" is fired:
Lua Code:
  1. scene:FireCallbacks("StateChange", oldState, newState)
You can register for that event to do something in your addon:
Lua Code:
  1. scene = SCENE_MANAGER:GetScene("worldMap")
  2. scene:RegisterCallback("StateChange",
  3.    function(oldState, newState)
  4.       if(newState == SCENE_SHOWING) then
  5.          MyAddon:RefreshData()
  6.       end
  7.    end)

Another good example could be inventory. There is just one global event "EVENT_INVENTORY_SINGLE_SLOT_UPDATE" for all inventory types (worn, backpack, bank, guildbank, buyback). All objects working with any inventory needs to do the same check over and over. Inventory manager listents to the event and then using the callback it passes processed information to other objects, so they do not need to that again - eg.:
Lua Code:
  1. CALLBACK_MANAGER:FireCallbacks("BackpackSlotUpdate", slotIndex)
  2. CALLBACK_MANAGER:FireCallbacks("InventorySlotUpdate", GetControl(slot.slotControl, "Button"))
  Reply With Quote
05/26/14, 10:36 AM   #8
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 648
Originally Posted by lyravega;847
[Highlight="Lua"
EVENT_MANAGER:RegisterForEvent( "QB" , EVENT_ADD_ON_LOADED , QB_Initialize )[/highlight]
The first parameter for RegisterForEvent is supposed to be a unique identifier. "QB" is not unique.

And, yes, for custom "events" you want callbacks. So follow what Garkin said above.
  Reply With Quote
05/26/14, 01:34 PM   #9
Garkin
 
Garkin's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 832
Originally Posted by Seerah View Post
The first parameter for RegisterForEvent is supposed to be a unique identifier. "QB" is not unique.
The first parameter is supposed to be unique per event. If you are registering for different events, you can use the same identifier.
  Reply With Quote

ESOUI » Developer Discussions » General Authoring Discussion » Event Help Needed


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off