Files
XCEngine/editor/app/Rendering/Assets/BuiltInIcons.h

134 lines
4.8 KiB
C++

#pragma once
#include "Assets/EditorIconService.h"
#include <condition_variable>
#include <cstdint>
#include <deque>
#include <filesystem>
#include <memory>
#include <mutex>
#include <string>
#include <thread>
#include <unordered_map>
#include <vector>
namespace XCEngine::UI::Editor::App {
class BuiltInIcons final : public EditorIconService {
public:
void Initialize(
Rendering::Host::UiTextureHost& renderer,
Host::EditorHostResourceService& resourceService) override;
void Shutdown() override;
void BeginFrame() override;
const ::XCEngine::UI::UITextureHandle& Resolve(BuiltInIconKind kind) const override;
const ::XCEngine::UI::UITextureHandle* ResolveAssetPreview(
const std::filesystem::path& assetPath,
const std::filesystem::path& projectRoot) override;
const std::string& GetLastError() const override;
struct LoadedTexturePixels {
std::vector<std::uint8_t> rgbaPixels = {};
int width = 0;
int height = 0;
};
struct SourceFileFingerprint {
std::uint64_t fileSize = 0;
std::int64_t lastWriteTimeTicks = 0;
bool IsValid() const {
return fileSize > 0 && lastWriteTimeTicks != 0;
}
bool operator==(const SourceFileFingerprint&) const = default;
};
struct PreviewDecodeJob {
std::string key = {};
std::filesystem::path filePath = {};
std::filesystem::path cacheFilePath = {};
std::string relativePathKey = {};
std::uint64_t fileSize = 0;
std::int64_t lastWriteTimeTicks = 0;
bool useDiskCache = false;
};
struct PreviewDecodeResult {
std::string key = {};
LoadedTexturePixels pixels = {};
std::uint64_t fileSize = 0;
std::int64_t lastWriteTimeTicks = 0;
bool success = false;
};
struct CachedAssetPreview {
::XCEngine::UI::UITextureHandle texture = {};
std::unique_ptr<LoadedTexturePixels> decodedPixels = {};
SourceFileFingerprint sourceFingerprint = {};
bool decodeQueued = false;
bool loadFailed = false;
std::int64_t lastUsedFrame = -1;
std::int64_t lastSourceValidationFrame = -1;
};
private:
void ResetAssetPreviewCache();
void StartPreviewWorkers();
void StopPreviewWorkers();
void PreviewWorkerMain();
void DrainPreviewDecodeResults();
void MaintainPreviewRuntimeState();
void InvalidateAssetPreview(CachedAssetPreview& preview);
bool RefreshAssetPreviewSourceFingerprint(
const std::filesystem::path& filePath,
CachedAssetPreview& preview);
bool QueuePreviewDecode(
const std::string& key,
const std::filesystem::path& filePath,
const SourceFileFingerprint& sourceFingerprint,
const std::filesystem::path& projectRoot);
CachedAssetPreview* GetOrCreateAssetPreview(
const std::filesystem::path& assetPath,
const std::filesystem::path& projectRoot);
void PruneAssetPreviewCache();
Rendering::Host::UiTextureHost* m_renderer = nullptr;
::XCEngine::UI::UITextureHandle m_folderIcon = {};
::XCEngine::UI::UITextureHandle m_gameObjectIcon = {};
::XCEngine::UI::UITextureHandle m_sceneIcon = {};
::XCEngine::UI::UITextureHandle m_cameraGizmoIcon = {};
::XCEngine::UI::UITextureHandle m_directionalLightGizmoIcon = {};
::XCEngine::UI::UITextureHandle m_pointLightGizmoIcon = {};
::XCEngine::UI::UITextureHandle m_spotLightGizmoIcon = {};
::XCEngine::UI::UITextureHandle m_playButtonIcon = {};
::XCEngine::UI::UITextureHandle m_pauseButtonIcon = {};
::XCEngine::UI::UITextureHandle m_stepButtonIcon = {};
::XCEngine::UI::UITextureHandle m_viewMoveToolIcon = {};
::XCEngine::UI::UITextureHandle m_viewMoveToolActiveIcon = {};
::XCEngine::UI::UITextureHandle m_moveToolIcon = {};
::XCEngine::UI::UITextureHandle m_moveToolActiveIcon = {};
::XCEngine::UI::UITextureHandle m_rotateToolIcon = {};
::XCEngine::UI::UITextureHandle m_rotateToolActiveIcon = {};
::XCEngine::UI::UITextureHandle m_scaleToolIcon = {};
::XCEngine::UI::UITextureHandle m_scaleToolActiveIcon = {};
::XCEngine::UI::UITextureHandle m_transformToolIcon = {};
::XCEngine::UI::UITextureHandle m_transformToolActiveIcon = {};
std::unordered_map<std::string, CachedAssetPreview> m_assetPreviews = {};
std::vector<std::thread> m_previewWorkers = {};
std::deque<PreviewDecodeJob> m_previewDecodeQueue = {};
std::deque<PreviewDecodeResult> m_previewDecodeResults = {};
std::mutex m_previewQueueMutex = {};
std::condition_variable m_previewQueueEvent = {};
bool m_previewWorkersRunning = false;
std::size_t m_pendingPreviewDecodeJobs = 0u;
std::int64_t m_frameIndex = 0;
int m_previewLoadsThisFrame = 0;
std::string m_lastError = {};
};
} // namespace XCEngine::UI::Editor::App