Thread Tools Display Modes
09-06-08, 03:23 PM   #1
acapela
A Cobalt Mageweaver
AddOn Author - Click to view addons
Join Date: Feb 2007
Posts: 241
Hook infinite loop?

posted this over at WoWAce as well... very confusing (to me ). hopefully someone here can help. so...

bear with me. this is all black magic to me (i understand the theory, but my practice is very very shaky). i am working with the addon "Aloft" (nameplate mod, heavily modularized), pulled off WoWAce.

the addon otherwise seems to "work", but in trying to figure out some flow of control, i added some tracing to a module, and things ran amok. i have simplified the code a few lines at a time, until it equates to the example below, and the problem persists.

so, the module is declared fairly simply:

local AloftModule = Aloft:NewModule("AloftModule", "AceEvent-2.0", "AceHook-2.1")
there is a hook function basically like this:

function AloftModule:UpdateMethod(frame)
ChatFrame7:AddMessage("enter")
self.hooks[this]["OnUpdate"](this)
ChatFrame7:AddMessage("exit")
end
it is being hooked (in the module, during module initialization) as follows:

ChatFrame7:AddMessage("hook OnUpdate")
self:HookScript(someframe, "OnUpdate", "UpdateMethod")
ChatFrame7:AddMessage("hook OnUpdate complete")
my results (to ChatFrame7) consist of what appears to be an infinite loop:

hook OnUpdate
enter
exit
enter
exit
enter
exit
...
i have done a "tostring(frame)" in these diagnostics, and the same pointer value (i.e. the same frame) is involved throughout. i have also commented out the invocation to "self.hooks[this]["OnUpdate"](this)". this being Aloft, the frame involved is a nameplate frame (specifically, the underlying nameplate frame supplied by the WoW client... this is in the process of trying to plug Aloft into these underlying nameplate frames).

it really looks like a single call to AceHook-2.1:HookScript() churns forever.

i hope i am missing something that is obvious to others, and that this has a simple resolution (whether i understand it or not :-)).

thanks in advice for any advice.
  Reply With Quote
09-06-08, 03:33 PM   #2
Tristanian
Andúril
Premium Member
AddOn Author - Click to view addons
Join Date: Nov 2007
Posts: 279
Your hook seems to be working fine, however since, to the best of my knowledge, OnUpdate script handlers are being called on every frame, your hook is being called in a similar manner, that's the reason you are getting "enter", "exit" all the time. What worries me though is where is the chat message "hook OnUpdate complete" It would also be good if you were more clear on why you are hooking an OnUpdate script in the first place, what is it that you are trying to accomplish.

Oh and btw, I'm not really sure if not calling the original function (the line you commented out) will provide meaningful results, if you want to discover how that function works in the first place.
  Reply With Quote
09-06-08, 04:32 PM   #3
acapela
A Cobalt Mageweaver
AddOn Author - Click to view addons
Join Date: Feb 2007
Posts: 241
Originally Posted by Tristanian View Post
...what is it that you are trying to accomplish.

