view DependencyLoader/DependencyLoader.lua @ 14:78b28ebdc169

added embeds.xml to load.xml added a couple of other internal notes
author mckenziemc
date Fri, 10 Dec 2010 05:29:22 -0800
parents b230b94d4487
children a46bf694050c
line wrap: on
line source
--	DependencyLoader
--	


--	TODO: implement a feature to disable unneeded libraries when a parent 
--	is disabled?

local addonName, addonTable = ...


local DependencyLoader = LibStub("AceAddon-3.0"):NewAddon(addonName, "AceHook-3.0")
_G[addonName] = DependencyLoader

addonTable.interface = DependencyLoader


local LibPrint = LibStub("LibPrint-1.0")
local LibScriptLink = LibStub("LibScriptLink-1.0")

DependencyLoader.printStream = LibPrint:NewStream("DependencyLoader", "DpLdr", print)
DependencyLoader.debugStream = LibPrint:NewStream("DependencyLoader", "DpLdr", "mcm")


function DependencyLoader:Print(...)
	self.printStream:Print(...)
end


function DependencyLoader:Debug(...)
	self.debugStream:Print(...)
end


function DependencyLoader:OnInitialize()
	self:Debug("Initializing", addonName)
	self:Enable()
end


function DependencyLoader:OnEnable()
	self:RawHook("LoadAddOn", true)
	self:RawHook("EnableAddOn", true)
	
	self:PrepareAllAddons()
	
	self:Print("Enabled", addonName)
end


function DependencyLoader:OnDisable()
	self:Print("Disabled", addonName)
end


--	Does not consider user settings or addon errata.
function DependencyLoader:IsForceLoadAvailable()
	return IsLoggedIn() and true or false
end


function DependencyLoader:IsForceLoadAllowed()
	--	TODO: check user settings
	return true
end


function DependencyLoader:CanForceLoad()
	return self:IsForceLoadAvailable() and self:IsForceLoadAllowed()
end


--	Enables any dependencies needed by the addons 
--	that have already been enabled
function DependencyLoader:PrepareAllAddons()
	local requestReload = false
	
	for i=1, GetNumAddOns() do
		local addon = addonTable.classes.Addon:Get(i)
		
		--	TODO: what if an addon was loaded but its deps were then disabled?
		if addon:IsEnabled() and not addon:IsLoaded() then
			self:EnableAddOn(addon:GetName())
		end
	end
	
	--[[
	if requestReload then
		local message = LibScriptLink:NewLink(ReloadUI) .. " to reload your UI."
		self:Print(message)
	end
	]]
end


function DependencyLoader:EnableAddOn(...)
	local id = ...
	local addon = addonTable.classes.Addon:Get(id)
	local tree = addonTable.classes.Tree:Get(addon)
	
	local requestReload = false
	
	if self:CanForceLoad() then
		--	NOTE: if we can force-load, then will enabling LoD addons cause them to load too?
		--	A: no, they will still wait for LoadAddOn
		
		--	Can the addon be loaded on demand if force-loading is 
		--	allowed for its dependencies
		--	if so, enable all deps and force-load if nec.
		--		deps will get enabled if all parents are lod, force-loaded
		--		if any parent can't be loaded on demand
		--	else
		--	if the addon is not loadable on demand but the tree can be
		--	force-loaded, then force-load it all
		--		deps will all get loaded since req. for root to load
		--	else
		--	if it can be loaded with a reloadui then prepare after login
		--	else
		--	it can't be loaded, maybe tell the user
		
		if tree:CanLoDWithForce() then
			tree:PrepareForLoD()
		elseif tree:CanForceLoad() then
			tree:ForceLoad()
		elseif tree:CanLoad() then
			tree:PrepareForReload()
			requestReload = true
		else
			--	TODO: tell user
		end
	else
		--	if it can be loaded on demand (deps are loaded or LoD) then
		--	prepare it (enable all deps)
		--	else
		--	if it can be loaded (and isn't already) then
		--		if force loading is available, we have to wait, then enable everything
		--		else
		--		prepare for reload (TODO: move this check and similar to PLAYER_LOGOUT)
		--	else
		--	can't be loaded, maybe tell the user
		
		if tree:CanLoD() then
			tree:PrepareForReload()
			--	don't actually intend to reload, just enable everything
		elseif tree:CanLoad() then
			tree:PrepareForReload()
			requestReload = true
		else
			--	TODO: tell user
		end
	end
	
	--	TODO: requestReload
	
	return self.hooks.EnableAddOn(...)
end



---	Prepares the addon tree rooted at the specified addon
function DependencyLoader:LoadAddOn(...)
	local id = ...
	
	local isBlizzardAddon = false
	
	if type(id) == "string" and string.match(id, "Blizzard_") then
		self:Debug("Asked to load Blizzard addon", id, ", skipping")
		isBlizzardAddon = true
	end
	
	if not isBlizzardAddon then
		local addon = addonTable.classes.Addon:Get(id)
		local tree = addonTable.classes.Tree:Get(addon)
		
		if tree:CanLoD() then
			tree:PrepareForLoD()
		elseif tree:CanLoad() then
			tree:PrepareForReload()
		end
	end
		
	--	call even if it can't be loaded so regular returns appear
	return self.hooks.LoadAddOn(...)
end