Data::AMF 0.03

| | Save This Page to del.icio.us このエントリーを含むはてなブックマーク

すっかりご無沙汰してしまいました。
書く習慣がなくなると駄目ですね。

というわけで、Data::AMF 0.03 がリリースされました。
http://search.cpan.org/dist/Data-AMF/

このバージョンから AMF3 がサポートされました。

あと、Data::AMF::Remoting というのが追加されていて、
NetConnection を使った Flash Remoting と、Flex の RemoteObject
を使った Flex RPC が簡単に出来るようになりました。

Plack でゲートウェイを実装するとこんな感じです。

use Data::AMF::Remoting;
use Plack::Request;
use UNIVERSAL::require;

sub
{
    my $env = shift;
    my $req = Plack::Request->new($env);
    my $res = $req->new_response(200);
	
    if ($req->path =~ /\/amf\/gateway$/)
    {
        my $remoting = Data::AMF::Remoting->new(
            source => $req->raw_body,
            message_did_process => sub
            {
                my $message = shift;
                my ($class_name, $method) = split '\.', $message->target_uri;
                $class_name->require;
                my $controller = $class_name->new;
                return $controller->$method($message->value);
            }
        );
        $remoting->run;
		
        $res->content_type('application/x-amf');
        $res->body($remoting->data);
    }
	
    return $res->finalize;
};

source に POSTデータを渡して、message_did_process というハンドラで、
メッセージ毎に処理しています。ヘッダー用には別途 header_did_process という
ハンドラが用意されています。

$message->target_uri に、Controller.method という形式の文字列が渡ってくるので、
これを使ってディスパッチします。

$message->value は Perl オブジェクトにデシリアライズされた引数です。


コントローラクラスの方は MooseX::Declare を使うと良い感じに書けます。

use MooseX::Declare;

class HelloController
{
    method echo(Str $text)
    {
        return $text;
    }
}


Flex 側はこんな感じです。

<mx:RemoteObject id="helloService"
    endpoint="http://localhost:5000/amf/gateway"
    destination="perlamf"
    source="HelloController"
    showBusyCursor="true"
    result="trace(event.result)"
    fault="trace(event.fault.faultDetail)"
/>
<mx:Button label="Hello" click="helloService.echo('Hello, world!')" />

destication は特に使われないのですが、空にするとランタイムエラーになるので、
適当に書いておきます。

source がサーバー側のクラス名になります。

これでボタンがクリックされると、HelloController クラスの echo メソッドが
コールされます。

Progression で Flex アプリケーションを作る

| | Save This Page to del.icio.us このエントリーを含むはてなブックマーク

Progression を使って Flex アプリケーションを作る場合、
自分ならどんな風に書くかな?と思って試してみました。

サンプル
ソース

--
まず、Progression と Flex を共存させるための基本的な考え方は、
コントローラを Progression で、ビューを Flex で書く、ということになります。

これを踏まえた、アーキテクチャは以下のようになります。

 
・View (MXML)

View は MXML で書きます。逆に考えると、MXML で書いた部分が View です。したがって、基本的に MXML にはビジュアルコンポーネントしか書きません。

・Delegate

Application、ItemRenderer など、View を生成するところで Flex の作法に逆らえないところは、View を操作するロジックを非ビジュアルコンポーネントとして View に記述します。Delegate は、後述する ViewController とは別のものになります。通常、View が ViewController を保持/参照することはありません。

・ViewController (Cast)

Progression の CastObject クラスを継承し、View オブジェクトを保持します。View の操作とイベントハンドリングを記述します。

・Scene

Progression の Scene です。Scene 毎に必要になる Model や View を生成し、それらを用いて ViewController を生成します。また、必要となるリソースは都度 Command を用いて取得し、生成した Model で処理/保持します。

・Service (Command)

外部サービスとの連携には Progression の Command を使います。これらの Command の生成と実行は、Scene が行います。

・Model

