view DependencyLoader/Core.lua @ 15:a46bf694050c

cleaned up Tree's methods a bit and improved documentation Addon:Exists will now return false for Blizzard addons (needs to be handled better) Addon.lua will now use the raw hooks from the interface module fixed the inverted returns from IsForceLoadAvailable EnableAddOn and LoadAddOn hooks will now skip the extra processing if the addon does not exist or is a Blizzard addon moved the EnableAddOn queing to the interface
author mckenziemc
date Sat, 11 Dec 2010 01:48:39 -0800
parents 78b28ebdc169
children 1d8898cd1c82
line wrap: on
line source



local addonName, addonTable = ...


--	NOTE: current contents of this file are no longer used
if true then
	return
end

local Core, core = addonTable:NewClass("Core")


function Core:New()
	local instance = {}
	setmetatable(instance, self.instanceMetatable)
	
	instance.addons = {}
	instance.nameToIndex = {}
	
	for i=1,GetNumAddOns() do
		local newAddon = Addon:New(i)
		
		instance.addons[i] = newAddon
		instance.nameToIndex[newAddon:GetName()] = i
	end
	
	--	TODO: enable dependencies for any addons that have already loaded
	
	return instance
end


--	@param	addon	Name or index of the addon to retrieve.
--	@return 		The addon object, or nil if not found
function core:GetAddon(addon)
	if not Addon:Exists(addon) then
		return nil
	end
	
	local index

	if type(addon) == "string" then
		index = self.nameToIndex[addon]
	elseif type(addon) == "number" then
		index = addon
	end
	
	return self.addons[index]
end	


--	Checks if the tree rooted at the specified addon can be force-loaded.
--	@param	root	The name or index of the root addon.
function core:CanForceLoadTree(root)
	--	convert root to an Addon object
	root = self:GetAddon(root)
	assert(root)
	
	if root:IsLoaded() then
		return true
	end
	
	--	check if the root itself can be force-loaded
	if not root:CanForceLoad() then
		return false
	end
	
	--	now check dependencies recursively
	--	FIXME: prevent infinite recursion

	local dependencies = {root:GetDependencies()}
	for i, depName in pairs(dependencies) do
		local dep = self:GetAddon(depName)
		
		if dep == nil then
			return false		--	missing dependency
		end
		
		--	if it's already loaded then skip to next one
		if not dep:IsLoaded() then
			if not self:CanForceLoadTree(depName) then
				return false
			end
		end
	end
	
	return true
end

--	NOTE: any tree that can be loaded on demand is also eligible for force-loading
--	Checks if the tree rooted at the specified addon can be loaded on demand.
--	@param	root	The name or index of the root addon.
function core:CanLoDTree(root)
	root = self:GetAddon(root)
	assert(root)

	--	since this will be used recursively, return true if 
	--	this is already loaded.
	if root:IsLoaded() then
		return true
	end
	
	--	true if all dependencies are loaded or LoD
	
	if not root:CanLoD() then
		return false
	end
	
	--	now check dependencies recursively
	local dependencies = {root:GetDependencies()}
	for i, depName in pairs(dependencies) do
		local dep = self:GetAddon(depName)
		
		if not dep then
			return false		--	missing
		end
		
		if not dep:IsLoaded() then
			if not self:CanLoDTree(depName) then
				return false
			end
		end
	end
	
	return true
end


--	Checks if the tree rooted at the specified addon 
--	can be loaded if all dependencies are enabled 
--	the UI is reloaded.
--	Basically makes sure all dependencies are installed.
function core:CanReloadTree(root)
	--	convert root to an Addon object
	root = self:GetAddon(root)
	assert(root)
	
	if root:IsLoaded() then
		return true
		--	FIXME: 	deps may have been disabled
	end
	
	--	TODO: make sure the root isn't incompatible
	
	--	now check dependencies recursively
	--	FIXME: prevent infinite recursion

	local dependencies = {root:GetDependencies()}
	for i, depName in pairs(dependencies) do
		local dep = self:GetAddon(depName)
		
		if dep == nil then
			return false		--	missing dependency
		end

		--	TODO: make sure it's compatible
	end
	
	return true
end

--	Loads the tree rooted at the specified addon.
--	FIXME: load the root too or not?
--	Supports both LoD addons and those that require force-loading.
function core:LoadTree(addon)
	--	don't check if the tree can actually be loaded.
	--	external code should do that itself to check if it 
	--	should even call this at all.

	if self:ForceLoadAvailable() then
		--	LoD trees can also be force-loaded
		self:ForceLoadTree(addon)
	else
		self:LoadLoDTree(addon)
	end
end


--	load the root too, since it may actually be a leaf
function core:ForceLoadTree(root)
	root = self:GetAddon(root)
	assert(root)
	
	--	load dependencies
	local dependencies = {root:GetDependencies(addon)}
	for i, depName in pairs(dependencies) do
		self:ForceLoadTree(depName)
	end

	--	load embeds, if they are available separately
	local embeds = {root:GetEmbeds(addon)}
	for i, embedName in pairs(embeds) do
		if Addon:Exists(embedName) then
			self:ForceLoadTree(embedName)
		end
	end
	
	root:ForceLoad()
end


function core:LoadLoDTree(root)
	root = self:GetAddon(root)
	assert(root)
	
	--	load dependencies
	local dependencies = {root:GetDependencies(addon)}
	for i, depName in pairs(dependencies) do
		self:LoadLoDTree(depName)
	end

	--	load embeds, if they are available separately
	local embeds = {root:GetEmbeds(addon)}
	for i, embedName in pairs(embeds) do
		if Addon:Exists(embedName) then
			self:LoadLoDTree(embedName)
		end
	end
	
	root:LoD()
end


--	I think the problem this solves is a major issue with 
--	migrating to separate libs. think about it more and document 
--	here and in project description
function core:PrepareLoDTree(root)
	root = self:GetAddon(root)
	assert(root)
	
	--	assume root is LoD
	
	--	check dependencies
	local dependencies = {root:GetDependencies(addon)}
	for i, depName in pairs(dependencies) do
		local dep = self:GetAddon(depName)
		
		--	assume external code made sure it exists
		
		if dep:CanLoD() then
			--	don't load it now but make sure its dependencies are prepared
			self:PrepareLoDTree(depName)
		else
			--	FIXME: if it's already loaded
			--	force-load it now so we can load the parent on demand
			self:ForceLoadTree(depName)
		end
	end

	--	prepare embeds, if they are available separately
	local embeds = {root:GetEmbeds(addon)}	--	FIXME: addon?
	for i, embedName in pairs(embeds) do
		local embed = self:GetAddon(embedName)
		
		if embed then
			if embed:CanLoD() then
				--	don't load it now but make sure its dependencies are prepared
				self:PrepareLoDTree(embedName)
			else
				--	FIXME: if it's already loaded
				--	force-load it now so we can load the parent on demand
				self:ForceLoadTree(depName)
			end
		end
	end
end


function Core:PrepareReloadTree(addon)
	root = self:GetAddon(root)
	assert(root)
	
	root:Enable()
	
	--	check dependencies
	local dependencies = {root:GetDependencies()}
	for i, depName in pairs(dependencies) do
		self:PrepareReloadTree(depName)
	end

	--	prepare embeds, if they are available separately
	local embeds = {root:GetEmbeds(addon)}
	for i, embedName in pairs(embeds) do
		local embed = self:GetAddon(embedName)
		
		if embed then
			self:PrepareReloadTree(embedName)
		end
	end
end


function Core:ForceLoadAvailable()
	return true
	--	FIXME: use field and a frame registered for PLAYER_LOGIN
end