Thread Tools Display Modes
11/23/14, 06:29 AM   #1
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,963
[Need help pls] Find slowdown bug at Advanced Filters & FCOItemSaver addons

Hey all,

I'm the developer of FCOItemSaver and need some help please.

About my addon:
FCOItemSaver is an addon which allows you to mark items in your inventories/banks.
These marked items will show in the inventories at the left to the item's name (e.g. a red lock or a yellow coin, or both at the same icon):


You are able to filter these marked items by buttons at the bottom of the inventories. These buttons look like the icon itself and change their state and color if you click them (filter enabled: hide all marked items=green, Filter enabled and only show marked: show only marked items=yellow, Filter disabled: show all items including marked ones=red):


So you are able to hide items you have marked to prevent them from beeing deconstructed or selling them (if filter is enabled, set to green):


Used library:
ESO is able to use additional filters for the list dialogs (inventories e.g.) to hide/show items.
This is how your inventory tab "Junk" only shows items marked as junk e.g.!

The addon AdvancedFilters and FCOItemSaver both use this library: "libFilters"
libFilters registers custom made filters to the additional filters.

This library will queue all filters, coming from different addons (e.g. AdvancedFilters + AF Plugins, ItemSaver, FCOItemSaver, and maybe others), and enable/disable them at the different panels (inventory, banks, stores, mail, trading to players, crafting stations, enchanting station, guild store).
AdvancedFilters even uses some subfilters (like the different weapon, armor, material types, etc.).


Problem:
After the last update to the game (v1.5), and some following changes to the addon Advanced Filters, my addon FCOItemSaver will crash the game, or at least slow it really down!

If you have opened the bank/guild bank, at least one item is marked with an icon, and at least one of the filters is enabled (green), and you change the AdvancedFilters tabs then (from "All" to "Weapons", or from "Weapons" to "Armor", or from "Armor" to "Materials", etc.)

the game will slow down or crash.

The more often you change the tabs the slower the client becomes.
-> If you use Wykkyd's information bar you can watch the FPS drop to below 10 and the ping increase up to several seconds o0.

I tried to recode the registering and unregistering of the filters but all my changes do not solve the slow down problem

So I'm searching for some experienced LUA developer who can review the code of FCOItemSaver, AdvancedFilters & libFilters to see why the game slows down all of sudden!
Thank you very much in advance for your help!