Model は ViewController の単位で生成します。ViewController が Model の値を View に適用します。値を保持する役割の他に、サービスから取得した値をデコードする処理なども担います。

--
次に、処理の流れを具体的に見て行きましょう。

1. ProgressionSample.mxml

Flex フレームワークを使う場合、メインクラスは Application クラス (MXML) になります。Application クラスは Flex のコンテナなので、直接 MXML を使って View を構築することも出来ますが、前述したアーキテクチャに従うために、ProgressionSampleDelegate コンポーネントのみが記述されています。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
	xmlns:mx="http://www.adobe.com/2006/mxml"
	xmlns:local="*"
	layout="absolute"
	viewSourceURL="srcview/index.html"
>
	<mx:Style source="ProgressionSample.css" />
	<local:ProgressionSampleDelegate />
</mx:Application>

2. ProgressionSampleDelegate

ProgressionSample の FlexEvent.INITIALIZE イベントで ProgressionSampleDelegate の initialize() が呼ばれます。initialize() が呼ばれるまでの処理は、親クラスの ApplicationDelegate に隠蔽しています。initialize() で Progression インスタンスを生成し、ここからの処理の流れは Progression に委ねます。

public class ProgressionSampleDelegate extends ApplicationDelegate
{
	public var view:ProgressionSample;
	
	override protected function initialize():void
	{
		SWFWheel.initialize(view.systemManager.stage);
		FilterShortcuts.init();
		
		var progression:Progression = new Progression("main", view.systemManager.stage, MainScene);
		progression.sync = true;
		progression.autoLock = false;
		progression.goto(progression.firstSceneId);	
	}
	
}

3. MainScene

MainScene は Page1Scene と Page2Scene を生成し、さらに Header/Navigation/Contents の View と ViewController を生成しています。スタティックなコンテンツなので難しいところは特にないと思います。これらは onLoad で Application に AddChild されます。さらに、onInit で Page1Scene に Goto するようになっています。

public function MainScene(initObject:Object = null)
{
	super("main", initObject);
	
	addScene(new Page1Scene());
	addScene(new Page2Scene());
	
	application = Application.application as Application;
	
	header = new HeaderController(null, new Header());
	navigation = new NavigationController(null, new Navigation());
	contents = new ContentsController(null, new Contents());
}
override protected function _onInit():void
{
	addCommand(
		new Goto(getSceneAt(0).sceneId)
	);
}

override protected function _onLoad():void
{
	addCommand(
		[
			new AddChild(application, header),
			new AddChild(application, navigation),
			new AddChild(application, contents)
		]
	);
}

4. Page1Scene

Page1Scene では、PageModel と Page1 を生成し、Page1Controller を生成しています。onLoad で外部 XML を読んで、PageModel に渡し、それから Contents に View1Controller を AddChild しています。

public function Page1Scene(initObject:Object = null)
{
	super("page1", initObject);
	
	addScene(new Page1DetailScene());

	controller = new Page1Controller(new PageModel(), new Page1());
}

public var controller:Page1Controller;

override protected function _onLoad():void
{
	addCommand(
		new LoadURL(new URLRequest("assets/data.en.xml")),
		
		function ():void
		{
			controller.model.parse(this.previous.data);
		},
		
		new AddChild(MainScene(parent).contents.view, controller)
	);
}

override protected function _onUnload():void
{
	addCommand(
		new RemoveChild(MainScene(parent).contents.view, controller)
	);
}

5. Page1Controller

Page1Controller は view プロパティに Page1 オブジェクトを保持しています。view の表示アニメーションを DoTweener コマンドで定義し、さらに view.dataGrid の MouseEvent.DOUBLE_CLICK イベントをハンドリングしています。データグリッドがダブルクリックされると、Page1DetailScene がダイナミックに生成する Scene に Goto しています。

public var model:PageModel;
public var view:Page1;

