以前からできないのかなと思っていて、
ちょっと調べたらできそうだったので調べてみた。
試した環境は Flex3 SDK です。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| package {
import flash.display.Sprite;
import flash.text.TextField;
import flash.utils.getDefinitionByName;
public class Hoge extends Sprite {
public function Hoge() {
var cls:Class = getDefinitionByName("flash.text.TextField") as Class;
var t:TextField = new cls();
t.text = "hoge";
t.y = 100;
addChild(t);
var t2:TextField = new TextField();
t2.text = "fuga";
addChild(t2);
}
}
} |
特に重要なのが8-9行目ですね。
これで動的にインスタンスを生成することができるみたいです。
getDefinitionByName便利ですね。
でもよく考えればできそうな気もせんでもないような。。。。
ま、できてなによりです。
参考資料
http://blog.isocchi.com/2007/12/flex-actionscript.html
http://www.fxug.net/modules/xhnewbb/viewtopic.php?topic_id=1241
——————————————————————————————–
追記: 2008/9/30 22:52
パフォーマンスがちょっと気になったのでベンチをとってみた。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
| package {
import flash.display.Sprite;
import flash.utils.getTimer;
import flash.utils.getDefinitionByName;
import org.libspark.utils.Dumper;
public class Generate extends Sprite{
private static const ROUND:uint = 50000;
public function Generate(){
bench(generate_new, "new");
bench(generate_class, "[new - class]");
}
private function generate_new():void{
for (var i:int = 0; i < ROUND; i++){ new Sprite(); }
}
private function generate_class():void{
for (var i:int = 0; i < ROUND; i++){
var cls:Class = getDefinitionByName("flash.display.Sprite") as Class;
new cls();
}
}
private function bench(func:Function, tag:String):void{
var start:uint = getTimer();
func();
trace((getTimer() - start) + "ms :" + tag);
}
}
} |
[64bitの結果]
330ms :new
659ms :[new - class]
355ms :new
658ms :[new - class]
[32bitの結果]
1285ms :new
1172ms :[new - class]
1285ms :new
1211ms :[new - class]
会社でも試した結果、おそらく32bitだと[new - class]の方がはやかった。
なぜだーーーーーと思って、家の64bit環境で試したら上記のような結果。
まぁ。。。納得?
できねーしw
どうも。久しぶりにエントリー書きます。
今回は compc を使って swc ファイルの作成を行います。
その際になんと、、、、
Class ファイルをすべてコマンドラインから指定してやらないといけないみたいなのです。
1
| compc compc -output [作成されるファイル名] -source-path [sourceのある場所] --include-classes [すべてのクラスファイル] |
これを実行すると swc ファイルを自分で作成することができます。
ただ何が問題かっていうと、
–include-classes にすべてのクラスファイルを指定しないといけないんです。
org.libspark.asreflect.errors.ASReflectError こんなフォーマットで。
これをファイルパスから取り出すのなんてめんどくさすぎる。
しかも / でなくて . 区切り。
というわけで、そこで perl の登場です。(※ここでは ASReflect を使用しています)
まず file だけを出力し、さらに .svn 以下のファイルを省きます。
1
| find -type f | grep -v svn |
この結果、出力される形式がこんな感じ
./org/libspark/asreflect/errors/ASReflectError.as
./org/libspark/asreflect/errors/NotFoundError.as
./org/libspark/asreflect/Method.as
./org/libspark/asreflect/Property.as
./org/libspark/asreflect/Parameter.as
./org/libspark/asreflect/Member.as
./org/libspark/asreflect/MetadataAware.as
./org/libspark/asreflect/Metadata.as
./org/libspark/asreflect/Type.as
./org/libspark/asreflect/ASReflect.as
./org/libspark/asreflect/TypeFactory.as
./org/libspark/asreflect/builders/BasicConstantHandler.as
./org/libspark/asreflect/builders/BasicTypeFactory.as
./org/libspark/asreflect/builders/BasicVariableHandler.as
./org/libspark/asreflect/builders/ImplementsInterfaceHandler.as
./org/libspark/asreflect/builders/ExtendsClass.as
./org/libspark/asreflect/builders/ImplementsInterface.as
./org/libspark/asreflect/builders/ParseContext.as
./org/libspark/asreflect/builders/BasicConstructorHandler.as
./org/libspark/asreflect/builders/BasicFactoryHandler.as
./org/libspark/asreflect/builders/ElementHandler.as
./org/libspark/asreflect/builders/BasicTypeHandler.as
./org/libspark/asreflect/builders/BasicAccessorHandler.as
./org/libspark/asreflect/builders/BasicParameterHandler.as
./org/libspark/asreflect/builders/BasicMethodHandler.as
./org/libspark/asreflect/builders/Arg.as
./org/libspark/asreflect/builders/BasicMetadataHandler.as
./org/libspark/asreflect/builders/ArgHandler.as
./org/libspark/asreflect/builders/XmlParser.as
./org/libspark/asreflect/builders/ExtendsClassHandler.as
./org/libspark/asreflect/impls/BasicType.as
./org/libspark/asreflect/impls/MetadataAwareSupport.as
./org/libspark/asreflect/impls/BasicMember.as
./org/libspark/asreflect/impls/BasicParameter.as
./org/libspark/asreflect/impls/BasicProperty.as
./org/libspark/asreflect/impls/BasicMetadata.as
./org/libspark/asreflect/impls/BasicMethod.as
これを整形します。
1. ./ を削除
2. .as を削除
3. / を . に変換
4. 空白区切りで連結して出力
この肯定を行えばいいわけです。
そこで登場するのが perl -p です。 perl -n でもいいです。
違いは改行あるかないか程度です。
これを使うことで
これと等価になるわけです。
つまりは、
1
2
3
4
5
6
7
8
| perl -ple 'chomp; s{\./}{};s{\.as$}{}s;s{/}{.}g';
whild(<>) {
chomp;
s{\./}{};
s{\.as$}{}s;
s{/}{.}g';
} |
ということですね。
簡単で便利です。
これでコマンドラインからの作業が軽減されました。
ちなみにこんなこともできるみたいです。
1
2
3
4
5
6
7
8
| perl -ple 'push @a, $_; }{ print @a;';
whild(<>) {
push @a, $_;
}
{
print @a;
} |
すげぇ~便利!!!
これで出力された値を –include-classes に指定して実行すれば
swc ファイルが生成されます。
これで毎度毎度の作業が楽になりそうです。
perl の特殊変数のメモ
$\ => printの末尾に出力される。 (perl -l だと “\n” のはず??)
$, => printを使った時のセパレータ
$” => リストコンテキスト変数展開をダブルクォートの中で行った時の区切り文字
$/ => ファイルハンドルからとってくる区切り文字
参考資料
特殊変数一覧
Perlコマンドラインオプション
昔にactionscriptの変数のスコープがfunctionスコープということを知らずに凄いハマったことがあって
それ以来は気をつけてはいたんですが、どうやらブロックスコープを実現できるみたいなので試してみた。
結論から言うと、withを使う。
actionscirpt1のころからwithの存在を知ってはいたけどコード量を短くする以外に使い道もわからなく
そんなに困ることもなく存在すら忘れ去れそうになっていましたw
でも、この子は非常に優秀です。できる子でした。
perlでいうlocalみたいなことができるんです。
素晴らしすぎます。今まで知らなかったことが残念で仕方ありません。
actionscript、javascript共に試したコードをつるしときます。
ver FlashIDE
1
2
3
4
5
6
7
8
9
10
11
| var hoge:Number = 8;
trace("default:" + hoge); // 8
(function():void {
var hoge:Number = 10;
trace("function:" + hoge); // 10
})();
with( {hoge:1} ) {
trace("with:" + hoge); // 1
} |
ver flex SDK(上のFlashIDEと対してかわりはありません。)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| package {
import flash.display.Sprite;
public class Hoge extends Sprite{
public function Hoge() {
var hoge:Number = 8;
trace("default:" + hoge); // 8
(function():void {
var hoge:Number = 10;
trace("function:" + hoge); // 10
})();
with( {hoge:1} ) {
trace("with:" + hoge); // 8 <- これがおかしい
}
}
}
} |
ver javascript
1
| (function(){var hoge=10;with({hoge:4}){alert(hoge);}alert(hoge);})(); // 4が表示され、次に10が表示される |
Flash IDEから使用した場合は問題なくブロックスコープが実現されています。
ただ、、、、
Flex SDKを使ってコンパイルする際には、withを使ってのブロックスコープが実現されません。
FlashPlayerのせいでもなさそうですし、おそらくはコンパイル時のSDKの実装によるものだと思います。
ちなみにSDKのバージョンはVersion 3.1.0 build 2710です。
普段はSDKをメインに開発してるので結局はfuncionを使っての方法でやるしかなさそう。。。
FlashDevelopも確かSDKのはずだからできないのかな??
windowsないんで試せる人いたら教えてほしーっす。
テンションあがったのになぁー
wiiFlashの接続があるswfをstandaloneのflashplayer(debug player)で起動すると
下記みたいなエラーが表示され起動しない。
1
2
3
4
5
6
| SecurityError: Error #2010: ローカルファイルシステムの SWF ファイルはソケットの使用が許可されません。
at flash.net::Socket/connect()
at WiiSocket/connect()
at org.wiiflash::Wiimote/connect()
at uranodai.display::Document()
at uranodai.slides::Slides() |
twitterにpostするとuranodaiさんが教えてくれた。
「Flash Playerのグローバルセキュリティのせいかも」と。
URLも教えてもらい試した結果、一時的にErrorはでなくなった。
正確にいうと、あるflash playerのバージョン(9.0.45.0)だとErrorがでない。ただし起動はするが実行されない。
それ以外だと上記のSecurityErrorがでる。
さっぱりわかんねー
どれか起動してくれたらいいのにな。
一応Flash IDEかAIRにすれば動いてるからいいけど、どーにかしてほしい。
ローカルのでは動かしたいな。ここも試したけど上手くいかず。
flash playerのセキュリティややこしいな。
誰か解決方法分かる人いれば教えて下さい。
uranodaiさんがsparkにコミットしたStreetviewを使って試してみた。
雑感だけど凄い便利にさわれた。
簡単にstreetviewをいじって遊べた。
んでwiiハンドルで操作するのは気になるのは何点かあるけど、
とりあえず形にはなった感じ。
あとは修正して問題なければ公開する予定。
ちなみに今回使用したconfigファイル。
(※)ソースは汚いのでおいおい公開します。
1
2
3
4
5
6
7
8
9
| <?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://ns.adobe.com/air/application/1.0">
<id>StreetViewWii</id>
<filename>StreetViewWii</filename>
<name>StreetViewWii</name>
<initialWindow>
<content>StreetViewWii.swf</content>
</initialWindow>
</application> |
公開証の作り方
1
| adt -certificate -cn SelfSigned 1024-RSA [証明書名] [パスワード] |
テスト
air用swf作成
airファイル作成
1
| adt -package -storetype pkcs12 -keystore [証明書名] [作成するairファイル名] [configファイル] [air化したいswfファイル] |
これでおk。
ちなみに全てFlex SDKでターミナルから叩いてやりました。
uranodaiさんどもっす!!