annotate DependencyLoader/Core.lua @ 18:e7995d599184 tip

updated pkgmeta fix the inversion in addon:Enable added support for late-loading
author mckenziemc
date Tue, 21 Dec 2010 00:23:57 -0800
parents f825ccf94a89
children
rev   line source
mckenziemc@16 1 -- Core
mckenziemc@17 2 -- Provides core functionality of Core
mckenziemc@17 3
mckenziemc@17 4
mckenziemc@17 5 -- TODO: disable bootstrap if we load successfully?
mckenziemc@17 6 -- TODO: implement a feature to disable unneeded libraries when a parent
mckenziemc@17 7 -- is disabled?
mckenziemc@0 8
mckenziemc@0 9
mckenziemc@0 10 local addonName, addonTable = ...
mckenziemc@0 11
mckenziemc@0 12
mckenziemc@17 13 -- locals
mckenziemc@17 14 local print = addonTable.print
mckenziemc@17 15 local debug = addonTable.debug
mckenziemc@17 16 local classes = addonTable.classes
mckenziemc@17 17
mckenziemc@17 18 local AceHook = LibStub("AceHook-3.0")
mckenziemc@17 19 local LibScriptLink = LibStub("LibScriptLink-1.0")
mckenziemc@17 20
mckenziemc@17 21
mckenziemc@17 22 local Core = addonTable:NewClass("Core")
mckenziemc@17 23
mckenziemc@17 24
mckenziemc@17 25 AceHook:Embed(Core)
mckenziemc@17 26
mckenziemc@17 27 Core.queuedEnables = {} -- addons queued to be enabled after PLAYER_LOGIN
mckenziemc@17 28
mckenziemc@17 29
mckenziemc@17 30 -- Does not consider user settings or addon errata.
mckenziemc@17 31 function Core:IsForceLoadAvailable()
mckenziemc@17 32 if IsLoggedIn() then
mckenziemc@17 33 return false
mckenziemc@17 34 else
mckenziemc@17 35 return true
mckenziemc@17 36 end
mckenziemc@17 37 end
mckenziemc@17 38
mckenziemc@17 39
mckenziemc@17 40 function Core:IsForceLoadAllowed()
mckenziemc@17 41 -- TODO: check user settings
mckenziemc@17 42 return true
mckenziemc@17 43 end
mckenziemc@17 44
mckenziemc@17 45
mckenziemc@17 46 function Core:CanForceLoad()
mckenziemc@17 47 return self:IsForceLoadAvailable() and self:IsForceLoadAllowed()
mckenziemc@17 48 end
mckenziemc@17 49
mckenziemc@17 50
mckenziemc@18 51 function Core:CanLoadLate()
mckenziemc@18 52 -- assume we've already logged in
mckenziemc@18 53 return true
mckenziemc@18 54 -- TODO: check user settings
mckenziemc@18 55 end
mckenziemc@18 56
mckenziemc@18 57
mckenziemc@17 58 -- Enables any dependencies needed by the addons
mckenziemc@17 59 -- that have already been enabled
mckenziemc@17 60 function Core:PrepareAllAddons()
mckenziemc@17 61 for i=1, GetNumAddOns() do
mckenziemc@17 62 local addon = classes.Addon:Get(i)
mckenziemc@17 63
mckenziemc@17 64 -- TODO: what if an addon was loaded but its deps were then disabled?
mckenziemc@17 65 if addon:IsEnabled() and not addon:IsLoaded() then
mckenziemc@17 66 self:EnableAddOn(i)
mckenziemc@17 67 end
mckenziemc@17 68 end
mckenziemc@17 69 end
mckenziemc@17 70
mckenziemc@17 71
mckenziemc@17 72 function Core:SetHooks()
mckenziemc@17 73 self:RawHook("EnableAddOn", true)
mckenziemc@17 74 self:RawHook("LoadAddOn", true)
mckenziemc@17 75 end
mckenziemc@17 76
mckenziemc@17 77
mckenziemc@17 78 -- FIXME: use pcall in EnableAddOn and LoadAddOn, so that if my part errors,
mckenziemc@17 79 -- it can still use the unhooked version
mckenziemc@17 80
mckenziemc@17 81 function Core:EnableAddOn(...)
mckenziemc@17 82 local id = ...
mckenziemc@17 83
mckenziemc@17 84 debug("EnableAddOn", ...)
mckenziemc@17 85
mckenziemc@17 86 -- even though we know EnableAddOn can cause force-loading before PLAYER_LOGIN,
mckenziemc@17 87 -- DO NOT attempt to "fix" it: another addon that -does- know about
mckenziemc@17 88 -- the different behavior might call our hook.
mckenziemc@17 89
mckenziemc@17 90 if classes.Addon:Exists(id) then
mckenziemc@17 91 local addon = classes.Addon:Get(id)
mckenziemc@17 92 local tree = classes.Tree:Get(addon)
mckenziemc@17 93
mckenziemc@17 94 local requestReload = false
mckenziemc@17 95
mckenziemc@17 96 if self:CanForceLoad() then
mckenziemc@17 97 -- NOTE: if we can force-load, then will enabling LoD addons cause them to load too?
mckenziemc@17 98 -- A: no, they will still wait for LoadAddOn
mckenziemc@17 99
mckenziemc@17 100 -- Can the addon be loaded on demand if force-loading is
mckenziemc@17 101 -- allowed for its dependencies
mckenziemc@17 102 -- if so, enable all deps and force-load if nec.
mckenziemc@17 103 -- deps will get enabled if all parents are lod, force-loaded
mckenziemc@17 104 -- if any parent can't be loaded on demand
mckenziemc@17 105 -- else
mckenziemc@17 106 -- if the addon is not loadable on demand but the tree can be
mckenziemc@17 107 -- force-loaded, then force-load it all
mckenziemc@17 108 -- deps will all get loaded since req. for root to load
mckenziemc@17 109 -- else
mckenziemc@17 110 -- if it can be loaded with a reloadui then prepare after login
mckenziemc@17 111 -- else
mckenziemc@17 112 -- it can't be loaded, maybe tell the user
mckenziemc@17 113
mckenziemc@18 114 debug("EnableAddOn hook, checking", addon:GetName())
mckenziemc@18 115
mckenziemc@17 116 if tree:CanForceLoad() then
mckenziemc@17 117 if addon:CanLoD() then
mckenziemc@17 118 tree:PrepareForLoD()
mckenziemc@17 119 else
mckenziemc@17 120 tree:ForceLoad()
mckenziemc@17 121 end
mckenziemc@17 122 elseif tree:CanLoad() then
mckenziemc@17 123 tree:PrepareForLoad()
mckenziemc@17 124 requestReload = true
mckenziemc@17 125 else
mckenziemc@17 126 -- TODO: tell user
mckenziemc@17 127 end
mckenziemc@17 128
mckenziemc@17 129
mckenziemc@17 130 --[[
mckenziemc@17 131 if tree:CanLoDWithForce() then
mckenziemc@17 132 tree:PrepareForLoD()
mckenziemc@17 133 elseif tree:CanForceLoad() then
mckenziemc@17 134 tree:ForceLoad()
mckenziemc@17 135 elseif tree:CanLoad() then
mckenziemc@17 136 tree:PrepareForLoad()
mckenziemc@17 137 requestReload = true
mckenziemc@17 138 else
mckenziemc@17 139 -- TODO: tell user
mckenziemc@17 140 end
mckenziemc@17 141 ]]
mckenziemc@17 142 else
mckenziemc@17 143 -- if it can be loaded on demand (deps are loaded or LoD) then
mckenziemc@17 144 -- prepare it (enable all deps)
mckenziemc@17 145 -- else
mckenziemc@17 146 -- if it can be loaded (and isn't already) then
mckenziemc@17 147 -- if force loading is available, we have to wait, then enable everything
mckenziemc@17 148 -- else
mckenziemc@17 149 -- prepare for reload (TODO: move this check and similar to PLAYER_LOGOUT)
mckenziemc@17 150 -- else
mckenziemc@17 151 -- can't be loaded, maybe tell the user
mckenziemc@17 152
mckenziemc@17 153 if tree:CanLoD() then
mckenziemc@17 154 tree:PrepareForLoad()
mckenziemc@17 155 -- don't actually intend to reload, just enable everything
mckenziemc@18 156 elseif self:CanLoadLate() and tree:CanLoadLate() then
mckenziemc@18 157 tree:LoadLate()
mckenziemc@17 158 elseif tree:CanLoad() then
mckenziemc@17 159 tree:PrepareForLoad()
mckenziemc@17 160 requestReload = true
mckenziemc@17 161 else
mckenziemc@17 162 -- TODO: tell user
mckenziemc@17 163 end
mckenziemc@17 164 end
mckenziemc@17 165
mckenziemc@17 166 if requestReload then
mckenziemc@17 167 self:RequestReload()
mckenziemc@17 168 end
mckenziemc@17 169 end
mckenziemc@17 170
mckenziemc@17 171 -- propogate the call even if it doesn't exist or deps are unavailable
mckenziemc@17 172 return self:RawEnableAddOn(...)
mckenziemc@17 173 end
mckenziemc@17 174
mckenziemc@17 175
mckenziemc@17 176
mckenziemc@17 177 --- Prepares the addon tree rooted at the specified addon
mckenziemc@17 178 function Core:LoadAddOn(...)
mckenziemc@17 179 local id = ...
mckenziemc@17 180
mckenziemc@17 181 debug("LoadAddOn", ...)
mckenziemc@17 182
mckenziemc@17 183 if classes.Addon:Exists(id) then
mckenziemc@17 184 local addon = classes.Addon:Get(id)
mckenziemc@17 185 local tree = classes.Tree:Get(addon)
mckenziemc@17 186
mckenziemc@17 187 if tree:CanLoD() then
mckenziemc@17 188 tree:PrepareForLoD()
mckenziemc@17 189 elseif tree:CanLoad() then
mckenziemc@17 190 tree:PrepareForLoad()
mckenziemc@17 191 -- TODO: request reload
mckenziemc@17 192 end
mckenziemc@17 193 end
mckenziemc@17 194
mckenziemc@17 195 -- call even if it can't be loaded so regular returns appear
mckenziemc@17 196 return self:RawLoadAddOn(...)
mckenziemc@17 197 end
mckenziemc@17 198
mckenziemc@17 199
mckenziemc@17 200 function Core:RequestReload()
mckenziemc@17 201 -- TODO: this should be throtled so that it can
mckenziemc@17 202 -- occur more than once but not within a short time
mckenziemc@17 203
mckenziemc@17 204 debug("reload requested (NYI)")
mckenziemc@17 205 end
mckenziemc@17 206
mckenziemc@17 207
mckenziemc@17 208 -- name or index
mckenziemc@17 209 function Core:QueueEnable(addon)
mckenziemc@17 210 self.queuedEnables[addon] = true
mckenziemc@17 211 end
mckenziemc@17 212
mckenziemc@17 213
mckenziemc@17 214 function Core:RawEnableAddOn(...)
mckenziemc@18 215 debug("RawEnableAddOn: enabling", ...)
mckenziemc@17 216 return self.hooks.EnableAddOn(...)
mckenziemc@17 217 end
mckenziemc@17 218
mckenziemc@17 219
mckenziemc@17 220 function Core:RawLoadAddOn(...)
mckenziemc@17 221 return self.hooks.LoadAddOn(...)
mckenziemc@17 222 end
mckenziemc@17 223
mckenziemc@17 224
mckenziemc@17 225 function Core:ProcessEnableQueue()
mckenziemc@17 226 for addon in pairs(self.queuedEnables) do
mckenziemc@17 227 self:RawEnableAddOn(addon)
mckenziemc@17 228 self.queuedEnables[addon] = nil
mckenziemc@17 229 end
mckenziemc@17 230 end