diff 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 diff
--- a/DependencyLoader/Core.lua	Sat Dec 11 01:54:15 2010 -0800
+++ b/DependencyLoader/Core.lua	Sat Dec 11 03:32:04 2010 -0800
@@ -1,8 +1,218 @@
 --	Core
---	Provides core functionality of DependencyLoader
+--	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 = ...
 
 
-local Core, core = addonTable:NewClass("Core")
+--	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