How to rebuild the problem:
1. Download and install AdvancedFilters addon: http://www.esoui.com/downloads/info2...edFilters.html
2. Download my current version of addon FCOItemSaver from dropbox (unreleased beta with recode of registering/unregistering filters): https://dl.dropboxusercontent.com/u/..._3_1b_beta.zip
3.Delete/rename "FcoItemSaver.lua" file from "SavedVariables" if you have used my addon before!
3. Play the game with standard settings of FCOItemSaver
4. Go to the bank or guild bank and open the bank panel
5. Mark at least one item with any icon (e.g. the "lock" icon) by right clicking the item in your bank/inventory and choosing the context (e.g. "Lock", "Add to gear 1", or "Mark for research")
6. Enable the appropriate filter (lock icon = lock filter, helmet icon = helmet filter, research icon=reserach filter, coin icon=coin filter) at the bottom of the bank inventory, by clicking on the button.
The filter button at the bottom of the inventory must be "green"!
The chat will give you feedback about the filter state too.
7. Change AdvancedFilters tabs a bit (from "AlL" to "Weapons" to "Armor" back to "AlL" and then to "Materials" etc.

The game client should slow down very fast and each change of AdvancedFilters tabs should slow it down even more.
This will only happen if FCOItemSaver is enabled. If you disable the addon and do a /reloadui changing the tabs at AdvancedFilters will work very quick and stable.

Information on error finding:
If you click on the filter buttons at the bottom of the inventories the function "doFilter()" will be called to change the filter state and unregister (function unregisterAllFilters()) the previous filter (if it was set) + registering (function registerAllFilters()) the new filter.
It depends on the panel (p_FilterPanelId) where you are (deconstruction, bank, inventory, mail, etc.) and the button you've clicked (filterId).

The unique filter's name, used to register the filter with library "libFilters" will be depending on the panel where you currently are:

Possible filterIds:
1: Left button at the bottom (Standard: lock icon)
2: 2nd button from left at the bottom (Standard: helmet icon)
3: 3rd button from left at the bottom (Standard: research icon)
4: 4th button from left at the bottom (Standard: coins icon)

Possible p_FilterPanelIds:
INV_BAGS = 1
INV_BANK = 2
INV_GUILDBANK = 3
INV_STORE = 4
INV_DECONSTRUCTION = 5
INV_GUILDSTORE = 6
INV_MAIL = 7
INV_TRADE = 8
INV_ENCHANTING = 9

Unique filter names:
Player bank filter: "FCOItemSaver_PlayerBankFilterNew<p_FilterPanelId>_<filterId>"
Guild bank filter: "FCOItemSaver_GuildBankFilterNew<p_FilterPanelId>_<filterId>"
Deconstruction filter: "FCOItemSaver_DeconstructionFilterNew<p_FilterPanelId>_<filterId>"
Guild store filter: "FCOItemSaver_GuildStoreFilterNew<p_FilterPanelId>_<filterId>"
Vendor filter: "FCOItemSaver_FilterNew<p_FilterPanelId>_<filterId>"
...

Error searching:
I tracked it down to the "libfilters:RegisterFilter()" function somehow.
Unregistering the filters works quick and without problems.
But (re)registering the filters will slow everything down.
I wasn't able to see where exactly the slowdown happens.

It seems to happen if you have at least one of the FCOItemSaver filters registered and then change the AdvancedFilters tab -> The given filters stay registered and all the new AdvancedFilters filters (e.g. "Weapons") + subfilters (e.g. "Axe", "Sword", etc.) get registered.

See function libFilters:RegisterFilter -> arrays idToFilter and thisFilter ->
if filterType == LAF_BANK -> SetInventoryFilter(LAF_BANK) -> filtertype = LAF_BANK -> inventorytype = INVENTORY_BANK -> currentFilter holds the registered filters (including FCOItemSaver filter) -> new filters will be added in callback function for PLAYER_INVENTORY.inventories[inventoryType].additionalFilter afterwards, respecting the currentFilters too:
Lua Code:
  1. --handle already existing filters
  2.             if(currentFilter) then
  3.                 result = result and currentFilter(slot)
  4.             end

I hope someone of you can help me fix this bug so ppl can use my addon again without any problems.
Thank you very much!
  Reply With Quote
11/23/14, 07:24 AM   #2
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
This looks so interesting that I can't resist

The first thing I noticed is that libFilters has a few loops like this:
Lua Code:
  1. function(slot)                              
  2.             local result = true                    
  3.             for _,v in pairs(filters[filterType]) do
  4.                 if(v) then                          
  5.                     result = result and v(slot)    
  6.                 end                                
  7.             end                                    
  8.             return result                          
  9.         end

These should do an early return, once any of the filters returns false, the result is final. I will send changes to Randactyl later; but this little thing can only cure some symptoms, not the disease (if the disease is filters accumulating in the list). So I guess I'll need to dig deeper
  Reply With Quote
11/23/14, 07:34 AM   #3
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,963
I hoped so @interesting
Thx man! I hope it is not any small bug or typo which causes this issue...
Every help is very appreciated!

Even small findings can improve the overall performance
If I understand you right:
If any of the registered filters for the current filterType (e.g. LAF_BANK) returns false the other filters shouldn't be executed/needed anymore, because the item will be hidden.
So one could abort the for ... do loop already in between?

Edit:
I've added a chat output in libFilters function SetInventoryFilter() to see which filters are registered upon loading of the game (Advanced filters & FCOItemSaver enabled) and when you click on FCOItemSaver filter button or any button in your inventory (weapons, armory, materials, etc.).
I also added a counter variable to libfilters which increases by 1 in the function SetInventoryFilter() at this line:
Code:
if(v) then
                	cnt = cnt + 1

Upon loading of the game (checked via Bugeater addon to see extra chat output before addons are loaded finally) I have a list of 24518 times filter "AdvancedFilters_Dropdown_Filter". This looks a bit much for me?


Same if you click on one of the AdvancedFilters buttons, e.g. the "Weapons". The filter list will explode with another 51 entries adding the filter "AdvancedFilters_Button_Filter".

If I click through the other Advanced Filters tabs the dropdown filter will be added (if I choose only "Bows" for example).

After clicking around the filter counter increased to 33492 in total.
Only changing from quest items to junk view added 884 new entries...

Maybe your fix about the "false" filter results will fix a bit of these, but aren't these numbers too high in total? Or am I missing something why this values are that high? Is the function SetInventoryFilter() executed for every item in the bags and that multiple times? I thought it is only for the bags and only if a filter is registered (upon change of a given filter).

Last edited by Baertram : 11/23/14 at 01:55 PM.
  Reply With Quote
11/23/14, 06:07 PM   #4
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
Originally Posted by Baertram View Post
I hoped so @interesting
Thx man! I hope it is not any small bug or typo which causes this issue...
Every help is very appreciated!

Even small findings can improve the overall performance
If I understand you right:
If any of the registered filters for the current filterType (e.g. LAF_BANK) returns false the other filters shouldn't be executed/needed anymore, because the item will be hidden.
So one could abort the for ... do loop already in between?

Edit:
I've added a chat output in libFilters function SetInventoryFilter() to see which filters are registered upon loading of the game (Advanced filters & FCOItemSaver enabled) and when you click on FCOItemSaver filter button or any button in your inventory (weapons, armory, materials, etc.).
I also added a counter variable to libfilters which increases by 1 in the function SetInventoryFilter() at this line:
Code:
if(v) then
                	cnt = cnt + 1

Upon loading of the game (checked via Bugeater addon to see extra chat output before addons are loaded finally) I have a list of 24518 times filter "AdvancedFilters_Dropdown_Filter". This looks a bit much for me?


Same if you click on one of the AdvancedFilters buttons, e.g. the "Weapons". The filter list will explode with another 51 entries adding the filter "AdvancedFilters_Button_Filter".

If I click through the other Advanced Filters tabs the dropdown filter will be added (if I choose only "Bows" for example).

After clicking around the filter counter increased to 33492 in total.
Only changing from quest items to junk view added 884 new entries...

Maybe your fix about the "false" filter results will fix a bit of these, but aren't these numbers too high in total? Or am I missing something why this values are that high? Is the function SetInventoryFilter() executed for every item in the bags and that multiple times? I thought it is only for the bags and only if a filter is registered (upon change of a given filter).
I wrote something just like advanced filters but I didnt do any of the filtering like libFilters does. I'm trying to figure it all out. I do see one thing so far though:
Lua Code:
  1. -- in libfilters.lua
  2. -- this should be local
  3. filters = libFilters.filters
  Reply With Quote
11/23/14, 07:33 PM   #5
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
I don't have much time & I am leaving for thanksgiving soon and will be gone for a week. I didn't find anything else wrong, but if all else fails...this may or may not be a better way to do it, just giving options.
I know this is not what your asking, but you could just filter the items yourself, eliminating libFitlers. I haven't used itemSaver or Advanced Filters so this may or may not cover everything you need to do in your addons.

Creating filters is not very hard, it can be done with 1 function & 1 line of code to change the filter. This is how the game does its filtering, I did it in an addon. The only problem I see is that since Advanced Filters is using libFilter & you would not be, Advanced filters might not filter your stuff correctly...but that could easily be solved. I wrote my own filter library (um never released it though wasn't really designed to track stuff for other addons also, maybe I will change that and release it when I get back next week).

Anyhow if your interested or for anyone else reading this creating filters is pretty easy. All you have to do is create a tabFilter & put it into the inventories tabFilter table, then call that inventories ChangeFilter(tabData) passing in your tabFitler....thats it.
Note: this has some extra code you would not need since you do not need a physical button...but advanced filters would so although some of this code (namely all of the parameters) are not used, I left some of the code from my addon in there to give everyone ideas on what you could do with it.

Warning: Spoiler


The default, built in, filterTypes that you can call are:
Lua Code:
  1. ITEMFILTERTYPE_ALL
  2. ITEMFILTERTYPE_WEAPONS
  3. ITEMFILTERTYPE_ARMOR
  4. ITEMFILTERTYPE_CONSUMABLE
  5. ITEMFILTERTYPE_CRAFTING
  6. ITEMFILTERTYPE_MISCELLANEOUS
  7. ITEMFILTERTYPE_JUNK

If you want to create your own filters to only display certain items all you have to do now is add a UNIQUE filter number to the items filterData table (found in /zgoo the item, goto dataEntry, data, filterData).
So say you create your own filterType:
Lua Code:
  1. local ITEMFILTERTYPE_FCOLOCKED = 137  -- whatever unique number
Then just place that number in the locked items filterData table, create a filterTab out of it, put the filterTab into the inventories tabFilters table, then when your ready call this (passing in your tabData filter)
Lua Code:
  1. PLAYER_INVENTORY:ChangeFilter(tabData)

You could create your own buttons to change the filters, add buttons to the inventory menu bar to do it, or hook the inventory menu bar buttons to change what they actualy show, whatever...

You would just have to handle the slotUpdate to handle when items are moved, sold, destroyed, looted, exc..to update its filterData values.
Oh and on initializing loop putting the filterData values into the tables too so they are there when the player logs in or /reloadui.

P.S. do be aware that bank inventory slots are not populated until the user opens the bank so you could not insert filterData until its populated..although you can do this to fix that problem:
Lua Code:
  1. PLAYER_INVENTORY:RefreshAllInventorySlots(iInventory)
Will refresh the slots, use it on the bank for example then the items (slots) will become available even before the user opens the bank.

So when you originally populate the slots on load you could do something like this:
Lua Code:
  1. local tSlots = PLAYER_INVENTORY.inventories[iInventory].slots
  2.     if not tSlot then
  3.         PLAYER_INVENTORY:RefreshAllInventorySlots(iInventory)
  4.         tSlots   = PLAYER_INVENTORY.inventories[iInventory].slots
  5.     end
  Reply With Quote
11/23/14, 11:44 PM   #6
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
Ok, couldn't sleep so had some more time to look at it, here is "A" problem I see. This seems to be the one causing the most lag.
A zillion edits, sorry I hate type-o's and grammar mistakes and I make tons of them.

One of the problems is with libFilters

In this click of a single inventory tab libFilters runs all of this:

Side note: Edit: See my next post about Advanced Filters on this problem. I didn't dig this deep into it, there may be a reason, but you might also want to look at: Why is libFilters Unregistering AdvancedFilters_Dropdown_fitler twice in a row, then registering it, then unregistering it again, then registering it again ? It also shows the AdvancedFilters_Button_Filter being unregistered twice in a row, then reregistered?

All of that is in a single click of an inventory tab and those are supposed to be unique filter ID's are they not? so it has to be the same thing its unregistering & registering multiple times correct?
The main problem is updating the filter list after every single register & unregister event. It processes every single slot like 20-30 ?more? times (I got tired of counting them) in the click of a single button. If even more addons were using this or you guys were registering multiple (more) filters it would probably crash users instantly.
I'm not sure why everything is registered & unregistered all of the time....why aren't filters just registered, left in a table & called when needed...
Anyhow It can be fixed doing this (not saying its ideal, I'm no expert here)

The main idea would be to just zo_calllater the UpdateFilteredList() and put a lock on it..
So set a flag, I called it updateSet (as in the update is set to process), when its true a zo_calllater has already been made for the UpdateFilteredList() to run after however long.
This gives all filters a chance to register/unregister before it runs. So that UpdateFilteredList() only needs to run once.


First make a new local variable for our lock flag in libFilters:
Lua Code:
  1. local updateSet = false
That tells us whether or not an UpdateFilteredList(..) has already been called with a zo_calllater (to run sometime in the future). This way if the lock flag is already set, we wont keep calling UpdateFilteredList() over & over for no reason. You probably want to adjust the time, i put 100ms in there just as a random number to test it.


Changes: function libFilters:RegisterFilter( filterId, filterType, filterCallback )
Warning: Spoiler



Changes: function libFilters:UnregisterFilter( filterId )
Warning: Spoiler


** Do note I would make sure you call
Lua Code:
  1. -- This line
  2. updateSet = false
  3. -- before calling this line
  4. UpdateFilteredList(filterType)
This way if something has already called RegisterFilter or UnRegisterFilter while the UpdateFilteredList is running...the new register/unregister event will have a chance to call another zo_calllater'd UpdateFilteredList because it will miss the....UpdateFilteredList that is already in progress.

If you called updateSet = false after calling UpdateFilteredList() something could slip through the cracks.
wow...I hope that made sense :P

P.S. And don't forget, this should be local !
Lua Code:
  1. -- in libfilters.lua
  2. -- this should be local
  3. filters = libFilters.filters

Last edited by circonian : 11/25/14 at 12:49 AM.
  Reply With Quote
11/24/14, 01:14 AM   #7
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
Advanced Filters

In advanced Filters I see this:

On a single click of an inventory button:
Oops, my picture is missing the first 3 lines:

Unregistering a filter: AdvancedFilters_Button_Filter
Unregistering a filter: AdvancedFilters_Dropdown_Filter
ResetToAll


* thats just d("xxxxx") code I added to AF

1) So ChangeFilter( self, filterTab ) gets called which calls
2) ResetToAll() gets called, which unregisters the AdvancedFilters_Dropdown_FIlter, and the AdvancedFilters_Button_Filter
That seems ok...

3) But then ResetToAll() selects the first item in the dropdown...which in turn fires:
4) OnDropDownSelect (through the function assigned to the dropdown items) which calls SetUpCallbackFilter, which attempts to unregister the AdvancedFilters_Dropdown_Filter again and then reregisters the AdvancedFilters_Dropdown_FIlter,

