// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Render2D/SpriteAtlas.h"
#include "Engine/Content/Asset.h"
#include "Engine/ContentImporters/Types.h"
#include "Engine/Graphics/Textures/GPUTexture.h"
#include "Engine/Threading/ThreadPoolTask.h"
#include "Engine/Graphics/Textures/TextureData.h"
///
/// Asset which contains set of asset items thumbnails (cached previews).
///
API_CLASS(Sealed, NoSpawn, Namespace="FlaxEditor") class PreviewsCache : public SpriteAtlas
{
DECLARE_BINARY_ASSET_HEADER(PreviewsCache, TexturesSerializedVersion);
private:
class FlushTask : public ThreadPoolTask
{
private:
PreviewsCache* _cache;
TextureData _data;
public:
FlushTask(PreviewsCache* cache)
: _cache(cache)
{
}
public:
///
/// Gets the texture data container.
///
TextureData& GetData()
{
return _data;
}
protected:
// [ThreadPoolTask]
bool Run() override;
void OnEnd() override;
};
private:
Array _assets;
bool _isDirty = false;
FlushTask* _flushTask = nullptr;
public:
///
/// Determines whether this atlas is ready (is loaded and has texture streamed).
///
API_PROPERTY() bool IsReady() const;
///
/// Finds the preview icon for given asset ID.
///
/// The asset id to find preview for it.
/// The output sprite slot handle or invalid if invalid in nothing found.
API_FUNCTION() SpriteHandle FindSlot(const Guid& id);
///
/// Determines whether this atlas has one or more free slots for the asset preview.
///
API_PROPERTY() bool HasFreeSlot() const;
///
/// Occupies the atlas slot.
///
/// The source texture to insert.
/// The asset identifier.
/// The added sprite slot handle or invalid if invalid in failed to occupy slot.
API_FUNCTION() SpriteHandle OccupySlot(GPUTexture* source, const Guid& id);
///
/// Releases the used slot.
///
/// The asset identifier.
/// True if slot has been release, otherwise it was not found.
API_FUNCTION() bool ReleaseSlot(const Guid& id);
///
/// Flushes atlas data from the GPU to the asset storage (saves data).
///
API_FUNCTION() void Flush();
///
/// Determines whether this instance is flushing.
///
/// True if this previews cache is flushing, otherwise false.
FORCE_INLINE bool IsFlushing() const
{
return _flushTask != nullptr;
}
public:
#if COMPILE_WITH_ASSETS_IMPORTER
///
/// Creates a new atlas.
///
/// The output asset file path.
/// True if this previews cache is flushing, otherwise false.
API_FUNCTION() static bool Create(const StringView& outputPath);
private:
static CreateAssetResult create(CreateAssetContext& context);
#endif
protected:
// [BinaryAsset]
LoadResult load() override;
void unload(bool isReloading) override;
AssetChunksFlag getChunksToPreload() const override;
};