/* * Copyright (c) 2014 Chukong Technologies Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ // Prepare JSB environment var cc = cc || {}; var window = window || this; /** * Iterate over an object or an array, executing a function for each matched element. * @param {object|array} obj * @param {function} iterator * @param {object} [context] */ cc.each = function (obj, iterator, context) { if (!obj) return; if (obj instanceof Array) { for (var i = 0, li = obj.length; i < li; i++) { if (iterator.call(context, obj[i], i) === false) return; } } else { for (var key in obj) { if (iterator.call(context, obj[key], key) === false) return; } } }; /** * Copy all of the properties in source objects to target object and return the target object. * @param {object} target * @param {object} *sources * @returns {object} */ cc.extend = function(target) { var sources = arguments.length >= 2 ? Array.prototype.slice.call(arguments, 1) : []; cc.each(sources, function(src) { for(var key in src) { if (src.hasOwnProperty(key)) { target[key] = src[key]; } } }); return target; }; /** * Check the obj whether is function or not * @param {*} obj * @returns {boolean} */ cc.isFunction = function(obj) { return typeof obj == 'function'; }; /** * Check the obj whether is number or not * @param {*} obj * @returns {boolean} */ cc.isNumber = function(obj) { return typeof obj == 'number' || Object.prototype.toString.call(obj) == '[object Number]'; }; /** * Check the obj whether is string or not * @param {*} obj * @returns {boolean} */ cc.isString = function(obj) { return typeof obj == 'string' || Object.prototype.toString.call(obj) == '[object String]'; }; /** * Check the obj whether is array or not * @param {*} obj * @returns {boolean} */ cc.isArray = function(obj) { return Array.isArray(obj) || (typeof obj === 'object' && Object.prototype.toString.call(obj) === '[object Array]'); }; /** * Check the obj whether is undefined or not * @param {*} obj * @returns {boolean} */ cc.isUndefined = function(obj) { return typeof obj === 'undefined'; }; /** * Check the obj whether is object or not * @param {*} obj * @returns {boolean} */ cc.isObject = function(obj) { return obj.__nativeObj !== undefined || ( typeof obj === "object" && Object.prototype.toString.call(obj) === '[object Object]' ); }; /** * Check the url whether cross origin * @param {String} url * @returns {boolean} */ cc.isCrossOrigin = function (url) { return false; }; /** * Common getter setter configuration function * @function * @param {Object} proto A class prototype or an object to config * @param {String} prop Property name * @param {function} getter Getter function for the property * @param {function} setter Setter function for the property */ cc.defineGetterSetter = function (proto, prop, getter, setter){ var desc = { enumerable: false, configurable: true }; getter && (desc.get = getter); setter && (desc.set = setter); Object.defineProperty(proto, prop, desc); }; /** * Associates a base class with a native superclass * @function * @param {object} jsobj subclass * @param {object} klass superclass */ cc.associateWithNative = function( jsobj, superclass_or_instance ) {}; // // JSB supports 2 official ways to create subclasses // // 1) Google "subclasses" borrowed from closure library // This is the recommended way to do it // cc.inherits = function (childCtor, parentCtor) { /** @constructor */ function tempCtor() {}; tempCtor.prototype = parentCtor.prototype; childCtor.superClass_ = parentCtor.prototype; childCtor.prototype = new tempCtor(); childCtor.prototype.constructor = childCtor; // Copy "static" method, but doesn't generate subclasses. // for( var i in parentCtor ) { // childCtor[ i ] = parentCtor[ i ]; // } }; cc.base = function(me, opt_methodName, var_args) { var caller = arguments.callee.caller; if (caller.superClass_) { // This is a constructor. Call the superclass constructor. ret = caller.superClass_.constructor.apply( me, Array.prototype.slice.call(arguments, 1)); return ret; } var args = Array.prototype.slice.call(arguments, 2); var foundCaller = false; for (var ctor = me.constructor; ctor; ctor = ctor.superClass_ && ctor.superClass_.constructor) { if (ctor.prototype[opt_methodName] === caller) { foundCaller = true; } else if (foundCaller) { return ctor.prototype[opt_methodName].apply(me, args); } } // If we did not find the caller in the prototype chain, // then one of two things happened: // 1) The caller is an instance method. // 2) This method was not called by the right caller. if (me[opt_methodName] === caller) { return me.constructor.prototype[opt_methodName].apply(me, args); } else { throw Error( 'cc.base called from a method of one name ' + 'to a method of a different name'); } }; var ClassManager = { id : (0|(Math.random()*998)), instanceId : (0|(Math.random()*998)), getNewID : function(){ return this.id++; }, getNewInstanceId : function(){ return this.instanceId++; } }; // // 2) Using "extend" subclassing // Simple JavaScript Inheritance By John Resig http://ejohn.org/ // cc.Class = function(){}; cc.Class.extend = function (prop) { var _super = this.prototype; // Instantiate a base class (but only create the instance, // don't run the init constructor) initializing = true; var prototype = Object.create(_super); initializing = false; fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/; // Copy the properties over onto the new prototype for (var name in prop) { // Check if we're overwriting an existing function prototype[name] = typeof prop[name] == "function" && typeof _super[name] == "function" && fnTest.test(prop[name]) ? (function (name, fn) { return function () { var tmp = this._super; // Add a new ._super() method that is the same method // but on the super-class this._super = _super[name]; // The method only need to be bound temporarily, so we // remove it when we're done executing var ret = fn.apply(this, arguments); this._super = tmp; return ret; }; })(name, prop[name]) : prop[name]; } // The dummy class constructor function Class() { // All construction is actually done in the init method if (!initializing) { if (!this.ctor) { if (this.__nativeObj) cc.log("No ctor function found! Please check whether `classes_need_extend` section in `ini` file like which in `tools/tojs/cocos2dx.ini`"); } else { this.ctor.apply(this, arguments); } } } var classId = ClassManager.getNewID(); ClassManager[classId] = _super; var desc = { writable: true, enumerable: false, configurable: true }; Class.id = classId; desc.value = classId; Object.defineProperty(prototype, '__pid', desc); // Populate our constructed prototype object Class.prototype = prototype; // Enforce the constructor to be what we expect Class.prototype.constructor = Class; // And make this class extendable Class.extend = arguments.callee; return Class; };