@@ -3,7 +3,6 @@ local thisAddonName = ...
33local s_trim = string .trim
44local t_insert = table.insert
55local t_removemulti = table .removemulti
6- local t_remove = table.remove
76local t_wipe = table .wipe
87local pairs = pairs
98local GetTime = GetTime
7978--- collect all available data
8079local ACTIVE_MODE = ' active' ;
8180--- collect only total and peak data - disables history range
82- --- @todo mostly implemented, but no toggle yet
8381local PERFORMANCE_MODE = ' performance' ;
8482--- collect no data at all, just reset the spike ms counters on reset - disables history range, and maybe show different columns?
85- --- @todo not yet implemented
8683local PASSIVE_MODE = ' passive' ;
8784
8885--- @type table<string , { title : string , notes : string , loaded : boolean } >
@@ -148,10 +145,15 @@ end
148145local HEADER_IDS = {
149146 addonTitle = " addonTitle" ,
150147 encounterAvgMs = " encounterAvgMs" ,
148+ overallEncounterAvgPercent = " overallEncounterAvgPercent" ,
151149 peakTimeMs = " peakTimeMs" ,
150+ overallPeakTimePercent = " overallPeakTimePercent" ,
152151 recentMs = " recentMs" ,
152+ overallRecentPercent = " overallRecentPercent" ,
153153 averageMs = " averageMs" ,
154154 totalMs = " totalMs" ,
155+ overallTotalPercent = " overallTotalPercent" ,
156+ applicationTotalPercent = " applicationTotalPercent" ,
155157 [" overCount-1" ] = " overCount-1" ,
156158 [" overCount-5" ] = " overCount-5" ,
157159 [" overCount-10" ] = " overCount-10" ,
@@ -171,10 +173,15 @@ function NAP:InitDB()
171173 local defaultShownColumns = {
172174 [HEADER_IDS .addonTitle ] = true ,
173175 [HEADER_IDS .encounterAvgMs ] = true ,
176+ [HEADER_IDS .overallEncounterAvgPercent ] = false ,
174177 [HEADER_IDS .peakTimeMs ] = true ,
178+ [HEADER_IDS .overallPeakTimePercent ] = false ,
175179 [HEADER_IDS .recentMs ] = false ,
180+ [HEADER_IDS .overallRecentPercent ] = false ,
176181 [HEADER_IDS .averageMs ] = true ,
177182 [HEADER_IDS .totalMs ] = true ,
183+ [HEADER_IDS .overallTotalPercent ] = true ,
184+ [HEADER_IDS .applicationTotalPercent ] = true ,
178185 [HEADER_IDS [' overCount-1' ]] = true ,
179186 [HEADER_IDS [' overCount-5' ]] = true ,
180187 [HEADER_IDS [' overCount-10' ]] = true ,
@@ -416,10 +423,15 @@ end
416423--- @field addonTitle string
417424--- @field addonNotes string
418425--- @field peakTime number
426+ --- @field overallPeakTime number
419427--- @field encounterAvg number
428+ --- @field overallEncounterAvg number
420429--- @field recentMs number
430+ --- @field overallRecentMs number
421431--- @field averageMs number
422432--- @field totalMs number
433+ --- @field overallTotalMs number
434+ --- @field applicationTotalMs number
423435--- @field numberOfTicks number
424436--- @field over1Ms number
425437--- @field over5Ms number
429441--- @field over500Ms number
430442--- @field over1000Ms number
431443--- @field overMsSum number
444+ -- 11.1 will likely allow adding applicationPeakTime, applicationEncounterAvg, applicationRecentMs
432445
433446--- @param forceUpdate boolean
434447--- @return table<NAP_Bucket , number> ? bucketsWithinHistory
@@ -462,11 +475,12 @@ function NAP:PrepareFilteredData(forceUpdate)
462475 end
463476 end
464477 end
478+ local overallStats = self :GetElelementDataForAddon (TOTAL_ADDON_METRICS_KEY , nil , withinHistory );
465479
466480 for addonName in pairs (self .loadedAddons ) do
467481 local info = self .addons [addonName ];
468482 if info .title :lower ():match (self .curMatch ) then
469- t_insert (self .filteredData , self :GetElelementDataForAddon (addonName , info , withinHistory ));
483+ t_insert (self .filteredData , self :GetElelementDataForAddon (addonName , info , withinHistory , overallStats ));
470484 end
471485 end
472486
@@ -479,20 +493,22 @@ function NAP:PrepareFilteredData(forceUpdate)
479493end
480494
481495--- @param addonName string
482- --- @param info { title : string , notes : string , loaded : boolean }
496+ --- @param info nil | { title : string , notes : string , loaded : boolean }
483497--- @param bucketsWithinHistory table<NAP_Bucket , number>
498+ --- @param overallStats NAP_ElementData ?
484499--- @return NAP_ElementData
485- function NAP :GetElelementDataForAddon (addonName , info , bucketsWithinHistory )
500+ function NAP :GetElelementDataForAddon (addonName , info , bucketsWithinHistory , overallStats )
486501 --- @type NAP_ElementData
487502 --- @diagnostic disable-next-line : missing-fields
488503 local data = {
489504 addonName = addonName ,
490- addonTitle = info .title ,
491- addonNotes = info .notes ,
505+ addonTitle = info and info .title or ' ' ,
506+ addonNotes = info and info .notes or ' ' ,
492507 peakTime = 0 ,
493508 averageMs = 0 ,
494509 totalMs = 0 ,
495510 numberOfTicks = 0 ,
511+ applicationTotalMs = 0 ,
496512 };
497513 if TOTAL_ADDON_METRICS_KEY == addonName then
498514 data .encounterAvg = C_AddOnProfiler_GetOverallMetric (Enum_AddOnProfilerMetric_EncounterAverageTime );
@@ -504,7 +520,9 @@ function NAP:GetElelementDataForAddon(addonName, info, bucketsWithinHistory)
504520 for _ , ms in pairs (msOptions ) do
505521 data [msOptionFieldMap [ms ]] = 0 ;
506522 end
523+ local now = self .frozenAt or GetTime ();
507524 if INFINITE_HISTORY == self :GetActiveHistoryRange () then
525+ data .applicationTotalMs = (now - self .resetTime ) * 1000 ;
508526 local currentMetrics = self .frozenMetrics and self .frozenMetrics [addonName ] or self :GetCurrentMsSpikeMetrics (addonName );
509527 for ms in pairs (msMetricMap ) do
510528 local currentMetric = currentMetrics [ms ] or 0 ;
@@ -516,8 +534,16 @@ function NAP:GetElelementDataForAddon(addonName, info, bucketsWithinHistory)
516534 data .totalMs = self .totalMs [addonName ];
517535 data .numberOfTicks = self .tickNumber - self .loadedAtTick [addonName ];
518536 else
537+ local firstTickTime = now ;
538+ local lastTickTime = 0 ;
519539 for bucket , startingTickIndex in pairs (bucketsWithinHistory ) do
520540 data .numberOfTicks = data .numberOfTicks + ((bucket .curTickIndex - startingTickIndex ) + 1 );
541+ if bucket .tickMap [startingTickIndex ] < firstTickTime then
542+ firstTickTime = bucket .tickMap [startingTickIndex ];
543+ end
544+ if bucket .tickMap [bucket .curTickIndex ] > lastTickTime then
545+ lastTickTime = bucket .tickMap [bucket .curTickIndex ];
546+ end
521547 for tickIndex = startingTickIndex , bucket .curTickIndex do
522548 local tickMs = bucket .lastTick [addonName ] and bucket .lastTick [addonName ][tickIndex ];
523549 if tickMs and tickMs > 0 then
@@ -550,6 +576,8 @@ function NAP:GetElelementDataForAddon(addonName, info, bucketsWithinHistory)
550576 end
551577 end
552578 end
579+
580+ data .applicationTotalMs = (lastTickTime - firstTickTime ) * 1000 ;
553581 end
554582 data .averageMs = data .numberOfTicks > 0 and (data .totalMs / data .numberOfTicks ) or 0 ; -- let's not divide by 0 :)
555583
@@ -570,6 +598,18 @@ function NAP:GetElelementDataForAddon(addonName, info, bucketsWithinHistory)
570598 previousGroupCount = count ;
571599 end
572600
601+ if TOTAL_ADDON_METRICS_KEY == addonName then
602+ data .overallPeakTime = data .peakTime ;
603+ data .overallEncounterAvg = data .encounterAvg ;
604+ data .overallRecentMs = data .recentMs ;
605+ data .overallTotalMs = data .totalMs ;
606+ elseif overallStats then
607+ data .overallPeakTime = overallStats .peakTime ;
608+ data .overallEncounterAvg = overallStats .encounterAvg ;
609+ data .overallRecentMs = overallStats .recentMs ;
610+ data .overallTotalMs = overallStats .totalMs ;
611+ end
612+
573613 return data ;
574614end
575615
@@ -590,9 +630,18 @@ function NAP:InitUI()
590630 local ROUND_TIME_FORMAT = function (val ) return (val > 0 and whiteColorFormat or greyColorFormat ):format (val ) .. msText ; end ;
591631 local COUNTER_FORMAT = function (val ) return (val > 0 and whiteColorFormat or greyColorFormat ):format (val ) .. xText ; end ;
592632 local RAW_FORMAT = function (val ) return val ; end ;
633+ local PERCENT_FORMAT = function (val )
634+ local color = val > 0.00005 and whiteColorFormat or greyColorFormat ;
635+
636+ return val >= 1 and color :format (" 100.00%" ) or color :format ((" %.2f%%" ):format (val * 100 ));
637+ end ;
593638
594639 local COLUMN_INFO = {};
595640 do
641+ local totalAddonsText = NORMAL_FONT_COLOR :WrapTextInColorCode (" Total Addons" );
642+ local applicationText = NORMAL_FONT_COLOR :WrapTextInColorCode (" Application" );
643+ local applicationShortText = NORMAL_FONT_COLOR :WrapTextInColorCode (" App" );
644+
596645 local Inf = math.huge
597646 local function makeSortMethods (key )
598647 return {
@@ -640,7 +689,21 @@ function NAP:InitUI()
640689 width = 96 ,
641690 textFormatter = TIME_FORMAT ,
642691 textKey = " encounterAvg" ,
643- tooltip = " Average CPU time spent per frame during a boss encounter. Ignores the History Range" ,
692+ tooltip = " Average CPU time spent per frame during a boss encounter. Ignores the History Range." ,
693+ sortMethods = makeSortMethods (" encounterAvg" ),
694+ };
695+ COLUMN_INFO [HEADER_IDS .overallEncounterAvgPercent ] = {
696+ ID = HEADER_IDS .overallEncounterAvgPercent ,
697+ order = counter (),
698+ availableInPassiveMode = true ,
699+ title = " Boss Avg %" ,
700+ width = 96 ,
701+ textFormatter = PERCENT_FORMAT ,
702+ --- @param data NAP_ElementData
703+ textFunc = function (data )
704+ return data .overallEncounterAvg > 0 and (data .encounterAvg / data .overallEncounterAvg ) or 0 ;
705+ end ,
706+ tooltip = " Percentage of " .. totalAddonsText .. " CPU time spent per frame during a boss encounter. Ignores the History Range." ,
644707 sortMethods = makeSortMethods (" encounterAvg" ),
645708 };
646709 COLUMN_INFO [HEADER_IDS .peakTimeMs ] = {
@@ -654,6 +717,20 @@ function NAP:InitUI()
654717 tooltip = " Biggest spike in ms, within the History Range." ,
655718 sortMethods = makeSortMethods (" peakTime" ),
656719 };
720+ COLUMN_INFO [HEADER_IDS .overallPeakTimePercent ] = {
721+ ID = HEADER_IDS .overallPeakTimePercent ,
722+ order = counter (),
723+ availableInPassiveMode = true ,
724+ title = " Peak %" ,
725+ width = 96 ,
726+ textFormatter = PERCENT_FORMAT ,
727+ --- @param data NAP_ElementData
728+ textFunc = function (data )
729+ return data .overallPeakTime > 0 and (data .peakTime / data .overallPeakTime ) or 0 ;
730+ end ,
731+ tooltip = " Percentage of " .. totalAddonsText .. " biggest spike in ms, within the History Range." ,
732+ sortMethods = makeSortMethods (" peakTime" ),
733+ };
657734 COLUMN_INFO [HEADER_IDS .recentMs ] = {
658735 ID = HEADER_IDS .recentMs ,
659736 order = counter (),
@@ -665,6 +742,20 @@ function NAP:InitUI()
665742 tooltip = " Average CPU time spent in the last 60 frames. Ignores the History Range" ,
666743 sortMethods = makeSortMethods (" recentMs" ),
667744 };
745+ COLUMN_INFO [HEADER_IDS .overallRecentPercent ] = {
746+ ID = HEADER_IDS .overallRecentPercent ,
747+ order = counter (),
748+ availableInPassiveMode = true ,
749+ title = " Recent %" ,
750+ width = 96 ,
751+ textFormatter = PERCENT_FORMAT ,
752+ --- @param data NAP_ElementData
753+ textFunc = function (data )
754+ return data .overallRecentMs > 0 and (data .recentMs / data .overallRecentMs ) or 0 ;
755+ end ,
756+ tooltip = " Percentage of " .. totalAddonsText .. " CPU time spent in the last 60 frames. Ignores the History Range." ,
757+ sortMethods = makeSortMethods (" recentMs" ),
758+ };
668759 COLUMN_INFO [HEADER_IDS .averageMs ] = {
669760 ID = HEADER_IDS .averageMs ,
670761 order = counter (),
@@ -685,6 +776,32 @@ function NAP:InitUI()
685776 tooltip = " Total CPU time spent, within the History Range." ,
686777 sortMethods = makeSortMethods (" totalMs" ),
687778 };
779+ COLUMN_INFO [HEADER_IDS .overallTotalPercent ] = {
780+ ID = HEADER_IDS .overallTotalPercent ,
781+ order = counter (),
782+ title = " Total %" ,
783+ width = 96 ,
784+ textFormatter = PERCENT_FORMAT ,
785+ --- @param data NAP_ElementData
786+ textFunc = function (data )
787+ return data .overallTotalMs > 0 and (data .totalMs / data .overallTotalMs ) or 0 ;
788+ end ,
789+ tooltip = " Percentage of " .. totalAddonsText .. " CPU time spent, within the History Range." ,
790+ sortMethods = makeSortMethods (" totalMs" ),
791+ };
792+ COLUMN_INFO [HEADER_IDS .applicationTotalPercent ] = {
793+ ID = HEADER_IDS .applicationTotalPercent ,
794+ order = counter (),
795+ title = " Total % of " .. applicationShortText ,
796+ width = 96 ,
797+ textFormatter = PERCENT_FORMAT ,
798+ --- @param data NAP_ElementData
799+ textFunc = function (data )
800+ return data .applicationTotalMs > 0 and (data .totalMs / data .applicationTotalMs ) or 0 ;
801+ end ,
802+ tooltip = " CPU time spent, as a percentage of the total " .. applicationText .. " CPU time. This includes default UI, graphics, etc." ,
803+ sortMethods = makeSortMethods (" totalMs" ),
804+ };
688805 for _ , ms in ipairs (msOptions ) do
689806 COLUMN_INFO [HEADER_IDS [" overCount-" .. ms ]] = {
690807 ID = HEADER_IDS [" overCount-" .. ms ],
@@ -1159,7 +1276,8 @@ function NAP:InitUI()
11591276 self :UpdateColumns ()
11601277 for columnText in self .columnPool :EnumerateActive () do
11611278 local column = columnText .column
1162- columnText :SetText (column .textFormatter (self .data [column .textKey ]))
1279+ local value = column .textFunc and column .textFunc (self .data ) or self .data [column .textKey ]
1280+ columnText :SetText (column .textFormatter (value ))
11631281 end
11641282 end
11651283 end
@@ -1179,7 +1297,8 @@ function NAP:InitUI()
11791297 row :UpdateColumns ()
11801298 for columnText in row .columnPool :EnumerateActive () do
11811299 local column = columnText .column
1182- columnText :SetText (column .textFormatter (data [column .textKey ]))
1300+ local value = column .textFunc and column .textFunc (data ) or data [column .textKey ]
1301+ columnText :SetText (column .textFormatter (value ))
11831302 end
11841303 end )
11851304
0 commit comments