comparison DependencyLoader/Tree.lua @ 10:e0a4a8b5b389

lots more modifications...
author mckenziemc
date Sun, 05 Dec 2010 03:10:07 -0800
parents 5362e308c3eb
children b230b94d4487
comparison
equal deleted inserted replaced
9:5362e308c3eb 10:e0a4a8b5b389
4 4
5 5
6 local addonName, addonTable = ... 6 local addonName, addonTable = ...
7 7
8 8
9 -- TODO: prevent infinite loops in the recursive functions 9 -- FIXME: prevent infinite loops in the recursive functions
10 10
11 11
12 local Tree, tree = addonTable:NewClass("Tree") 12 local Tree, tree = addonTable:NewClass("Tree")
13 13
14 14
15 Tree.trees = {} 15 Tree.trees = {}
16
16 17
17 -- internal 18 -- internal
18 -- Creates a new tree object 19 -- Creates a new tree object
19 -- @param root Name, index, or Addon object of the root addon. 20 -- @param root Name, index, or Addon object of the root addon.
20 function Tree:New(root) 21 function Tree:New(root)
66 67
67 return bitfield 68 return bitfield
68 end 69 end
69 70
70 71
71 -- Checks if the tree rooted at the specified addon can be force-loaded. 72 --- Checks if this tree can be force-loaded.
72 -- @param root The name or index of the root addon. 73 -- Does not check user settings nor if force-loading is actually available.
73 function core:CanForceLoadTree(root) 74 -- @return canForceLoad True if this tree can be force loaded, false otherwise
74 -- TODO: if some addons have already loaded, we have to check 75 function tree:CanForceLoad()
75 -- forceafter for those and forcebefore for the others 76 if self.root:IsLoaded() then
76 return false 77 return true
78 end
79
80 if not self.root:CanForceLoad() then
81 return false
82 end
83
84 -- now check dependencies recursively
85 local dependencies = {self.root:GetDependencies()}
86 for i, depName in pairs(dependencies) do
87 local depTree = Tree:Get(depName)
88
89 if not depTree:CanForceLoad() then
90 return false
91 end
92 end
93
94 return
77 end 95 end
78 96
79 97
80 -- NOTE: any tree that can be loaded on demand is also eligible for force-loading 98 -- NOTE: any tree that can be loaded on demand is also eligible for force-loading
81 -- Checks if the tree rooted at the specified addon can be loaded on demand. 99 -- Checks if the tree can be loaded on demand.
82 -- @param root The name or index of the root addon. 100 function tree:CanLoD()
83 function core:CanLoDTree(root)
84 local bitfield = self:GetLoadBitfield()
85 root = self:GetAddon(root)
86 assert(root)
87
88 -- since this will be used recursively, return true if 101 -- since this will be used recursively, return true if
89 -- this is already loaded. 102 -- this is already loaded.
90 if root:IsLoaded() then 103 if self.root:IsLoaded() then
91 return true 104 return true
92 end 105 end
93 106
94 -- true if all dependencies are loaded or LoD 107 -- true if all dependencies are loaded or LoD
95 108
96 if not root:CanLoD() then 109 if not self.root:CanLoD() then
97 return false 110 return false
98 end 111 end
99 112
100 -- now check dependencies recursively 113 -- now check dependencies recursively
101 local dependencies = {root:GetDependencies()} 114 local dependencies = {root:GetDependencies()}
102 for i, depName in pairs(dependencies) do 115 for i, depName in pairs(dependencies) do
103 local dep = self:GetAddon(depName) 116 local depTree = Tree:Get(depName)
104 117
105 if not dep then 118 if not depTree:CanLoD() then
106 return false -- missing 119 return false
107 end
108
109 if not dep:IsLoaded() then
110 if not self:CanLoDTree(depName) then
111 return false
112 end
113 end 120 end
114 end 121 end
115 122
116 return true 123 return true
117 end 124 end
119 126
120 -- Checks if the tree rooted at the specified addon 127 -- Checks if the tree rooted at the specified addon
121 -- can be loaded if all dependencies are enabled 128 -- can be loaded if all dependencies are enabled
122 -- the UI is reloaded. 129 -- the UI is reloaded.
123 -- Basically makes sure all dependencies are installed. 130 -- Basically makes sure all dependencies are installed.
124 function core:CanReloadTree(root) 131 function tree:CanLoad()
125 -- convert root to an Addon object 132 if self.root:IsLoaded() then
126 root = self:GetAddon(root)
127 assert(root)
128
129 if root:IsLoaded() then
130 return true 133 return true
131 -- FIXME: deps may have been disabled 134 -- FIXME: deps may have been disabled
132 end 135 end
133 136
134 -- TODO: make sure the root isn't incompatible 137 -- TODO: make sure the root isn't incompatible
135 138
136 -- now check dependencies recursively 139 -- now check dependencies recursively
137 -- FIXME: prevent infinite recursion 140 -- FIXME: prevent infinite recursion
138 141
139 local dependencies = {root:GetDependencies()} 142 local dependencies = {self.root:GetDependencies()}
140 for i, depName in pairs(dependencies) do 143 for i, depName in pairs(dependencies) do
141 local dep = self:GetAddon(depName) 144 local depTree = Tree:Get(depName)
142 145
143 if dep == nil then 146 if not depTree:CanLoad() then
144 return false -- missing dependency 147 return false -- missing dependency
145 end 148 end
146 149
147 -- TODO: make sure it's compatible 150 -- TODO: make sure it's compatible
148 end 151 end
149 152
150 return true 153 return true
151 end 154 end
152 155
156 --[[
153 -- Loads the tree rooted at the specified addon. 157 -- Loads the tree rooted at the specified addon.
154 -- FIXME: load the root too or not? 158 -- FIXME: load the root too or not?
155 -- Supports both LoD addons and those that require force-loading. 159 -- Supports both LoD addons and those that require force-loading.
156 function core:LoadTree(addon) 160 function tree:Load(addon)
157 -- don't check if the tree can actually be loaded. 161 -- don't check if the tree can actually be loaded.
158 -- external code should do that itself to check if it 162 -- external code should do that itself to check if it
159 -- should even call this at all. 163 -- should even call this at all.
160 164
161 if self:ForceLoadAvailable() then 165 if self:ForceLoadAvailable() then
163 self:ForceLoadTree(addon) 167 self:ForceLoadTree(addon)
164 else 168 else
165 self:LoadLoDTree(addon) 169 self:LoadLoDTree(addon)
166 end 170 end
167 end 171 end
172 ]]
168 173
169 174
170 -- load the root too, since it may actually be a leaf 175 -- load the root too, since it may actually be a leaf
171 function core:ForceLoadTree(root) 176 function tree:ForceLoad()
172 root = self:GetAddon(root)
173 assert(root)
174
175 -- load dependencies 177 -- load dependencies
176 local dependencies = {root:GetDependencies(addon)} 178 local dependencies = {self.root:GetDependencies()}
177 for i, depName in pairs(dependencies) do 179 for i, depName in pairs(dependencies) do
178 self:ForceLoadTree(depName) 180 local depTree = Tree:Get(depName)
181 depTree:ForceLoad()
179 end 182 end
180 183
181 -- load embeds, if they are available separately 184 -- load embeds, if they are available separately
182 local embeds = {root:GetEmbeds(addon)} 185 local embeds = {self.root:GetEmbeds()}
183 for i, embedName in pairs(embeds) do 186 for i, embedName in pairs(embeds) do
184 if Addon:Exists(embedName) then 187 local embedTree = Tree:Get(embedName)
185 self:ForceLoadTree(embedName) 188 embedTree:ForceLoad()
186 end
187 end 189 end
188 190
189 root:ForceLoad() 191 root:ForceLoad()
190 end 192 end
191 193
192 194
195 --[[ don't think i need this
193 function core:LoadLoDTree(root) 196 function core:LoadLoDTree(root)
194 root = self:GetAddon(root) 197 root = self:GetAddon(root)
195 assert(root) 198 assert(root)
196 199
197 -- load dependencies 200 -- load dependencies
208 end 211 end
209 end 212 end
210 213
211 root:LoD() 214 root:LoD()
212 end 215 end
216 ]]
213 217
214 218
215 -- I think the problem this solves is a major issue with 219 -- I think the problem this solves is a major issue with
216 -- migrating to separate libs. think about it more and document 220 -- migrating to separate libs. think about it more and document
217 -- here and in project description 221 -- here and in project description
218 function core:PrepareLoDTree(root) 222 function tree:PrepareForLoD()
219 root = self:GetAddon(root)
220 assert(root)
221
222 -- assume root is LoD 223 -- assume root is LoD
223 224
224 -- check dependencies 225 -- check dependencies
225 local dependencies = {root:GetDependencies(addon)} 226 local dependencies = {root:GetDependencies(addon)}
226 for i, depName in pairs(dependencies) do 227 for i, depName in pairs(dependencies) do
227 local dep = self:GetAddon(depName) 228 local depTree = Tree:Get(depName)
228 229 depTree:PrepareForLoD()
229 -- assume external code made sure it exists 230
230 231 --[[
231 if dep:CanLoD() then 232 if dep:CanLoD() then
232 -- don't load it now but make sure its dependencies are prepared 233 -- don't load it now but make sure its dependencies are prepared
233 self:PrepareLoDTree(depName) 234 self:PrepareLoDTree(depName)
234 else 235 else
235 -- FIXME: if it's already loaded 236 -- FIXME: if it's already loaded
236 -- force-load it now so we can load the parent on demand 237 -- force-load it now so we can load the parent on demand
237 self:ForceLoadTree(depName) 238 self:ForceLoadTree(depName)
238 end 239 end
240 ]]
239 end 241 end
240 242
241 -- prepare embeds, if they are available separately 243 -- prepare embeds, if they are available separately
242 local embeds = {root:GetEmbeds(addon)} -- FIXME: addon? 244 local embeds = {root:GetEmbeds(addon)} -- FIXME: addon?
243 for i, embedName in pairs(embeds) do 245 for i, embedName in pairs(embeds) do
244 local embed = self:GetAddon(embedName) 246 local embedTree = Tree:Get(embedName)
245 247 embedTree:PrepareForLoD()
248
249 --[[
246 if embed then 250 if embed then
247 if embed:CanLoD() then 251 if embed:CanLoD() then
248 -- don't load it now but make sure its dependencies are prepared 252 -- don't load it now but make sure its dependencies are prepared
249 self:PrepareLoDTree(embedName) 253 self:PrepareLoDTree(embedName)
250 else 254 else
251 -- FIXME: if it's already loaded 255 -- FIXME: if it's already loaded
252 -- force-load it now so we can load the parent on demand 256 -- force-load it now so we can load the parent on demand
253 self:ForceLoadTree(depName) 257 self:ForceLoadTree(depName)
254 end 258 end
255 end 259 end
256 end 260 ]]
257 end 261 end
258 262 end
259 263
260 function Core:PrepareReloadTree(addon) 264
261 root = self:GetAddon(root) 265 function tree:PrepareForReload()
262 assert(root) 266 self.root:Enable()
263
264 root:Enable()
265 267
266 -- check dependencies 268 -- check dependencies
267 local dependencies = {root:GetDependencies()} 269 local dependencies = {self.root:GetDependencies()}
268 for i, depName in pairs(dependencies) do 270 for i, depName in pairs(dependencies) do
269 self:PrepareReloadTree(depName) 271 Tree:Get(depName):PrepareForReload()
270 end 272 end
271 273
272 -- prepare embeds, if they are available separately 274 -- prepare embeds, if they are available separately
273 local embeds = {root:GetEmbeds(addon)} 275 local embeds = {self.root:GetEmbeds(addon)}
274 for i, embedName in pairs(embeds) do 276 for i, embedName in pairs(embeds) do
275 local embed = self:GetAddon(embedName) 277 Tree:Get(embedName):PrepareForReload()
276 278 end
277 if embed then 279 end
278 self:PrepareReloadTree(embedName)
279 end
280 end
281 end
282
283
284 function Core:ForceLoadAvailable()
285 return true
286 -- FIXME: use field and a frame registered for PLAYER_LOGIN
287 end