うーむ

rb_set_end_procはRubyのENDブロックの登録らしい。
なるほど、それは最終的なGCより前に動かないと都合が悪い。
んで、最終的なGCよりも後に呼ばれる関数というものは無いようだ。
こういうものがいままで無かったのは、普通は無くてもよいということなのだろう。
まあ、対策を考えよう。


モジュールとして実装している部分は、GCで回収されるとか考えなくていいから無視。
問題はクラスで、描画系はベースがDirectXGraphicsとSpriteで、個別がTexture。
前の2つとTextureは独立してるから大丈夫。
フォントも他とは関係ない。
つまり、この件で問題になるのは音まわりだけってことだ。
どーも音関連の解放がごちゃごちゃしてると思ったが、そういうことで試行錯誤した結果なのだな、これは。


rb_set_end_procに期待できないということは、rb_set_end_procでは音まわりの解放はできないから、GCのタイミングで基本インターフェースも解放することになる。
GCのタイミングで解放するってことは、参照カウントを持つようにして、全部回収されたら基本インターフェースを解放するような処理になる。
これはゲーム中でも発生する可能性があって、その場合、newで再取得できないと困るから、基本インターフェースの取得はInit_dxrubyから消して、newの中にまとめたほうがよい。


DirectMusicで扱うオブジェクトは、一番上にパフォーマンス、これが全体共通で、その下にオーディオパスがくるが、オーディオパスごとにボリュームの設定などができるから、クロスフェードをしようと思ったら、曲データごとにオーディオパスを作る必要がある。
いまの実装だとBGM用と効果音用に共通として持ってるから、0.0.6ではオーディオパス以下をオブジェクトに持たせるようにしよう。
参照カウントで取得・解放をするのはパフォーマンスだけになって、このあたりのコードはシンプルになる。
かわりにオブジェクト単位のコードが大変なことになる。


以上。
DXRubyの実装はどーでもいいかもしれないけど、こういう考え方とか考える順番とか、公開しといたら誰かの参考になったりするかしらん。


ところで、なんで効果音にDirectSoundじゃなくてDirectMusicを使っているのかという話だが、DirectSoundにはファイルを読み込む機能が無いのだ。
自力でwavを読まないといけないから面倒で、DirectX8だったかでDirectMusic経由でDirectSoundを扱えるようになって、ファイルが読めるようになったから、それを使っている。
そのおかげで、同じデータを複数再生しても勝手に合成されるから楽ちんだ。
DirectSoundを使うと、1つのバッファの再生は同時に1つしかできなくて、合成する必要がある。
DirectMusic経由で取得したDirectSoundバッファはロックすることができないから、SoundEffectクラスのほうはDirectSoundを直接使っていて、同じオブジェクトを同時再生できないのはそういう理由からだ。