#pragma once #include #include #include #include #include #include #include #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 Data{ 0, DefaultVal }; }; struct AssetPath { std::filesystem::path path{}; AssetGUID GUID{}; }; template using unordered_map_guid = std::unordered_map; namespace std { template <> struct hash { size_t operator()(const AssetGUID& v) const noexcept { auto h1 = std::hash{}(v.Data[0]); auto h2 = std::hash{}(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 GetExtensions(); }; struct AssetCollectionBase { std::vector*> AssetsInterface{}; std::vector AssetNames{}; template AssetType* GetAsset(AssetGUID guid) { for (size_t i = 0; i < AssetNames.size(); i++) if (AssetNames[i] == type_name()) { auto& assetMap = (*AssetsInterface[i]); auto it = assetMap.find(guid); if (it != assetMap.end()) { return static_cast(it->second); } return nullptr; } return nullptr; } }; template > struct AssetCollection : public AssetCollectionBase { using AssetsT = typename AssetTypes::template AsContainedType; AssetsT Assets; AssetCollection(AssetsT&& assets) : AssetNames(AssetTypes::get_names()) , AssetsInterface(sizeof...(AssetTypes)) , Assets(std::move(assets)) { size_t index = 0; AssetTypes::ForEachT([this, &index]() { AssetsInterface[index++] = &std::get>(Assets); }); } };