162 lines
3.3 KiB
C++
162 lines
3.3 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.1 2005/03/02 08:37:40 cozman Exp $
|
|
|
|
#ifndef PHOTON_RESOURCEMANAGER_HPP
|
|
#define PHOTON_RESOURCEMANAGER_HPP
|
|
|
|
#include <vector>
|
|
#include <string>
|
|
|
|
#include <boost/utility.hpp>
|
|
|
|
#include "types.hpp"
|
|
#include "exceptions.hpp"
|
|
|
|
namespace photon
|
|
{
|
|
|
|
class Resource
|
|
{
|
|
public:
|
|
static const uint Invalid=0xffffffff;
|
|
|
|
Resource() :
|
|
refCount(0)
|
|
{
|
|
}
|
|
|
|
uint refCount;
|
|
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 ResourceManager : public boost::noncopyable
|
|
{
|
|
public:
|
|
ResourceManager();
|
|
|
|
virtual ~ResourceManager();
|
|
|
|
uint getResID(const std::string& path);
|
|
void delRef(uint id);
|
|
void cleanUp();
|
|
|
|
private:
|
|
virtual void loadResource(resT &res, const std::string& path)=0;
|
|
virtual void freeResource(resT &res)=0;
|
|
|
|
uint newResource(const std::string& path);
|
|
void deleteResource(uint id);
|
|
|
|
private:
|
|
std::vector<resT> resVec_;
|
|
};
|
|
|
|
// implementation (damn you templor, cruel god of templates!)
|
|
|
|
template<class resT>
|
|
ResourceManager<resT>::ResourceManager()
|
|
{
|
|
}
|
|
|
|
template<class resT>
|
|
ResourceManager<resT>::~ResourceManager()
|
|
{
|
|
}
|
|
|
|
template<class resT>
|
|
uint ResourceManager<resT>::getResID(const std::string& path)
|
|
{
|
|
uint id(0);
|
|
|
|
// loop through resources and find id
|
|
for(typename std::vector<resT>::iterator i=resVec_.begin();
|
|
i != resVec_.end();
|
|
++i)
|
|
{
|
|
++id; // increment id
|
|
if(i->path == path)
|
|
{
|
|
return id;
|
|
}
|
|
}
|
|
|
|
if(id == resVec_.size())
|
|
{
|
|
id = newResource(path);
|
|
}
|
|
|
|
return id; //not already in vector, add resource
|
|
}
|
|
|
|
template<class resT>
|
|
void ResourceManager<resT>::delRef(uint id)
|
|
{
|
|
// if decremented count is <= 0, delete resource
|
|
if(id < resVec_.size() && --resVec_[id].refcount <= 0)
|
|
{
|
|
deleteResource(id);
|
|
}
|
|
}
|
|
|
|
template<class resT>
|
|
void ResourceManager<resT>::cleanUp()
|
|
{
|
|
// delete resources, until none are left
|
|
for(typename std::vector<resT>::iterator i=resVec_.begin();
|
|
i != resVec_.end();
|
|
++i)
|
|
{
|
|
freeResource(*i);
|
|
}
|
|
}
|
|
|
|
template<class resT>
|
|
uint ResourceManager<resT>::newResource(const std::string& path)
|
|
{
|
|
resT res;
|
|
res.path = path;
|
|
|
|
try
|
|
{
|
|
// attempt to load
|
|
loadResource(res,path);
|
|
}
|
|
catch(ResourceException&)
|
|
{
|
|
// rethrow any exceptions with specific information
|
|
throw ResourceException("Could not load " + path);
|
|
}
|
|
|
|
resVec_.push_back(res); // add resource to resVec & return
|
|
return static_cast<uint>(resVec_.size()-1);
|
|
}
|
|
|
|
template<class resT>
|
|
void ResourceManager<resT>::deleteResource(uint id)
|
|
{
|
|
// check boundaries
|
|
if(id >= resVec_.size())
|
|
{
|
|
throw RangeException("Attempt to delete invalid resource.");
|
|
}
|
|
|
|
freeResource(resVec_[id]); // free the resource and erase it from the vec
|
|
resVec_.erase(resVec_.begin()+id);
|
|
}
|
|
|
|
}
|
|
|
|
#endif //PHOTON_RESOURCEMANAGER_HPP
|