2012-10-27 53 views
0

我正在創建我的第一個遊戲。它將是Pacman或Snake。我打算使用DirectX 11.模板中的錯誤可能是錯誤設計的資源管理器

我正在寫資源管理器。我想創造它最簡單的使用,但我認爲它沒有很好的設計。這是我寫的:

#pragma once 

class Shader; 
class Mesh; 
class Texture; 

typedef std::map<std::string, std::auto_ptr<Shader>> shaders_map; 
typedef std::map<std::string, std::auto_ptr<Mesh>>  meshes_map; 
typedef std::map<std::string, std::auto_ptr<Texture>> textures_map; 

template<class C, class E> 
inline int findElementInMap(const C& cont, E *ptr) 
{ 
    C::const_iterator it = cont.begin(); 
    int i = 0; 

    while(it != cont.end()) 
    { 
     if(it->second.get() == ptr) // ERROR AT THIS LINE!!!! 
      return i; 

     i++; 
     it++; 
    } 

    return -1; 
} 

class ResourceManager 
{ 
public: 
    ResourceManager(void); 
    ~ResourceManager(void); 

    template<class T> 
    inline T* get(const std::string &name) 
    { 
     if(typeid(T) == typeid(Shader)) { 
      return (T*)getShader(name); 
     } 
     else if(typeid(T) == typeid(Mesh)) { 
      return (T*)getMesh(name); 
     } 
     else if(typeid(T) == typeid(Texture)) { 
      return (T*)getTexture(name); 
     } 

     return nullptr; 
    } 

    Shader*  getShader(const std::string &name); 
    Mesh*  getMesh(const std::string &name); 
    Texture* getTexture(const std::string &name); 

    template<class T> 
    inline bool add(T *ptr) 
    { 
     if(typeid(T) == typeid(Shader)) { 
      return addShader((Shader*)((void*)ptr)); 
     } 
     else if(typeid(T) == typeid(Mesh)) { 
      return addMesh((Mesh*)((void*)ptr)); 
     } 
     else if(typeid(T) == typeid(Texture)) { 
      return addTexture((Texture*)((void*)ptr)); 
     } 

     return false; 
    } 

    bool  addShader(Shader *ptr); 
    bool  addMesh(Mesh *ptr); 
    bool  addTexture(Texture *ptr); 

    template<class E> 
    inline void release(E *ptr) 
    { 
     if(typeid(E) == typeid(Shader)) { 
      release<shaders_map, E>(shaders, (E*)((void*)ptr)); 
      return; 
     } 
     else if(typeid(E) == typeid(Mesh)) { 
      release<meshes_map, E>(meshes, (E*)((void*)ptr)); 
      return; 
     } 
     else if(typeid(E) == typeid(Texture)) { 
      release<textures_map, E>(textures, ptr); 
     } 
    } 

     // THIS METHOD CAUSES PROBLEM 
    template<class C, class E> 
    void release(C &container, E *ptr) 
    { 
     assert(ptr != nullptr); 

     int index = findElementInMap<C, E>(container, ptr); 
     if(index < 0) 
      return; 

     C::iterator it = container.begin(); 
     it->second.release(); 
    } 
private: 
    shaders_map  shaders; 
    meshes_map  meshes; 
    textures_map textures; 
}; 

現在編譯錯誤:

error C2440: '==' : cannot convert from 'Shader *' to 'Mesh *' 
int findElementInMap<C,E>(const C &,E *)' being compiled 
     with 
     [ 
      C=textures_map, 
      E=Shader 
     ] 

所以容器類型和元素類型不匹配。任何想法如何設置它的工作?

或者我應該從頭開始構建新的資源管理器?

編輯: 這就是我如何使用這個類:

Shader *sh = new Shader(); 
    resourceManager.add<Shader>(sh); 
    resourceManager.release<Shader>(sh); 
+1

顯然,你叫'findElementInMap'在地圖'Texture'對象搜索'Shader'。你爲什麼這樣做?在着色器貼圖和紋理貼圖中搜索着色器。 – jogojapan

+0

不顯示網格和着色器類,你不能期望得到一個知識淵博的答案。 – SomeWittyUsername

+0

@icepack:這些類是空的。 – micnyk

回答

2

許多方法來做到這一點。

你可以用簡單的重載做:

bool  add(Shader *ptr){ 
    return addShader(ptr); 
} 
bool  add(Mesh *ptr){ 
    return addMesh(ptr); 
} 

bool  add(Texture *ptr){ 
    return addTexture(ptr); 
} 

,或者如果你想使用的模板,只要add和get方法模板的方法和專門

template<class T> 
void add(T *ptr){ 

} 

和每個資源類型

template<> 
ResourceManager<Texture>::add(Texture *ptr){ 
    return addTexture(ptr); 
} 

template<> 
ResourceManager<Shader>::add(Shader *ptr){ 
    return addShader(ptr); 
} 

template<> 
ResourceManager<Mesh>::add(Mesh *ptr){ 
    return addMesh(ptr); 
} 

另一個更清潔的選擇是製作一個模板方法, d返回目標容器

template<typename T> 
std::map<std::string, std::auto_ptr<typename T> > &getContainer(){ 


} 

專營它返回的好容器上的類型

template<> 
std::map<std::string, std::auto_ptr<Mesh> > &ResourceManager::getContainer<Mesh>(){ 

    return meshes_map; 
} 
template<> 
std::map<std::string, std::auto_ptr<Texture> > &ResourceManager::getContainer<Texture>(){ 

    return textures_map; 
} 
template<> 
std::map<std::string, std::auto_ptr<Shader> > &ResourceManager::getContainer<Shader>(){ 

    return shader_map; 
} 

這歸結get方法例如喜歡的東西:

template<typename T> 
    T* get(const std::string &name){ 
     return getContainer<T>().get(name); 
    } 

免責聲明:那只是一個快點,我沒有編譯它。問你是否有更多的問題

編輯有關您的編譯錯誤: 您可以致電resourceManager.release<Shader>(sh); 對於圖片,在釋放方法中將E替換爲Shader,您將看到它無法編譯。釋放(紋理,PTR) 爲您釋放的方法來編譯,你必須明確地即投:

template<class E> 
    inline void release(E *ptr) 
    { 
     if(typeid(E) == typeid(Shader)) { 
      release<shaders_map, Shader>(shaders, (Shader*)((void*)ptr)); 
      return; 
     } 
     else if(typeid(E) == typeid(Mesh)) { 
      release<meshes_map, Mesh>(meshes, (Mesh*)((void*)ptr)); 
      return; 
     } 
     else if(typeid(E) == typeid(Texture)) { 
      release<textures_map, Texture>(textures, (Texture*)((void*)ptr)); 
     } 
    } 
+0

我想我會耐心這個類,但任何人都可以告訴我爲什麼釋放方法在我的代碼導致問題? – micnyk

+1

我編輯了答案 –

+0

非常感謝! – micnyk