/**\r
* Class を定義し システムの管理下に置く.\r
* 全てのクラスと pool が有効の場合インスタンスへの参照が保持される.\r
- * 1. X.Class.create( def, opt_final, opt_pool, opt_abstract ) でクラスを登録.\r
+ * 1. X.Class.create( opt_settings, opt_name, opt_props ) でクラスを登録.\r
* 2. コンストラクタ となるメソッドは、Constructor : function( arg ){ ... }, に書く.\r
* 3. 通常通り new で インスタンス生成\r
* 4. kill() でオブジェクトをクリーンして削除、pool が有効の場合は pool される.\r
* 6. \r
* \r
*/\r
-X.Class = ( function(){\r
- var CLASS_LIST = [],\r
- DEF_LIST = [],\r
- PRIVATE_CLASS_LIST = [],\r
- PRIVATE_DEF_LIST = [],\r
- CONSTRUCTOR = 'Constructor',\r
- killPrivateFlag = false,\r
- traits = null,\r
- useObjectCreate = false, // !!Object.create, http://jsperf.com/prototype-vs-object-create-perf\r
- use__proto__ = !!X.emptyFunction.prototype.__proto__;\r
- _DEF_LIST = DEF_LIST;\r
- /* サブクラスを作るメソッド \r
- * var subClass = superClass.inherits( ... ) \r
- * http://d.hatena.ne.jp/m-hiyama/20051018/1129605002\r
- */\r
- function inherits( /* displayName, classSetting, opt_PrivateClass, props */ ){\r
+\r
+// ------------------------------------------------------------------------- //\r
+// ------------ local variables -------------------------------------------- //\r
+// ------------------------------------------------------------------------- //\r
+var X_Class_CLASS_LIST = [],\r
+ X_Class_DEF_LIST = [],\r
+ X_Class_PRIVATE_CLASS_LIST = [],\r
+ X_Class_PRIVATE_DEF_LIST = [],\r
+ X_Class_killPrivateFlag = false,\r
+ X_Class_traits = null,\r
+ X_Class_useObjectCreate = false, // !!Object.create, http://jsperf.com/prototype-vs-object-create-perf\r
+ X_Class_use_proto_ = !!X.emptyFunction.prototype.__proto__;\r
+\r
+// ------------------------------------------------------------------------- //\r
+// --- interface ----------------------------------------------------------- //\r
+// ------------------------------------------------------------------------- //\r
+X.Class = {\r
+ \r
+ POOL_OBJECT : 1,\r
+ ABSTRACT : 2,\r
+ FINAL : 4,\r
+ SUPER_ACCESS : 8,\r
+ PRIVATE_DATA : 16,\r
+ \r
+ SINGLETON : 32, // 未実装\r
+ \r
+ create : function( /* displayName, classSetting, opt_PrivateClass, props */ ){\r
var args = X.copyArray( arguments ),\r
- params = [],\r
- Super = this,\r
- superDef = X.Class._getClassDef( Super ),\r
displayName = args[ 0 ],\r
classSetting,\r
- opt_super,\r
- klass, def;\r
- if( superDef.Final ) X.Notification.critical( 'X.Class inherits, Class is final!' );\r
- \r
- // サブクラス名\r
- if( X.Type.isString( displayName ) ){\r
+ opt_pool, opt_abstract, opt_final, opt_private,\r
+ privateDef,\r
+ props,\r
+ klass,\r
+ classDef = {};\r
+ if( X.Type.isString( displayName ) === true ){\r
+ classDef.displayName = displayName;\r
args.shift();\r
- } else {\r
- displayName = 'SubClass of ' + superDef.displayName;\r
};\r
- params.push( displayName );\r
\r
- // ã\82µã\83\96ã\82¯ã\83©ã\82¹è¨å®\9a\r
- classSetting = args[ 0 ];\r
+ // クラス設定\r
+ classDef.setting = classSetting = args[ 0 ];\r
if( X.Type.isNumber( classSetting ) ){\r
+ opt_pool = !!( classSetting & X.Class.POOL_OBJECT );\r
+ opt_abstract = !!( classSetting & X.Class.ABSTRACT );\r
+ opt_final = !!( classSetting & X.Class.FINAL );\r
+ opt_private = !!( classSetting & X.Class.PRIVATE_DATA );\r
+ if( opt_final && opt_abstract ){\r
+ X.Notification.critical( 'final & Abstract!' );\r
+ return;\r
+ }; \r
args.shift();\r
} else {\r
- // クラス設定がない場合、親からコピーして、Abstract flag は落とす??\r
- classSetting = superDef.setting;// &= ~X.Class.ABSTRACT;\r
+ classDef.setting = 0;\r
};\r
- if( superDef.isPrivate ) classSetting = classSetting | X.Class.PRIVATE_DATA;\r
- opt_super = !!( classSetting & X.Class.SUPER_ACCESS );\r
- params.push( classSetting );\r
-\r
- // サブクラスのシャドウ\r
- if( args[ 0 ] && X.Class._getClass( args[ 0 ] ) ){\r
- params.push( args.shift() );\r
+ \r
+ // シャドウクラス\r
+ if( X_Class_PRIVATE_CLASS_LIST.indexOf( args[ 0 ] ) !== -1 ){\r
+ privateDef = X_Class_getClassDef( args[ 0 ] );\r
+ if( privateDef.isPrivate !== true ){\r
+ X.Notification.critical( 'PrivateClass not found! please, X.Class.create( X.Class.PRIVATE, {...} ).' );\r
+ return;\r
+ } else\r
+ if( privateDef.Abstract === true ){\r
+ X.Notification.critical( 'PrivateClass is Abstract!' );\r
+ return;\r
+ };\r
+ classDef.privateClass = args.shift();\r
+ };\r
+ \r
+ // インスタンスのメンバー\r
+ props = args[ 0 ];\r
+ if( !X.Type.isObject( props ) ){\r
+ // サブクラスの場合、クラス定義の上書きがなくても作成可能\r
+ // サブクラスでなくても、クラスメンバ用オブジェクトが無しでも作成可能\r
+ //if( !X_Class_traits ){\r
+ // X.Notification.critical( 'No Class Def!' );\r
+ // return;\r
+ //};\r
+ props = {};\r
} else\r
- if( superDef.privateClass ){\r
- params.push( superDef.privateClass );\r
+ if( props.Constructor && X.Type.isFunction( props.Constructor ) ){\r
+ classDef.Constructor = props.Constructor;\r
};\r
- params.push( args[ 0 ] ); /* props サブクラスでは未定義でも可 */\r
+\r
+ // TODO use X.Function\r
+ klass = new Function( 'var a=arguments,f=a.callee;if(f.__new)return f.__new(a)' );\r
+ klass.__new = X_Class_actualConstructor;\r
+ klass.superClassOf = X_Class_superClassOf;\r
+ klass.subClassOf = X_Class_subClassOf;\r
\r
- // 継承クラスの作成\r
- if( useObjectCreate ){\r
- traits = Object.create( Super.prototype );\r
+ if( X_Class_useObjectCreate ){\r
+ klass.prototype = X.Class._override( X.Class._override( X_Class_traits || klass.prototype, props, true ), X_Class_CommonProps, false );\r
+ klass.prototype.constructor = klass;\r
} else\r
- if( use__proto__ ){\r
- traits = Super.prototype;\r
+ if( X_Class_use_proto_ ){\r
+ X.Class._override( klass.prototype, props, true );\r
+ if( X_Class_traits ){\r
+ klass.prototype.__proto__ = X_Class_traits;\r
+ } else {\r
+ X.Class._override( klass.prototype, X_Class_CommonProps, false );\r
+ };\r
} else {\r
- Super.__new = null;\r
- traits = new Super();\r
- Super.__new = C; \r
+ klass.prototype = X.Class._override( X.Class._override( X_Class_traits || klass.prototype, props, true ), X_Class_CommonProps, false );\r
+ klass.prototype.constructor = klass;\r
};\r
- klass = X.Class.create.apply( X.Class, params );\r
- traits = null;\r
+ klass.name = displayName;\r
\r
- def = X.Class._getClassDef( klass );\r
- // 継承用プロパティを控える\r
- if( opt_super === true ){\r
- def.superAccess = true;\r
- def.Super = Super;\r
- def.SuperProto = Super.prototype;\r
- def.SuperConstructor = superDef[ CONSTRUCTOR ] || superDef.SuperConstructor;\r
+ if( opt_abstract === true ){\r
+ classDef.Abstract = true;\r
+ } else\r
+ if( opt_pool === true ){\r
+ classDef.pool = [];\r
+ if( opt_private === false ) classDef.live = [];\r
+ }; \r
+ if( opt_final === true ){\r
+ classDef.Final = true;\r
+ } else {\r
+ klass.inherits = X_Class_inherits;\r
+ }; \r
+ if( opt_private === true ){\r
+ if( classDef.privateClass ){\r
+ X.Notification.critical( 'Private Data Class has no PrivateClass!' );\r
+ return;\r
+ };\r
+ classDef.isPrivate = true;\r
+ X_Class_PRIVATE_CLASS_LIST.push( klass );\r
+ X_Class_PRIVATE_DEF_LIST.push( classDef );\r
} else {\r
- def.Super = Super; // instanceOf() で親クラスを調べる!\r
+ X_Class_CLASS_LIST.push( klass );\r
+ X_Class_DEF_LIST.push( classDef ); \r
};\r
- \r
return klass;\r
- };\r
+ },\r
\r
- /* X.Class.create で作られたクラスのインスタンスが共通で備えるメソッド \r
- *\r
- *\r
- */\r
- var CommonProps = {\r
- kill : function(){\r
- var instance = this,\r
- klass = X.Class._getClass( instance ),\r
- def = X.Class._getClassDef( klass ),\r
- data, p, i;\r
- if( def.isPrivate && !killPrivateFlag ){\r
- X.Notification.critical( 'PrivateInstance.kill() work in PrivateUser.kill().' );\r
- return;\r
- };\r
- killPrivateFlag = false; // onKill 内で PrivateInstance.kill() を防ぐため\r
- \r
- // onKill() === false の場合、kill のキャンセル\r
- // private は false での キャンセル は無視される\r
- \r
- if( this.instanceOf( X.EventDispatcher ) ){\r
- console.log( 'this.instanceOf( X.EventDispatcher )! ' + this._dispatching );\r
- if( !def.isPrivate ){\r
- if( this._dispatching ){\r
- this.dispatch( X.Event.BEFORE_KILL_INSTANCE );\r
- this._killReserved = true;\r
- this.dispatch( X.Event.KILL_INSTANCE_CANCELED );\r
- return;\r
- } else\r
- if( this.dispatch( X.Event.BEFORE_KILL_INSTANCE ) & X.Callback.PREVENT_DEFAULT ){\r
- this.dispatch( X.Event.KILL_INSTANCE_CANCELED );\r
- return;\r
- };\r
- } else {\r
- this.dispatch( X.Event.BEFORE_KILL_INSTANCE ); \r
- };\r
- this.dispatch( X.Event.KILL_INSTANCE );\r
- this._listeners && this.unlisten();\r
- } else\r
- if( X.Type.isFunction( instance.onKill ) && instance.onKill() === false && !def.isPrivate ){\r
- return;\r
- };\r
- \r
- console.log('kill ' + this._dispatching);\r
- \r
- for( p in instance ){\r
- if( instance.hasOwnProperty && !instance.hasOwnProperty( p ) ) continue;\r
- delete instance[ p ];\r
- };\r
- if( def.pool ){\r
- def.live && def.live.splice( def.live.indexOf( instance ), 1 );\r
- def.pool[ def.pool.length ] = instance;\r
- };\r
- if( def.privateClass ){\r
- i = def.userList.indexOf( instance );\r
- if( i !== -1 ){\r
- data = X.Class._getPrivate( instance );\r
- killPrivateFlag = true;\r
- if( data._dispatching && data.instanceOf( X.EventDispatcher ) ){\r
- data._killReserved = true;\r
- } else {\r
- data.kill();\r
- };\r
- def.dataList.splice( i, 1 );\r
- def.userList.splice( i, 1 );\r
- };\r
- };\r
- },\r
- \r
- // Super\r
- // SuperCall\r
- \r
- instanceOf : function( klass ){\r
- var Super = this;\r
- if( this.constructor === klass ) return true;\r
- while( Super = X.Class._getClassDef( Super ).Super ){\r
- if( Super === klass ) return true;\r
- };\r
- return false;\r
- }\r
+ _getClass : X_Class_getClass,\r
+ \r
+ _getClassDef : X_Class_getClassDef,\r
+ \r
+ _newPrivate : X_Class_newPrivate,\r
+ \r
+ _getPrivate : X_Class_getPrivate,\r
+ \r
+ _override : X_Class_override\r
+ \r
+};\r
+\r
+// ------------------------------------------------------------------------- //\r
+// --- implements ---------------------------------------------------------- //\r
+// ------------------------------------------------------------------------- //\r
+function X_Class_getClass( instance ){\r
+ var cList = X_Class_CLASS_LIST,\r
+ i = cList.length,\r
+ klass;\r
+ for( ; i; ){\r
+ klass = cList[ --i ];\r
+ if( instance.constructor === klass ) return klass;\r
+ };\r
+ cList = X_Class_PRIVATE_CLASS_LIST;\r
+ i = cList.length;\r
+ for( ; i; ){\r
+ klass = cList[ --i ];\r
+ if( instance.constructor === klass ) return klass;\r
};\r
\r
- /*\r
- * new の実体.コンストラクタの機能は instance.Constructor に書く.\r
- * これにより pool された オブジェクト(破棄されたインスタンス) を再利用できる\r
- */\r
- /* Constructor Real for GeneralClass */\r
- function C( args ){\r
- var klass = this,\r
- def = X.Class._getClassDef( klass ),\r
- dataUser = def._tempUser,\r
- instance, obj,\r
- userDef;\r
- if( def.Abstract === true ){\r
- X.Notification.critical( 'AbstractClass!' );\r
- return;\r
- };\r
- if( def.isPrivate === true && dataUser === null ){\r
- X.Notification.critical( 'use myClass.newPrivate( instance, ...args )!' );\r
+ if( cList.indexOf( instance ) !== -1 ) return instance;\r
+ if( X_Class_CLASS_LIST.indexOf( instance ) !== -1 ) return instance;\r
+};\r
+\r
+function X_Class_getClassDef( KlassOrInstance ){\r
+ var i = X_Class_CLASS_LIST.indexOf( KlassOrInstance );\r
+ if( i === -1 ) i = X_Class_CLASS_LIST.indexOf( X_Class_getClass( KlassOrInstance ) );\r
+ if( i !== -1 ) return X_Class_DEF_LIST[ i ];\r
+ \r
+ i = X_Class_PRIVATE_CLASS_LIST.indexOf( KlassOrInstance );\r
+ if( i === -1 ) i = X_Class_PRIVATE_CLASS_LIST.indexOf( X_Class_getClass( KlassOrInstance ) );\r
+ if( i !== -1 ) return X_Class_PRIVATE_DEF_LIST[ i ];\r
+ \r
+ if( X_Class_DEF_LIST.indexOf( KlassOrInstance ) !== -1 ) return KlassOrInstance;\r
+ if( X_Class_PRIVATE_DEF_LIST.indexOf( KlassOrInstance ) !== -1 ) return KlassOrInstance;\r
+};\r
+\r
+function X_Class_newPrivate( /* instance, args */ ){\r
+ var args = X.copyArray( arguments ),\r
+ user = args.shift(),\r
+ def = X_Class_getClassDef( user ),\r
+ privateClass = def.privateClass,\r
+ privateDef = X_Class_getClassDef( privateClass ),\r
+ i = -1;\r
+ if( def.userList ){\r
+ i = def.userList.indexOf( user );\r
+ } else {\r
+ def.userList = [];\r
+ def.dataList = [];\r
+ };\r
+ if( i !== -1 ){\r
+ X.Notification.critical( 'PrivateData already exist!' );\r
+ return;\r
+ };\r
+ if( privateDef._tempUser ){\r
+ X.Notification.critical( 'newPrivate を連続呼び出しされたところ破綻' );\r
+ return;\r
+ };\r
+ privateDef._tempUser = user;\r
+ return privateClass.__new( args );\r
+};\r
+\r
+function X_Class_getPrivate( instance ){\r
+ var def = X_Class_getClassDef( instance ),\r
+ i = def.userList.indexOf( instance );\r
+ if( i !== -1 ) return def.dataList[ i ];\r
+};\r
+\r
+/* over のプロパティを target にコピーする.ただし target の プロパティが優先, force で解除 */\r
+function X_Class_override( target, src, force ){\r
+ var p;\r
+ for( p in src ){\r
+ if( p === 'Super' || p === 'SuperConstructor' || p === '__proto__' || p === 'prototype' || p === 'constructor' ){\r
+ X.Notification.critical( 'Super & SuperConstructor is reserved!' );\r
return;\r
};\r
- klass.__new = null;\r
- instance = def.pool && def.pool.length > 0 ?\r
- def.pool.pop() :\r
- useObjectCreate ?\r
- Object.create( klass.prototype ) :\r
- new klass();\r
- klass.__new = C;\r
- if( def.isPrivate === true ){\r
- userDef = X.Class._getClassDef( dataUser );\r
- userDef.dataList.push( instance );\r
- userDef.userList.push( dataUser );\r
- instance.User = dataUser;\r
- def._tempUser = null;\r
- } else {\r
- def.live && def.live.push( instance );\r
- };\r
- if( def.superAccess ){\r
- // TODO klass.prototype に移動\r
- instance.Super = def.SuperProto;\r
- instance.SuperConstructor = superConstructor;\r
+ if( force || target[ p ] === void 0 ){\r
+ target[ p ] = src[ p ];\r
};\r
- obj = def[ CONSTRUCTOR ] ?\r
- def[ CONSTRUCTOR ].apply( instance, args ) :\r
- def.SuperConstructor &&\r
- def.SuperConstructor.apply( instance, args );\r
- if( ( X.Type.isObject( obj ) && obj !== instance ) || X.Type.isFunction( obj ) ){ // Class\r
- instance.kill();\r
- return obj;\r
- };\r
- return instance;\r
};\r
+ return target;\r
+};\r
+\r
+function X_Class_superClassOf( klass ){\r
+ var myDef = X_Class_getClassDef( this ),\r
+ targetDef = X_Class_getClassDef( klass ),\r
+ SuperClass = klass;\r
+\r
+ if( !myDef || !targetDef || this === klass ) return false;\r
\r
- function superConstructor(){\r
- var s = X.Class._getClassDef( this ).SuperConstructor;\r
- s && s.apply( this, arguments );\r
+ while( SuperClass = X_Class_getClassDef( SuperClass ).SuperClass ){\r
+ if( SuperClass === this ) return true;\r
};\r
\r
- return {\r
- POOL_OBJECT : 1,\r
- ABSTRACT : 2,\r
- FINAL : 4,\r
- SUPER_ACCESS : 8,\r
- PRIVATE_DATA : 16,\r
- create : function( /* displayName, classSetting, opt_PrivateClass, props */ ){\r
- var args = X.copyArray( arguments ),\r
- displayName = args[ 0 ],\r
- classSetting,\r
- opt_pool, opt_abstract, opt_final, opt_private,\r
- privateDef,\r
- props,\r
- klass,\r
- classDef = {};\r
- if( X.Type.isString( displayName ) === true ){\r
- classDef.displayName = displayName;\r
- args.shift();\r
- };\r
- \r
- // クラス設定\r
- classDef.setting = classSetting = args[ 0 ];\r
- if( X.Type.isNumber( classSetting ) ){\r
- opt_pool = !!( classSetting & X.Class.POOL_OBJECT );\r
- opt_abstract = !!( classSetting & X.Class.ABSTRACT );\r
- opt_final = !!( classSetting & X.Class.FINAL );\r
- opt_private = !!( classSetting & X.Class.PRIVATE_DATA );\r
- if( opt_final && opt_abstract ){\r
- X.Notification.critical( 'final & Abstract!' );\r
- return;\r
- }; \r
- args.shift();\r
- } else {\r
- classDef.setting = 0;\r
- };\r
- \r
- // シャドウクラス\r
- if( PRIVATE_CLASS_LIST.indexOf( args[ 0 ] ) !== -1 ){\r
- privateDef = X.Class._getClassDef( args[ 0 ] );\r
- if( privateDef.isPrivate !== true ){\r
- X.Notification.critical( 'PrivateClass not found! please, X.Class.create( X.Class.PRIVATE, {...} ).' );\r
+ return false;\r
+};\r
+\r
+function X_Class_subClassOf( klass ){\r
+ return X.Class._superClassOf.call( klass, this );\r
+};\r
+ \r
+/* サブクラスを作るメソッド \r
+ * var subClass = superClass.inherits( ... ) \r
+ * http://d.hatena.ne.jp/m-hiyama/20051018/1129605002\r
+ */\r
+function X_Class_inherits( /* displayName, classSetting, opt_PrivateClass, props */ ){\r
+ var args = X.copyArray( arguments ),\r
+ params = [],\r
+ Super = this,\r
+ superDef = X_Class_getClassDef( Super ),\r
+ displayName = args[ 0 ],\r
+ classSetting,\r
+ opt_super,\r
+ klass, def;\r
+ if( superDef.Final ) X.Notification.critical( 'X.Class inherits, Class is final!' );\r
+ \r
+ // サブクラス名\r
+ if( X.Type.isString( displayName ) ){\r
+ args.shift();\r
+ } else {\r
+ displayName = 'SubClass of ' + superDef.displayName;\r
+ };\r
+ params.push( displayName );\r
+ \r
+ // サブクラス設定\r
+ classSetting = args[ 0 ];\r
+ if( X.Type.isNumber( classSetting ) ){\r
+ args.shift();\r
+ } else {\r
+ // クラス設定がない場合、親からコピーして、Abstract flag は落とす??\r
+ classSetting = superDef.setting;// &= ~X.Class.ABSTRACT;\r
+ };\r
+ if( superDef.isPrivate ) classSetting = classSetting | X.Class.PRIVATE_DATA;\r
+ opt_super = !!( classSetting & X.Class.SUPER_ACCESS );\r
+ params.push( classSetting );\r
+\r
+ // サブクラスのシャドウ\r
+ if( args[ 0 ] && X_Class_getClass( args[ 0 ] ) ){\r
+ params.push( args.shift() );\r
+ } else\r
+ if( superDef.privateClass ){\r
+ params.push( superDef.privateClass );\r
+ };\r
+ params.push( args[ 0 ] ); /* props サブクラスでは未定義でも可 */\r
+ \r
+ // 継承クラスの作成\r
+ if( X_Class_useObjectCreate ){\r
+ X_Class_traits = Object.create( Super.prototype );\r
+ } else\r
+ if( X_Class_use_proto_ ){\r
+ X_Class_traits = Super.prototype;\r
+ } else {\r
+ Super.__new = null;\r
+ X_Class_traits = new Super();\r
+ Super.__new = X_Class_actualConstructor; \r
+ };\r
+ klass = X.Class.create.apply( X.Class, params );\r
+ X_Class_traits = null;\r
+ \r
+ def = X_Class_getClassDef( klass );\r
+ // 継承用プロパティを控える\r
+ if( opt_super === true ){\r
+ def.superAccess = true;\r
+ def.SuperClass = Super;\r
+ def.SuperProto = Super.prototype;\r
+ def.SuperConstructor = superDef.Constructor || superDef.SuperConstructor;\r
+ } else {\r
+ def.SuperClass = Super; // instanceOf() で親クラスを調べる!\r
+ };\r
+ \r
+ return klass;\r
+};\r
+\r
+/* X.Class.create で作られたクラスのインスタンスが共通で備えるメソッド \r
+ *\r
+ *\r
+ */\r
+var X_Class_CommonProps = {\r
+ kill : function(){\r
+ var instance = this,\r
+ klass = X_Class_getClass( instance ),\r
+ def = X_Class_getClassDef( klass ),\r
+ data, p, i;\r
+ if( def.isPrivate && !X_Class_killPrivateFlag ){\r
+ X.Notification.critical( 'PrivateInstance.kill() work in PrivateUser.kill().' );\r
+ return;\r
+ };\r
+ X_Class_killPrivateFlag = false; // onKill 内で PrivateInstance.kill() を防ぐため\r
+ \r
+ // onKill() === false の場合、kill のキャンセル\r
+ // private は false での キャンセル は無視される\r
+ \r
+ if( this.instanceOf( X.EventDispatcher ) ){\r
+ console.log( 'this.instanceOf( X.EventDispatcher )! ' + this._dispatching );\r
+ if( !def.isPrivate ){\r
+ if( this._dispatching ){\r
+ this.dispatch( X.Event.BEFORE_KILL_INSTANCE );\r
+ this._killReserved = true;\r
+ this.dispatch( X.Event.KILL_INSTANCE_CANCELED );\r
return;\r
} else\r
- if( privateDef.Abstract === true ){\r
- X.Notification.critical( 'PrivateClass is Abstract!' );\r
- return;\r
- };\r
- classDef.privateClass = args.shift();\r
- };\r
- \r
- // インスタンスのメンバー\r
- props = args[ 0 ];\r
- if( !X.Type.isObject( props ) ){\r
- // サブクラスの場合、クラス定義の上書きがなくても作成可能\r
- // サブクラスでなくても、クラスメンバ用オブジェクトが無しでも作成可能\r
- //if( !traits ){\r
- // X.Notification.critical( 'No Class Def!' );\r
- // return;\r
- //};\r
- props = {};\r
- } else\r
- if( props[ CONSTRUCTOR ] && X.Type.isFunction( props[ CONSTRUCTOR ] ) ){\r
- classDef[ CONSTRUCTOR ] = props[ CONSTRUCTOR ];\r
- };\r
-\r
- klass = new Function( 'var a=arguments,f=a.callee;if(f.__new)return f.__new(a)' );\r
- klass.__new = C;\r
- klass.superClassOf = X.Class._superClassOf;\r
- klass.subClassOf = X.Class._subClassOf;\r
- \r
- if( useObjectCreate ){\r
- klass.prototype = X.Class._override( X.Class._override( traits || klass.prototype, props, true ), CommonProps, false );\r
- klass.prototype.constructor = klass;\r
- } else\r
- if( use__proto__ ){\r
- X.Class._override( klass.prototype, props, true );\r
- if( traits ){\r
- klass.prototype.__proto__ = traits;\r
- } else {\r
- X.Class._override( klass.prototype, CommonProps, false );\r
- };\r
- } else {\r
- klass.prototype = X.Class._override( X.Class._override( traits || klass.prototype, props, true ), CommonProps, false );\r
- klass.prototype.constructor = klass;\r
- };\r
- klass.name = displayName;\r
- \r
- if( opt_abstract === true ){\r
- classDef.Abstract = true;\r
- } else\r
- if( opt_pool === true ){\r
- classDef.pool = [];\r
- if( opt_private === false ) classDef.live = [];\r
- }; \r
- if( opt_final === true ){\r
- classDef.Final = true;\r
- } else {\r
- klass.inherits = inherits;\r
- }; \r
- if( opt_private === true ){\r
- if( classDef.privateClass ){\r
- X.Notification.critical( 'Private Data Class has no PrivateClass!' );\r
+ if( this.dispatch( X.Event.BEFORE_KILL_INSTANCE ) & X.Callback.PREVENT_DEFAULT ){\r
+ this.dispatch( X.Event.KILL_INSTANCE_CANCELED );\r
return;\r
};\r
- classDef.isPrivate = true;\r
- PRIVATE_CLASS_LIST.push( klass );\r
- PRIVATE_DEF_LIST.push( classDef );\r
- } else {\r
- CLASS_LIST.push( klass );\r
- DEF_LIST.push( classDef ); \r
- };\r
- return klass;\r
- },\r
- sys_shutdown : function(){\r
- \r
- },\r
- _getClass : function( instance ){\r
- var cList = CLASS_LIST,\r
- i = cList.length,\r
- klass;\r
- for( ; i; ){\r
- klass = cList[ --i ];\r
- if( instance.constructor === klass ) return klass;\r
- };\r
- cList = PRIVATE_CLASS_LIST;\r
- i = cList.length;\r
- for( ; i; ){\r
- klass = cList[ --i ];\r
- if( instance.constructor === klass ) return klass;\r
- };\r
- \r
- if( cList.indexOf( instance ) !== -1 ) return instance;\r
- if( CLASS_LIST.indexOf( instance ) !== -1 ) return instance;\r
- },\r
- _getClassDef : function( KlassOrInstance ){\r
- var i = CLASS_LIST.indexOf( KlassOrInstance );\r
- if( i === -1 ) i = CLASS_LIST.indexOf( X.Class._getClass( KlassOrInstance ) );\r
- if( i !== -1 ) return DEF_LIST[ i ];\r
- \r
- i = PRIVATE_CLASS_LIST.indexOf( KlassOrInstance );\r
- if( i === -1 ) i = PRIVATE_CLASS_LIST.indexOf( X.Class._getClass( KlassOrInstance ) );\r
- if( i !== -1 ) return PRIVATE_DEF_LIST[ i ];\r
- \r
- if( DEF_LIST.indexOf( KlassOrInstance ) !== -1 ) return KlassOrInstance;\r
- if( PRIVATE_DEF_LIST.indexOf( KlassOrInstance ) !== -1 ) return KlassOrInstance;\r
- },\r
- _newPrivate : function( /* instance, args */ ){\r
- var args = X.copyArray( arguments ),\r
- user = args.shift(),\r
- def = X.Class._getClassDef( user ),\r
- privateClass = def.privateClass,\r
- privateDef = X.Class._getClassDef( privateClass ),\r
- i = -1;\r
- if( def.userList ){\r
- i = def.userList.indexOf( user );\r
} else {\r
- def.userList = [];\r
- def.dataList = [];\r
+ this.dispatch( X.Event.BEFORE_KILL_INSTANCE ); \r
};\r
+ this.dispatch( X.Event.KILL_INSTANCE );\r
+ this._listeners && this.unlisten();\r
+ } else\r
+ if( X.Type.isFunction( instance.onKill ) && instance.onKill() === false && !def.isPrivate ){\r
+ return;\r
+ };\r
+ \r
+ console.log('kill ' + this._dispatching);\r
+ \r
+ for( p in instance ){\r
+ if( instance.hasOwnProperty && !instance.hasOwnProperty( p ) ) continue;\r
+ delete instance[ p ];\r
+ };\r
+ if( def.pool ){\r
+ def.live && def.live.splice( def.live.indexOf( instance ), 1 );\r
+ def.pool[ def.pool.length ] = instance;\r
+ };\r
+ if( def.privateClass ){\r
+ i = def.userList.indexOf( instance );\r
if( i !== -1 ){\r
- X.Notification.critical( 'PrivateData already exist!' );\r
- return;\r
- };\r
- if( privateDef._tempUser ){\r
- X.Notification.critical( 'newPrivate を連続呼び出しされたところ破綻' );\r
- return;\r
- };\r
- privateDef._tempUser = user;\r
- return privateClass.__new( args );\r
- },\r
- _getPrivate : function( instance ){\r
- var def = X.Class._getClassDef( instance ),\r
- i = def.userList.indexOf( instance );\r
- if( i !== -1 ) return def.dataList[ i ];\r
- },\r
- /* over のプロパティを target にコピーする.ただし target の プロパティが優先, force で解除 */\r
- _override : function ( target, src, force ){\r
- var p;\r
- for( p in src ){\r
- if( p === 'Super' || p === 'SuperConstructor' || p === '__proto__' || p === 'prototype' || p === 'constructor' ){\r
- X.Notification.critical( 'Super & SuperConstructor is reserved!' );\r
- return;\r
- };\r
- if( force || target[ p ] === void 0 ){\r
- target[ p ] = src[ p ];\r
+ data = X.Class._getPrivate( instance );\r
+ X_Class_killPrivateFlag = true;\r
+ if( data._dispatching && data.instanceOf( X.EventDispatcher ) ){\r
+ data._killReserved = true;\r
+ } else {\r
+ data.kill();\r
};\r
+ def.dataList.splice( i, 1 );\r
+ def.userList.splice( i, 1 );\r
};\r
- return target;\r
- },\r
- _superClassOf : function(){\r
- \r
- },\r
- _subClassOf : function(){\r
- \r
- }\r
+ };\r
+ },\r
+ \r
+ // TODO Super\r
+ // SuperCall\r
+ \r
+ instanceOf : function( klass ){\r
+ var Super = this;\r
+ if( this.constructor === klass ) return true;\r
+ while( Super = X_Class_getClassDef( Super ).SuperClass ){\r
+ if( Super === klass ) return true;\r
+ };\r
+ return false;\r
+ }\r
+};\r
+ \r
+/*\r
+ * new の実体.コンストラクタの機能は instance.Constructor に書く.\r
+ * これにより pool された オブジェクト(破棄されたインスタンス) を再利用できる\r
+ */\r
+function X_Class_actualConstructor( args ){\r
+ var klass = this,\r
+ def = X_Class_getClassDef( klass ),\r
+ dataUser = def._tempUser,\r
+ instance, obj,\r
+ userDef;\r
+ if( def.Abstract ){\r
+ X.Notification.critical( 'AbstractClass!' );\r
+ return;\r
+ };\r
+ if( def.isPrivate && !dataUser ){\r
+ X.Notification.critical( 'use myClass.newPrivate( instance, ...args )!' );\r
+ return;\r
+ };\r
+ klass.__new = null;\r
+ instance = def.pool && def.pool.length > 0 ?\r
+ def.pool.pop() :\r
+ X_Class_useObjectCreate ?\r
+ Object.create( klass.prototype ) :\r
+ new klass();\r
+ klass.__new = X_Class_actualConstructor;\r
+ \r
+ if( def.isPrivate ){\r
+ userDef = X_Class_getClassDef( dataUser );\r
+ userDef.dataList.push( instance );\r
+ userDef.userList.push( dataUser );\r
+ instance.User = dataUser;\r
+ def._tempUser = null;\r
+ } else {\r
+ def.live && def.live.push( instance );\r
+ };\r
+ if( def.superAccess ){\r
+ // TODO klass.prototype に移動\r
+ instance.Super = def.SuperProto;\r
+ instance.SuperConstructor = X_Class_superConstructor;\r
};\r
-})();\r
+ obj = def.Constructor ?\r
+ def.Constructor.apply( instance, args ) :\r
+ def.SuperConstructor &&\r
+ def.SuperConstructor.apply( instance, args );\r
+ if( ( X.Type.isObject( obj ) && obj !== instance ) || X.Type.isFunction( obj ) ){ // Class\r
+ instance.kill();\r
+ return obj;\r
+ };\r
+ return instance;\r
+};\r
+\r
+function X_Class_superConstructor(){\r
+ var s = X_Class_getClassDef( this ).SuperConstructor;\r
+ s && s.apply( this, arguments );\r
+};\r
\r
console.log( 'X.Core.Class' );\r