5) Then the OnClickedCallback fires, which again selects the first item in the dropdown...which starts the cycle all over:
6) Fires OnDropdownSelect, SetUpCallbackFilter, which unregisteres & reregisters AdvancedFilters_Dropdown_FIlter, filters again.

7) And then at the end of the OnClickedCallback...it has its own code to manually fire: SetUpCallbackFilter again...
Although this one might look like it is ok, its for the button this time, not the Dropdown_Filter BUT...it does end up attempting to Unregister the AdvancedFilters_Button_Filter again, which we already did at the very beginning in ChangeFilter(...), then it reregisters the button filter.

Aren't these filterID's UNIQUE...why are they being unregistered at all, if you just re-register the exact same filter ?
Either way the exact same filter is getting unregistered & reregistered multiple times as we can see, unless I am missing something if the filterID's are not unique or being changed in the code somewhere & I missed it.


If you can get libFilter fixed so it doesn't call UpdateFilterList on every Register/Unregister, and you straighten out this sequence of code events in AdvancedFilters so it doesn't select the first item in the dropdown multple times and stop it from firing extra register/unregister events I think the two will solve all your problems.

Last edited by circonian : 11/24/14 at 01:41 AM.
  Reply With Quote
11/24/14, 02:07 AM   #8
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
Originally Posted by Baertram View Post
I hoped so @interesting
Thx man! I hope it is not any small bug or typo which causes this issue...
Every help is very appreciated!

