deviceの管理
DirectXで描画をする時はDeviceが必要なわけだが,どうにもこれがめんどくさい.
struct directx { LPDIRECT3DDEVICE9 device() const; // ... }; struct texture { bool create(LPDIRECT3DDEVICE9 device, const std::string& file_path); // ... };
なんて実装にすると,テクスチャを作る時がめんどう.
directx x;
texture tex;
tex.create(x.device(), "foo/bar.bmp");
こんなデバイスをどこにでも持っていかなきゃならない実装は嫌(めんどい)ので,裏に隠す.
private継承でis-implementation-in-terms-ofを実現(言ってみたかっただけ.
# それ以前に用語として合ってるのか・・・.
class directx { static LPDIRECT3DDEVICE9 device_; protected: static LPDIRECT3DDEVICE9 device(){ return device_; } // ... }; LPDIRECT3DDEVICE9 directx::device_ = NULL; struct texture : private directx { bool create(const std::string& file_path){ LPDIRECT3DDEVICE9 dev = directx::device(); // ... } // ... }; texture tex; tex.create("baz/qux.bmp");
今までこうしてたんだけど,directxクラスの静的メンバ関数にいきなりアクセスされたりする(*1)とまずいので覆う.
あとcom_ptr<>を使ってみる.
以下の例はログの設定とか.
//TODO: directxクラスのローカルクラスへ class directx_impl { LPDIRECT3DDEVICE9 device_; log_manager log_; public: LPDIRECT3DDEVICE9 device() const{ return device_; } void log_level(int lv){ log_.level(lv); } // ... }; class directx { static directx_impl& impl(){ static directx_impl impl_; return impl_; } protected: static com_ptr<IDirect3DDevice9> device(){ return com_ptr<IDirect3DDevice9>(impl().device()); } public: static void log_level(int lv){ impl().log_level(lv); } // ... }; struct texture : private directx { bool create(const std::string& file_path){ auto dev = directx::device(); // 何 // ... } // ... }; int main(){ directx::log_level(3); // ok texture tex; tex.create("quux/corge.bmp"); // ok }
こんなんどうかな.
まだ実装してないけど.
これ・・・動くのか?(無責任
directx_impl::~directx_impl()が一回しか呼ばれないから,deviceの解放し忘れのチェックとかできるかも?.
staticなdeviceが一個ならだけど.
# C++0xのautoは知ってるけど,C++03のautoは知らなかったり.
余談だけど,LPDIRECT3DDEVICE9 IDirect3DTexture9::GetDevice()があるので,初期化さえしちゃえばいいんだよね.
LPDIRECT3DTEXTURE9 texture = my_create_texture("grault/garply.bmp");
LPDIRECT3DDEVICE9 device = texture->GetDevice();
device->some_func();
device->Release();