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 //Forward compatible interface
198 
199 ccs.actionTimelineCache = {
200 
201 
202     //@deprecated This function will be deprecated sooner or later please use ccs.load
203     /**
204      * Create Timeline Action
205      * @param file
206      * @returns {*}
207      */
208     createAction: function(file){
209         return ccs._load(file, "action");
210     }
211 };
212 
213 ccs.csLoader = {
214 
215     //@deprecated This function will be deprecated sooner or later please use ccs.load
216     /**
217      * Create Timeline Node
218      * @param file
219      * @returns {*}
220      */
221     createNode: function(file){
222         return ccs._load(file);
223     }
224 };
225 
226 cc.loader.register(["json"], {
227     load : function(realUrl, url, res, cb){
228         cc.loader.loadJson(realUrl, function(error, data){
229             var path = cc.path;
230             if(data && data["Content"] && data["Content"]["Content"]["UsedResources"]){
231                 var UsedResources = data["Content"]["Content"]["UsedResources"],
232                     dirname = path.dirname(url),
233                     list = [],
234                     tmpUrl, normalUrl;
235                 for(var i=0; i<UsedResources.length; i++){
236                     tmpUrl = path.join(dirname, UsedResources[i]);
237                     normalUrl = path._normalize(tmpUrl);
238                     if(!ccs.load.validate[normalUrl]){
239                         ccs.load.validate[normalUrl] = true;
240                         list.push(tmpUrl);
241                     }
242                 }
243                 cc.loader.load(list, function(){
244                     cb(error, data);
245                 });
246             }else{
247                 cb(error, data);
248             }
249 
250         });
251     }
252 });