My favorites
▼
|
Sign in
as3-bulk-preloader
A preloader for large AS3 applications
Project Home
Downloads
Wiki
Issues
Source
Checkout
Browse
Changes
Source path:
svn
/
trunk
/
src
/
com
/
alecmce
/
preloader
/
Preloader.as
r2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
/*
* Copyright 2009 (c) Alec McEachran, alec@alecmce.com.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
package com.alecmce.preloader
{
import br.com.stimuli.loading.BulkLoader;
import br.com.stimuli.loading.BulkProgressEvent;
import flash.display.Loader;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.ErrorEvent;
import flash.events.Event;
/**
* This is the document class for a preloader which should be built using
* FDT or the MXMLC compiler.
*
* The idea behind the preloader is that it will first load XML which
* defines an asset that acts as a preloader animation. Once that is
* loaded, all other defined assets are loaded and the progress is reflected
* by the preloader animation asset. Once all assets have been loaded, the
* initial asset, also defined in the XML is added to the stage, and optionally
* a method in that asset is triggered.
*
* Their are two premise behind this approach: firstly to manage loading a large
* number of different initial assets when an application is launched, and secondly
* to separate assets from application logic.
*
* Projects often have multiple assets that are required over the life of the
* application, and that these should all be loaded 'as one' while the preloader
* reflects their progress. The list of the assets to be preloaded can be easily
* managed by modifying the XML.
*
* Modification of the XML can be done independently from the modification of the
* preloader animation asset.
*
* The structure of the XML is as follows:
*
* <config init="mainSwfAsset.swf" method="init">
*
* <preloader url="preloaderAnimationAsset.swf" />
*
* <asset url="mainSwfAsset.swf" />
* <asset url="secondSwfAsset.swf" />
* <asset url="secondPngAsset.png" />
* <asset url="secondPngAsset.png" />
* ...
* <asset url="lastAsset.swf" />
* </config>
*
* In this example, first the preloaderAnimationAsset.swf will be loaded and
* its first frame will be loaded. Then all the <asset ... /> elements will
* be loaded and the overall proportion of the loading progress will be
* displayed by the frame being updated. When all assets are loaded,
* the asset defined in the <config /> tag's init property will added to the
* stage, and if it has a method that matches the <config /> tag's method
* property, that method will be called without any parameters.
*
* The assets will be accessibly by retrieving the preloader singleton:
*
* Preloader.assetLoader()
*
* @author Alec McEachran
*/
public class Preloader extends Sprite
{
/*********************************************************************/
// Public Static Methods
/*********************************************************************/
/** preloader singleton instance */
private static var instance:Preloader;
/**
* @return The bulk loader which contains references to all preloaded assets
*/
public static function assetLoader():BulkLoader
{
if (!instance)
return null;
return instance.loader;
}
/*********************************************************************/
// Constants
/*********************************************************************/
/** the name of the loader */
private const NAME:String = "preloader";
/** the default config XML */
private const DEFAULT_CONFIG:String = "config.xml";
/** the error message that is received if the configuration xml can't be found */
private const CONFIG_NOT_FOUND:String = "The configuration XML can't be found";
/** the error message that is received if the configuration xml is malformed */
private const CONFIG_MALFORMED:String = "The configuration XML is malformed";
/** the error message that is received if the preloader SWF can't be found */
private const PRELOADER_NOT_FOUND:String = "The preloader SWF can't be found";
/** the error message that is received if an asset SWF can't be found */
private const ASSET_NOT_FOUND:String = "The asset SWF can't be found";
/** the error message that is received if no target asset SWF is specified */
private const NO_TARGET:String = "The target asset isn't specified or can't be found";
/** the error message that is received if the target asset SWF is specified */
private const NO_TARGET_METHOD:String = "The target asset doesn't have the init method specified";
/***************************************************************/
// Member Variables
/***************************************************************/
/** the configuration URL */
private var config:String;
/** the configuration XML */
private var xml:XML;
/** the bulk loader which is used to load all items */
private var loader:BulkLoader;
/** the preloader MovieClip */
private var preloader:MovieClip;
/** the method in the asset to be called */
public var method:String;
/***************************************************************/
// Public Methods
/***************************************************************/
/**
* Class Constructor
*/
public function Preloader()
{
instance = this;
config = loaderInfo.parameters.config;
if (!config)
config = DEFAULT_CONFIG;
loadConfig();
}
/***************************************************************/
// Config Methods
/***************************************************************/
/**
* Load the configuration XML.
*/
private function loadConfig():void
{
loader = new BulkLoader(NAME);
loader.addEventListener(ErrorEvent.ERROR, onConfigError, false, 0, true);
loader.addEventListener(Event.COMPLETE, onConfigLoaded, false, 0, true);
loader.add(config);
loader.start();
}
/**
* Remove bulk loader listeners added while loading the configuration XML.
*/
private function removeConfigListeners():void
{
loader.removeEventListener(ErrorEvent.ERROR, onConfigError);
loader.removeEventListener(Event.COMPLETE, onConfigLoaded);
}
/**
* Throw an error if the configuration XML cannot be found.
*
* @param event An event indicating that the configuration XML can't be
* found
*/
private function onConfigError(event:ErrorEvent):void
{
removeConfigListeners();
throw new Error(CONFIG_NOT_FOUND);
}
/**
* Parse the configuration XML and load the preloader animation asset.
* If the XML is malformed throw an error to indicate that fact.
*
* @param event The event indicating that the configuration XML has
* been successfully loaded
*/
private function onConfigLoaded(event:Event):void
{
removeConfigListeners();
try
{
xml = loader.getXML(config, true);
var url:String = xml.preloader.@url;
if (url != "")
loadPreloader(url);
}
catch (err:Error)
{
throw new Error(CONFIG_MALFORMED);
return;
}
}
/*********************************************************************/
// Preloader Methods
/*********************************************************************/
/**
* Load the preloader animation asset.
*
* @param url The URL of the preloader animation asset, passed from
* the configuration XML
*/
private function loadPreloader(url:String):void
{
loader.addEventListener(ErrorEvent.ERROR, onPreloaderError, false, 0, true);
loader.addEventListener(Event.COMPLETE, onPreloaderLoaded, false, 0, true);
loader.add(url);
loader.start();
}
/**
* Remove the listeners added for the loading of the preloader
* animation assset.
*/
private function removePreloaderListeners():void
{
loader.removeEventListener(ErrorEvent.ERROR, onPreloaderError);
loader.removeEventListener(Event.COMPLETE, onPreloaderLoaded);
}
/**
* Throw an error if the defined preloader animation asset cannot be
* found.
*
* @param event An event indicating that the preloader asset can't be
* found
*/
private function onPreloaderError(event:ErrorEvent):void
{
removePreloaderListeners();
throw new Error(PRELOADER_NOT_FOUND);
}
/**
* Add the preloader asset to the stage and load all the other assets.
*
* @param event The event which indicates that the preloader animation
* asset has been loaded
*/
private function onPreloaderLoaded(event:Event):void
{
removePreloaderListeners();
addPreloader();
try
{
loadAssets();
}
catch (err:Error)
{
throw new Error(CONFIG_MALFORMED);
return;
}
}
/**
* Add the preloader asset to the stage.
*/
private function addPreloader():void
{
preloader = loader.getContent(xml.preloader.@url) as MovieClip;
var itemLoader:Loader = preloader.loaderInfo.loader;
itemLoader.name = NAME;
addChild(itemLoader);
preloader.gotoAndStop(1);
}
/**
* Remove the preloader from the stage (and from memory).
*/
private function removePreloader():void
{
var itemLoader:Loader = getChildByName(NAME) as Loader;
removeChild(itemLoader);
loader.remove(xml.preloader.@url);
}
/*********************************************************************/
// Asset Loader Methods
/*********************************************************************/
/**
* Load the assets defined in the configuration XML.
*/
private function loadAssets():void
{
var node:XML;
var url:String;
for each (node in xml.asset)
{
url = node.@url;
if (url != "")
loader.add(url);
}
loader.addEventListener(ErrorEvent.ERROR, onAssetsError, false, 0, true);
loader.addEventListener(Event.COMPLETE, onAssetsLoaded, false, 0, true);
loader.addEventListener(BulkProgressEvent.PROGRESS, onAssetsProgress, false, 0, true);
loader.start();
}
/**
* Remove the event listeners that were added for monitoring the
* loading of assets.
*/
private function removeAssetListeners():void
{
loader.removeEventListener(ErrorEvent.ERROR, onAssetsError);
loader.removeEventListener(Event.COMPLETE, onAssetsLoaded);
loader.removeEventListener(BulkProgressEvent.PROGRESS, onAssetsProgress);
}
/**
* Throw an error if an asset cannot be found.
*
* @param event An event indicating that an asset can't be found
*/
private function onAssetsError(event:ErrorEvent):void
{
removeAssetListeners();
throw new Error(ASSET_NOT_FOUND);
}
/**
* Remove the preloader and launch the target asset indicated in
* the configuration XML.
*
* @param event An event which indicates that all of the assets
* have been loaded
*/
private function onAssetsLoaded(event:Event):void
{
removeAssetListeners();
try
{
removePreloader();
launchTarget();
}
catch (err:Error)
{
throw new Error(CONFIG_MALFORMED);
return;
}
}
/**
* Launch the asset defined as the primary asset by the configuration
* XML, calling a method in the asset if the method is defined in XML
* and exists in the asset.
*/
private function launchTarget():void
{
var init:String = xml.@init;
var method:String = xml.@method;
if (!init)
{
throw new Error(NO_TARGET);
return;
}
var target:MovieClip = loader.getContent(init) as MovieClip;
var targetLoader:Loader = target.loaderInfo.loader;
addChild(targetLoader);
if (method && target.hasOwnProperty(method))
{
var fn:Function = target[method] as Function;
if (fn == null)
{
throw new Error(NO_TARGET_METHOD);
return;
}
fn.call();
}
}
/**
* Update the frame of the preloader animation asset in order to
* indicate the proportion of the preloading assets that have
* been loaded so far.
*
* @param event An event from the bulk loader which contains
* statistics for how much of the assets have been loaded so far
*/
private function onAssetsProgress(event:BulkProgressEvent):void
{
var frame:int = (event.percentLoaded * preloader.totalFrames) >> 0;
preloader.gotoAndStop(frame);
}
}
}
Show details
Hide details
Change log
r2
by a...@alecmce.com on Aug 1, 2009
Diff
add source code folder
Go to:
/trunk/src
/trunk/src/com
/trunk/src/com/alecmce
/trunk/src/com/alecmce/preloader
...m/alecmce/preloader/Preloader.as
Project members,
sign in
to write a code review
Older revisions
All revisions of this file
File info
Size: 13812 bytes, 472 lines
View raw file
Powered by
Google Project Hosting