Even small findings can improve the overall performance
If I understand you right:
If any of the registered filters for the current filterType (e.g. LAF_BANK) returns false the other filters shouldn't be executed/needed anymore, because the item will be hidden.
So one could abort the for ... do loop already in between?
Yes, since your always doing:
Lua Code:
  1. result = result and <something else>
if result is already false, its always going to return false, regardless of what <something else> is.


Someone please correct me if I'm misunderstanding this part, but isn't the if statement unnecessary?
Lua Code:
  1. for _,v in pairs(filters[filterType]) do
  2.    if(v) then
  3.       result = result and v(slot)
  4.    end
  5. end

Doesn't v just represent functions in the table that tell if something should be displayed or not...since v is not a boolean (correct?) then wont the: if(v) always return true. If v did not exist it never would have made it to that part of the code, it would have broken out of the for loop before that.

So then couldn't he just do:
Lua Code:
  1. for _,v in pairs(filters[filterType]) do
  2.    result = result and v(slot)
  3.    if result == false then
  4.       return result
  5.    end
  6. end

Last edited by circonian : 11/24/14 at 02:14 AM.
  Reply With Quote
11/24/14, 02:23 AM   #9
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
Anyways

So anyways, I hope that helps you guys out some. Goodluck getting it all straightened out !
  Reply With Quote
11/24/14, 10:54 AM   #10
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,963
Thank you very much for all your analysis Circonian!!!

I didn't dig this deep into it, there may be a reason, but you might also want to look at: Why is libFilters Unregistering AdvancedFilters_Dropdown_fitler twice in a row, then registering it, then unregistering it again, then registering it again ? It also shows the AdvancedFilters_Button_Filter being unregistered twice in a row, then reregistered?

All of that is in a single click of an inventory tab and those are supposed to be unique filter ID's are they not? so it has to be the same thing its unregistering & registering multiple times correct?
This is EXACTLY what I've written in my post before your posts!
libFilters does unregister and reregister the filters about 30000! times in total, if you just switch around between some of the invetory tabs and subtabs of AdvancedFilters.

After your analysis of the AdvancedFilters functions for the dropdown boxes and the callback functions this seems to clear things up, why the number is that high.

Aren't these filterID's UNIQUE...why are they being unregistered at all, if you just re-register the exact same filter ?
Either way the exact same filter is getting unregistered & reregistered multiple times as we can see, unless I am missing something if the filterID's are not unique or being changed in the code somewhere & I missed it.
Yes the filter IDs are qunique. But they are used with different content and the same ID.
Example: They get unregistered to remove let's say the "armor types" dropdown filter and reregister teh same filter ID with the "weapon types" dropdown filter, if you change from the inventory tab "Armor" to "Weapons". At least this is what I understand AdvancedFilters does.
If you do not unregister the old filter the callback function will try to hide "armor types" from the "weapons" tab?!

But you are right with the question: Why is it happening so often?


Doesn't v just represent functions in the table that tell if something should be displayed or not...since v is not a boolean (correct?) then wont the: if(v) always return true. If v did not exist it never would have made it to that part of the code, it would have broken out of the for loop before that.
Yeah, you are right.

Creating filters is not very hard, it can be done with 1 function & 1 line of code to change the filter.
I know. I have coded everything without libFilters in some older versions of FCOItemSaver. I've changed to use libFilters as the library was stable and AdvancedFilters has used it, because then the filters registered will work all together between different addons. And this is what I want. I don't want to recode AdvancedFilters :-) But thx for the information.


Result
I think the bug of the slowdown comes from AdvancedFilters (dropdown change functions) + libFilters (refresh of inventories after each filter registered, where the same filters get registered a thousand times upon one inventory tab change) then.

Bug fixing
I hope the addon author of libFilters and AdvancedFilters can take a look at Circonian's research and fix the un- & reregistering + needles inventory updating in those 2 addons.
-> Maybe we can talk about the changed enchanting filter in libFilters at the same time

I'll try to find a "workaround" solution for the inventory updates too which I can implement to fix things "roughly" for now.

Question
I do not understand why the errors in AdvancdFilters and libFilters, explained by Circonian above, don't slow down the game generally?

Example:
If you simply use AdvancedFilters addon, maybe together with some of the plugin addons, the changing of inventory tabs is fast and smooth. Even here the unregistering and reregistering of filters take place about thousands of times and the inventory is updated many times.

But at the moment you enable FCOItemSaver addon too, together with AdvancedFilters, the game gets sloooooooooow.
Is this only because of the updating of inventory contents after each filter reregistering, and because FCOItemSaver uses extra textures inside the inventories to show the marked items?

I'm wondering why the game does not slow down markable if you simply use AdvancedFilters without FCOItemSaver?


To All:
Thank you very very much for all the research into this problem so far!

Last edited by Baertram : 11/24/14 at 11:12 AM.
  Reply With Quote
11/24/14, 01:24 PM   #11
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,963
I tried this zo_callLater workaround with 500ms. It is annoying as the filters won#t update after the click, but half a second later.
It seems to bring a way better performance as you switch tabs in inventories.
But only as long as you do not enable all FCOItemSaver filters (4 possible) in the inventories.
If all 4 filters are enabled each click will last for about 3 seconds again before something happens

So using the updateFlag variable is not a working workaround alone. It seems the behaviour of AdvancedFilters needs to be fixed too.



Originally Posted by circonian View Post
Ok, couldn't sleep so had some more time to look at it, here is "A" problem I see. This seems to be the one causing the most lag.
A zillion edits, sorry I hate type-o's and grammar mistakes and I make tons of them.

The problem is with libFilters

In this click of a single inventory tab libFilters runs all of this:

