diff --git a/lime/app/Preloader.hx b/lime/app/Preloader.hx index 3eca377f4..46c798556 100644 --- a/lime/app/Preloader.hx +++ b/lime/app/Preloader.hx @@ -21,6 +21,8 @@ import flash.events.ProgressEvent; import flash.Lib; #end +@:access(lime.utils.AssetLibrary) + #if !lime_debug @:fileXml('tags="haxe,release"') @:noDebug @@ -34,9 +36,10 @@ class Preloader #if flash extends Sprite #end { public var onComplete = new EventVoid> (); public var onProgress = new EventInt->Void> (); + private var bytesLoaded:Int; + private var bytesTotal:Int; + private var bytesTotalCache = new Map (); private var initLibraryNames:Bool; - private var itemsProgressLoaded:Int; - private var itemsProgressTotal:Int; private var libraries:Array; private var libraryNames:Array; private var loadedLibraries:Int; @@ -49,6 +52,8 @@ class Preloader #if flash extends Sprite #end { super (); #end + bytesLoaded = 0; + bytesTotal = 0; libraries = new Array (); libraryNames = new Array (); @@ -91,12 +96,9 @@ class Preloader #if flash extends Sprite #end { public function load ():Void { - itemsProgressLoaded = 0; - itemsProgressTotal = 0; - for (library in libraries) { - itemsProgressTotal += library.computeProgressTotal (); + bytesTotal += library.bytesTotal; } @@ -104,9 +106,10 @@ class Preloader #if flash extends Sprite #end { for (library in libraries) { - library.load ().onProgress (function (_, _) { + library.load ().onProgress (function (loaded, total) { - updateItemsProgress (); + bytesLoaded += loaded; + onProgress.dispatch (bytesLoaded, bytesTotal); }).onComplete (function (_) { @@ -121,9 +124,11 @@ class Preloader #if flash extends Sprite #end { } + // TODO: Handle bytes total better + for (name in libraryNames) { - itemsProgressTotal += 1; + bytesTotal += 200; } @@ -159,8 +164,7 @@ class Preloader #if flash extends Sprite #end { private function updateProgress ():Void { - update (itemsProgressLoaded, itemsProgressTotal); - // update (loadedLibraries, libraries.length); + onProgress.dispatch (bytesLoaded, bytesTotal); if (loadedLibraries == libraries.length && !initLibraryNames) { @@ -168,9 +172,23 @@ class Preloader #if flash extends Sprite #end { for (name in libraryNames) { - Assets.loadLibrary (name).onProgress (function (_, _) { + Assets.loadLibrary (name).onProgress (function (loaded, total) { - updateItemsProgress (); + if (total > 0) { + + if (!bytesTotalCache.exists (name)) { + + bytesTotalCache.set (name, total); + bytesTotal += (total - 200); + + } + + if (loaded > total) loaded = total; + bytesLoaded += loaded; + + onProgress.dispatch (bytesLoaded, bytesTotal); + + } }).onComplete (function (_) { @@ -195,16 +213,12 @@ class Preloader #if flash extends Sprite #end { } - private function updateItemsProgress ():Void { - - itemsProgressLoaded++; - updateProgress(); - - } #if flash private function current_onEnter (event:flash.events.Event):Void { + // TODO: Merge progress with library load progress + if (!loadedStage && Lib.current.loaderInfo.bytesLoaded == Lib.current.loaderInfo.bytesTotal) { loadedStage = true; diff --git a/lime/tools/helpers/AssetHelper.hx b/lime/tools/helpers/AssetHelper.hx index c0a8900dd..6a0b50cad 100644 --- a/lime/tools/helpers/AssetHelper.hx +++ b/lime/tools/helpers/AssetHelper.hx @@ -23,11 +23,20 @@ class AssetHelper { if (asset.type != AssetType.TEMPLATE) { + var size = 100; + + if (FileSystem.exists (asset.sourcePath)) { + + size = FileSystem.stat (asset.sourcePath).size; + + } + manifest.assets.push ({ id: asset.id, path: asset.resourceName, - type: Std.string (asset.type) + type: Std.string (asset.type), + size: size }); diff --git a/lime/utils/AssetLibrary.hx b/lime/utils/AssetLibrary.hx index 89db762ff..6d7ba11d1 100644 --- a/lime/utils/AssetLibrary.hx +++ b/lime/utils/AssetLibrary.hx @@ -26,6 +26,11 @@ class AssetLibrary { public var onChange = new EventVoid> (); + private var assetsLoaded:Int; + private var assetsTotal:Int; + private var bytesLoaded:Int; + private var bytesLoadedCache:Map; + private var bytesTotal:Int; private var cachedAudioBuffers = new Map (); private var cachedBytes = new Map (); private var cachedFonts = new Map (); @@ -34,12 +39,8 @@ class AssetLibrary { private var classTypes = new Map> (); private var paths = new Map (); private var preload = new Map (); - private var progressBytesLoadedCache:Map; - private var progressBytesLoaded:Int; - private var progressBytesTotal:Int; - private var progressLoaded:Int; - private var progressTotal:Int; private var promise:Promise; + private var sizes = new Map (); private var types = new Map (); #if (js && html5) @@ -49,7 +50,8 @@ class AssetLibrary { public function new () { - + bytesLoaded = 0; + bytesTotal = 0; } @@ -104,22 +106,18 @@ class AssetLibrary { var library:AssetLibrary = null; - if (manifest.version == 1) { + if (manifest.libraryType == null) { - if (manifest.libraryType == null) { - - library = new AssetLibrary (); - - } else { - - library = Type.createInstance (Type.resolveClass (manifest.libraryType), manifest.libraryArgs); - - } + library = new AssetLibrary (); - library.__fromManifest (manifest); + } else { + + library = Type.createInstance (Type.resolveClass (manifest.libraryType), manifest.libraryArgs); } + library.__fromManifest (manifest); + return library; } @@ -378,37 +376,16 @@ class AssetLibrary { } - public function computeProgressTotal ():Int { - - var result = 1; - - for (id in preload.keys ()) { - - switch (types.get (id)) { - - case BINARY, FONT, IMAGE, MUSIC, SOUND, TEXT: - - result++; - - default: - - } - - } - - return result; - - } public function load ():Future { if (promise == null) { promise = new Promise (); - progressBytesLoadedCache = new Map (); + bytesLoadedCache = new Map (); - progressLoaded = 0; - progressTotal = 1; + assetsLoaded = 0; + assetsTotal = 1; for (id in preload.keys ()) { @@ -416,7 +393,7 @@ class AssetLibrary { case BINARY: - progressTotal++; + assetsTotal++; var future = loadBytes (id); future.onProgress (load_onProgress.bind (id)); @@ -425,7 +402,7 @@ class AssetLibrary { case FONT: - progressTotal++; + assetsTotal++; var future = loadFont (id); future.onProgress (load_onProgress.bind (id)); @@ -434,7 +411,7 @@ class AssetLibrary { case IMAGE: - progressTotal++; + assetsTotal++; var future = loadImage (id); future.onProgress (load_onProgress.bind (id)); @@ -443,7 +420,7 @@ class AssetLibrary { case MUSIC, SOUND: - progressTotal++; + assetsTotal++; var future = loadAudioBuffer (id); future.onProgress (load_onProgress.bind (id)); @@ -452,7 +429,7 @@ class AssetLibrary { case TEXT: - progressTotal++; + assetsTotal++; var future = loadText (id); future.onProgress (load_onProgress.bind (id)); @@ -465,7 +442,7 @@ class AssetLibrary { } - updateProgressLoaded (); + __assetLoaded (null); } @@ -637,13 +614,41 @@ class AssetLibrary { } - private function updateProgressLoaded ():Void { + private function __assetLoaded (id:String):Void { - progressLoaded++; - promise.progress(progressLoaded, progressTotal); + assetsLoaded++; - if (progressLoaded == progressTotal) { + if (id != null) { + var size = sizes.get (id); + + if (!bytesLoadedCache.exists (id)) { + + bytesLoaded += size; + + } else { + + var cache = bytesLoadedCache.get (id); + + if (cache < size) { + + bytesLoaded += (size - cache); + + } + + } + + bytesLoadedCache.set (id, size); + + } + + if (assetsLoaded < assetsTotal) { + + promise.progress (bytesLoaded, bytesTotal); + + } else { + + promise.progress (bytesTotal, bytesTotal); promise.complete (this); } @@ -653,12 +658,22 @@ class AssetLibrary { private function __fromManifest (manifest:AssetManifest):Void { - if (manifest.version == 1) { + var hasSize = (manifest.version >= 2); + var size; + + bytesTotal = 0; + + for (asset in manifest.assets) { - for (asset in manifest.assets) { + size = hasSize ? asset.size : 100; + + paths.set (asset.id, asset.path); + sizes.set (asset.id, size); + types.set (asset.id, asset.type); + + if (preload.exists (asset.id)) { - paths.set (asset.id, asset.path); - types.set (asset.id, asset.type); + bytesTotal += size; } @@ -677,7 +692,7 @@ class AssetLibrary { private function loadAudioBuffer_onComplete (id:String, audioBuffer:AudioBuffer):Void { cachedAudioBuffers.set (id, audioBuffer); - updateProgressLoaded (); + __assetLoaded (id); } @@ -685,7 +700,7 @@ class AssetLibrary { private function loadBytes_onComplete (id:String, bytes:Bytes):Void { cachedBytes.set (id, bytes); - updateProgressLoaded (); + __assetLoaded (id); } @@ -693,7 +708,7 @@ class AssetLibrary { private function loadFont_onComplete (id:String, font:Font):Void { cachedFonts.set (id, font); - updateProgressLoaded (); + __assetLoaded (id); } @@ -701,7 +716,7 @@ class AssetLibrary { private function loadImage_onComplete (id:String, image:Image):Void { cachedImages.set (id, image); - updateProgressLoaded (); + __assetLoaded (id); } @@ -709,7 +724,7 @@ class AssetLibrary { private function loadText_onComplete (id:String, text:String):Void { cachedText.set (id, text); - updateProgressLoaded (); + __assetLoaded (id); } @@ -723,21 +738,42 @@ class AssetLibrary { private function load_onProgress (id:String, bytesLoaded:Int, bytesTotal:Int):Void { - if (progressBytesLoadedCache.exists (id)) { + if (bytesLoaded > 0) { - var previous = progressBytesLoadedCache.get (id); - progressBytesLoaded += (bytesLoaded - previous); - progressBytesLoadedCache.set (id, bytesLoaded); - - promise.progress (progressBytesLoaded, progressBytesTotal); - - } else { + var size = sizes.get (id); + var percent; if (bytesTotal > 0) { - progressBytesLoadedCache.set (id, bytesLoaded); - progressBytesLoaded += bytesLoaded; - progressBytesTotal += bytesTotal; + // Use a ratio in case the real bytesTotal is different than our precomputed total + + percent = (bytesLoaded / bytesTotal); + if (percent > 1) percent = 1; + bytesLoaded = Math.floor (percent * size); + + } else if (bytesLoaded > size) { + + bytesLoaded = size; + + } + + if (bytesLoadedCache.exists (id)) { + + var cache = bytesLoadedCache.get (id); + + if (bytesLoaded != cache) { + + bytesLoaded += (bytesLoaded - cache); + + } + + bytesLoadedCache.set (id, bytesLoaded); + promise.progress (this.bytesLoaded, this.bytesTotal); + + } else { + + bytesLoadedCache.set (id, bytesLoaded); + this.bytesLoaded += bytesLoaded; } diff --git a/lime/utils/AssetManifest.hx b/lime/utils/AssetManifest.hx index 10653f484..b81c8c05d 100644 --- a/lime/utils/AssetManifest.hx +++ b/lime/utils/AssetManifest.hx @@ -30,7 +30,7 @@ class AssetManifest { assets = []; libraryArgs = []; - version = 1; + version = 2; } @@ -82,14 +82,10 @@ class AssetManifest { var manifestData = Json.parse (data); var manifest = new AssetManifest (); - if (manifestData.version == 1) { - - manifest.name = manifestData.name; - manifest.libraryType = manifestData.libraryType; - manifest.libraryArgs = manifestData.libraryArgs; - manifest.assets = Unserializer.run (manifestData.assets); - - } + manifest.name = manifestData.name; + manifest.libraryType = manifestData.libraryType; + manifest.libraryArgs = manifestData.libraryArgs; + manifest.assets = Unserializer.run (manifestData.assets); return manifest; diff --git a/lime/utils/Assets.hx b/lime/utils/Assets.hx index 5f699d78b..b190824f9 100644 --- a/lime/utils/Assets.hx +++ b/lime/utils/Assets.hx @@ -486,9 +486,18 @@ class Assets { if (data != null && data != "") { var library = AssetLibrary.fromManifest (AssetManifest.parse (data)); - libraries.set (name, library); - library.onChange.add (onChange.dispatch); - promise.completeWith (library.load ()); + + if (library == null) { + + promise.error ("[Assets] Cannot open library \"" + name + "\""); + + } else { + + libraries.set (name, library); + library.onChange.add (onChange.dispatch); + promise.completeWith (library.load ()); + + } } else { diff --git a/templates/haxe/DefaultAssetLibrary.hx b/templates/haxe/DefaultAssetLibrary.hx index 3deb1339c..61c9f2b70 100644 --- a/templates/haxe/DefaultAssetLibrary.hx +++ b/templates/haxe/DefaultAssetLibrary.hx @@ -165,16 +165,13 @@ import sys.FileSystem; private override function __fromManifest (manifest:AssetManifest):Void { - if (manifest.version == 1) { + super.__fromManifest (manifest); + + if (rootPath != "") { for (asset in manifest.assets) { - if (!classTypes.exists (asset.id)) { - - paths.set (asset.id, rootPath + asset.path); - types.set (asset.id, cast (asset.type, AssetType)); - - } + paths.set (asset.id, rootPath + asset.path); }