#pragma once #include "Common/Sizes.hpp" #include "Common/Assert.hpp" #include "Common/Unique.hpp" #include "AllAssets.hpp" namespace MC { using Asset = Char const* const; using AssetToken = U64; #define X(ns, _name, file_path) namespace Assets::Files { extern Asset file_path; } ALL_ASSETS #undef X namespace Assets { constexpr AssetToken invalid_asset = 0; #define X(ns, name, _file_path) namespace ns { constexpr AssetToken name = UNIQUE_NUMBER; } ALL_ASSETS #undef X } constexpr Asset lookup(AssetToken token) { switch (token) { #define X(ns, name, file_path) case Assets::ns::name: return Assets::Files::file_path; ALL_ASSETS #undef X default: UNREACHABLE("Invalid asset token."); } } template constexpr Asset asset(AssetToken t = Assets::invalid_asset) { static_assert(T != Assets::invalid_asset, "Invalid asset token."); ASSERT(t == Assets::invalid_asset || t == T, "Can't lookup asset both dynamically and statically at the same time."); return lookup(T); } template <> inline Asset asset(AssetToken token) { return lookup(token); } }