Side note: Edit: See my next post about Advanced Filters on this problem. I didn't dig this deep into it, there may be a reason, but you might also want to look at: Why is libFilters Unregistering AdvancedFilters_Dropdown_fitler twice in a row, then registering it, then unregistering it again, then registering it again ? It also shows the AdvancedFilters_Button_Filter being unregistered twice in a row, then reregistered?

All of that is in a single click of an inventory tab and those are supposed to be unique filter ID's are they not? so it has to be the same thing its unregistering & registering multiple times correct?
The main problem is updating the filter list after every single register & unregister event. It processes every single slot like 20-30 ?more? times (I got tired of counting them) in the click of a single button. If even more addons were using this or you guys were registering multiple (more) filters it would probably crash users instantly.
I'm not sure why everything is registered & unregistered all of the time....why aren't filters just registered, left in a table & called when needed...
Anyhow It can be fixed doing this (not saying its ideal, I'm no expert here)

The main idea would be to just zo_calllater the UpdateFilteredList() and put a lock on it..
So set a flag, I called it updateSet (as in the update is set to process), when its true a zo_calllater has already been made for the UpdateFilteredList() to run after however long.
This gives all filters a chance to register/unregister before it runs. So that UpdateFilteredList() only needs to run once.


First make a new local variable for our lock flag in libFilters:
Lua Code:
  1. local updateSet = false
That tells us whether or not an UpdateFilteredList(..) has already been called with a zo_calllater (to run sometime in the future). This way if the lock flag is already set, we wont keep calling UpdateFilteredList() over & over for no reason. You probably want to adjust the time, i put 500 in there just as a random number to test it, thats probably to long.


Changes: function libFilters:RegisterFilter( filterId, filterType, filterCallback )
Warning: Spoiler



Changes: function libFilters:UnregisterFilter( filterId )
Warning: Spoiler


** Do note I would make sure you call
Lua Code:
  1. -- This line
  2. updateSet = false
  3. -- before calling this line
  4. UpdateFilteredList(filterType)
This way if something has already called RegisterFilter or UnRegisterFilter while the UpdateFilteredList is running...the new register/unregister event will have a chance to call another zo_calllater'd UpdateFilteredList because it will miss the....UpdateFilteredList that is already in progress.

If you called updateSet = false after calling UpdateFilteredList() something could slip through the cracks.
wow...I hope that made sense :P

P.S. And don't forget, this should be local !
Lua Code:
  1. -- in libfilters.lua
  2. -- this should be local
  3. filters = libFilters.filters
  Reply With Quote
11/24/14, 03:20 PM   #12
Randactyl
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 251
Hey guys,

I just wanted to drop in and say I've been keeping tabs on this development. I've gotten your PMs, Baertram and circonian, I've just been swamped with midterms and backlogged school work.

I'll be on break soon and I'll read through everything and make changes. Thank you for doing all of this detective work in the first place!
  Reply With Quote
11/24/14, 03:49 PM   #13
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,963
Thx for giving a shout Randactyl. Take your time please. Ppl will be able to play without addons too

I'm currently testing around with AdvancedFilters and libFilters. If I find a working solution I'll send you a pm with more information.
  Reply With Quote
11/24/14, 03:58 PM   #14
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
Originally Posted by Baertram View Post
I tried this zo_callLater workaround with 500ms. It is annoying as the filters won#t update after the click, but half a second later.
It seems to bring a way better performance as you switch tabs in inventories.
But only as long as you do not enable all FCOItemSaver filters (4 possible) in the inventories.
If all 4 filters are enabled each click will last for about 3 seconds again before something happens

So using the updateFlag variable is not a working workaround alone. It seems the behaviour of AdvancedFilters needs to be fixed too.
Yeah, that 500ms was just a random number I used...its obviously way to long, 100 might even be to big.
half second later...haha...that is still quicker than what I was getting pushing tab buttons without it ;P

Also yes you are right, its not a complete fix by itself, but it was like 50 times faster than without it & I was using 500ms which is waaaayyy to long. I didn't check with all 4 filters I was just doing the 1 filter like you stated.
Originally Posted by Baertram View Post
I know. I have coded everything without libFilters in some older versions of FCOItemSaver. I've changed to use libFilters as the library was stable and AdvancedFilters has used it, because then the filters registered will work all together between different addons. And this is what I want. I don't want to recode AdvancedFilters :-) But thx for the information.
I understand, but no matter what the fact that the way libFitlers does its filtering, by calling additional filter functions to check EVERY single filter on EVERY single slot to see if the item should be displayed or not means that the more filters used (by any/all addons) the more lag every addon is going to get when a filter is changed. The more filters registered, the more addons using it, the more times every single slot has to be checked when the user pushes a button.
Which is why I originally posted about how to do the filters the other way. Then you only need to handle slotUpdate to update items "as needed" when a slot is updated. When you change a filter none of the slots need to be checked because the filterData is already up to date. The change is instant.

Originally Posted by Baertram View Post
because then the filters registered will work all together between different addons.
As I said I never used libFilters or any of these addons and when I was looking at all of this I wasn't really paying attention to what was getting filtered & what wasn't, so I may be way off in my assumptions here, but from the code that I did look at...If ANY filter returns false then the item will not be displayed correct? So I don't really see how this makes different addons filters work together. That seems to me like they actually work against each other.
If you want item 1,2, & 3 to show, but not item 4, 5, & 6...your filter returns true on the first 3 & false on the next 3. But then if another addon has filters registered that does the opposite: returning false for the first 3 items & true for the last 3...Since each item had a false return somewhere, wont all of the items end up hidden? Thus your addon did not get what it wanted Items 1, 2, & 3 were hidden?


Originally Posted by Baertram View Post
Question
I do not understand why the errors in AdvancdFilters and libFilters, explained by Circonian above, don't slow down the game generally?
Because, my guess from the things that I did test...is that the problem seemed to occur (for me at least) as I continued to click buttons, the faster I clicked the worse it got. Because there are so many updates going on & it they take so long to finish running yet...as I continue pushing buttons its starting more & more updates even though the original updates haven't even finished yet. So like you said if its updating every slot 40-50 times on a single push & I push the button again before its finished, now theres 40-50 more updates running on every single slot, then push it again now 120-150 updates running on every single slot, exc...
So why doesn't it slow the game down generally? Because eventually all of those updates finish running & the lag goes away....if that's what you meant by that.



