diff --git a/src/loaders/spritesheetParser.js b/src/loaders/spritesheetParser.js index 8de8b68..c748ba9 100644 --- a/src/loaders/spritesheetParser.js +++ b/src/loaders/spritesheetParser.js @@ -1,13 +1,18 @@ var Resource = require('resource-loader').Resource, path = require('path'), - core = require('../core'); + core = require('../core'), + async = require('async'); + +var BATCH_SIZE = 1000; module.exports = function () { return function (resource, next) { - // skip if no data, its not json, or it isn't spritesheet data - if (!resource.data || !resource.isJson || !resource.data.frames) + var imageResourceName = resource.name + '_image'; + + // skip if no data, its not json, it isn't spritesheet data, or the image resource already exists + if (!resource.data || !resource.isJson || !resource.data.frames || this.resources[imageResourceName]) { return next(); } @@ -20,63 +25,93 @@ var route = path.dirname(resource.url.replace(this.baseUrl, '')); - var resolution = core.utils.getResolutionOfUrl( resource.url ); - // load the image for this sheet - this.add(resource.name + '_image', route + '/' + resource.data.meta.image, loadOptions, function (res) + this.add(imageResourceName, route + '/' + resource.data.meta.image, loadOptions, function (res) { resource.textures = {}; var frames = resource.data.frames; + var frameKeys = Object.keys(frames); + var resolution = core.utils.getResolutionOfUrl(resource.url); + var batchIndex = 0; - for (var i in frames) + function processFrames(initialFrameIndex, maxFrames) { - var rect = frames[i].frame; + var frameIndex = initialFrameIndex; - if (rect) + while (frameIndex - initialFrameIndex < maxFrames && frameIndex < frameKeys.length) { - var size = null; - var trim = null; + var frame = frames[frameKeys[frameIndex]]; + var rect = frame.frame; - if (frames[i].rotated) { - size = new core.Rectangle(rect.x, rect.y, rect.h, rect.w); - } - else { - size = new core.Rectangle(rect.x, rect.y, rect.w, rect.h); - } - - // Check to see if the sprite is trimmed - if (frames[i].trimmed) + if (rect) { - trim = new core.Rectangle( - frames[i].spriteSourceSize.x / resolution, - frames[i].spriteSourceSize.y / resolution, - frames[i].sourceSize.w / resolution, - frames[i].sourceSize.h / resolution - ); + var size = null; + var trim = null; + + if (frame.rotated) + { + size = new core.Rectangle(rect.x, rect.y, rect.h, rect.w); + } + else + { + size = new core.Rectangle(rect.x, rect.y, rect.w, rect.h); + } + + // Check to see if the sprite is trimmed + if (frame.trimmed) + { + trim = new core.Rectangle( + frame.spriteSourceSize.x / resolution, + frame.spriteSourceSize.y / resolution, + frame.sourceSize.w / resolution, + frame.sourceSize.h / resolution + ); + } + + // flip the width and height! + if (frame.rotated) + { + var temp = size.width; + size.width = size.height; + size.height = temp; + } + + size.x /= resolution; + size.y /= resolution; + size.width /= resolution; + size.height /= resolution; + + resource.textures[frameKeys[frameIndex]] = new core.Texture(res.texture.baseTexture, size, size.clone(), trim, frame.rotated); + + // lets also add the frame to pixi's global cache for fromFrame and fromImage functions + core.utils.TextureCache[frameKeys[frameIndex]] = resource.textures[frameKeys[frameIndex]]; } - - // flip the width and height! - if (frames[i].rotated) - { - var temp = size.width; - size.width = size.height; - size.height = temp; - } - - size.x /= resolution; - size.y /= resolution; - size.width /= resolution; - size.height /= resolution; - - resource.textures[i] = new core.Texture(res.texture.baseTexture, size, size.clone(), trim, frames[i].rotated ? 2 : 0); - - // lets also add the frame to pixi's global cache for fromFrame and fromImage functions - core.utils.TextureCache[i] = resource.textures[i]; + frameIndex++; } } - next(); + function shouldProcessNextBatch() + { + return batchIndex * BATCH_SIZE < frameKeys.length; + } + + function processNextBatch(done) + { + processFrames(batchIndex * BATCH_SIZE, BATCH_SIZE); + batchIndex++; + setTimeout(done, 0); + } + + if (frameKeys.length <= BATCH_SIZE) + { + processFrames(0, BATCH_SIZE); + next(); + } + else + { + async.whilst(shouldProcessNextBatch, processNextBatch, next); + } }); }; };