— boreal-kiss.com

Archive
Tag "Flex"

年の瀬なんで泣ける小話でも。

******

Flex Builder 3では、Flex Builder 3で作った各プロジェクトをFlex Builder 3から削除する際に二つオプションが選べる。

  • Flex Builderからプロジェクトの参照だけを削除し、ファイル自体はマシン内に残す(デフォルト)
  • Flex Bulderからプロジェクトの参照を削除し、さらにファイル自体もマシンから削除する(ゴミ箱に移動させるわけではなく、マシンから抹消する)

使用者が指定しない限り、前者の削除方法が選ばれる。しかし、例えばプロジェクト名を中途半端に間違えて作ってしまい、「あ、やべ、ミスった。消そ」とか、同じ名前のプロジェクトを作り直したい場合なんかは後者を選ぶ方が楽な場合がある。僕自身も面倒が少ないからという理由で後者の削除方法を使うことが少なからずあるのだけど、この後者がやばい。後者のファイル削除の範囲はプロジェクトと関係あるかないかに関わらずそのプロジェクトのディレクトリ配下全部だからである。以下実例。

Aさん(僕じゃないよ)の場合

Aさん(僕じゃないよ)は、普段Flex Builder 3のデフォルトのドキュメントディレクトリを使ってプロジェクトを作成していた。Macの場合だと

/Users/USERNAME/Documents/Flex Builder 3/

普通にFlex Builder 3を使っているとプロジェクトは全てこの階層配下に作成されるようになっている。(デフォルトの場所を使用するにチェックが入っており、他の場所へのプロジェクト作成がロックされた状態)。しかしそのときは、どうしてもローカルサイトでテストする必要があり、localhostにプロジェクト(PROJECT_JP)を作成した。

/Users/Username/Sites/PROJECT_JP/src/
/Users/Username/Sites/PROJECT_JP/bin-debug/
/Users/Username/Sites/PROJECT_JP/bin-release/

かくしてPROJECT_JPは完成したが、PROJECT_JPをローカライズしたもの(PROJECT_EN)を作成する必要があった。同様にしてローカルサイトにプロジェクトを作成するが、普段デフォルトのFlex Builder 3ディレクトリしか使っていなかったため、思わぬミスを犯す。一階層上をプロジェクトディレクトリにしてしまったのだ(つまりSites)。PROJECT_ENの内容は以下のようになった(PROJECT_EN内にPROJECT_JPが混在した状態)。

Aさん(僕じゃないよ)が予定していたディレクトリ構造

/Users/Username/Sites/PROJECT_EN/src/
/Users/Username/Sites/PROJECT_EN/bin-debug/
/Users/Username/Sites/PROJECT_EN/bin-release/
/Users/Username/Sites/PROJECT_JP/src/
/Users/Username/Sites/PROJECT_JP/bin-debug/
/Users/Username/Sites/PROJECT_JP/bin-release/

実際に作ったディレクトリ構造

/Users/Username/Sites/src/
/Users/Username/Sites/bin-debug/
/Users/Username/Sites/bin-release/
/Users/Username/Sites/PROJECT_JP/src/
/Users/Username/Sites/PROJECT_JP/bin-debug/
/Users/Username/Sites/PROJECT_JP/bin-release/

Sitesをプロジェクトのトップディレクトリに設定しているにもかかわらず、Flex Builder 3上ではこのプロジェクトディレクトリは”PROJECT_EN”と表示される点がポイント。Flex Builder 3のデフォルトのドキュメントディレクトリ配下のプロジェクトでは、Flex Builder 3上のプロジェクトフォルダ名とマシン上のフォルダ名は必ず一致するが、デフォルトではない場所にプロジェクトを作成した場合必ずしも両者は一致しない。

すぐに作成場所のミスに気づいたAさん(僕じゃないよ)は、PROJECT_ENを削除して作り直そうとした。その際横着をして前述の「プロジェクトの参照を削除し、なおかつファイルをマシンから抹消する」方法をとった。つまり「Flex Builder 3上でPROJECT_ENと表示されているプロジェクトの参照を削除し、さらにそのプロジェクトファイルをマシンから抹消する」方法をとったのである。その結果プロジェクトはたしかにマシンから削除され、以下のような構造になった。Sites配下には何も残っていない。っておい。

/Users/Username/Sites/

