annotate DependencyLoader_Core/Addon.lua @ 8:930871e163bc

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