Skip to content

Commit c2d8380

Browse files
committed
Performance improvements loading the config page with a lot of crafters.
1 parent 1812dc3 commit c2d8380

6 files changed

Lines changed: 156 additions & 71 deletions

File tree

Config/ConfigPage.lua

Lines changed: 101 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,8 @@ local function MakeProfessionNodeFactory(root)
185185
label = L(isCurrent and 'Crafters' or 'Legacy Crafters'),
186186
startCollapsed = not isCurrent,
187187
},
188+
sorter = SortByHeaderLabel,
188189
})
189-
SetSortComparator(expansionNode, SortByHeaderLabel)
190190
db[isCurrent] = expansionNode
191191
end
192192

@@ -208,9 +208,9 @@ local function MakeProfessionNodeFactory(root)
208208
GetLabelColor = GetCrafterNameColor,
209209
label = CraftScan.NameAndRealmToName(char, true),
210210
},
211+
sorter = SortByHeaderLabel,
211212
})
212213

213-
SetSortComparator(charNode, SortByHeaderLabel)
214214
charNode:Insert({ order = 1, bottomPadding = true })
215215
db[isCurrent][char] = charNode
216216
end
@@ -241,8 +241,8 @@ local function MakeProfessionNodeFactory(root)
241241
ppConfig = CraftScan.DB.characters[char].parent_professions[profConfig.parentProfID],
242242
LoadOptions = CraftScan.Config.LoadProfessionConfigOptions,
243243
},
244+
sorter = false,
244245
})
245-
SetSortComparator(profNode)
246246
-- Scan_state is set as order, so 1-4 for pending/on/off/unlearned.
247247
-- Add some bottom padding by setting order higher than that - 10.
248248
profNode:Insert({ order = 10, bottomPadding = true })
@@ -262,8 +262,8 @@ local function MakeProfessionNodeFactory(root)
262262
label = CraftScan.RecipeStateName(recipeConfig, profConfig),
263263
startCollapsed = true,
264264
},
265+
sorter = SortByItemLabel,
265266
})
266-
SetSortComparator(sectionNode, SortByItemLabel)
267267
sectionNode:Insert({ order = 1, bottomPadding = true })
268268
profNode[recipeScanState] = sectionNode
269269
end
@@ -321,7 +321,7 @@ local function MakeProfessionNodeFactory(root)
321321
-- it, there's a bit of a screen lock up as the tree is updated, so we
322322
-- time slice that into small chunks so the tree updates in real time
323323
-- for the user to see instead of freezing the screen.
324-
local perFrame = existingRecipeIDs and 5 or 10000000
324+
local perFrame = existingRecipeIDs and 5 or 2000000
325325

326326
if not profConfig.recipes then
327327
if onFinished then
@@ -535,39 +535,49 @@ function CraftScanConfigPageMixin:ToggleMenu()
535535
self:SetMenuCollapsed(not self.isMenuCollapsed)
536536
end
537537

538-
function CraftScanConfigPageMixin:SelectRecipe(char, profID, recipeID, retryCount)
539-
retryCount = retryCount or 0
538+
function CraftScanConfigPageMixin:SelectRecipe(char, profID, recipeID, attachButton)
539+
local menu = self.Menu
540540

541-
self:Show()
541+
local function OnMenuInitialized()
542+
if ProfessionsFrame.CraftingPage.SchematicForm:IsShown() then
543+
self:SetMenuCollapsed(true)
544+
self:AnchorToProfessionPage()
545+
end
542546

543-
if ProfessionsFrame.CraftingPage.SchematicForm:IsShown() then
544-
self:SetMenuCollapsed(true)
545-
self:AnchorToProfessionPage()
547+
local dataProvider = menu.dataProvider
548+
549+
-- Find the tree node containing what we need.
550+
local node = dataProvider:FindElementDataByPredicate(function(node)
551+
local data = node:GetData()
552+
return data.configInfo
553+
and data.configInfo.recipeID
554+
and data.configInfo.recipeID == recipeID
555+
and data.configInfo.char == char
556+
and data.configInfo.profID == profID
557+
end, TreeDataProviderConstants.IncludeCollapsed)
558+
559+
if node then
560+
menu.ExpandToNode(dataProvider:GetRootNode(), node:GetData().configInfo)
561+
menu.selectionBehavior:SelectElementData(node)
562+
dataProvider:Invalidate()
563+
menu.ScrollBox:ScrollToElementData(node)
564+
end
546565
end
547566