PROJECT_ENは正しく削除されたが、PROJECT_EN配下に存在していたPROJECTも跡形もなく削除されたわけだ。幸いPROJECT_JPのバックアップは前日にとってあったが、一日分の作業が跡形も無く抹消されたわけである。さらにローカルサイトという特別な場所に作成したのが災いした。ローカルサイトには今回とは無関係なフォルダが多数あったのである。例えば

/Users/Username/Sites/phpMyAdmin/

など。これらも同様に跡形も無く消去された。

教訓

今後は以下を死んでも遵守する、とAさん(僕じゃないよ)は言っている。

  1. Flex Builder 3のプロジェクトは可能な限りデフォルトのドキュメントディレクトリを使う
  2. 不要なプロジェクトは参照だけを削除する。実際のファイル削除は面倒でも手動で行う
  3. バックアップは頻繁に行う。そのためにコミット回数が増えても気にしない

ちなみにマシンルートに作ったFlexプロジェクトの完全削除とかどうなるのだろう。マシン破壊?誰か試してみて。トラウマになりそうでできんわ。

Read More

どちらも同じ出版社の本だけど対照的。

  • Adobe Air in Action
    Adobe Air in Action

    AIRの良書。Flash, Flexに慣れ親しんだ人がAIRについてのみ知りたい場合などに最適。逆にFlashの知識が全くない状態でAIRをやってみようという場合には解読不能かも。Window, File system, Drag-and drop, SQLiteなど、AIR特有の機能に内容を絞っていて、しかもかなり原理的なところから説明しているので好感度が高い(FileStreamの進行状況を視覚化してあったり)。難点を挙げるとすると、これは出版社MANNINGの問題なんだけど、ここの本のレイアウト、文字スタイルが無駄に凝ってたり見出しごとにフォントかえてたりして見づらいんだよね。目がチカチカするっていうか。O’Reillyはそのへんさすがだと思う。

    » レーダーチャート評点

  • Flexible Rails: Flex 3 on Rails 2
    Flexible Rails: Flex 3 on Rails 2

    Flex + Rails。2008年に購入した本の中でぶっちぎり独走状態のクソ本。扱っている内容はFlex, Railsとも実践的で高度なのだが(Flex 3, Rails 2.0, RubyAMF, Cairngormなどを一緒に扱っている本はたぶん世の中にこれしかない)、著者の文章力がお粗末。自分の挙げた質問に脱線しまくったあげく見当違いな答えが書いてあったりして愕然とさせられる。要所要所でかいま見られる「この本への著者の愛」も読んでて非常に気持ち悪い。「TVゲームが超絶うまい小学生に書かかせたゲーム攻略本の文章」っていうとイメージ湧くかな。この本のせいで出版社のMANNINGのイメージがよろしくなくなった。

    » レーダーチャート評点

Read More

ローカルから画像をロードしたらそれっぽく陰影を付けて立体的に見せてくれるアプリケーション。気に入ったタイミングでスナップショットボタンを押せばそのときの状態の画像がローカルマシンに保存されます。タイミング難しいけど。

» Tube3D (要Flash Player 10)

Read More

[Flash] パワースペクトル
» [Flash] パワースペクトル (SWF) (要Flash Player 10、音注意)
» ソースコード

Flash Player 10から音を生成できるようになったのでそのテスト。単周期のサイン波を生成してそのパワースペクトルをSoundMixer.computeSpectrum()で表示。ダイナミックサウンドについては情報がまちまちなので完全には理解できていない。が、Saqoosha.net :: SoundMixer.computeSpectrum の FFT モードの周波数帯に書いてあるように0-11kHzの範囲でスペクトルが表示されているので結果はおかしくない、と思う。スペクトルに幅がでちゃってるのは生成されたサウンドに問題があるのかフーリエ変換の精度に問題あるのか不明。

Read More

これは知らないとはまる。Filereferenceオブジェクトへの参照をローカル変数の受け渡しで扱っている場合注意が必要。ローカル変数のみを使用する場合ロードが中断される可能性がある。Flash Player 10 (Astro)のAPIはまだ日本語になっていないようだったので以下を引用するが同じことがFilereference.load()にもあてはまる。

FileReference オブジェクトがスコープ外に移動した場合、そのオブジェクトに対して完了していないアップロードまたはダウンロードは、スコープから離れた時点でキャンセルされます。アップロードまたはダウンロードの続行を期待できる限りは、FileReference オブジェクトがスコープ内にあることを確認してください。

