Thread Tools Display Modes
08-24-13, 11:50 AM   #1
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Onupdate

I started working on this little project today, which imitates the rank style gui and sounds stytem from Devil May Cry 5. However i feel the the CPU usage is quite high for an addon with only 1 onupdate event. (5-6ms/s)

Here is my code:

Code:
local _, ns = ...
local DevilMayCry = { }
ns.DevilMayCry = DevilMayCry

local BaseSize = 128
local TextureSize = 128
local AnimSize = 300
local ReachedMax = false

local Frame = CreateFrame("Frame", nil, UIParent)
Frame:SetPoint("CENTER", 500, 450)
Frame:SetFrameStrata("Medium")
Frame:SetFrameLevel(0)
Frame:SetWidth(TextureSize)
Frame:SetHeight(TextureSize)
Frame:SetAlpha(0.99)
Frame:SetMovable(true)
Frame:EnableMouse(true)
Frame:SetClampedToScreen(false)
Frame:RegisterForDrag("LeftButton")

local Background = Frame:CreateTexture("Texture", "Background")
Background:SetTexture("Interface\\Addons\\DevilMayCry\\Textures\\Background")
Background:SetWidth(TextureSize)
Background:SetHeight(TextureSize)
Background:SetBlendMode("Disable")
Background:SetDrawLayer("Background", 0)
Background:SetAllPoints(Frame)

local Foreground = Frame:CreateTexture("Texture", "Background")
Foreground:SetTexture("Interface\\Addons\\DevilMayCry\\Textures\\Foreground")
Foreground:SetWidth(TextureSize)
Foreground:SetHeight(TextureSize)
Foreground:SetBlendMode("Disable")
Foreground:SetDrawLayer("Background", 1)
Foreground:SetPoint("Bottom", Frame, "Bottom")

local UpdateFrame = CreateFrame("Frame", nil)
local TimeSinceLastUpdate = 0
local NextUpdate = 0.0050

function DevilMayCry.StartMove(frame, button)
	if button ~= "LeftButton" then
		return
	end
	frame:StartMoving()
end

Frame:SetScript("OnMouseDown", DevilMayCry.StartMove)

function DevilMayCry.StopMove(frame, button)
	if button ~= "LeftButton" then
		return
	end
	frame:StopMovingOrSizing()
	local x = math.floor(frame:GetLeft() + (frame:GetWidth() - UIParent:GetWidth()) / 2 + 0.5)
	local y = math.floor(frame:GetTop() - (frame:GetHeight() + UIParent:GetHeight()) / 2 + 0.5)
	frame:ClearAllPoints()
	frame:SetPoint("CENTER", x, y)
end

Frame:SetScript("OnMouseUp", DevilMayCry.StopMove)

function DevilMayCry:Foreground()
	if Foreground:GetHeight() > TextureSize * 0.9999 then
		ReachedMax = true
	end
	if Foreground:GetHeight() <= 0 then
		-- Test Mode
		Frame:SetWidth(TextureSize)
		Frame:SetHeight(TextureSize)
		Background:SetAllPoints(Frame)
		Foreground:SetWidth(TextureSize)
		Foreground:SetHeight(TextureSize)
		Foreground:SetTexCoord(0, 0, 0, 1, 1, 0, 1, 1)
	else
		local y = Foreground:GetHeight() / TextureSize
		if y > 1 then
			Foreground:SetHeight(TextureSize)
			y = 1
		end
		Frame:SetHeight(TextureSize)
		Frame:SetWidth(TextureSize)
		Background:SetAllPoints(Frame)
		if Foreground:GetWidth() > TextureSize then
			Foreground:SetWidth(Foreground:GetWidth() - ((TextureSize / 128) * 0.1))
		end
		Foreground:SetHeight(Foreground:GetHeight() - ((TextureSize / 128) * 0.1))
		local ULx, ULy, LLx, LLy, URx, URy, LRx, LRy = Foreground:GetTexCoord()
		Foreground:SetTexCoord(ULx, 1 - y, LLx, LLy, URx, 1 - y, LRx, LRy)
	end
	return 0.0050
end

function DevilMayCry:SetTextureSize(size)
	local LastSize = TextureSize
	TextureSize = size
	Foreground:SetWidth(Foreground:GetWidth() * TextureSize / LastSize)
	Foreground:SetHeight(Foreground:GetHeight() * TextureSize / LastSize)
end

function DevilMayCry:AnimateTexture()
	DevilMayCry:SetTextureSize(AnimSize)
	if AnimSize >= (BaseSize + 2) then
		AnimSize = AnimSize - 2
	else
		AnimSize = 300
		ReachedMax = false
	end
end

function DevilMayCry_IncreaseHeight(percent)
	if Foreground:GetHeight() < (TextureSize * (1 - percent)) then
		Foreground:SetHeight(Foreground:GetHeight() + (TextureSize * percent))
	else
		Foreground:SetHeight(TextureSize)
	end
	if Foreground:GetWidth() <= (TextureSize) then
		Foreground:SetWidth(Foreground:GetWidth() * 1.12)
	else
		Foreground:SetWidth(TextureSize * 1.12)
	end
end

function DevilMayCry:OnUpdate(elapsed)
	TimeSinceLastUpdate = TimeSinceLastUpdate + elapsed
	while TimeSinceLastUpdate > NextUpdate do
		TimeSinceLastUpdate = TimeSinceLastUpdate - NextUpdate
		if ReachedMax == true then
			DevilMayCry:AnimateTexture()
		end
		NextUpdate = DevilMayCry:Foreground()
	end
end

UpdateFrame:SetScript("OnUpdate", DevilMayCry.OnUpdate)
GitHub:

https://github.com/Resike/DevilMayCry
  Reply With Quote
