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


local addonName, addonTable = ...


--	NOTE: I assume that the API addon functions are 
--	slightly quicker with an index than with a number.

--	TODO: modify the dependency stuff to use the Errata module if available

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


--	load ability masks
Addon.loadMasks = {
	reload = 		bit.lshift(1, 0),	--	can load after reloadui
	ondemand = 		bit.lshift(1, 1),	--	can load on demand
	forceafter = 	bit.lshift(1, 2),	--	force load after it would normally be loaded
	forcebefore = 	bit.lshift(1, 3),	--	force load before it would normally be loaded
}


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
			error("Addon not found")
		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:GetLoadMasks()
	return self.masks
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


function addon:GetLoadBitfield()
	local bitfield = 0
	
	if self:CanLoad() then
		bitfield = bitfield + self.masks.reload
	end
	
	if self:CanLoD() then
		bitfield = bitfield + self.masks.ondemand
	end
	
	if self:CanForceLoadAfter() then
		bitfield = bitfield + self.masks.forceafter
	end
	
	if self:CanForceLoadBefore() then
		bitfield = bitfield + self.masks.forcebefore
	end
	
	return bitfield
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:Enable()
	--	FIXME: delay this till after PLAYER_LOGIN or it'll get force-loaded
	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