Adobe® Flex™ 3 リファレンスガイド

以下にFileRefarence.load()が正しく完了する場合と完了しない場合の二種類の例を挙げる。どちらも”Load”ボタンを押すとローカルから画像を選択できるようになり、画像を選択するとステージにその画像が表示されるという構造になっている。両者の違いはFilereferenceオブジェクトを扱う変数がローカル変数のみかそうではないかだけである。

FileReference.load()が成功する場合

FileReferenceオブジェクト変数をクラスプロパティで定義しているため(_fr)クラスファイル内でFilereferenceオブジェクトのスコープがはずれることはない。そのためボタンクリックでローカルから選択された画像はFileReference.load()で正しくロードされキャンバス(_canvas)に表示される。

<!-- FileReference.load()が正しく完了する例 -->
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    
    <mx:Button label="Load" click="onClick(event)"/>
    <mx:Canvas id="_canvas"/>

    <mx:Script>
        <![CDATA[
            import flash.net.FileReference;
            
            //クラスプロパティとして定義
            private var _fr:FileReference;
            
            private function setListeners(target:FileReference):void{
                var fr:FileReference = target as FileReference;
                fr.addEventListener(Event.SELECT,onSelect);
                fr.addEventListener(Event.COMPLETE,onComplete);
            }
            
            private function onClick(e:Event):void{
                _fr = new FileReference();
                setListeners(_fr);
                _fr.browse();
            }
            
            //関数を抜けてもFileReferenceオブジェクトへの参照"_fr"はスコープ内
            //そのため関数を抜けてもFileReference.load()は続行される
            private function onSelect(e:Event):void{
                var fr:FileReference = e.target as FileReference;
                fr.load();
            }
            
            private function onComplete(e:Event):void{
                var fr:FileReference = e.target as FileReference;
                var loader:Loader = new Loader();
                loader.loadBytes(fr.data);
                loader.contentLoaderInfo.addEventListener(Event.INIT,onInit);
            }
            
            private function onInit(e:Event):void{
                _canvas.rawChildren.addChild(e.target.content);
            }
        ]]>
    </mx:Script>
</mx:Application>

FileReference.load()が失敗する場合

一方、以下の場合FileReferenceオブジェクト変数はローカル変数でしか定義されておらず、Filereferenceオブジェクトのスコープが完全にはずれる箇所がある(onSelect()を抜けた直後)。その時点でFileReference.load()はキャンセルされるためロード完了によるEvent.COMPLETEが発動しない(_canvasに画像が表示されまでに至らない)。

<!-- FileReference.load()が途中でキャンセルされる例 -->
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    
    <mx:Button label="Load" click="onClick(event)"/>
    <mx:Canvas id="_canvas"/>

    <mx:Script>
        <![CDATA[
            import flash.net.FileReference;
            
            private function setListeners(target:FileReference):void{
                var fr:FileReference = target as FileReference;
                fr.addEventListener(Event.SELECT,onSelect);
                fr.addEventListener(Event.COMPLETE,onComplete);
            }
            
            private function onClick(e:Event):void{
                //ローカル変数として定義
                var fr:FileReference = new FileReference();
                setListeners(fr);
                fr.browse();
            }
            
            //関数を抜けるとFileReferenceオブジェクトへの参照がスコープ外になる
            //そのため関数を抜けるとFileReference.load()は完了前にキャンセルされる
            private function onSelect(e:Event):void{
                trace(e);
                var fr:FileReference = e.target as FileReference;
                fr.load();
            }
            
            private function onComplete(e:Event):void{
                var fr:FileReference = e.target as FileReference;
                var loader:Loader = new Loader();
                loader.loadBytes(fr.data);
                loader.contentLoaderInfo.addEventListener(Event.INIT,onInit);
            }
            
            private function onInit(e:Event):void{
                _canvas.rawChildren.addChild(e.target.content);
            }
        ]]>
    </mx:Script>
</mx:Application>
Read More

ASDoc in MXML – Flex SDK – Confluenceによると、Flex SDK 4 (Gumbo)からmxmlコンポーネントにもASDocが書ける。

(注意: 正確にはASDocのnew versionで使えるようになるとしか記載されていないが、Flex 3.1で出力できず、Flex 4で実際に出力できたという理由から上記のようなタイトルにした。Flex 4より前に使えるようになる可能性はある)

