連休終わり。あんまり休みすぎは良くない。
IronRubyとSilverlightで上手く日本語表示してくれないのは、エントリポイントのファイル*1かBOM付きUTF-8という気持ち悪いファイルだとちゃんとUTF-8と認識してくれることがわかりました。
エントリポイントのファイルは強制的にUTF-8を仮定して読み込まれてしまうこと、BOM付きだとUTF-8だと強制的に認識することがポインヨ。ポインヨ。
これだとIronRubyにパッチ当てなくても日本語いけます。良かったね。まあ俺はパッチ当てて起動時オプション指定したけど。
DLR1.0のソースからSilverlight4用のChiron作ったらmonoで動かなくなっちゃった。どうも.NET4のランタイム使わないとちゃんと動かないらしい。.NET3.5用にビルドしたつもりなんだけどな。
IronRuby起動時にオプションを渡したいこともあるので、Chironは使わずC#のアプリ作ってそこからIronRubyを呼び出すことに。xap作成はAppManifest.xamlを用意しといてあとはzipで固めるだけなのでべつになんとでも。
しかしIronRubyを起動させるだけのアプリ作るのがまためんどい。まあ起動だけならそれほどでもないんだが、ファイル読み込みをxapから行なえるようにするとか、エラーをブラウザに表示できるようにするとかするとしんどいのよこれがもう。
Chiron使った時のエントリポイントであるMicrosoft.Scripting.Silverlightのクラスを継承すればいいかと思ったらそうでも無さげ。一部だけ使いまわせる作りになってねぇ…。このソースはちょっとひどい。
仕方ないので使いまわせそうなクラスは参照して使いまわし、そうでないところはコピペでちょっといじって使いまわすことにした。ライセンス読んでおかないとなー。
そんなわけで普通に起動できるようになった。頑張ればMacで動かしてWindowsでリモートデバッグも…あれ、VS2010 Expressにリモートデバッグ無くね?Professional貰えるのいつになるのかなー?
とか言ってたらVS2010 ProfessionalがExpression Professional Subscriptionでも貰えるようになってたよ。Expression Professional SubscriptionはVS2010もProだし*2、MSDNのProfessionalでは入ってないExpression Studioが当然ついてるからかなりおすすめ。個人で買うなら特に。
あとはUIをExpression Blend使って作ってxamlを動的に読み込んでみたり。 Silverlight Toolkitを使ったら読み込み時によくわからないエラーが。Styleプロパティが設定できないとか。なんでー?
どうも単に読み込むアセンブリが足りなかっただけらしい。それならそれっぽい例外投げて欲しい。
あるアセンブリが依存してるアセンブリは
monop -r:アセンブリ名 --refs
で表示できるようだ。あとmonoのコマンドリファレンスはなぜかAPIリファレンスのページにある。
ちと長くなったので分割。数日分の日記を溜めるからこうなる。
キャラクター選択画面と装備選択画面はそれなりに出来た。
IronRubyからだとDataBindingは自由に使えないのでSilverlightっぽくないUIのコードだが、まあそれでもかなり使いやすいので満足だ。
リストボックスにCheckBoxをつっこむのだけ苦労した。ItemTemplateを設定するとかなんとかのはずなんだが、テンプレートを作成してもBlend上でちゃんと表示されずに困ってた。が、ItemTemplateはItemsSourceを指定した時に生成される物だということ。なるほどね。
仕方ないのでここだけDataBindingを設定したんだが、あとで気付いたんだけど、ListBoxのItemsって何でも入るんだね。ItemsにCheckBoxをぶちこめばそれだけでも良かったのかもしれん。
SilverlightではDynamicObjectへのBindingはできないのでIronRubyではDataBindingができないんだけど、そこは配列を使ってインチキ回避。
##highlight ruby listbox.items_source = [ [true, 'foo'], [false, 'bar'], ]
こんな感じでソースに配列を指定してやる。
##highlight xml <CheckBox Content="{Binding [1]}" Value="{Binding [0]}" />
XAML側ではこんな感じでバインディングを指定してやると完成です。インデックス指定がなんともアレだが動くからまあいいや。
Silverlight4では[]内に文字列を指定しての文字列によるインデキシングってのが出来るっぽいんでHashでやってみたんだけど上手くいかず。IronRubyのHashはDictionary<object,object>のようなので、Dictionary<string,object>じゃないとダメなのかもしれない。やってみようかと思ったけどめんどいからやめた。
あとシェーダ書こうと思ったけどどうにも情報が少なくて苦労する。
弾の画像を1Pが撃った弾と2Pが撃った弾で変えてたんだけど、弾作る毎に1P用と2P用作って読み込んで…っていうのもなんだかなぁと思いまして動的にいろかえしようと思ったんですよ。
とりあえずは色乗算しながらビットマップ描画すればいいやと思ったら出来なさげ。ブレンディングも通常のアルファブレンドしかないわ…。
しかしピクセルシェーダを使えるのでこれで乗算しつつ描けばいいよね、と、やろうとしました。
サンプルがちょっとしょぼすぎて、シェーダにパラメータを渡す方法がわからんので調べると、DependencyPropertyというものを作ってやれば良さげ。ただこれはIronRubyから作るにはちょっと無理がありそう*1なのでC#でやった方が良さそうだ。
floatやサンプラの定数レジスタを設定することが出来るのは分かったんだがColorを渡したいんだよなぁ。Color型のプロパティが変更されたらrgba個別に作ったfloatプロパティにあらためて入れればいいんだろうか。めんどいな。
あとシェーダ使うと完全にソフトウェアレンダリングになってしまうようなので、沢山描く弾なんかではちょっと不安。でも一回色設定してWriteableに描画した弾画像をキャッシュしてつかえばいいか。あれ、シェーダの必要無くねえか?一回だけならWriteableBitmapのPixelsを直接操作でもいいのでは…。
ま、まあエフェクトにしておけば使いまわせるしね…。
*1 無理では無いかもしれないが、厳しそう…
ところでSilverlightのプラグイン、結構落ちるんだけどやばくないか?なんかミスったプログラム書くとブラウザごとプラグイン落としてくれてブラクラ完成ですよ。やったー。
IE8に至っては、落ちました→自動で復帰して再表示します→落ちました→再表示し…の無限ループ。おい、IE8のその動きもやばくねーか?落ちたページを自動で再表示しちゃまずいでしょ。やるにしても1回だけにしとけ。10.6のSafariはプラグインだけ死んでくれるのでダメージ少ない。
今までに落ちたのはReloaderみたいなの作って読み込んでるrbファイルを実行時に全部リロードした時と、初期化ミスってあるオブジェクトのinitializeから自分のクラスのnewを呼び出すような無限再帰しちゃったとき。
プラグインが落ちちゃうとデバッグしづらいんですよ*1。たのむぜMSさんよぉ。
*1 そういう問題ばかりで無い気もするが