TradeSkillMaster/Core/Lib/Addon.lua

205 lines
6.6 KiB
Lua
Raw Permalink Normal View History

2020-11-13 14:13:12 -05:00
-- ------------------------------------------------------------------------------ --
-- TradeSkillMaster --
-- https://tradeskillmaster.com --
-- All Rights Reserved - Detailed license information included with addon. --
-- ------------------------------------------------------------------------------ --
local TSM_NAME, TSM = ...
local Analytics = TSM.Include("Util.Analytics")
local Event = TSM.Include("Util.Event")
local Log = TSM.Include("Util.Log")
local LibTSMClass = TSM.Include("LibTSMClass")
local private = {
eventFrames = {},
initializeQueue = {},
enableQueue = {},
disableQueue = {},
totalInitializeTime = 0,
totalEnableTime = 0,
}
local TIME_WARNING_THRESHOLD_MS = 20
local MAX_TIME_PER_EVENT_MS = 12000
local NUM_EVENT_FRAMES = 10
-- ============================================================================
-- Event Handling
-- ============================================================================
function private.DoInitialize()
local eventStartTime = debugprofilestop()
while #private.initializeQueue > 0 and debugprofilestop() < (eventStartTime + MAX_TIME_PER_EVENT_MS) do
local addon = tremove(private.initializeQueue, 1)
if addon.OnInitialize then
local addonStartTime = debugprofilestop()
addon.OnInitialize()
local addonTimeTaken = debugprofilestop() - addonStartTime
if addonTimeTaken > TIME_WARNING_THRESHOLD_MS then
Log.Warn("OnInitialize (%s) took %0.2fms", addon, addonTimeTaken)
end
end
tinsert(private.enableQueue, addon)
end
if private.totalInitializeTime == 0 then
for _, path, moduleLoadTime, settingsLoadTime in TSM.ModuleInfoIterator() do
if moduleLoadTime > TIME_WARNING_THRESHOLD_MS then
Log.Warn("Loading module %s took %0.2fms", path, moduleLoadTime)
end
if settingsLoadTime > TIME_WARNING_THRESHOLD_MS then
Log.Warn("Loading settings for %s took %0.2fms", path, settingsLoadTime)
end
end
end
private.totalInitializeTime = private.totalInitializeTime + debugprofilestop() - eventStartTime
return #private.initializeQueue == 0
end
function private.DoEnable()
local eventStartTime = debugprofilestop()
while #private.enableQueue > 0 and debugprofilestop() < (eventStartTime + MAX_TIME_PER_EVENT_MS) do
local addon = tremove(private.enableQueue, 1)
if addon.OnEnable then
local addonStartTime = debugprofilestop()
addon.OnEnable()
local addonTimeTaken = debugprofilestop() - addonStartTime
if addonTimeTaken > TIME_WARNING_THRESHOLD_MS then
Log.Warn("OnEnable (%s) took %0.2fms", addon, addonTimeTaken)
end
end
tinsert(private.disableQueue, addon)
end
if private.totalEnableTime == 0 then
for _, path, _, _, gameDataLoadTime in TSM.ModuleInfoIterator() do
if (gameDataLoadTime or 0) > TIME_WARNING_THRESHOLD_MS then
Log.Warn("Loading game data for %s took %0.2fms", path, gameDataLoadTime)
end
end
end
private.totalEnableTime = private.totalEnableTime + debugprofilestop() - eventStartTime
return #private.enableQueue == 0
end
function private.PlayerLogoutHandler()
private.OnDisableHelper()
wipe(private.disableQueue)
end
function private.OnDisableHelper()
local disableStartTime = debugprofilestop()
for _, addon in ipairs(private.disableQueue) do
-- defer the main TSM.OnDisable() call to the very end
if addon.OnDisable and addon ~= TSM then
local startTime = debugprofilestop()
addon.OnDisable()
local timeTaken = debugprofilestop() - startTime
if timeTaken > TIME_WARNING_THRESHOLD_MS then
Log.Warn("OnDisable (%s) took %0.2fms", addon, timeTaken)
end
end
end
local totalDisableTime = debugprofilestop() - disableStartTime
Analytics.Action("ADDON_DISABLE", floor(totalDisableTime))
if TSM.OnDisable then
TSM.OnDisable()
end
end
do
-- Blizzard did something silly in 8.1 where scripts time throw an error after 19 seconds, but nothing prevents us
-- from just splitting the processing across multiple script handlers, so we do that here.
local function EventHandler(self, event, arg)
if event == "ADDON_LOADED" and arg == "TradeSkillMaster" then
if private.DoInitialize() then
-- we're done
for _, frame in ipairs(private.eventFrames) do
frame:UnregisterEvent(event)
end
Analytics.Action("ADDON_INITIALIZE", floor(private.totalInitializeTime))
elseif self == private.eventFrames[#private.eventFrames] then
error("Ran out of event frames to initialize TSM")
end
elseif event == "PLAYER_LOGIN" then
if private.DoEnable() then
-- we're done
for _, frame in ipairs(private.eventFrames) do
frame:UnregisterEvent(event)
end
Analytics.Action("ADDON_ENABLE", floor(private.totalEnableTime))
elseif self == private.eventFrames[#private.eventFrames] then
error("Ran out of event frames to enable TSM")
end
end
end
for _ = 1, NUM_EVENT_FRAMES do
local frame = CreateFrame("Frame")
frame:SetScript("OnEvent", EventHandler)
frame:RegisterEvent("ADDON_LOADED")
frame:RegisterEvent("PLAYER_LOGIN")
tinsert(private.eventFrames, frame)
end
Event.Register("PLAYER_LOGOUT", private.PlayerLogoutHandler)
end
-- ============================================================================
-- AddonPackage Class
-- ============================================================================
local AddonPackage = LibTSMClass.DefineClass("AddonPackage")
function AddonPackage.__init(self, name)
self.name = name
tinsert(private.initializeQueue, self)
end
function AddonPackage.__tostring(self)
return self.name
end
function AddonPackage.NewPackage(self, name)
local package = AddonPackage(name)
assert(not self[name])
self[name] = package
return package
end
-- ============================================================================
-- Addon Class
-- ============================================================================
local Addon = LibTSMClass.DefineClass("Addon", AddonPackage)
function Addon.__init(self, name)
self.__super:__init(name)
end
-- ============================================================================
-- Initialization Code
-- ============================================================================
do
LibTSMClass.ConstructWithTable(TSM, Addon, TSM_NAME)
end
-- ============================================================================
-- Module Functions (Debug Only)
-- ============================================================================
function TSM.AddonTestLogout()
private.OnDisableHelper()
TSM.DebugLogout()
for _, path, _, _, _, moduleUnloadTime in TSM.ModuleInfoIterator() do
if moduleUnloadTime > TIME_WARNING_THRESHOLD_MS then
Log.Warn("Unloading %s took %0.2fms", path, moduleUnloadTime)
end
end
end