WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   MoP Beta archived threads (https://www.wowinterface.com/forums/forumdisplay.php?f=162)
-   -   Nameplates (https://www.wowinterface.com/forums/showthread.php?t=43789)

zork 07-30-12 02:51 PM

In case anyone is interested. I took p3lims advise and changed my script. I'm now checking for nameplates like this:

Lua Code:
  1. --init
  2.   local _DB
  3.   local a = CreateFrame("Frame")
  4.   local index = 1
  5.   --timer  
  6.   local ag = a:CreateAnimationGroup()
  7.   ag.anim = ag:CreateAnimation()
  8.   ag.anim:SetDuration(0.33)
  9.   ag:SetLooping("REPEAT")
  10.   ag:SetScript("OnLoop", function(self, event, ...)
  11.     if _DB.namePlateIndex and _G["NamePlate".._DB.namePlateIndex] then
  12.       index = _DB.namePlateIndex
  13.       _DB.namePlateIndex = nil
  14.     end
  15.     while(_G["NamePlate" .. index]) do
  16.       local frame = _G['NamePlate' .. index]
  17.       if frame and not frame.rDB_styled then
  18.         styleNameplate(frame)
  19.       end
  20.       index = index + 1
  21.     end
  22.   end)
  23.   ag:Play()
  24.   --load some variable stuff
  25.   a:RegisterEvent("PLAYER_LOGIN")
  26.   a:RegisterEvent("PLAYER_LOGOUT")
  27.   a:SetScript("OnEvent", function(self,event,...)
  28.     if event == "PLAYER_LOGIN" then
  29.       _DB = _G["rDP_DB"] or {}
  30.       _G["rDP_DB"] = _DB
  31.     else
  32.       _DB.namePlateIndex = index + 0
  33.     end
  34.   end)

Sidenote...the index must not be increased by 1 on logout or one nameplate will not get styled. (Because the index is already increased by 1 once an index is found.

Running perfectly for now:

ballagarba 07-30-12 02:55 PM

Did you do any CPU profiling comparing the two methods?

Dridzt 07-30-12 02:58 PM

I'm interested :)

I tested build 15913 and it seems they've fixed the :GetChildren() crash, can't reproduce it in any of the situations I used for previous build (it wasn't 100% reproducible, seemed to happen reliably when many nameplates spawned - ex. training all the mobs in Stockade).

Anyway, it seems the client no longer crashes with WorldFrame:GetChildren() so I reverted back to the 'traditional' way of finding plates as simpler.

Will keep an eye on this thread though for sure, an alternative is good to have.

zork 07-30-12 03:13 PM

@ballagarba
The two versions don't differ that much. Both use OnUpdate. (Even the animationgroup does).

The only big difference is that in the traditional way you iterate over all WorldFrame:GetChildren() all the time.

In the new version you check just one index that is either available or not.

ballagarba 07-30-12 03:43 PM

Quote:

Originally Posted by zork (Post 259031)
@ballagarba
The two versions don't differ that much. Both use OnUpdate. (Even the animationgroup does).

The only big difference is that in the traditional way you iterate over all WorldFrame:GetChildren() all the time.

In the new version you check just one index that is either available or not.

I'm curious about how expensive WorldFrame:GetChildren() is. Assume: "local frames = select('#', WorldFrame:GetChildren())". Now you only have to do something if "frames" has changed from previous iteration, and you'd only have to iterate from the previous value of "frames" to its new one. So the cost of the function pretty much equals select('#', WorldFrame:GetChildren()).

p3lim 07-30-12 03:45 PM

Why are you using an animationgroup for this?

Torhal 07-30-12 04:40 PM

Because for the past few years now it's been the cool kids' way of writing a timer. The theory is since it's done in C, it's less overhead. Since we can't measure, I don't actually buy it.

acapela 07-30-12 06:26 PM

Quote:

Originally Posted by Lombra (Post 258882)
Some spontaneous ideas, should anyone put together a formal proposal to Blizzard; NAMEPLATE_SHOW(index), GetNumNameplates(), GetNameplate(index). Possibly additional events for _CREATE and _UPDATED, and/or an argument indicating a new frame was created.

yeah, show/hide events, at least, would be great. given something like that for initial discovery, one could maintain a small cache of frame references, and just iterate it. separate events for the whole lifecycle (create/show/hide/update/destroy/whatever) would be OK, too, assuming there was any value in delivery timing (and assuming "destroy" actually ever meant something).

one of the most requested features in my experience is the ability to control the in-game "range" at which nameplates become visible (currently "hardcoded" at 40 yards, in game terms; used to be much shorter, several major revisions ago). i requested this in the Blizzard forums, long ago and far away, but never heard a peep in response. some folks want to shorten this range, so they update fewer frames.

its funny, too... i never experienced this crash with :GetChildren(). i was not among the first round(s) of Beta access granted, however. seems to have been fixed by the time i received my Blizzard email.

zork 07-31-12 01:20 AM

Quote:

Originally Posted by p3lim (Post 259033)
Why are you using an animationgroup for this?

I just like the timer handling more. But using OnUpdate wouldn't be that much different.

p3lim 07-31-12 10:18 AM

Alright, haven't really used animationgroups before so I just found it weird to be used like this.

One thing tho, to avoid spamming the loading process, run :Play() on PLAYER_LOGIN.

Lua Code:
  1. local function Update(frame)
  2.     -- do whatever
  3. end
  4.  
  5. local index = 1
  6.  
  7. local handler = CreateFrame('Frame')
  8. handler:RegisterEvent('PLAYER_LOGOUT')
  9. handler:RegisterEvent('PLAYER_LOGIN')
  10.  
  11. local animation = handler:CreateAnimationGroup()
  12. animation:CreateAnimation():SetDuration(1/3)
  13. animation:SetLooping('REPEAT')
  14. animation:SetScript('OnLoop', function()
  15.     if(t9e5e5rb and _G['NamePlate' .. t9e5e5rb]) then
  16.         index = t9e5e5rb
  17.         t9e5e5rb = nil
  18.     end
  19.  
  20.     while(_G['NamePlate' .. index]) do
  21.         local frame = _G['NamePlate' .. index]
  22.         frame:HookScript('OnShow', Update)
  23.         Update(frame)
  24.  
  25.         index = index + 1
  26.     end
  27. end)
  28.  
  29. handler:SetScript('OnEvent', function(self, event)
  30.     if(event == 'PLAYER_LOGIN') then
  31.         animation:Play()
  32.     else
  33.         t9e5e5rb = index
  34.     end
  35. end)

p3lim 08-09-12 10:44 PM

Tried both methods today, though as hard as it is to try and stress-test this, I ended up with some results.

The "new" method uses 0.01 CPU/ms less than the previous method (on average), and 0.1 CPU/ms less during stress testing (20+ nameplates).
This was tested with the addon Addon Profiler, and both versions were polling 5 times per second.

These values are so miniscule, you can just use what ever you prefer tbh.
Personally, I will use the stuff I came up with, just because :p.

villiv 08-14-12 01:53 AM

really helpful thread. thank you for sharing this. :)

since all we like efficiency, do CVars-checking will help as well? or useless thoughts?

Lua Code:
  1. local f = CreateFrame('Frame')
  2. local a = f:CreateAnimationGroup()
  3. a:CreateAnimation():SetDuration(1/3)
  4. a:SetLooping('REPEAT')
  5. a:SetScript('OnLoop', function ()
  6.   -- LF Nameplates
  7. end)
  8.  
  9. local cvars = {
  10.     nameplateShowFriends = true, nameplateShowFriendlyPets = true, nameplateShowFriendlyGuardians = true, nameplateShowFriendlyTotems = true,
  11.     nameplateShowEnemies = true, nameplateShowEnemyPets = true, nameplateShowEnemyGuardians = true, nameplateShowEnemyTotems = true,
  12. }
  13.  
  14. local function check ()
  15.     for cvar in next, cvars do if ( GetCVarBool(cvar) ) then return a:Play() end end
  16.     return a:Stop()
  17. end
  18.  
  19. hooksecurefunc('SetCVar', function (cvar) if ( cvars[cvar] ) then return check() end end)


All times are GMT -6. The time now is 05:37 AM.

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