mxml内でのASDoc記法は通常のmxmlコメントアウトの先頭の"<!–"にマイナス記号をもう1コ(計3コ)付け加えるだけ。

<!-- 通常のmxml内のコメントアウト -->
<!--- mxml内のASDocコメント -->

以下の例ではクラス(VBox)へのコメント、クラス内のコンポーネント(Button)へのコメント、Scriptタグ内の通常のASDocコメントがASDocとして出力される(Flex SDK4.0.0.3280で出力確認済)。マイナス記号が繋がってしまってて見づらいけど先頭側は3コある。

<?xml version="1.0" encoding="utf-8"?>
<!---
    ASDoc for the Class
    @see http://opensource.adobe.com/wiki/display/flexsdk/ASDoc+in+MXML
-->
<mx:VBox xmlns="http://ns.adobe.com/mxml/2009" xmlns:mx="library:adobe/flex/halo">
    <!--- 
        ASDoc for the Button below
    -->
    <mx:Button label="Test" click="onClick(event)"/>
    
     <Script>
        <![CDATA[
            /** 
             * ASDoc for the following public function
             * @param e flash.events.Event
             */
            public function onClick(e:Event):void{
                trace(e);
            }   
        ]]>
    </Script>
</mx:VBox>

重要なのはmxタグのネームスペースが変更されている点。

<!-- Flex SDK 3 -->
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml">

<!-- Flex SDK 4 -->
<mx:VBox xmlns="http://ns.adobe.com/mxml/2009" xmlns:mx="library:adobe/flex/halo">

そのため<mx:Metadata>や<mx:Script>の記法も変更されている。

<!-- Flex SDK 3 -->
<mx:Metadata>, <mx:Script>

<!-- Flex SDK 4 -->
<Metadata>, <Script>

このへんの記法はFlex 4が開発段階なので今後どうなるかわからないが、mxmlでもASDoc出力できるようになるのは開発側としてはうれしい。

Read More

SimpleLogger update

[AIR] SimpleLogger ver. 1.07

  • mxパッケージ専用のクライアントSimpleLoggerMx.asを追加。
  • オートアップデート機能を追加。

Alertのデザイン変更ではまった。どうもAlert内部のボタンのデザインはAlertのプロパティbuttonStyleNameを変更してやらないといけないらしい(デフォルトはbuttonStyleName=”alertButtonStyle”)。上記の場合だと

/* alert_desin.css */

Alert{
    buttonStyleName: "alertButton";
    fontWeight: normal;   
    color: #FFFFFF;
    backgroundColor: #101010;
    borderStyle: solid;
    cornerRadius: 4;
}

.alertButton{
    textRollOverColor: #00FF00;
    color: #FFFFFF;
    themeColor: #00FF00;
    fillColors: #101010, #101010;
    borderColor : #101010;
    highlightAlphas: 0.0, 0.0;
    cornerRadius: 4;
    fontWeight: normal;
}

という設定にしてやってmxmlに埋め込んである。

<mx:Style source="alert_design.css" />

コンポーネントのCSSデザインはadobe – Flex 2 Style Explorerを使った。コンポーネントのデザインを動的に変更でき、変更したスタイル情報がその場にCSSとして表示されるので便利。

