diff DependencyLoader/Addon.lua @ 9:5362e308c3eb

renamed the old DependencyLoader module to DependencyLoader_Bootstrap renamed DependencyLoader_Core to DependencyLoader
author mckenziemc
date Sun, 05 Dec 2010 00:12:57 -0800
parents DependencyLoader_Core/Addon.lua@930871e163bc
children e0a4a8b5b389
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DependencyLoader/Addon.lua	Sun Dec 05 00:12:57 2010 -0800
@@ -0,0 +1,248 @@
+--	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