06/23(水)


昨日、生まれて初めてfriend指定を使ってみた。
何故friendを使ったかを今週の作業を追って書いておきます。

まず、今週のアタマにDirectDrawSurfaceを隠蔽するクラスTSurfaceを書きました。
これはこれで、いい感じに作れていたワケです。

で、次にスプライトのクラスを書いたワケです。(「まだ書いてなかったのか!」などと言わないように)
で、ですねぇ。スプライトのクラスには当然Drawってなメソッドがあるわけで、これは引数に描画先のサーフェスを渡してやるんですけど、それがさっきのTSurfaceのポインタなんです。
ところがですね、スプライトをいざバックバッファに描画しようと思ってみると、何とバックバッファはTSurfaceじゃないんです。

バックバッファは、そもそも、MDxDrawのプロパティとしてあるワケです。(MDxDrawは過去に作ったDirectDrawの初期化を支援するコンポーネント)
バックバッファがMDxDrawの中にむき出しであるのは以前から気になってたので、「こいつは書き換えるしかないな」って思いまして、MDxDrawを書き直し始めたんです。もちろん、バックバッファとプライマリサーフェスをTSurfaceの派生クラスにするつもりで。

しかし、MDxDrawのソースを見ると、意外にややこしい。
ウィンドウモードとフルスクリーンモードの場合でサーフェスの確保の仕方が違うし、フルスクリーンのときはプライマリとバックが同時に確保されていて、「どないしたもんやろ?」ってなってしまったんですよ。

そこでですねぇ、TSurfaceの派生クラスでサーフェスを確保するのをあきらめて、今あるMDxDrawで確保されたサーフェスをTSurfaceに押し込んでやることにしたワケです。
で、friendの登場になったワケです。
はっきり言いまして、ややこしいのを解決するのがメンドクサイってんでfriend使ってみたんですが、結構いい感じで書きかえれました。


で、friendに関連したことでもう一つ悩んでいます。
正確にはもう一件悩んでたことがあるんだけど、それもfriendのおかげで上手く解決できそうって事なんですけどね。

で、悩んでたことってのは、またまたTSurfaceのことなんですよ。

DirectDrawSurfaceってのはDirectDrawからクリエイトするワケで、大元のDirectDrawか開放されちゃうとそっからクリエイトしたDirectDrawSurfaceも自動的に開放されちゃうワケですよねぇ。

えむっちの場合、ウィンドウモードとフルスクリーンモードを切り替えるときにMDxDrawでいったんDirectDrawを開放して反対のモードでもう一回作成って事をやってます。

しかし、TSurfaceの自体はDirectDrawに関係なく存在しているワケで、モードを切り替えると知らない間にDirectDrawSurfaceがなくなってしまうワケです。

で、切り替わったときに自動的に再確保されるようにしたいんです。
なぜなら、自動再確保をあきらめるとTSurfaceにReallocateとかってメソッドを作ってそれをpublicメンバにする必要が出てくると思います。
Reallocateが必要なのは事実なんですが、publicにしてしまうと、誰でも呼び出せるようになってしまって2回続けて呼び出されたら、最初に確保された方のDirectDrawSurfaceは行方不明になってジ・エンドです。
だって、DirectDrawSurfaceがホントに確保されているかどうかを調べる方法がないからねぇ。

そこで、Reallocateはpublicじゃないメンバにして、firendのMDxDrawから呼び出そうと思ってます。
そもそも、モードが切り替わるタイミングはMDxDrawじゃないとわからないワケだし、ちょうどfriend指定になってるので都合がいいですねぇ。

あとは、MDxDrawにTSurfaceのリストを持ってやるだけかな。
で、TSurfaceをnewするときににMDxDrawのポインタを渡してやればOKだね。

でもまてよ、このリストはpublicメンバにしちゃまずいよねぇ?
勝手にリストから削除されたりしたら、危険な目に会いそう。

さっきと同じ要領でMDxDrawでTSurfaceをfriendにすれば解決できそうだけど、そんなことしてもいいもんなんだろうか?
(つまり、お互いがfriendになるってことなんだけどね)

friend、使うべきじゃなかったのかなぁ・・・
クラス崩壊の危機なのか?

だれか、エレガントな解決策を知っていたら教えてくれー。


戻る