OSDN Git Service

Version 0.6.85, update X.Class.
authoritozyun <itozyun@user.sourceforge.jp>
Tue, 23 Sep 2014 15:20:38 +0000 (00:20 +0900)
committeritozyun <itozyun@user.sourceforge.jp>
Tue, 23 Sep 2014 15:20:38 +0000 (00:20 +0900)
0.6.x/js/00_core/04_XClass.js

index 031f5b1..3438f9b 100644 (file)
@@ -1,7 +1,7 @@
 /**\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