« おならを空中で止める技術が開発される | Home | hulu »

Mar 152008

外部swfのクラスを親swfから使う。

もともとBGMで使用するサウンドファイルがでかいので、共有ライブラリにして外部に持たせておこうと思ったのが始まり。で、AS2はもうパッケージにしていたのだけど、AS3でどーやって実装しようかと色々試しているうちに、別に共有書き出しとかしなくっても普通に共有できた。(昔からだっけ?忘れた)
昔は一度タイムライン上に出現(これはMovieClipを作って1フレ目でstop&visible=falseにして、それ以降のタイムラインにサウンドを割り当てて、とかやるアタッチ系プリローダーの手法ね)させないとattachも出来無かったと思うのだけど(違う方法があったらゴメン)、それすらもしなくて良いと言う、超お手軽になっていた。大量の外部ファイルでの連携を必要とするコンテンツには便利だ。

ということでメモ。

肝のクラスは
flash.system.ApplicationDomain;
flash.system.LoaderContext;
の二つ。

たとえば外部SWFに埋め込んだサウンドクラスを引っ張り出したいときは

var shareLoader:Loader = new Loader();
var shareURLreq:URLRequest = new URLRequest(aURL);
var context:LoaderContext = new LoaderContext();
context.applicationDomain = ApplicationDomain.currentDomain;
shareLoader.load(shareURLreq, context);
で、あとはEvent.COMPLETE発動後にそのクラスを引っ張り出してやれば良い。 (音の処理のところは面倒なので書かない。) これと同じ手法で、イメージ、ムービークリップインスタンス、クラス等も利用可能だと思う。 ただし注意点としては同じクラスが重複しないようにすること。(同じクラスが存在する場合オーバーライドはされないけど、子供のクラスは使えない)

* All code in a SWF file is defined to exist in an application domain. The current domain is where your main application runs. The system domain contains all application domains, including the current domain, which means that it contains all Flash Player classes. * All application domains, except the system domain, have an associated parent domain. The parent domain for your main application's application domain is the system domain. Loaded classes are defined only when their parent doesn't already define them. You cannot override a loaded class definition with a newer definition.

ちなみにこんなことも出来る。

Usage C: Use the parent's class definitions by creating a new child domain of the current domain. The application domain of module3.swf is a child of the current domain, and the child uses the parent's versions of all classes. One use of this technique might be a module of a multiple-screen rich Internet application (RIA), loaded as a child of the main application, that uses the main application's types. If you can ensure that all classes are always updated to be backward compatible, and that the loading application is always newer than the things it loads, the children will use the parent versions. Having a new application domain also allows you to unload all the class definitions for garbage collection, if you can ensure that you do not continue to have references to the child SWF.

This technique lets loaded modules share the loader's singleton objects and static class members.

The following code creates a new child domain of the current domain:

request.url = "module3.swf";
request.applicationDomain = new ApplicationDomain(ApplicationDomain.currentDomain);

これは検証してないのであれだけど、外部ファイルがクラスを持たずともクラスを叩けるということか?これできると運用系がとっても楽になる。暇になったら検証しておきたい。SWF間をつなぐproxyのような働きをする連結クラスがいらないんだー。ワクワク。

一応念のため、ここで言われているdomainはアプリケーションドメインのこと。

Application domain: A mechanism for separating classes used in different SWF files, so that if the SWF files include different classes with the same name, the classes don't overwrite each other.

これ。

HTTPドメインが異なるクロスドメインスクリプティングの場合はこれとは別の問題で、Security.allowDomain()、LoaderContext.securityDomainとかになります。
as3ではやったこと無いので詳しくはしらないけどas2のときとそんなに変わってなさそうでです。

ちなみにas2のころ外部のmp3ファイルをloadしてloopさせると途切れるっつー現象があったけど、あれは解決したのだろうか?その辺検証する余裕が無いのでいきなりこの手法に走ったのだけど・・。

ただまぁmp3ファイルそのままよりはswfに入れたほうがファイルサイズが小さいか?
いや知らんけど。
mp3のビットレートを直接変えたことが無いので分からん。
CBRならいいけど、VBRとかだとプレイヤーの負荷も上がりそうじゃないですかー。
いや、それも知らんけど。

1 Comment

と言うことで、一旦デザインの方の作業にシフト。

Leave a comment

Search and Archives