Cóż to wiele mówić - próbuję się późną godziną wgryźć w tworzenie klasy, która będzie threadsafe.
#include <functional>
#include <vector>
#include <memory>
#include <utility>
#include <mutex>
template<typename T>
class ResourceManager{
public:
using ResourcePtr = std::unique_ptr<T>;
using SafeResource = std::pair<ResourcePtr, std::mutex>;
using Key = size_t;
using Actions = struct{
std::function<T*(const std::string &)> load;
std::function<void(T *)> unload;
};
public:
ResourceManager(Actions actions):
_actions(actions){}
ResourceManager(const ResourceManager &) = delete;
public:
Key load(const std::string &path){
auto resource = _actions.load(path);
return load(resource);
}
Key load(T *resource){
std::lock_guard<std::mutex> guard(_mutex);
auto resourcePtr = ResourcePtr(resource, _actions.unload);
_resources.push_back(make_pair(resourcePtr, std::mutex()));
return _resources.size()-1;
}
void unload(Key key){
std::lock_guard<std::mutex> guard(_mutex);
_resources.erase(_resources.begin()+key);
}
void operate(Key key, std::function<void(T &)> operation){
auto safeResource = _resources.at(key);
std::lock_guard<std::mutex> guard(safeResource.second);
operation(*safeResource.first);
}
const T *get(Key key) const{
auto safeResource = _resources.at(key);
std::lock_guard<std::mutex> guard(safeResource.second);
return safeResource.first;
}
private:
Actions _actions;
std::vector<SafeResource> _resources;
std::mutex _mutex;
};
Trochę nie wypada... ale co z tego, pff.