annotate DependencyLoader/Addon.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@0 1 -- Addon
mckenziemc@10 2 -- Represents individual addon modules.
mckenziemc@0 3
mckenziemc@0 4
mckenziemc@0 5 local addonName, addonTable = ...
mckenziemc@0 6
mckenziemc@0 7
mckenziemc@18 8 local debug = addonTable.debug
mckenziemc@18 9
mckenziemc@10 10 -- TODO: test if the API functions are quicker with indexes than names.
mckenziemc@10 11 -- TODO: modify the dependency stuff to check the Errata module.
mckenziemc@0 12
mckenziemc@0 13 local Addon, addon = addonTable:NewClass("Addon")
mckenziemc@0 14
mckenziemc@8 15 Addon.addons = {}
mckenziemc@8 16 Addon.nameToIndex = {}
mckenziemc@8 17
mckenziemc@8 18
mckenziemc@15 19 --- (private) Creates a new Addon object
mckenziemc@8 20 -- @param id Name or index of the addon.
mckenziemc@0 21 function Addon:New(id)
mckenziemc@0 22 local instance = {}
mckenziemc@0 23 setmetatable(instance, self.instanceMetatable)
mckenziemc@0 24
mckenziemc@0 25 if type(id) == "number" then
mckenziemc@0 26 -- TODO: make sure it's in range
mckenziemc@0 27 instance.index = id
mckenziemc@0 28 instance.name = GetAddOnInfo(id)
mckenziemc@0 29 else
mckenziemc@0 30 -- FIXME: allow blizzard addons?
mckenziemc@0 31 local index
mckenziemc@0 32
mckenziemc@0 33 for i=1,GetNumAddOns() do
mckenziemc@0 34 if GetAddOnInfo(i) == id then
mckenziemc@0 35 index = i
mckenziemc@0 36 break
mckenziemc@0 37 end
mckenziemc@0 38 end
mckenziemc@0 39
mckenziemc@0 40 if index then
mckenziemc@0 41 instance.name = GetAddOnInfo(id)
mckenziemc@0 42 instance.index = index
mckenziemc@0 43 else
mckenziemc@12 44 local message = "Addon not found: "..(id or "nil")
mckenziemc@12 45 error(message)
mckenziemc@0 46 end
mckenziemc@0 47 end
mckenziemc@0 48
mckenziemc@0 49 return instance
mckenziemc@0 50 end
mckenziemc@0 51
mckenziemc@0 52
mckenziemc@8 53 --- Retrieves an Addon object.
mckenziemc@8 54 -- @param id Name or index of the addon to retrieve.
mckenziemc@8 55 -- @return The Addon object, or nil if not found.
mckenziemc@8 56 function Addon:Get(id)
mckenziemc@15 57 assert(id)
mckenziemc@15 58
mckenziemc@8 59 if not self:Exists(id) then
mckenziemc@8 60 return nil
mckenziemc@8 61 end
mckenziemc@8 62
mckenziemc@8 63 if type(id) == "number" then
mckenziemc@8 64 if self.addons[id] ~= nil then
mckenziemc@8 65 return self.addons[id]
mckenziemc@8 66 end
mckenziemc@8 67
mckenziemc@8 68 local new = self:New(id)
mckenziemc@8 69 self.addons[new:GetIndex()] = new
mckenziemc@8 70 self.nameToIndex[new:GetName()] = id
mckenziemc@8 71
mckenziemc@8 72 return new
mckenziemc@8 73 elseif type(id) == "string" then
mckenziemc@8 74 if self.nameToIndex[id] then
mckenziemc@8 75 return self.addons[self.nameToIndex[id] ]
mckenziemc@8 76 end
mckenziemc@8 77
mckenziemc@8 78 local new = self:New(id)
mckenziemc@8 79 self.addons[new:GetIndex()] = new
mckenziemc@8 80 self.nameToIndex[id] = new:GetIndex()
mckenziemc@8 81
mckenziemc@8 82 return new
mckenziemc@8 83 end
mckenziemc@8 84 end
mckenziemc@8 85
mckenziemc@10 86
mckenziemc@0 87 -- Checks if an addon exists with the specified name.
mckenziemc@0 88 -- @param addon Name of the addon.
mckenziemc@0 89 -- @return True if the addon is present, false otherwise.
mckenziemc@0 90 function Addon:Exists(addon)
mckenziemc@0 91 if type(addon) == "number" then
mckenziemc@0 92 if addon >= 1 and addon <= GetNumAddOns() then
mckenziemc@0 93 return true
mckenziemc@0 94 else
mckenziemc@0 95 return false
mckenziemc@0 96 end
mckenziemc@0 97 elseif type(addon) == "string" then
mckenziemc@15 98 if addon:match("Blizzard_") then
mckenziemc@15 99 return false
mckenziemc@15 100 end
mckenziemc@15 101
mckenziemc@0 102 local status = select(6, GetAddOnInfo(addon))
mckenziemc@0 103
mckenziemc@0 104 if status == "MISSING" then
mckenziemc@0 105 return false
mckenziemc@0 106 else
mckenziemc@0 107 return true
mckenziemc@0 108 end
mckenziemc@0 109 else
mckenziemc@15 110 local message = string.format("Unexpected argument type: \"%s\", value: %s", type(addon), addon or "nil")
mckenziemc@15 111 error(message)
mckenziemc@0 112 end
mckenziemc@0 113 end
mckenziemc@0 114
mckenziemc@0 115
mckenziemc@0 116 function addon:GetName()
mckenziemc@0 117 return self.name
mckenziemc@0 118 end
mckenziemc@0 119
mckenziemc@0 120
mckenziemc@0 121 function addon:GetIndex()
mckenziemc@0 122 return self.index
mckenziemc@0 123 end
mckenziemc@0 124
mckenziemc@0 125
mckenziemc@0 126 function addon:IsEnabled()
mckenziemc@0 127 -- FIXME: written while tired; review later
mckenziemc@0 128 local status = select(6, GetAddOnInfo(self.index))
mckenziemc@0 129
mckenziemc@0 130 if status == "DISABLED" then
mckenziemc@0 131 return false
mckenziemc@0 132 else
mckenziemc@0 133 return true
mckenziemc@0 134 end
mckenziemc@0 135 end
mckenziemc@0 136
mckenziemc@0 137
mckenziemc@15 138 function addon:IsLoaded()
mckenziemc@15 139 if IsAddOnLoaded(self.index) then
mckenziemc@15 140 return true
mckenziemc@15 141 else
mckenziemc@15 142 return false
mckenziemc@15 143 end
mckenziemc@15 144 end
mckenziemc@15 145
mckenziemc@15 146
mckenziemc@8 147 --- Checks if the addon is loadable.
mckenziemc@8 148 -- Considers interface issues, missing, etc. (NYI)
mckenziemc@8 149 -- Does not check dependencies.
mckenziemc@8 150 function addon:CanLoad()
mckenziemc@8 151 -- FIXME: an addon may be present but unloadable if loading out of date addons is disabled.
mckenziemc@8 152 return true
mckenziemc@8 153 end
mckenziemc@8 154
mckenziemc@8 155
mckenziemc@0 156 function addon:CanLoD()
mckenziemc@0 157 -- FIXME: what will the client say about addons using LoadManagers if the LM was force-loaded?
mckenziemc@0 158 if IsAddOnLoadOnDemand(self.name) then
mckenziemc@0 159 return true
mckenziemc@0 160 else
mckenziemc@0 161 return false
mckenziemc@0 162 end
mckenziemc@0 163 end
mckenziemc@0 164
mckenziemc@8 165
mckenziemc@18 166 function addon:CanLoadLate()
mckenziemc@18 167 -- TODO: check Errata module
mckenziemc@18 168 return false
mckenziemc@18 169 end
mckenziemc@18 170
mckenziemc@18 171
mckenziemc@15 172 -- can this addon be force-loaded after the point where the client would enable it?
mckenziemc@8 173 function addon:CanForceLoadAfter()
mckenziemc@8 174 -- TODO: check Errata module
mckenziemc@8 175 return false
mckenziemc@8 176 end
mckenziemc@8 177
mckenziemc@8 178
mckenziemc@15 179 -- can this addon be force-loaded before the point where the client would enable it?
mckenziemc@8 180 function addon:CanForceLoadBefore()
mckenziemc@8 181 -- TODO: check Errata module
mckenziemc@8 182 return false -- TODO: check if there's any reason addons can't be forceloaded
mckenziemc@8 183 end
mckenziemc@8 184
mckenziemc@8 185
mckenziemc@10 186 function addon:CanForceLoad()
mckenziemc@10 187 -- FIXME: check if this would've already been loaded
mckenziemc@15 188 return self:CanForceLoadAfter() or self:CanLoD()
mckenziemc@15 189 -- FIXME: should CanLoD() be in here?
mckenziemc@10 190 end
mckenziemc@10 191
mckenziemc@10 192
mckenziemc@8 193 function addon:Enable()
mckenziemc@15 194 if IsLoggedIn() then
mckenziemc@18 195 addonTable.classes.Core:RawEnableAddOn(self.name)
mckenziemc@18 196 else
mckenziemc@17 197 addonTable.classes.Core:QueueEnable(self.name)
mckenziemc@15 198 end
mckenziemc@8 199 end
mckenziemc@8 200
mckenziemc@8 201
mckenziemc@0 202 -- NOTE: only call for LoD, not force-loading
mckenziemc@0 203 function addon:Load()
mckenziemc@0 204 assert(self:CanLoD())
mckenziemc@0 205
mckenziemc@17 206 addonTable.classes.Core:RawEnableAddOn(self.name)
mckenziemc@17 207 addonTable.classes.Core:RawLoadAddOn(self.name)
mckenziemc@0 208 end
mckenziemc@0 209
mckenziemc@8 210
mckenziemc@18 211 function addon:LoadLate()
mckenziemc@18 212 classes.Core:RawEnableAddOn(self.name)
mckenziemc@18 213 classes.Core:RawLoadAddOn(self.name)
mckenziemc@18 214 end
mckenziemc@18 215
mckenziemc@18 216
mckenziemc@0 217 function addon:ForceLoad()
mckenziemc@18 218 debug("addon:ForceLoad called on", self.name)
mckenziemc@18 219
mckenziemc@0 220 assert(self:CanForceLoad())
mckenziemc@0 221 -- TODO: make sure force-loading is available at this time
mckenziemc@0 222
mckenziemc@17 223 addonTable.Core:RawEnableAddOn(self.name) -- This should cause the game to also load this addon
mckenziemc@0 224 end
mckenziemc@0 225
mckenziemc@0 226
mckenziemc@0 227 function addon:GetDependencies()
mckenziemc@8 228 -- TODO: consider no-lib embeds as deps?
mckenziemc@0 229 return GetAddOnDependencies(self.index)
mckenziemc@0 230 end
mckenziemc@0 231
mckenziemc@0 232
mckenziemc@0 233 function addon:GetEmbeds()
mckenziemc@0 234 local embeds = {}
mckenziemc@0 235
mckenziemc@0 236 local embedString = GetAddOnMetadata(self.name, "X-Embeds")
mckenziemc@0 237
mckenziemc@0 238 if embedString then
mckenziemc@0 239 for match in string.gmatch(embedString, "[^,%s]+") do
mckenziemc@0 240 table.insert(embeds, match)
mckenziemc@0 241 end
mckenziemc@0 242 end
mckenziemc@0 243
mckenziemc@0 244 return unpack(embeds)
mckenziemc@0 245 end