File:SpineAnimTask.js
/**
* @module PIXI Spine
* @namespace springroll.pixi
* @requires Core, PIXI Display, Animation
*/
(function()
{
var Task = include('springroll.Task'),
TextureAtlasTask = include('springroll.pixi.TextureAtlasTask'),
atlasParser = include('PIXI.spine.loaders.atlasParser', false),
SkeletonJsonParser = include('PIXI.spine.SpineRuntime.SkeletonJsonParser', false),
AtlasAttachmentParser = include('PIXI.spine.SpineRuntime.AtlasAttachmentParser', false),
SpineAtlasTask = include('springroll.pixi.SpineAtlasTask', false),
SpineAtlas = include('springroll.pixi.SpineAtlas', false);
if (!atlasParser) return;
/**
* SpineAnimTask loads a spine animation and the texture atlas(es) that it needs.
* @class SpineAnimTask
* @constructor
* @private
* @param {String} asset.spineAnim The Spine skeleton data image path.
* @param {Object} asset.atlas The atlas for the skeleton. This can be a Pixi TextureAtlas
* asset or a Spine specific atlas.
* @param {String} asset.atlas.type Must be "pixi" to ensure that the atlas is loaded for Pixi.
* @param {String} [asset.atlas.atlas] (TextureAtlas) The source data path for a TextureAtlas.
* @param {String} [asset.atlas.image] (TextureAtlas) A image path for a TextureAtlas
* @param {String} [asset.atlas.color] (TextureAtlas) The color image path, if not using image
* property
* @param {String} [asset.atlas.alpha] (TextureAtlas) The alpha image path, if not using image
* property
* @param {String} [asset.atlas.spineAtlas] (Spine Atlas) The source data path for an atlas
* exported from Spine, with a .txt or .atlas
* extension.
* @param {Array} [asset.atlas.images] (Spine Atlas) A set of image paths for the spineAtlas
* data file to pull from.
* @param {Object} [asset.extraImages] A dictionary of extra Texture assets to add to the atlas.
* This should be useful if you have individual images not
* added to a TextureAtlas.
* @param {Boolean} [asset.cache=false] If we should cache the result - caching results in
* caching in the global Pixi texture cache as well as
* Application's asset cache.
* @param {String} [asset.id] The id of the task.
* @param {Function} [asset.complete] The callback to call when the load is completed.
*/
var SpineAnimTask = function(asset)
{
Task.call(this, asset, asset.spineAnim);
/**
* The skeleton data source path
* @property {String} spineAnim
*/
this.spineAnim = this.filter(asset.spineAnim);
/**
* The spine atlas data source path
* @property {String} atlas
*/
this.atlas = asset.atlas;
/**
* Extra images to be added to the atlas
* @property {String} extraImages
*/
this.extraImages = asset.extraImages;
};
// Extend the base Task
var p = Task.extend(SpineAnimTask);
/**
* Test to see if we should load an asset
* @method test
* @static
* @param {Object} asset The asset to test
* @return {Boolean} If this qualifies for this task
*/
SpineAnimTask.test = function(asset)
{
//anim data is required
if (!asset.spineAnim)
return false;
//if atlas exists, make sure it is a valid atlas
if (asset.atlas &&
!(TextureAtlasTask.test(asset.atlas) || SpineAtlasTask.test(asset.atlas)))
return false;
//if atlas does not exist, extraImages is required
if (!asset.atlas)
return !!asset.extraImages;
//if it made it this far, it checks out
return true;
};
/**
* Start the load
* @method start
* @param callback Callback to call when the load is done
*/
p.start = function(callback)
{
var asset = {
_anim: this.spineAnim
};
if (this.atlas)
asset._atlas = this.atlas;
if (this.extraImages)
asset._images = {
assets: this.extraImages
};
this.load(asset, function(results)
{
var spineAtlas = results._atlas;
//if we didn't load an atlas, then should make an atlas because we were probably
//loading individual images
if (!spineAtlas)
spineAtlas = new SpineAtlas();
//if a TextureAtlas was loaded, make a SpineAtlas out of it
if (!(spineAtlas instanceof SpineAtlas))
{
var textureAtlas = spineAtlas;
spineAtlas = new SpineAtlas();
spineAtlas.fromTextureAtlas(textureAtlas);
}
//see if we need to add in any individual images
if (results._images)
{
for (var name in results._images)
{
spineAtlas.addImage(name, results._images[name]);
}
}
// spine animation
var spineJsonParser = new SkeletonJsonParser(new AtlasAttachmentParser(spineAtlas));
var skeletonData = spineJsonParser.readSkeletonData(results._anim);
//store both the atlas and the skeleton data for later cleanup
var asset = {
id: this.id,
spineData: skeletonData,
spineAtlas: spineAtlas
};
//store the skeletonData in the external cache, for standardization
if (atlasParser.enableCaching && this.cache)
atlasParser.AnimCache[this.id] = skeletonData;
//set up a destroy function for cleanly unloading the asset (in particular the atlas)
asset.destroy = function()
{
//remove from external cache
delete atlasParser.AnimCache[this.id];
//destroy atlas
this.spineAtlas.destroy();
//destroy skeleton data - skeleton data is just a bunch of organized arrays
//of spine runtime objects, no display objects or anything
this.spineData = this.spineAtlas = null;
};
//return the asset object
callback(asset, results);
}.bind(this));
};
/**
* Destroy this load task and don't use after this.
* @method destroy
*/
p.destroy = function()
{
Task.prototype.destroy.call(this);
};
// Assign to the namespace
namespace('springroll.pixi').SpineAnimTask = SpineAnimTask;
}());