1 /****************************************************************************
  2  Copyright (c) 2013-2014 Chukong Technologies Inc.
  3 
  4  http://www.cocos2d-x.org
  5 
  6  Permission is hereby granted, free of charge, to any person obtaining a copy
  7  of this software and associated documentation files (the "Software"), to deal
  8  in the Software without restriction, including without limitation the rights
  9  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 10  copies of the Software, and to permit persons to whom the Software is
 11  furnished to do so, subject to the following conditions:
 12 
 13  The above copyright notice and this permission notice shall be included in
 14  all copies or substantial portions of the Software.
 15 
 16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 19  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 21  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 22  THE SOFTWARE.
 23  ****************************************************************************/
 24 
 25 ccs._load = (function(){
 26 
 27     /**
 28      * load file
 29      * @param {String} file
 30      * @param {String} [type=] - ccui|node|action
 31      * @param {String} [path=] - Resource search path
 32      * @returns {*}
 33      */
 34     var load = function(file, type, path){
 35 
 36         var json = cc.loader.getRes(file);
 37 
 38         if(!json)
 39             return cc.log("%s does not exist", file);
 40         var ext = extname(file).toLocaleLowerCase();
 41         if(ext !== "json" && ext !== "exportjson")
 42             return cc.log("%s load error, must be json file", file);
 43 
 44         var parse;
 45         if(!type){
 46             if(json["widgetTree"])
 47                 parse = parser["ccui"];
 48             else if(json["nodeTree"])
 49                 parse = parser["timeline"];
 50             else if(json["Content"] && json["Content"]["Content"])
 51                 parse = parser["timeline"];
 52             else if(json["gameobjects"])
 53                 parse = parser["scene"];
 54         }else{
 55             parse = parser[type];
 56         }
 57 
 58         if(!parse){
 59             cc.log("Can't find the parser : %s", file);
 60             return new cc.Node();
 61         }
 62         var version = json["version"] || json["Version"];
 63         if(!version && json["armature_data"]){
 64             cc.warn("%s is armature. please use:", file);
 65             cc.warn("    ccs.armatureDataManager.addArmatureFileInfoAsync(%s);", file);
 66             cc.warn("    var armature = new ccs.Armature('name');");
 67             return new cc.Node();
 68         }
 69         var currentParser = getParser(parse, version);
 70         if(!currentParser){
 71             cc.log("Can't find the parser : %s", file);
 72             return new cc.Node();
 73         }
 74 
 75         return currentParser.parse(file, json, path) || null;
 76     };
 77 
 78     var parser = {
 79         "ccui": {},
 80         "timeline": {},
 81         "action": {},
 82         "scene": {}
 83     };
 84 
 85     load.registerParser = function(name, version, target){
 86         if(!name || !version || !target)
 87             return cc.log("register parser error");
 88         if(!parser[name])
 89             parser[name] = {};
 90         parser[name][version] = target;
 91     };
 92 
 93     load.getParser = function(name, version){
 94         if(name && version)
 95             return parser[name] ? parser[name][version] : undefined;
 96         if(name)
 97             return parser[name];
 98         return parser;
 99     };
100 
101     //Gets the file extension
102     var extname = function(fileName){
103         var arr = fileName.match(extnameReg);
104         return ( arr && arr[1] ) ? arr[1] : null;
105     };
106     var extnameReg = /\.([^\.]+)$/;
107 
108 
109     var parserReg = /([^\.](\.\*)?)*$/;
110     var getParser = function(parser, version){
111         if(parser[version])
112             return parser[version];
113         else if(version === "*")
114             return null;
115         else
116             return getParser(parser, version.replace(parserReg, "*"));
117     };
118 
119     return load;
120 
121 })();
122 
123 ccs._parser = cc.Class.extend({
124 
125     ctor: function(){
126         this.parsers = {};
127     },
128 
129     _dirnameReg: /\S*\//,
130     _dirname: function(path){
131         var arr = path.match(this._dirnameReg);
132         return (arr && arr[0]) ? arr[0] : "";
133     },
134 
135     getClass: function(json){
136         return json["classname"];
137     },
138 
139     getNodeJson: function(json){
140         return json["widgetTree"];
141     },
142 
143     parse: function(file, json, resourcePath){
144         resourcePath = resourcePath || this._dirname(file);
145         this.pretreatment(json, resourcePath);
146         var node = this.parseNode(this.getNodeJson(json), resourcePath, file);
147         node && this.deferred(json, resourcePath, node, file);
148         return node;
149     },
150 
151     pretreatment: function(json, resourcePath, file){},
152 
153     deferred: function(json, resourcePath, node, file){},
154 
155     parseNode: function(json, resourcePath){
156         var parser = this.parsers[this.getClass(json)];
157         var widget = null;
158         if(parser)
159             widget = parser.call(this, json, resourcePath);
160         else
161             cc.log("Can't find the parser : %s", this.getClass(json));
162 
163         return widget;
164     },
165 
166     registerParser: function(widget, parse){
167         this.parsers[widget] = parse;
168     }
169 });
170 
171 /**
172  * Analysis of studio JSON file
173  * The incoming file name, parse out the corresponding object
174  * Temporary support file list:
175  *   ui 1.*
176  *   node 1.* - 2.*
177  *   action 1.* - 2.*
178  *   scene 0.* - 1.*
179  * @param {String} file
180  * @param {String} [path=] Resource path
181  * @returns {{node: cc.Node, action: cc.Action}}
182  */
183 ccs.load = function(file, path){
184     var object = {
185         node: null,
186         action: null
187     };
188 
189     object.node = ccs._load(file, null, path);
190     object.action = ccs._load(file, "action", path);
191     if(object.action && object.action.tag === -1 && object.node)
192         object.action.tag = object.node.tag;
193     return object;
194 };
195 ccs.load.validate = {};
196 
197 /**
198  * Analysis of studio JSON file and layout ui widgets by visible size.
199  * The incoming file name, parse out the corresponding object
200  * Temporary support file list:
201  *   ui 1.*
202  *   node 1.* - 2.*
203  *   action 1.* - 2.*
204  *   scene 0.* - 1.*
205  * @param {String} file
206  * @param {String} [path=] Resource path
207  * @returns {{node: cc.Node, action: cc.Action}}
208  */
209 ccs.loadWithVisibleSize = function(file, path){
210     var object = ccs.load(file, path);
211     var size = cc.director.getVisibleSize();
212     if(object.node && size){
213         object.node.setContentSize(size.width, size.height);
214         ccui.helper.doLayout(object.node);
215     }
216     return object;
217 };
218 
219 //Forward compatible interface
220 
221 ccs.actionTimelineCache = {
222 
223 
224     //@deprecated This function will be deprecated sooner or later please use ccs.load
225     /**
226      * Create Timeline Action
227      * @param file
228      * @returns {*}
229      */
230     createAction: function(file){
231         return ccs._load(file, "action");
232     }
233 };
234 
235 ccs.csLoader = {
236 
237     //@deprecated This function will be deprecated sooner or later please use ccs.load
238     /**
239      * Create Timeline Node
240      * @param file
241      * @returns {*}
242      */
243     createNode: function(file){
244         return ccs._load(file);
245     }
246 };
247 
248 cc.loader.register(["json"], {
249     load : function(realUrl, url, res, cb){
250         cc.loader.loadJson(realUrl, function(error, data){
251             var path = cc.path;
252             if(data && data["Content"] && data["Content"]["Content"]["UsedResources"]){
253                 var UsedResources = data["Content"]["Content"]["UsedResources"],
254                     dirname = path.dirname(url),
255                     list = [],
256                     tmpUrl, normalUrl;
257                 for(var i=0; i<UsedResources.length; i++){
258                     tmpUrl = path.join(dirname, UsedResources[i]);
259                     normalUrl = path._normalize(tmpUrl);
260                     if(!ccs.load.validate[normalUrl]){
261                         ccs.load.validate[normalUrl] = true;
262                         list.push(tmpUrl);
263                     }
264                 }
265                 cc.loader.load(list, function(){
266                     cb(error, data);
267                 });
268             }else{
269                 cb(error, data);
270             }
271 
272         });
273     }
274 });