Skip to content

Instantly share code, notes, and snippets.

@davll
Created December 17, 2015 02:53
Show Gist options
  • Select an option

  • Save davll/47788f6e5959ac8292f7 to your computer and use it in GitHub Desktop.

Select an option

Save davll/47788f6e5959ac8292f7 to your computer and use it in GitHub Desktop.
Resource Management
#include "Thales/Resource.h"
#include <string.h>
namespace Thales {
ResourceManager::ResourceManager(IResourceFinder* finder)
: m_Finder(finder)
{
for (int i = 0; i < MAX_TYPE_COUNT; ++i)
m_Factories[i] = NULL;
}
ResourceManager::~ResourceManager()
{
}
void ResourceManager::addFactory(IResourceFactory* factory)
{
int i;
for (i = 0; i < MAX_TYPE_COUNT; ++i) {
if (m_Factories[i] == NULL)
break;
}
THALES_ASSERT(i < MAX_TYPE_COUNT);
m_Factories[i] = factory;
factory->setTypeID(i);
factory->setResourceFinder(m_Finder);
}
void ResourceManager::removeFactory(IResourceFactory* factory)
{
for (i = 0; i < MAX_TYPE_COUNT; ++i) {
if (m_Factories[i] == factory)
m_Factories[i] = NULL;
}
factory->setTypeID(0xFFu);
factory->setResourceFinder(NULL);
}
IResourceFactory* ResourceManager::findFactory(const char* type)
{
IResourceFactory* factory = NULL;
for (i = 0; i < MAX_TYPE_COUNT; ++i) {
if (strcmp(m_Factories[i]->type(), type) == 0) {
factory = m_Factories[i];
break;
}
}
return factory;
}
ResourceHandle ResourceManager::retain(ResourceName name)
{
IResourceFactory* factory = NULL;
for (int i = 0; i < MAX_TYPE_COUNT; ++i) {
if (m_Finder->compareType(name, m_Factories[i]->type())) {
factory = m_Factories[i];
}
}
if (!factory)
return {0,0,0};
ResourceHandle res = factory->find(name);
if (valid(res)) {
factory->retain(res);
THALES_ASSERT(res.type == i);
return res;
}
res = factory->create(name);
if (valid(res)) {
THALES_ASSERT(res.type == i);
return res;
}
return { 0, 0, 0 };
}
void ResourceManager::release(ResourceHandle res)
{
THALES_ASSERT(valid(res));
m_Factories[res.type]->release(res);
}
bool ResourceManager::valid(ResourceHandle res)
{
if (res.version != 0 && res.type < (unsigned)MAX_TYPE_COUNT) {
IResourceFactory* factory = m_Factories[res.type];
if (factory)
return factory->valid(res);
}
return false;
}
ResourceStatus ResourceManager::status(ResourceHandle res)
{
return m_Factories[res.type]->status(res);
}
bool ResourceManager::load(ResourceHandle res)
{
return m_Factories[res.type]->load(res);
}
bool ResourceManager::unload(ResourceHandle res)
{
return m_Factories[res.type]->unload(res);
}
}
// -*- C++ -*-
namespace Thales {
struct ResourceName {
uint32_t uuid[4];
};
struct ResourceHandle {
uint8_t type;
uint8_t version;
uint16_t index;
};
enum class ResourceStatus {
UNKNOWN = 0,
UNLOADED,
LOADING,
LOADED,
UNLOADING,
};
class IResourceFinder {
public:
virtual bool exist(ResourceName) = 0;
virtual bool compareType(ResourceName, const char* type) = 0;
virtual IFile* open(ResourceName) = 0;
};
class IResourceFactory {
friend class ResourceManager;
public:
virtual const char* type() const = 0;
virtual ResourceStatus status(ResourceHandle) const = 0;
virtual bool valid(ResourceHandle) const = 0;
virtual ResourceHandle create(ResourceName) = 0;
virtual ResourceHandle find(ResourceName) = 0;
virtual void retain(ResourceHandle) = 0;
virtual void release(ResourceHandle) = 0;
virtual bool load(ResourceHandle) = 0;
virtual bool unload(ResourceHandle) = 0;
protected:
virtual void setTypeID(uint8_t tid) = 0;
virtual void setResourceFinder(IResourceFinder*) = 0;
};
class ResourceManager {
public:
ResourceManager(IResourceFinder* finder);
~ResourceManager();
// ResourceManager doesn't own factories
// Callers (sub-systems) are responsible to create/delete factories
void addFactory(IResourceFactory*);
void removeFactory(IResourceFactory*);
IResourceFactory* findFactory(const char* type);
ResourceHandle retain(ResourceName);
void release(ResourceHandle);
bool valid(ResourceHandle);
ResourceStatus status(ResourceHandle);
bool load(ResourceHandle);
bool unload(ResourceHandle);
private:
IResourceFinder* m_Finder;
private:
static constexpr int MAX_TYPE_COUNT = 64;
IResourceFactory* m_Factories[MAX_TYPE_COUNT];
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment