#pragma once #include "CoreMinimal.h" #include "AssetRegistry/AssetData.h" #include "Misc/CookSideEffectCollector.h" namespace UE { namespace Cook { /** * @struct FCookAssetData * @brief Represents the asset registry information for a single asset within a package. */ struct FCookAssetData { FName AssetClass; uint32 PackageFlags = 0; TMap Tags; friend FArchive& operator<<(FArchive& Ar, FCookAssetData& Data) { Ar << Data.AssetClass; Ar << Data.PackageFlags; Ar << Data.Tags; return Ar; } /** * Equality operator to compare asset data across processes. * Necessary for Director to identify if the same asset's side effects are being reported. */ friend bool operator==(const FCookAssetData& A, const FCookAssetData& B) { if (A.AssetClass != B.AssetClass || A.Tags.Num() != B.Tags.Num()) { return false; } for (const auto& TagPair: A.Tags) { const FString* BValue = B.Tags.Find(TagPair.Key); if (!BValue || *BValue != TagPair.Value) { return false; } } return true; } friend bool operator!=(const FCookAssetData& A, const FCookAssetData& B) { return !(A == B); } }; /** * @class FMPCookSideEffectCollector * @brief A thread-local singleton used to collect side-effect data (EDL, AssetRegistry) during a UPackage::Save operation. * * This avoids the need to modify the engine's SavePackage function signatures. The worker's save logic should * call BeginPackage() before saving, and EndPackage() afterwards. The low-level functions like * FEDLCookChecker::AddExport can then access the collector via Get() to get the current context and populate the data. */ class FCookWorkerClient; struct FPackageData; struct FMPCookSideEffectCollectorData { FCriticalSection CookSideEffectsLock; FCriticalSection AssetPackageDataLock; FCriticalSection AssetRegistryDataLock; FCookSideEffects CookSideEffects; TMap> AssetRegistryDataMap; TMap> AssetPackageDataMap; void UniqueToCookSideEffects(FCookSideEffects& To); }; class FMPCookSideEffectCollector: public ICookSideEffectCollector { public: FMPCookSideEffectCollector() = default; void AddExport(UObject* Export) override; void AddImport(UObject* Import, UPackage* ImportingPackage) override; void AddArc(UObject* DepObject, bool bDepIsSerialize, UObject* Export, bool bExportIsSerialize) override; void RecordAssetTag(const ITargetPlatform* TargetPlatform, FName AssetPath, FName AssetClass, FName TagName, const FString& TagValue); static void SetCookWorkerClient(FCookWorkerClient* InCookWorkerClient); static ICookSideEffectCollector* NewCookSideEffectCollector(); private: static FCookWorkerClient* CookWorkerClient; }; } // namespace Cook } // namespace UE