95 lines
2.9 KiB
C
95 lines
2.9 KiB
C
|
|
#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<FName, FString> 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<FName, TArray<FCookAssetData>> AssetRegistryDataMap;
|
||
|
|
TMap<FName, TArray<FAssetPackageData>> 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
|