Динамический тип Singleton с шаблонными типами. Это жизнеспособный подход? [Решение предоставлено]

В настоящее время я работаю над своим собственным движком, в частности графическим интерфейсом, и пытаюсь сделать так, чтобы он мог выбирать между DirectX и openGL рендерингом. Для этой цели я хочу иметь синглтон Менеджера текстур (я привык использовать стандартную реализацию этого). Однако в этом случае я хочу иметь возможность выбирать динамический тип экземпляра при абстрагировании функциональности. Вот моя реализация до сих пор:

template <typename T>
class TextureManagerType
{
public:

virtual ~TextureManagerType() = 0 {}T* GetTexture(TEXTURE_ID texID)
{
std::map<TEXTURE_ID, T*>::const_iterator it = m_textures.find(texID);
if(it != m_textures.end())
{
return (*it)->second;
}
else
{
assert(0);
return 0;
}
}

bool Load(const std::string& texturePaths)
{
File f;
if(!f.Open(texturePaths))
{
ReportError("Fatal error! Could not open: " + texturePaths);
return false;
}

std::string str;

while(!f.EndOf())
{
if(!f.GetString(&str))
{
ReportError("Warning: Unexpected end of file in     texturepaths file: " + texturePaths);
}
LoadTexture(str);
}

return true;
}

virtual T* LoadTexture(const std::string& texturePath) = 0;

protected:
std::map<TEXTURE_ID, T*> m_textures;
};//Uncopyable is a base class with a disabled copy constructor
class TextureManager : public Uncopyable
{
private:
TheTextureManager();

public:
//T here is underlined in all three mentions as it is undefined
static TextureManagerType<T>* Instance()
{
return m_pInstance;
}
static void SetDynamicType(TextureManagerType<T>* type)
{
m_pInstance = type;
}
static TextureManagerType<T>* m_pInstance;//static TexManagerType* Instance()
//{
//  return m_pInstance;
//}
//static void SetDynamicType(TexManagerType* type)
//{
//  m_pInstance = type;
//}
//static TexManagerType* m_pInstance;

};

//Named to be consistent with normal singletons
typedef TextureManager TheTextureManager;

Как вы можете видеть, я пожертвовал бонусом RAII синглтона и мне нужно инициализировать указатель m_pInstance на ноль.

//I want the singleton once set, to be able to be accessed thusly:
TheTextureManager::Instance()->DoTextureFunction();

Я не хочу синглтона для каждого типа TextureManager, так как я хотел бы иметь возможность контролировать срок службы каждого производного менеджера при сохранении глобальной доступности.
В настоящее время моя система НЕ работает вообще, поскольку возвращаемый тип для TextureManager :: Instance требует знания шаблонного типа, который недоступен.

Я пытался вложить TextureManagerType в TextureManager, но это означало, что каждый вызов
диспетчеру текстур понадобится требуемый тип в качестве параметра шаблона, который в некотором роде лишает смысла абстрагировать это.

Пожалуйста, помогите парням и девушкам и будьте конструктивны в своих комментариях.
Пожалуйста, задавайте вопросы, если я пропустил важные / все детали. Мозг слишком устал, чтобы думать прямо сейчас.
Спасибо

1

Решение

Вы можете определить абстрактный, не шаблонный интерфейс для вашего TextureManagerTypeи используйте это для ссылки на реализацию менеджера текстур из одноэлементного объекта менеджера текстур.
Для этого вам также понадобится полиморфное представление для ваших объектов Texture, которое может быть чем-то простым, например, объединяющим типом или абстрактным базовым классом, с производными классами для различных конкретных типов текстур.
Все может выглядеть примерно так:

union TextureContainer {
OpenGLTexture* oglt;
DirectXTexture* dxt;
};

class TextureManagerTypeBase
{
public:

virtual ~TextureManagerType() = 0;
virtual TextureContainer GetTexture(TEXTURE_ID texID) = 0;
virtual TextureContainer LoadTexture(const std::string& texturePath) = 0;

//this looks like it only refers to other public
// methods, so it's staying here
virtual bool Load(const std::string& texturePaths)
{
...
}
};

template <typename T>
class TextureManagerType : public TextureManagerTypeBase
{
public:
// pretty much the same as before
// minus Load wich is defined in the base class
// plus wrapping T into a TextureContainer
...
};//Uncopyable is a base class with a disabled copy constructor
class TextureManager : public Uncopyable
{
private:
TheTextureManager();

public:
//T here is underlined in all three mentions as it is undefined
static TextureManagerTypeBase* Instance()
{
return m_pInstance;
}
static void SetDynamicType(TextureManagerTypeBase* type)
{
m_pInstance = type;
}
static TextureManagerTypeBase* m_pInstance;
};

Это немного грубо, но, надеюсь, вы поняли идею.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]