Originally Posted by Baertram View Post
Example:
If you simply use AdvancedFilters addon, maybe together with some of the plugin addons, the changing of inventory tabs is fast and smooth. Even here the unregistering and reregistering of filters take place about thousands of times and the inventory is updated many times.

But at the moment you enable FCOItemSaver addon too, together with AdvancedFilters, the game gets sloooooooooow.
Is this only because of the updating of inventory contents after each filter reregistering, and because FCOItemSaver uses extra textures inside the inventories to show the marked items?

I'm wondering why the game does not slow down markable if you simply use AdvancedFilters without FCOItemSaver?
As for that part I have no clue. I was only checking the sequence as you had stated the visible problem from, with 1 itemSaver filter on & clicking AdvancedFilter tabs. After going through libFilters & AdvancedFilters and trying to document what I found on those two I just didn't have time to look into ItemSaver. So any other connections to the problem caused by ItemSaver I didn't get a chance to look for.
Edit: As an after thought to this question, it could it possibly be what I said above..by turning on itemSaver filters as well more & more filters get registered causing more & more updates to process on every single slot.

Last edited by circonian : 11/24/14 at 04:36 PM.
  Reply With Quote
11/24/14, 04:06 PM   #15
Sasky
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 231
Originally Posted by circonian View Post
Yes, since your always doing:
Lua Code:
  1. result = result and <something else>
if result is already false, its always going to return false, regardless of what <something else> is.


Someone please correct me if I'm misunderstanding this part, but isn't the if statement unnecessary?
Lua Code:
  1. for _,v in pairs(filters[filterType]) do
  2.    if(v) then
  3.       result = result and v(slot)
  4.    end
  5. end

Doesn't v just represent functions in the table that tell if something should be displayed or not...since v is not a boolean (correct?) then wont the: if(v) always return true. If v did not exist it never would have made it to that part of the code, it would have broken out of the for loop before that.

So then couldn't he just do:
Lua Code:
  1. for _,v in pairs(filters[filterType]) do
  2.    result = result and v(slot)
  3.    if result == false then
  4.       return result
  5.    end
  6. end
The IF would return true as long as v isn't NIL or boolean false. If it's NIL, it shouldn't even be iterated over. If it's a function it can't be false.

As far as the short circuit, it could be simplified even more if v(slot) always returns a boolean:
Lua Code:
  1. function(slot)
  2.     for _,v in pairs(filters[filterType]) do
  3.         if not v(slot) then
  4.             return false
  5.         end
  6.     end
  7.     return true
  8. end
If you hit false, it'll carry the false throughout, and the rest of the filters aren't necessary (as merlight noted) so you can immediately exit. Similarly, this also means a true return will only happen if and only if it iterates through the whole loop. And every time it processes the whole loop it'll return true, so the running assignment is unnecessary. Not as much of an optimization as early exit, but does save some assignment operations.

Last edited by Sasky : 11/24/14 at 04:09 PM.
  Reply With Quote
11/24/14, 04:39 PM   #16
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
Originally Posted by Sasky View Post
The IF would return true as long as v isn't NIL or boolean false. If it's NIL, it shouldn't even be iterated over. If it's a function it can't be false.
Yeah I just wasn't sure if v was actually functions like I thought or if it could ever possibly be something else.

Originally Posted by Sasky View Post
As far as the short circuit, it could be simplified even more if v(slot) always returns a boolean:
Lua Code:
  1. function(slot)
  2.     for _,v in pairs(filters[filterType]) do
  3.         if not v(slot) then
  4.             return false
  5.         end
  6.     end
  7.     return true
  8. end
If you hit false, it'll carry the false throughout, and the rest of the filters aren't necessary (as merlight noted) so you can immediately exit. Similarly, this also means a true return will only happen if and only if it iterates through the whole loop. And every time it processes the whole loop it'll return true, so the running assignment is unnecessary. Not as much of an optimization as early exit, but does save some assignment operations.
Oh, nice one.
  Reply With Quote
11/24/14, 06:24 PM   #17
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,963
Originally Posted by circonian;
As I said I never used libFilters or any of these addons and when I was looking at all of this I wasn't really paying attention to what was getting filtered & what wasn't, so I may be way off in my assumptions here, but from the code that I did look at...If ANY filter returns false then the item will not be displayed correct? So I don't really see how this makes different addons filters work together. That seems to me like they actually work against each other.
If you want item 1,2, & 3 to show, but not item 4, 5, & 6...your filter returns true on the first 3 & false on the next 3. But then if another addon has filters registered that does the opposite: returning false for the first 3 items & true for the last 3...Since each item had a false return somewhere, wont all of the items end up hidden? Thus your addon did not get what it wanted Items 1, 2, & 3 were hidden?
Correct. And this is how it should work. If I got several addons (FCOItemSaver, AdvancedFilters, ItemSaver, etc.) all filters should apply to one item.
Example:
I mark a medium piece of armor (some gloves) with the "Gear set 1" icon from FCOItemSaver and put the medium armor on my bank. At the bank I enable FCOItemSaver's "Gear" filter so the item will be hidden from the bank inventory.
This applies to the inventory tabs "All" and "Armor".

If I switch to the AdvancedFilters subtabs for "Armor" I can choose different armor types (light, medium, heavy) and the parts (head, body, feet, gloves, etc.) by buttons & dropdown box.
I select all medium armor (by button=1 additional filter) and gloves (by dropdown box=another filter).
In total 3 filters are active now: FCOItemSaver "gear sets", AdvancedFilters button "medium armor", AdvancedFilters dropdown "gloves".
All gloves of medium armor will be shown now, except the ones marked with FCOItemSaver's "Gear set 1" icons.
This behaviour (multiple filters of different addons apply to the same item) is wished (at least for FCOItemSaver :-) ).

You could even mark an item with 2 different icons in FCOItemSaver and enable one filter but set the other filter to "show only marked". They will work against each other too. The item will be shown because "show only marked" is set, which weights more then filter enabled (hide item).

Originally Posted by circonian;
As for that part I have no clue. I was only checking the sequence as you had stated the visible problem from, with 1 itemSaver filter on & clicking AdvancedFilter tabs. After going through libFilters & AdvancedFilters and trying to document what I found on those two I just didn't have time to look into ItemSaver. So any other connections to the problem caused by ItemSaver I didn't get a chance to look for.
Edit: As an after thought to this question, it could it possibly be what I said above..by turning on itemSaver filters as well more & more filters get registered causing more & more updates to process on every single slot.
Could be. I noticed that the really noticeable slowdown happens only at banks & guild banks. At your local vendor, crafting stations and inventory the fixed version I've tried today was working with a better performance. Maybe it is because of the amount of items stored at the banks (up to 500).

