#pragma once #include "project_parser.h" template > auto FindAssetFiles(std::string_view project_root) { using AssetsContainer = typename AssetTypes::template AsContainedType; AssetsContainer Assets{}; for (const auto& entry : std::filesystem::recursive_directory_iterator(project_root)) { if (entry.is_directory()) continue; std::string extension = entry.path().extension().string(); if (extension == std::string_view(".meta")) continue; AssetTypes::ForEachT([&Assets, &extension, &entry]() { constexpr auto assetExtensions = AssetT::Extensions; for (auto assetExtension : assetExtensions) { if (extension == assetExtension) { static_assert(std::is_base_of_v, "Asset Type must derive from AssetBase"); AssetT asset{}; asset.Path = entry.path(); asset.GUID = GetAssetGUIDFromFile(entry.path().string() + ".meta"); std::get>(Assets).emplace(asset.GUID, std::move(asset)); return; } } }); } return Assets; } template , typename ProjectType> void InitializeAssetFiles(ProjectType& project) { AssetTypes::ForEachT([&project]() { std::string buffer{}; auto& assetMap = std::get>(project.Assets); for (auto& [guid, asset] : assetMap) { buffer.clear(); std::ifstream file(asset.Path); buffer.assign(std::istreambuf_iterator(file), std::istreambuf_iterator()); asset.Parse(project, buffer); } }); } template < typename AssetTypes = TypeCollection<>, typename UnityTypes = TypeCollection<>, typename MonobehaviourTypes = TypeCollection<> > ParsedProject ParseProject(const std::filesystem::path& projectRoot) { auto project = ParsedProject{projectRoot}; project.Assets = FindAssetFiles(projectRoot.generic_string()); InitializeAssetFiles(project); return project; }