Thread Tools Display Modes
10-27-13, 02:48 PM   #1
Mayron
A Frostmaul Preserver
 
Mayron's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2010
Posts: 275
Issue with While Loops causing the game to crash

Hi, I'm still learning and this is my first attempt at a while loop so I'm guessing I'm doing something wrong because when I press a button to execute the code, the game crashes.

Before using a while loop I was using an OnUpdate script and basically I want to create a button and when pressed it would execute a block of code every 0.5 seconds (may change depending on if its fast enough). I was using an OnUpdate script but this depended upon the FPS of the game which didn't work for the project I'm working on.

Anyway I want the while loop (or any alternative) to execute a block of code ever 0.5 seconds and not sure how to go about it. This is what I have so far, hopefully this will make more sense than my explanation:

Lua Code:
  1. local startMoving, newTopValue = false, 40
  2. local initiate = true
  3. local function MUI_timer(retractEnabled)
  4.         while startMoving do
  5.             initiate = true
  6.             local currentTime = GetTime()
  7.             local amount = currentTime + 0.5
  8.             while currentTime <= amount do
  9.                 if initiate then
  10.                     if retractEnabled then
  11.                         if newTopValue > 40 then
  12.                             newTopValue = newTopValue - 1
  13.                             -- do stuff
  14.                         else
  15.                             retractEnabled = false
  16.                             startMoving = false
  17.                         end
  18.                     elseif newTopValue < 76 then
  19.                         newTopValue = newTopValue + 1
  20.                         -- do stuff
  21.                     else
  22.                         startMoving = false
  23.                     end
  24.                 initiate = false
  25.                 else
  26.                 currentTime = GetTime()
  27.                 end
  28.             end
  29.         end
  30.     end
  31.    
  32.     local function Expand_Retract()
  33.         if newTopValue == 40 then -- Expand
  34.             startMoving = true
  35.             MUI_timer(false)
  36.         elseif newTopValue == 76 then -- Retract
  37.             startMoving = true
  38.             MUI_timer(true)
  39.         end
  40.     end

Could anyone guide me on how to fix the crashing issue? Been stuck on this for a long time now.
Thank you for reading!

Last edited by Mayron : 10-27-13 at 02:57 PM.
  Reply With Quote
10-27-13, 02:55 PM   #2
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
OnUpdate script doesn't effect on the speed of the code, only how frequently the updating happens.
  Reply With Quote
10-27-13, 02:56 PM   #3
Malsomnus
A Cobalt Mageweaver
AddOn Author - Click to view addons
Join Date: Apr 2013
Posts: 203
Long story short, what you're describing cannot be done that way. You can either use OnUpdate and check that 0.5s have passed since the last call, or repeatedly use a 0.5s animation.
__________________
SanityCheck - If you've ever said the words "Sorry, I forgot" then you need this add-on.

Remember, every time you post a comment on an add-on, a kitten gets its wings!
  Reply With Quote
10-27-13, 02:59 PM   #4
Mayron
A Frostmaul Preserver
 
Mayron's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2010
Posts: 275
Originally Posted by Resike View Post
OnUpdate script doesn't effect on the speed of the code, only how frequently the updating happens.
Yes I know sorry I didn't word that well, basically the code is used to create an animated effect of moving UI elements but if you have bad FPS then the OnUpdate script causes the animation effect to run too slowly. I decided to use a loop with the GetTime() function instead to make it run at a set speed rather than depending on your FPS.

Originally Posted by Malsomnus View Post
or repeatedly use a 0.5s animation.
Ok thank you, I only thought you could create an animation for precise things such as an Alpha change. I did not know you could create an animation to do anything you wanted over a set time

Last edited by Mayron : 10-27-13 at 03:05 PM.
  Reply With Quote
10-27-13, 03:04 PM   #5
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Originally Posted by Mayron View Post
Yes I know sorry I didn't word that well, basically the code is used to create an animated effect of moving UI elements but if you have bad FPS then the OnUpdate script causes the animation effect to run too slowly. I decided to use a loop with the GetTime() function instead to make it run at a set speed rather than depending on your FPS.
I see you can dinamically slow down the update times on higher fps with "GetFramerate()".
  Reply With Quote
