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 ccs.load.preload = true;
198 
199 /**
200  * Analysis of studio JSON file and layout ui widgets by visible size.
201  * The incoming file name, parse out the corresponding object
202  * Temporary support file list:
203  *   ui 1.*
204  *   node 1.* - 2.*
205  *   action 1.* - 2.*
206  *   scene 0.* - 1.*
207  * @param {String} file
208  * @param {String} [path=] Resource path
209  * @returns {{node: cc.Node, action: cc.Action}}
210  */
211 ccs.loadWithVisibleSize = function(file, path){
212     var object = ccs.load(file, path);
213     var size = cc.director.getVisibleSize();
214     if(object.node && size){
215         object.node.setContentSize(size.width, size.height);
216         ccui.helper.doLayout(object.node);
217     }
218     return object;
219 };
220 
221 //Forward compatible interface
222 
223 ccs.actionTimelineCache = {
224 
225 
226     //@deprecated This function will be deprecated sooner or later please use ccs.load
227     /**
228      * Create Timeline Action
229      * @param file
230      * @returns {*}
231      */
232     createAction: function(file){
233         return ccs._load(file, "action");
234     }
235 };
236 
237 ccs.csLoader = {
238 
239     //@deprecated This function will be deprecated sooner or later please use ccs.load
240     /**
241      * Create Timeline Node
242      * @param file
243      * @returns {*}
244      */
245     createNode: function(file){
246         return ccs._load(file);
247     }
248 };
249 
250 cc.loader.register(["json"], {
251     load : function(realUrl, url, res, cb){
252         cc.loader.loadJson(realUrl, function(error, data){
253             var path = cc.path;
254             if(data && data["Content"] && data["Content"]["Content"]["UsedResources"]){
255                 var UsedResources = data["Content"]["Content"]["UsedResources"],
256                     dirname = path.dirname(url),
257                     list = [],
258                     tmpUrl, normalUrl;
259                 for(var i=0; i<UsedResources.length; i++){
260                     if (!ccs.load.preload && /\.(png|jpg$)/.test(UsedResources[i]))
261                         continue;
262                     tmpUrl = path.join(dirname, UsedResources[i]);
263                     normalUrl = path._normalize(tmpUrl);
264                     if(!ccs.load.validate[normalUrl]){
265                         ccs.load.validate[normalUrl] = true;
266                         list.push(normalUrl);
267                     }
268                 }
269                 cc.loader.load(list, function(){
270                     cb(error, data);
271                 });
272             }else{
273                 cb(error, data);
274             }
275 
276         });
277     }
278 });