今回もガチ・プログラミングなネタです。
一昨日から、Managed Direcrt X による XNA の Game クラスのようなモノを再度作り直し始めたというお話しをしました。
そして、昨夜のことです。
デバイス消失時のイベントハンドラとデバイスリセット時のイベントハンドラを、継承元クラスの方に移して、そこから、LoadContent仮想メソッドと、UnloadContet仮想メソッドを呼ぶという構成の変更を行ないました。
すると、今まで特に問題なく動作していたプログラムが、デバイスリセット時に、NullReferenceExceptionが発生するようになってしまいました。
???
あっ!
そう、もうお気づきの方もいらっしゃると思いますが、UnloadContentメソッド中で、生成したリソースの開放を行っているのですが、そこには管理されているリソースも含まれているのです。
Managed DirectXでデバイスのリセットを行う場合、管理されているリソースはリセット時に自動的に復帰されるため、デバイス消失時に開放してはならなかったのです!
つまり、デバイス消失時のイベントハンドラでの処理と、UnloadContentの処理は別々に記述すべきだったのですね。
そういうわけで、デバイス消失時のイベントハンドラとデバイスリセット時のイベントハンドラは、それ自体を仮想メソッドに戻して、継承先クラスでLoadContent仮想メソッドとUnloadContet仮想メソッドとは別に処理するという構成に戻しました。
勿論、このノウハウを忘れないように、コード中にコメントを追加しました。
こういうノウハウは、実際のアプリケーションを組む場合は必須になるのですが、ドキュメントには記述されていなかったり、書いてあっても素通りしまったりして、自分が不具合を体験してみないと、なかなか、身に付かないものなんですよね。
この事に気づいたのは、実に収穫でした。
それにしても、ソーサリーフォースのデバイス消失サンプルコードが、アンマネージドリソースを含める形で作られていなかったら、この事に気づくのは、まだまだ、先のこととなったでしょう。
ソーサリーフォースのオノデラユウイチ様、本当にありがとうございます。