548-
local menu = self.Menu
549-
local dataProvider = menu.dataProvider
550-
551-
-- Find the tree node containing what we need.
552-
local node = dataProvider:FindElementDataByPredicate(function(node)
553-
local data = node:GetData()
554-
return data.configInfo
555-
and data.configInfo.recipeID
556-
and data.configInfo.recipeID == recipeID
557-
and data.configInfo.char == char
558-
and data.configInfo.profID == profID
559-
end, TreeDataProviderConstants.IncludeCollapsed)
560-
561-
if node then
562-
menu.ExpandToNode(dataProvider:GetRootNode(), node:GetData().configInfo)
563-
menu.selectionBehavior:SelectElementData(node)
564-
dataProvider:Invalidate()
565-
menu.ScrollBox:ScrollToElementData(node)
566-
elseif retryCount < 50 then
567-
-- Fail / Retry: The recipe isn't loaded yet.
568-
C_Timer.After(0.1, function()
569-
self:SelectRecipe(char, profID, recipeID, retryCount + 1)
570-
end)
567+
if self:IsShown() then
568+
OnMenuInitialized()
569+
else
570+
if attachButton then
571+
attachButton:AttachedMenuLoading()
572+
end
573+
menu.onMenuInitialized = function()
574+
OnMenuInitialized()
575+
self:Show()
576+
if attachButton then
577+
attachButton:AttachedMenuLoadComplete()
578+
end
579+
end
580+
menu:InitMenu()
571581
end
572582
end
573583

@@ -724,10 +734,16 @@ function CraftScanConfigMenuMixin:OnLoad()
724734
if event == 'NEW_RECIPE_LEARNED' then
725735
local recipeID, recipeLevel, baseRecipeID = ...
726736

727-
if issecretvalue(recipeID) then return end
737+
if issecretvalue(recipeID) then
738+
return
739+
end
728740

729741
local profInfo = C_TradeSkillUI.GetProfessionInfoByRecipeID(recipeID)
730-
if not profInfo.isPrimaryProfession or not profInfo.parentProfessionID or not CraftScan.DB.characters[char] then
742+
if
743+
not profInfo.isPrimaryProfession
744+
or not profInfo.parentProfessionID
745+
or not CraftScan.DB.characters[char]
746+
then
731747
return
732748
end
733749
local char = CraftScan.GetPlayerName(true)
@@ -773,19 +789,30 @@ end
773789
CraftScan.Config = {}
774790
CraftScan.Config.OnConfigChange = OnConfigChange
775791

792+
function CraftScanConfigMenuMixin:OnMenuInitialized()
793+
if self.onMenuInitialized then
794+
self.onMenuInitialized()
795+
self.onMenuInitialized = nil
796+
end
797+
end
798+
776799
function CraftScanConfigMenuMixin:OnShow()
800+
self:InitMenu()
801+
end
802+
803+
function CraftScanConfigMenuMixin:InitMenu()
777804
if menuInitialized then
805+
self:OnMenuInitialized()
778806
return
779807
end
808+
780809
menuInitialized = true
781810

782811
local dataProvider = CreateTreeDataProvider()
783812
self.dataProvider = dataProvider
784813

785814
local node = dataProvider:GetRootNode()
786815