Read More
  • The Essential Guide to Open Source Flash Development (The Essential Guide)

    The Essential Guide to Open Source Flash Development (The Essential Guide)

    Flash本。ネットで断片的に情報を集めるとえらい時間がかかりそうな膨大な数のオープンソースプロジェクトを一カ所に集めてレビュー(ほとんどは紹介のみだがワクワクさせられる)しているすごい本。しかもそれぞれのプロジェクトの責任者のような人が執筆しているのがよい点で俄然信頼性がでてくる。内容が無茶苦茶濃いので全部読めてないけど、AMFPHPとデバッグツールに関するレビュー部分は役立った。haXeが気になった。前半5章ぐらいを同じ人が執筆しているのだけど、何故かActionScript 2と3を(断りなしに)混在させて説明していくスタイルなのでよみづらい。Papervision3Dは10ページほどしか説明されていない。こんな中途半端にページ割くぐらいならなくてもいいんじゃない。あとTweenerじゃなくてFuseってのが紹介されてる。Tweenerにしろよ!

    総合ポイント

  • Foundation Flex for Developers: Data-Driven Applications with PHP, ASP.NET, ColdFusion, and LCDS (Foundation)

    Foundation Flex for Developers: Data-Driven Applications with PHP, ASP.NET, ColdFusion, and LCDS (Foundation)

    Flex本。名前の通りFlexとその他とのデータ通信、という部分に重点を置いている。HTTPService(URLLoadrと違うところ)やRemoteObject、サーバー側の各技術についてそれぞれ章を設けて過不足なく説明している。本の半分は各サーバーサイド技術のケーススタディなので中々貴重な本なんじゃないかな。RemoteObjectに必要なconfigファイルが何なのか説明がなく残念(今だに理解できておらず)。Ruby(Rails)との連携が全然書いてないのも残念無念。

    総合ポイント

  • Creating Mashups with Adobe Flex and AIR (Friends of Ed Abobe Learning Library)

    Creating Mashups with Adobe Flex and AIR (Friends of Ed Abobe Learning Library)

    Flex + AIR本。マッシュアップされる側(Twitter, Amazon, etc.)のAPIの説明に重点が置かれていて、ActionScriptはできて当たり前という感じ。扱っている内容は高度だと思う。同時に3コのAPIを盛り込んで(1コずつやれよ!)モリモリコーディングしていくけどスクリプトの説明はおかまいなしというスタイルで、重要なところが見えにくく教本としてはあまり好きになれない。後半、結構なページ量AIRに割かれていて、それは役立った。特にFlexからAIRに移行する際のつまずきそうな箇所に重点が置かれている(ウィンドウと***-app.xmlについて等)。

    総合ポイント

    Twitterクライアントの作成例の図に日本人の方の発言がでかでかと掲載されてて超おもろい。本の著者は絶対理解してないだろうけど。

    ****: エロゲはよくわからんな。
    *******: 靴脱がしちゃらめええええええええ

    (Creating Mashups p.212 Figure 10-4より)

Read More

サーバーから受信したxmlデータをActionScript Objectで受信したとき、格納したArrayCollection (Array)の構造を簡単に調べたいというのがそもそもの目的。いくつかあたってみたのでその簡単な使い方と個人的な感想を書き留める。Flex 3でしか確認していないので、Flashの場合は少し勝手が違うかもしれません。結論を先に言うと、Xray, ThunderBolt, Arthropodの中で目的を達成できたのはXrayのみ。個人的に気に入ったのはArthropod。

調べたこと

以下のようなxmlデータをHTTPServiceのレスポンスとして受け取りArrayCollectionに格納したとき、ネストした内容(id, name)がLoggingツールで見れるかどうか確認。

<?xml version="1.0" encoding="utf-8"?>

<users>
    <user>
        <id>1</id>
        <name>Chris Allen</name>
    </user>
    <user>
        <id>2</id>
        <name>Wade Arnold</name>
    </user>
    <user>
        <id>3</id>
        <name>Aral Balkan</name>
    </user>
    <user>
        <id>4</id>
        <name>Nicolas Cannasse</name>
    </user>
</users>

1. Xray

生のArrayCollectionの中身は見えなかったが、ArrayUtil.toArray()を用いて受信データをArrayCollection -> Arrayに変換すれば確認可能。ツール自体の機能で、ステージ上のオブジェクト全てのプロパティを丸見えにすることができ、さらにプロパティをXrayコンソールから動的にいじることができるのが便利。フレームレートがリアルタイムに確認できるので、例えば予定以下のパフォーマンスだった場合に、ボトルネックになる箇所を探せる可能性がある(アルファをいじったら改善された etc.)。難点は超不安定なところ。専用コンソール(.swf)がやたらと落ちる(起動中に止まる)。Macを再起動しないと再生できないような状態になることもしばしばで、使うのがためらわれる。現在開発進行中ではないことも理由かもしれない。