override protected function _onCastAdded():void
{
	view.alpha = 0;
	
	view.dataGrid.dataProvider = model.words;
	view.dataGrid.addEventListener(MouseEvent.DOUBLE_CLICK, dataGridDoubleClickHandler);
	
	addCommand(
		new DoTweener(
			view,
			{
				_Blur_blurX : .1,
				_Blur_blurY : .1,
				alpha: 1,
				time: 1
			}
		)
	);
}

override protected function _onCastRemoved():void
{
	view.dataGrid.removeEventListener(MouseEvent.DOUBLE_CLICK, dataGridDoubleClickHandler);
	
	addCommand(
		new DoTweener(
			view,
			{
				_Blur_blurX : .1,
				_Blur_blurY : .1,
				_Blur_quality : 3,
				alpha: 0,
				time: 1
			}
		)
	);
}

private function dataGridDoubleClickHandler(event:MouseEvent):void
{	
	new Goto(new SceneId("/main/page1/detail/" + view.dataGrid.selectedItem.@id)).execute();
}

6. Page1DetailScene

Page1DetailScene は通過専用の Scene で、ここで目的地となる Scene をダイナミックに生成しながら、遷移しています。この辺りは muraken さんの記事 を多いに参考(と言うより、ほぼそのまま...)にさせていただきました。遷移が終わったら、View を持たない Controller を生成し、Alert.show() でモーダルウィンドウを表示させています。

public function Page1DetailScene()
{
	super("detail");
	
	controller = new Page1DetailController();
}

public var controller:Page1DetailController;

override protected function _onLoad():void
{
	super._onLoad();
	
	var parentController:Page1Controller = Page1Scene(parent).controller;
	var item:XML = parentController.model.getItemById(current.name);
		
	controller.show(item, parentController.view);
}
public function show(item:XML, target:Sprite):void
{
	if (item == null)
		Alert.show("Couldn't find.", "Error", 4, target, closeHandler);
	else
		Alert.show(item.@value, "No." + item.@id, 4, target, closeHandler);		
}

private function closeHandler(event:CloseEvent):void
{
	new Goto(new SceneId('/main/page1')).execute()
}

--
基本的な流れは以上です。

DataGrid の DataGridColumn に無駄に豪華な ItemRenderer を当てていますが、ItemRenderer と ItemRendererDelegate はこんな具合に書くよ、というサンプルのつもりで敢えてそうしてあります。

html-template は Flex Builder でデプロイするのに最適なようにカスタマイズしてあります。

--
以下は余談ですが、今回の検証で本格的な Flex アプリケーションを Progression を使って実装出来ることがわかりました。

Flex フレームワークはページ管理、状態管理といった部分の機能が非常に貧弱なので、大規模な開発を管理するのが難しいという側面があります。それを補うために、Cairngorm や PureMVC といった Flex アプリケーション向けのフレームワークが開発されていますが、Progression もそれらと比較しても遜色はないと思いました。

特に Scene という概念が秀逸で、Scene が Facade になって内部の MVC を隠蔽してくれるため、Scene 単位でアプリケーションを分けることが出来ます。Scene 毎に分散して開発することで、大規模な開発もしやすいと思いました。

さらに余談ですが、MXML に非ビジュアルコンポーネントを記述することは、Flash Professional でタイムラインにスクリプトを書くのと同じ感覚なので、実際のプロジェクトでは使用されていないスタイルだと思います。

個人的には Cocoa + Interface Builder のように、View に相当する部分は GUI で構築してしまって、中のソースコードは意識しなくて済むように隠蔽されている、というのが案外望ましいのかな、と思っているので、Flash Catalyst + Flash Builder の開発はそこを目指して欲しいなと思っています。残念ながら Beta から汲み取れる雰囲気ではそうなっていないようですが...。

ActionScript でコマンドラインツールを作る方法

| | Save This Page to del.icio.us このエントリーを含むはてなブックマーク

Flex SDK に含まれる AIR 開発用の adl コマンドを使って、ActionScript で簡単なコマンドラインツールが作れることに気が付きました。

コンソールに Hello, world! と引数の中身を適当に出力するツールは、こんな感じで実装出来ます。

