-/**\r
- * Class を定義し システムの管理下に置く.\r
- * 全てのクラスと pool が有効の場合インスタンスへの参照が保持される.\r
- * 1. X.Class.create( opt_settings, opt_name, opt_privateClass, opt_props ) でクラスを登録.\r
- * 2. コンストラクタ となるメソッドは、opt_props 内の Constructor : function( arg ){ ... }, に書く.\r
- * 3. 通常通り new で インスタンス生成\r
- * 4. kill() でオブジェクトをクリーンして削除、pool が有効の場合は pool される.\r
- * 5. pool が有効の場合、new で pool されたインスタンスが返される.\r
- * 6. \r
- * \r
- */\r
\r
// ------------------------------------------------------------------------- //\r
// ------------ local variables -------------------------------------------- //\r
// ------------------------------------------------------------------------- //\r
-var X_Class_CLASS_LIST = [],\r
+var\r
+ /**\r
+ * 全てのクラスのスーパークラスのようなもの。(ライブラリ内にカプセル化されているため、ユーザが触ることはありません)<br>\r
+ * X.Class.create() で定義されたクラスのインスタンスが共通で備えるメソッド を確認してください。\r
+ * @class __ClassBase__\r
+ * @private\r
+ * @abstract\r
+ */\r
+ __ClassBase__ = {\r
+ /**\r
+ * クラス名\r
+ * @type {string}\r
+ */\r
+ name : ''\r
+ },\r
+\r
+ X_Class_CLASS_LIST = [],\r
X_Class_DEF_LIST = [],\r
- X_Class_PRIVATE_CLASS_LIST = [],\r
- X_Class_PRIVATE_DEF_LIST = [],\r
X_Class_CALLING_SUPER = [],\r
X_Class_CALL_SUPER_STACK = [],\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_UA.OperaMobile && !X_UA.OperaTablet && !!X.emptyFunction.prototype.__proto__,\r
+ X_Class_use_proto_ = !X_UA[ 'OperaMobile' ] && !X_UA[ 'OperaTablet' ] && !!X_emptyFunction.prototype.__proto__,\r
// Opera Mobile 12.10 Android11 IS01 でクラスのメンバが欠落する問題に遭遇。__proto__ を使わないと動作,,,\r
\r
-/** \r
- * X.Class.create で定義されたクラスのインスタンスが共通で備えるメソッド を格納\r
- *\r
- * @class\r
- */ \r
-X_Class_CommonProps =\r
-\r
+X_Class_CommonMethods =\r
+/** @lends __ClassBase__.prototype */\r
{\r
- /*\r
- * インスタンスの破棄。\r
- * TODO kill したインスタンスのイベントが残っていないか?これは開発用のみ\r
+ /**\r
+ * 全ての動的メンバを削除して、インスタンスを破棄する。<br>\r
+ * インスタンスが X.EventDispatcher とそのサブクラスの場合、次の動作をする。\r
+ * <ol>\r
+ * <li>X.Event.BEFORE_KILL_INSTANCE を発火する。戻り値のビットフラグに X_Callback.PREVENT_DEFAULT が立つ場合、破棄をキャンセルし X.Event.KILL_INSTANCE_CANCELED を発火する。\r
+ * <li>破棄に進む場合は、X.Event.KILL_INSTANCE を発火する。\r
+ * <li>dispatch 中は、インスタンスの全ての dispatch が終了するまで実際の破棄を待つ。\r
+ * <li>実際の破棄では、インスタンスのメンバの削除に加えて全てのイベントリスナを解除する。\r
*/\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.Logger.critical( 'PrivateInstance.kill() work in PrivateUser.kill().' );\r
- return;\r
- };\r
- X_Class_killPrivateFlag = false; // instance.kill() 内で PrivateInstance.kill() を防ぐため\r
+ // TODO kill したインスタンスのイベントが残っていないか?これは開発用のみ\r
+ 'kill' : function(){\r
+ var def, listeners, p;\r
+ \r
+ // TODO kill 中の kill の呼び出しを防ぐ, 破棄済のインスタンスへの kill\r
\r
- // X.EventDispatcher とそのサブクラスは kill() が呼ばれた通知を発行する。\r
- // X.Event.BEFORE_KILL_INSTANCE はキャンセル可能(private な class は不可)\r
- // X.Event.KILL_INSTANCE は、プロパティやイベントリスナの削除直前に発行\r
- // X.Event.KILL_INSTANCE_CANCELED は kill() がキャンセルされた場合に発行。また dispatchループ中にkill()が呼ばれると一旦キャンセルされ発行。\r
- // (flagを立ててdispatchの終わりにkillする)\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
+ if( this[ 'instanceOf' ]( X_EventDispatcher ) ){\r
+\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
+ \r
+ listeners = this[ '_listeners' ];\r
+ \r
+ if( listeners && listeners[ X_LISTENERS_DISPATCHING ] ){\r
+ listeners[ X_LISTENERS_KILL_RESERVED ] = true;\r
+ return;\r
+ };\r
+\r
+ // asyncDispatch の削除\r
+ for( p in X_EventDispatcher_LAZY_TIMERS ){\r
+ if( X_EventDispatcher_LAZY_TIMERS[ p ] === this ){\r
+ // delete X_EventDispatcher_LAZY_TIMERS[ p ]; コレ不要\r
+ X_Timer_remove( p );\r
};\r
- } else {\r
- this.dispatch( X.Event.BEFORE_KILL_INSTANCE ); \r
};\r
- this.dispatch( X.Event.KILL_INSTANCE );\r
- this._listeners && X_EventDispatcher_systemUnlisten( this ); //.unlisten();\r
+ \r
+ this[ 'dispatch' ]( X_EVENT_KILL_INSTANCE );\r
+ listeners && X_EventDispatcher_unlistenAll( this );\r
};\r
\r
- for( p in instance ){\r
- if( instance.hasOwnProperty && !instance.hasOwnProperty( p ) ) continue;\r
- delete instance[ p ];\r
- };\r
+ X_Object_clear( this );\r
+ \r
+ def = X_Class_getClassDef( this );\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
- 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
+ def.live.splice( def.live.indexOf( this ), 1 );\r
+ def.pool[ def.pool.length ] = this;\r
};\r
},\r
\r
- /* クラス定義を辿ってスーパークラスのコンストラクタを探す。\r
- * 呼び出したコンストラクタは配列に控える。\r
- * さらに呼ばれた場合、配列を元にさらに奥のコンストラクタを取得\r
- * TODO 現在 new しているインスタンスを保持してチェックする\r
+ /**\r
+ * 関数は Constructor 内で使用します。クラス定義を辿ってスーパークラスのコンストラクタを探します。<br>\r
+ * 内部的には、呼び出したコンストラクタは配列に控え(X_Class_CALLING_SUPER)、呼び出したコンストラクタ内でさらに Super が呼ばれた場合、配列を元にさらにスーパーなコンストラクタを辿ります。\r
+ * @example Constructor : function( arg1, arg2 ){\r
+ * this.Super( aeg1, arg2 );\r
+ * }\r
+ * @param var_args {...?} 親コンストラクタを呼ぶ際に渡す任意の数の引数\r
+ * @return {*}\r
*/\r
- Super : function(){\r
+ // TODO 現在 new しているインスタンスを保持してチェックする\r
+ 'Super' : function( var_args ){\r
var sClass = this,\r
i = X_Class_CALLING_SUPER.indexOf( sClass ),\r
n = -1,\r
console.log( 'スーパークラスのコンストラクタが見つかりません' );\r
},\r
\r
- /*\r
- * func について、親クラスで設定されている同名の関数メンバーを呼び出す\r
- * 2つ以上の異なる名前で同じ関数がメンバーだった場合、失敗します\r
- * 例) this.superCall( arguments.callee, param0, param1, ... )\r
+ /**\r
+ * func について、親クラスで設定されている同名の関数メンバーを呼び出す。<br>\r
+ * 第一引数に関数を指定し、2つ以上の異なる名前で同じ関数がメンバーがいた場合、動作が不確実になります。<br>\r
+ * 参考:<a href="http://qiita.com/no22@github/items/d3bead2acbb7ff1fb86b" target="_blank">ES5なJavascriptでモダンなクラス的継承&スーパー呼び出し </a>\r
+ * @param funcNameOrFunc {Function|string} スーパークラスの関数名 または、オーバーライド済の自身の関数。\r
+ * @param var_args {...*} オーバーライド元関数に渡す任意の数の引数\r
+ * @example return this.superCall( arguments.callee, param0, param1, ... );\r
+ * @return {*} オーバーライド元の関数を呼び出した戻り値。\r
*/\r
- superCall : function( func /* ...args */ ){\r
+ 'superCall' : function( funcNameOrFunc, var_args ){\r
var sClass = this,\r
args = arguments,\r
name, p, sFunc, hit = false;\r
- if( X.Type.isFunction( func ) ){\r
- for( p in this ){\r
- if( this[ p ] === func ){\r
+ if( X_Type_isFunction( funcNameOrFunc ) ){\r
+ for( p in this.constructor.prototype ){\r
+ if( this.constructor.prototype[ p ] === funcNameOrFunc ){\r
name = p;\r
break;\r
};\r
def = X_Class_getClassDef( sClass );\r
sClass = def.SuperClass;\r
sFunc = sClass.prototype[ name ];\r
- if( sFunc === func ){\r
+ if( sFunc === funcNameOrFunc ){\r
hit = true; // 現在の関数にヒット\r
} else\r
if( hit && X_Object_inObject( name, this ) ){\r
- if( X.Type.isFunction( sFunc ) ){\r
+ if( X_Type_isFunction( sFunc ) ){\r
switch( args.length ){\r
case 1 :\r
return sFunc.call( this );\r
case 4 :\r
return sFunc.call( this, args[ 1 ], args[ 2 ], args[ 3 ] );\r
default :\r
- args = X.Object.cloneArray( args );\r
+ args = X_Object_cloneArray( args );\r
args.shift();\r
return sFunc.apply( this, args );\r
};\r
};\r
},\r
\r
- /*\r
- * TODO instanceof に対応したブラウザはそちらを使用\r
+ /**\r
+ * インスタンスのクラスか?またはスーパークラスか?調べる。<br>\r
+ * instanceof 構文をサポートしない環境(IE4,Mac IE5)を想定する場合、必ずこのメソッドを使用すること。<br>\r
+ * クラスのインスタンスか?だけ調べたい場合は this.constructor === klass が高速。\r
+ * @param klass {__ClassBase__} クラス定義\r
+ * @return {boolean}\r
*/\r
- instanceOf : function( klass ){\r
+ // TODO instanceof に対応したブラウザはそちらを使用\r
+ 'instanceOf' : function( klass ){\r
var Super = this;\r
if( this.constructor === klass ) return true;\r
while( Super = X_Class_getClassDef( Super ).SuperClass ){\r
// --- interface ----------------------------------------------------------- //\r
// ------------------------------------------------------------------------- //\r
\r
-/** @namespace */ \r
-X.Class = {\r
- \r
- NONE : 0,\r
+/*\r
+ * @enum {number}\r
+ * @const\r
+ */\r
+var X_Class = {\r
+ NONE : 0,\r
+ POOL_OBJECT : 1,\r
+ ABSTRACT : 2,\r
+ FINAL : 4,\r
+ SINGLETON : 8\r
+};\r
+\r
+/**\r
+ * <p>Class を定義し システムの管理下に置く。\r
+ * <p>prototype 継承のブラウザ毎の差異も吸収し、 以下から最適な方法をしてくれる。\r
+ * \r
+ * <ol>\r
+ * <li>Object.create はパフォーマンスが悪そうなので現在は使っていない。\r
+ * <li>SubClass.prototype.__proto__ = SuperClass.prototype;\r
+ * <li>SubClass.prototype = new SuperClass;\r
+ * </ol>\r
+ * \r
+ * <ol>\r
+ * <li>X.Class.create( opt_settings, opt_name, opt_props ) でクラスを登録.\r
+ * <li>コンストラクタ となるメソッドは、opt_props 内の Constructor : function( arg ){ ... }, に書く.\r
+ * <li>通常通り new で インスタンス生成\r
+ * <li>kill() でオブジェクトをクリーンして削除、pool が有効の場合は pool される.\r
+ * <li>pool が有効の場合、new で pool されたインスタンスが返される.\r
+ * </ol>\r
+ * @namespace X.Class\r
+ * @alias X.Class\r
+ */ \r
+X[ 'Class' ] = /** @lends X.Class */ {\r
+\r
+ /**\r
+ * 設定なし。\r
+ * @const\r
+ */ \r
+ 'NONE' : X_Class.NONE,\r
\r
/**\r
* インスタンスは破棄時(this.kill())に回収され、次回の new MyClass() 時に再利用されます。\r
- * @memberof X.Class */\r
- POOL_OBJECT : 1,\r
+ * @const\r
+ */\r
+ 'POOL_OBJECT' : X_Class.POOL_OBJECT,\r
\r
/**\r
* 定義するクラスは抽象クラスになります。new AbstractClass() とするとエラーになります。\r
- * @memberof X.Class */\r
- ABSTRACT : 2,\r
- \r
- \r
- /** @memberof X.Class */\r
- FINAL : 4,\r
- /** @memberof X.Class */\r
- SUPER_ACCESS : 8,\r
- /** @memberof X.Class */\r
- PRIVATE_DATA : 16,\r
- /** @memberof X.Class */\r
- SINGLETON : 32, // 未実装\r
+ * @const\r
+ */\r
+ 'ABSTRACT' : X_Class.ABSTRACT,\r
+\r
+ /**\r
+ * クラスの継承を禁止する。\r
+ * @const\r
+ */\r
+ 'FINAL' : X_Class.FINAL,\r
+\r
+ /**\r
+ * 未実装。でも目印になるので付けておきましょう。\r
+ * @const\r
+ */\r
+ 'SINGLETON' : X_Class.SINGLETON,\r
+\r
+ 'create' : X_Class_create\r
\r
- create : function( /* displayName, classSetting, opt_PrivateClass, props */ ){\r
+ // TODO collect\r
+};\r
+\r
+\r
+\r
+// ------------------------------------------------------------------------- //\r
+// --- implements ---------------------------------------------------------- //\r
+// ------------------------------------------------------------------------- //\r
+ /**\r
+ * クラスを定義する。<br>\r
+ * X.Class.create() によるクラス定義は必ずしもコンストラクタ('Constructor')を必要としません。クラス定義時にコンストラクタが未設定の場合、スーパークラスがあればそのコンストラクタを使用します。\r
+ * @alias X.Class.create\r
+ * @param {string} [displayName] クラスの名前\r
+ * @param {number} [classSetting=0] X_Class.POOL_OBJECT | X_Class.FINAL など\r
+ * @param {object} [props={}] このクラスのメンバと関数。コンストラクタは Constructor と書くこと\r
+ * @return {__ClassBase__}\r
+ * @example var myClass = X.Class.create(\r
+ * 'myClass',\r
+ * X.Class.FINAL,\r
+ * {\r
+ * name : '',\r
+ * Constructor : function( obj ){\r
+ * this.name = obj.name;\r
+ * },\r
+ * getName : function(){\r
+ * return this.name;\r
+ * },\r
+ * setName : function(v){\r
+ * this.name = v;\r
+ * }\r
+ * }\r
+ * );\r
+ */\r
+ function X_Class_create( /* displayName, classSetting, privateClass, props */ ){\r
var args = X_Object_cloneArray( arguments ),\r
displayName = args[ 0 ],\r
classSetting,\r
- opt_pool, opt_abstract, opt_final, opt_private,\r
+ opt_pool, opt_abstract, opt_final,\r
privateDef,\r
props,\r
klass,\r
- classDef = {}, hash;\r
- if( X.Type.isString( displayName ) === true ){\r
+ classDef = {},\r
+ cbHash = { proxy : X_Class_actualConstructor, classDef : classDef };\r
+\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( 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
if( opt_final && opt_abstract ){\r
X.Logger.critical( 'final & Abstract!' );\r
return;\r
classDef.setting = 0;\r
};\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.Logger.critical( 'PrivateClass not found! please, X.Class.create( X.Class.PRIVATE, {...} ).' );\r
- return;\r
- } else\r
- if( privateDef.Abstract === true ){\r
- X.Logger.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.Logger.critical( 'No Class Def!' );\r
- // return;\r
- //};\r
+ if( !X_Type_isObject( props ) ){\r
+ // クラスメンバ用オブジェクトが無しでもクラスは作成可能\r
props = {};\r
} else\r
- if( props.Constructor && X.Type.isFunction( props.Constructor ) ){\r
- classDef.Constructor = props.Constructor;\r
+ if( props[ 'Constructor' ] ){\r
+ //{+dev\r
+ if( !X_Type_isFunction( props[ 'Constructor' ] ) ){\r
+ alert( '"Constructor" is not function.' );\r
+ return;\r
+ };\r
+ //}+dev\r
+ classDef.Constructor = props[ 'Constructor' ];\r
};\r
\r
- klass = X_Callback_actualClosure( hash = { _ : X_Class_actualConstructor } ); // TODO hash = classDef\r
- hash.c = klass;\r
- klass.superClassOf = X_Class_superClassOf;\r
- klass.subClassOf = X_Class_subClassOf;\r
+ klass = X_Callback_actualClosure( cbHash ); // TODO callbackHash を class定義の置き場所にしてしまう!なるほど…\r
+ cbHash.klass = klass;\r
+ klass[ 'superClassOf' ] = X_Class_superClassOf;\r
+ klass[ 'subClassOf' ] = X_Class_subClassOf;\r
\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 = X_Class_override( X_Class_override( X_Class_traits || klass.prototype, props, true ), X_Class_CommonMethods, false );\r
klass.prototype.constructor = klass;\r
} else\r
if( X_Class_use_proto_ ){\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
+ X_Class_override( klass.prototype, X_Class_CommonMethods, false );\r
};\r
} else {\r
- klass.prototype = X_Class_override( X_Class_override( X_Class_traits || klass.prototype, props, true ), X_Class_CommonProps, false );\r
+ klass.prototype = X_Class_override( X_Class_override( X_Class_traits || klass.prototype, props, true ), X_Class_CommonMethods, false );\r
klass.prototype.constructor = klass;\r
};\r
- klass.name = displayName;\r
+ \r
+ klass[ 'name' ] = displayName;\r
\r
if( opt_abstract ){\r
classDef.Abstract = true;\r
} else\r
if( opt_pool ){\r
classDef.pool = [];\r
- if( opt_private === false ) classDef.live = [];\r
+ classDef.live = [];\r
}; \r
if( opt_final ){\r
classDef.Final = true;\r
} else {\r
- klass.inherits = X_Class_inherits;\r
+ klass[ 'inherits' ] = X_Class_inherits;\r
}; \r
- if( opt_private ){\r
- if( classDef.privateClass ){\r
- X.Logger.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
- X_Class_CLASS_LIST.push( klass );\r
- X_Class_DEF_LIST.push( classDef ); \r
- };\r
+ \r
+ X_Class_CLASS_LIST.push( klass );\r
+ X_Class_DEF_LIST.push( classDef ); \r
+\r
return klass;\r
- },\r
- \r
- _newPrivate : X_Class_newPrivate,\r
- \r
- _getPrivate : X_Class_getPrivate\r
- \r
-};\r
+ };\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 = 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
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
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_Object_cloneArray( 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.Logger.critical( 'PrivateData already exist!' );\r
- return;\r
- };\r
- if( privateDef._tempUser ){\r
- X.Logger.critical( 'newPrivate を連続呼び出しされたところ破綻' );\r
- return;\r
- };\r
- privateDef._tempUser = user;\r
- return X_Class_actualConstructor( privateClass( X_Closure_COMMAND_BACK ), args );// 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
X.Logger.critical( p + ' is reserved!' );\r
return;\r
};\r
- if( force || target[ p ] === void 0 ){\r
+ if( force || target[ p ] === undefined ){\r
target[ p ] = src[ p ];\r
};\r
};\r
return target;\r
};\r
\r
+/**\r
+ * スーパークラスか?調べます。\r
+ * @alias __ClassBase__.superClassOf\r
+ * @param klass {__ClassBase__}\r
+ * @return {boolean}\r
+ */\r
function X_Class_superClassOf( klass ){\r
var myDef = X_Class_getClassDef( this ),\r
targetDef = X_Class_getClassDef( klass ),\r
return false;\r
};\r
\r
+/**\r
+ * サブクラスか?調べます。\r
+ * @alias __ClassBase__.subClassOf\r
+ * @type {Function}\r
+ * @param klass {__ClassBase__}\r
+ * @return {boolean}\r
+ */\r
function X_Class_subClassOf( klass ){\r
- return X_Class_superClassOf.call( klass, this );\r
+ return klass && 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
+/**\r
+ * サブクラスを作ります。与える引数は X_Class.create と同じです。http://d.hatena.ne.jp/m-hiyama/20051018/1129605002\r
+ * @alias __ClassBase__.inherits\r
+ * @example var SubClass = SuperClass.inherits( 'Sub', X_Class.FINAL, { ... } );\r
+ * @param {string} [displayName] クラスの名前\r
+ * @param {number} [classSetting=0] X_Class.POOL_OBJECT | X_Class.FINAL など\r
+ * @param {__ClassBase__=} [privateClass] このクラスとペアで動作するシャドウクラス\r
+ * @param {object} [props={}] このクラスのメンバと関数。コンストラクタは Constructor と書くこと\r
+ * @return {__ClassBase__}\r
*/\r
function X_Class_inherits( /* displayName, classSetting, opt_PrivateClass, props */ ){\r
var args = X_Object_cloneArray( arguments ),\r
if( superDef.Final ) X.Logger.critical( 'X.Class inherits, Class is final!' );\r
\r
// サブクラス名\r
- if( X.Type.isString( displayName ) ){\r
+ if( X_Type_isString( displayName ) ){\r
args.shift();\r
} else {\r
displayName = 'SubClass of ' + superDef.displayName;\r
\r
// サブクラス設定\r
classSetting = args[ 0 ];\r
- if( X.Type.isNumber( classSetting ) ){\r
+ if( X_Type_isNumber( classSetting ) ){\r
args.shift();\r
} else {\r
// クラス設定がない場合、親からコピーして、Abstract flag は落とす??\r
- classSetting = superDef.setting;// &= ~X.Class.ABSTRACT;\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
+\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
\r
/* props 未定義でも可 */\r
} else {\r
X_Class_traits = new Super( X_Closure_COMMAND_DROP );\r
};\r
- klass = X.Class.create.apply( X.Class, params );\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
+ def.SuperClass = Super;\r
+ def.SuperProto = Super.prototype;\r
+ def.SuperConstructor = superDef.Constructor || superDef.SuperConstructor;\r
\r
return klass;\r
};\r
* new の実体.コンストラクタの機能は instance.Constructor に書く.\r
* これにより pool された オブジェクト(破棄されたインスタンス) を再利用できる\r
*/\r
-function X_Class_actualConstructor( obj, args ){\r
- var klass = obj.c,//this,\r
- def = X_Class_getClassDef( klass ),\r
- dataUser = def._tempUser,\r
- instance, obj,\r
- userDef;\r
+function X_Class_actualConstructor( f, args ){\r
+ var klass = f.klass,\r
+ def = f.classDef,\r
+ instance, obj;\r
+\r
if( def.Abstract ){\r
X.Logger.critical( 'AbstractClass!' );\r
return;\r
};\r
- if( def.isPrivate && !dataUser ){\r
- X.Logger.critical( 'use myClass.newPrivate( instance, ...args )!' );\r
- return;\r
- };\r
\r
- instance = def.pool && def.pool.length > 0 ?\r
+ instance = def.pool && def.pool.length ?\r
def.pool.pop() :\r
X_Class_useObjectCreate ?\r
Object.create( klass.prototype ) :\r
new klass( X_Closure_COMMAND_DROP );\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
+ def.live && def.live.push( instance );\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
+\r
+ if( obj !== instance && ( X_Type_isObject( obj ) || X_Type_isFunction( obj ) ) ){ // Class\r
+ instance[ 'kill' ]();\r
return obj;\r
};\r
return instance;\r