使い方

  1. osflash-xray – Google Code > Downloads > Xray_Flex2_Library_v0.5.swc をダウンロード(コネクター)。Flex3と名のつくものはなくてこれが最新バージョンになっている。
  2. Xray ( The AdminTool ) Open Source Flash > Downloads > Interfaceよりコンソールをダウンロード(SWF Onlyと書かれたもの)。これを使ってモニターすることになる。
  3. Flexプロジェクトにswcファイルにパスを通す。
    import com.blitzagency.xray.inspector.flex2.Flex2Xray;
    import com.blitzagency.xray.logger.XrayLog;

    をインポートし、それぞれのインスタンスを作成して、swfファイルを起動(例えばmyFlexと命名)。

    var xray:Flex2Xray = new Flex2Xray();
    var log:XrayLog = new XrayLog();
  4. Xrayコンソール(Xray.swf)を起動して左側のGoボタンを押すと調べたいswfファイルのモニタリングを開始する。
  5. myFlex内の調べたいオブジェクトに例えば以下のような処理を(myFlex内で)施すことでXray.swfコンソールで中身を確認できる。
    //ac is ArrayCollection receiving the xml data
    var ary:Array = ArrayUtil.toArray(ac);
    log.debug("Nested arrays:", ary);

Xray

2. Arthropod

シンプルでコンパクトで見た目もこぎれいなAIR製Logger。利用方法も簡単なので非常に良いと思うけど、目的は達成できず。ArrayColection、ArrayCollectionをArray変換したもの、ネストしたArrayともに視覚化できなかった。今回は結局何にもできなかったけど、個人的にはオススメ。

使い方

  1. Arthropod > DownloadよりASソース(1ファイル)とコンソール本体(.air)をダウンロード
  2. Flexプロジェクト(myFlex)にソースをインポート。
    import com.carlcalderon.arthropod.Debug;
  3. myFlex内の調べたいオブジェクトに以下のような処理を施し、myFlex.swfを起動するとArthropod.airで中身をモニターすることができる。Logging用のインスタンスを作らなくてよいところが便利。
    //ac is ArrayCollection receiving the xml data
    var ary:Array = ArrayUtil.toArray(ac);
    Debug.array(ary);
  4. 他にもいくつかユーティリティがあるがそれほど多くなく、長ったらしいドキュメンテーションもない。

Arthropod

3. ThunderBolt

Arthropodと同じくモニターはair製で、Flash Playerが吐くFlashlog.txtをモニターする作りになっている。ArrayCollection、ArrayCollectionをArray化したものの視覚化はできなかったが、例えば以下のようにネストしたArrayの中身は確認できた。

var ary:Array = [{id:"1",name:"Chris Allen"}, 
                {id:"2",name:"Wade Arnold"}, 
                {id:"3",name:"Aral Balkan"},
                {id:"4",name:"Nicolas Cannasse"}];

ただ、僕の目的は達成できておらず、さらに起動までの設定が少し面倒、モニターが無駄にでかい、なんか見た目がダサイというところが使う気を起こさせない。

使い方

設定についてはFlashのログ閲覧アプリThunderBoltをいれてみた|_level0.CUPPYが詳しいのでそちらを参照ください。少し補足しておくと、Flash PlayerにFlashlog.txt (Macの場合、/Users/USERNAME/Library/Preferences/Macromedia/Flash Player/Logs/flashlog.txt)というログファイルを吐き出させる設定が必要で、そのためには”/Users/USERNAME/mm.cfg”に以下の記述をする必要がある。

TraceOutputFileEnable=1

ThunderBolt

Read More

Railsからの応答をE4Xで受信した場合とAMFで受信した場合を比較した。使ったのはidとnameからなる1000行のMySQLデータ。Flexからリクエストしてから応答までの時間を測定したところ、AMFの方が5倍も遅くなって困惑した。環境はFlex SDK 3.0, Ruby 1.8.6, Rails 2.1, MySQL 5.0.45で全て同じローカルマシン内。

Rails側

RubyAMFをインストールしたRailsプロジェクト内にUserモデルとUsersControllerを作成。UserモデルはMySQLのusersテーブル(id, name)とシンクロ済み(テストデータはgeneratedata.comで作成)。UsersControllerに以下のようにindexを記述。

class UsersController < ApplicationController

  def index
    @users = User.find(:all)    
    respond_to do |format|
      format.xml {render :xml => @users} # For HTTPService
      format.amf {render :amf => @users} # For RemoteObject
    end
  end
end

AMFの結果をArrayCollectionで簡単に受け取れるようrubyamf_config.rbを一部修正。ただしこの設定はRemoteObjectに対して有効で、NetConnectionではArrayCollectionが使えないため無効。

