123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334 |
- /****************************************************************************
- Copyright (c) 2008-2010 Ricardo Quesada
- Copyright (c) 2011-2012 cocos2d-x.org
- Copyright (c) 2013-2014 Chukong Technologies Inc.
- http://www.cocos2d-x.org
- 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.
- ****************************************************************************/
- /**
- * The main namespace of Cocos2d-JS, all engine core classes, functions, properties and constants are defined in this namespace
- * @namespace
- * @name cc
- */
- var cc = cc || {};
- /**
- * @namespace
- * @name ClassManager
- */
- var ClassManager = {
- id : (0|(Math.random()*998)),
- instanceId : (0|(Math.random()*998)),
- compileSuper : function(func, name, id){
- //make the func to a string
- var str = func.toString();
- //find parameters
- var pstart = str.indexOf('('), pend = str.indexOf(')');
- var params = str.substring(pstart+1, pend);
- params = params.trim();
- //find function body
- var bstart = str.indexOf('{'), bend = str.lastIndexOf('}');
- var str = str.substring(bstart+1, bend);
- //now we have the content of the function, replace this._super
- //find this._super
- while(str.indexOf('this._super')!= -1)
- {
- var sp = str.indexOf('this._super');
- //find the first '(' from this._super)
- var bp = str.indexOf('(', sp);
- //find if we are passing params to super
- var bbp = str.indexOf(')', bp);
- var superParams = str.substring(bp+1, bbp);
- superParams = superParams.trim();
- var coma = superParams? ',':'';
- //replace this._super
- str = str.substring(0, sp)+ 'ClassManager['+id+'].'+name+'.call(this'+coma+str.substring(bp+1);
- }
- return Function(params, str);
- },
- getNewID : function(){
- return this.id++;
- },
- getNewInstanceId : function(){
- return this.instanceId++;
- }
- };
- ClassManager.compileSuper.ClassManager = ClassManager;
- /* Managed JavaScript Inheritance
- * Based on John Resig's Simple JavaScript Inheritance http://ejohn.org/blog/simple-javascript-inheritance/
- * MIT Licensed.
- */
- (function () {
- var fnTest = /\b_super\b/;
- var config = cc.game.config;
- var releaseMode = config[cc.game.CONFIG_KEY.classReleaseMode];
- if(releaseMode) {
- console.log("release Mode");
- }
- /**
- * The base Class implementation (does nothing)
- * @class
- */
- cc.Class = function () {
- };
- /**
- * Create a new Class that inherits from this Class
- * @static
- * @param {object} props
- * @return {function}
- */
- cc.Class.extend = function (props) {
- var _super = this.prototype;
- // Instantiate a base Class (but only create the instance,
- // don't run the init constructor)
- var prototype = Object.create(_super);
- var classId = ClassManager.getNewID();
- ClassManager[classId] = _super;
- // Copy the properties over onto the new prototype. We make function
- // properties non-eumerable as this makes typeof === 'function' check
- // unneccessary in the for...in loop used 1) for generating Class()
- // 2) for cc.clone and perhaps more. It is also required to make
- // these function properties cacheable in Carakan.
- var desc = { writable: true, enumerable: false, configurable: true };
- prototype.__instanceId = null;
- // The dummy Class constructor
- function Class() {
- this.__instanceId = ClassManager.getNewInstanceId();
- // All construction is actually done in the init method
- if (this.ctor)
- this.ctor.apply(this, arguments);
- }
- Class.id = classId;
- // desc = { writable: true, enumerable: false, configurable: true,
- // value: XXX }; Again, we make this non-enumerable.
- desc.value = classId;
- Object.defineProperty(prototype, '__pid', desc);
- // Populate our constructed prototype object
- Class.prototype = prototype;
- // Enforce the constructor to be what we expect
- desc.value = Class;
- Object.defineProperty(Class.prototype, 'constructor', desc);
- // Copy getter/setter
- this.__getters__ && (Class.__getters__ = cc.clone(this.__getters__));
- this.__setters__ && (Class.__setters__ = cc.clone(this.__setters__));
- for(var idx = 0, li = arguments.length; idx < li; ++idx) {
- var prop = arguments[idx];
- for (var name in prop) {
- var isFunc = (typeof prop[name] === "function");
- var override = (typeof _super[name] === "function");
- var hasSuperCall = fnTest.test(prop[name]);
- if (releaseMode && isFunc && override && hasSuperCall) {
- desc.value = ClassManager.compileSuper(prop[name], name, classId);
- Object.defineProperty(prototype, name, desc);
- } else if (isFunc && override && hasSuperCall) {
- desc.value = (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]);
- Object.defineProperty(prototype, name, desc);
- } else if (isFunc) {
- desc.value = prop[name];
- Object.defineProperty(prototype, name, desc);
- } else {
- prototype[name] = prop[name];
- }
- if (isFunc) {
- // Override registered getter/setter
- var getter, setter, propertyName;
- if (this.__getters__ && this.__getters__[name]) {
- propertyName = this.__getters__[name];
- for (var i in this.__setters__) {
- if (this.__setters__[i] == propertyName) {
- setter = i;
- break;
- }
- }
- cc.defineGetterSetter(prototype, propertyName, prop[name], prop[setter] ? prop[setter] : prototype[setter], name, setter);
- }
- if (this.__setters__ && this.__setters__[name]) {
- propertyName = this.__setters__[name];
- for (var i in this.__getters__) {
- if (this.__getters__[i] == propertyName) {
- getter = i;
- break;
- }
- }
- cc.defineGetterSetter(prototype, propertyName, prop[getter] ? prop[getter] : prototype[getter], prop[name], getter, name);
- }
- }
- }
- }
- // And make this Class extendable
- Class.extend = cc.Class.extend;
- //add implementation method
- Class.implement = function (prop) {
- for (var name in prop) {
- prototype[name] = prop[name];
- }
- };
- return Class;
- };
- })();
- /**
- * Common getter setter configuration function
- * @function
- * @param {Object} proto A class prototype or an object to config<br/>
- * @param {String} prop Property name
- * @param {function} getter Getter function for the property
- * @param {function} setter Setter function for the property
- * @param {String} getterName Name of getter function for the property
- * @param {String} setterName Name of setter function for the property
- */
- cc.defineGetterSetter = function (proto, prop, getter, setter, getterName, setterName){
- if (proto.__defineGetter__) {
- getter && proto.__defineGetter__(prop, getter);
- setter && proto.__defineSetter__(prop, setter);
- } else if (Object.defineProperty) {
- var desc = { enumerable: false, configurable: true };
- getter && (desc.get = getter);
- setter && (desc.set = setter);
- Object.defineProperty(proto, prop, desc);
- } else {
- throw new Error("browser does not support getters");
- }
- if(!getterName && !setterName) {
- // Lookup getter/setter function
- var hasGetter = (getter != null), hasSetter = (setter != undefined), props = Object.getOwnPropertyNames(proto);
- for (var i = 0; i < props.length; i++) {
- var name = props[i];
- if( (proto.__lookupGetter__ ? proto.__lookupGetter__(name)
- : Object.getOwnPropertyDescriptor(proto, name))
- || typeof proto[name] !== "function" )
- continue;
- var func = proto[name];
- if (hasGetter && func === getter) {
- getterName = name;
- if(!hasSetter || setterName) break;
- }
- if (hasSetter && func === setter) {
- setterName = name;
- if(!hasGetter || getterName) break;
- }
- }
- }
- // Found getter/setter
- var ctor = proto.constructor;
- if (getterName) {
- if (!ctor.__getters__) {
- ctor.__getters__ = {};
- }
- ctor.__getters__[getterName] = prop;
- }
- if (setterName) {
- if (!ctor.__setters__) {
- ctor.__setters__ = {};
- }
- ctor.__setters__[setterName] = prop;
- }
- };
- /**
- * Create a new object and copy all properties in an exist object to the new object
- * @function
- * @param {object|Array} obj The source object
- * @return {Array|object} The created object
- */
- cc.clone = function (obj) {
- // Cloning is better if the new object is having the same prototype chain
- // as the copied obj (or otherwise, the cloned object is certainly going to
- // have a different hidden class). Play with C1/C2 of the
- // PerformanceVirtualMachineTests suite to see how this makes an impact
- // under extreme conditions.
- //
- // Object.create(Object.getPrototypeOf(obj)) doesn't work well because the
- // prototype lacks a link to the constructor (Carakan, V8) so the new
- // object wouldn't have the hidden class that's associated with the
- // constructor (also, for whatever reasons, utilizing
- // Object.create(Object.getPrototypeOf(obj)) + Object.defineProperty is even
- // slower than the original in V8). Therefore, we call the constructor, but
- // there is a big caveat - it is possible that the this.init() in the
- // constructor would throw with no argument. It is also possible that a
- // derived class forgets to set "constructor" on the prototype. We ignore
- // these possibities for and the ultimate solution is a standardized
- // Object.clone(<object>).
- var newObj = (obj.constructor) ? new obj.constructor : {};
- // Assuming that the constuctor above initialized all properies on obj, the
- // following keyed assignments won't turn newObj into dictionary mode
- // becasue they're not *appending new properties* but *assigning existing
- // ones* (note that appending indexed properties is another story). See
- // CCClass.js for a link to the devils when the assumption fails.
- for (var key in obj) {
- var copy = obj[key];
- // Beware that typeof null == "object" !
- if (((typeof copy) == "object") && copy &&
- !(copy instanceof cc.Node) && !(copy instanceof HTMLElement)) {
- newObj[key] = cc.clone(copy);
- } else {
- newObj[key] = copy;
- }
- }
- return newObj;
- };
|