Skip to content

Commit

Permalink
Font as resource (#454)
Browse files Browse the repository at this point in the history
  • Loading branch information
briaguya-ai authored Mar 4, 2024
1 parent 972b535 commit ec01bc7
Show file tree
Hide file tree
Showing 12 changed files with 147 additions and 56 deletions.
4 changes: 4 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,10 @@ set(Source_Files__Window__Gui
${CMAKE_CURRENT_SOURCE_DIR}/window/gui/GuiElement.cpp
${CMAKE_CURRENT_SOURCE_DIR}/window/gui/GuiMenuBar.h
${CMAKE_CURRENT_SOURCE_DIR}/window/gui/GuiMenuBar.cpp
${CMAKE_CURRENT_SOURCE_DIR}/window/gui/resource/Font.h
${CMAKE_CURRENT_SOURCE_DIR}/window/gui/resource/Font.cpp
${CMAKE_CURRENT_SOURCE_DIR}/window/gui/resource/FontFactory.h
${CMAKE_CURRENT_SOURCE_DIR}/window/gui/resource/FontFactory.cpp
)

source_group("window/gui" FILES ${Source_Files__Window__Gui})
Expand Down
40 changes: 16 additions & 24 deletions src/resource/ResourceManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,9 @@ bool ResourceManager::DidLoadSuccessfully() {
return mArchiveManager != nullptr && mArchiveManager->IsArchiveLoaded();
}

std::shared_ptr<File> ResourceManager::LoadFileProcess(const std::string& filePath) {
auto file = mArchiveManager->LoadFile(filePath);
std::shared_ptr<File> ResourceManager::LoadFileProcess(const std::string& filePath,
std::shared_ptr<ResourceInitData> initData) {
auto file = mArchiveManager->LoadFile(filePath, initData);
if (file != nullptr) {
SPDLOG_TRACE("Loaded File {} on ResourceManager", file->InitData->Path);
} else {
Expand All @@ -55,18 +56,19 @@ std::shared_ptr<File> ResourceManager::LoadFileProcess(const std::string& filePa
return file;
}

std::shared_ptr<IResource> ResourceManager::LoadResourceProcess(const std::string& filePath, bool loadExact) {
std::shared_ptr<IResource> ResourceManager::LoadResourceProcess(const std::string& filePath, bool loadExact,
std::shared_ptr<ResourceInitData> initData) {
// Check for and remove the OTR signature
if (OtrSignatureCheck(filePath.c_str())) {
const auto newFilePath = filePath.substr(7);
return LoadResourceProcess(newFilePath);
return LoadResourceProcess(newFilePath, false, initData);
}

// Attempt to load the alternate version of the asset, if we fail then we continue trying to load the standard
// asset.
if (!loadExact && CVarGetInteger("gAltAssets", 0) && !filePath.starts_with(IResource::gAltAssetPrefix)) {
const auto altPath = IResource::gAltAssetPrefix + filePath;
auto altResource = LoadResourceProcess(altPath, loadExact);
auto altResource = LoadResourceProcess(altPath, loadExact, initData);

if (altResource != nullptr) {
return altResource;
Expand Down Expand Up @@ -99,7 +101,7 @@ std::shared_ptr<IResource> ResourceManager::LoadResourceProcess(const std::strin
}

// Get the file from the OTR
auto file = LoadFileProcess(filePath);
auto file = LoadFileProcess(filePath, initData);
if (file == nullptr) {
SPDLOG_TRACE("Failed to load resource file at path {}", filePath);
}
Expand Down Expand Up @@ -136,20 +138,9 @@ std::shared_ptr<IResource> ResourceManager::LoadResourceProcess(const std::strin
return resource;
}

std::shared_future<std::shared_ptr<File>> ResourceManager::LoadFileAsync(const std::string& filePath, bool priority) {
if (priority) {
return mThreadPool->submit_front(&ResourceManager::LoadFileProcess, this, filePath).share();
} else {
return mThreadPool->submit_back(&ResourceManager::LoadFileProcess, this, filePath).share();
}
}

std::shared_ptr<File> ResourceManager::LoadFile(const std::string& filePath) {
return LoadFileAsync(filePath, true).get();
}

std::shared_future<std::shared_ptr<IResource>> ResourceManager::LoadResourceAsync(const std::string& filePath,
bool loadExact, bool priority) {
std::shared_future<std::shared_ptr<IResource>>
ResourceManager::LoadResourceAsync(const std::string& filePath, bool loadExact, bool priority,
std::shared_ptr<ResourceInitData> initData) {
// Check for and remove the OTR signature
if (OtrSignatureCheck(filePath.c_str())) {
auto newFilePath = filePath.substr(7);
Expand All @@ -167,14 +158,15 @@ std::shared_future<std::shared_ptr<IResource>> ResourceManager::LoadResourceAsyn
const auto newFilePath = std::string(filePath);

if (priority) {
return mThreadPool->submit_front(&ResourceManager::LoadResourceProcess, this, newFilePath, loadExact);
return mThreadPool->submit_front(&ResourceManager::LoadResourceProcess, this, newFilePath, loadExact, initData);
} else {
return mThreadPool->submit_back(&ResourceManager::LoadResourceProcess, this, newFilePath, loadExact);
return mThreadPool->submit_back(&ResourceManager::LoadResourceProcess, this, newFilePath, loadExact, initData);
}
}

std::shared_ptr<IResource> ResourceManager::LoadResource(const std::string& filePath, bool loadExact) {
auto resource = LoadResourceAsync(filePath, loadExact, true).get();
std::shared_ptr<IResource> ResourceManager::LoadResource(const std::string& filePath, bool loadExact,
std::shared_ptr<ResourceInitData> initData) {
auto resource = LoadResourceAsync(filePath, loadExact, true, initData).get();
if (resource == nullptr) {
SPDLOG_ERROR("Failed to load resource file at path {}", filePath);
}
Expand Down
16 changes: 9 additions & 7 deletions src/resource/ResourceManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,15 @@ class ResourceManager {
bool DidLoadSuccessfully();
std::shared_ptr<ArchiveManager> GetArchiveManager();
std::shared_ptr<ResourceLoader> GetResourceLoader();
std::shared_future<std::shared_ptr<File>> LoadFileAsync(const std::string& filePath, bool priority = false);
std::shared_ptr<File> LoadFile(const std::string& filePath);
std::shared_ptr<IResource> GetCachedResource(const std::string& filePath, bool loadExact = false);
std::shared_ptr<IResource> LoadResource(const std::string& filePath, bool loadExact = false);
std::shared_ptr<IResource> LoadResourceProcess(const std::string& filePath, bool loadExact = false);
std::shared_ptr<IResource> LoadResource(const std::string& filePath, bool loadExact = false,
std::shared_ptr<ResourceInitData> initData = nullptr);
std::shared_ptr<IResource> LoadResourceProcess(const std::string& filePath, bool loadExact = false,
std::shared_ptr<ResourceInitData> initData = nullptr);
size_t UnloadResource(const std::string& filePath);
std::shared_future<std::shared_ptr<IResource>> LoadResourceAsync(const std::string& filePath,
bool loadExact = false, bool priority = false);
std::shared_future<std::shared_ptr<IResource>>
LoadResourceAsync(const std::string& filePath, bool loadExact = false, bool priority = false,
std::shared_ptr<ResourceInitData> initData = nullptr);
std::shared_ptr<std::vector<std::shared_ptr<IResource>>> LoadDirectory(const std::string& searchMask);
std::shared_ptr<std::vector<std::shared_future<std::shared_ptr<IResource>>>>
LoadDirectoryAsync(const std::string& searchMask, bool priority = false);
Expand All @@ -45,7 +46,8 @@ class ResourceManager {
bool OtrSignatureCheck(const char* fileName);

protected:
std::shared_ptr<File> LoadFileProcess(const std::string& filePath);
std::shared_ptr<File> LoadFileProcess(const std::string& filePath,
std::shared_ptr<ResourceInitData> initData = nullptr);
std::shared_ptr<IResource> GetCachedResource(std::variant<ResourceLoadError, std::shared_ptr<IResource>> cacheLine);
std::variant<ResourceLoadError, std::shared_ptr<IResource>> CheckCache(const std::string& filePath,
bool loadExact = false);
Expand Down
28 changes: 17 additions & 11 deletions src/resource/archive/Archive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,18 +203,24 @@ std::shared_ptr<tinyxml2::XMLDocument> Archive::CreateXMLReader(std::shared_ptr<
return xmlReader;
}

std::shared_ptr<File> Archive::LoadFile(const std::string& filePath) {
auto metaFilePath = filePath + ".meta";
auto metaFileToLoad = LoadFileRaw(metaFilePath);

std::shared_ptr<File> Archive::LoadFile(const std::string& filePath, std::shared_ptr<ResourceInitData> initData) {
std::shared_ptr<File> fileToLoad = nullptr;
if (metaFileToLoad != nullptr) {
auto initData = ReadResourceInitData(filePath, metaFileToLoad);
fileToLoad = LoadFileRaw(initData->Path);

if (initData != nullptr) {
fileToLoad = LoadFileRaw(filePath);
fileToLoad->InitData = initData;
} else {
fileToLoad = LoadFileRaw(filePath);
fileToLoad->InitData = ReadResourceInitDataLegacy(filePath, fileToLoad);
auto metaFilePath = filePath + ".meta";
auto metaFileToLoad = LoadFileRaw(metaFilePath);

if (metaFileToLoad != nullptr) {
auto initDataFromMetaFile = ReadResourceInitData(filePath, metaFileToLoad);
fileToLoad = LoadFileRaw(initDataFromMetaFile->Path);
fileToLoad->InitData = initDataFromMetaFile;
} else {
fileToLoad = LoadFileRaw(filePath);
fileToLoad->InitData = ReadResourceInitDataLegacy(filePath, fileToLoad);
}
}

if (fileToLoad == nullptr) {
Expand All @@ -234,10 +240,10 @@ std::shared_ptr<File> Archive::LoadFile(const std::string& filePath) {
return fileToLoad;
}

std::shared_ptr<File> Archive::LoadFile(uint64_t hash) {
std::shared_ptr<File> Archive::LoadFile(uint64_t hash, std::shared_ptr<ResourceInitData> initData) {
const std::string& filePath =
*Context::GetInstance()->GetResourceManager()->GetArchiveManager()->HashToString(hash);
return LoadFile(filePath);
return LoadFile(filePath, initData);
}

std::shared_ptr<ResourceInitData> Archive::CreateDefaultResourceInitData() {
Expand Down
5 changes: 3 additions & 2 deletions src/resource/archive/Archive.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ class Archive {
void Load();
void Unload();

virtual std::shared_ptr<File> LoadFile(const std::string& filePath);
virtual std::shared_ptr<File> LoadFile(uint64_t hash);
virtual std::shared_ptr<File> LoadFile(const std::string& filePath,
std::shared_ptr<ResourceInitData> initData = nullptr);
virtual std::shared_ptr<File> LoadFile(uint64_t hash, std::shared_ptr<ResourceInitData> initData = nullptr);
std::shared_ptr<std::unordered_map<uint64_t, std::string>> ListFiles();
std::shared_ptr<std::unordered_map<uint64_t, std::string>> ListFiles(const std::string& filter);
bool HasFile(const std::string& filePath);
Expand Down
9 changes: 5 additions & 4 deletions src/resource/archive/ArchiveManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,21 +40,22 @@ bool ArchiveManager::IsArchiveLoaded() {
return !mArchives.empty();
}

std::shared_ptr<File> ArchiveManager::LoadFile(const std::string& filePath) {
std::shared_ptr<File> ArchiveManager::LoadFile(const std::string& filePath,
std::shared_ptr<ResourceInitData> initData) {
if (filePath == "") {
return nullptr;
}

return LoadFile(CRC64(filePath.c_str()));
return LoadFile(CRC64(filePath.c_str()), initData);
}

std::shared_ptr<File> ArchiveManager::LoadFile(uint64_t hash) {
std::shared_ptr<File> ArchiveManager::LoadFile(uint64_t hash, std::shared_ptr<ResourceInitData> initData) {
const auto archive = mFileToArchive[hash];
if (archive == nullptr) {
return nullptr;
}

auto file = archive->LoadFile(hash);
auto file = archive->LoadFile(hash, initData);
file->Parent = archive;
return file;
}
Expand Down
5 changes: 3 additions & 2 deletions src/resource/archive/ArchiveManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <unordered_map>
#include <unordered_set>
#include <stdint.h>
#include "resource/File.h"

namespace LUS {
struct File;
Expand All @@ -19,8 +20,8 @@ class ArchiveManager {
~ArchiveManager();

bool IsArchiveLoaded();
std::shared_ptr<File> LoadFile(const std::string& filePath);
std::shared_ptr<File> LoadFile(uint64_t hash);
std::shared_ptr<File> LoadFile(const std::string& filePath, std::shared_ptr<ResourceInitData> initData = nullptr);
std::shared_ptr<File> LoadFile(uint64_t hash, std::shared_ptr<ResourceInitData> initData = nullptr);
std::shared_ptr<File> LoadFileRaw(const std::string& filePath);
std::shared_ptr<File> LoadFileRaw(uint64_t hash);
bool HasFile(const std::string& filePath);
Expand Down
19 changes: 13 additions & 6 deletions src/window/gui/GameOverlay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

#include "public/bridge/consolevariablebridge.h"
#include "resource/File.h"
#include "window/gui/resource/Font.h"
#include "window/gui/resource/FontFactory.h"
#include "resource/archive/Archive.h"
#include "resource/ResourceManager.h"
#include "Context.h"
Expand All @@ -17,12 +19,14 @@ GameOverlay::~GameOverlay() {

void GameOverlay::LoadFont(const std::string& name, const std::string& path, float fontSize) {
ImGuiIO& io = ImGui::GetIO();
std::shared_ptr<File> font = Context::GetInstance()->GetResourceManager()->GetArchiveManager()->LoadFileRaw(path);
if (font->IsLoaded) {
// TODO: Nothing is ever unloading the font or this fontData array.
char* fontData = new char[font->Buffer->size()];
memcpy(fontData, font->Buffer->data(), font->Buffer->size());
mFonts[name] = io.Fonts->AddFontFromMemoryTTF(fontData, font->Buffer->size(), fontSize);
auto initData = std::make_shared<ResourceInitData>();
initData->Format = RESOURCE_FORMAT_BINARY;
initData->Type = static_cast<uint32_t>(RESOURCE_TYPE_FONT);
initData->ResourceVersion = 0;
std::shared_ptr<Font> font = std::static_pointer_cast<Font>(
Context::GetInstance()->GetResourceManager()->LoadResource(path, false, initData));
if (font != nullptr) {
mFonts[name] = io.Fonts->AddFontFromMemoryTTF(font->Data, font->DataSize, fontSize);
}
}

Expand Down Expand Up @@ -127,6 +131,9 @@ ImVec2 GameOverlay::CalculateTextSize(const char* text, const char* textEnd, boo
}

void GameOverlay::Init() {
Context::GetInstance()->GetResourceManager()->GetResourceLoader()->RegisterResourceFactory(
std::make_shared<ResourceFactoryBinaryFontV0>(), RESOURCE_FORMAT_BINARY, "Font",
static_cast<uint32_t>(RESOURCE_TYPE_FONT), 0);
LoadFont("Press Start 2P", "fonts/PressStart2P-Regular.ttf", 12.0f);
LoadFont("Fipps", "fonts/Fipps-Regular.otf", 32.0f);
const std::string defaultFont = mFonts.begin()->first;
Expand Down
20 changes: 20 additions & 0 deletions src/window/gui/resource/Font.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include "Font.h"

namespace LUS {
Font::Font() : Resource(std::shared_ptr<ResourceInitData>()) {
}

Font::~Font() {
if (Data != nullptr) {
delete Data;
}
}

void* Font::GetPointer() {
return Data;
}

size_t Font::GetPointerSize() {
return DataSize * sizeof(char);
}
} // namespace LUS
21 changes: 21 additions & 0 deletions src/window/gui/resource/Font.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once

#include "resource/Resource.h"

namespace LUS {
#define RESOURCE_TYPE_FONT 0x464F4E54 // FONT

class Font : public Resource<void> {
public:
using Resource::Resource;

Font();
~Font();

void* GetPointer() override;
size_t GetPointerSize() override;

char* Data = nullptr;
size_t DataSize;
};
}; // namespace LUS
25 changes: 25 additions & 0 deletions src/window/gui/resource/FontFactory.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#include "window/gui/resource/FontFactory.h"
#include "window/gui/resource/Font.h"
#include "spdlog/spdlog.h"

namespace LUS {
std::shared_ptr<IResource> ResourceFactoryBinaryFontV0::ReadResource(std::shared_ptr<File> file) {
if (!FileHasValidFormatAndReader(file)) {
return nullptr;
}

auto font = std::make_shared<Font>(file->InitData);
auto reader = std::get<std::shared_ptr<BinaryReader>>(file->Reader);

font->DataSize = file->Buffer->size();

font->Data = new char[font->DataSize];
reader->Read(font->Data, font->DataSize);

// for (uint32_t i = 0; i < dataSize; i++) {
// font->Data.push_back(reader->ReadChar());
// }

return font;
}
} // namespace LUS
11 changes: 11 additions & 0 deletions src/window/gui/resource/FontFactory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#pragma once

#include "resource/Resource.h"
#include "resource/ResourceFactoryBinary.h"

namespace LUS {
class ResourceFactoryBinaryFontV0 : public ResourceFactoryBinary {
public:
std::shared_ptr<IResource> ReadResource(std::shared_ptr<File> file) override;
};
}; // namespace LUS

0 comments on commit ec01bc7

Please sign in to comment.