08-24-13, 03:21 PM   #2
semlar
A Pyroguard Emberseer
 
semlar's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2007
Posts: 1,060
You have a while loop inside of your OnUpdate function, so every frame you're telling the game to stop everything until that while condition is satisfied.

You probably want an if statement or something.
  Reply With Quote
08-24-13, 04:10 PM   #3
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Originally Posted by semlar View Post
You have a while loop inside of your OnUpdate function, so every frame you're telling the game to stop everything until that while condition is satisfied.

You probably want an if statement or something.
Yes because i manually set the update times with that while.
  Reply With Quote
08-24-13, 04:20 PM   #4
suicidalkatt
A Rage Talon Dragon Guard
 
suicidalkatt's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2008
Posts: 331
Just out of curiosity, any particular reason you don't just use a statusbar and set the orientation to vertical?

You just need to use if and reset your variable:
Lua Code:
  1. function DevilMayCry:OnUpdate(elapsed)
  2.     TimeSinceLastUpdate = TimeSinceLastUpdate + elapsed
  3.     if TimeSinceLastUpdate > 0.005 do
  4.         if ReachedMax == true then
  5.             DevilMayCry:AnimateTexture()
  6.         end
  7.         TimeSinceLastUpdate = 0
  8.     end
  9. end

Last edited by suicidalkatt : 08-24-13 at 04:27 PM.
  Reply With Quote
08-24-13, 05:10 PM   #5
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Originally Posted by suicidalkatt View Post
Just out of curiosity, any particular reason you don't just use a statusbar and set the orientation to vertical?

You just need to use if and reset your variable:
Lua Code:
  1. function DevilMayCry:OnUpdate(elapsed)
  2.     TimeSinceLastUpdate = TimeSinceLastUpdate + elapsed
  3.     if TimeSinceLastUpdate > 0.005 do
  4.         if ReachedMax == true then
  5.             DevilMayCry:AnimateTexture()
  6.         end
  7.         TimeSinceLastUpdate = 0
  8.     end
  9. end
Hmm, i never used statusbars yet however i'm not sure i can animate them properly. However i'll try them, i'm not sure which is the best method for this task yet i just started this project today.
  Reply With Quote
08-24-13, 05:13 PM   #6
Vrul
A Scalebane Royal Guard
 
Vrul's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2007
Posts: 404
Is that going to be a cooldown timer? Will there eventually be more than one thing making it need to be modular?
  Reply With Quote
08-24-13, 05:23 PM   #7
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Originally Posted by Vrul View Post
Is that going to be a cooldown timer? Will there eventually be more than one thing making it need to be modular?
Most likely you deal damage to fill the bar, when the bar is filled then you go to the next streak, when it's becomes empty it gonna reset all of your streak.

Last edited by Resike : 08-24-13 at 05:27 PM.
  Reply With Quote
08-25-13, 01:26 AM   #8
myrroddin
A Pyroguard Emberseer
 
myrroddin's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 1,240
FYI, you do not need to explicitly check if a variable is true (or 1/nil). Lua assumes that. Likewise for false or nil. The only time you need to check the latter is for tri-state variables true/false/nil.
Lua Code:
  1. -- all the same in Lua, if the returns for var are either 1/nil or true/false
  2. if var then
  3. if var == true then
  4. if var == 1 then
  5. if var ~= false then
  6. if var ~= nil then
  7.  
  8. if not var then
  9. if var == nil then
  10. if var == false then
  11. if var ~= true then
  12. if var ~= 1 then
  13.  
  14. -- if the returns for var are nil/1/2 or true/false/nil
  15. -- these are not the same
  16. if not var then
  17. if var == false then
  18. if var ~= true then
  19. if var ~= nil then
It is preferable, when writing code, if the variable only has two return values, to do the following, because it is much, much easier to read, especially later when you come back.
Lua Code:
  1. if var then
  2. if not var then

Last edited by myrroddin : 08-25-13 at 01:30 AM. Reason: Clarity.
  Reply With Quote
08-25-13, 03:10 AM   #9
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Originally Posted by myrroddin View Post
FYI, you do not need to explicitly check if a variable is true (or 1/nil). Lua assumes that. Likewise for false or nil. The only time you need to check the latter is for tri-state variables true/false/nil.
Lua Code:
  1. -- all the same in Lua, if the returns for var are either 1/nil or true/false
  2. if var then
  3. if var == true then
  4. if var == 1 then
  5. if var ~= false then
  6. if var ~= nil then
  7.  
  8. if not var then
  9. if var == nil then
  10. if var == false then
  11. if var ~= true then
  12. if var ~= 1 then
  13.  
  14. -- if the returns for var are nil/1/2 or true/false/nil
  15. -- these are not the same
  16. if not var then
  17. if var == false then
  18. if var ~= true then
  19. if var ~= nil then
It is preferable, when writing code, if the variable only has two return values, to do the following, because it is much, much easier to read, especially later when you come back.
Lua Code:
  1. if var then
  2. if not var then
Yes i'm aware of that but isn't is faster only to compare to 1 thing rather then to two?
  Reply With Quote
08-25-13, 05:52 AM   #10
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Code:
if var then
... is not comparing "var" to anything at all, let alone to two things. Functionally, it achieves the same result as:

Code:
if var ~= nil and var ~= false then
... but it's not actually the same thing.
__________________
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
08-26-13, 05:57 PM   #11
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,323
Originally Posted by Resike View Post
Yes I'm aware of that but isn't it faster only to compare to 1 thing rather then to two?
If you really want to look into it, we can break down how the lines work. When you compare with if var==true then, you are running a binary operation (==) that returns a boolean value after comparing var and true, then feeding it into the if ... then statement. If you use if var then, you bypass the binary operation and feed var directly into it
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Onupdate


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