Thread Tools Display Modes
09-09-17, 11:38 AM   #1
pas06
A Theradrim Guardian
Join Date: Apr 2009
Posts: 62
Chain Positioning of buttons

Hi,

I did some tests today with my Addon https://mods.curse.com/addons/wow/27...egroundenemies
I wanted to test how it would look like with 30 or 40 players in a row. I noticed that it gets really laggy when entering the testmode. I found out that the problem is caused by my function BattleGroundEnemies:ButtonPositioning()
The function looks like this (i added the print for debug reasons)
Lua Code:
  1. function BattleGroundEnemies:ButtonPositioning()
  2.  
  3.     local previousButton = self
  4.     for number, name in ipairs(self.EnemySortingTable) do
  5.         local enemyButton = self.Enemies[name]
  6.         enemyButton.Position = number
  7.        
  8.         enemyButton:ClearAllPoints()
  9.         if self.db.profile.Growdirection == "downwards" then
  10.             local startTime = debugprofilestop()
  11.             enemyButton:SetPoint("TOPLEFT", previousButton, "BOTTOMLEFT", 0, -self.db.profile.SpaceBetweenRows)
  12.             enemyButton:SetPoint("TOPRIGHT", previousButton, "BOTTOMRIGHT", 0, -self.db.profile.SpaceBetweenRows)
  13.             print(debugprofilestop() - startTime)
  14.         else
  15.             enemyButton:SetPoint("BOTTOMLEFT", previousButton, "TOPLEFT", 0, self.db.profile.SpaceBetweenRows)
  16.             enemyButton:SetPoint("BOTTOMRIGHT", previousButton, "TOPRIGHT", 0, self.db.profile.SpaceBetweenRows)
  17.         end
  18.         previousButton = enemyButton
  19.     end
  20. end
I found out that the duration for each iterations grows Exponential
The outputs of this prints
Lua Code:
  1. [07:32:21] 0.0022993683815002
  2. [07:32:21] 0.0028104186058044
  3. [07:32:21] 0.003065824508667
  4. [07:32:21] 0.0028104186058044
  5. [07:32:21] 0.0033213496208191
  6. [07:32:21] 0.0048542618751526
  7. [07:32:21] 0.0079201459884644
  8. [07:32:21] 0.013796448707581
  9. [07:32:21] 0.025548875331879
  10. [07:32:21] 0.050075829029083
  11. [07:32:21] 0.096063911914825
  12. [07:32:21] 0.19136130809784
  13. [07:32:21] 0.37837928533554
  14. [07:32:21] 0.76135736703873
  15. [07:32:21] 1.6034492850304
  16. [07:32:21] 3.1299964189529
  17. [07:32:21] 6.1787472963333
  18. [07:32:21] 12.497247099876
  19. [07:32:21] 25.104099035263
  20. [07:32:21] 50.724030435085
  21. [07:32:21] 100.23934215307
  22. [07:32:21] 200.18180602789
  23. [07:32:22] 405.05413562059
  24. [07:32:22] 822.46883159876
  25. [07:32:24] 1608.76526737

As you can see those 2 SetPoint() calls took 1.6 seconds
is this a bug or am i just doing something wrong?

Last edited by pas06 : 09-09-17 at 01:31 PM.
  Reply With Quote
09-09-17, 12:18 PM   #2
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,877
It wouldn't hurt to save self.db.profile.SpaceBetweenRows and self.db.profile.Growdirection to local variables at the start of the function rather than doing a table lookup once or twice each iteration.
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.
  Reply With Quote
09-09-17, 12:20 PM   #3
pas06
A Theradrim Guardian
Join Date: Apr 2009
Posts: 62
yeah, i know, but this is not whats causing this huge durations
Edit: Just a side note, i commented all SetScripts out to make shure that this problem is not caused by any attached scripts.

Last edited by pas06 : 09-09-17 at 01:25 PM.
  Reply With Quote
09-09-17, 01:34 PM   #4
MunkDev
A Scalebane Royal Guard
 
MunkDev's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2015
Posts: 431
Just speculating here, but since you're anchoring both top corners to the bottom corners of the previous button (or vice versa), is it possible that the slowdown happens because it needs to go back up the chain with each iteration to find out where to draw the next button? When you anchor two opposite corners, it'll ultimately use the distance between them to determine the span instead of whatever value you feed to it.

A conversation between them might look like a little bit like this:
- "I was supposed to anchor to you and match your width. Where should I draw myself?"
- "I don't really know, I'll ask the guy I'm anchored to because he's in control of my position."
* repeat until the first button is reached *

Lua Code:
  1. function BattleGroundEnemies:ButtonPositioning()
  2.  
  3.     local previousButton, buttons = self, self.Enemies
  4.     local spaceBetweenRows = self.db.profile.SpaceBetweenRows
  5.     local growDownwards = (self.db.profile.Growdirection == "downwards")
  6.     local mainWidth = self:GetWidth()
  7.  
  8.     for number, name in ipairs(self.EnemySortingTable) do
  9.         local enemyButton = buttons[name]
  10.         enemyButton.Position = number
  11.        
  12.         enemyButton:SetWidth(mainWidth)
  13.         enemyButton:ClearAllPoints()
  14.         if growDownwards then
  15.             enemyButton:SetPoint("TOPLEFT", previousButton, "BOTTOMLEFT", 0, -spaceBetweenRows)
  16.         else
  17.             enemyButton:SetPoint("BOTTOMLEFT", previousButton, "TOPLEFT", 0, spaceBetweenRows)
  18.         end
  19.         previousButton = enemyButton
  20.     end
  21. end

Try this to confirm or debunk this theory. (And please report your findings even if it solves your problem.)
__________________

Last edited by MunkDev : 09-09-17 at 01:48 PM.
  Reply With Quote
09-09-17, 01:49 PM   #5
pas06
A Theradrim Guardian
Join Date: Apr 2009
Posts: 62
Thanks, this really helped a lot, it now works without any lag. So i will change my code to only anchor one Point and set the width for each individual button. And i thought this way of positioning is smart since i only need to adjust the parents width to change the width of all attached buttons with 30 buttons it crashed my client
  Reply With Quote
09-09-17, 02:02 PM   #6
MunkDev
A Scalebane Royal Guard
 
MunkDev's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2015
Posts: 431
That might seem like the most intuitive approach, but if you think about how the UI engine needs to work in order to draw your frames in the right place, creating a chain of relative positioning entails a lot of unnecessary calculation because of their interdependent relationships, as opposed to just knowing a single point where it should anchor and a plain number to determine the width.
__________________
  Reply With Quote
09-09-17, 02:20 PM   #7
pas06
A Theradrim Guardian
Join Date: Apr 2009
Posts: 62
I haven't thought about that its that complicated to get the actual position of a frame. I thougth that there is some sort of database of each frame and its position (so that the points don't need to be calculated through the whole chain) Anyways, thanks for you help
  Reply With Quote

WoWInterface » AddOns, Compilations, Macros » AddOn Help/Support » Chain Positioning of buttons

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