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

137 lines
4.3 KiB
C++

#pragma once
#include "Ports/PortFwd.h"
#include <XCEngine/UI/Types.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 {
enum class BuiltInIconKind : std::uint8_t {
Folder = 0,
GameObject,
Scene,
CameraGizmo,
DirectionalLightGizmo,
PointLightGizmo,
SpotLightGizmo,
PlayButton,
PauseButton,
StepButton
};
class BuiltInIcons {
public:
void Initialize(Ports::TexturePort& renderer);
void Shutdown();
void BeginFrame();
const ::XCEngine::UI::UITextureHandle& Resolve(BuiltInIconKind kind) const;
const ::XCEngine::UI::UITextureHandle* ResolveAssetPreview(
const std::filesystem::path& assetPath,
const std::filesystem::path& projectRoot);
const std::string& GetLastError() const;
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();
Ports::TexturePort* 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 = {};
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