view 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
line wrap: on
line source
--	Addon
--	Represents individual addon modules.


local addonName, addonTable = ...


--	TODO: test if the API functions are quicker with indexes than names.
--	TODO: modify the dependency stuff to check the Errata module.

local Addon, addon = addonTable:NewClass("Addon")

Addon.enableAddon = EnableAddOn		--	TODO: use raw hook from main module?

Addon.addons = {}
Addon.nameToIndex = {}


--	Internal function
--	Creates a new Addon object
--	@param	id		Name or index of the addon.
function Addon:New(id)
	local instance = {}
	setmetatable(instance, self.instanceMetatable)
	
	if type(id) == "number" then
		--	TODO: make sure it's in range
		instance.index = id
		instance.name = GetAddOnInfo(id)
	else
		--	FIXME: allow blizzard addons?
		local index
		
		for i=1,GetNumAddOns() do
			if GetAddOnInfo(i) == id then
				index = i
				break
			end
		end
		
		if index then
			instance.name = GetAddOnInfo(id)
			instance.index = index
		else
			local message = "Addon not found: "..(id or "nil")
			error(message)
		end
	end
	
	return instance
end


---	Retrieves an Addon object.
--	@param	id	Name or index of the addon to retrieve.
--	@return 	The Addon object, or nil if not found.
function Addon:Get(id)
	if not self:Exists(id) then
		return nil
	end
	
	if type(id) == "number" then
		if self.addons[id] ~= nil then
			return self.addons[id]
		end
		
		local new = self:New(id)
		self.addons[new:GetIndex()] = new
		self.nameToIndex[new:GetName()] = id
		
		return new
	elseif type(id) == "string" then
		if self.nameToIndex[id] then
			return self.addons[self.nameToIndex[id] ]
		end
		
		local new = self:New(id)
		self.addons[new:GetIndex()] = new
		self.nameToIndex[id] = new:GetIndex()
		
		return new
	end
end	


--	Checks if an addon exists with the specified name.
--	@param	addon	Name of the addon.
--	@return			True if the addon is present, false otherwise.
function Addon:Exists(addon)
	if type(addon) == "number" then
		if addon >= 1 and addon <= GetNumAddOns() then
			return true
		else
			return false
		end
	elseif type(addon) == "string" then
		local status = select(6, GetAddOnInfo(addon))
		
		if status == "MISSING" then
			return false
		else
			return true
		end
	else
		error()
	end
end


function addon:GetName()
	return self.name
end


function addon:GetIndex()
	return self.index
end


function addon:IsEnabled()
	--	FIXME: written while tired; review later
	local status = select(6, GetAddOnInfo(self.index))
	
	if status == "DISABLED"	then
		return false
	else
		return true
	end
end


---	Checks if the addon is loadable.
--	Considers interface issues, missing, etc. (NYI)
--	Does not check dependencies.
function addon:CanLoad()
	--	FIXME: an addon may be present but unloadable if loading out of date addons is disabled.
	return true
end


function addon:CanLoD()
	--	FIXME: what will the client say about addons using LoadManagers if the LM was force-loaded?
	if IsAddOnLoadOnDemand(self.name) then
		return true
	else
		return false
	end
end


function addon:CanForceLoadAfter()
	--	TODO: check Errata module
	return false
end


function addon:CanForceLoadBefore()
	--	TODO: check Errata module
	return false		--	TODO: check if there's any reason addons can't be forceloaded
end


function addon:CanForceLoad()
	--	FIXME: check if this would've already been loaded
	return self:CanForceLoadAfter()
end


function addon:Enable()
	--	FIXME: delay this till after PLAYER_LOGIN or it'll get force-loaded
	Addon.enableAddon(self.name)
end


--	NOTE: only call for LoD, not force-loading
function addon:Load()
	assert(self:CanLoD())
	
	EnableAddOn(self.name)
	LoadAddOn(self.name)
end


function addon:ForceLoad()
	assert(self:CanForceLoad())
	--	TODO: make sure force-loading is available at this time
	
	EnableAddOn(self.name)	--	This should cause the game to also load this addon
end


function addon:GetDependencies()
	--	TODO: consider no-lib embeds as deps?
	return GetAddOnDependencies(self.index)
end


function addon:GetEmbeds()
	local embeds = {}
	
	local embedString = GetAddOnMetadata(self.name, "X-Embeds")
	
	if embedString then
		for match in string.gmatch(embedString, "[^,%s]+") do
			table.insert(embeds, match)
		end
	end
	
	return unpack(embeds)
end

function addon:IsLoaded()
	if IsAddOnLoaded(self.index) then
		return true
	else
		return false
	end
end