annotate DependencyLoader/Addon.lua @ 15:a46bf694050c

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