For today I'll stop trying to find a workaround. The performance was increased now, but it is still too laggy and slow.
  Reply With Quote
11/24/14, 11:46 PM   #18
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
Item Saver

On Item Saver I see this:
Now I didn't have tons of time to spend on this one, so forgive me if I missunderstood the code I glanced at or if theres more going on that I noticed, but...on a single click of an inventory tab I got so much spam on functions that are firing I couldn't even fit it all in the chat window and some serious lag . Thats even after I maxed out the chat window buffer MaxHistoryLines...which is at 1,000. I see what you mean now about having all 4 filters on.

I see this running over & over & over


This part here:
Lua Code:
  1. --Choose the filter type
  2. local function getSettingsIsFilterOn(p_filterId, p_filterPanel)
Looks like it is getting called a lot...a lot. I couldn't really tell where it was coming from, there's so many calls to it all over. But I saw no other function before it firing to call it, so it must be getting called from a hook somewhere? It would probably be easier for you to track down being more familiar with the code.

Either way, What does getSettingsIsFilterOn() do. It looks like it just checks to see if certain filters are turned on or not for certain bags/inventories ? Could you just store all of the filter states for each of the inventories in a table, then use it wherever needed instead of calling this function everywhere? As filter states change just update the table. It looks like that is what its trying to do, but the question is, is there a reason it gets called so many times?



I also see this spamming a lot, scrolling through the entire buffer.

Create marker control is set as part of your callback on inventory row items and is whats calling the other functions after it.
Almost all of the code I see getting called from the callback on the inventory is doing stuff like setting dimensions, anchors, texture, colors, setting the tiers, exc.... I may be wrong do they move or change colors? Even if they do those don't seem like they should be part of the callback code. The callback itself is not what changes the color/size, so just change the color/size whenever the user pushes a button or whatever causes the color/size change, not every time the callback fires. These controls could probably be created & setup 1 time, then hidden/shown & change colors/sizes ONLY as needed.

As for MyGetItemInstanceId, MyGetItemDetails, & SignItemId are getting called from that it looks like.


