疲れがとれにゃい。
Catalyst11.12でOpenGL 4.2対応というので入れてみたら確かに4.2になった。そりゃそうだ。しかしグラボも挿してないのでA8-3850とかいうCPUに内蔵されてるGPUでGL4.2ですよ。なんかすげーな。最近グラフィック関係いじってもないので宝の持ち腐れですが。
うーん、しかしちょっとまたグラフィックスもいじりたくなってきたな。グラフィックスというよりげーむえんじん作りたい。IronRubyとOpenTKでGLES2のラップをしたものまでは作ったからそれのOpenGL版を作りたかったんだが、MacBookでだらりとやろうとしたらmonoでIronRubyが動きやしないので諦めたんだった。IronRubyじゃなくてJRubyとJoglの方がいろいろといいんだろうな。でもできればIronRubyの方を贔屓にしたい。JRubyはメジャーだからな。メジャーなもの使ってもおもしろくないだろ!
Joglに手を出しづらいのはパッケージが多すぎてよくわからんのもある。これは一回設定すりゃ大したこともないだろうが。
HTMLベースのUIを作成中。
テンプレートの適用もできて特に問題なく動いた。テンプレートを適用するにあたってファイルの文字コードをどう判別しようかとちょっと悩んだが、UTF-8決め打ちで問題もあるまい。
テンプレートエンジンはDotLiquidを使った。トップページが綺麗だからドキュメントとかわかりやすそうと選んだんだが、綺麗なのはトップページだけだった。残念ながらドキュメントが弱くて最初にちょっと手間取ったが、文法以外はそう複雑なものでもないのでちょっとソースを見たらだいたいわかる。文法はRuby版Liquidのページにある。
はまったのはテンプレート適用時に参照できる変数として適当なオブジェクトを渡したら文句言われるところ。HashとかICollectionとかならそのままアクセスできるんだけど、それ以外の普通のオブジェクトだと組み込み型かILiquidizableを実装した型じゃないとだめだぞと怒られてしまう。仕方ないのでILiquidizableを実装したラッパクラスを作って渡してやろうとするんだが、ILiquidizableはObjectを返すToLiquidメソッドだけを持っていて、さてこいつは何を返したものかと。
適当にプロパティに数値や文字列やコレクションのみを持つ匿名オブジェクトを作って返してやったら上手くいったのでそれで良かったらしい。おそらく最初から匿名オブジェクトを渡すのでもいけたんじゃないかとも思うが詳しく見てないし、登録したいオブジェクトがけっこう多くて匿名オブジェクトの生成は遅延したかったのでこれでいいだろう。
あとは表示したい物をまとめたりHTML書いたりしてみてそこそこできた。表示のみ。UIというからには表示だけじゃなくて操作もできないといけないんだが、そっちはさっぱり書いてねぇわ。
今まで通りのGUIもあるので自分でデバッグがてら使ってたんだが、しばらくしてから操作したらオブジェクトにアクセスできない的な例外が。接続が切れたとかなんとか。そういやUIとコア部分はAppDomainを分けてたので同一プロセス内ではあるもののリモート扱いなんだった。しかしリモート扱いとはいえ同一プロセス内、接続が切れるとかありえねぇ。
原因はなんとなく分かってて、リモート先に渡したオブジェクトは適当な時間で貸し出し期限切れになってしまうって奴だろう。回避するにはMarshalByRefObjectを継承してるクラスでInitializeLifeTimeServiceメソッドをオーバーライドしてnullを返してやればいい。nullを返すと無期限にしてくれるんだとさ。やったー。
いやいやちょっと待て。本当に無期限にしていいものか考え物だな。今まで考えてなかったが、リモート先に公開したオブジェクトがクライアントからいまだに参照されてるかどうかってのは分からないんじゃないか?参照されてるかどうかわからんということはGCしていいかどうかわからん。そこで貸し出し期限てのを設けて、期限が切れたらもうリモート先から参照されてないんじゃねーということになっているわけだ。となると期限を無期限にすると一生GCされなくなっちゃう。なんでもかんでも無期限にしちゃだめだなこりゃー。シングルトン的などっちにしろいつまでも生きてるような物だけが無期限にしていい奴か。
ちゃんと調べてみるとクライアント側でまだ使ってたら適宜延長してやるとか、何かメソッドが呼ばれたら自動延長するとかいう方法が取れるようだ。どっちにしてもめんどい。後者は比較的簡単そうだがUIに使うには向いてないな。ユーザの操作によってアクセスされるから間隔は結構あるし。
よく考えてみるとAppDomainをUIとコアで分けたのはUI部分をASP.NETをホストしてやろうとしたからで、ASP.NETのホストを諦めた今となっては分けることに必須じゃない。分かれてたほうがUIの動的アンロードとかできてちょっとかっこいいよねーというのはあるけど、ちょっとかっこいい代償がUI作るのめんどいになるのは高くついてませんかね。UIの動的アンロードなんてしないし!
そんなわけでとりあえずAppDomainは分けない方向に戻そうかと。あちこちにMarshalByRefObjectをつけまくったのが無駄になるなぁ。でも今後コア部分だけサービス化しようとかへんなこと考えた時に使えるかもしんない……ってその時はその時にまた考えたほうがいいだろうな。一旦消すか。