Oh and btw, I'm not really sure if not calling the original function (the line you commented out) will provide meaningful results, if you want to discover how that function works in the first place.
in this case, it is the Aloft "Alpha" module... when a nameplate frame fires an OnUpdate event, the Aloft "Alpha" hook is called, and it adjusts the alpha of the nameplate frame to a user-configured value (based on whether the nameplate's unit is selected as a target, etc). note that code that actually adjusts the frame alpha is commented out, in fact all that exists are my calls to ChatFrame7:AddMessage().

calling the original function is fine. i can leave that in, with the same results.

so, i inserted a "ChatFrame7:AddMessage("stack:\n" .. debugstack(1, 4, 4))". as well... and i get the following, infinitely (on top of my original ChatFrame7:Addmessage() calls:

enter table: 1D7C28F8
stack:
Interface\AddOns\Aloft\Modules\Alpha.lua:110: in function <Interface\AddOns\Aloft\Modules\Alpha.lua:103>
(tail call): ?
exit
line 103 is the first line of the declaration of the function passed as the handler to AceHook-2.1:HookScript(). line 110 is my call to debugstack(). the first line comes as the result of a ChatFrame7:AddMessage("enter " .. tostring(frame)).

i have elided the timestamps, but i ran this for minutes, and watched it (as the seconds in the timestamp output ticked by). the output never changed. the call stack is identical, "infinitely" (hence presumably not tail recursion?). the nameplate frame pointer value received as argument never changes (according to tostring()).

yes, nameplates might reasonably expect to receive a certain volume of OnUpdate events... hold on a moment... based on the timestamps, these events are arriving at my chosen nameplate frame at a rate of 30-31 a second...

i am completely ignorant of what i should expect here, but this seems a very suspicious number. it would seem to be excessive, but maybe the WoW client does this on purpose?

anyway, i could live with this... if i needed to, i could easily throttle these events, only do my associated processing 5 times a second or whatever.

so, maybe the question is: would 30 OnUpdate events per second be reasonable for something like a nameplate frame (i.e. the underlying Blizzard nameplate frame, which is what Aloft plugs everything into)? another question: is there a better event to use (less "intensive") than "OnUpdate"? i will rummage around and see if i can find some documentation...

Last edited by acapela : 09-06-08 at 04:43 PM.
  Reply With Quote
09-06-08, 05:30 PM   #4
Tristanian
Andúril
Premium Member
AddOn Author - Click to view addons
Join Date: Nov 2007
Posts: 279
Why would you need to set the alpha on a frame 30 times in a second and not just once (let's say OnShow or whenever a condition is met, not necessarily an event). I'm not that much familiar with Blizzard's nameplates, do they use the same frame for every unit (or maybe the same template) ? But to answer your question, it does sound excessive yes.
  Reply With Quote
09-06-08, 07:03 PM   #5
acapela
A Cobalt Mageweaver
AddOn Author - Click to view addons
Join Date: Feb 2007
Posts: 241
Originally Posted by Tristanian View Post
Why would you need to set the alpha on a frame 30 times in a second and not just once (let's say OnShow or whenever a condition is met, not necessarily an event). I'm not that much familiar with Blizzard's nameplates, do they use the same frame for every unit (or maybe the same template) ? But to answer your question, it does sound excessive yes.
i will brain dump on this in case someone else runs into the problem someday.

this issue of "why" was indeed one of my questions. this is "legacy" Aloft functionality that i am trying to understand (along with the general frame lifecycles for these underlying Blizzard nameplates, which among other things apparently fire OnShow and OnHide events at times that don't seem to correspond to when they actually become visible as healthbars, if the events fire at all). with Aloft you can set your target's nameplate at one alpha, non-target nameplates at another alpha, etc. i find the feature useful as an end-user, but it is has been problematic as an addon implementor.

as for "the same frame": Blizzard supplies (by default) a dedicated nameplate frame per unit (actually, a healthbar and a castbar, both, associatied with a parent nameplate frame). Aloft re-uses these nameplate frames (mines them out of the Worldframe "children", among other things), and then tweaks them (in terms of texture/color/etc), and adds things (text/event-driven mana bar/etc; myself, i have been working on threat bars). however, Blizzard retains control over their fundamental visibility.

i did some experimenting, with a throttle on this alpha functionality. looks like Blizzard also wants to control the alpha of these underlying nameplate frames. it sets alpha on them effectively as a precondition on every OnUpdate event (as an impending event on the underlying nameplate frame). if you don't override alpha using Aloft, the OnUpdate events are just never hooked, and nothing happens, you get Blizzard's default alpha. if you do override alpha with Aloft, and then you try to throttle Aloft's alpha processing, you get an annoying flicker in the nameplate frames (as Blizzard sets the alpha 30 times a second, and Aloft resets it 15 times a second, or whatever). this becomes increasingly (and very rapidly) apparent the greater the throttle interval you apply (i implemented a slider and fiddled it in realtime).

(these nameplates as Blizzard implements them almost seem like an afterthought... definitely not a full-fledged subsystem designed to permit direct customization. Aloft jumps through all sorts of hoops.)

so basically, yes, i guess you have to (re)set alpha 30 times a second .

Aloft's alpha feature can be disabled, though, which i expect would save a fair bit of overhead. i should benchmark with and without, in a busy environment, and try to quantify that.

anyway, thanks for at least thinking about the problem. i appreciate it.
  Reply With Quote
09-06-08, 07:41 PM   #6
Tristanian
Andúril
Premium Member
AddOn Author - Click to view addons
Join Date: Nov 2007
Posts: 279
"it sets alpha on them effectively as a precondition on every OnUpdate event (as an impending event on the underlying nameplate frame)."

That's what I was afraid of. It seems to me you have 2 choices. Either accept the fact that Blizzy is going to maintain control over the parent frame and just hook its OnUpdate to override the alpha with your setting (basically how it works now) OR unfortunately (since the current implementation can be too "expensive" CPU wise), hide the Blizzard parent frame, create your own nameplate frame and set its properties as your leisure without having to worry that someone will override it (unless obviously he is using another addon that offers similar functionality).
  Reply With Quote
09-07-08, 08:26 AM   #7
acapela
A Cobalt Mageweaver
AddOn Author - Click to view addons
Join Date: Feb 2007
Posts: 241
Originally Posted by Tristanian View Post
That's what I was afraid of.
fortunately, Aloft permits the user to simply disable this alpha override completely, which unhooks the OnUpdate event completely and enables the default Blizzard behavior (i.e. no additional overhead from the addon). so, flip a few options and this whole weird mess goes away completely.

as i said, i want to benchmark with this Aloft alpha stuff turned on, and again turned off, and see how expensive it is. at least then i can put some notes in my README.txt that will inform the user about the pitfalls of use of that particular part of Aloft.

i have always used this alpha option, and have benchmarked other stuff while Aloft was running, and never noticed Aloft on the resulting list of memory-hogs or CPU hogs, so maybe the difference with/without alpha override just doesn't amount to much. Aloft does very little processing on these OnUpdate events, it may be something that can be lived with.

in my ignorance though, it all came as an unpleasant suprise .

as for replacing blizzard's nameplates completely... each nameplate parent frame is effectively "hardcoded" into the WoW client specifically as a nameplate (along with a healthbar and castbar, all of them as an attribute of the unit, not something that can be thrown away and replaced by an addon, only tweaked), and Blizzard expects them to be there in a certain form, and controls their lifecycles, visibility, default appearance, etc. i don't know enough to be certain, but i strongly suspect there would be significant side effects trying to replace them. something to play with, perhaps, but i want to know more before i dig into it.
  Reply With Quote

WoWInterface » Developer Discussions » General Authoring Discussion » Hook infinite loop?


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