WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   Legion Beta archived threads (https://www.wowinterface.com/forums/forumdisplay.php?f=177)
-   -   Hooking a function used for OnUpdate. (https://www.wowinterface.com/forums/showthread.php?t=54036)

Fizzlemizz 07-26-16 05:06 PM

Hooking a function used for OnUpdate.
 
Using the code below, the function called for OnUpdate won't get hooked using hooksecurefunc but will if you change it to HookScript.

hooksecurefunc will work for functions used for other scripts.

I don't believe this was the way it worked previously.

Lua Code:
  1. function SomeDopeyfunc(self)
  2. print("A")
  3. end
  4.  
  5. local f = CreateFrame("Frame", "SomeDopeyFrameName")
  6. f:SetSize(20, 20)
  7. f:SetScript("OnUpdate", SomeDopeyfunc)
  8.  
  9. local function SomeOtherfunc(self)
  10. print(self)
  11. end
  12.  
  13. --SomeDopeyFrameName:HookScript("OnUpdate", SomeOtherfunc)
  14. hooksecurefunc("SomeDopeyfunc", SomeOtherfunc)

Edit: Is this intended? Changing SomeDopeyfunc to a local function I get:
[code]
1x A\A.lua:16: hooksecurefunc(): SomeDopeyfunc is not a function
[C]: in function `hooksecurefunc'
A\A.lua:16: in main chunk

[code]

Resike 07-26-16 06:22 PM

I think you want to do:

Lua Code:
  1. hooksecurefunc(SomeDopeyFrameName, "OnUpdate", function(self, elapsed)
  2.     print(self:GetName(), elapsed)
  3. end)

hooksecurefunc is designed to catch secure but mainly global functions, so thats why it might not be able to handle local ones.

Fizzlemizz 07-26-16 06:26 PM

Quote:

Originally Posted by Resike (Post 317038)
I think you want to do:

Lua Code:
  1. hooksecurefunc(SomeDopeyFrameName, "OnUpdate", function(self, elapsed)
  2.     print(self:GetName(), elapsed)
  3. end)

hooksecurefunc is designed to catch secure but mainly global functions, so thats why it might not be able to handle local funcitons.

I can use the original form to hook a function being used for an OnEvent script without problem. I'm pretty sure it was usable for OnUpdate pre 7.x.

I wasn't sure about the local thing.

SDPhantom 07-26-16 07:44 PM

The syntax is hooksecurefunc([table,]index,function). If table is omitted, _G is assumed. The entire design of the function is to hook another function stored in index of table. This means it has to be accessible from the global namespace or a provided table. hooksecurefunc() doesn't operate on locals and trying to use it on a frame won't necessarily work unless someone is dumb enough to have a dynamic function like this: frame:SetScript("OnUpdate",function(self) self:OnUpdate(); end).

In addition, if any function is directly assigned as a handler, changing it in any way outside of Frame:HookScript() won't update the function pointer used. Meaning the original function as defined would be updated, but the reference given to the frame to use for a handler will still point to the old function instead of your hook.

For example:
Code:

function A() print("A"); end
function B() print("B"); end

local frame=CreateFrame("Frame");
frame:SetScript("OnUpdate",A);

hooksecurefunc("A",B);

From your logic, you're thinking it would print A and B on alternating lines, but you'll only see A bring printed. What hooksecurefunc() is doing in this case is dynamicly creating a 3rd function that runs function A and B, passing the returns along from the first. The pointer to this new function then overwrites the old pointer in the global namespace. The pointer given to the frame for its handler remains unchanged.

The end result is, if you need to hook a script handler, use Frame:HookScript(), that's what it's there for.

Fizzlemizz 07-26-16 08:34 PM

I think I need to reevaluate my test.

Apparently this addon was working pre-7.x hooking the function used by OnUpdate and no longer does after clearing the error by changing line 14 to

Code:

local textDisplay        = self.Text--getglobal(self:GetName().."Text")
Something to ponder while I'm away, Thank you.

SDPhantom 07-26-16 10:33 PM

My guess is they updated the XML.

From:
Code:

<OnUpdate>CastingBarFrame_OnUpdate(self,elapsed)</OnUpdate>
To:
Code:

<OnUpdate function="CastingBarFrame_OnUpdate"/>
The first creates an intermediate function that calls CastingBarFrame_OnUpdate(), the second sets CastingBarFrame_OnUpdate() as the handler. This is why the hook worked pre-7.0.

Lombra 07-27-16 04:26 AM

Didn't realise hooksecurefunc simply replaced the hooked function, but that was easily confirmed.
Code:

local a = print
hooksecurefunc("print", function() end)
print(print == a) -- false


Ketho 07-27-16 05:50 AM

Quote:

Originally Posted by Lombra (Post 317072)
Didn't realise hooksecurefunc simply replaced the hooked function, but that was easily confirmed.


Same, I only found out about that when I tried to see with hooksecurefunc whether RemoveExtraSpaces/RunScript was changed, or pointing to something else
Thought I was going crazy when the reference kept changing after I hooked it... every day you learn something new ><

http://wow.gamepedia.com/API_hooksecurefunc
Quote:

Keep in mind that it actually replaces the original function with a new one (the function reference changes)


All times are GMT -6. The time now is 07:53 PM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2004 - 2022 MMOUI