ResourceManager class for game engine
$begingroup$
Writing a very basic game engine (just a bunch of utilities that I may use later if I decide to make a game), and I'm currently working on designing the ResourceManager class that keeps track of all resources currently in use.
Resource.h
#ifndef RESOURCE_H
#define RESOURCE_H
#include<string>
typedef unsigned int ResourceId;
typedef std::string ResourcePath;
namespace Real
{
enum class ResourceType
{
NONE,
VIDEO,
TEXTURE,
FONT
/*
SFML streams audio, so don't really need a ResourceManager for that
*/
};
template<typename T>
class Resource
{
protected:
ResourceId id;
ResourcePath path;
ResourceType type;
T* resource;
public:
// creates an empty Resource object
Resource();
Resource(ResourceId _id, ResourcePath _path, ResourceType _type);
~Resource();
/*
* Leaving the creation of ResourceId upto the ResourceManager
* Checking whether resource already exists is the job of the ResourceManager.
* load() operators under the assumption that any new Resource object created is for
* a resource that doesn't yet exist
*/
void load();
void unload();
size_t getSize();
void setResourceId(ResourceId _id);
ResourceId getResourceId() const;
// on getting a new resource path, the current resource is destroyed, and a new resource is created with the ResourceId = current id
void setResourcePath(ResourcePath _path);
ResourcePath getResourcePath() const;
// the deference operator returns the pointer to the actual resource stored in memory
T* operator*() const;
};
}
#endif
Resource.cpp
#include "Resource.h"
namespace Real
{
template<typename T>
Resource<T>::Resource() : id(0), type(ResourceType::None), path(nullptr), resource(nullptr)
{}
template<typename T>
Resource<T>::Resource(ResourceId _id, ResourcePath _path, ResourceType _type): id(_id), path(_path), _type(type)
{
load();
}
template<typename T>
Resource<T>::~Resource()
{
unload();
}
template<typename T>
void Resource<T>::load()
{
resource = new T();
if (!resource->loadFromFile(path))
{
//TODO: define defaultpath inside Resource.h that points to default resource in case load fails
resource->loadFromFile(defaultpath);
}
}
template<typename T>
void Resource<T>::unload()
{
if (resource != nullptr)
delete resource;
}
template<typename T>
size_t Resource<T>::getSize()
{
//TODO
return 0;
}
template<typename T>
void Resource<T>::setResourceId(ResourceId _id)
{
id = _id;
}
template<typename T>
ResourceId Resource<T>::getResourceId() const
{
return id;
}
template<typename T>
void Resource<T>::setResourcePath(ResourcePath _path)
{
unload();
load(_path);
}
template<typename T>
ResourcePath Resource<T>::getResourcePath() const
{
return path;
}
template<typename T>
T* Resource<T>::operator*() const
{
return resource;
}
}
ResourceManager.h
#ifndef RESOURCE_MANAGER_H
#define RESOURCE_MANAGER_H
#include<unordered_map>
#include "Resource.h"
namespace Real
{
template<typename T>
class ResourceManager
{
protected:
std::unordered_map<ResourcePath, Resource<T>> resources;
ResourceId nextId; // variables that hold the next ResourceId to be assigned to a resource
public:
ResourceManager();
~ResourceManager();
Resource<T> loadResource(ResourcePath path, ResourceType type);
bool unloadResource(ResourcePath path);
Resource<T> getResource(ResourcePath path);
private:
Resource<T> addNewResource(ResourcePath path, ResourceType type);
};
}
#endif
ResourceManager.cpp
#include "ResourceManager.h"
namespace Real
{
template<typename T>
ResourceManager<T>::ResourceManager(): nextId(0)
{}
template<typename T>
ResourceManager<T>::~ResourceManager()
{
resources.clear(); // Calls the destructor for every Resource object, ensuring that the heap-allocated objects are deleted
}
template<typename T>
Resource<T> ResourceManager<T>::loadResource(ResourcePath path, ResourceType type)
{
typename std::unordered_map<ResourcePath, Resource<T>>::const_iterator it = resources.find(path);
if (it == resources.end())
{
addNewResource(path, type);
}
else
{
return resources.at(ResourcePath);
}
}
template<typename T>
bool ResourceManager<T>::unloadResource(ResourcePath path)
{
typename std::unordered_map<ResourcePath, Resource<T>>::const_iterator it = resources.find(path);
if (it == resources.end())
{
return false;
}
resources.erase(ResourcePath);
}
template<typename T>
Resource<T> ResourceManager<T>::getResource(ResourcePath path)
{
typename std::unordered_map<ResourcePath, Resource<T>>::const_iterator it = resources.find(path);
if (it == resources.end())
{
return nullptr;
}
return resources.at(path);
}
template<typename T>
Resource<T> ResourceManager<T>::addNewResource(ResourcePath path, ResourceType type)
{
Resource<T> newResource(path, type);
resources.insert(newResource);
nextId += 1;
return newResource;
}
}
Here's where I am having trouble deciding on the best route.
1) I'm using SFML, and am assuming that the type being passed as template argument is going to be SFML types sf::Texture
, sf::Font
, etc. Keeping that in mind, is it better to keep the code the way it is, or should I create a base ResourceManager
class, from which different types of ResourceManagers (TextureManager
,FontManager
) inherit from?
2) In Resource.cpp
, there is defaultpath
variable which points to a default resource if the user-provided path to the resource is not valid/cannot be loaded. Since I'm using templates, I don't really have a good way of making sure defaultpath would contain the path for the appropriate type of resource (for example, Resource<sf::Texture>
's defaultpath
would contain the path to an image).
3) Since the iterator is being created every I want to update the map, should I create a single static iterator beforehand, and use that instead of creating a new one every function call?
Any feedback would be much appreciated!
c++ c++17
New contributor
$endgroup$
add a comment |
$begingroup$
Writing a very basic game engine (just a bunch of utilities that I may use later if I decide to make a game), and I'm currently working on designing the ResourceManager class that keeps track of all resources currently in use.
Resource.h
#ifndef RESOURCE_H
#define RESOURCE_H
#include<string>
typedef unsigned int ResourceId;
typedef std::string ResourcePath;
namespace Real
{
enum class ResourceType
{
NONE,
VIDEO,
TEXTURE,
FONT
/*
SFML streams audio, so don't really need a ResourceManager for that
*/
};
template<typename T>
class Resource
{
protected:
ResourceId id;
ResourcePath path;
ResourceType type;
T* resource;
public:
// creates an empty Resource object
Resource();
Resource(ResourceId _id, ResourcePath _path, ResourceType _type);
~Resource();
/*
* Leaving the creation of ResourceId upto the ResourceManager
* Checking whether resource already exists is the job of the ResourceManager.
* load() operators under the assumption that any new Resource object created is for
* a resource that doesn't yet exist
*/
void load();
void unload();
size_t getSize();
void setResourceId(ResourceId _id);
ResourceId getResourceId() const;
// on getting a new resource path, the current resource is destroyed, and a new resource is created with the ResourceId = current id
void setResourcePath(ResourcePath _path);
ResourcePath getResourcePath() const;
// the deference operator returns the pointer to the actual resource stored in memory
T* operator*() const;
};
}
#endif
Resource.cpp
#include "Resource.h"
namespace Real
{
template<typename T>
Resource<T>::Resource() : id(0), type(ResourceType::None), path(nullptr), resource(nullptr)
{}
template<typename T>
Resource<T>::Resource(ResourceId _id, ResourcePath _path, ResourceType _type): id(_id), path(_path), _type(type)
{
load();
}
template<typename T>
Resource<T>::~Resource()
{
unload();
}
template<typename T>
void Resource<T>::load()
{
resource = new T();
if (!resource->loadFromFile(path))
{
//TODO: define defaultpath inside Resource.h that points to default resource in case load fails
resource->loadFromFile(defaultpath);
}
}
template<typename T>
void Resource<T>::unload()
{
if (resource != nullptr)
delete resource;
}
template<typename T>
size_t Resource<T>::getSize()
{
//TODO
return 0;
}
template<typename T>
void Resource<T>::setResourceId(ResourceId _id)
{
id = _id;
}
template<typename T>
ResourceId Resource<T>::getResourceId() const
{
return id;
}
template<typename T>
void Resource<T>::setResourcePath(ResourcePath _path)
{
unload();
load(_path);
}
template<typename T>
ResourcePath Resource<T>::getResourcePath() const
{
return path;
}
template<typename T>
T* Resource<T>::operator*() const
{
return resource;
}
}
ResourceManager.h
#ifndef RESOURCE_MANAGER_H
#define RESOURCE_MANAGER_H
#include<unordered_map>
#include "Resource.h"
namespace Real
{
template<typename T>
class ResourceManager
{
protected:
std::unordered_map<ResourcePath, Resource<T>> resources;
ResourceId nextId; // variables that hold the next ResourceId to be assigned to a resource
public:
ResourceManager();
~ResourceManager();
Resource<T> loadResource(ResourcePath path, ResourceType type);
bool unloadResource(ResourcePath path);
Resource<T> getResource(ResourcePath path);
private:
Resource<T> addNewResource(ResourcePath path, ResourceType type);
};
}
#endif
ResourceManager.cpp
#include "ResourceManager.h"
namespace Real
{
template<typename T>
ResourceManager<T>::ResourceManager(): nextId(0)
{}
template<typename T>
ResourceManager<T>::~ResourceManager()
{
resources.clear(); // Calls the destructor for every Resource object, ensuring that the heap-allocated objects are deleted
}
template<typename T>
Resource<T> ResourceManager<T>::loadResource(ResourcePath path, ResourceType type)
{
typename std::unordered_map<ResourcePath, Resource<T>>::const_iterator it = resources.find(path);
if (it == resources.end())
{
addNewResource(path, type);
}
else
{
return resources.at(ResourcePath);
}
}
template<typename T>
bool ResourceManager<T>::unloadResource(ResourcePath path)
{
typename std::unordered_map<ResourcePath, Resource<T>>::const_iterator it = resources.find(path);
if (it == resources.end())
{
return false;
}
resources.erase(ResourcePath);
}
template<typename T>
Resource<T> ResourceManager<T>::getResource(ResourcePath path)
{
typename std::unordered_map<ResourcePath, Resource<T>>::const_iterator it = resources.find(path);
if (it == resources.end())
{
return nullptr;
}
return resources.at(path);
}
template<typename T>
Resource<T> ResourceManager<T>::addNewResource(ResourcePath path, ResourceType type)
{
Resource<T> newResource(path, type);
resources.insert(newResource);
nextId += 1;
return newResource;
}
}
Here's where I am having trouble deciding on the best route.
1) I'm using SFML, and am assuming that the type being passed as template argument is going to be SFML types sf::Texture
, sf::Font
, etc. Keeping that in mind, is it better to keep the code the way it is, or should I create a base ResourceManager
class, from which different types of ResourceManagers (TextureManager
,FontManager
) inherit from?
2) In Resource.cpp
, there is defaultpath
variable which points to a default resource if the user-provided path to the resource is not valid/cannot be loaded. Since I'm using templates, I don't really have a good way of making sure defaultpath would contain the path for the appropriate type of resource (for example, Resource<sf::Texture>
's defaultpath
would contain the path to an image).
3) Since the iterator is being created every I want to update the map, should I create a single static iterator beforehand, and use that instead of creating a new one every function call?
Any feedback would be much appreciated!
c++ c++17
New contributor
$endgroup$
add a comment |
$begingroup$
Writing a very basic game engine (just a bunch of utilities that I may use later if I decide to make a game), and I'm currently working on designing the ResourceManager class that keeps track of all resources currently in use.
Resource.h
#ifndef RESOURCE_H
#define RESOURCE_H
#include<string>
typedef unsigned int ResourceId;
typedef std::string ResourcePath;
namespace Real
{
enum class ResourceType
{
NONE,
VIDEO,
TEXTURE,
FONT
/*
SFML streams audio, so don't really need a ResourceManager for that
*/
};
template<typename T>
class Resource
{
protected:
ResourceId id;
ResourcePath path;
ResourceType type;
T* resource;
public:
// creates an empty Resource object
Resource();
Resource(ResourceId _id, ResourcePath _path, ResourceType _type);
~Resource();
/*
* Leaving the creation of ResourceId upto the ResourceManager
* Checking whether resource already exists is the job of the ResourceManager.
* load() operators under the assumption that any new Resource object created is for
* a resource that doesn't yet exist
*/
void load();
void unload();
size_t getSize();
void setResourceId(ResourceId _id);
ResourceId getResourceId() const;
// on getting a new resource path, the current resource is destroyed, and a new resource is created with the ResourceId = current id
void setResourcePath(ResourcePath _path);
ResourcePath getResourcePath() const;
// the deference operator returns the pointer to the actual resource stored in memory
T* operator*() const;
};
}
#endif
Resource.cpp
#include "Resource.h"
namespace Real
{
template<typename T>
Resource<T>::Resource() : id(0), type(ResourceType::None), path(nullptr), resource(nullptr)
{}
template<typename T>
Resource<T>::Resource(ResourceId _id, ResourcePath _path, ResourceType _type): id(_id), path(_path), _type(type)
{
load();
}
template<typename T>
Resource<T>::~Resource()
{
unload();
}
template<typename T>
void Resource<T>::load()
{
resource = new T();
if (!resource->loadFromFile(path))
{
//TODO: define defaultpath inside Resource.h that points to default resource in case load fails
resource->loadFromFile(defaultpath);
}
}
template<typename T>
void Resource<T>::unload()
{
if (resource != nullptr)
delete resource;
}
template<typename T>
size_t Resource<T>::getSize()
{
//TODO
return 0;
}
template<typename T>
void Resource<T>::setResourceId(ResourceId _id)
{
id = _id;
}
template<typename T>
ResourceId Resource<T>::getResourceId() const
{
return id;
}
template<typename T>
void Resource<T>::setResourcePath(ResourcePath _path)
{
unload();
load(_path);
}
template<typename T>
ResourcePath Resource<T>::getResourcePath() const
{
return path;
}
template<typename T>
T* Resource<T>::operator*() const
{
return resource;
}
}
ResourceManager.h
#ifndef RESOURCE_MANAGER_H
#define RESOURCE_MANAGER_H
#include<unordered_map>
#include "Resource.h"
namespace Real
{
template<typename T>
class ResourceManager
{
protected:
std::unordered_map<ResourcePath, Resource<T>> resources;
ResourceId nextId; // variables that hold the next ResourceId to be assigned to a resource
public:
ResourceManager();
~ResourceManager();
Resource<T> loadResource(ResourcePath path, ResourceType type);
bool unloadResource(ResourcePath path);
Resource<T> getResource(ResourcePath path);
private:
Resource<T> addNewResource(ResourcePath path, ResourceType type);
};
}
#endif
ResourceManager.cpp
#include "ResourceManager.h"
namespace Real
{
template<typename T>
ResourceManager<T>::ResourceManager(): nextId(0)
{}
template<typename T>
ResourceManager<T>::~ResourceManager()
{
resources.clear(); // Calls the destructor for every Resource object, ensuring that the heap-allocated objects are deleted
}
template<typename T>
Resource<T> ResourceManager<T>::loadResource(ResourcePath path, ResourceType type)
{
typename std::unordered_map<ResourcePath, Resource<T>>::const_iterator it = resources.find(path);
if (it == resources.end())
{
addNewResource(path, type);
}
else
{
return resources.at(ResourcePath);
}
}
template<typename T>
bool ResourceManager<T>::unloadResource(ResourcePath path)
{
typename std::unordered_map<ResourcePath, Resource<T>>::const_iterator it = resources.find(path);
if (it == resources.end())
{
return false;
}
resources.erase(ResourcePath);
}
template<typename T>
Resource<T> ResourceManager<T>::getResource(ResourcePath path)
{
typename std::unordered_map<ResourcePath, Resource<T>>::const_iterator it = resources.find(path);
if (it == resources.end())
{
return nullptr;
}
return resources.at(path);
}
template<typename T>
Resource<T> ResourceManager<T>::addNewResource(ResourcePath path, ResourceType type)
{
Resource<T> newResource(path, type);
resources.insert(newResource);
nextId += 1;
return newResource;
}
}
Here's where I am having trouble deciding on the best route.
1) I'm using SFML, and am assuming that the type being passed as template argument is going to be SFML types sf::Texture
, sf::Font
, etc. Keeping that in mind, is it better to keep the code the way it is, or should I create a base ResourceManager
class, from which different types of ResourceManagers (TextureManager
,FontManager
) inherit from?
2) In Resource.cpp
, there is defaultpath
variable which points to a default resource if the user-provided path to the resource is not valid/cannot be loaded. Since I'm using templates, I don't really have a good way of making sure defaultpath would contain the path for the appropriate type of resource (for example, Resource<sf::Texture>
's defaultpath
would contain the path to an image).
3) Since the iterator is being created every I want to update the map, should I create a single static iterator beforehand, and use that instead of creating a new one every function call?
Any feedback would be much appreciated!
c++ c++17
New contributor
$endgroup$
Writing a very basic game engine (just a bunch of utilities that I may use later if I decide to make a game), and I'm currently working on designing the ResourceManager class that keeps track of all resources currently in use.
Resource.h
#ifndef RESOURCE_H
#define RESOURCE_H
#include<string>
typedef unsigned int ResourceId;
typedef std::string ResourcePath;
namespace Real
{
enum class ResourceType
{
NONE,
VIDEO,
TEXTURE,
FONT
/*
SFML streams audio, so don't really need a ResourceManager for that
*/
};
template<typename T>
class Resource
{
protected:
ResourceId id;
ResourcePath path;
ResourceType type;
T* resource;
public:
// creates an empty Resource object
Resource();
Resource(ResourceId _id, ResourcePath _path, ResourceType _type);
~Resource();
/*
* Leaving the creation of ResourceId upto the ResourceManager
* Checking whether resource already exists is the job of the ResourceManager.
* load() operators under the assumption that any new Resource object created is for
* a resource that doesn't yet exist
*/
void load();
void unload();
size_t getSize();
void setResourceId(ResourceId _id);
ResourceId getResourceId() const;
// on getting a new resource path, the current resource is destroyed, and a new resource is created with the ResourceId = current id
void setResourcePath(ResourcePath _path);
ResourcePath getResourcePath() const;
// the deference operator returns the pointer to the actual resource stored in memory
T* operator*() const;
};
}
#endif
Resource.cpp
#include "Resource.h"
namespace Real
{
template<typename T>
Resource<T>::Resource() : id(0), type(ResourceType::None), path(nullptr), resource(nullptr)
{}
template<typename T>
Resource<T>::Resource(ResourceId _id, ResourcePath _path, ResourceType _type): id(_id), path(_path), _type(type)
{
load();
}
template<typename T>
Resource<T>::~Resource()
{
unload();
}
template<typename T>
void Resource<T>::load()
{
resource = new T();
if (!resource->loadFromFile(path))
{
//TODO: define defaultpath inside Resource.h that points to default resource in case load fails
resource->loadFromFile(defaultpath);
}
}
template<typename T>
void Resource<T>::unload()
{
if (resource != nullptr)
delete resource;
}
template<typename T>
size_t Resource<T>::getSize()
{
//TODO
return 0;
}
template<typename T>
void Resource<T>::setResourceId(ResourceId _id)
{
id = _id;
}
template<typename T>
ResourceId Resource<T>::getResourceId() const
{
return id;
}
template<typename T>
void Resource<T>::setResourcePath(ResourcePath _path)
{
unload();
load(_path);
}
template<typename T>
ResourcePath Resource<T>::getResourcePath() const
{
return path;
}
template<typename T>
T* Resource<T>::operator*() const
{
return resource;
}
}
ResourceManager.h
#ifndef RESOURCE_MANAGER_H
#define RESOURCE_MANAGER_H
#include<unordered_map>
#include "Resource.h"
namespace Real
{
template<typename T>
class ResourceManager
{
protected:
std::unordered_map<ResourcePath, Resource<T>> resources;
ResourceId nextId; // variables that hold the next ResourceId to be assigned to a resource
public:
ResourceManager();
~ResourceManager();
Resource<T> loadResource(ResourcePath path, ResourceType type);
bool unloadResource(ResourcePath path);
Resource<T> getResource(ResourcePath path);
private:
Resource<T> addNewResource(ResourcePath path, ResourceType type);
};
}
#endif
ResourceManager.cpp
#include "ResourceManager.h"
namespace Real
{
template<typename T>
ResourceManager<T>::ResourceManager(): nextId(0)
{}
template<typename T>
ResourceManager<T>::~ResourceManager()
{
resources.clear(); // Calls the destructor for every Resource object, ensuring that the heap-allocated objects are deleted
}
template<typename T>
Resource<T> ResourceManager<T>::loadResource(ResourcePath path, ResourceType type)
{
typename std::unordered_map<ResourcePath, Resource<T>>::const_iterator it = resources.find(path);
if (it == resources.end())
{
addNewResource(path, type);
}
else
{
return resources.at(ResourcePath);
}
}
template<typename T>
bool ResourceManager<T>::unloadResource(ResourcePath path)
{
typename std::unordered_map<ResourcePath, Resource<T>>::const_iterator it = resources.find(path);
if (it == resources.end())
{
return false;
}
resources.erase(ResourcePath);
}
template<typename T>
Resource<T> ResourceManager<T>::getResource(ResourcePath path)
{
typename std::unordered_map<ResourcePath, Resource<T>>::const_iterator it = resources.find(path);
if (it == resources.end())
{
return nullptr;
}
return resources.at(path);
}
template<typename T>
Resource<T> ResourceManager<T>::addNewResource(ResourcePath path, ResourceType type)
{
Resource<T> newResource(path, type);
resources.insert(newResource);
nextId += 1;
return newResource;
}
}
Here's where I am having trouble deciding on the best route.
1) I'm using SFML, and am assuming that the type being passed as template argument is going to be SFML types sf::Texture
, sf::Font
, etc. Keeping that in mind, is it better to keep the code the way it is, or should I create a base ResourceManager
class, from which different types of ResourceManagers (TextureManager
,FontManager
) inherit from?
2) In Resource.cpp
, there is defaultpath
variable which points to a default resource if the user-provided path to the resource is not valid/cannot be loaded. Since I'm using templates, I don't really have a good way of making sure defaultpath would contain the path for the appropriate type of resource (for example, Resource<sf::Texture>
's defaultpath
would contain the path to an image).
3) Since the iterator is being created every I want to update the map, should I create a single static iterator beforehand, and use that instead of creating a new one every function call?
Any feedback would be much appreciated!
c++ c++17
c++ c++17
New contributor
New contributor
edited 1 min ago
Rish
New contributor
asked 8 mins ago
RishRish
1
1
New contributor
New contributor
add a comment |
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Rish is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f214586%2fresourcemanager-class-for-game-engine%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Rish is a new contributor. Be nice, and check out our Code of Conduct.
Rish is a new contributor. Be nice, and check out our Code of Conduct.
Rish is a new contributor. Be nice, and check out our Code of Conduct.
Rish is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f214586%2fresourcemanager-class-for-game-engine%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown