« 鱒と梅 | Home | 20090210 »

Feb 092009

ProgressionでRSLを配置するとCastDocumentの"_onInit"がロストしてしまう件

先日のエントリー(AS3での埋め込みフォントの共有について:其の伍[RSLの先読み対応 with Progression](多分解決))の中で書いた、「2)ProgressionでRSLを配置するとCastDocumentの"_onInit"がロストしてしまう。」の件について少し調べてみました。前回のエントリーでは

loaderInfoの"Event.COMPLETE"がRSLが存在すると発動しないというのが起因しているかと思います。
ってさらっと書きましたが、一応順を追って書いておきます。

"CastDocument._onIinit"は"ExDocument._initialize"内でdispachされて発動されます。"ExDocument._initialize"の発動は、"ExDocument"内の4つのフラグ"_initialized","_loaderInited","_loaderCompleted","_addedToStaged"が

if ( _initialized ) { return; }
if ( !_loaderInited ) { return; }
if ( !_loaderCompleted ) { return; }
if ( !_addedToStaged ) { return; }
を満たした場合に実行されます。 で、RSLを配置しない場合は
trace("ExDocument._initialize",_initialized,_loaderInited,_loaderCompleted,_addedToStaged);
//ExDocument._initialize false false false true
//ExDocument._initialize false true false true
//ExDocument._initialize false true true true
//発動
な感じで"_onInit"がcallされます。

一方RSLを配置した場合は

trace("ExDocument._initialize",_initialized,_loaderInited,_loaderCompleted,_addedToStaged);
//ExDocument._initialize false false false true
//ExDocument._initialize false true false true
//停止

のなります。問題になっているのは3番目の変数"loaderCompleted"であって、これは"ExDocument.loaderInfo"の"Event.COMPLETE"によって切り替わるフラグになります。

loaderInfo.addEventListener( Event.COMPLETE, _complete, false, int.MAX_VALUE, true );

つまり"CastDocument.loaderInfo"の"Event.COMPLETE"が発動しない。というのが先の

loaderInfoの"Event.COMPLETE"がRSLが存在すると発動しないというのが起因しているかと思います。
この一文の意味するところです。

RSLを配置していると何故に"CastDocument.loaderInfo"の"Event.COMPLETE"が発動しないのか?そこさえクリアすれば動作するのですが、RSLの情報にどーやってアクセスすんだ?ってことろが未だ分からず途方に暮れております。

先のエントリーでは"Event.ADDED_TO_STAGE"をキーにして強制的に"_onInit"を発動させていましたが、幾つか試したところ問題があったので、もう少し厳密にやるとなると、"Event.COMPLETE"の監視を無視した状態で"_onInit"をcallするほうが安全かもしれません。(これもこれで問題ありそうですが・・・)

ただ"ExDocument._loaderCompleted"、またそれを制御するイベントハンドラー"ExDocumet._complete"共に"private"のため、上位からの制御が出来ません。あまりよろしくないですが、"ExDocument._initialize"の中の

if ( !_loaderCompleted ) { return; }
をスルーするようにしてしまうのが、簡単なやり方です。幸い"loaderInfo.complete"でcallされる"ExDocument._complete"はリスナーの削除とフラグの制御しか行っていませんので、実害は発生しないだろうと思います。

※ただしこれはProgression自身に改変を加えることになりますのではっきり言ってお勧めはしません。もしやられる場合にはあくまで自己責任でやってくださいませ。

まぁProgression自身に改変を加えず、もう少しゆるいやり方で解決を試みるならば、以下の方法もありかな?と思います。

先に"Event.ADDED_TO_STAGE"を用いた回避策は、対象となるイベント"Event.ADDED_TO_STAGE"だけを監視して"_onInit"を発動させていたので、"loaderInfo.init"がスルーされた状態で初期化される危険がありました。なのでドキュメントクラス(CastDocumentのサブクラス)のコンストラクタ部分を以下のように・・。

public function Index() 
{
	loaderInfo.addEventListener( Event.INIT, _checkInit, false, 0, true );
	addEventListener(Event.ADDED_TO_STAGE, _checkInit, false, 0, true);
}
private var _checkCount:int = 0;
private function _checkInit(e:Event):void
{
	if (++_checkCount != 2)return;
	loaderInfo.removeEventListener( Event.INIT, _checkInit, false);
	removeEventListener(Event.ADDED_TO_STAGE, _checkInit, false);
	_onInit();
}
また、"_onInit"の2重発動をブロックするために(一応progression自身は2回目の初期化はブロックしていますが、"_onInit"に含まれるその他の初期化の多重初期化も防止する意味で・・・・)
protected override function _onInit():void {
	if (prog) return;
・・・

一応"LoaderInfo.init"の後に"LoaderInfo.complete"がcallされるはずですが、意味としてはほぼ同意だと思うので、問題ないんじゃないかしら?と・・・。

まぁそれでも一応仕様を超えた使い方になりますので、リスクを伴う可能性はあるということを認識して自己責任の元でやってみてくださいませ。

7 Comments

現在ベータテスト中のパッケージで、ExDocument クラスの読み込み部分に少し修正を加えています。

こちらで少し試した感じですと、こちらであれば RSL 問題が解決しているような気もするんですが、どうでしょうか・・・。

http://forum.progression.jp/index.php?topic=61.0

ちょっと待ってくださいね。
すぐ確認しまっす!

無事動作しましたよ!

if ( loaderInfo.bytesTotal > 0 && loaderInfo.bytesLoaded >= loaderInfo.bytesTotal ) {
ってなるですね。

こりゃRSLはloaderInfoに内包されてるっつーことなんですかね・・。付け焼刃の対応をしてしまった・・・恥

っつーかβテストに参加する余裕が無くってスイマセン・・・。
一人で勝手にこんなことやってるのはある意味迷惑ですよね・・・申し訳ない。
今の案件が一段落したら色々参加させて頂きたいと思っております。

確認ありがとうございます!

意図していませんでしたが、無事解決するようですので、終戦点の 1 つとしてリストアップさせて頂きますね。

多重投稿した上に間違ってますね・・・。

×終戦点
○修正点

> 一人で勝手にこんなことやってるのはある意味迷惑ですよね・・・申し訳ない。

いえいえ!
報告上がってない問題の発掘は大事なので、このエントリーもものすごくありがたいです!

>報告上がってない問題の発掘は大事なので、このエントリーもものすごくありがたいです!
ありがとございます。
実戦の中での検証なので、問題の根本的解決まで煮詰めれず、回避or投げっぱなしみたいなのが多くってスイマセヌ。もう少し根本的な解決策を提示できるように精進します。

Leave a comment

Search and Archives