Skip to content

Instantly share code, notes, and snippets.

@emileber
Last active January 24, 2017 19:36
Show Gist options
  • Save emileber/8516592 to your computer and use it in GitHub Desktop.
Save emileber/8516592 to your computer and use it in GitHub Desktop.
Resources or assets manager template in C++. Uses a Singleton pattern template as well, which I'm not fond of, but works really well in this particular case. Feel free to use it in your own personal or commercial code. The whole lib is available at https://github.com/PrismalStudio/PrismalUtils
/**
* @file Resource.cpp
* @brief Implementation of Resource methods. Mainly getters/setters.
* @author E. Bergeron
* @date 2012-02-13
* @copyright Prismal Studio 2008-2013 www.prismalstudio.com
*/
#include "Resource.h"
namespace Util
{
Resource::Resource() :
mFilename(),
mLoaded(false)
{
}
Resource::~Resource()
{
}
bool Resource::reload()
{
return (getFilename() != "") ? load(getFilename()) : false;
}
std::string Resource::getFilename() const
{
return mFilename;
}
void Resource::setFilename(const std::string& filename)
{
mFilename = filename;
}
bool Resource::isLoaded() const
{
return mLoaded;
}
void Resource::setLoaded(bool loaded)
{
mLoaded = loaded;
}
} // namespace Util
/**
* @file Resource.h
* @brief Pure virtual class to be used as a the parent class with the generic Manager template
* @details You must implement load, which is the point of the Resource class.
*
* @author E. Bergeron
* @date 2012-02-13
* @pre inherit from this class in a subclass that must be managed.
* @copyright Prismal Studio 2008-2013 www.prismalstudio.com
*/
#ifndef RESOURCE_H_
#define RESOURCE_H_
#include <string>
namespace Util
{
class Resource
{
public:
/**
* Default constructor
*/
Resource();
virtual ~Resource();
/**
* Pure virtual function, MUST be implement in the sub-class
* @param filename
* @return true if it loaded correctly, false otherwise.
*/
virtual bool load(const std::string& filename) = 0;
/**
* Reload the resource
* @return false on failed attempt
*/
virtual bool reload();
/**
* GETTER / SETTER
*/
std::string getFilename() const;
void setFilename(const std::string& filename);
bool isLoaded() const;
protected:
void setLoaded(bool loaded);
std::string mFilename; /**< the filename and path if necessary to access the resource */
bool mLoaded; /**< loading flag */
};
} // namespace Util
#endif /* RESOURCE_H_ */
/**
* @file TManager.h
* @brief Generic Template to manage Ressource sub-class.
* @details It protects you from loading a file twice.
*
* NO NEED TO CREATE, IT'S A SINGLETON.
*
* To have access to it:
* TManager<YourResourceSubClass>::getInstance();
*
* To get a ressource:
* TManager<YourResourceSubClass>::getInstance()->loadResource("resourceFilePath");
*
* The file path serves as a key, if you use loadResource with a file
* that has already been loaded, you'll get the pointer to that resource.
*
* CHANGES:
* 24-02-2013 EB useless if inside isLoaded
*
* @author E. Bergeron
* @date 2012-02-13
* @pre a class that inherit from Resource
* @copyright Prismal Studio 2008-2013 www.prismalstudio.com
*/
#ifndef TManager_H_
#define TManager_H_
#include "TSingleton.h"
#include <map>
namespace Util
{
template<typename T>
class TResourceManager: public TSingleton<TResourceManager<T> >
{
friend class TSingleton<TResourceManager<T> > ;
public:
/**
* Load the resource only if not already register in the map container.
* @param filename is the key in the map of ressource
* @return a pointer to the resource itself or NULL if it failed
*/
T * load(const std::string& filename);
/**
* Clear the map
*/
void deleteAll();
/**
* Reload all the ressource in the map
*/
void reloadAll();
/**
* Check if a file is already in the map
* @param filename ...obvious
* @return true if filename is already loaded in the map
*/
bool isLoaded(std::string filename);
/**
* If not already loaded, add the resource to the map
* @param resource of the sub-type to register
*/
void registerResource(T * resource);
/**
* Removes a texture from management
* @param resource of the sub-type to unregister
*/
void unRegisterResource(T * resource);
/**
* To get a string of all the keys (filename) in the map
* @return a string of all keys on a line each
*/
std::string listAllKey();
protected:
TResourceManager();
virtual ~TResourceManager();
private:
std::map<std::string, T *> mResourceMap; /**< the map in which all the resource are stored */
};
template<typename T>
inline TResourceManager<T>::TResourceManager()
{
}
template<typename T>
inline TResourceManager<T>::~TResourceManager()
{
deleteAll();
}
/**
* Load the resource only if not already register in the map container.
* @param filename is the key in the map of ressource
* @return a pointer to the resource itself or NULL if it failed
*/
template<typename T>
inline T * TResourceManager<T>::load(const std::string& filename)
{
if (!isLoaded(filename))
{
T * newResource = new T();
newResource->setFilename(filename);
// only register a loaded resource
// load return false on failed attempt
if (newResource->load(filename))
{
registerResource(newResource);
return newResource;
}
}
else
{
return mResourceMap[filename];
}
return NULL;
}
/**
* Clear the map
*/
template<typename T>
inline void TResourceManager<T>::deleteAll()
{
typename std::map<std::string, T*>::iterator pos = mResourceMap.begin();
while (pos != mResourceMap.end())
{
delete (*pos).second;
pos++;
}
mResourceMap.clear();
}
/**
* Reload all the ressource in the map
*/
template<typename T>
inline void TResourceManager<T>::reloadAll()
{
typename std::map<std::string, T*>::iterator pos = mResourceMap.begin();
while (pos != mResourceMap.end())
{
(*pos).second->reload();
pos++;
}
}
/**
* Check if a file is already in the map
* @param filename ...obvious
* @return true if filename is already loaded in the map
*/
template<typename T>
inline bool TResourceManager<T>::isLoaded(std::string filename)
{
return (mResourceMap.find(filename) != mResourceMap.end());
}
/**
* If not already loaded, add the resource to the map
* @param resource of the sub-type to register
*/
template<typename T>
inline void TResourceManager<T>::registerResource(T * resource)
{
if (!isLoaded(resource->getFilename()))
{
mResourceMap[resource->getFilename()] = resource;
}
}
/**
* Removes a texture from management
* @param resource of the sub-type to unregister
*/
template<typename T>
inline void TResourceManager<T>::unRegisterResource(T * resource)
{
if (isLoaded(resource->getFilename()))
{
mResourceMap.erase(resource->getFilename());
}
}
/**
* To get a string of all the keys (filename) in the map
* @return a string of all keys on a line each
*/
template<typename T>
inline std::string TResourceManager<T>::listAllKey()
{
std::string listStr;
typename std::map<std::string, T*>::iterator pos = mResourceMap.begin();
while (pos != mResourceMap.end())
{
listStr += (*pos).first + "\n";
pos++;
}
return listStr;
}
} // namespace Util
#endif /* TManager_H_ */
/**
* @file TSingleton.h
* @brief Easily make your class a singleton by inheriting from this class.
* @details To use it, first make the constructor and destructor private.
* Then, inherit from this class like this:
*
* class YourClass: public TSingleton< YourClass > {
* friend class TSingleton< YourClass > ;
*
* It's important to make it a friend class to have access to the constructor and destructor.
*
* @author E. Bergeron
* @date 2011-12-26
* @pre inherit from this class in a subclass that you want it to be a singleton.
* @copyright Prismal Studio 2008-2013 www.prismalstudio.com
*/
#ifndef SINGLETON_H_
#define SINGLETON_H_
namespace Util
{
template<typename T>
class TSingleton
{
protected:
/**
* Protected Constructor and destructor
* You don't want anyone to create an
* instance of T except T which derive
* from the TSingleton template.
*/
TSingleton()
{
}
virtual ~TSingleton()
{
}
public:
/**
* Global access, create the instance if not already done.
* @return a T pointer of the single instance
*/
static T *getInstance()
{
if (0 == _singleton)
{
_singleton = new T;
}
return (static_cast<T*>(_singleton));
}
/**
* Kills the only instance
*/
static void kill()
{
if (0 != _singleton)
{
delete _singleton;
_singleton = 0;
}
}
private:
static T *_singleton; /**< unique instance static T pointer */
};
/**
* initialize it to null
*/
template<typename T>
T *TSingleton<T>::_singleton = 0;
} // namespace
#endif /* SINGLETON_H_ */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment