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
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:
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
Lua Code:
--filterCallback must be a function with parameter (slot) and return true/false function libFilters:RegisterFilter( filterId, filterType, filterCallback ) d("registering a filter: "..filterId) --lazily initialize the library if(not self.IS_INITIALIZED) then self:InitializeLibFilters() end --fail silently if the id isn't free or type out of range or if anything is nil if(not filterId or not filterType or filterType < 1 or filterType > #filters or not filterCallback) then d("ERROR: Invalid arguments to libFilters:RegisterFilter! Args: (" .. zo_strjoin(", ", filterId, filterType, filterCallback) .. ")") return elseif(idToFilter[filterId]) then d("ERROR: " .. filterId .. " is already in use!") return end local thisFilter = filters[filterType] idToFilter[filterId] = filterType thisFilter[filterId] = filterCallback if(filterType == LAF_BAGS or filterType == LAF_BANK or filterType == LAF_GUILDBANK) then SetInventoryFilter(filterType) elseif(filterType == LAF_STORE or filterType == LAF_GUILDSTORE or filterType == LAF_MAIL or filterType == LAF_TRADE) then SetFilterByFragment(filterType) elseif(filterType == LAF_DECONSTRUCTION or filterType == LAF_ENCHANTING) then --do nothing because this is filtered with a different method end --****************************************************************************-- --*************************** Changes Here ************************************-- --****************************************************************************-- -- get rid of this -- UpdateFilteredList(filterType) -- check to see if were already updating -- if not if not updateSet then -- set our updateSet "lock" this temporarily prevents other UpdateFilteredList -- from being called until after the current one were about to call has run updateSet = true -- delay the update to give all of the filters a chance to register/unregister zo_callLater(function() -- unlock our updateSet flag so if more stuff happens another -- update can be run updateSet = false -- unlock it -- call the update UpdateFilteredList(filterType) end, 500) end --****************************************************************************-- --****************************************************************************-- end
Changes: function libFilters:UnregisterFilter( filterId )
Warning: Spoiler
Lua Code:
function libFilters:UnregisterFilter( filterId ) d("Unregistering a filter: "..filterId) --lazily initialize the add-on if(not self.IS_INITIALIZED) then self:InitializeLibFilters() end if(not filterId or not self:IsFilterRegistered(filterId)) then return end --fail quietly local filterType = idToFilter[filterId] filters[filterType][filterId] = nil idToFilter[filterId] = nil --****************************************************************************-- --*************************** Changes Here ************************************-- --****************************************************************************-- -- do the same here, get rid of this --UpdateFilteredList(filterType) -- check to see if were already updating if not updateSet then -- set our updateSet "lock" this temporarily prevents other UpdateFilteredList -- from being called until after the current one were about to call has run updateSet = true -- delay the update to give all of the filters a chance to register/unregister zo_callLater(function() -- unlock our updateSet flag so if more stuff happens another -- update can be run updateSet = false -- unlock it -- call the update UpdateFilteredList(filterType) end, 500) end --****************************************************************************-- --****************************************************************************-- end
** Do note I would make sure you call
Lua Code:
-- This line updateSet = false -- before calling this line 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:
-- in libfilters.lua -- this should be local filters = libFilters.filters
|