1 /****************************************************************************
  2  Copyright (c) 2011-2012 cocos2d-x.org
  3  Copyright (c) 2013-2014 Chukong Technologies Inc.
  4 
  5  http://www.cocos2d-x.org
  6 
  7  Permission is hereby granted, free of charge, to any person obtaining a copy
  8  of this software and associated documentation files (the "Software"), to deal
  9  in the Software without restriction, including without limitation the rights
 10  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 11  copies of the Software, and to permit persons to whom the Software is
 12  furnished to do so, subject to the following conditions:
 13 
 14  The above copyright notice and this permission notice shall be included in
 15  all copies or substantial portions of the Software.
 16 
 17  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 18  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 19  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 20  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 21  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 22  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 23  THE SOFTWARE.
 24  ****************************************************************************/
 25 
 26 /**
 27  * @ignore
 28  */
 29 ccs.CONST_VERSION = "version";
 30 ccs.CONST_VERSION_2_0 = 2.0;
 31 ccs.CONST_VERSION_COMBINED = 0.3;
 32 
 33 ccs.CONST_ARMATURES = "armatures";
 34 ccs.CONST_ARMATURE = "armature";
 35 ccs.CONST_BONE = "b";
 36 ccs.CONST_DISPLAY = "d";
 37 
 38 ccs.CONST_ANIMATIONS = "animations";
 39 ccs.CONST_ANIMATION = "animation";
 40 ccs.CONST_MOVEMENT = "mov";
 41 ccs.CONST_FRAME = "f";
 42 
 43 ccs.CONST_TEXTURE_ATLAS = "TextureAtlas";
 44 ccs.CONST_SUB_TEXTURE = "SubTexture";
 45 
 46 ccs.CONST_SKELETON = "skeleton";
 47 
 48 ccs.CONST_A_NAME = "name";
 49 ccs.CONST_A_DURATION = "dr";
 50 ccs.CONST_A_FRAME_INDEX = "fi";
 51 ccs.CONST_A_DURATION_TO = "to";
 52 ccs.CONST_A_DURATION_TWEEN = "drTW";
 53 ccs.CONST_A_LOOP = "lp";
 54 ccs.CONST_A_MOVEMENT_SCALE = "sc";
 55 ccs.CONST_A_MOVEMENT_DELAY = "dl";
 56 ccs.CONST_A_DISPLAY_INDEX = "dI";
 57 
 58 ccs.CONST_A_PLIST = "plist";
 59 
 60 ccs.CONST_A_PARENT = "parent";
 61 ccs.CONST_A_SKEW_X = "kX";
 62 ccs.CONST_A_SKEW_Y = "kY";
 63 ccs.CONST_A_SCALE_X = "cX";
 64 ccs.CONST_A_SCALE_Y = "cY";
 65 ccs.CONST_A_Z = "z";
 66 ccs.CONST_A_EVENT = "evt";
 67 ccs.CONST_A_SOUND = "sd";
 68 ccs.CONST_A_SOUND_EFFECT = "sdE";
 69 ccs.CONST_A_TWEEN_EASING = "twE";
 70 ccs.CONST_A_EASING_PARAM = "twEP";
 71 ccs.CONST_A_TWEEN_ROTATE = "twR";
 72 ccs.CONST_A_IS_ARMATURE = "isArmature";
 73 ccs.CONST_A_DISPLAY_TYPE = "displayType";
 74 ccs.CONST_A_MOVEMENT = "mov";
 75 
 76 ccs.CONST_A_X = "x";
 77 ccs.CONST_A_Y = "y";
 78 
 79 ccs.CONST_A_COCOS2DX_X = "cocos2d_x";
 80 ccs.CONST_A_COCOS2DX_Y = "cocos2d_y";
 81 
 82 ccs.CONST_A_WIDTH = "width";
 83 ccs.CONST_A_HEIGHT = "height";
 84 ccs.CONST_A_PIVOT_X = "pX";
 85 ccs.CONST_A_PIVOT_Y = "pY";
 86 
 87 ccs.CONST_A_COCOS2D_PIVOT_X = "cocos2d_pX";
 88 ccs.CONST_A_COCOS2D_PIVOT_Y = "cocos2d_pY";
 89 
 90 ccs.CONST_A_BLEND_TYPE = "bd";
 91 ccs.CONST_A_BLEND_SRC = "bd_src";
 92 ccs.CONST_A_BLEND_DST = "bd_dst";
 93 
 94 ccs.CONST_A_ALPHA = "a";
 95 ccs.CONST_A_RED = "r";
 96 ccs.CONST_A_GREEN = "g";
 97 ccs.CONST_A_BLUE = "b";
 98 ccs.CONST_A_ALPHA_OFFSET = "aM";
 99 ccs.CONST_A_RED_OFFSET = "rM";
