WoW:Using OnUpdate correctly: Difference between revisions

From AddOn Studio
Jump to navigation Jump to search
(Added a more accurate method)
m (Move page script moved page Using OnUpdate correctly to Using OnUpdate correctly without leaving a redirect)
 
(6 intermediate revisions by 6 users not shown)
Line 1: Line 1:
=How Often Is It Called=
This page is a guide on '''using OnUpdate correctly'''.
 
== How Often Is It Called ==
The game engine will call your OnUpdate function once each frame.  This is (in most cases) extremely excessive.
The game engine will call your OnUpdate function once each frame.  This is (in most cases) extremely excessive.
*'''Ctrl + R'''  to see the FPS on screen.
<!---
added: *'''Ctrl + R'''  to see the FPS on screen.
- Crixi 2008-08-23
--->


=When Is It Called =
== When Is It Called ==
OnUpdate is not called on any hidden frames, only while they are shown on-screen.  OnUpdate will also never be called on a virtual frame, but will be called on any frames that inherit from one.
OnUpdate is not called on any hidden frames, only while they are shown on-screen.  OnUpdate will also never be called on a virtual frame, but will be called on any frames that inherit from one.


=Proper Use Example=
== Proper Use Example ==
; your_xml_file.xml
; your_xml_file.xml
  <Ui ...>
  <Ui ...>
Line 11: Line 18:
     ...
     ...
     <Scripts>
     <Scripts>
       <OnUpdate> MyAddon_OnUpdate(arg1); </OnUpdate>       
       <OnLoad>self.TimeSinceLastUpdate = 0 </OnLoad>
      <OnUpdate function="MyAddon_OnUpdate" />       
     </Scripts>
     </Scripts>
   </Frame>
   </Frame>
  </Ui>
  </Ui>
The important part for us is the "arg1" parameter that we're passing to our function. This is a variable that's being inherited from the WoW system telling us how long it's been since the last update call cycle.
The important part for us is the local "elapsed" (Global is arg1) parameter that we're passing to our function. This is a variable that's being inherited from the WoW system telling us how long it's been since the last update call cycle.


; your_lua_file.lua
; your_lua_file.lua
Line 22: Line 30:
   
   
  -- Functions Section
  -- Functions Section
  function MyAddon_OnUpdate(elapsed)
  function MyAddon_OnUpdate(self, elapsed)
   this.TimeSinceLastUpdate = this.TimeSinceLastUpdate + elapsed;
   self.TimeSinceLastUpdate = self.TimeSinceLastUpdate + elapsed;
   
   
   if (this.TimeSinceLastUpdate > MyAddon_UpdateInterval) then
   if (self.TimeSinceLastUpdate > MyAddon_UpdateInterval) then
     --
     --
     -- Insert your OnUpdate code here
     -- Insert your OnUpdate code here
     --
     --
   
   
     this.TimeSinceLastUpdate = 0;
     self.TimeSinceLastUpdate = 0;
   end
   end
  end
  end
Line 36: Line 44:


If you're doing things that require high accuracy in the frequency of the OnUpdate calls, the above code won't be accurate since every time it is called, you will lose milliseconds as the ''TimeSinceLastUpdate'' variable is reset to 0 (If it was 1.05 seconds since last update, it would take 0.05 more seconds until the next update than it should, assuming that one hits 1.0, otherwise it would be delayed by another 0.05, etc). The below code accounts for this, and has a ''while'' structure to make sure that if the players framerate is very low, it'll still do the updates as many times as is needed.
If you're doing things that require high accuracy in the frequency of the OnUpdate calls, the above code won't be accurate since every time it is called, you will lose milliseconds as the ''TimeSinceLastUpdate'' variable is reset to 0 (If it was 1.05 seconds since last update, it would take 0.05 more seconds until the next update than it should, assuming that one hits 1.0, otherwise it would be delayed by another 0.05, etc). The below code accounts for this, and has a ''while'' structure to make sure that if the players framerate is very low, it'll still do the updates as many times as is needed.
  function MyAddon_OnUpdate(elapsed)
  function MyAddon_OnUpdate(self, elapsed)
   this.TimeSinceLastUpdate = this.TimeSinceLastUpdate + elapsed;
   self.TimeSinceLastUpdate = self.TimeSinceLastUpdate + elapsed;
   
   
   while (this.TimeSinceLastUpdate > MyAddon_UpdateInterval) do
   while (self.TimeSinceLastUpdate > MyAddon_UpdateInterval) do
     --
     --
     -- Insert your OnUpdate code here
     -- Insert your OnUpdate code here
     --
     --
   
   
     this.TimeSinceLastUpdate = this.TimeSinceLastUpdate - MyAddon_UpdateInterval;
     self.TimeSinceLastUpdate = self.TimeSinceLastUpdate - MyAddon_UpdateInterval;
   end
   end
  end
  end
[[Category:HOWTOs|Use OnUpdate Correctly]]
[[Category:HOWTOs|Use OnUpdate Correctly]]

Latest revision as of 04:49, 15 August 2023

This page is a guide on using OnUpdate correctly.

How Often Is It Called[edit]

The game engine will call your OnUpdate function once each frame. This is (in most cases) extremely excessive.

  • Ctrl + R to see the FPS on screen.

When Is It Called[edit]

OnUpdate is not called on any hidden frames, only while they are shown on-screen. OnUpdate will also never be called on a virtual frame, but will be called on any frames that inherit from one.

Proper Use Example[edit]

your_xml_file.xml
<Ui ...>
  <Frame ...>
    ...
    <Scripts>
      <OnLoad>self.TimeSinceLastUpdate = 0 </OnLoad>
      <OnUpdate function="MyAddon_OnUpdate" />      
    </Scripts>			
  </Frame>
</Ui>

The important part for us is the local "elapsed" (Global is arg1) parameter that we're passing to our function. This is a variable that's being inherited from the WoW system telling us how long it's been since the last update call cycle.

your_lua_file.lua
-- Globals Section
MyAddon_UpdateInterval = 1.0; -- How often the OnUpdate code will run (in seconds)

-- Functions Section
function MyAddon_OnUpdate(self, elapsed)
  self.TimeSinceLastUpdate = self.TimeSinceLastUpdate + elapsed; 	

  if (self.TimeSinceLastUpdate > MyAddon_UpdateInterval) then
    --
    -- Insert your OnUpdate code here
    --

    self.TimeSinceLastUpdate = 0;
  end
end

Insert your code at the '-- Insert your OnUpdate code here', and substitute the MyAddon_ with your addon's name. You might also want to tweak your MyAddon_UpdateInterval global variable to reflect how often your addon needs the code run; the less the better. This solution also happens to be thread-safe, which is another issue when your code is being run every 0.1 seconds, finished or not.

If you're doing things that require high accuracy in the frequency of the OnUpdate calls, the above code won't be accurate since every time it is called, you will lose milliseconds as the TimeSinceLastUpdate variable is reset to 0 (If it was 1.05 seconds since last update, it would take 0.05 more seconds until the next update than it should, assuming that one hits 1.0, otherwise it would be delayed by another 0.05, etc). The below code accounts for this, and has a while structure to make sure that if the players framerate is very low, it'll still do the updates as many times as is needed.

function MyAddon_OnUpdate(self, elapsed)
  self.TimeSinceLastUpdate = self.TimeSinceLastUpdate + elapsed; 	

  while (self.TimeSinceLastUpdate > MyAddon_UpdateInterval) do
    --
    -- Insert your OnUpdate code here
    --

    self.TimeSinceLastUpdate = self.TimeSinceLastUpdate - MyAddon_UpdateInterval;
  end
end