require 'app/configuration'
module RubyAMF
  module Configuration
    ClassMappings.assume_types = true
    ClassMappings.use_array_collection = true
  end
end

Flex側 (HTTPService – E4X)

load()とonResult()までの時間を10回測った。測定時間はTextAreaに、受信内容はDataGridにそれぞれ表示。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

    <mx:HBox width="100%" height="100%">
        <mx:DataGrid id="dg" width="50%" height="100%">
            <mx:columns>
                <mx:DataGridColumn dataField="id"/>
                <mx:DataGridColumn dataField="name"/>
            </mx:columns>
        </mx:DataGrid>
        <mx:TextArea id="loadText" width="50%" height="100%"/>
    </mx:HBox>  
    <mx:Button label="Load" width="100" height="30" click="load(event)" />

    <mx:Script>
        <![CDATA[
            import mx.rpc.http.HTTPService;
            import mx.rpc.events.ResultEvent;
            import mx.rpc.events.FaultEvent;
            import flash.utils.getTimer;
            
            private var _start:uint;
            private var _str:String = "";
            
            private function load(e:Event):void{
                var req:HTTPService = new HTTPService();
                req.url = "http://127.0.0.1:3000/users.xml";
                req.resultFormat = HTTPService.RESULT_FORMAT_E4X;
                req.send();
                req.addEventListener(ResultEvent.RESULT,onResult);
                req.addEventListener(FaultEvent.FAULT,onFault);
                _start = getTimer();    
            }
            
            private function onResult(e:ResultEvent):void{
                dg.dataProvider = e.target.lastResult.user;
                _str += (getTimer() - _start).toString() + " msec\n";
                loadText.text = _str;
            }
            
            private function onFault(e:FaultEvent):void{
                loadText.text = e.fault.faultDetail;
            }
        ]]>
    </mx:Script>
</mx:Application>

Flex側 (RemoteObject – AMF)

MXMLの骨格はHTTPServiceを使う場合と同じ。スクリプト部分とservices-config.xmlの設定は以下の通り。

スクリプト部分

<mx:Script>
    <![CDATA[
        import mx.rpc.remoting.RemoteObject;
        import mx.rpc.events.ResultEvent;
        import mx.rpc.events.FaultEvent;
        import flash.utils.getTimer;
        
        private var _start:uint;
        private var _str:String = "";
        
        private function load(e:Event):void{
            var ro:RemoteObject = new RemoteObject();
            ro.source = "UsersController";
            ro.destination = "rubyamf";
            ro.index();
            ro.addEventListener(ResultEvent.RESULT,onResult);
            ro.addEventListener(FaultEvent.FAULT,onFault);
            _start = getTimer();
        }
        
        private function onResult(e:ResultEvent):void{
            dg.dataProvider = e.result;
            _str += (getTimer() - _start).toString() + " msec\n";
            loadText.text = _str;
        }
        
        private function onFault(e:FaultEvent):void{
            loadText.text = e.fault.faultString;
        }
    ]]>
</mx:Script>

services-config.xml (コンパイラオプションに追加)

<?xml version="1.0" encoding="UTF-8"?>
<services-config>
    <services>
        <service id="remoting-service" 
            class="flex.messaging.services.RemotingService" 
            messageTypes="flex.messaging.messages.RemotingMessage">
            <destination id="rubyamf">
                <channels>
                    <channel ref="ch-rubyamf" />
                </channels>
                <properties>
                    <source>*</source>
                </properties>
            </destination>
        </service>
    </services>
    
    <channels>
        <channel-definition id="ch-rubyamf" 
            class="mx.messaging.channels.AMFChannel">
            <endpoint uri="http://127.0.0.1:3000/rubyamf/gateway" 
                class="flex.messaging.endpoints.AMFEndpoint" />
        </channel-definition>
    </channels>
</services-config>

結果

HTTPService – E4X

load()からonResult()までの時間測定は右テキストエリア内(msec)。10回測定でだいたい0.5-0.6秒。ちなみにRESULT_FORMAT_OBJECT(ActionScript Object)で受信すると0.7-0.8秒ぐらいだった。

RemoteObject – AMF

HTTPServiceの場合と同じ測定で一回あたり約3秒。

AMF、通信設定が面倒なくせにすげー遅い。Ajax and Flex Data Loading Benchmarks | James Ward – RIA Cowboyの結果と違いすぎる。どっか間違ってる?

Read More