読者です 読者をやめる 読者になる 読者になる

やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

描画Frameworkをつくってみた4

前回問題だったGraphicsSelectorクラスのSelect関数におけるif文と文字リテラルをなくした。 Select関数の修正が必要なくなった。

入手先

GitHub MEGA

方法

非静的なclassメンバ関数ポインタを使った。 https://www.qoosky.io/techs/4e0d4bc039
関数ポインタよりもさらに複雑怪奇な記述が必要だった。

改善

前回と大差ない。

以下のSelect関数の記述が不要になり、かわりにInitialize関数に追記する形になった。 if文が減り、文字リテラルはInitializeで記述するため、追記するときにミスしづらくなった。

Select関数

} else if (_T("OpenGL") == wndProcKey) {
    this->SelectDrawWndProc(wndProcKey);
    this->SelectOpenGLDrawer(drawerKey);
}

Initialize関数

m_selectDrawerMap.insert(map<basic_string<TCHAR>, FpSelectDrawer>::value_type(_T("OpenGL"), &GraphicsSelector::SelectOpenGLDrawer));

課題

依然として描画アーキテクチャと描画内容が追加されるたびにGraphicsSelectorクラスを以下のように修正する必要がある。 できればすべて不要にしたい。 さて、どうしたものか。

GraphicsSelector.h

private:
    Selector<IOpenGLDrawer*> m_openglSelector;

GraphicsSelector.cpp

Initialize関数

if (!m_openglSelector.IsContain(_T("Scene1"))) {
    m_openglSelector.Add(_T("Scene1"), (IOpenGLDrawer*) new OpenGLDrawerScene1());
}
if (!m_openglSelector.IsContain(_T("Scene2"))) {
    m_openglSelector.Add(_T("Scene2"), (IOpenGLDrawer*) new OpenGLDrawerScene2());
}
m_openglSelector.Select(_T("Scene1"));

if (!m_drawWndProcSelector.IsContain(_T("OpenGL"))) {
    m_drawWndProcSelector.Add(_T("OpenGL"), (IDrawWndProc*) new OpenGLWndProc(&m_openglSelector));
}

m_selectDrawerMap.insert(map<basic_string<TCHAR>, FpSelectDrawer>::value_type(_T("OpenGL"), &GraphicsSelector::SelectOpenGLDrawer));

Finalize関数

delete m_drawWndProcSelector.Get(_T("OpenGL"));

delete m_openglSelector.Get(_T("Scene1"));
delete m_openglSelector.Get(_T("Scene2"));
m_openglSelector.Clear();

SelectOpenGLDrawer関数

void GraphicsSelector::SelectOpenGLDrawer(const std::basic_string<TCHAR>& key)
{
    if (!m_openglSelector.IsContain(key)) { return; }
    if (m_openglSelector.Get(key) == m_openglSelector.GetSelected()) { return; }
    m_openglSelector.GetSelected()->Finalize();
    m_openglSelector.Select(key);
    m_openglSelector.GetSelected()->Initialize();
}