// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
#pragma once
#include "Editor/Cooker/GameCooker.h"
#include "Engine/Core/Types/Pair.h"
#include "Engine/Core/Types/DateTime.h"
#include "Engine/Core/Collections/Dictionary.h"
#include "Engine/Content/AssetInfo.h"
#include "Engine/Content/Cache/AssetsCache.h"
class Asset;
class BinaryAsset;
class JsonAssetBase;
struct AssetInitData;
///
/// Cooking step that builds all the assets and packages them to the output directory.
/// Uses incremental build cache to provide faster building.
///
///
class FLAXENGINE_API CookAssetsStep : public GameCooker::BuildStep
{
public:
typedef Array> FileDependenciesList;
///
/// Cached cooked asset entry data.
///
struct FLAXENGINE_API CacheEntry
{
///
/// The asset identifier.
///
Guid ID;
///
/// The stored data full typename. Used to recognize asset type.
///
String TypeName;
///
/// The asset file modification time.
///
DateTime FileModified;
///
/// The list of files on which this entry depends on. Cached date is the last edit time used to discard cache result on modification.
///
FileDependenciesList FileDependencies;
bool IsValid(bool withDependencies = false);
};
///
/// Assets cooking cache data (incremental building feature).
///
struct FLAXENGINE_API CacheData
{
///
/// The cache header file path.
///
String HeaderFilePath;
///
/// The cached files folder.
///
String CacheFolder;
///
/// The build options used to cook assets. Changing some options in game settings might trigger cached assets invalidation.
///
struct
{
struct
{
bool SupportDX12;
bool SupportDX11;
bool SupportDX10;
bool SupportVulkan;
} Windows;
struct
{
bool SupportDX11;
bool SupportDX10;
} UWP;
struct
{
bool SupportVulkan;
} Linux;
struct
{
bool ShadersNoOptimize;
bool ShadersGenerateDebugData;
Guid StreamingSettingsAssetId;
int32 ShadersVersion;
int32 MaterialGraphVersion;
int32 ParticleGraphVersion;
} Global;
} Settings;
///
/// The cached entries.
///
Dictionary Entries;
public:
///
/// Gets the path to the asset of the given id (file may be missing).
///
/// The asset id.
/// The cached file path to use for creating cache storage.
void GetFilePath(const Guid& id, String& cachedFilePath) const
{
cachedFilePath = CacheFolder / id.ToString(Guid::FormatType::N);
}
///
/// Creates the new entry for the cooked asset file.
///
/// The asset.
/// The cached file path to use for creating cache storage.
/// The added entry reference.
CacheEntry& CreateEntry(const JsonAssetBase* asset, String& cachedFilePath);
///
/// Creates the new entry for the cooked asset file.
///
/// The asset.
/// The cached file path to use for creating cache storage.
/// The added entry reference.
CacheEntry& CreateEntry(const Asset* asset, String& cachedFilePath);
///
/// Removes all cached entries for assets that contain a shader. This forces rebuild for them.
///
void InvalidateShaders();
///
/// Removes all cached entries for assets that contain a texture. This forces rebuild for them.
///
void InvalidateCachePerType(const StringView& typeName);
///
/// Loads the cache for the given cooking data.
///
/// The data.
void Load(CookingData& data);
///
/// Saves this cache (header file).
///
void Save();
};
struct FLAXENGINE_API AssetCookData
{
CookingData& Data;
CacheData& Cache;
AssetInitData& InitData;
Asset* Asset;
FileDependenciesList& FileDependencies;
};
typedef bool (*ProcessAssetFunc)(AssetCookData&);
///
/// The asset processors (key: asset full typename, value: processor function that cooks the asset).
///
static Dictionary AssetProcessors;
static bool ProcessDefaultAsset(AssetCookData& options);
private:
AssetsCache::Registry AssetsRegistry;
AssetsCache::PathsMapping AssetPathsMapping;
bool Process(CookingData& data, CacheData& cache, Asset* asset);
bool Process(CookingData& data, CacheData& cache, BinaryAsset* asset);
bool Process(CookingData& data, CacheData& cache, JsonAssetBase* asset);
public:
///
/// Initializes a new instance of the class.
///
CookAssetsStep();
public:
// [BuildStep]
bool Perform(CookingData& data) override;
};