view DependencyLoader/Core.lua @ 17:f825ccf94a89

fixed an indexing issue in Addon.lua moved most of the code in DependencyLoader.lua to Core.lua, and renamed the former to frontend.lua updated load.xml rearranged stuff in start.lua
author mckenziemc
date Sat, 11 Dec 2010 03:32:04 -0800
parents 1d8898cd1c82
children e7995d599184
line wrap: on
line source
--	Core
--	Provides core functionality of Core


--	TODO: disable bootstrap if we load successfully?
--	TODO: implement a feature to disable unneeded libraries when a parent 
--	is disabled?


local addonName, addonTable = ...


--	locals
local print = addonTable.print
local debug = addonTable.debug
local classes = addonTable.classes

local AceHook = LibStub("AceHook-3.0")
local LibScriptLink = LibStub("LibScriptLink-1.0")


local Core = addonTable:NewClass("Core")


AceHook:Embed(Core)

Core.queuedEnables = {}		--	addons queued to be enabled after PLAYER_LOGIN


--	Does not consider user settings or addon errata.
function Core:IsForceLoadAvailable()
	if IsLoggedIn() then
		return false
	else
		return true
	end
end


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


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


--	Enables any dependencies needed by the addons 
--	that have already been enabled
function Core:PrepareAllAddons()
	for i=1, GetNumAddOns() do
		local addon = 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(i)
		end
	end
end


function Core:SetHooks()
	self:RawHook("EnableAddOn", true)
	self:RawHook("LoadAddOn", true)
end


--	FIXME: use pcall in EnableAddOn and LoadAddOn, so that if my part errors,  
--	it can still use the unhooked version

function Core:EnableAddOn(...)
	local id = ...
	
	debug("EnableAddOn", ...)
	
	--	even though we know EnableAddOn can cause force-loading before PLAYER_LOGIN, 
	--	DO NOT attempt to "fix" it: another addon that -does- know about 
	--	the different behavior might call our hook.
	
	if classes.Addon:Exists(id) then
		local addon = classes.Addon:Get(id)
		local tree = 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:CanForceLoad() then
				if addon:CanLoD() then
					tree:PrepareForLoD()
				else
					tree:ForceLoad()
				end
			elseif tree:CanLoad() then
				tree:PrepareForLoad()
				requestReload = true
			else
				--	TODO: tell user
			end
			
			
			--[[
			if tree:CanLoDWithForce() then
				tree:PrepareForLoD()
			elseif tree:CanForceLoad() then
				tree:ForceLoad()
			elseif tree:CanLoad() then
				tree:PrepareForLoad()
				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:PrepareForLoad()
				--	don't actually intend to reload, just enable everything
			elseif tree:CanLoad() then
				tree:PrepareForLoad()
				requestReload = true
			else
				--	TODO: tell user
			end
		end
		
		if requestReload then
			self:RequestReload()
		end
	end
	
	--	propogate the call even if it doesn't exist or deps are unavailable
	return self:RawEnableAddOn(...)
end



---	Prepares the addon tree rooted at the specified addon
function Core:LoadAddOn(...)
	local id = ...
	
	debug("LoadAddOn", ...)
	
	if classes.Addon:Exists(id) then
		local addon = classes.Addon:Get(id)
		local tree = classes.Tree:Get(addon)
		
		if tree:CanLoD() then
			tree:PrepareForLoD()
		elseif tree:CanLoad() then
			tree:PrepareForLoad()
			--	TODO: request reload
		end
	end
		
	--	call even if it can't be loaded so regular returns appear
	return self:RawLoadAddOn(...)
end


function Core:RequestReload()
	--	TODO: this should be throtled so that it can 
	--	occur more than once but not within a short time
	
	debug("reload requested (NYI)")
end


--	name or index
function Core:QueueEnable(addon)
	self.queuedEnables[addon] = true
end


function Core:RawEnableAddOn(...)
	return self.hooks.EnableAddOn(...)
end


function Core:RawLoadAddOn(...)
	return self.hooks.LoadAddOn(...)
end


function Core:ProcessEnableQueue()
	for addon in pairs(self.queuedEnables) do
		self:RawEnableAddOn(addon)
		self.queuedEnables[addon] = nil
	end
end