-
Posted by patrickbateman on Tue, 01 Sep 2009 12:31:26
Hello everyone. I have a situation similar to this example:
function AddonName_SendChatMessage(msg, system, language, channel) --Your 'before' code here SavedSendChatMessage(msg, system, language, channel); --Your 'after' code here end local SavedSendChatMessage = SendChatMessage; SendChatMessage = AddonName_SendChatMessage;
My issue is that the equivalent in my case of the old function SendChatMessage is defined like:
function Mod:SendChatMsg()
Simply changing SendChatMessage with Mod:SendChatMsg doesn't work. I tried various combinations, like Mod.SendChatMsg etc, to no avail.
Can anyone help me?
-
Posted by jnwhiteh on Tue, 01 Sep 2009 12:36:08
It would help if you could explain what you're trying to accomplish. Hooking functions is something to be avoided at all costs, especially with a complete overwriting hook like you're using here. Could you please provide more information (not code) about what you're trying to do?
-
Posted by patrickbateman on Tue, 01 Sep 2009 12:52:46
Sure. I have my addon that computes (and re-computes) some values when the event
PLAYER_EQUIPMENT_CHANGED
is called (my addon has registered to it ofc).Now, I want to add that same feature to another mod, an in game dressing room mod so to speak. Obviously that mod doesn't trigger
PLAYER_EQUIPMENT_CHANGED
, so I need to post hook the re-evaluation of my addon to the function that that mod calls when you select a new piece of equipment. -
Posted by jnwhiteh on Tue, 01 Sep 2009 12:56:24
Your best bet is getting in touch with the other mod author, or just use securehookfunc to do the post-hook without replacing anything. In short, your mod should have as little effect on the rest of the game as possible. If you are currently replacing an API function with your own version, that is "bad". If you're replacing another addon's function, that is also bad.
The integration should be possible without hooking like this, whether that means setting up a post hook using securehookfunc, or talking to the addon author about exposing a callback or other function.
Let me know if that doesn't make sense.
-
Posted by patrickbateman on Tue, 01 Sep 2009 13:08:59
I'm still having the same issue with the : though.
Take this example:
local lastCompanionType, lastCompanionIndex; local function postHook(typeID, index) lastCompanionType, lastCompanionIndex = typeID, index; end hooksecurefunc("PickupCompanion", postHook);
How would that become if PickupCompanion was defined something like this
function Pickup:Companion() ... end
-
Posted by jnwhiteh on Tue, 01 Sep 2009 13:21:14
If you're using hooksecurefunc, you'd do:
hooksecurefunc(Pickup, "Companion")
If you're replacing the function directly, you'd do
local old = Pickup.Companion function Pickup.Companion(...) -- Do pre stuff return old(Pickup, ...) end
Doing hooks on your own is really difficult to get right. For example, if you wanted to do something after the original function is called you would need to do something more complex like this:
local niltbl = {} local function capture(...) local data = {} for i = 1, select("#", ...) do local item = select(i, ...) if type(item) == "nil" then data[i] = niltbl else data[i] = item end end return data end local function release_helper(item, ...) if item == niltbl then item = nil end if select("#", ...) == 0 then return item else return item, release_helper(...) end end local function release(data) return release_helper(unpack(data)) end
Then finally we could do:
local old = Pickup.Companion function Pickup.Companion(...) -- Do pre stuff local results = capture(old(Pickup, ...)) -- Do post stuff return release(results) end
Hope that all makes sense.
-
Posted by patrickbateman on Tue, 01 Sep 2009 13:28:17
Thanks, I'll spend some thing thinking and trying before I get back to you with a stupid question.
P.
EDIT: this worked out properly
hooksecurefunc(Pickup, "Companion", test);
-
Posted by jnwhiteh on Tue, 01 Sep 2009 13:29:34
There are no stupid questions here, I promise! If you're using securehookfunc() you don't have to worry about any of the stuff that I mentioned at the end of the post. All those issues are thrown out the window, which is nice!
-
Posted by patrickbateman on Tue, 01 Sep 2009 13:37:49
I'd say that I could settle with the securehook solution. Since I like to understand the problem a little more though, I'll try to make the other solution work. Just one thing:
local old = Pickup.Companion function Pickup.Companion(...) -- Do pre stuff local results = capture(old(Pickup, ...)) -- Do post stuff return release(results) end
What if the original function
function Pickup:Companion() ... end
has no return values, it just sets something on a widget for example. Do I still need to do all that code that you've posted? My idea was more like:
local old = Pickup.Companion function Pickup.Companion(...) old() -- Do post stuff end
-
Posted by jnwhiteh on Tue, 01 Sep 2009 13:41:35
-
Posted by patrickbateman on Tue, 01 Sep 2009 13:45:55
Nevermind, I got it right.
local old = Pickup.Companion; function Pickup:Companion(...) old(self, ...); out("done!") end
Thanks a lot for the help! (I got it after a couple more tries, had to remember that since the original was defined as
Pickup:Companion()
I had to call out(self, ...), without self it didn't work. )