コマンドラインツールなので、最後に exit() を呼んでやる必要があります。
引数は InvokeEvent 経由で受け取るようになっています。

// hello.as
package {
	import flash.desktop.NativeApplication;
	import flash.display.Sprite;
	import flash.events.InvokeEvent;

	import mx.utils.ObjectUtil;

	public class hello extends Sprite
	{
		public function hello()
		{
			NativeApplication.nativeApplication.addEventListener(InvokeEvent.INVOKE, initialize);
		}
		
		private function initialize(event:InvokeEvent):void
		{
			trace("--------------------------------------------------------------------------------");
			trace("Hello, world!");
			trace("");
			
			// コマンドライン引数を受け取る
			var args:Array = event.arguments;
			
			trace(ObjectUtil.toString(args));
			
			trace("");
			NativeApplication.nativeApplication.exit();	
		}
	}
}

// hello-app.xml
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://ns.adobe.com/air/application/1.5">
	<id>HelloASCommandLineTool</id>
	<filename>hello</filename>
	<name>hello</name>
	<version>v1</version>
	<initialWindow>
		<content>hello.swf</content>
	</initialWindow>
</application>

後は、これを適当に amxmlc でコンパイルし、adl で実行するだけです。

% amxmlc -output hello.swf hello.as
Loading configuration file /Applications/Adobe Flex Builder 3/sdks/3.2.0/frameworks/air-config.xml
hello.swf (14304 bytes)

% adl hello-app.xml -- Hoge Fuga "`pwd`"
--------------------------------------------------------------------------------
Hello, world!

(Array)#0
  [0] "Hoge"
  [1] "Fuga"
  [2] "/Users/yoshizu/Desktop/ASCLTool"

ちなみに、trace ログの出力は、mm.cfg で flashlog.txt に書き込まれるようにしている場合は、flashlog.txt に向きます。mm.cfg 作っていない場合は、そのままコンソールに出力されます。

ただ、このままだと hello-app.xml を置いているディレクトリを使う時にいちいち意識しないといけないので、簡単なラッパーとなるシェルスクリプトを作っておいて、パスが通る場所に置いておくと便利です。

今回は、ホームディレクトリ以下にこんな構成で配置しました。

bin
  |- as
  |- astools
      |- hello
          |- hello.as
          |- hello-app.xml
          |- hello.swf

#!/bin/sh

if [ ${1:-0} = 0 ]
then
	echo "usage: % as hello"
	exit
fi

