2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2025-09-01 14:37:25 +00:00

feat: add loader for fonticon json files

This commit is contained in:
Jan Laupetin
2025-07-23 19:21:09 +01:00
parent 9f4727789a
commit b8f72b7826
5 changed files with 173 additions and 8 deletions

View File

@@ -1,4 +1,4 @@
#include "LoaderFontIconT6.h"
#include "CsvLoaderFontIconT6.h"
#include "Csv/CsvStream.h"
#include "Game/T6/CommonT6.h"
@@ -30,10 +30,10 @@ namespace
constexpr unsigned COL_COUNT_ALIAS = 4;
constexpr unsigned COL_COUNT_MIN = std::min(COL_COUNT_ICON, COL_COUNT_ALIAS);
class FontIconLoader final : public AssetCreator<AssetFontIcon>
class CsvFontIconLoader final : public AssetCreator<AssetFontIcon>
{
public:
FontIconLoader(MemoryManager& memory, ISearchPath& searchPath)
CsvFontIconLoader(MemoryManager& memory, ISearchPath& searchPath)
: m_memory(memory),
m_search_path(searchPath)
{
@@ -284,8 +284,8 @@ namespace
namespace T6
{
std::unique_ptr<AssetCreator<AssetFontIcon>> CreateFontIconLoader(MemoryManager& memory, ISearchPath& searchPath)
std::unique_ptr<AssetCreator<AssetFontIcon>> CreateCsvFontIconLoader(MemoryManager& memory, ISearchPath& searchPath)
{
return std::make_unique<FontIconLoader>(memory, searchPath);
return std::make_unique<CsvFontIconLoader>(memory, searchPath);
}
} // namespace T6

View File

@@ -9,5 +9,5 @@
namespace T6
{
std::unique_ptr<AssetCreator<AssetFontIcon>> CreateFontIconLoader(MemoryManager& memory, ISearchPath& searchPath);
std::unique_ptr<AssetCreator<AssetFontIcon>> CreateCsvFontIconLoader(MemoryManager& memory, ISearchPath& searchPath);
} // namespace T6

View File

@@ -0,0 +1,150 @@
#include "JsonLoaderFontIconT6.h"
#include "Game/T6/CommonT6.h"
#include "Game/T6/FontIcon/FontIconCommonT6.h"
#include "Game/T6/FontIcon/JsonFontIconT6.h"
#include "Game/T6/T6.h"
#include <algorithm>
#include <format>
#include <iostream>
#include <nlohmann/json.hpp>
using namespace nlohmann;
using namespace T6;
namespace
{
class JsonFontIconLoader final : public AssetCreator<AssetFontIcon>
{
public:
JsonFontIconLoader(MemoryManager& memory, ISearchPath& searchPath)
: m_memory(memory),
m_search_path(searchPath)
{
}
AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override
{
const auto file = m_search_path.Open(font_icon::GetJsonFileNameForAssetName(assetName));
if (!file.IsOpen())
return AssetCreationResult::NoAction();
auto* fontIcon = m_memory.Alloc<FontIcon>();
fontIcon->name = m_memory.Dup(assetName.c_str());
AssetRegistration<AssetFontIcon> registration(assetName, fontIcon);
try
{
const auto jRoot = json::parse(*file.m_stream);
std::string type;
unsigned version;
jRoot.at("_type").get_to(type);
jRoot.at("_version").get_to(version);
if (type != "font-icon" || version != 1u)
{
std::cerr << std::format("Tried to load font icon \"{}\" but did not find expected type font-icon of version 1\n", assetName);
return AssetCreationResult::Failure();
}
const auto jFontIcon = jRoot.get<JsonFontIcon>();
if (CreateFontIconFromJson(jFontIcon, *fontIcon, registration, context))
return AssetCreationResult::Success(context.AddAsset(std::move(registration)));
}
catch (const json::exception& e)
{
std::cerr << std::format("Failed to parse json of font icon: {}\n", e.what());
}
return AssetCreationResult::Failure();
}
private:
bool CreateFontIconFromJson(const JsonFontIcon& jFontIcon,
FontIcon& fontIcon,
AssetRegistration<AssetFontIcon>& registration,
AssetCreationContext& context) const
{
std::vector<FontIconAlias> aliases;
fontIcon.numEntries = static_cast<unsigned>(jFontIcon.entries.size());
fontIcon.fontIconEntry = m_memory.Alloc<FontIconEntry>(fontIcon.numEntries);
for (auto entryIndex = 0u; entryIndex < fontIcon.numEntries; entryIndex++)
{
if (!CreateFontIconEntryFromJson(jFontIcon.entries[entryIndex], fontIcon.fontIconEntry[entryIndex], aliases, registration, context))
return false;
}
std::sort(fontIcon.fontIconEntry,
&fontIcon.fontIconEntry[fontIcon.numEntries],
[](const FontIconEntry& e0, const FontIconEntry& e1) -> bool
{
return e0.fontIconName.hash < e1.fontIconName.hash;
});
if (!aliases.empty())
{
fontIcon.numAliasEntries = static_cast<unsigned>(aliases.size());
fontIcon.fontIconAlias = m_memory.Alloc<FontIconAlias>(fontIcon.numAliasEntries);
std::memcpy(fontIcon.fontIconAlias, aliases.data(), sizeof(FontIconAlias) * fontIcon.numAliasEntries);
std::sort(fontIcon.fontIconAlias,
&fontIcon.fontIconAlias[fontIcon.numAliasEntries],
[](const FontIconAlias& a0, const FontIconAlias& a1) -> bool
{
return a0.aliasHash < a1.aliasHash;
});
}
return true;
}
bool CreateFontIconEntryFromJson(const JsonFontIconEntry& jFontIconEntry,
FontIconEntry& fontIconEntry,
std::vector<FontIconAlias>& aliases,
AssetRegistration<AssetFontIcon>& registration,
AssetCreationContext& context) const
{
fontIconEntry.fontIconName.string = m_memory.Dup(jFontIconEntry.name.c_str());
fontIconEntry.fontIconName.hash = Common::Com_HashString(jFontIconEntry.name.c_str());
auto* materialDependency = context.LoadDependency<AssetMaterial>(jFontIconEntry.material);
if (materialDependency == nullptr)
{
std::cerr << std::format("Failed to load material \"{}\" for font icon entry \"{}\"\n", jFontIconEntry.material, jFontIconEntry.name);
return false;
}
registration.AddDependency(materialDependency);
fontIconEntry.fontIconMaterialHandle = materialDependency->Asset();
fontIconEntry.fontIconSize = static_cast<int>(jFontIconEntry.size);
fontIconEntry.xScale = jFontIconEntry.scale.has_value() ? jFontIconEntry.scale->x : 0;
fontIconEntry.yScale = jFontIconEntry.scale.has_value() ? jFontIconEntry.scale->y : 0;
for (const auto& alias : jFontIconEntry.aliases)
aliases.emplace_back(Common::Com_HashString(alias.c_str()), fontIconEntry.fontIconName.hash);
if (jFontIconEntry.aliasHashes.has_value())
{
for (const auto aliasHash : *jFontIconEntry.aliasHashes)
aliases.emplace_back(aliasHash, fontIconEntry.fontIconName.hash);
}
return true;
}
MemoryManager& m_memory;
ISearchPath& m_search_path;
};
} // namespace
namespace T6
{
std::unique_ptr<AssetCreator<AssetFontIcon>> CreateJsonFontIconLoader(MemoryManager& memory, ISearchPath& searchPath)
{
return std::make_unique<JsonFontIconLoader>(memory, searchPath);
}
} // namespace T6

View File

@@ -0,0 +1,13 @@
#pragma once
#include "Asset/IAssetCreator.h"
#include "Game/T6/T6.h"
#include "SearchPath/ISearchPath.h"
#include "Utils/MemoryManager.h"
#include <memory>
namespace T6
{
std::unique_ptr<AssetCreator<AssetFontIcon>> CreateJsonFontIconLoader(MemoryManager& memory, ISearchPath& searchPath);
} // namespace T6

View File

@@ -1,7 +1,8 @@
#include "ObjLoaderT6.h"
#include "Asset/GlobalAssetPoolsLoader.h"
#include "FontIcon/LoaderFontIconT6.h"
#include "FontIcon/CsvLoaderFontIconT6.h"
#include "FontIcon/JsonLoaderFontIconT6.h"
#include "Game/T6/CommonT6.h"
#include "Game/T6/GameAssetPoolT6.h"
#include "Game/T6/GameT6.h"
@@ -412,7 +413,8 @@ namespace T6
// collection.AddAssetCreator(std::make_unique<AssetLoaderGfxWorld>(memory));
// collection.AddAssetCreator(std::make_unique<AssetLoaderLightDef>(memory));
// collection.AddAssetCreator(std::make_unique<AssetLoaderFont>(memory));
collection.AddAssetCreator(CreateFontIconLoader(memory, searchPath));
collection.AddAssetCreator(CreateCsvFontIconLoader(memory, searchPath));
collection.AddAssetCreator(CreateJsonFontIconLoader(memory, searchPath));
// collection.AddAssetCreator(std::make_unique<AssetLoaderMenuList>(memory));
// collection.AddAssetCreator(std::make_unique<AssetLoaderMenu>(memory));
collection.AddAssetCreator(CreateLocalizeLoader(memory, searchPath, zone));