resources

This commit is contained in:
2024-07-30 21:51:25 +03:00
parent 660fb5247c
commit 22c64c9e9b
17 changed files with 259 additions and 18 deletions

View File

@@ -0,0 +1,84 @@
#include <unordered_map>
#include <fstream>
#include <sstream>
#include "../UsefulException.hpp"
#include "../format.hpp"
#include "Resources.hpp"
#include "embedded_resources.h"
namespace ougge::Resources {
Resource::Resource(const std::string& path, const std::size_t size, StreamFactoryMethod open_read_steam_func)
: path(path), size(size), openStream(open_read_steam_func)
{}
MemoryStreamBuf::MemoryStreamBuf(void* _p, const std::size_t n){
char* p=(char*)_p;
setg(p, p, p + n);
setp(p, p + n);
}
class MemoryStreamRead : public std::istream {
public:
MemoryStreamRead(const void* p, const std::size_t n)
: std::istream(new MemoryStreamBuf((void*)p, n))
{}
virtual ~MemoryStreamRead(){
delete rdbuf();
}
};
static std::unordered_map<std::string, Resource>* _resourceMap = nullptr;
void loadEmbeddedResources(){
for(int i = 0; i < EmbeddedResource_table_count; i++){
const EmbeddedResource& e = EmbeddedResource_table[i];
std::cout <<"loading resource '" << e.path << "' "
<< formatSizeHumanReadable(e.size) << std::endl;
auto embedded_resource_factory = [e]() -> std::unique_ptr<std::istream> {
return std::make_unique<MemoryStreamRead>(e.data, e.size);
};
auto r = _resourceMap->emplace(e.path,
Resource(e.path, e.size, embedded_resource_factory));
if(!r.second)
throw UsefulException(format("can't load duplicate resource '%s'", e.path));
}
}
void init(){
if(_resourceMap != nullptr)
throw UsefulException("resource has been initialized already");
_resourceMap = new std::unordered_map<std::string, Resource>();
loadEmbeddedResources();
}
Resource& getResource(const std::string& path){
auto it = _resourceMap->find(path);
if(it == _resourceMap->end())
throw UsefulException(format("can't find resource '%s'", path.c_str()));
return it->second;
}
std::string formatSizeHumanReadable(std::size_t b){
std::stringstream ss;
ss.precision(3);
std::size_t k = b / 1024;
std::size_t m = k / 1024;
std::size_t g = m / 1024;
if(g)
ss<<m / 1024.0f<<'G';
else if(m)
ss<<k / 1024.0f<<'M';
else if(k)
ss<<b / 1024.0f<<'K';
else ss<<b;
return ss.str();
}
}