• entries
    437
  • comments
    1182
  • views
    764832

Pathed resource allocator

Sign in to follow this  

129 views

Something that I have dealt with on and off for the entire time I've been game programming is the idea that I need certain resources to be loaded from file exactly once, but used by multiple entities. I've written several generations of allocator-type classes and structures to manage this, but my latest effort is pretty nifty, fairly safe, and easy. In this iteration, I created a templated class that maintains an std::map of string->object mappings, where each object in the map is a boost::weak_ptr to an allocated resource. Entities that require a certain named resource call the allocator to get a boost::shared_ptr to the resource. In this way, I have a central mapping of name->object that does not itself maintain a shared_ptr; thus, when all entities release a resource, it gets dumped. Although an entry remains in the allocator map, the behavior of weak_ptr is such that it will indicate its expired status, and subsequent requests for the same pathed resource will result in a reload. Having this central mapping also makes it easier to perform iterative operations on the loaded resources, such as dumping, reloading, re-submitting vertex buffers, or what have you, as necessary. Here's my first try at the allocator class. Thoughts?


#ifndef TEMP_PATHED_RALLOCATOR
#define TEMP_PATHED_RALLOCATOR

#include
#include
#include
#include

#include

// TPathedAllocator
// Implements a template class for an allocator/manager for string-pathed
// resource loading.
// Useful for images, textures, meshes, etc... which can be shared among
// many objects, and which should only be loaded once.


template <class T>
class TPathedAllocator
{
public:
typedef typename std::map >::iterator TIter;

TPathedAllocator()
{
};

~TPathedAllocator()
{
};

boost::shared_ptr getResource(const char *n)
{
std::string name=std::string(n);
TIter iter;
iter = m_map.find(name);
if(iter == m_map.end())
{
// Resource not found, create new
boost::shared_ptr temp(new T(n));
boost::weak_ptr tempweak(temp);
m_map[name]=tempweak;
return temp;
}

if((*iter).second.expired())
{
// Resource expired
boost::shared_ptr temp(new T(n));
boost::weak_ptr tempweak(temp);
m_map[name]=tempweak;
return temp;
}

// Get here, resource valid and not expired
boost::shared_ptr temp((*iter).second);
return temp;
};

template void iterateObjects(_Function f)
{
TIter ti= m_map.begin();
while(ti != m_map.end())
{
if(!(*ti).second.expired())
{
boost::shared_ptr temp((*ti).second);
f(temp);
}
++ti;
}

};


protected:
std::map > m_map;
};


#endif






I perform resource construction via a const char * because many types of resource allocation calls may end up bound to Lua, and this simplifies things.
Sign in to follow this  


0 Comments


Recommended Comments

There are no comments to display.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now