メッセージループの別スレッド化

Ruby1.9以降、スレッドはネイティブスレッドとなった。
DirectX9ではウィンドウを作ったスレッドとDirect3Dを初期化・Reset・Releaseするスレッドは同じでないといけないという制限がある。DXRubyではrequire'dxruby'した時点で内部的にウィンドウを生成し、Window.loopやWindow.createはそれを実行した時点でResetを発行するので、これらのスレッドは同じでなければならない。
つまり、以下のコードが動かない。

require 'dxruby'

image = Image.new(100,100,C_WHITE)

Thread.new do
  Window.loop do
    Window.draw(0,0,image)
    break if Input.key_push?(K_ESCAPE)
  end
end.join

このように描画系を別スレッドにするようなプログラムは恐らくそれなりに真面目に作られたツール系であろうと思われる。DXRubyはツール系のものを作るには向かないのではないかと作者的には思うのだが、そのようなことをしようと思う人がいるのであれば動くに越したことはない。使いにくいヽ(`Д´)ノって言われるんだろうけども。
んで、手元のDXRuby1.5.1devではウィンドウの生成やDirectXの初期化・終了・Reset、メッセージループなど一連の処理を別スレッドに逃がした。初の内部マルチスレッド化、日本政府にさきがけてDXRubyの構造改革である。これにより上記のコードはきちんと動くようになった。めでたい。
ちなみに副産物としてタイトルバーを掴んでウィンドウを動かしたときに実行が止まらなくなった。あとたぶんメッセージ処理が別スレッドになったのでほんのちょっぴり体感できない程度に速くなっているかもしれない。シングルコアのCPUでは遅くなってるんだろうけどいまどき無いし気にしない。
あと、フルスクリーンのFPS制御を書き直した。書き直したといっても1.5.0devでは存在しなかった処理なので書き足したという感じだ。ウィンドウモードのFPS制御も含めていろいろ検討したすえ、結局1.4.0とほとんど変わらないという結論になった。まあ、ちらつきバグ修正と可変FPSだけでも進歩したと思っておけばいいんじゃないかな。
1.5.1devはあとAyame/Rubyの機能追加とバグ修正、動画再生の初期サポートあたりをどうにかしたらリリースしようかと思っているが、なにかと難しい部分なのでいつになるかわからん感じである。