mckenziemc@10
|
1 -- DependencyLoader
|
mckenziemc@0
|
2 --
|
mckenziemc@0
|
3
|
mckenziemc@12
|
4
|
mckenziemc@14
|
5 -- TODO: implement a feature to disable unneeded libraries when a parent
|
mckenziemc@14
|
6 -- is disabled?
|
mckenziemc@14
|
7
|
mckenziemc@0
|
8 local addonName, addonTable = ...
|
mckenziemc@0
|
9
|
mckenziemc@0
|
10
|
mckenziemc@10
|
11 local DependencyLoader = LibStub("AceAddon-3.0"):NewAddon(addonName, "AceHook-3.0")
|
mckenziemc@0
|
12 _G[addonName] = DependencyLoader
|
mckenziemc@0
|
13
|
mckenziemc@10
|
14 addonTable.interface = DependencyLoader
|
mckenziemc@10
|
15
|
mckenziemc@10
|
16
|
mckenziemc@12
|
17 local LibPrint = LibStub("LibPrint-1.0")
|
mckenziemc@10
|
18 local LibScriptLink = LibStub("LibScriptLink-1.0")
|
mckenziemc@10
|
19
|
mckenziemc@12
|
20 DependencyLoader.printStream = LibPrint:NewStream("DependencyLoader", "DpLdr", print)
|
mckenziemc@12
|
21 DependencyLoader.debugStream = LibPrint:NewStream("DependencyLoader", "DpLdr", "mcm")
|
mckenziemc@0
|
22
|
mckenziemc@0
|
23
|
mckenziemc@0
|
24 function DependencyLoader:Print(...)
|
mckenziemc@0
|
25 self.printStream:Print(...)
|
mckenziemc@0
|
26 end
|
mckenziemc@0
|
27
|
mckenziemc@0
|
28
|
mckenziemc@0
|
29 function DependencyLoader:Debug(...)
|
mckenziemc@0
|
30 self.debugStream:Print(...)
|
mckenziemc@0
|
31 end
|
mckenziemc@0
|
32
|
mckenziemc@0
|
33
|
mckenziemc@0
|
34 function DependencyLoader:OnInitialize()
|
mckenziemc@10
|
35 self:Debug("Initializing", addonName)
|
mckenziemc@0
|
36 self:Enable()
|
mckenziemc@0
|
37 end
|
mckenziemc@0
|
38
|
mckenziemc@0
|
39
|
mckenziemc@0
|
40 function DependencyLoader:OnEnable()
|
mckenziemc@12
|
41 self:RawHook("LoadAddOn", true)
|
mckenziemc@12
|
42 self:RawHook("EnableAddOn", true)
|
mckenziemc@12
|
43
|
mckenziemc@12
|
44 self:PrepareAllAddons()
|
mckenziemc@12
|
45
|
mckenziemc@10
|
46 self:Print("Enabled", addonName)
|
mckenziemc@0
|
47 end
|
mckenziemc@0
|
48
|
mckenziemc@10
|
49
|
mckenziemc@0
|
50 function DependencyLoader:OnDisable()
|
mckenziemc@0
|
51 self:Print("Disabled", addonName)
|
mckenziemc@0
|
52 end
|
mckenziemc@0
|
53
|
mckenziemc@0
|
54
|
mckenziemc@10
|
55 -- Does not consider user settings or addon errata.
|
mckenziemc@10
|
56 function DependencyLoader:IsForceLoadAvailable()
|
mckenziemc@10
|
57 return IsLoggedIn() and true or false
|
mckenziemc@10
|
58 end
|
mckenziemc@10
|
59
|
mckenziemc@10
|
60
|
mckenziemc@10
|
61 function DependencyLoader:IsForceLoadAllowed()
|
mckenziemc@10
|
62 -- TODO: check user settings
|
mckenziemc@10
|
63 return true
|
mckenziemc@10
|
64 end
|
mckenziemc@10
|
65
|
mckenziemc@10
|
66
|
mckenziemc@10
|
67 function DependencyLoader:CanForceLoad()
|
mckenziemc@10
|
68 return self:IsForceLoadAvailable() and self:IsForceLoadAllowed()
|
mckenziemc@10
|
69 end
|
mckenziemc@10
|
70
|
mckenziemc@0
|
71
|
mckenziemc@0
|
72 -- Enables any dependencies needed by the addons
|
mckenziemc@0
|
73 -- that have already been enabled
|
mckenziemc@12
|
74 function DependencyLoader:PrepareAllAddons()
|
mckenziemc@10
|
75 local requestReload = false
|
mckenziemc@10
|
76
|
mckenziemc@0
|
77 for i=1, GetNumAddOns() do
|
mckenziemc@10
|
78 local addon = addonTable.classes.Addon:Get(i)
|
mckenziemc@0
|
79
|
mckenziemc@10
|
80 -- TODO: what if an addon was loaded but its deps were then disabled?
|
mckenziemc@10
|
81 if addon:IsEnabled() and not addon:IsLoaded() then
|
mckenziemc@12
|
82 self:EnableAddOn(addon:GetName())
|
mckenziemc@0
|
83 end
|
mckenziemc@0
|
84 end
|
mckenziemc@10
|
85
|
mckenziemc@12
|
86 --[[
|
mckenziemc@10
|
87 if requestReload then
|
mckenziemc@10
|
88 local message = LibScriptLink:NewLink(ReloadUI) .. " to reload your UI."
|
mckenziemc@10
|
89 self:Print(message)
|
mckenziemc@10
|
90 end
|
mckenziemc@12
|
91 ]]
|
mckenziemc@0
|
92 end
|
mckenziemc@10
|
93
|
mckenziemc@10
|
94
|
mckenziemc@10
|
95 function DependencyLoader:EnableAddOn(...)
|
mckenziemc@12
|
96 local id = ...
|
mckenziemc@12
|
97 local addon = addonTable.classes.Addon:Get(id)
|
mckenziemc@12
|
98 local tree = addonTable.classes.Tree:Get(addon)
|
mckenziemc@12
|
99
|
mckenziemc@12
|
100 local requestReload = false
|
mckenziemc@12
|
101
|
mckenziemc@12
|
102 if self:CanForceLoad() then
|
mckenziemc@12
|
103 -- NOTE: if we can force-load, then will enabling LoD addons cause them to load too?
|
mckenziemc@12
|
104 -- A: no, they will still wait for LoadAddOn
|
mckenziemc@12
|
105
|
mckenziemc@12
|
106 -- Can the addon be loaded on demand if force-loading is
|
mckenziemc@12
|
107 -- allowed for its dependencies
|
mckenziemc@12
|
108 -- if so, enable all deps and force-load if nec.
|
mckenziemc@12
|
109 -- deps will get enabled if all parents are lod, force-loaded
|
mckenziemc@12
|
110 -- if any parent can't be loaded on demand
|
mckenziemc@12
|
111 -- else
|
mckenziemc@12
|
112 -- if the addon is not loadable on demand but the tree can be
|
mckenziemc@12
|
113 -- force-loaded, then force-load it all
|
mckenziemc@12
|
114 -- deps will all get loaded since req. for root to load
|
mckenziemc@12
|
115 -- else
|
mckenziemc@12
|
116 -- if it can be loaded with a reloadui then prepare after login
|
mckenziemc@12
|
117 -- else
|
mckenziemc@12
|
118 -- it can't be loaded, maybe tell the user
|
mckenziemc@12
|
119
|
mckenziemc@12
|
120 if tree:CanLoDWithForce() then
|
mckenziemc@12
|
121 tree:PrepareForLoD()
|
mckenziemc@12
|
122 elseif tree:CanForceLoad() then
|
mckenziemc@12
|
123 tree:ForceLoad()
|
mckenziemc@12
|
124 elseif tree:CanLoad() then
|
mckenziemc@12
|
125 tree:PrepareForReload()
|
mckenziemc@12
|
126 requestReload = true
|
mckenziemc@12
|
127 else
|
mckenziemc@12
|
128 -- TODO: tell user
|
mckenziemc@12
|
129 end
|
mckenziemc@12
|
130 else
|
mckenziemc@12
|
131 -- if it can be loaded on demand (deps are loaded or LoD) then
|
mckenziemc@12
|
132 -- prepare it (enable all deps)
|
mckenziemc@12
|
133 -- else
|
mckenziemc@12
|
134 -- if it can be loaded (and isn't already) then
|
mckenziemc@12
|
135 -- if force loading is available, we have to wait, then enable everything
|
mckenziemc@12
|
136 -- else
|
mckenziemc@12
|
137 -- prepare for reload (TODO: move this check and similar to PLAYER_LOGOUT)
|
mckenziemc@12
|
138 -- else
|
mckenziemc@12
|
139 -- can't be loaded, maybe tell the user
|
mckenziemc@12
|
140
|
mckenziemc@12
|
141 if tree:CanLoD() then
|
mckenziemc@12
|
142 tree:PrepareForReload()
|
mckenziemc@12
|
143 -- don't actually intend to reload, just enable everything
|
mckenziemc@12
|
144 elseif tree:CanLoad() then
|
mckenziemc@12
|
145 tree:PrepareForReload()
|
mckenziemc@12
|
146 requestReload = true
|
mckenziemc@12
|
147 else
|
mckenziemc@12
|
148 -- TODO: tell user
|
mckenziemc@12
|
149 end
|
mckenziemc@12
|
150 end
|
mckenziemc@12
|
151
|
mckenziemc@12
|
152 -- TODO: requestReload
|
mckenziemc@12
|
153
|
mckenziemc@12
|
154 return self.hooks.EnableAddOn(...)
|
mckenziemc@10
|
155 end
|
mckenziemc@12
|
156
|
mckenziemc@12
|
157
|
mckenziemc@12
|
158
|
mckenziemc@12
|
159 --- Prepares the addon tree rooted at the specified addon
|
mckenziemc@12
|
160 function DependencyLoader:LoadAddOn(...)
|
mckenziemc@12
|
161 local id = ...
|
mckenziemc@12
|
162
|
mckenziemc@12
|
163 local isBlizzardAddon = false
|
mckenziemc@12
|
164
|
mckenziemc@12
|
165 if type(id) == "string" and string.match(id, "Blizzard_") then
|
mckenziemc@12
|
166 self:Debug("Asked to load Blizzard addon", id, ", skipping")
|
mckenziemc@12
|
167 isBlizzardAddon = true
|
mckenziemc@12
|
168 end
|
mckenziemc@12
|
169
|
mckenziemc@12
|
170 if not isBlizzardAddon then
|
mckenziemc@12
|
171 local addon = addonTable.classes.Addon:Get(id)
|
mckenziemc@12
|
172 local tree = addonTable.classes.Tree:Get(addon)
|
mckenziemc@12
|
173
|
mckenziemc@12
|
174 if tree:CanLoD() then
|
mckenziemc@12
|
175 tree:PrepareForLoD()
|
mckenziemc@12
|
176 elseif tree:CanLoad() then
|
mckenziemc@12
|
177 tree:PrepareForReload()
|
mckenziemc@12
|
178 end
|
mckenziemc@12
|
179 end
|
mckenziemc@12
|
180
|
mckenziemc@12
|
181 -- call even if it can't be loaded so regular returns appear
|
mckenziemc@12
|
182 return self.hooks.LoadAddOn(...)
|
mckenziemc@12
|
183 end
|