100 ccs.CONST_A_GREEN_OFFSET = "gM";
101 ccs.CONST_A_BLUE_OFFSET = "bM";
102 ccs.CONST_A_COLOR_TRANSFORM = "colorTransform";
103 ccs.CONST_A_TWEEN_FRAME = "tweenFrame";
104 
105 ccs.CONST_CONTOUR = "con";
106 ccs.CONST_CONTOUR_VERTEX = "con_vt";
107 
108 ccs.CONST_FL_NAN = "NaN";
109 
110 ccs.CONST_FRAME_DATA = "frame_data";
111 ccs.CONST_MOVEMENT_BONE_DATA = "mov_bone_data";
112 ccs.CONST_MOVEMENT_DATA = "mov_data";
113 ccs.CONST_ANIMATION_DATA = "animation_data";
114 ccs.CONST_DISPLAY_DATA = "display_data";
115 ccs.CONST_SKIN_DATA = "skin_data";
116 ccs.CONST_BONE_DATA = "bone_data";
117 ccs.CONST_ARMATURE_DATA = "armature_data";
118 ccs.CONST_CONTOUR_DATA = "contour_data";
119 ccs.CONST_TEXTURE_DATA = "texture_data";
120 ccs.CONST_VERTEX_POINT = "vertex";
121 ccs.CONST_COLOR_INFO = "color";
122 
123 ccs.CONST_CONFIG_FILE_PATH = "config_file_path";
124 ccs.CONST_CONTENT_SCALE = "content_scale";
125 
126 /**
127  * @ignore
128  * @constructor
129  */
130 ccs.DataInfo = function () {
131     this.asyncStruct = null;
132     this.configFileQueue = [];
133     this.contentScale = 1;
134     this.filename = "";
135     this.baseFilePath = "";
136     this.flashToolVersion = 0;
137     this.cocoStudioVersion = 0
138 };
139 
140 /**
141  * CocoStudio data reader helper
142  * @namespace
143  * @name ccs.dataReaderHelper
144  */
145 ccs.dataReaderHelper = /** @lends ccs.dataReaderHelper# */{
146     ConfigType: {
147         DragonBone_XML: 0,
148         CocoStudio_JSON: 1,
149         CocoStudio_Binary: 2
150     },
151 
152     _configFileList: [],
153     _flashToolVersion: ccs.CONST_VERSION_2_0,
154 //    _cocoStudioVersion: ccs.CONST_VERSION_COMBINED,
155     _positionReadScale: 1,
156     _asyncRefCount: 0,
157     _asyncRefTotalCount: 0,
158 
159     _dataQueue: null,
160 
161     //LoadData don't need
162 
163     setPositionReadScale: function (scale) {
164         this._positionReadScale = scale;
165     },
166 
167     getPositionReadScale: function () {
168         return this._positionReadScale;
169     },
170 
171     addDataFromFile: function (filePath) {
172         /*
173          * Check if file is already added to ArmatureDataManager, if then return.
174          */
175         if (this._configFileList.indexOf(filePath) != -1)
176             return;
177         this._configFileList.push(filePath);
178 
179         //! find the base file path
180         var basefilePath = this._initBaseFilePath(filePath);
181 
182         // Read content from file
183         // Here the reader into the next process
184 
185         var str = cc.path.extname(filePath).toLowerCase();
186 
187         var dataInfo = new ccs.DataInfo();
188         dataInfo.filename = filePath;
189         dataInfo.basefilePath = basefilePath;
190         if (str == ".xml")
191             ccs.dataReaderHelper.addDataFromXML(filePath, dataInfo);
192         else if (str == ".json" || str == ".exportjson")
193             ccs.dataReaderHelper.addDataFromJson(filePath, dataInfo);
194         else if(str == ".csb")
195             ccs.dataReaderHelper.addDataFromBinaryCache(filePath, dataInfo);
196     },
197 
198     addDataFromFileAsync: function (imagePath, plistPath, filePath, selector, target) {
199         /*
200          * Check if file is already added to ArmatureDataManager, if then return.
201          */
202         if (this._configFileList.indexOf(filePath) != -1) {
203             if (target && selector) {
204                 if (this._asyncRefTotalCount == 0 && this._asyncRefCount == 0)
205                     this._asyncCallBack(selector,target, 1);
206                 else
207                     this._asyncCallBack(selector, target, (this._asyncRefTotalCount - this._asyncRefCount) / this._asyncRefTotalCount);
208             }
209             return;
210         }
211 //        this._configFileList.push(filePath);
212 
213         //! find the base file path
214 //        var basefilePath = this._initBaseFilePath(filePath);
215 
216         this._asyncRefTotalCount++;
217         this._asyncRefCount++;
218         var self = this;
219         var fun = function () {
220             self.addDataFromFile(filePath);
221             self._asyncRefCount--;
222             self._asyncCallBack(selector,target, (self._asyncRefTotalCount - self._asyncRefCount) / self._asyncRefTotalCount);
223         };
224         cc.director.getScheduler().scheduleCallbackForTarget(this, fun, 0.1, false);
225     },
226 
227     removeConfigFile: function (configFile) {
228 //        cc.arrayRemoveObject(this._configFileList, configFile);
229         var locFileList = this._configFileList;
230         var len = locFileList.length;
231         var it = locFileList[len];
232         for (var i = 0;i<len; i++){
233             if (locFileList[i] == configFile)
234                 it = i;
235         }
236 
237         if (it != locFileList[len])
238             cc.arrayRemoveObject(locFileList, configFile);
239     },
240 
241     addDataFromCache: function (skeleton, dataInfo) {
242         if (!skeleton) {
243             cc.log("XML error  or  XML is empty.");
244             return;
245         }
246         dataInfo.flashToolVersion = parseFloat(skeleton.getAttribute(ccs.CONST_VERSION));
247 
248         /*
249          * Begin decode armature data from xml
250          */
251         var armaturesXML = skeleton.querySelectorAll(ccs.CONST_SKELETON + " > " + ccs.CONST_ARMATURES + " >  " + ccs.CONST_ARMATURE + "");
252         var armatureDataManager = ccs.armatureDataManager, i;
253         for (i = 0; i < armaturesXML.length; i++) {
254             var armatureData = this.decodeArmature(armaturesXML[i], dataInfo);
255             armatureDataManager.addArmatureData(armatureData.name, armatureData, dataInfo.filename);
256         }
257 
258         /*
259          * Begin decode animation data from xml
260          */
261         var animationsXML = skeleton.querySelectorAll(ccs.CONST_SKELETON + " > " + ccs.CONST_ANIMATIONS + " >  " + ccs.CONST_ANIMATION + "");
262         for (i = 0; i < animationsXML.length; i++) {
263             var animationData = this.decodeAnimation(animationsXML[i], dataInfo);
264             armatureDataManager.addAnimationData(animationData.name, animationData, dataInfo.filename);
265         }
266 
267         var texturesXML = skeleton.querySelectorAll(ccs.CONST_SKELETON + " > " + ccs.CONST_TEXTURE_ATLAS + " >  " + ccs.CONST_SUB_TEXTURE + "");
268         for (i = 0; i < texturesXML.length; i++) {
269             var textureData = this.decodeTexture(texturesXML[i], dataInfo);
270             armatureDataManager.addTextureData(textureData.name, textureData, dataInfo.filename);
271         }
272     },
273 
274     decodeArmature: function (armatureXML, dataInfo) {
275         var armatureData = new ccs.ArmatureData();
276         armatureData.init();
277         armatureData.name = armatureXML.getAttribute(ccs.CONST_A_NAME);
278 
279         var bonesXML = armatureXML.querySelectorAll(ccs.CONST_ARMATURE + " > " + ccs.CONST_BONE);
280 
281         for (var i = 0; i < bonesXML.length; i++) {
282             /*
283              *  If this bone have parent, then get the parent bone xml
284              */
285             var boneXML = bonesXML[i];
286             var parentName = boneXML.getAttribute(ccs.CONST_A_PARENT);
287             var parentXML = null;
288             if (parentName) {
289                 //parentXML = armatureXML.querySelectorAll(ccs.CONST_ARMATURE+" > "+ccs.CONST_BONE);
290                 for (var j = 0; j < bonesXML.length; j++) {
291                     parentXML = bonesXML[j];
292                     if (parentName == bonesXML[j].getAttribute(ccs.CONST_A_NAME)) {
293                         //todo
294                         break;
295                     }
296                 }
297             }
298             var boneData = this.decodeBone(boneXML, parentXML, dataInfo);
299             armatureData.addBoneData(boneData);
300         }
301         return armatureData;
302     },
303 
304     decodeArmatureFromJSON: function (json, dataInfo) {
305         var armatureData = new ccs.ArmatureData();
306         armatureData.init();
307 
308         var name = json[ccs.CONST_A_NAME];
309         if (name) {
310             armatureData.name = name;
311         }
312 
313         dataInfo.cocoStudioVersion = armatureData.dataVersion = json[ccs.CONST_VERSION] || 0.1;
314 
315         var boneDataList = json[ccs.CONST_BONE_DATA];
316         for (var i = 0; i < boneDataList.length; i++) {
317             var boneData = this.decodeBoneFromJson(boneDataList[i], dataInfo);
318             armatureData.addBoneData(boneData);
319         }
320         return armatureData;
321     },
322 
323     decodeBone: function (boneXML, parentXML, dataInfo) {
324         var boneData = new ccs.BoneData();
325         boneData.init();
326 
327         boneData.name = boneXML.getAttribute(ccs.CONST_A_NAME);
328         boneData.parentName = boneXML.getAttribute(ccs.CONST_A_PARENT) || "";
329 
330         boneData.zOrder = parseInt(boneXML.getAttribute(ccs.CONST_A_Z)) || 0;
331 
332         var displaysXML = boneXML.querySelectorAll(ccs.CONST_BONE + " > " + ccs.CONST_DISPLAY);
333         for (var i = 0; i < displaysXML.length; i++) {
334             var displayXML = displaysXML[i];
335             var displayData = this.decodeBoneDisplay(displayXML, dataInfo);
336             boneData.addDisplayData(displayData);
337         }
338         return boneData;
339     },
340 
341     decodeBoneFromJson: function (json, dataInfo) {
342         var boneData = new ccs.BoneData();
343         boneData.init();
344 
345         this.decodeNodeFromJson(boneData, json, dataInfo);
346 
347         boneData.name = json[ccs.CONST_A_NAME] || "";
348 
349         boneData.parentName = json[ccs.CONST_A_PARENT] || "";
350         var displayDataList = json[ccs.CONST_DISPLAY_DATA] || [];
351         for (var i = 0; i < displayDataList.length; i++) {
352             var locDisplayData = this.decodeBoneDisplayFromJson(displayDataList[i], dataInfo);
353             boneData.addDisplayData(locDisplayData);
354         }
355         return boneData;
356     },
357 
358     decodeBoneDisplay: function (displayXML, dataInfo) {
359         var isArmature = parseFloat(displayXML.getAttribute(ccs.CONST_A_IS_ARMATURE)) || 0;
360         var displayData = null;
361 
362         if (isArmature == 1) {
363             displayData = new ccs.ArmatureDisplayData();
364             displayData.displayType = ccs.DISPLAY_TYPE_ARMATURE;
365         } else {
366             displayData = new ccs.SpriteDisplayData();
367             displayData.displayType = ccs.DISPLAY_TYPE_SPRITE;
368         }
369 
370         var displayName = displayXML.getAttribute(ccs.CONST_A_NAME) || "";
371         if (displayName) {
372             displayData.displayName = displayName;
373         }
374         return displayData;
375     },
376 
377     decodeBoneDisplayFromJson: function (json, dataInfo) {
378         var displayType = json[ccs.CONST_A_DISPLAY_TYPE] || ccs.DISPLAY_TYPE_SPRITE;
379         var displayData = null;
380 
381         switch (displayType) {
382             case ccs.DISPLAY_TYPE_SPRITE:
383                 displayData = new ccs.SpriteDisplayData();
384 
385                 var name = json[ccs.CONST_A_NAME];
386                 if(name != null){
387                     displayData.displayName =  name;
388                 }
389 
390                 var dicArray = json[ccs.CONST_SKIN_DATA] || [];
391                 var dic = dicArray[0];
392                 if (dic) {
393                     var skinData = displayData.skinData;
394                     skinData.x = dic[ccs.CONST_A_X] * this._positionReadScale;
395                     skinData.y = dic[ccs.CONST_A_Y] * this._positionReadScale;
396                     skinData.scaleX = dic[ccs.CONST_A_SCALE_X] == null ? 1 : dic[ccs.CONST_A_SCALE_X];
397                     skinData.scaleY = dic[ccs.CONST_A_SCALE_Y] == null ? 1 : dic[ccs.CONST_A_SCALE_Y];
398                     skinData.skewX = dic[ccs.CONST_A_SKEW_X] == null ? 1 : dic[ccs.CONST_A_SKEW_X];
399                     skinData.skewY = dic[ccs.CONST_A_SKEW_Y] == null ? 1 : dic[ccs.CONST_A_SKEW_Y];
400 
401                     skinData.x *= dataInfo.contentScale;
402                     skinData.y *= dataInfo.contentScale;
403                 }
404                 break;
405             case ccs.DISPLAY_TYPE_ARMATURE:
406                 displayData = new ccs.ArmatureDisplayData();
407                 var name = json[ccs.CONST_A_NAME];
408                 if(name != null){
409                     displayData.displayName = json[ccs.CONST_A_NAME];
410                 }
411                 break;
412             case ccs.DISPLAY_TYPE_PARTICLE:
413                 displayData = new ccs.ParticleDisplayData();
414                 var plist = json[ccs.CONST_A_PLIST];
415                 if(plist != null){
416                     if(dataInfo.asyncStruct){
417                         displayData.displayName = dataInfo.asyncStruct.basefilePath + plist;
418                     }else{
419                         displayData.displayName = dataInfo.basefilePath + plist;
420                     }
421                 }
422                 break;
423             default:
424                 displayData = new ccs.SpriteDisplayData();
425                 break;
426         }
427         displayData.displayType = displayType;
428         return displayData;
429     },
430 
431     decodeAnimation: function (animationXML, dataInfo) {
432         var aniData = new ccs.AnimationData();
433         var name = animationXML.getAttribute(ccs.CONST_A_NAME);
434         var armatureData = ccs.armatureDataManager.getArmatureData(name);
435         aniData.name = name;
436 
437         var movementsXML = animationXML.querySelectorAll(ccs.CONST_ANIMATION + " > " + ccs.CONST_MOVEMENT);
438         var movementXML = null;
439 
440         for (var i = 0; i < movementsXML.length; i++) {
441             movementXML = movementsXML[i];
442             var movementData = this.decodeMovement(movementXML, armatureData, dataInfo);
443             aniData.addMovement(movementData);
444         }
445         return aniData;
446     },
447 
448     decodeAnimationFromJson: function (json, dataInfo) {
449         var aniData = new ccs.AnimationData();
450         var name = json[ccs.CONST_A_NAME];
451         if(name){
452             aniData.name = json[ccs.CONST_A_NAME];
453         }
454 
455         var movementDataList = json[ccs.CONST_MOVEMENT_DATA] || [];
456         for (var i = 0; i < movementDataList.length; i++) {
457             var locMovementData = this.decodeMovementFromJson(movementDataList[i], dataInfo);
458             aniData.addMovement(locMovementData);
459         }
460         return aniData;
461     },
462 
463     decodeMovement: function (movementXML, armatureData, dataInfo) {
464         var movementData = new ccs.MovementData();
465         movementData.name = movementXML.getAttribute(ccs.CONST_A_NAME);
466 
467         var duration, durationTo, durationTween, loop, tweenEasing = 0;
468 
469         duration = movementXML.getAttribute(ccs.CONST_A_DURATION);
470         movementData.duration = duration == null ? 0 : parseFloat(duration);
471 
472         durationTo = movementXML.getAttribute(ccs.CONST_A_DURATION_TO);
473         movementData.durationTo = durationTo == null ? 0 : parseFloat(durationTo);
474 
475         durationTween = movementXML.getAttribute(ccs.CONST_A_DURATION_TWEEN);
476         movementData.durationTween = durationTween == null ? 0 : parseFloat(durationTween);
477 
478         loop = movementXML.getAttribute(ccs.CONST_A_LOOP);
479         movementData.loop = loop ? Boolean(parseFloat(loop)) : true;
480 
481         var easing = movementXML.getAttribute(ccs.CONST_A_TWEEN_EASING);
482         if (easing) {
483             if (easing != ccs.CONST_FL_NAN) {
484                 tweenEasing = easing == null ? 0 : parseFloat(easing);
485                 movementData.tweenEasing = tweenEasing == 2 ? ccs.TweenType.sineEaseInOut : tweenEasing;
486             } else
487                 movementData.tweenEasing = ccs.TweenType.linear;
488         }
489 
490         var movBonesXml = movementXML.querySelectorAll(ccs.CONST_MOVEMENT + " > " + ccs.CONST_BONE);
491         var movBoneXml = null;
492         for (var i = 0; i < movBonesXml.length; i++) {
493             movBoneXml = movBonesXml[i];
494             var boneName = movBoneXml.getAttribute(ccs.CONST_A_NAME);
495 
496             if (movementData.getMovementBoneData(boneName))
497                 continue;
498 
499             var boneData = armatureData.getBoneData(boneName);
500             var parentName = boneData.parentName;
501 
502             var parentXML = null;
503             if (parentName != "") {
504                 for (var j = 0; j < movBonesXml.length; j++) {
505                     parentXML = movBonesXml[j];
506                     if (parentName == parentXML.getAttribute(ccs.CONST_A_NAME))
507                         break;
508                 }
509             }
510             var moveBoneData = this.decodeMovementBone(movBoneXml, parentXML, boneData, dataInfo);
511             movementData.addMovementBoneData(moveBoneData);
512         }
513         return movementData;
514     },
515 
516     decodeMovementFromJson: function (json, dataInfo) {
517         var movementData = new ccs.MovementData();
518 
519         movementData.loop = json[ccs.CONST_A_LOOP] == null ? false : json[ccs.CONST_A_LOOP];
520         movementData.durationTween = json[ccs.CONST_A_DURATION_TWEEN] || 0;
521         movementData.durationTo = json[ccs.CONST_A_DURATION_TO] || 0;
522         movementData.duration = json[ccs.CONST_A_DURATION] || 0;
523 
524         if(json[ccs.CONST_A_DURATION] == null){
525             movementData.scale = 1;
526         }else{
527             movementData.scale = json[ccs.CONST_A_MOVEMENT_SCALE] == null ? 1 : json[ccs.CONST_A_MOVEMENT_SCALE];
528         }
529 
530         movementData.tweenEasing = json[ccs.CONST_A_TWEEN_EASING] == null ? ccs.TweenType.linear : json[ccs.CONST_A_TWEEN_EASING];
531         var name = json[ccs.CONST_A_NAME];
532         if(name)
533             movementData.name = name;
534 
535         var movementBoneList = json[ccs.CONST_MOVEMENT_BONE_DATA] || [];
536         for (var i = 0; i < movementBoneList.length; i++) {
537             var locMovementBoneData = this.decodeMovementBoneFromJson(movementBoneList[i], dataInfo);
538             movementData.addMovementBoneData(locMovementBoneData);
539         }
540         return movementData;
541     },
542 
543     decodeMovementBone: function (movBoneXml, parentXml, boneData, dataInfo) {
544         var movBoneData = new ccs.MovementBoneData();
545         movBoneData.init();
546 
547         var scale, delay;
548         if (movBoneXml) {
549             scale = parseFloat(movBoneXml.getAttribute(ccs.CONST_A_MOVEMENT_SCALE)) || 0;
550             movBoneData.scale = scale;
551 
552             delay = parseFloat(movBoneXml.getAttribute(ccs.CONST_A_MOVEMENT_DELAY)) || 0;
553             if (delay > 0)
554                 delay -= 1;
555             movBoneData.delay = delay;
556         }
557 
558         var length = 0, parentTotalDuration = 0,currentDuration = 0;
559         var parentFrameXML = null,parentXMLList = [];
560 
561         /*
562          *  get the parent frame xml list, we need get the origin data
563          */
564         if (parentXml != null) {
565             var parentFramesXML = parentXml.querySelectorAll(ccs.CONST_BONE + " > " + ccs.CONST_FRAME);
566             for (var i = 0; i < parentFramesXML.length; i++)
567                 parentXMLList.push(parentFramesXML[i]);
568             length = parentXMLList.length;
569         }
570 
571         movBoneData.name = movBoneXml.getAttribute(ccs.CONST_A_NAME);
572 
573         var framesXML = movBoneXml.querySelectorAll(ccs.CONST_BONE + " > " + ccs.CONST_FRAME);
574 
575         var j = 0, totalDuration = 0;
576         for (var ii = 0; ii < framesXML.length; ii++) {
577             var frameXML = framesXML[ii];
578             if (parentXml) {
579                 /*
580                  *  in this loop we get the corresponding parent frame xml
581                  */
582                 while (j < length && (parentFrameXML ? (totalDuration < parentTotalDuration || totalDuration >= parentTotalDuration + currentDuration) : true)) {
583                     parentFrameXML = parentXMLList[j];
584                     parentTotalDuration += currentDuration;
585                     currentDuration = parseFloat(parentFrameXML.getAttribute(ccs.CONST_A_DURATION));
586                     j++;
587                 }
588             }
589             var boneFrameData = this.decodeFrame(frameXML, parentFrameXML, boneData, dataInfo);
590             movBoneData.addFrameData(boneFrameData);
591             boneFrameData.frameID = totalDuration;
592             totalDuration += boneFrameData.duration;
593             movBoneData.duration = totalDuration;
594         }
595 
596         //Change rotation range from (-180 -- 180) to (-infinity -- infinity)
597         var frames = movBoneData.frameList, pi = Math.PI;
598         for (var i = frames.length - 1; i >= 0; i--) {
599             if (i > 0) {
600                 var difSkewX = frames[i].skewX - frames[i - 1].skewX;
601                 var difSkewY = frames[i].skewY - frames[i - 1].skewY;
602 
603                 if (difSkewX < -pi || difSkewX > pi) {
604                     frames[i - 1].skewX = difSkewX < 0 ? frames[i - 1].skewX - 2 * pi : frames[i - 1].skewX + 2 * pi;
605                 }
606 
607                 if (difSkewY < -pi || difSkewY > pi) {
608                     frames[i - 1].skewY = difSkewY < 0 ? frames[i - 1].skewY - 2 * pi : frames[i - 1].skewY + 2 * pi;
609                 }
610             }
611         }
612 
613         var frameData = new ccs.FrameData();
614         frameData.copy(movBoneData.frameList[movBoneData.frameList.length - 1]);
615         frameData.frameID = movBoneData.duration;
616         movBoneData.addFrameData(frameData);
617         return movBoneData;
618     },
619 
620     decodeMovementBoneFromJson: function (json, dataInfo) {
621         var movementBoneData = new ccs.MovementBoneData();
622         movementBoneData.init();
623         movementBoneData.delay = json[ccs.CONST_A_MOVEMENT_DELAY] || 0;
624 
625         var name = json[ccs.CONST_A_NAME];
626         if(name)
627             movementBoneData.name = name;
628 
629         var framesData = json[ccs.CONST_FRAME_DATA] || [];
630         var length = framesData.length;
631         for (var i = 0; i < length; i++) {
632             var dic = json[ccs.CONST_FRAME_DATA][i];
633             var frameData = this.decodeFrameFromJson(dic, dataInfo);
634             movementBoneData.addFrameData(frameData);
635 
636             if (dataInfo.cocoStudioVersion < ccs.CONST_VERSION_COMBINED){
637                 frameData.frameID = movementBoneData.duration;
638                 movementBoneData.duration += frameData.duration;
639             }
640         }
641 
642         if (dataInfo.cocoStudioVersion < ccs.VERSION_CHANGE_ROTATION_RANGE) {
643             //! Change rotation range from (-180 -- 180) to (-infinity -- infinity)
644             var frames = movementBoneData.frameList;
645             var pi = Math.PI;
646             for (var i = frames.length - 1; i >= 0; i--) {
647                 if (i > 0) {
648                     var difSkewX = frames[i].skewX - frames[i - 1].skewX;
649                     var difSkewY = frames[i].skewY - frames[i - 1].skewY;
650 
651                     if (difSkewX < -pi || difSkewX > pi) {
652                         frames[i - 1].skewX = difSkewX < 0 ? frames[i - 1].skewX - 2 * pi : frames[i - 1].skewX + 2 * pi;
653                     }
654 
655                     if (difSkewY < -pi || difSkewY > pi) {
656                         frames[i - 1].skewY = difSkewY < 0 ? frames[i - 1].skewY - 2 * pi : frames[i - 1].skewY + 2 * pi;
657                     }
658                 }
659             }
660         }
661 
662         if (dataInfo.cocoStudioVersion < ccs.CONST_VERSION_COMBINED) {
663             if (movementBoneData.frameList.length > 0) {
664                 var frameData = new ccs.FrameData();
665                 frameData.copy(movementBoneData.frameList[movementBoneData.frameList.length - 1]);
666                 movementBoneData.addFrameData(frameData);
667                 frameData.frameID = movementBoneData.duration;
668             }
669         }
670         return movementBoneData;
671     },
672 
673     decodeFrame: function (frameXML, parentFrameXml, boneData, dataInfo) {
674         var x = 0, y = 0, scale_x = 0, scale_y = 0, skew_x = 0, skew_y = 0, tweenRotate = 0;
675         var duration = 0, displayIndex = 0, zOrder = 0, tweenEasing = 0, blendType = 0;
676 
677         var frameData = new ccs.FrameData();
678         frameData.strMovement = frameXML.getAttribute(ccs.CONST_A_MOVEMENT) || "";
679         frameData.movement = frameData.strMovement;
680         frameData.strEvent = frameXML.getAttribute(ccs.CONST_A_EVENT) || "";
681         frameData.event = frameData.strEvent;
682         frameData.strSound = frameXML.getAttribute(ccs.CONST_A_SOUND) || "";
683         frameData.sound = frameData.strSound;
684         frameData.strSoundEffect = frameXML.getAttribute(ccs.CONST_A_SOUND_EFFECT) || "";
685         frameData.soundEffect = frameData.strSoundEffect;
686 
687         var isTween = frameXML.getAttribute(ccs.CONST_A_TWEEN_FRAME);
688         frameData.isTween = isTween == undefined?true: Boolean(isTween);
689 
690         if (dataInfo.flashToolVersion >= ccs.CONST_VERSION_2_0) {
691             x = frameXML.getAttribute(ccs.CONST_A_COCOS2DX_X);
692             if(x){
693                 frameData.x = parseFloat(x);
694                 frameData.x *= this._positionReadScale;
695             }
696             y = frameXML.getAttribute(ccs.CONST_A_COCOS2DX_Y);
697             if(y){
698                 frameData.y = -parseFloat(y);
699                 frameData.y *= this._positionReadScale;
700             }
701         } else {
702             x = frameXML.getAttribute(ccs.CONST_A_X);
703             if(x) {
704                 frameData.x = parseFloat(x);
705                 frameData.x *= this._positionReadScale;
706             }
707             y = frameXML.getAttribute(ccs.CONST_A_Y);
708             if(y) {
709                 frameData.y = -parseFloat(y);
710                 frameData.y *= this._positionReadScale;
711             }
712         }
713 
714         scale_x = frameXML.getAttribute(ccs.CONST_A_SCALE_X);
715         if( scale_x != null )
716             frameData.scaleX = parseFloat(scale_x);
717         scale_y = frameXML.getAttribute(ccs.CONST_A_SCALE_Y);
718         if( scale_y != null )
719             frameData.scaleY = parseFloat(scale_y);
720         skew_x = frameXML.getAttribute(ccs.CONST_A_SKEW_X);
721         if( skew_x != null )
722             frameData.skewX = cc.degreesToRadians(parseFloat(skew_x));
723         skew_y = frameXML.getAttribute(ccs.CONST_A_SKEW_Y);
724         if( skew_y != null )
725             frameData.skewY = cc.degreesToRadians(-parseFloat(skew_y));
726 
727         duration = frameXML.getAttribute(ccs.CONST_A_DURATION);
728         if( duration != null )
729             frameData.duration = parseFloat(duration);
730         displayIndex = frameXML.getAttribute(ccs.CONST_A_DISPLAY_INDEX);
731         if( displayIndex != null )
732             frameData.displayIndex = parseFloat(displayIndex);
733         zOrder = frameXML.getAttribute(ccs.CONST_A_Z);
734         if( zOrder != null )
735             frameData.zOrder = parseInt(zOrder);
736         tweenRotate = frameXML.getAttribute(ccs.CONST_A_TWEEN_ROTATE);
737         if( tweenRotate != null )
738             frameData.tweenRotate = parseFloat(tweenRotate);
739 
740         blendType = frameXML.getAttribute(ccs.CONST_A_BLEND_TYPE);
741         if ( blendType != null ) {
742             var blendFunc = frameData.blendFunc;
743             switch (blendType) {
744                 case ccs.BLEND_TYPE_NORMAL:
745                     blendFunc.src = cc.BLEND_SRC;
746                     blendFunc.dst = cc.BLEND_DST;
747                     break;
748                 case ccs.BLEND_TYPE_ADD:
749                     blendFunc.src = cc.SRC_ALPHA;
750                     blendFunc.dst = cc.ONE;
751                     break;
752                 case ccs.BLEND_TYPE_MULTIPLY:
753                     blendFunc.src = cc.DST_COLOR;
754                     blendFunc.dst = cc.ONE_MINUS_SRC_ALPHA;
755                     break;
756                 case ccs.BLEND_TYPE_SCREEN:
757                     blendFunc.src = cc.ONE;
758                     blendFunc.dst = cc.ONE_MINUS_DST_COLOR;
759                     break;
760                 default:
761                     frameData.blendFunc.src = cc.BLEND_SRC;
762                     frameData.blendFunc.dst = cc.BLEND_DST;
763                     break;
764             }
765         }
766 
767         var colorTransformXML = frameXML.querySelectorAll(ccs.CONST_FRAME + " > " + ccs.CONST_A_COLOR_TRANSFORM);
768         if (colorTransformXML && colorTransformXML.length > 0) {
769             colorTransformXML = colorTransformXML[0];
770             var alpha, red, green, blue;
771             var alphaOffset, redOffset, greenOffset, blueOffset;
772 
773             alpha = colorTransformXML.getAttribute(ccs.CONST_A_ALPHA) || 0;
774             red = colorTransformXML.getAttribute(ccs.CONST_A_RED) || 0;
775             green = colorTransformXML.getAttribute(ccs.CONST_A_GREEN) || 0;
776             blue = colorTransformXML.getAttribute(ccs.CONST_A_BLUE) || 0;
777 
778             alphaOffset = colorTransformXML.getAttribute(ccs.CONST_A_ALPHA_OFFSET) || 0;
779             redOffset = colorTransformXML.getAttribute(ccs.CONST_A_RED_OFFSET) || 0;
780             greenOffset = colorTransformXML.getAttribute(ccs.CONST_A_GREEN_OFFSET) || 0;
781             blueOffset = colorTransformXML.getAttribute(ccs.CONST_A_BLUE_OFFSET) || 0;
782 
783             frameData.a = 2.55 * alphaOffset + alpha;
784             frameData.r = 2.55 * redOffset + red;
785             frameData.g = 2.55 * greenOffset + green;
786             frameData.b = 2.55 * blueOffset + blue;
787 
788             frameData.isUseColorInfo = true;
789         }
790 
791         var _easing = frameXML.getAttribute(ccs.CONST_A_TWEEN_EASING);
792         if(_easing != null) {
793             if(_easing != ccs.CONST_FL_NAN){
794                 tweenEasing = frameXML.getAttribute(ccs.CONST_A_TWEEN_EASING);
795                 if( tweenEasing )
796                     frameData.tweenEasing = (tweenEasing == 2) ? ccs.TweenType.sineEaseInOut : tweenEasing;
797             } else
798                 frameData.tweenEasing = ccs.TweenType.linear;
799         }
800 
801         if (parentFrameXml) {
802             //*  recalculate frame data from parent frame data, use for translate matrix
803             var helpNode = new ccs.BaseData();
804             if (dataInfo.flashToolVersion >= ccs.CONST_VERSION_2_0) {
805                 helpNode.x = parseFloat(parentFrameXml.getAttribute(ccs.CONST_A_COCOS2DX_X));
806                 helpNode.y = parseFloat(parentFrameXml.getAttribute(ccs.CONST_A_COCOS2DX_Y));
807             } else {
808                 helpNode.x = parseFloat(parentFrameXml.getAttribute(ccs.CONST_A_X));
809                 helpNode.y = parseFloat(parentFrameXml.getAttribute(ccs.CONST_A_Y));
810             }
811             helpNode.skewX = parseFloat(parentFrameXml.getAttribute(ccs.CONST_A_SKEW_X));
812             helpNode.skewY = parseFloat(parentFrameXml.getAttribute(ccs.CONST_A_SKEW_Y));
813 
814             helpNode.y = -helpNode.y;
815             helpNode.skewX = cc.degreesToRadians(helpNode.skewX);
816             helpNode.skewY = cc.degreesToRadians(-helpNode.skewY);
817             ccs.TransformHelp.transformFromParent(frameData, helpNode);
818         }
819         return frameData;
820     },
821 
822     decodeFrameFromJson: function (json, dataInfo) {
823         var frameData = new ccs.FrameData();
824 
825         this.decodeNodeFromJson(frameData, json, dataInfo);
826 
827         frameData.tweenEasing = json[ccs.CONST_A_TWEEN_EASING] || ccs.TweenType.linear;
828         frameData.displayIndex = json[ccs.CONST_A_DISPLAY_INDEX];
829         var bd_src = json[ccs.CONST_A_BLEND_SRC] == null ? cc.BLEND_SRC : json[ccs.CONST_A_BLEND_SRC];
830         var bd_dst = json[ccs.CONST_A_BLEND_DST] == null ? cc.BLEND_DST : json[ccs.CONST_A_BLEND_DST];
831         frameData.blendFunc.src = bd_src;
832         frameData.blendFunc.dst = bd_dst;
833         frameData.isTween = json[ccs.CONST_A_TWEEN_FRAME] == null ? true : json[ccs.CONST_A_TWEEN_FRAME];
834 
835         var event = json[ccs.CONST_A_EVENT];
836         if(event != null){
837             frameData.strEvent = event;
838             frameData.event = event;
839         }
840 
841         if (dataInfo.cocoStudioVersion < ccs.CONST_VERSION_COMBINED)
842             frameData.duration = json[ccs.CONST_A_DURATION] == null ? 1 : json[ccs.CONST_A_DURATION];
843         else
844             frameData.frameID = json[ccs.CONST_A_FRAME_INDEX];
845 
846         var twEPs = json[ccs.CONST_A_EASING_PARAM] || [];
847         for (var i = 0; i < twEPs.length; i++) {
848             frameData.easingParams[i] = twEPs[i];
849         }
850 
851         return frameData;
852     },
853 
854     decodeTexture: function (textureXML, dataInfo) {
855         var textureData = new ccs.TextureData();
856         textureData.init();
857 
858         if (textureXML.getAttribute(ccs.CONST_A_NAME)) {
859             textureData.name = textureXML.getAttribute(ccs.CONST_A_NAME);
860         }
861 
862         var px, py;
863 
864         if (dataInfo.flashToolVersion >= ccs.CONST_VERSION_2_0) {
865             px = parseFloat(textureXML.getAttribute(ccs.CONST_A_COCOS2D_PIVOT_X)) || 0;
866             py = parseFloat(textureXML.getAttribute(ccs.CONST_A_COCOS2D_PIVOT_Y)) || 0;
867         } else {
868             px = parseFloat(textureXML.getAttribute(ccs.CONST_A_PIVOT_X)) || 0;
869             py = parseFloat(textureXML.getAttribute(ccs.CONST_A_PIVOT_Y)) || 0;
870         }
871 
872         var width = parseFloat(textureXML.getAttribute(ccs.CONST_A_WIDTH)) || 0;
873         var height = parseFloat(textureXML.getAttribute(ccs.CONST_A_HEIGHT)) || 0;
874 
875         var anchorPointX = px / width;
876         var anchorPointY = (height - py) / height;
877 
878         textureData.pivotX = anchorPointX;
879         textureData.pivotY = anchorPointY;
880 
881         var contoursXML = textureXML.querySelectorAll(ccs.CONST_SUB_TEXTURE + " > " + ccs.CONST_CONTOUR);
882         for (var i = 0; i < contoursXML.length; i++) {
883             textureData.addContourData(this.decodeContour(contoursXML[i], dataInfo));
884         }
885         return textureData;
886     },
887 
888     decodeTextureFromJson: function (json) {
889         var textureData = new ccs.TextureData();
890         textureData.init();
891 
892         var name = json[ccs.CONST_A_NAME];
893         if(name != null)
894             textureData.name = name;
895 
896         textureData.width = json[ccs.CONST_A_WIDTH] || 0;
897         textureData.height = json[ccs.CONST_A_HEIGHT] || 0;
898         textureData.pivotX = json[ccs.CONST_A_PIVOT_X] || 0;
899         textureData.pivotY = json[ccs.CONST_A_PIVOT_Y] || 0;
900 
901         var contourDataList = json[ccs.CONST_CONTOUR_DATA] || [];
902         for (var i = 0; i < contourDataList.length; i++) {
903             textureData.contourDataList.push(this.decodeContourFromJson(contourDataList[i]));
904         }
905         return textureData;
906     },
907 
908     decodeContour: function (contourXML, dataInfo) {
909         var contourData = new ccs.ContourData();
910         contourData.init();
911 
912         var vertexDatasXML = contourXML.querySelectorAll(ccs.CONST_CONTOUR + " > " + ccs.CONST_CONTOUR_VERTEX);
913         var vertexDataXML;
914         for (var i = 0; i < vertexDatasXML.length; i++) {
915             vertexDataXML = vertexDatasXML[i];
916             var vertex = cc.p(0, 0);
917             vertex.x = parseFloat(vertexDataXML.getAttribute(ccs.CONST_A_X)) || 0;
918             vertex.y = parseFloat(vertexDataXML.getAttribute(ccs.CONST_A_Y)) || 0;
919 
920             vertex.y = - vertex.y;
921             contourData.vertexList.push(vertex);
922         }
923         return contourData;
924 
925     },
926 
927     decodeContourFromJson: function (json) {
928         var contourData = new ccs.ContourData();
929         contourData.init();
930 
931         var vertexPointList = json[ccs.CONST_VERTEX_POINT] || [];
932         var len = vertexPointList.length;
933         for (var i = 0; i < len; i++) {
934             var dic = vertexPointList[i];
935             var vertex = cc.p(0, 0);
936             vertex.x = dic[ccs.CONST_A_X] || 0;
937             vertex.y = dic[ccs.CONST_A_Y] || 0;
938             contourData.vertexList.push(vertex);
939         }
940         return contourData;
941     },
942 
943     addDataFromJsonCache: function (dic, dataInfo) {
944         dataInfo.contentScale = dic[ccs.CONST_CONTENT_SCALE] == null ? 1 : dic[ccs.CONST_CONTENT_SCALE];
945 
946         // Decode armatures
947         var armatureDataArr = dic[ccs.CONST_ARMATURE_DATA] || [], i;
948         var armatureData;
949         for (i = 0; i < armatureDataArr.length; i++) {
950             armatureData = this.decodeArmatureFromJSON(armatureDataArr[i], dataInfo);
951             ccs.armatureDataManager.addArmatureData(armatureData.name, armatureData, dataInfo.filename);
952         }
953 
954         // Decode animations
955         var animationDataArr = dic[ccs.CONST_ANIMATION_DATA] || [];
956         var animationData;
957         for (i = 0; i < animationDataArr.length; i++) {
958             animationData = this.decodeAnimationFromJson(animationDataArr[i], dataInfo);
959             ccs.armatureDataManager.addAnimationData(animationData.name, animationData, dataInfo.filename);
960         }
961 
962         // Decode textures
963         var textureDataArr = dic[ccs.CONST_TEXTURE_DATA] || [];
964         var textureData;
965         for (i = 0; i < textureDataArr.length; i++) {
966             textureData = this.decodeTextureFromJson(textureDataArr[i], dataInfo);
967             ccs.armatureDataManager.addTextureData(textureData.name, textureData, dataInfo.filename);
968         }
969 
970         // Auto load sprite file
971         var autoLoad = dataInfo.asyncStruct == null ? ccs.armatureDataManager.isAutoLoadSpriteFile() : dataInfo.asyncStruct.autoLoadSpriteFile;
972 //        if (isLoadSpriteFrame) {
973         if (autoLoad) {
974             var configFiles = dic[ccs.CONST_CONFIG_FILE_PATH] || [];
975             var locFilePath, locPos, locPlistPath, locImagePath;
976             for (i = 0; i < configFiles.length; i++) {
977                 locFilePath = configFiles[i];
978                 locPos = locFilePath.lastIndexOf(".");
979                 locFilePath = locFilePath.substring(0, locPos);
980                 locPlistPath = dataInfo.basefilePath + locFilePath + ".plist";
981                 locImagePath = dataInfo.basefilePath + locFilePath + ".png";
982                 ccs.armatureDataManager.addSpriteFrameFromFile(locPlistPath, locImagePath, dataInfo.filename);
983             }
984         }
985 
986         armatureData = null;
987         animationData = null;
988     },
989 
990     decodeNodeFromJson: function (node, json, dataInfo) {
991         node.x = json[ccs.CONST_A_X] * this._positionReadScale;
992         node.y = json[ccs.CONST_A_Y] * this._positionReadScale;
993 
994         node.x *= dataInfo.contentScale;
995         node.y *= dataInfo.contentScale;
996 
997         node.zOrder = json[ccs.CONST_A_Z];
998 
999         node.skewX = json[ccs.CONST_A_SKEW_X] || 0;
1000         node.skewY = json[ccs.CONST_A_SKEW_Y] || 0;
1001         node.scaleX = json[ccs.CONST_A_SCALE_X] == null ? 1 : json[ccs.CONST_A_SCALE_X];
1002         node.scaleY = json[ccs.CONST_A_SCALE_Y] == null ? 1 : json[ccs.CONST_A_SCALE_Y];
1003 
1004         var colorDic;
1005         if (dataInfo.cocoStudioVersion < ccs.VERSION_COLOR_READING) {
1006             colorDic = json[0];
1007             if (colorDic){
1008                 node.a = colorDic[ccs.CONST_A_ALPHA] == null ? 255 : colorDic[ccs.CONST_A_ALPHA];
1009                 node.r = colorDic[ccs.CONST_A_RED] == null ? 255 : colorDic[ccs.CONST_A_RED];
1010                 node.g = colorDic[ccs.CONST_A_GREEN] == null ? 255 : colorDic[ccs.CONST_A_GREEN];
1011                 node.b = colorDic[ccs.CONST_A_BLUE] == null ? 255 : colorDic[ccs.CONST_A_BLUE];
1012                 node.isUseColorInfo = true;
1013             }
1014         } else {
1015             colorDic = json[ccs.CONST_COLOR_INFO] || null;
1016             if (colorDic){
1017                 node.a = colorDic[ccs.CONST_A_ALPHA] == null ? 255 : colorDic[ccs.CONST_A_ALPHA];
1018                 node.r = colorDic[ccs.CONST_A_RED] == null ? 255 : colorDic[ccs.CONST_A_RED];
1019                 node.g = colorDic[ccs.CONST_A_GREEN] == null ? 255 : colorDic[ccs.CONST_A_GREEN];
1020                 node.b = colorDic[ccs.CONST_A_BLUE] == null ? 255 : colorDic[ccs.CONST_A_BLUE];
1021                 node.isUseColorInfo = true;
1022             }
1023         }
1024     },
1025 
1026     clear: function () {
1027         this._configFileList = [];
1028         this._asyncRefCount = 0;
1029         this._asyncRefTotalCount = 0;
1030     },
1031 
1032     _asyncCallBack: function (selector, target, percent) {
1033         if(selector && typeof selector === 'function')
1034             selector.call(target, percent);
1035         if(target && selector && typeof selector === 'string')
1036             target[selector](percent);
1037     },
1038     /**
1039      * find the base file path
1040      * @param filePath
1041      * @returns {String}
1042      * @private
1043      */
1044     _initBaseFilePath: function (filePath) {
1045         var path = filePath;
1046         var pos = path.lastIndexOf("/");
1047         if (pos > -1)
1048             path = path.substr(0, pos + 1);
1049         else
1050             path = "";
1051         return path;
1052     },
1053 
1054     addDataFromXML: function (xml, dataInfo) {
1055         /*
1056          *  Need to get the full path of the xml file, or the Tiny XML can't find the xml at IOS
1057          */
1058         var xmlStr = cc.loader.getRes(xml);
1059         if (!xmlStr) throw "Please load the resource first : " + xml;
1060         var skeletonXML = cc.saxParser.parse(xmlStr);
1061         var skeleton = skeletonXML.documentElement;
1062         if (skeleton)
1063             this.addDataFromCache(skeleton, dataInfo);
1064     },
1065 
1066     addDataFromJson: function (filePath, dataInfo) {
1067         var fileContent = cc.loader.getRes(filePath);
1068         this.addDataFromJsonCache(fileContent, dataInfo);
1069     }
1070 };