187 lines
4.4 KiB
C++
187 lines
4.4 KiB
C++
//This file is part of Photon (http://photon.sourceforge.net)
|
|
//Copyright (C) 2004-2005 James Turk
|
|
//
|
|
// Author:
|
|
// James Turk (jpt2433@rit.edu)
|
|
//
|
|
// Version:
|
|
// $Id: ResourceManager.hpp,v 1.10 2005/07/19 01:31:37 cozman Exp $
|
|
|
|
#ifndef PHOTON_RESOURCEMANAGER_HPP
|
|
#define PHOTON_RESOURCEMANAGER_HPP
|
|
|
|
#include <map>
|
|
#include <string>
|
|
|
|
#include <boost/utility.hpp>
|
|
|
|
#include "types.hpp"
|
|
#include "exceptions.hpp"
|
|
|
|
namespace photon
|
|
{
|
|
|
|
class Resource
|
|
{
|
|
public:
|
|
Resource() :
|
|
refCount(0)
|
|
{ }
|
|
|
|
public:
|
|
uint refCount;
|
|
};
|
|
|
|
class ResourceDescriptor
|
|
{
|
|
public:
|
|
ResourceDescriptor() { }
|
|
ResourceDescriptor(const std::string& p) :
|
|
path(p)
|
|
{ }
|
|
|
|
public:
|
|
std::string path;
|
|
};
|
|
|
|
// Class: ResourceManager
|
|
// Templated base class for managing resources like textures and music.
|
|
//
|
|
// All ResourceManager work is done behind the scenes, it and all classes
|
|
// derived from it are therefore left without public documentation.
|
|
template<class resT, class ResDescT_=ResourceDescriptor>
|
|
class ResourceManager : public boost::noncopyable
|
|
{
|
|
public:
|
|
typedef ResDescT_ ResDescT;
|
|
|
|
public:
|
|
ResourceManager();
|
|
|
|
virtual ~ResourceManager();
|
|
|
|
void newResource(const std::string& name, const ResDescT& path);
|
|
|
|
resT& getResource(const std::string& name);
|
|
|
|
void delRef(const std::string& name);
|
|
void cleanUp();
|
|
|
|
private:
|
|
virtual void loadResourceData(resT &res, const ResDescT& path)=0;
|
|
virtual void freeResourceData(resT &res)=0;
|
|
|
|
void deleteResource(const std::string& name);
|
|
|
|
public:
|
|
void printReport(std::ostream& os);
|
|
|
|
private:
|
|
typedef std::map<std::string,resT> MapT;
|
|
typedef typename MapT::iterator MapIterator;
|
|
MapT resourceMap_;
|
|
};
|
|
|
|
// implementation (damn you templor, cruel god of templates!)
|
|
|
|
template<class resT, class ResDescT>
|
|
ResourceManager<resT, ResDescT>::ResourceManager()
|
|
{ }
|
|
|
|
template<class resT, class ResDescT>
|
|
ResourceManager<resT, ResDescT>::~ResourceManager()
|
|
{ }
|
|
|
|
template<class resT, class ResDescT>
|
|
void ResourceManager<resT, ResDescT>::newResource(const std::string& name,
|
|
const ResDescT& desc)
|
|
{
|
|
resT resource;
|
|
|
|
try
|
|
{
|
|
// attempt to load
|
|
loadResourceData(resource, desc);
|
|
}
|
|
catch(ResourceException& e)
|
|
{
|
|
// rethrow any exceptions with specific information
|
|
throw ResourceException("Could not load " + desc.path + " as " + name +
|
|
": " + e.getDesc());
|
|
}
|
|
|
|
resourceMap_[name] = resource; // add the resource to resourceMap
|
|
}
|
|
|
|
template<class resT, class ResDescT>
|
|
resT& ResourceManager<resT, ResDescT>::getResource(const std::string& name)
|
|
{
|
|
MapIterator resource( resourceMap_.find(name) ); // fetch resource
|
|
|
|
if(resource != resourceMap_.end())
|
|
{
|
|
// increment the refCount and return the resource for use
|
|
++resource->second.refCount;
|
|
return resource->second;
|
|
}
|
|
else
|
|
{
|
|
throw ResourceException("No resource named \"" + name + "\" exists.");
|
|
}
|
|
}
|
|
|
|
template<class resT, class ResDescT>
|
|
void ResourceManager<resT, ResDescT>::deleteResource(const std::string& name)
|
|
{
|
|
MapIterator resource( resourceMap_.find(name) ); // fetch resource
|
|
|
|
// if the resource was found
|
|
if(resource != resourceMap_.end())
|
|
{
|
|
// free resource and remove it from the map
|
|
freeResourceData(resource->second);
|
|
resourceMap_.erase(name);
|
|
}
|
|
}
|
|
|
|
template<class resT, class ResDescT>
|
|
void ResourceManager<resT, ResDescT>::delRef(const std::string& name)
|
|
{
|
|
MapIterator resource( resourceMap_.find(name) ); // fetch resource
|
|
|
|
// if the resource was found
|
|
if(resource != resourceMap_.end())
|
|
{
|
|
if(--resource->second.refCount <= 0)
|
|
{
|
|
deleteResource(name);
|
|
}
|
|
}
|
|
}
|
|
|
|
template<class resT, class ResDescT>
|
|
void ResourceManager<resT, ResDescT>::cleanUp()
|
|
{
|
|
// delete resources, until none are left
|
|
while(!resourceMap_.empty())
|
|
{
|
|
deleteResource(resourceMap_.begin()->first);
|
|
}
|
|
}
|
|
|
|
template<class resT, class ResDescT>
|
|
void ResourceManager<resT, ResDescT>::printReport(std::ostream& os)
|
|
{
|
|
// go through all resources and output debug info (name/path/refCount)
|
|
for(MapIterator i = resourceMap_.begin(); i != resourceMap_.end(); ++i)
|
|
{
|
|
os << i->second.name << "\t" << i->second.path << "\t"
|
|
<< i->second.refCount << "\n";
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
#endif //PHOTON_RESOURCEMANAGER_HPP
|