« Loaderの読み込み強制終了 Loader.unload編 | Home | progression検証 #19 progression.jsを使用した際のSWFForceSizeの挙動不審 »

Nov 162008

progression検証 #18 CastImageLoaderの読み込み強制終了 CastImageLoader.close編

apeirophobia: Loaderの読み込み強制終了 Loader.close編apeirophobia: Loaderの読み込み強制終了 Loader.unload編の続き。Progression3でやるとどうなるか?の検証。

主要なコードは以下の通り。本当はもっとスマートな書き方がCastImageLoaderにはありますが、敢えてここはcontentsLoaderInfoと比較するためにこの記述の仕方で・・。
CODE:1

_loader = new CastImageLoader();
//CastImageLoaderイベント
_loader.addEventListener(CastEvent.CAST_LOAD_COMPLETE, _loaded_Loader);
_loader.addEventListener(CastEvent.CAST_LOAD_START, function() { trace("CastImageLoader::ロード開始");_output.text = "CAST_LOAD_START"} );
_loader.addEventListener(Event.UNLOAD, function() { trace("CastImageLoader::アンロードされました"); _output.text = "CAST_REMOVED" } );
//contentLoaderInfoイベント
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function() { trace("contentLoaderInfo::ロード完了"); } );
_loader.contentLoaderInfo.addEventListener(Event.OPEN, function() { trace("contentLoaderInfo::ロード開始"); );
_loader.contentLoaderInfo.addEventListener(Event.UNLOAD, function() { trace("contentLoaderInfo::アンロードされました"); } );
・・・
_bt_cancel.onCastMouseDown = function()
{
	trace("CLOSE実行");
	if (_loader.contentLoaderInfo && _loader.contentLoaderInfo.bytesLoaded < _loader.contentLoaderInfo.bytesTotal)
	{
		_loader.close();
	}
	_loader.unload();
}
・・・
private function _loaded_Loader(e:Event):void
{
	trace("CastImageLoader::ロード完了");
	addChildAt(_loader,0);
}
で、一点注意点としてはCastEventは"UNLOAD"イベントを持たないので、その部分だけはEvent.UNLOADを使用します。あ、あとcontentLoaderInfoではなく直接CastImageLoaderを監視します。

プレビュー/ダウンロードシミュレートでの実行結果は

1:読み込み中にclose実行>読み込みは中断されず、COMPLETEイベント発生。ただし_loaderは表示されない。
2:読み込み前にclose実行>特に問題なし
3:読み込み後にclose実行>_loader消去
4:読み込み中にclose実行後、再度読み込み>2回目の読み込みCOMPLETEイベントが発生するが、_loaderが表示されない。
5:読み込み完了後にclose実行後、再度読み込み>問題なく表示
6:読み込み後、再度読み込み中にclose実行>unloadが無視され、COMPLETE発生後表示されてしまう。

という感じに。読み込みは中断されずCOMPLETEイベントは発生してしまいますが、表示されることはありません。

ただし4、5、6あたりが挙動が不審なところで、読み込み中にunloadを実行する、もしくは一度unlaod無しでCOMPLETEしてしまうとcontents(DisplayObject)の制御が利かなくなるようです。(ExLoader、ExImageLoader、CastImageLoaderの中を見てみましたが、ちょっと原因良く分からなかった)

HTTP経由での実行結果は

1:読み込み中にclose実行>読み込み中断。
2:読み込み前にclose実行>特に問題なし
3:読み込み後にclose実行>_loader消去
4:読み込み中にclose実行後、再度読み込み>問題なし
5:読み込み完了後にclose実行後、再度読み込み>問題なく表示
6:読み込み後、再度読み込み中にclose実行>問題なし

という結果になりました。プレビュー環境でおかしかった4、5、6辺りはHTTP経由では問題ないようです。

で、話はちょっと横にそれますが、contentsLoaderInfoのイベントとのタイミングですが、普通にLoadingした場合

CastImageLoader::ロード開始
contentLoaderInfo::ロード開始
CastImageLoader::ロード完了
contentLoaderInfo::ロード完了

というようにCastImageLoaderのイベントのほうが先に実行されています。ステキです。

では続いて、CastImageLoaderに最適と思われる記述の仕方をしてみます。

CastImageLoader - Progression 3.0 - API Referenceに書かれてある仕様に乗っ取って書いてみると。こんな感じ。
CODE:2

_loader = new CastImageLoader();
_loader.onCastLoadStart = function()
{
	trace("CastImageLoader::ロード開始");
	_output.text = "CAST_LOAD_START"
}
_loader.onCastLoadComplete = _loaded_Loader;
_loader.addEventListener(CastEvent.CAST_REMOVED, function() { trace("CastImageLoader::アンロードされました"); _output.text = "CAST_REMOVED" } );
・・・
_bt_cancel.onCastMouseDown = function()
{
	trace("CLOSE実行");
	if(_loader.loading)
	{
		_loader.close();
	}
	_loader.unload();
}
onCastLoadStart、onCastLoadComplete、等がプロパティとして用意されています。(ちょっとこれを使用した場合明示的にremoveAllListenersをしなくても良いのか?が未確認ですが・・)

でHTTP経由で実行した結果

1:読み込み中にclose実行>読み込み中断されずCOMPLETEイベント発生。_loader表示されず
2:読み込み前にclose実行>特に問題なし
3:読み込み後にclose実行>_loader消去
4:読み込み中にclose実行後、再度読み込み>2回目の読み込みCOMPLETEイベントが発生するが、_loaderが表示されない。
5:読み込み完了後にclose実行後、再度読み込み>問題なく表示
6:読み込み後、再度読み込み中にclose実行>unloadが無視され、COMPLETE発生後表示されてしまう。

という感じで、プレビューでの挙動とほぼ一緒になってしまいました。
で、元々これが今回の検証の発端な訳ですが、ここで、close実行の判定式を
if(_loader.loading)
から
if (_loader.contentLoaderInfo && _loader.contentLoaderInfo.bytesLoaded < _loader.contentLoaderInfo.bytesTotal)
に戻してみます。
実行結果は

1:読み込み中にclose実行>読み込み中断。
2:読み込み前にclose実行>特に問題なし
3:読み込み後にclose実行>_loader消去
4:読み込み中にclose実行後、再度読み込み>問題なし
5:読み込み完了後にclose実行後、再度読み込み>問題なく表示
6:読み込み後、再度読み込み中にclose実行>問題なし

という感じの理想の挙動になりました。恐らくCastImageLoader.loadingが正しく動いていないのではないかな?と思います。

じっくり検証したいのだけど、納品前なので、とりあえず結果のみ。(ゴメンナサイ)

一応正常に動作するコードを書いておきます。
CODE:3

_loader = new CastImageLoader();
_loader.onCastLoadStart = function()
{
	trace("CastImageLoader::ロード開始");
	_output.text = "CAST_LOAD_START"
}
_loader.onCastLoadComplete = _loaded_Loader;
_loader.addEventListener(CastEvent.CAST_REMOVED, function() { trace("CastImageLoader::アンロードされました"); _output.text = "CAST_REMOVED" } );
・・・
_bt_cancel.onCastMouseDown = function()
{
	trace("CLOSE実行");
	if (_loader.contentLoaderInfo && _loader.contentLoaderInfo.bytesLoaded < _loader.contentLoaderInfo.bytesTotal)
	{
		_loader.close();
	}
	_loader.unload();
}
・・・
private function _loaded_Loader(e:Event=null):void
{
	trace("CastImageLoader::ロード完了");
	_output.text = "CAST_LOAD_COMPLETE"
	addChildAt(_loader,0);
}
とりあえずローカルでの挙動は誤動作だという前提の頭でガシガシ組んでいければよいけど、やっぱちょっと混乱しますね。これはProgressionの問題と言うよりはFlashにおけるLoader.closeの挙動の問題です。その辺理解して実装を進めていけば何とかなるかと・・。

ちょっと気になるのは、前にも書いたのだけど、closeを実行してサーバが反応するまでの時間にばらつきがあること。closeしているのにCOMPLETEイベントが発生するケースが稀にあります。その辺も考慮してリスナーの制御をしたほうが良いかもしれない。

add 2008/11/16 20:18
こっちのほうがスマートか・・・。

_bt_cancel.onCastMouseDown = function()
{
	trace("CLOSE実行");
	try
	{
		_loader.close();
	}
	catch (e)
	{
		trace(e);
	}
	_loader.unload();
}
事務所のエアコンの機嫌が悪くて寒いです。 今日も徹夜予定ですが、明け方の寒さは身にしみます。

1 Comment

コード部分CSSがしょっぱすぎて読みづらくてゴメンナサイ。
http://code.google.com/p/syntaxhighlighter/
とか導入したいんですが、苦手な分野なのでなかなか腰が上がりません・・・。

Leave a comment

Search and Archives