137 lines
4.3 KiB
C++
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
|
|
|