Dark Legion Forum (http://www.daoc-darklegion.de/index.php)
- Öffentlicher Bereich (http://www.daoc-darklegion.de/board.php?boardid=1)
-- Interface Erweiterungen - SharkUI (http://www.daoc-darklegion.de/board.php?boardid=53)
--- UI Ladezeiten (http://www.daoc-darklegion.de/threadid.php?threadid=2511)


Geschrieben von Riemu am 04.04.2006 um 11:04:

  UI Ladezeiten

http://forums.worldofwarcraft.com/thread.aspx?fn=wow-realm-argentdawn&t=253872

http://forums.worldofwarcraft.com/thread.aspx?fn=wow-interface-customization&t=352710&p=#post352710

Zitat:
Anyone around here have problems with load times in excess of 1-2 minutes when zoning from one place to another? I may have an easy solution for ya. A little time consuming, but still very viable.

This needs to be repeated for every mod you have, or at least those dealing with bags/bars/buttons/etc.

Let me explain a little how this fix works first, before going over the 'how to'.

When you zone, the server sends the event "PLAYER_LEAVING_WORLD" to the UI, which indicates that you are starting to zone. When the loading bar gets full on the other side of the zone, it will send the event "PLAYER_ENTERING_WORLD". The problem most people have with loading times, is because as soon as that "PLAYER_ENTERING_WORLD" event fires, the UI rushes to catch up to all events it missed in that load time. The longer the load time, the more events it has to catch up on, and the longer it will take you to complete zoning.

As an example, in Blackwing Lair, I was one of the last to zone in, and I recieved over a few hundred "BAG_UPDATE" events, and a few hundred "UNIT_MANA" or somesuch updates. My average zone time hovering around 1.5 minutes.

Basically, every mod you have, has events it registers to listen to, to parse events which occur, such as cooldowns ending, unit HP chanages, items moving in your inventory, etc. Why do you need to listen to these when you can't see your character? Well it depends on the type of mod. Chat mods, as an example, you do not want to turn off. If you turn off Chat mods, they will not be able to process any data sent while you were zoning. Essentially though, any other mod that does not rely on outside 'events' (IE the chat based mods) can use this to improve your load times.

The fix, essentially involves watching for the two events: "PLAYER_ENTERING_WORLD", and "PLAYER_LEAVING_WORLD". When we enter the world, we want to make the mod listen to all the events it should, and when we leave, we want to STOP listening so we don't have to parse all that data!

A good example to start with (that I will use) is AllInOneInventory.

First, open AllInOneInventory.lua in notepad (if it comes up with little box characters and looks funny, close it, open it in WordPad, save, close and reopen in notepad to fix it.)

Search for: RegisterEvent, and try to find one where you have something like:
this:RegisterEvent("BAG_UPDATE"); or somesuch. You'll find that there is no such one. There's only two:
this:RegisterEvent("PLAYER_LOGIN");
this:RegisterEvent("ADDON_LOADED");
these are just to notify the mod that the game is loaded, and we are ready to fly. In almost all cases, if the mod can be 'fixed' by this method, the function name you will have will be something like:
function MyMod_OnLoad()

In any case, lets try the other LUA files (remember, you may have to search through each of the LUA files, and sometimes even the XML file too!), although generally it will NOT be in the localization files.

The next file to check will be the AllInOneInventory_Items.lua file.

In fact, in this file, you need not even try to use search, it's right almost at the top! You see this function:


function AllInOneInventoryItemsFrame_OnLoad()

local f = AllInOneInventoryItemsFrame;

f:RegisterEvent("BAG_UPDATE");

f:RegisterEvent("BAG_UPDATE_COOLDOWN");

f:RegisterEvent("ITEM_LOCK_CHANGED");

f:RegisterEvent("UPDATE_INVENTORY_ALERTS");

f:RegisterEvent("VARIABLES_LOADED");

end



This is exactly what we are looking for! Now, we need to add two new events to this, so following the same thing they used here for RegisterEvent, we register two new events on top of this. We need to add "PLAYER_ENTERING_WORLD", and "PLAYER_LEAVING_WORLD".

After adding the events, the file should look like this:


function AllInOneInventoryItemsFrame_OnLoad()

local f = AllInOneInventoryItemsFrame;

f:RegisterEvent("PLAYER_ENTERING_WORLD");

f:RegisterEvent("PLAYER_LEAVING_WORLD");

f:RegisterEvent("BAG_UPDATE");

f:RegisterEvent("BAG_UPDATE_COOLDOWN");

f:RegisterEvent("ITEM_LOCK_CHANGED");

f:RegisterEvent("UPDATE_INVENTORY_ALERTS");

f:RegisterEvent("VARIABLES_LOADED");

end



Okay, now we are 1/3 of the way done! Our next step is to have the client start and stop listening to these other events when we need it, so copy and paste that whole muck of register events, along with the local variable (most mods don't use local variables, just simply refer to 'this:RegisterEvent("EVENT_NAME")')

The next thing we need to look for is an OnEvent handler, that handles these events when they occur. If you use CTRL+F to search for _OnEvent, you will come to the following function:


function AllInOneInventoryItemsFrame_OnEvent(event)

if ( event == "BAG_UPDATE" ) then

AllInOneInventoryItemsFrame_DoUpdate(arg1);

return;

end

if ( event == "BAG_UPDATE_COOLDOWN" ) then

AllInOneInventoryItemsFrame_DoUpdate(arg1, true);

return;

end

if ( event == "ITEM_LOCK_CHANGED" ) then

AllInOneInventoryItems_UpdateFrame();

return;

end

if ( event == "UPDATE_INVENTORY_ALERTS" ) then

AllInOneInventoryItems_UpdateFrame();

return;

end

if ( event == "VARIABLES_LOADED" ) then

local f = AllInOneInventoryItemsFrame;

f:UnregisterEvent(event);

AllInOneInventoryItemsFrame_DoUpdate();

return;

end

end



This is where the magic of the mod takes place for the most part, where it handles all the events wow sends it. So, to get this to work, we need to create two if statements. These two if statements will check for "PLAYER_ENTERING_WORLD" and "PLAYER_LEAVING_WORLD" and register/unregister the events based on that. Here are the functions I used:


if ( event == "PLAYER_ENTERING_WORLD") then

local f = AllInOneInventoryItemsFrame;

f:RegisterEvent("BAG_UPDATE");

f:RegisterEvent("BAG_UPDATE_COOLDOWN");

f:RegisterEvent("ITEM_LOCK_CHANGED");

f:RegisterEvent("UPDATE_INVENTORY_ALERTS");

f:RegisterEvent("VARIABLES_LOADED");

return;

end

if ( event == "PLAYER_LEAVING_WORLD") then

local f = AllInOneInventoryItemsFrame;

f:UnregisterEvent("BAG_UPDATE");

f:UnregisterEvent("BAG_UPDATE_COOLDOWN");

f:UnregisterEvent("ITEM_LOCK_CHANGED");

f:UnregisterEvent("UPDATE_INVENTORY_ALERTS");

f:UnregisterEvent("VARIABLES_LOADED");

return;

end



piece of cake smile . All I did was copy and pasted the events from the OnLoad function into here, after checking for the PLAYER_WHATEVER_WORLD events. If player is LEAVING, then we STOP listining (IE UnregisterEvent), and vice versa when ENTERING world. Make sure to place the "return;" at the end of the if statement, as we want the function to end when the event is done unregistering/registering.

We then place these if statements to the BOTTOM of the function. Why the bottom? Because these are 'low priority'. We want the other functions to go as fast as they can, as they will probably be run more often then the registering/unregistering. This speeds up the function, if only slightly, for normal processing, thus leaving no impact for the normal mod operation.

The final OnEvent looks like so:


function AllInOneInventoryItemsFrame_OnEvent(event)

if ( event == "BAG_UPDATE" ) then

AllInOneInventoryItemsFrame_DoUpdate(arg1);

return;

end

if ( event == "BAG_UPDATE_COOLDOWN" ) then

AllInOneInventoryItemsFrame_DoUpdate(arg1, true);

return;

end

if ( event == "ITEM_LOCK_CHANGED" ) then

AllInOneInventoryItems_UpdateFrame();

return;

end

if ( event == "UPDATE_INVENTORY_ALERTS" ) then

AllInOneInventoryItems_UpdateFrame();

return;

end

if ( event == "VARIABLES_LOADED" ) then

local f = AllInOneInventoryItemsFrame;

f:UnregisterEvent(event);

AllInOneInventoryItemsFrame_DoUpdate();

return;

end

if ( event == "PLAYER_ENTERING_WORLD") then

local f = AllInOneInventoryItemsFrame;

f:RegisterEvent("BAG_UPDATE");

f:RegisterEvent("BAG_UPDATE_COOLDOWN");

f:RegisterEvent("ITEM_LOCK_CHANGED");

f:RegisterEvent("UPDATE_INVENTORY_ALERTS");

f:RegisterEvent("VARIABLES_LOADED");

return;

end

if ( event == "PLAYER_LEAVING_WORLD") then

local f = AllInOneInventoryItemsFrame;

f:UnregisterEvent("BAG_UPDATE");

f:UnregisterEvent("BAG_UPDATE_COOLDOWN");

f:UnregisterEvent("ITEM_LOCK_CHANGED");

f:UnregisterEvent("UPDATE_INVENTORY_ALERTS");

f:UnregisterEvent("VARIABLES_LOADED");

return;

end

end



save the file, and move on to the next mod! That's the only three changes that need to be made.

Summary of what we did:


* Add frame:RegisterEvent("PLAYER_ENTERING/LEAVING_WORLD"); events to OnLoad handler to allow us to watch for these events.
* Add if/then check for "PLAYER_ENTERING/LEAVING_WORLD" to OnEvent handler to allow us to register/unregister watching for events.
* Use this:RegisterEvent("EVENT_NAME") inside "PLAYER_ENTERING_WORLD" event handler
* Use this:UnregisterEvent("EVENT_NAME") inside "PLAYER_LEAVING_WORLD" event handler



Be sure to back up the mod before attempting this, so if you make a mistake, you have something to go back to, instead of redownloading/etc. Using this, I was able to decrease my loading time from that approx. 1.5 minutes down to 15-20 seconds, and I only did this to my bar mods/bag mods/map mods, as I figured these ones would have the greatest impact. If you find the OnLoad handler, and it has no real things in it as far as RegisterEvent goes, then move on to the next file/mod, as those are most likely using more advanced systems I'm not going to get into right now. If you have any questions, just let me know. I will NOT do this for you, but I will help if there are any general concerns on the basic operation.

To determine which Events are best to filter out, in the case of advanced users, I found the following utility extremely useful to figure out where the biggest impact was coming from:

Warmup
http://ui.worldofwar.net/ui.php?id=1644&page=2

This mod will tell you exactly what events are being run, how many times it runs, and how long your mods take to load for the first time when you first log in.

Hopefully this helps some people, if so, I may post this on the interface forums as well.

-TigerHeart



Geschrieben von Shark am 04.04.2006 um 11:26:

 

Gehe seit 5 Stunden alle Addons durch, bin mir aber nicht sicher ob es wirklich hilft, da ich schon seit UI 6.0 für 15 Sek beim Zonen alle Eventhandler abschalte.

edit:

Nochmal drüber nachgedacht, und die Eventabschaltung wird durch das Addon Fastmount gemacht, d.h. wenn jmd dieses disabled hat, hat er nichts davon. Werde es vom FastMount zum Core verschieben.



Geschrieben von Luariina am 04.04.2006 um 15:51:

 

Hab die neuste Version und wollte nur sagen "WOW".
Vorher Zone Zeiten von ~1min gehabt; jetzt geht das in 10sec smile

Also für mich hat sich deine Mühe echt rentiert; vielen Dank!


Powered by: Burning Board 2.1.6 © 2001-2003 WoltLab GbR