787-
SetSortComparator(node, SortByHeaderLabel)
788-
789816
local generalNode = node:Insert({
790817
order = 0,
791818
configInfo = {
@@ -809,6 +836,18 @@ function CraftScanConfigMenuMixin:OnShow()
809836
local excludeCollapsed = false
810837
dataProvider:ForEach(function(node)
811838
local elementData = node:GetData()
839+
840+
-- Now that the full tree is populated, apply the sorter for a
841+
-- single n*log(n) sort instead of the original n*n*log(n) we got
842+
-- from applying the sorter before inserting children.
843+
if elementData.sorter ~= nil then
844+
if elementData.sorter then
845+
SetSortComparator(node, elementData.sorter)
846+
else
847+
SetSortComparator(node)
848+
end
849+
elementData.sorter = nil
850+
end
812851
if elementData.headerInfo and elementData.headerInfo.startCollapsed then
813852
node:SetCollapsed(true)
814853

@@ -821,17 +860,33 @@ function CraftScanConfigMenuMixin:OnShow()
821860
end, excludeCollapsed)
822861
end
823862

863+
-- Wait until we have fully populated the tree to render it. Before
864+
-- rendering, we collapse almost all the nodes so we only display the
865+
-- current expansion's professions
866+
local waitGroup = CraftScan.WaitGroup(function()
867+
CollapseTree()
868+
SetSortComparator(node, SortByHeaderLabel)
869+
self.ScrollBox:SetDataProvider(dataProvider, ScrollBoxConstants.RetainScrollPosition)
870+
self.selectionBehavior:SelectElementData(generalNode)
871+
self.ScrollBox:ScrollToElementData(generalNode)
872+
self.Spinner:SetShown(false)
873+
self:OnMenuInitialized()
874+
end)
875+
876+
local OnProfessionLoadComplete = function()
877+
waitGroup:Done()
878+
end
879+
880+
self.Spinner:SetShown(true)
824881
self.GetRecipeParentNode, self.PopulateProfessionNode, self.UpdateProfessionNode, self.RemoveMissingProfessionNodes, self.ExpandToNode =
825882
MakeProfessionNodeFactory(node)
826883
for char, charConfig in pairs(CraftScan.DB.characters) do
827884
for profID, profConfig in pairs(charConfig.professions) do
828-
self.PopulateProfessionNode(char, profID, profConfig, nil, CollapseTree)
885+
waitGroup:Add()
886+
self.PopulateProfessionNode(char, profID, profConfig, nil, OnProfessionLoadComplete)
829887
end
830888
end
831-
832-
self.ScrollBox:SetDataProvider(dataProvider, ScrollBoxConstants.RetainScrollPosition)
833-
self.selectionBehavior:SelectElementData(generalNode)
834-
self.ScrollBox:ScrollToElementData(generalNode)
889+
waitGroup:Close()
835890
end
836891

837892
CraftScanConfigMenuHeaderMixin = {}
@@ -924,7 +979,9 @@ end
924979

925980
function CraftScan.Config.OnRecipeScanStateChange(configInfo, skipReload)
926981
-- If the tree hasn't initialized the configInfo yet, nothing to do.
927-
if not configInfo.treeNode then return end
982+
if not configInfo.treeNode then
983+
return
984+
end
928985

929986
local menu = CraftScanConfigPage.Menu
930987
local newParent = menu.GetRecipeParentNode(

Config/ConfigPage.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@
6666
<Anchor point="BOTTOMRIGHT" x="0" y="0" />
6767
</Anchors>
6868
</Frame>
69+
<Frame parentKey="Spinner" inherits="SpinnerTemplate" frameLevel="2200">
70+
<Anchors>
71+
<Anchor point="CENTER" />
72+
</Anchors>
73+
</Frame>
6974
<Frame parentKey="ScrollBox" inherits="WowScrollBoxList">
7075
<Anchors>
7176
<Anchor point="TOPLEFT" relativeKey="$parent.Background"

Config/RecipeSchematicMenu.lua

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,13 +357,15 @@ local function ScanAllRecipes(OnScanComplete, forceScan)
357357
end
358358
CraftScan.Events:Register('TRADESKILL_OPENED', ScanAllRecipes)
359359

360+
local attachButton = nil
360361
local function CreateMenuShownButton()
361362
local button = CreateFrame(
362363
'Button',
363364
'CraftScanToggleScannerConfigButton',
364365
ProfessionsFrame.CraftingPage.SchematicForm,
365366
'CraftScan_ScannerConfigButtonTemplate'
366367
)
368+
attachButton = button
367369

368370
CraftScan.Events:Register({
369371
'RECIPE_SELECTED',
@@ -416,12 +418,22 @@ local function OpenRecipe()
416418
local profID = isDecor and ctxt.currentExpID or profession.professionID
417419
local profConfig = isDecor and ctxt.dbCurrentExp or ctxt.dbSelectedExp
418420
if profConfig.recipes[recipeInfo.recipeID] then
419-
CraftScan.Events:Emit('OPEN_RECIPE', ctxt.name, profID, recipeInfo.recipeID)
421+
CraftScan.Events:Emit('OPEN_RECIPE', ctxt.name, profID, recipeInfo.recipeID, attachButton)
420422
end
421423
end
422424

423425
CraftScan_ScannerConfigButtonMixin = {}
424426

427+
function CraftScan_ScannerConfigButtonMixin:AttachedMenuLoading()
428+
self:SetEnabled(false)
429+
self.Spinner:SetShown(true)
430+
end
431+
432+
function CraftScan_ScannerConfigButtonMixin:AttachedMenuLoadComplete()
433+
self:SetEnabled(true)
434+
self.Spinner:SetShown(false)
435+
end
436+
425437
function CraftScan_ScannerConfigButtonMixin:Setup(ctxt)
426438
ctxt = ctxt or GetParentContext()
427439
if not ctxt then

Config/RecipeSchematicMenu.xml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,17 @@
99
<Scripts>
1010
<OnClick method="OnClick" />
1111
</Scripts>
12-
12+
<Frames>
13+
<Frame parentKey="Spinner" inherits="SpinnerTemplate" frameLevel="2200" hidden="true">
14+
<Size x="22" y="22" />
15+
<Anchors>
16+
<Anchor point="CENTER" />
17+
</Anchors>
18+
</Frame>
19+
</Frames>
1320
<Layers>
1421
<Layer level="ARTWORK">
15-
<FontString parentKey="ScanningLabel" inherits="GameFontHighlightSmall2"
22+
<FontString parentKey="ScanningLabel" inherits="GameFontHighlightSmall2"
1623
justifyV="CENTER" justifyH="LEFT">
1724
<Size x="200" y="20" />
1825
<Anchors>

Customer/ChatScanner.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ function CraftScan.Scanner.LoadConfig()
314314
end
315315
end
316316

317-
local perFrame = 10
317+
local perFrame = 1000
318318
waitGroup:Add()
319319
CraftScan.TimeSlice(prof.recipes, perFrame, ProcessRecipe, function()
320320
waitGroup:Done()

0 commit comments

Comments
 (0)