Thread Tools Display Modes
01/19/21, 03:47 PM   #1
QuantumPie
AddOn Author - Click to view addons
Join Date: Sep 2019
Posts: 32
How do hooks behave if two addons modify the original?

For the achievement addon I'm developing, I'm hooking into some functions via:
Lua Code:
  1. local orgLayoutAchievements = ACHIEVEMENTS.LayoutAchievements
  2. function ACHIEVEMENTS:LayoutAchievements(achievements)
  3.     addon.achievementPool:ReleaseAllObjects()
  4.     ZO_ClearTable(self.achievementsById)
  5.     ZO_Scroll_ResetToTop(addon.contentList)
  6.  
  7.     local previous
  8.     for i = 1, #achievements do
  9.         local id = achievements[i]
  10.         if ZO_ShouldShowAchievement(self.categoryFilter.filterType, id) then
  11.             local achievement = addon.achievementPool:AcquireObject()
  12.             local baseAchievementId = self:GetBaseAchievementId(id)
  13.             self.achievementsById[baseAchievementId] = achievement
  14.             --  i here is the same as the achievementIndex for the achievement
  15.             achievement:SetIndex(i)
  16.  
  17.             achievement:Show(ZO_GetNextInProgressAchievementInLine(id))
  18.  
  19.             achievement:SetAnchoredToAchievement(previous)
  20.             previous = achievement
  21.         end
  22.     end
  23.  
  24.     orgLayoutAchievements(self, achievements)
  25. end

If a second addon was to hook into this function, how would it behave? I'm assuming whichever one is loaded last becomes the defacto implementation. I initially used ZO_PreHook but for some reason switched to the method above for later hooks. Do both methods behave the same with a 2nd addon hooking into it?
  Reply With Quote
01/19/21, 05:18 PM   #2
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,912
The addons will be loaded from Z (ZOs) to A.
In addition the load order dependes on the defined ## OptionalDependsOn or ## DependsOn tags in all addons and libs (also addons).

In the addons it's important then where you do the hook.
In event_add_on_loaded, somewhere in any addon file in a ddo ... end statement (loaded even before event_add_on_loaded) or later at event_player_activated, or even any other event liek a special crafting event -> 1st call -> apply hook.

This all matters and defines which will be "the first".

If you use Zo_PreHook to hook the vanilla code and do not return true all other addons + vanila code will be also run properly!
If you use SecurePostHook or ZO_PostHook there is no way to suppress the call to the vanilla code before as you are hooking "behind" it.
Still breaking the code there could destroy other SecurePostHooks or ZO_PostHooks which are run after your addon, due to the load order etc. described above.

If you overwrite the vanilla UI code, like you have done above, you replace the original function.
-> In most cases there is no need to do this! Just use the proper hooks provided and watch that your return isn't using true so that following hooks and vanilla code will run as well. Only use the return true if you really want to abort some function on purpose there.
If you have overwritten the function and another addon later hooks into it, it wil hook into your function.
If hooks were already applied to the vanilla function you will take them with you in your call to "originalFunc" (orgLayoutAchievements in your example).
-> I'd change this to a normal ZO_PreHook again if your code above orgLayoutAchievements is the vanilla code. If you need to change variables and values in the original vanilla code, like add another function call within some nested lines, which cannot be done as a prehook before the vanilla code runs, than an overwrite is often necessary).

Depending on WHERE you overwrite something, e.g. in the "base class" like ZO_Smithing, or the created object SMITHING, it might even break other addons as well. e.g. you hook into ZO_Smithing and change values. Others hook into the created object SMITHING (which will be later, after ZO_Smithing) and want to do something which you have changed already -> lua error.
Either all hook the same class OR object, or need to test and talk to each other, change the ## OptionalDependsOn to change the load orders, and so on.

Last edited by Baertram : 01/19/21 at 05:25 PM.
  Reply With Quote

ESOUI » Developer Discussions » Lua/XML Help » How do hooks behave if two addons modify the original?

Thread Tools
Display Modes

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