10-27-13, 03:07 PM   #6
Malsomnus
A Cobalt Mageweaver
AddOn Author - Click to view addons
Join Date: Apr 2013
Posts: 203
If you want to move UI elements, I strongly suggest you use animations. That is why they exist
You can start here: http://wowprogramming.com/docs/widgets/Animation
__________________
SanityCheck - If you've ever said the words "Sorry, I forgot" then you need this add-on.

Remember, every time you post a comment on an add-on, a kitten gets its wings!
  Reply With Quote
10-27-13, 03:10 PM   #7
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Originally Posted by Malsomnus View Post
If you want to move UI elements, I strongly suggest you use animations. That is why they exist
You can start here: http://wowprogramming.com/docs/widgets/Animation
I'm pretty sure it's using the same OnUpdate functions.
  Reply With Quote
10-27-13, 03:13 PM   #8
Mayron
A Frostmaul Preserver
 
Mayron's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2010
Posts: 275
My "animation" is not one that I thought an animation method could help me with as I wanted to run a function every set seconds until a condition is met. I thought these animations only let you do simpler things like alpha changes, rotations and others.

Last edited by Mayron : 10-27-13 at 03:38 PM.
  Reply With Quote
10-27-13, 03:45 PM   #9
Malsomnus
A Cobalt Mageweaver
AddOn Author - Click to view addons
Join Date: Apr 2013
Posts: 203
Originally Posted by Mayron View Post
My "animation" is not one that I thought an animation method could help me with as I wanted to run a function every set seconds until a condition is met. I thought these animations only let you do simpler things like alpha changes, rotations and others.
Well that's legit, but they can still be used as a timer (and seem to be popular as such).
To use OnUpdate properly, you need to do something along the lines of:

