#include #include #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); } std::istream::pos_type MemoryStreamBuf::seekoff( std::istream::off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which) { if (dir == std::ios_base::cur) gbump(off); else if (dir == std::ios_base::end) setg(eback(), egptr() + off, egptr()); else if (dir == std::ios_base::beg) setg(eback(), eback() + off, egptr()); return gptr() - eback(); } MemoryStreamRead::MemoryStreamRead(const void* p, const std::size_t n) : std::istream(new MemoryStreamBuf((void*)p, n)) {} MemoryStreamRead::~MemoryStreamRead(){ delete rdbuf(); } static std::unordered_map* _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 { return std::make_unique(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(); 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<