annotate DependencyLoader/Addon.lua @ 12:b230b94d4487

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