120 lines
3.0 KiB
C++
120 lines
3.0 KiB
C++
#pragma once
|
|
|
|
#include <filesystem>
|
|
#include <array>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
#include <string>
|
|
#include <string_view>
|
|
|
|
#include <ryml.hpp>
|
|
|
|
#include "type_info.hpp"
|
|
|
|
|
|
struct AssetGUID
|
|
{
|
|
AssetGUID() = default;
|
|
AssetGUID(const char* data) : AssetGUID(std::string_view(data, 32)) {};
|
|
AssetGUID(std::string_view data)
|
|
{
|
|
for (size_t i = 0; i < 16; ++i) Data[0] = (Data[0] << 4) | hexToVal(data[i]);
|
|
for (size_t i = 16; i < 32; ++i) Data[1] = (Data[1] << 4) | hexToVal(data[i]);
|
|
}
|
|
|
|
static uint64_t hexToVal(char c)
|
|
{
|
|
return (c >= '0' && c <= '9') ? (c - '0') : (c - 'a' + 10);
|
|
}
|
|
|
|
bool operator==(const AssetGUID& other) const
|
|
{
|
|
return Data[0] == other.Data[0] && Data[1] == other.Data[1];
|
|
}
|
|
|
|
static constexpr uint64_t DefaultVal = 0xe000000000000000;
|
|
|
|
std::array<uint64_t, 2> Data{ 0, DefaultVal };
|
|
};
|
|
|
|
struct AssetPath
|
|
{
|
|
std::filesystem::path path{};
|
|
AssetGUID GUID{};
|
|
};
|
|
|
|
template <typename T>
|
|
using unordered_map_guid = std::unordered_map<AssetGUID, T>;
|
|
|
|
namespace std
|
|
{
|
|
template <>
|
|
struct hash<AssetGUID> {
|
|
size_t operator()(const AssetGUID& v) const noexcept
|
|
{
|
|
auto h1 = std::hash<uint64_t>{}(v.Data[0]);
|
|
auto h2 = std::hash<uint64_t>{}(v.Data[1]);
|
|
return h1 ^ (h2 << 1);
|
|
}
|
|
};
|
|
}
|
|
|
|
inline AssetGUID ParseAssetGUID(const ryml::ConstNodeRef& node)
|
|
{
|
|
auto guidStringSpan2 = node["guid"].val();
|
|
|
|
assert(guidStringSpan2.size() == 32);
|
|
|
|
return AssetGUID{std::string_view(guidStringSpan2.data(), guidStringSpan2.size())};
|
|
}
|
|
|
|
struct AssetBase
|
|
{
|
|
std::filesystem::path Path{};
|
|
AssetGUID GUID{};
|
|
|
|
// static std::span<std::string_view> GetExtensions();
|
|
};
|
|
|
|
struct AssetCollectionBase
|
|
{
|
|
std::vector<std::unordered_map<AssetGUID, AssetBase*>*> AssetsInterface{};
|
|
std::vector<std::string_view> AssetNames{};
|
|
|
|
template <typename AssetType>
|
|
AssetType* GetAsset(AssetGUID guid)
|
|
{
|
|
for (size_t i = 0; i < AssetNames.size(); i++)
|
|
if (AssetNames[i] == type_name<AssetType>())
|
|
{
|
|
auto& assetMap = (*AssetsInterface[i]);
|
|
auto it = assetMap.find(guid);
|
|
if (it != assetMap.end())
|
|
{
|
|
return static_cast<AssetType*>(it->second);
|
|
}
|
|
return nullptr;
|
|
}
|
|
return nullptr;
|
|
}
|
|
};
|
|
|
|
template <typename AssetTypes = TypeCollection<>>
|
|
struct AssetCollection : public AssetCollectionBase
|
|
{
|
|
using AssetsT = typename AssetTypes::template AsContainedType<unordered_map_guid>;
|
|
|
|
AssetsT Assets;
|
|
|
|
AssetCollection(AssetsT&& assets)
|
|
: AssetNames(AssetTypes::get_names())
|
|
, AssetsInterface(sizeof...(AssetTypes))
|
|
, Assets(std::move(assets))
|
|
{
|
|
size_t index = 0;
|
|
AssetTypes::ForEachT([this, &index]<typename AssetT>()
|
|
{
|
|
AssetsInterface[index++] = &std::get<std::unordered_map<AssetGUID, AssetT>>(Assets);
|
|
});
|
|
}
|
|
}; |