mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-11-26 03:12:18 -05:00
Optimize away memory allocations (#340)
This commit is contained in:
parent
bd6e637fee
commit
d8d1388ec6
@ -204,7 +204,7 @@ namespace Ship {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<SFILE_FIND_DATA> Archive::ListFiles(const std::string& searchMask) {
|
||||
std::vector<SFILE_FIND_DATA> Archive::ListFiles(const std::string& searchMask) const {
|
||||
auto fileList = std::vector<SFILE_FIND_DATA>();
|
||||
SFILE_FIND_DATA findContext;
|
||||
HANDLE hFind;
|
||||
@ -248,7 +248,7 @@ namespace Ship {
|
||||
return fileList;
|
||||
}
|
||||
|
||||
bool Archive::HasFile(const std::string& filename) {
|
||||
bool Archive::HasFile(const std::string& filename) const {
|
||||
bool result = false;
|
||||
auto start = std::chrono::steady_clock::now();
|
||||
|
||||
@ -267,8 +267,9 @@ namespace Ship {
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string Archive::HashToString(uint64_t hash) {
|
||||
return hashes[hash];
|
||||
const std::string* Archive::HashToString(uint64_t hash) const {
|
||||
auto it = hashes.find(hash);
|
||||
return it != hashes.end() ? &it->second : nullptr;
|
||||
}
|
||||
|
||||
bool Archive::Load(bool enableWriting, bool genCRCMap) {
|
||||
|
@ -34,9 +34,9 @@ namespace Ship
|
||||
bool AddFile(const std::string& path, uintptr_t fileData, DWORD dwFileSize);
|
||||
bool RemoveFile(const std::string& path);
|
||||
bool RenameFile(const std::string& oldPath, const std::string& newPath);
|
||||
std::vector<SFILE_FIND_DATA> ListFiles(const std::string& searchMask);
|
||||
bool HasFile(const std::string& searchMask);
|
||||
std::string HashToString(uint64_t hash);
|
||||
std::vector<SFILE_FIND_DATA> ListFiles(const std::string& searchMask) const;
|
||||
bool HasFile(const std::string& searchMask) const;
|
||||
const std::string* HashToString(uint64_t hash) const;
|
||||
protected:
|
||||
bool Load(bool enableWriting, bool genCRCMap);
|
||||
bool Unload();
|
||||
|
@ -36,7 +36,7 @@
|
||||
|
||||
// OTRTODO: fix header files for these
|
||||
extern "C" {
|
||||
char* ResourceMgr_GetNameByCRC(uint64_t crc, char* alloc);
|
||||
const char* ResourceMgr_GetNameByCRC(uint64_t crc);
|
||||
int32_t* ResourceMgr_LoadMtxByCRC(uint64_t crc);
|
||||
Vtx* ResourceMgr_LoadVtxByCRC(uint64_t crc);
|
||||
Gfx* ResourceMgr_LoadGfxByCRC(uint64_t crc);
|
||||
@ -134,14 +134,14 @@ static struct RDP {
|
||||
const uint8_t *addr;
|
||||
uint8_t siz;
|
||||
uint32_t width;
|
||||
char* otr_path;
|
||||
const char* otr_path;
|
||||
} texture_to_load;
|
||||
struct {
|
||||
const uint8_t *addr;
|
||||
uint32_t size_bytes;
|
||||
uint32_t full_image_line_size_bytes;
|
||||
uint32_t line_size_bytes;
|
||||
char* otr_path;
|
||||
const char* otr_path;
|
||||
} loaded_texture[2];
|
||||
struct {
|
||||
uint8_t fmt;
|
||||
@ -1636,11 +1636,11 @@ static void gfx_dp_set_scissor(uint32_t mode, uint32_t ulx, uint32_t uly, uint32
|
||||
rdp.viewport_or_scissor_changed = true;
|
||||
}
|
||||
|
||||
static void gfx_dp_set_texture_image(uint32_t format, uint32_t size, uint32_t width, const void* addr, char* otr_path) {
|
||||
static void gfx_dp_set_texture_image(uint32_t format, uint32_t size, uint32_t width, const void* addr, const char* otr_path) {
|
||||
rdp.texture_to_load.addr = (const uint8_t*)addr;
|
||||
rdp.texture_to_load.siz = size;
|
||||
rdp.texture_to_load.width = width;
|
||||
if ( otr_path != nullptr && !strncmp(otr_path, "__OTR__", 7)) otr_path = otr_path + 7;
|
||||
if (otr_path != nullptr && !strncmp(otr_path, "__OTR__", 7)) otr_path = otr_path + 7;
|
||||
rdp.texture_to_load.otr_path = otr_path;
|
||||
}
|
||||
|
||||
@ -2114,7 +2114,7 @@ static void gfx_run_dl(Gfx* cmd) {
|
||||
//puts("dl");
|
||||
int dummy = 0;
|
||||
char dlName[128];
|
||||
char fileName[128];
|
||||
const char* fileName;
|
||||
|
||||
Gfx* dListStart = cmd;
|
||||
uint64_t ourHash = -1;
|
||||
@ -2437,7 +2437,7 @@ static void gfx_run_dl(Gfx* cmd) {
|
||||
uintptr_t addr = cmd->words.w1;
|
||||
cmd++;
|
||||
uint64_t hash = ((uint64_t)cmd->words.w0 << 32) + (uint64_t)cmd->words.w1;
|
||||
ResourceMgr_GetNameByCRC(hash, fileName);
|
||||
fileName = ResourceMgr_GetNameByCRC(hash);
|
||||
#if _DEBUG && 0
|
||||
char* tex = ResourceMgr_LoadTexByCRC(hash);
|
||||
ResourceMgr_GetNameByCRC(hash, fileName);
|
||||
|
@ -40,8 +40,11 @@ namespace Ship
|
||||
|
||||
for (size_t i = 0; i < patches.size(); i++)
|
||||
{
|
||||
std::string hashStr = resMgr->HashToString(patches[i].crc);
|
||||
auto resShared = resMgr->GetCachedFile(hashStr);
|
||||
const std::string* hashStr = resMgr->HashToString(patches[i].crc);
|
||||
if (hashStr == nullptr)
|
||||
continue;
|
||||
|
||||
auto resShared = resMgr->GetCachedFile(hashStr->c_str());
|
||||
if (resShared != nullptr)
|
||||
{
|
||||
auto res = (Ship::DisplayList*)resShared.get();
|
||||
|
@ -215,7 +215,7 @@ namespace Ship {
|
||||
return ToLoad;
|
||||
}
|
||||
|
||||
std::shared_ptr<Ship::Resource> ResourceMgr::GetCachedFile(std::string FilePath) {
|
||||
std::shared_ptr<Ship::Resource> ResourceMgr::GetCachedFile(const char* FilePath) const {
|
||||
auto resCacheFind = ResourceCache.find(FilePath);
|
||||
|
||||
if (resCacheFind != ResourceCache.end() &&
|
||||
@ -227,8 +227,13 @@ namespace Ship {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<Resource> ResourceMgr::LoadResource(std::string FilePath) {
|
||||
auto Promise = LoadResourceAsync(FilePath);
|
||||
std::shared_ptr<Resource> ResourceMgr::LoadResource(const char* FilePath) {
|
||||
auto Res = LoadResourceAsync(FilePath);
|
||||
|
||||
if (std::holds_alternative<std::shared_ptr<Resource>>(Res))
|
||||
return std::get<std::shared_ptr<Resource>>(Res);
|
||||
|
||||
auto& Promise = std::get<std::shared_ptr<ResourcePromise>>(Res);
|
||||
|
||||
if (!Promise->bHasResourceLoaded)
|
||||
{
|
||||
@ -241,21 +246,18 @@ namespace Ship {
|
||||
return Promise->resource;
|
||||
}
|
||||
|
||||
std::shared_ptr<ResourcePromise> ResourceMgr::LoadResourceAsync(std::string FilePath) {
|
||||
StringHelper::ReplaceOriginal(FilePath, "\\", "/");
|
||||
|
||||
if (StringHelper::StartsWith(FilePath, "__OTR__"))
|
||||
FilePath = StringHelper::Split(FilePath, "__OTR__")[1];
|
||||
|
||||
std::shared_ptr<ResourcePromise> Promise = std::make_shared<ResourcePromise>();
|
||||
std::variant<std::shared_ptr<Resource>, std::shared_ptr<ResourcePromise>> ResourceMgr::LoadResourceAsync(const char* FilePath) {
|
||||
if (FilePath[0] == '_' && FilePath[1] == '_' && FilePath[2] == 'O' && FilePath[3] == 'T' && FilePath[4] == 'R' && FilePath[5] == '_' && FilePath[6] == '_')
|
||||
FilePath += 7;
|
||||
|
||||
const std::lock_guard<std::mutex> ResLock(ResourceLoadMutex);
|
||||
auto resCacheFind = ResourceCache.find(FilePath);
|
||||
if (resCacheFind == ResourceCache.end() || resCacheFind->second->isDirty/* || !FileData->bIsLoaded*/) {
|
||||
if (resCacheFind == ResourceCache.end()) {
|
||||
SPDLOG_TRACE("Cache miss on Resource load: {}", FilePath.c_str());
|
||||
SPDLOG_TRACE("Cache miss on Resource load: {}", FilePath);
|
||||
}
|
||||
|
||||
std::shared_ptr<ResourcePromise> Promise = std::make_shared<ResourcePromise>();
|
||||
std::shared_ptr<File> FileData = LoadFile(FilePath);
|
||||
Promise->file = FileData;
|
||||
|
||||
@ -269,12 +271,13 @@ namespace Ship {
|
||||
ResourceLoadQueue.push(Promise);
|
||||
ResourceLoadNotifier.notify_all();
|
||||
}
|
||||
} else {
|
||||
Promise->bHasResourceLoaded = true;
|
||||
Promise->resource = resCacheFind->second;
|
||||
}
|
||||
|
||||
return Promise;
|
||||
return Promise;
|
||||
}
|
||||
else
|
||||
{
|
||||
return resCacheFind->second;
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<std::vector<std::shared_ptr<ResourcePromise>>> ResourceMgr::CacheDirectoryAsync(std::string SearchMask) {
|
||||
@ -282,10 +285,15 @@ namespace Ship {
|
||||
auto fileList = OTR->ListFiles(SearchMask);
|
||||
|
||||
for (DWORD i = 0; i < fileList.size(); i++) {
|
||||
auto file = LoadResourceAsync(fileList.operator[](i).cFileName);
|
||||
if (file != nullptr) {
|
||||
loadedList->push_back(file);
|
||||
auto resource = LoadResourceAsync(fileList.operator[](i).cFileName);
|
||||
if (std::holds_alternative<std::shared_ptr<Resource>>(resource))
|
||||
{
|
||||
auto promise = std::make_shared<ResourcePromise>();
|
||||
promise->bHasResourceLoaded = true;
|
||||
promise->resource = std::get<std::shared_ptr<Resource>>(resource);
|
||||
resource = promise;
|
||||
}
|
||||
loadedList->push_back(std::get<std::shared_ptr<ResourcePromise>>(resource));
|
||||
}
|
||||
|
||||
return loadedList;
|
||||
@ -335,7 +343,7 @@ namespace Ship {
|
||||
ResourceCache.clear();
|
||||
}
|
||||
|
||||
std::string ResourceMgr::HashToString(uint64_t Hash) {
|
||||
const std::string* ResourceMgr::HashToString(uint64_t Hash) const {
|
||||
return OTR->HashToString(Hash);
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <queue>
|
||||
#include <variant>
|
||||
#include "Resource.h"
|
||||
#include "GlobalCtx2.h"
|
||||
|
||||
@ -25,7 +26,7 @@ namespace Ship
|
||||
std::shared_ptr<Archive> GetArchive() { return OTR; }
|
||||
std::shared_ptr<GlobalCtx2> GetContext() { return Context.lock(); }
|
||||
|
||||
std::string HashToString(uint64_t Hash);
|
||||
const std::string* HashToString(uint64_t Hash) const;
|
||||
|
||||
void InvalidateResourceCache();
|
||||
|
||||
@ -33,9 +34,10 @@ namespace Ship
|
||||
void SetGameVersion(uint32_t newGameVersion);
|
||||
std::shared_ptr<File> LoadFileAsync(std::string FilePath);
|
||||
std::shared_ptr<File> LoadFile(std::string FilePath);
|
||||
std::shared_ptr<Ship::Resource> GetCachedFile(std::string FilePath);
|
||||
std::shared_ptr<Resource> LoadResource(std::string FilePath);
|
||||
std::shared_ptr<ResourcePromise> LoadResourceAsync(std::string FilePath);
|
||||
std::shared_ptr<Ship::Resource> GetCachedFile(const char* FilePath) const;
|
||||
std::shared_ptr<Resource> LoadResource(const char* FilePath);
|
||||
std::shared_ptr<Resource> LoadResource(const std::string& FilePath) { return LoadResource(FilePath.c_str()); }
|
||||
std::variant<std::shared_ptr<Resource>, std::shared_ptr<ResourcePromise>> LoadResourceAsync(const char* FilePath);
|
||||
std::shared_ptr<std::vector<std::shared_ptr<Resource>>> CacheDirectory(std::string SearchMask);
|
||||
std::shared_ptr<std::vector<std::shared_ptr<ResourcePromise>>> CacheDirectoryAsync(std::string SearchMask);
|
||||
std::shared_ptr<std::vector<std::shared_ptr<Resource>>> DirtyDirectory(std::string SearchMask);
|
||||
@ -50,7 +52,7 @@ namespace Ship
|
||||
std::weak_ptr<GlobalCtx2> Context;
|
||||
volatile bool bIsRunning;
|
||||
std::map<std::string, std::shared_ptr<File>> FileCache;
|
||||
std::map<std::string, std::shared_ptr<Resource>> ResourceCache;
|
||||
std::map<std::string, std::shared_ptr<Resource>, std::less<>> ResourceCache;
|
||||
std::queue<std::shared_ptr<File>> FileLoadQueue;
|
||||
std::queue<std::shared_ptr<ResourcePromise>> ResourceLoadQueue;
|
||||
std::shared_ptr<Archive> OTR;
|
||||
|
@ -119,17 +119,16 @@ extern "C" {
|
||||
ModInternal::callBindHook(0);
|
||||
}
|
||||
|
||||
char* ResourceMgr_GetNameByCRC(uint64_t crc, char* alloc) {
|
||||
std::string hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc);
|
||||
strcpy(alloc, hashStr.c_str());
|
||||
return (char*)hashStr.c_str();
|
||||
const char* ResourceMgr_GetNameByCRC(uint64_t crc) {
|
||||
const std::string* hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc);
|
||||
return hashStr != nullptr ? hashStr->c_str() : nullptr;
|
||||
}
|
||||
|
||||
Vtx* ResourceMgr_LoadVtxByCRC(uint64_t crc) {
|
||||
std::string hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc);
|
||||
const std::string* hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc);
|
||||
|
||||
if (hashStr != "") {
|
||||
auto res = std::static_pointer_cast<Ship::Array>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr));
|
||||
if (hashStr != nullptr) {
|
||||
auto res = std::static_pointer_cast<Ship::Array>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr->c_str()));
|
||||
|
||||
//if (res != nullptr)
|
||||
return (Vtx*)res->vertices.data();
|
||||
@ -142,10 +141,10 @@ extern "C" {
|
||||
}
|
||||
|
||||
int32_t* ResourceMgr_LoadMtxByCRC(uint64_t crc) {
|
||||
std::string hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc);
|
||||
const std::string* hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc);
|
||||
|
||||
if (hashStr != "") {
|
||||
auto res = std::static_pointer_cast<Ship::Matrix>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr));
|
||||
if (hashStr != nullptr) {
|
||||
auto res = std::static_pointer_cast<Ship::Matrix>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr->c_str()));
|
||||
return (int32_t*)res->mtx.data();
|
||||
} else {
|
||||
return nullptr;
|
||||
@ -153,10 +152,10 @@ extern "C" {
|
||||
}
|
||||
|
||||
Gfx* ResourceMgr_LoadGfxByCRC(uint64_t crc) {
|
||||
std::string hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc);
|
||||
const std::string* hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc);
|
||||
|
||||
if (hashStr != "") {
|
||||
auto res = std::static_pointer_cast<Ship::DisplayList>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr));
|
||||
if (hashStr != nullptr) {
|
||||
auto res = std::static_pointer_cast<Ship::DisplayList>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr->c_str()));
|
||||
return (Gfx*)&res->instructions[0];
|
||||
} else {
|
||||
return nullptr;
|
||||
@ -164,14 +163,14 @@ extern "C" {
|
||||
}
|
||||
|
||||
char* ResourceMgr_LoadTexByCRC(uint64_t crc) {
|
||||
const std::string hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc);
|
||||
const std::string* hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(crc);
|
||||
|
||||
if (!hashStr.empty()) {
|
||||
const auto res = static_cast<Ship::Texture*>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr).get());
|
||||
if (hashStr != nullptr) {
|
||||
const auto res = static_cast<Ship::Texture*>(Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr->c_str()).get());
|
||||
|
||||
ModInternal::bindHook(LOAD_TEXTURE);
|
||||
ModInternal::initBindHook(2,
|
||||
HookParameter({.name = "path", .parameter = (void*)hashStr.c_str() }),
|
||||
HookParameter({.name = "path", .parameter = (void*)hashStr->c_str() }),
|
||||
HookParameter({.name = "texture", .parameter = static_cast<void*>(&res->imageData) })
|
||||
);
|
||||
ModInternal::callBindHook(0);
|
||||
@ -184,11 +183,11 @@ extern "C" {
|
||||
|
||||
void ResourceMgr_RegisterResourcePatch(uint64_t hash, uint32_t instrIndex, uintptr_t origData)
|
||||
{
|
||||
std::string hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(hash);
|
||||
const std::string* hashStr = Ship::GlobalCtx2::GetInstance()->GetResourceManager()->HashToString(hash);
|
||||
|
||||
if (hashStr != "")
|
||||
if (hashStr != nullptr)
|
||||
{
|
||||
auto res = (Ship::Texture*)Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr).get();
|
||||
auto res = (Ship::Texture*)Ship::GlobalCtx2::GetInstance()->GetResourceManager()->LoadResource(hashStr->c_str()).get();
|
||||
|
||||
Ship::Patch patch;
|
||||
patch.crc = hash;
|
||||
|
Loading…
Reference in New Issue
Block a user