Optimize away memory allocations (#340)

This commit is contained in:
Emill 2022-05-15 21:32:05 +02:00 committed by GitHub
parent bd6e637fee
commit d8d1388ec6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 74 additions and 61 deletions

View File

@ -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) {

View File

@ -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();

View File

@ -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);

View File

@ -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();

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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;