I've grown to love the Singleton pattern, even if its commonly known overusing it is bad. I think the information that a class is a singleton is of no concern to that class, so should be kept seperate (like in a System or Manager or through Boost).
I modified your code a bit to match my system a little, and attempted to clean it up to what I think would be logical (and as compulsion I've changed a lot of formatting). It doesn't mean its right, and I concertainly wouldn't expect it to be since I had some troubles making out the entire system, but maybe it'll give you a different perspective - who knows.
Code:
template< typename tnResource >
class ResourceContainer
{
public:
bool CheckExists(const std::string&);
tnResource* Find(const std::string&);
void Add(const std::string&, tnResource*);
void Remove(const std::string&, tnResource*) {}
virtual ~Manager(void)
{
std::map< std::string, tnResource* >::const_iterator I;
for(I = m_Resources.begin(); I != m_Resources.end(); ++I)
{
delete I->second;
}
}
private:
std::map< std::string, tnResource* > m_Resources;
};
template< typename tnResource >
tnResource* ResourceContainer< tnResource >::Find(const std::string& p_sFilename)
{
std::map< std::string, tnResource* >::const_iterator entry = m_Resources.find(p_sFilename);
if(entry != Resources.end()) // if the entry is found
return entry->second; // return the reference to the resource
else
return false;
}
template< typename tnResource >
bool ResourceContainer<tnResource>::CheckExists(const std::string& p_sFilename)
{
std::map< std::string, tnResource* >::const_iterator entry = m_Resources.find(p_sFilename);
if(entry != m_Resources.end()) // if the entry is found
return true;
else
return false;
}
template< typename tnResource >
void ResourceContainer< tnResource >::Add(const std::string& p_sFilename, tnResource* Resource)
{
m_Resources.insert(std::make_pair(p_sFilename, Resource));
}
class Manager // singleton god
{
public:
ResourceManager* Resources()
{
if(!m_ResourceManager)
m_ResourceManager = new ResourceManager();
return m_ResourceManager;
}
D3DTextureHandler* Textures()
{
if(!m_D3DTextureHandler)
m_D3DTextureHandler = new D3DTextureHandler();
return m_D3DTextureHandler;
}
Manager* Instance()
{
if(!m_Instance)
m_Instance = new Manager();
return m_Instance;
}
protected:
Manager()
{
}
private:
Manager* m_Instance;
ResourceManager* m_ResourceManager;
D3DTextureHandler* m_D3DTextureHandler;
};
class ResourceManager
{
public:
void Add(std::string p_sFilename)
{
switch(GetExtension(p_sFilename).c_string())
{
case "ms3d": m_MS3DModelManager->Create(p_sFilename);
break;
case "ai": //m_AIMotionManager->Create(p_sFilename);
break;
default:
break;
}
}
void Remove(std::string p_sFilename)
{
}
std::string GetExtension(std::string p_sFilename)
{
return p_sFilename.substr(p_sFilename.rfind('.') + 1); //+1 to not include the dot...
}
MS3DModelManager* MS3DModels()
{
if(!m_MS3DModelManager)
m_MS3DModelManager = new MS3DModelManager();
return m_MS3DModelManager;
}
AIMotionManager* AIMotions()
{
if(!m_AIMotionManager)
m_AIMotionManager = new AIMotionManager();
return m_AIMotionManager;
}
private:
MS3DModelManager* m_MS3DModelManager;
AIMotionManager* m_AIMotionManager;
};
class MS3DModelManager
{
MS3DModel* Create(std::string p_sFilename)
{
MS3DModelRenderData* ModelData = new MS3DModelRenderData;
ModelData->Model = new MS3DModel;
m_Models.push_back(ModelData);
if(m_Resources.CheckExists(p_sFilename) == false)
{
std::cout << "Resource was not on the list!" << std::endl;
m_Resources.Add(p_sFilename, ModelData->Model);
}
return ModelData->Model;
}
void Destroy(std::string p_sFilename)
{
}
private:
struct MS3DModelRenderData
{
float Position[3]; // will be changed to vectors eventually
float Orientation[3];
MS3DModel *Model;
};
std::vector< MS3DModelRenderData* > m_Models; // holds pointers to all MS3D Models
ResourceContainer< MS3DModel > m_Resources;
};
int main()
{
Manager::Instance()->Resources()->Add("AttackShip.ms3d");
Manager::Instance()->Resources()->Add("AttackShip.ms3d");
}