1 /**************************************************************************** 2 Copyright (c) 2010-2012 cocos2d-x.org 3 Copyright (c) 2008-2010 Ricardo Quesada 4 Copyright (c) 2011 Zynga Inc. 5 6 http://www.cocos2d-x.org 7 8 Permission is hereby granted, free of charge, to any person obtaining a copy 9 of this software and associated documentation files (the "Software"), to deal 10 in the Software without restriction, including without limitation the rights 11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 copies of the Software, and to permit persons to whom the Software is 13 furnished to do so, subject to the following conditions: 14 15 The above copyright notice and this permission notice shall be included in 16 all copies or substantial portions of the Software. 17 18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 THE SOFTWARE. 25 ****************************************************************************/ 26 27 /** 28 * copy an new object 29 * @function 30 * @param {object|Array} obj source object 31 * @return {Array|object} 32 */ 33 cc.clone = function (obj) { 34 // Cloning is better if the new object is having the same prototype chain 35 // as the copied obj (or otherwise, the cloned object is certainly going to 36 // have a different hidden class). Play with C1/C2 of the 37 // PerformanceVirtualMachineTests suite to see how this makes an impact 38 // under extreme conditions. 39 // 40 // Object.create(Object.getPrototypeOf(obj)) doesn't work well because the 41 // prototype lacks a link to the constructor (Carakan, V8) so the new 42 // object wouldn't have the hidden class that's associated with the 43 // constructor (also, for whatever reasons, utilizing 44 // Object.create(Object.getPrototypeOf(obj)) + Object.defineProperty is even 45 // slower than the original in V8). Therefore, we call the constructor, but 46 // there is a big caveat - it is possible that the this.init() in the 47 // constructor would throw with no argument. It is also possible that a 48 // derived class forgets to set "constructor" on the prototype. We ignore 49 // these possibities for and the ultimate solution is a standardized 50 // Object.clone(<object>). 51 var newObj = (obj.constructor) ? new obj.constructor : {}; 52 53 // Assuming that the constuctor above initialized all properies on obj, the 54 // following keyed assignments won't turn newObj into dictionary mode 55 // becasue they're not *appending new properties* but *assigning existing 56 // ones* (note that appending indexed properties is another story). See 57 // CCClass.js for a link to the devils when the assumption fails. 58 for (var key in obj) { 59 var copy = obj[key]; 60 // Beware that typeof null == "object" ! 61 if (((typeof copy) == "object") && copy && 62 !(copy instanceof cc.Node) && !(copy instanceof HTMLElement)) { 63 newObj[key] = cc.clone(copy); 64 } else { 65 newObj[key] = copy; 66 } 67 } 68 return newObj; 69 }; 70 71 /** 72 * Function added for JS bindings compatibility. Not needed in cocos2d-html5. 73 * @function 74 * @param {object} jsObj subclass 75 * @param {object} superclass 76 */ 77 cc.associateWithNative = function (jsObj, superclass) { 78 }; 79 80 /** 81 * keymap 82 * @example 83 * //Example 84 * //to mark a keydown 85 * cc.keyDown[65] = true; 86 * //or 87 * cc.keyMap[cc.KEY.a] 88 * 89 * //to mark a keyup 90 * do cc.keyDown[65] = false; 91 * 92 * //to find out if a key is down, check 93 * if(cc.keyDown[65]) 94 * //or 95 * if,(cc.keyDown[cc.KEY.space]) 96 * //if its undefined or false or null, its not pressed 97 * @constant 98 * @type object 99 */ 100 cc.KEY = { 101 backspace:8, 102 tab:9, 103 enter:13, 104 shift:16, //should use shiftkey instead 105 ctrl:17, //should use ctrlkey 106 alt:18, //should use altkey 107 pause:19, 108 capslock:20, 109 escape:27, 110 pageup:33, 111 pagedown:34, 112 end:35, 113 home:36, 114 left:37, 115 up:38, 116 right:39, 117 down:40, 118 insert:45, 119 Delete:46, 120 0:48, 121 1:49, 122 2:50, 123 3:51, 124 4:52, 125 5:53, 126 6:54, 127 7:55, 128 8:56, 129 9:57, 130 a:65, 131 b:66, 132 c:67, 133 d:68, 134 e:69, 135 f:70, 136 g:71, 137 h:72, 138 i:73, 139 j:74, 140 k:75, 141 l:76, 142 m:77, 143 n:78, 144 o:79, 145 p:80, 146 q:81, 147 r:82, 148 s:83, 149 t:84, 150 u:85, 151 v:86, 152 w:87, 153 x:88, 154 y:89, 155 z:90, 156 num0:96, 157 num1:97, 158 num2:98, 159 num3:99, 160 num4:100, 161 num5:101, 162 num6:102, 163 num7:103, 164 num8:104, 165 num9:105, 166 '*':106, 167 '+':107, 168 '-':109, 169 'numdel':110, 170 '/':111, 171 f1:112, //f1-f12 dont work on ie 172 f2:113, 173 f3:114, 174 f4:115, 175 f5:116, 176 f6:117, 177 f7:118, 178 f8:119, 179 f9:120, 180 f10:121, 181 f11:122, 182 f12:123, 183 numlock:144, 184 scrolllock:145, 185 semicolon:186, 186 ',':186, 187 equal:187, 188 '=':187, 189 ';':188, 190 comma:188, 191 dash:189, 192 '.':190, 193 period:190, 194 forwardslash:191, 195 grave:192, 196 '[':219, 197 openbracket:219, 198 ']':221, 199 closebracket:221, 200 backslash:220, 201 quote:222, 202 space:32 203 }; 204 205 206 /** 207 * Image Format:JPG 208 * @constant 209 * @type Number 210 */ 211 cc.FMT_JPG = 0; 212 213 /** 214 * Image Format:PNG 215 * @constant 216 * @type Number 217 */ 218 cc.FMT_PNG = 1; 219 220 /** 221 * Image Format:TIFF 222 * @constant 223 * @type Number 224 */ 225 cc.FMT_TIFF = 2; 226 227 /** 228 * Image Format:RAWDATA 229 * @constant 230 * @type Number 231 */ 232 cc.FMT_RAWDATA = 3; 233 234 /** 235 * Image Format:WEBP 236 * @constant 237 * @type Number 238 */ 239 cc.FMT_WEBP = 4; 240 241 /** 242 * Image Format:UNKNOWN 243 * @constant 244 * @type Number 245 */ 246 cc.FMT_UNKNOWN = 5; 247 248 cc.getImageFormatByData = function (imgData) { 249 // if it is a png file buffer. 250 if (imgData.length > 8) { 251 if (imgData[0] == 0x89 252 && imgData[1] == 0x50 253 && imgData[2] == 0x4E 254 && imgData[3] == 0x47 255 && imgData[4] == 0x0D 256 && imgData[5] == 0x0A 257 && imgData[6] == 0x1A 258 && imgData[7] == 0x0A) { 259 return cc.FMT_PNG; 260 } 261 } 262 263 // if it is a tiff file buffer. 264 if (imgData.length > 2) { 265 if ((imgData[0] == 0x49 && imgData[1] == 0x49) 266 || (imgData[0] == 0x4d && imgData[1] == 0x4d) 267 || (imgData[0] == 0xff && imgData[1] == 0xd8)) { 268 return cc.FMT_TIFF; 269 } 270 } 271 272 return cc.FMT_UNKNOWN; 273 }; 274 275 276 /** 277 * Common getter setter configuration function 278 * @function 279 * @param {Object} proto A class prototype or an object to config<br/> 280 * @param {String} prop Property name 281 * @param {function} getter Getter function for the property 282 * @param {function} setter Setter function for the property 283 * @param {String} getterName Name of getter function for the property 284 * @param {String} setterName Name of setter function for the property 285 */ 286 cc.defineGetterSetter = function (proto, prop, getter, setter, getterName, setterName) 287 { 288 if (proto.__defineGetter__) { 289 getter && proto.__defineGetter__(prop, getter); 290 setter && proto.__defineSetter__(prop, setter); 291 } 292 else if (Object.defineProperty) { 293 var desc = { enumerable: false, configurable: true }; 294 getter && (desc.get = getter); 295 setter && (desc.set = setter); 296 Object.defineProperty(proto, prop, desc); 297 } 298 else { 299 throw new Error("browser does not support getters"); 300 return; 301 } 302 303 if(!getterName && !setterName) { 304 // Lookup getter/setter function 305 var hasGetter = (getter != null), hasSetter = (setter != undefined); 306 var props = Object.getOwnPropertyNames(proto); 307 for (var i = 0; i < props.length; i++) { 308 var name = props[i]; 309 if( proto.__lookupGetter__(name) || typeof proto[name] !== "function" ) continue; 310 var func = proto[name]; 311 if (hasGetter && func === getter) { 312 getterName = name; 313 if(!hasSetter || setterName) break; 314 } 315 if (hasSetter && func === setter) { 316 setterName = name; 317 if(!hasGetter || getterName) break; 318 } 319 } 320 } 321 322 // Found getter/setter 323 var ctor = proto.constructor; 324 if (getterName) { 325 if (!ctor.__getters__) { 326 ctor.__getters__ = {}; 327 } 328 ctor.__getters__[getterName] = prop; 329 } 330 if (setterName) { 331 if (!ctor.__setters__) { 332 ctor.__setters__ = {}; 333 } 334 ctor.__setters__[setterName] = prop; 335 } 336 }; 337 338 /** 339 * copy an array's item to a new array (its performance is better than Array.slice) 340 * @param {Array} arr 341 * @returns {Array} 342 */ 343 cc.copyArray = function(arr){ 344 var i, len = arr.length, arr_clone = new Array(len); 345 for (i = 0; i < len; i += 1) 346 arr_clone[i] = arr[i]; 347 return arr_clone; 348 }; 349