I've never used prehooks so I may misunderstand whats going on here, but just in case I thought I would point this out. In your CreateMarkerControl (which is called in a callback from the inventory hook, so it fires a lot), it looks like it is constantly creating more & more & more prehooks everytime the function makes it into that part of the code? If for whatever reason it only makes it into that part of the code once then it doesn't need to be in the callback code. It should be called elsewhere to create the prehook then never called again?
Lua Code:
  1. if (controlId==1 and parent:GetParent() == ZO_ListDialog1ListContents) then
  2.  
  3.             --Pre-Hook the handler for mouse button up, to show context menu at mouse button 2, but keep the normal OnMouseUp handler as well
  4.             --parent:SetHandler("OnMouseUp", function(control, button, upInside)
  5.             --PreHookHandler( "OnMouseUp", parent, function(control, button, upInside)
  6.             ZO_PreHookHandler(parent, "OnMouseUp", function(control, button, upInside)
  7.                 --d("Clicked: " ..control:GetName() .. ", MouseButton: " .. tostring(button))
  8.                 --button 1= left mouse button / 2= right mouse button
  9.                 if button == 2 and upInside then
  10.                     --Add the menu items to the popup dialog row (parent)
  11.                     ClearMenu()
  12.                     for i = 1, gFCONumFilterIcons, 1 do
  13.                         zo_callLater(function() AddMark(parent, i, false) end, 50)
  14.                     end
  15.                 end
  16.             end)
  17.         end


One other thing I noticed, I don't think this is a big problem I never even saw this function fire, but while I'm at all of this (you did say even little fixes will help) in this function there is a lot of if/elseif statements:
Lua Code:
  1. --Check the weapon type of a weapon
  2. local function checkWeaponType(p_weaponType, p_check)
  3. d(colorDrkOrange.."checkWeaponType")
  4.     if (p_check == nil or p_check == '') then
  5.         p_check = '1hd'
  6.     end
  7.     if (p_weaponType ~= nil) then
  8.  
  9.         if     (p_check == '1hd') then
  10.  
  11.             if (p_weaponType == WEAPONTYPE_AXE or
  12.                 p_weaponType == WEAPONTYPE_DAGGER or
  13.                 p_weaponType == WEAPONTYPE_HAMMER or
  14.                 p_weaponType == WEAPONTYPE_SWORD) then
  15.                 return true
  16.             end
  17. -- exc....more code, lots of elseif statements --

it looks like you could just create a local table out of all of that info and then just check the table inside your function to see what to return. It would be a lot faster.
Like:
Lua Code:
  1. local p_Check_table = {
  2.    ["1hd"] = {
  3.       [WEAPONTYPE_AXE] = true,
  4.       [WEAPONTYPE_DAGGER] = true,
  5.       [WEAPONTYPE_HAMMER] = true,
  6.       [WEAPONTYPE_SWORD] = true,
  7.    },
  8. --- exc...do this for all of the p_check types
  9.    }
  10. }
  11. -- then do something like:
  12. local function checkWeaponType(p_weaponType, p_check)
  13.    -- ... code ... --
  14.    if (p_weaponType ~= nil) then
  15.       if p_Check_table[p_check] and p_Check_table[p_check][p_weaponType] then
  16.          return true
  17.       end
  18.    end
  19. --.. was there more code? I'm getting to lazy to go back and look.. if so do it too.. --
  20.    return false
  21. end

In the function:
local function AddMark(rowControl, markId, isEquipmentSlot)
I see
Lua Code:
  1. if (    rowControl:GetParent() ~= ZO_StoreWindowListContents
  2.         and rowControl:GetParent() ~= ZO_BuyBackListContents
  3.         and rowControl:GetParent() ~= ZO_PlayerInventoryQuestContents
  4.         --and rowControl:GetParent() ~= ZO_SmithingTopLevelImprovementPanelInventoryBackpackContents
  5.         and rowControl:GetParent() ~= ZO_SmithingTopLevelImprovementPanel
  6.         and rowControl:GetParent() ~= ZO_SmithingTopLevelResearchPanelResearchLineListList
  7.         and rowControl:GetParent() ~= ZO_SmithingTopLevelCreationPanelPatternListList
  8.         and rowControl:GetParent() ~= ZO_SmithingTopLevelCreationPanelMaterialListList
  9.         and rowControl:GetParent() ~= ZO_SmithingTopLevelCreationPanelStyleListList
  10.         and rowControl:GetParent() ~= ZO_SmithingTopLevelCreationPanelTraitListList
  11.         and rowControl:GetParent() ~= ZO_AlchemyTopLevelInventoryBackpackContents
  12.         and rowControl             ~= ZO_AlchemyTopLevelSlotContainer
  13.         --and rowControl:GetParent() ~= ZO_EnchantingTopLevelInventoryBackpackContents
  14.         and rowControl             ~= ZO_EnchantingTopLevelRuneSlotContainer
  15.         and rowControl             ~= ZO_EnchantingTopLevelExtractionSlotContainer
  16.         and rowControl:GetParent() ~= ZO_MailInboxMessage
  17.         and rowControl:GetParent() ~= ZO_MailSend
  18.         and rowControl             ~= ZO_ApplyEnchantPanel
  19.         and rowControl             ~= ZO_SoulGemItemChargerPanel
  20.         and rowControl:GetParent() ~= ZO_QuickSlotListContents) then
first, there are some of them missing the :GetParent() is that correct?

Either way that should really be changed to something like this, so you only have to call rowControl:GetParent() 1 time.
Lua Code:
  1. local parent = rowControl:GetParent()
  2.     --Check if the right click menu should be updated. Only allowed panels and menus apply
  3.     if (    parent ~= ZO_StoreWindowListContents
  4.         and parent ~= ZO_BuyBackListContents
  5.         and parent ~= ZO_PlayerInventoryQuestContents
  6.         --and parent ~= ZO_SmithingTopLevelImprovementPanelInventoryBackpackContents
  7.         and parent ~= ZO_SmithingTopLevelImprovementPanel
  8.         and parent ~= ZO_SmithingTopLevelResearchPanelResearchLineListList
  9.         and parent ~= ZO_SmithingTopLevelCreationPanelPatternListList
  10.         and parent ~= ZO_SmithingTopLevelCreationPanelMaterialListList
  11.         and parent ~= ZO_SmithingTopLevelCreationPanelStyleListList
  12.         and parent ~= ZO_SmithingTopLevelCreationPanelTraitListList
  13.         and parent ~= ZO_AlchemyTopLevelInventoryBackpackContents
  14.         and rowControl             ~= ZO_AlchemyTopLevelSlotContainer
  15.         --and parent ~= ZO_EnchantingTopLevelInventoryBackpackContents
  16.         and rowControl             ~= ZO_EnchantingTopLevelRuneSlotContainer
  17.         and rowControl             ~= ZO_EnchantingTopLevelExtractionSlotContainer
  18.         and parent ~= ZO_MailInboxMessage
  19.         and parent ~= ZO_MailSend
  20.         and rowControl             ~= ZO_ApplyEnchantPanel
  21.         and rowControl             ~= ZO_SoulGemItemChargerPanel
  22.         and parent ~= ZO_QuickSlotListContents) then
Although it would be a lot better if you just made a table out of the allowed panels and menus & then just check the table to see if parent and/or rowControl is in the table, if it is then it is an allowed panel. You could do it several ways, one would be getting the control names, storing them in the table with a value of true (if they are allowed panels) then checking the table to see if the panel is allowed.

I don't really know anything about these panels or menus. I do see your saying those panels up there are NOT allowed, but I don't know any other panel names to use so i'm going to use them and pretend they are allowed in my example.
You could do :
Lua Code:
  1. local tAllowedPanels = {
  2.    ["AlchemyTopLevelInventoryBackpackContents"] = true,
  3.    ["SmithingTopLevelCreationPanelTraitListList"]     = true,
  4.    ["SmithingTopLevelResearchPanelResearchLineListList"] = true,
  5. -- exc...--
  6. }
Then grab the parents name & see if it is an allowed panel by checking your table:
Lua Code:
  1. -- instead of doing this
  2. --local parent = rowControl:GetParent()
  3. -- and that big if statement
  4.  
  5. -- you could just do this
  6. local parentName = rowControl:GetParent():GetName()
  7. if tAllowedPanels[parentName] then
  8. -- do whatever --
  9. end


I see the same thing for this below, should probably do the same thing here with rowControl:GetName()
Lua Code:
  1. if (settings.autoMarkAllWeapon == false) then
  2.    if (    rowControl:GetName() == 'ZO_CharacterEquipmentSlotsMainHand'
  3.    or rowControl:GetName() == 'ZO_CharacterEquipmentSlotsOffHand'
  4.    -- lots more rowControl:GetName()


What about this:
Lua Code:
  1. local function UpdatePlayerInventory()
  2. ---...code...---
  3. -- It calls:
  4. PLAYER_INVENTORY:UpdateList(1)
If libFilters is handling the filtering why is your code calling UpdateList ?

Last edited by circonian : 11/25/14 at 12:04 AM.
  Reply With Quote
11/24/14, 11:54 PM   #19
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
Anyhow I hope I'm not spamming this thread to much with all of this stuff, hopefully it helps you find a fix to the problem.
  Reply With Quote
11/24/14, 11:57 PM   #20
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
Originally Posted by Baertram View Post
I tried this zo_callLater workaround with 500ms. It is annoying as the filters won#t update after the click, but half a second later.
Just change it to like 100ms or less even would probably work, I shouldn't have put 500 on there. I should have changed it to a lower number before I posted that code. I wasn't looking for an optimal setting I was just messing around making sure I put a big enough number in there to see if it helped and it did. A lot.

Edit:
I just tested it again with 50ms and it was still plenty long enough that the UpdateFilteredList() only got called once while switching tabs. Heck I took it all the way down to 1ms and it still seemed to filter just fine only calling UpdateFilteredList once. Going that low though of course is not necessary & probably not a good idea.

Last edited by circonian : 11/25/14 at 01:13 AM.
  Reply With Quote

ESOUI » AddOns » AddOn Help/Support » [Need help pls] Find slowdown bug at Advanced Filters & FCOItemSaver addons

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