Code:
f.elapsed = 0
f:SetScript ("OnUpdate", function (self, elapsed,...)
    f.elapsed = f.elapsed + elapsed
    if f.elapsed > 0.5 then
        ...
        f.elapsed = 0
    end
end
(Off the top of my head, please don't murder me if I missed something)

Point is, the code you used was simply blocking the game 100% of the time. Being stuck in a while loop means nothing on the screen can update, so the game basically freezes.
__________________
SanityCheck - If you've ever said the words "Sorry, I forgot" then you need this add-on.

Remember, every time you post a comment on an add-on, a kitten gets its wings!
  Reply With Quote
10-27-13, 04:32 PM   #10
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Originally Posted by Resike View Post
I see you can dinamically slow down the update times on higher fps with "GetFramerate()".
Lets say your update interval value use this: "1 / math.sqrt(GetFrameRate())" then your onupdate code runs ~0.2sec on 30fps and ~0.5sec on 100fps. On 30fps the OnUpdate script runs every 0.03sec, 0.2 * 0.03 = 0.006 and on 100fps on every 0.01sec, 0.5 * 0.01 = 0.005, almost the same values.

Means your animations speed wont change (that much) on different fps values.

Last edited by Resike : 10-27-13 at 04:44 PM.
  Reply With Quote
10-28-13, 02:34 AM   #11
zork
A Pyroguard Emberseer
 
zork's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 1,740
I have a script that extracts the displayInfo model db from WoW (60k models). I use the animation loop with a 0.001 timer for that purpose. I have a function that will try to extract data but only will be called if a global boolean is set to the true. As long as the extract function runs that boolean is set to false.
Lua Code:
  1. local index = 0
  2. local maxIndex = 60000
  3. local canExtract = true
  4.  
  5. local model = CreateFrame("PlayerModel")
  6. local modelData = {}
  7. local tinsert = tinsert
  8.  
  9. local function ExtractModelData()
  10.   index = index + 1
  11.   model:ClearModel()
  12.   model:SetDisplayInfo(index)
  13.   tinsert(modelData, model:GetModel())
  14.   canExtract = true
  15. end
  16.  
  17. local loop = CreateFrame("Frame")
  18. loop.ag = loop:CreateAnimationGroup()
  19. loop.ag.anim = loop.ag:CreateAnimation()
  20. loop.ag.anim:SetDuration(0.001)
  21. loop.ag:SetLooping("REPEAT")
  22. loop.ag:SetScript("OnLoop", function(self)
  23.   if index > maxIndex then self:Stop() end
  24.   if canExtract then
  25.     canExtract = false
  26.     ExtractModelData()
  27.   end
  28. end)
  29.  
  30. loop:SetScript("OnEvent", function(self)
  31.   self.ag:Play()
  32. end)
  33. loop:RegisterEvent("PLAYER_LOGIN")
__________________
| Simple is beautiful.
| WoWI AddOns | GitHub | Zork (WoW)

"I wonder what the non-pathetic people are doing tonight?" - Rajesh Koothrappali (The Big Bang Theory)

Last edited by zork : 10-28-13 at 02:46 AM.
  Reply With Quote
10-28-13, 03:23 AM   #12
Mayron
A Frostmaul Preserver
 
Mayron's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2010
Posts: 275
Thank you very much for that Zork! Looks interesting and might be what I'm looking for, I know Malsomnus mentioned animations but I was confused at the time since I didn't know animations could work like this. Will experiment with it tonight
  Reply With Quote
11-05-13, 02:25 AM   #13
AnrDaemon
A Chromatic Dragonspawn
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 156
I can put your issue in this way:
OnUpdate runs every frame. That is, every time a game render new frame, it run your OnUpdate handler.
You can do something at that time, or not, matters not. Unless the flame is hidden when interpreter leaves your handler, it will be displayed.
Now, if you are satisfied with ~10 FPS update to whatever you want to do with your frame, OnUpdate will give you enough control over process. There's a very, very little chance that FPS will be lower than that, as it's quickly nearing unplayable status at this point.
The one way to control OnUpdate was given above. Slightly more precise variant is to not reset f.elapsed to zero, but set it to subtraction (f.elapsed - 0.05). Now, if you are running into 0.04 -> 0.06 gap, the next animation step will happen a bit sooner, evening out the curve.
  Reply With Quote
11-06-13, 07:27 AM   #14
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Originally Posted by zork View Post
I have a script that extracts the displayInfo model db from WoW (60k models). I use the animation loop with a 0.001 timer for that purpose. I have a function that will try to extract data but only will be called if a global boolean is set to the true. As long as the extract function runs that boolean is set to false.
Lua Code:
  1. local index = 0
  2. local maxIndex = 60000
  3. local canExtract = true
  4.  
  5. local model = CreateFrame("PlayerModel")
  6. local modelData = {}
  7. local tinsert = tinsert
  8.  
  9. local function ExtractModelData()
  10.   index = index + 1
  11.   model:ClearModel()
  12.   model:SetDisplayInfo(index)
  13.   tinsert(modelData, model:GetModel())
  14.   canExtract = true
  15. end
  16.  
  17. local loop = CreateFrame("Frame")
  18. loop.ag = loop:CreateAnimationGroup()
  19. loop.ag.anim = loop.ag:CreateAnimation()
  20. loop.ag.anim:SetDuration(0.001)
  21. loop.ag:SetLooping("REPEAT")
  22. loop.ag:SetScript("OnLoop", function(self)
  23.   if index > maxIndex then self:Stop() end
  24.   if canExtract then
  25.     canExtract = false
  26.     ExtractModelData()
  27.   end
  28. end)
  29.  
  30. loop:SetScript("OnEvent", function(self)
  31.   self.ag:Play()
  32. end)
  33. loop:RegisterEvent("PLAYER_LOGIN")
Why do you need thoose vaules? Also i think there is much more models in the game then 60k, and a lot of them have the same displayInfo.
  Reply With Quote
11-19-13, 01:53 PM   #15
Billtopia
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Apr 2009
Posts: 110
all you need to know for an OnUpdate animation is a few things

how far does the item have to move?
how long is it supposed to take?
how long has it been?

so say you have to move something 100 pixels over 4 seconds
every second is 25 pixels...
onupdate tells you how long it has been since the last frame redraw

subtract the elapsed from the lifespan of the item and remove the item if it is lifespan < 0 and exit the loop

move your sprite (elapsed * pixelsPerSecond)


exit the loop
  Reply With Quote
11-19-13, 08:53 PM   #16
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
I think you may have posted in the wrong thread, but there's no reason to use an OnUpdate script for animations anymore. Blizzard added a dedicated animation system specifically to replace the use of OnUpdate scripts for animation. If you want to move/rescale/rotate/fade/whatever something, use animations, not OnUpdate scripts. Even if what you want to do isn't an actual animation (eg. "run this function 10 times per second") it's still easier now to use an "animation" than an OnUpdate script, because you don't need to keep track of intervals, implement throttling, etc. yourself.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Issue with While Loops causing the game to crash


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