hello, so I am actually making an asset manager, I know there are tools for these but I prefer my own implementations because I have my own specific requirements. So my Asset class has just one requirement, that is it needs to have the implementation details on way on how to load that particular asset. Just think of C#'s Func<T,R> and Action<T>. That is what I am trying to do. Because instead of inheriting from a class just to have your own load implementation is quite cumbersome. I just want to enforce that loading scheme must be on the application level.
Here is my actual implementation:
#ifndef ASSET_HPP
#define ASSET_HPP
#include<map>
using std::map;
using std::pair;
#include<functional>
using std::function;
#include<string>
using std::string;
#include<memory>
using std::unique_ptr;
namespace esc
{
template<class T>
class Asset
{
typedef map<string, unique_ptr<T>> AssetLibrary;
typedef function<T*(const string &)> LoadMethod;
public:
Asset();
explicit Asset(const LoadMethod &);
virtual ~Asset();
bool loadFromFile(const string & oname, const string & path);
bool deleteFromAssetLibrary(const string &aname);
size_t getSize() const;
T * getAsset(const string &);
private:
AssetLibrary library;
LoadMethod loadMethod;
};
template<class T> Asset<T>::Asset(){}
template<class T>
Asset<T>::Asset(const LoadMethod &_m)
: loadMethod(_m)
{
}
template<class T>
Asset<T>::~Asset()
{
}
template<class T>
bool Asset<T>::loadFromFile(const string &oname, const string &path)
{
if(T * asset = loadMethod(path))
{
library.insert(pair<string, unique_ptr<T>>(oname, unique_ptr<T>(asset)));
return true;
}
return false;
}
template<class T>
bool Asset<T>::deleteFromAssetLibrary(const string &oname)
{
if (library.find(oname) == library.end())
{
library.erase(oname);
return false;
}
return true;
}
template<class T>
size_t Asset<T>::getSize() const
{
return library.size();
}
template<class T>
T * Asset<T>::getAsset(const string &oname)
{
if (library.find(oname) == library.end())
return library[oname];
return false;
}
}
#endif
This the Asset<T> class, where T is the type of the asset. It requires on how to load that T regardless of what library I am using.
The following code is the implementation details on GameApplication, game application has the function to load the asset.
#include<iostream>
using std::cout;
using std::endl;
#include "GameApplication.hpp"
...
sf::Texture * GameApplication::loadTextureFromFile(const string & path)
{
cout << "Calling this function..." << endl;
sf::Texture * t = new sf::Texture();
if (!t->loadFromFile(path))
return nullptr;
return t;
}
...
So here's how I "tested" it.
...
GameApplication app;
app.setScreenSize(800, 600);
esc::Asset<sf::Texture> asset(bind(app, &GameApplication::loadTextureFromFile, _1));
if (!asset.loadFromFile("object1", "URL"))
{
cout << "ERROR: file not found" << endl;
}
//return app.run();
...
This code works, well at least in compiling those source codes, but I hit a wall. SFML says that I cannot access private member declared in sf::NonCopyable but doesn't tell which member.
I might have overlooked something. Did I miss something?
PS. Also, don't lecture me yet on wrong designs this and that, that is
not what I actually came here for. I hope you understand. We'll talk about that on my next post.
I just wanna learn std::function so this more of like for learning purposes and this one really bothers me. Thank you any help there is.