path=${0%/*}

adl ${path}/astools/${1}/${1}-app.xml -- $2 $3 $4 $5 $6 $7 $8 $9

exit

すると、こんな風にどこからでも叩けるようになりました。

% as hello Hoge Fuga "`pwd`"
--------------------------------------------------------------------------------
Hello, world!

(Array)#0
  [0] "Hoge"
  [1] "Fuga"
  [2] "/Users/yoshizu/Desktop"

違うツールを作った時にも、astools 以下に放り込んでおけば、as コマンドは共通して使えるので便利です。

--
追記 (2009.05.15)

mm.cfg で trace が flashlog.txt にいってしまう人は、一時的に mm.cfg の中身を書き換えてあげるとコンソールに trace が表示されるようになります。

#!/bin/sh

function replace
{
	sed -e $1 $2 > $3
	mv $3 $2
	return 0;
}

mm=${HOME}/mm.cfg
path=${0%/*}

if [ ${1:-0} = 0 ]
then
	echo "usage: % as hello"
	exit
fi

replace "s/^\(.*\)=1$/\1=0/g" $mm ${path}/as-tmp

adl ${path}/astools/${1}/${1}-app.xml -- $2 $3 $4 $5 $6 $7 $8 $9

replace "s/^\(.*\)=0$/\1=1/g" $mm ${path}/as-tmp

exit

SWFSound (Draft)

| | Save This Page to del.icio.us このエントリーを含むはてなブックマーク

Adobe MAX Japan 2009 への参加を通じて、
たくさんの発見とインスピレーションを得ることが出来たので、
もう少しコミュニティに貢献していきたいなと思いまして、
新しくサウンド系のライブラリを作ろうと思います。

Spark project の音系ライブラリと言えば sazameki がありますが、
充実した機能を持っている反面、音を鳴らすまでに必要な手続きが少し長いので、
プログラムに不慣れな人にとっては少し敷居が高いように思えました。

そこで、もっと手軽に音を鳴らすことが出来るライブラリを作ろうと思いました。

手軽に使えるという部分を意識するようになったのは、
Spark project の TeraFire から大きなインスピレーションを得たからです。

TeraFire は、new して addChild することで炎を作ることが出来ますが、
SWFSound は、new して play するだけで音が鳴らすことが出来ます。

var instrument:Instrument = new Instrument();
instrument.play();

音程や音量や音の長さも気軽に変えることが出来ます。

// 音程を変える
instrument.noteNumber = 60; // 0 〜 127 の MIDI ナンバーでで音程を決める
instrument.frequency = 440; // 周波数で音程を決める

// 音量を変える
instrument.volume = 0.8; // 0  〜 1.0 の範囲の値

// 音の長さを変える
instrument.lentgth = 3.0; // 単位は秒

音色は IPreset を実装したクラスのインスタンスを与えることで変えられます。
豊富なプリセットを用意する予定です。

// ピコピコな音にします
var preset:IPreset = new PicoPico();
instrument.preset = preset;

プリセットを微調整することも出来ますし、全く新しく作ることも出来ます。

// オシレータをサイン波にする
preset.oscillator1 = new Sinewave();

// ADSR エンベロープを調整する (0 〜 1.0 の範囲の値)
preset.attack = 0.8;
preset.decay = 1.0;
preset.sustain = 0.4;
preset.release = 0.6;

// 新しくプリセットを作る
var customPreset:IPreset = new Preset();
customPreset. oscillator1 = new SquareWave();
customPreset. oscillator2 = new Noise();
customPreset.attack = 0;
customPreset.decay = 1.0;
customPreset.sustain = 0;
customPreset.release = 0;

また、楽器をいくつか組み合わせたキットを作ることも出来ます。
デフォルトでも、DrumKit や WebSiteKit などを搭載する予定です。

// ドラムキット
var drums:IKit = new DrumKit();
drums.play(0); // キック
drums.play(1); // スネア
drums.cymbal.play(); // シンバル
drums.closeHighHat.play(); // クローズハイハット

// ウェブサイト用の音を集めたキット
var website:IKit = new WebSiteKit();
website.click.play(); // クリック
website.rollover.play(); // ロールオーバー
website.rollout.play(); // ロールアウト

もちろん、新しくキットを作ることも出来ます。

// 汎用的なキット
var kit:IKit = new Kit();
kit.addInstrument(instrument1);
kit.addInstrument(instrument2);
kit.play(0);

エフェクトも使えます。

// エフェクトを作る
var effect:IEffect = new Delay();

// 楽器に適用
instrument.addEffect(effect);

// プリセットに適用
preset.addEffect(effect);

// キットに適用
kit.addEffect(effect);

楽器、プリセット、キットという単位で好きなようにカスタマイズ出来るので、
ユーザーにたくさんの音色を作ってもらって、どんどん公開してもらうのが狙いです。

さらにおまけとして、Ambient Music Generator の開発を通じて得たノウハウを元に、
スケールを定義するクラスを同梱しようと思います。

// スケールを作る
var scale:IScale = new MajorScale();
scale.rootkey = 5; キーを E に変更

// 音程の範囲を制限する
scale.min = 40; // 最小値
scale.max = 80; // 最大値

// 作ったスケールを使ってランダムに鳴らす
var noteNumber:int = scale.notes[Math.random() * scale.numNotes];
instrument.noteNumber = noteNumber;
instrument.play();

これらを Timer とかで適当に回したりすると、自動作曲っぽいことが出来ます。

というようなライブラリを絶賛開発中です。
公開予定は今春として濁しておきたいと思います...。

要望などございましたらどしどしお寄せ下さい!

yoshizu [ at ] s2factory.co.jp
twitter.com/seagirl

Wonderfl ワンダフル!

| | Save This Page to del.icio.us このエントリーを含むはてなブックマーク

KAYAC さんの新しいサービス Wonderfl がおもしろいです。

ブラウザで書いた AS3 コードが即座にコンパイルされてプレビュー出来るといったサービスみたいです。

まだベータテスト中(?)らしいのですが、すでに Twitter 界隈の ASer たちが続々とコードを投稿しています。

嬉しいのが、Flash Player 10 に対応した Flex SDK でコンパイルしているっぽくて、
Dynamic Sound Generation とかも普通に動いてます。

さらに外部ライブラリもすでにいくつか組み込まれており、Thread とか Tweener などが使えます。

というわけで、僕もいくつか投稿してみました。

1. Dynamic Sound Generation
http://wonderfl.kayac.com/code/8b17ddb1ce4c73ebe8165c95d30f208bd393d037

2. BitmapFilter
http://wonderfl.kayac.com/code/b9c68bf8505c61b9b617dade4491ee8d2b3b98f

Ambient Music Generator 1.2

| | Save This Page to del.icio.us このエントリーを含むはてなブックマーク

Picture 2.png

Ambient Music Generator 1.2 をリリースしました。
http://seagirl.jp/ambient/ambient.air

主な変更点は、新たにビジュアル表現を追加したことと、全体的なアルゴリズムの見直しによるパフォーマンスの向上です。

なお、バージョンアップに伴って、AGF ファイルのフォーマットが新しくなったため、古いバージョンのファイルを開く事が出来なくなっています。

ある音階の周波数の求める式

| | Save This Page to del.icio.us このエントリーを含むはてなブックマーク

AS3 である音階の周波数の求める式

var midiNumber:int = 0;
var frequency:Number = 440 * Math.pow(2, (midiNumber - 69) / 12);

(参考)MIDI Number と音階の対応表
http://www.phys.unsw.edu.au/jw/notes.htm

ある MIDI Number の周波数をぱっと知りたい時の Perl ワンライナー

% perl -e 'printf "%.03f", 440 * (2 ** ((0 - 69) / 12))'
8.176

Ambient Music Generator

| | Save This Page to del.icio.us このエントリーを含むはてなブックマーク

capture_001.png

Spark project 勉強会 #05 で Ambient Music Generator という AIR アプリケーションのデモをさせていただきました。

今回の勉強会のお題が「Flash Player 10 の新しい機能を使った何か」だったので、Dynamic Sound Generation を使ったアプリケーションを何か作れないか、というのが動機でした。

新機能を使っている点としては、他にも Vector や AIR 1.5 から SDK に組み込まれた Adobe AIR Update Framework など。


Ambient Music Generator は、アンビエント・ミュージックを動的に生成するためのツールです。次に鳴らす音をダイナミックに変化させていくという点では楽器とも言えますし、自動的に音が生成され続けるという点では、BGM マシンとも言えます。

仕組みとしては、リズムや音程にある程度の制約を与えた中で、ランダムに音を選択していくことで、音楽らしさをなるべく損なわない形で、音を生成するようになっています。

制約に関しては、スケール、キー、音の間隔、音量といったパラメータで与えていて、これらを GUI で操作出来るようにしています。その他にプログラムにハードコーディングしてあるパラメータがいくつかあります。

今後の課題としては、音色を増やしたり、アルゴリズムを増やしたり、絵を見せたりすることが考えられますが、目指している方向として「簡単にそれらしい音楽を生成するツール」というのがあるので、そこはバランスを取りながら考えたいです。


Ambient Music Generator
http://seagirl.jp/ambient/ambient.air
(予め Adobe AIR をインストールする必要があります)

AMF と Perl について

| | Save This Page to del.icio.us このエントリーを含むはてなブックマーク

Flex や Flash で言うところの「Remoting」を行いたい場合、
サーバー側を Perl で実装しようとすると、どんな手段があるでしょうか。

古くから CPAN に存在するのは、AMF::Perl というモジュールです。
これは、AMFPHP からの移植されたモジュールらしいのですが、
残念ながら 2004 年でメンテナンスが止まってしまっていることで、
なかなか使いにくいという状況でした。

そんななか、先日 Data::AMF という新しいモジュールが CPAN
登録されている気付いたので、これを試してみることにしました。

そして試してみる中で色々わかったことがあったのでまとめてみようと思います。

Genius Framework Version 1.3.0

| | Save This Page to del.icio.us このエントリーを含むはてなブックマーク

先日に引き続き、Genius Framework Version 1.3.0 をリリースしました。

ロードマップなどは前回と変わっていません。
Version 1.5.0 へ向けて、着々と開発が進んでおります。

各ドキュメントやサンプルも 1.3.0 に対応したものに更新してあります。
詳しくはプロジェクトページを参照して下さい。

http://www.libspark.org/wiki/seagirl/genius

以下、前回からの差分を記します。

Genius Framework Version 1.2.0

| | Save This Page to del.icio.us このエントリーを含むはてなブックマーク

Genius Framework 1.2.0 をリリースしました。

いつの間にか branches が出来ていたので、
今回 trunk と tags を作って、既存のファイルは全て trunk に移しました。

今後のロードマップとしては、
7月22日に行われる Spark project 勉強会 #01 を目処に
Version 1.5.0 をリリースし、これを安定版として、
tags にスナップショットを置く予定です。

それまでは、trunk の方が変わりやすい状況が続くと思いますので、
ご注意下さい。

Version 1.0.0 からの主な変更点をまとめておきます。

コンポーネントの初期化フロー

| | Save This Page to del.icio.us このエントリーを含むはてなブックマーク

今回は Flex におけるコンポーネントの初期化フローについて、
ソースを追いながら内部でどんなことが起きているのかを調べたので、
わかったことをまとめてみたいと思います。

誤解しやすいところなので、確認しておくと、
ここでの「コンポーネント」はビジュアルコンポーネント
呼ばれているものを指してします。

さらに、コンポーネントは大きく分けて2つに分類されます。
一つは、Label クラスのように、UIComponent を直接継承しているものです。
もう一つは、Canvas クラスのように、Container クラスを継承しているものです。

実際には、Container は UIComponent のサブクラスなので、
Container も UIComponent になるのですが、
ここでは UIComponet を直接継承しているか、
Container を挟んで継承しているか、を区別しています。

そして、前者を「コントロール」、後者を「コンテナ」と呼びたいと思います。

前置きが長くなりましたが、本題に入ります。

Adobe AIR Update Framework

| | Save This Page to del.icio.us このエントリーを含むはてなブックマーク

Adobe Labs にて Adobe AIR Update Framework がベータリリースされています。
http://labs.adobe.com/wiki/index.php/AdobeAIRUpdate_Framework

AIR アプリケーションをアップデートするための Framework みたいです。

Genius にも同じ目的で作ったクラスがあるのですが、
こういうクラスがもう少し早く出てきてくれていれば、
わざわざ自前で作る必要もなかったのにな、と。。。

元々何でないのだろうというところだったので、
そのうち出るんじゃないかなとは思っていたのですが。

ところでサンプルコードを見ていておっと思ったのですが、
ADF から情報を取得するのに、XML のネームスペースの扱いが
知らないと難しいのですが、XML クラスのnamespaceメソッドを使うと、
こんな風に書けるのねというのを今さら知ったので書いておきます。

private function setApplicationNameAndVersion():void {
    var appXML:XML = NativeApplication.nativeApplication.applicationDescriptor;
    var ns:Namespace = appXML.namespace();
    lblAppVersion.text = appXML.ns::version;
    lblAppName.text = appXML.ns::name;
}

Tamarinと戯れてみる

| | Save This Page to del.icio.us このエントリーを含むはてなブックマーク

Tamarinとは

 Tamarinプロジェクト
 Adobe Flash Player 9に組み込まれているAVM2(Adobe ActionScript Vitual Machine)のソースコードがAdobeからMozillaに寄付された。Mozillaはこのコードをオープンソースプロジェクトとしてホストすることになりました。そのプロジェクト名をTamarinといいます。Tamarinプロジェクトの目標は「言語仕様 ECMAScript 第 4 版 (ES4) を、パフォーマンスの高い、オープンソースのコードとして実装すること」とされています。


AVMPlus

 Tamarinプロジェクトのソースコードをビルドすると、AVMPlusというVMとガベージコレクタ(MMgc)のライブラリを作り、avmplusというコマンドを手に入れることが出来ます。今回はこのavmplusを使って遊んでみたよ、というお話です。

Genius Framework 1.0.0

| | Save This Page to del.icio.us このエントリーを含むはてなブックマーク

Genius Framework Version 1.0.0
http://www.libspark.org/browser/as3/GeniusFramework

兼ねてから自分用に作って使っていたFlex用のフレームワークを
Spark projectのリポジトリにコミットしました。

ひとまず簡単な紹介を書いておきます。
詳しい紹介や使い方はまた追ってポストしていこうと思います。

E4Xのフィルタ演算子

| | Save This Page to del.icio.us このエントリーを含むはてなブックマーク

 社内メーリングリストにポストしたら中々好評だったのでblogにまとめてみます。

 E4Xにはフィルタ演算をする演算子として丸括弧があって、それを使うと、簡単に検索やフィルタリングが出来ます。

 詳しくはこの辺りを参考に Core JavaScript 1.5 Guide:Processing XML with E4X

 このこと自体は結構有名なので、知っている人や活用している人も多いかと思いますが、今回はこんな使い方もあるよというのを紹介してみます。

AIRアプリでOS側からのドラッグ&ドロップを受け付ける方法

| | Save This Page to del.icio.us このエントリーを含むはてなブックマーク

 またしてもAIRネタです。ハイペースで情報を詰め込むと忘れやすいので、覚えているうちにネタ毎にまとめてblogに投げておくと、後々自分にとっても役に立ちそうなので書いてしまいます。

 さてさて、今回はMacのFinderやWindowsのExplorerのから直接ファイルをAIRアプリにドラッグ&ドロップして渡すためのAPIの使い方です。

AIRアプリで特定のファイルフォーマットのファイルを開く方法

| | Save This Page to del.icio.us このエントリーを含むはてなブックマーク

 社内でアルファチャンネル付きのFLVを開くアプリケーションはないかと聞かれ、よく考えたらそういうアプリケーションが見当たらないことに気付きました。

 FLVならばFlashで開けるだろう、ということでAdobe AIRを使って「FLV Player」を社内向けに作ることにしました。

 ローカルアプリなんだから、普通にFLVファイルをダブルクリックして開いた時にこの「FLV Player」で開けないものかな、と思って調べたら出来たのでまとめておきます。

Dateクラスのコンストラクタの引数

| | Save This Page to del.icio.us このエントリーを含むはてなブックマーク

 Dateクラスのコンストラクタの第一引数(yearOrTimevalue)に渡すことが出来る値のフォーマットについて調べてみました。

 結論から書くと、ある程度のフォーマットならば適当に解釈してくれました。

AIRアプリの起動時の位置

| | Save This Page to del.icio.us このエントリーを含むはてなブックマーク

 いきなり脱線しますが、Adobe AIRで作られたアプリケーションは何と呼べば良いのでしょうか。とりあえずAIRアプリと呼ぶことにしましたが、どうもわかりずらいですね。

 というわけで、AIRアプリの起動時の位置について社内で質問を受けたのでまとめておこうと思います。