mirror of
https://github.com/leozide/leocad.git
synced 2026-10-27 06:20:55 +00:00
233 lines
6.7 KiB
C++
233 lines
6.7 KiB
C++
#pragma once
|
|
|
|
#include "lc_library.h"
|
|
#include "piece.h"
|
|
|
|
class PieceInfo;
|
|
class lcPiece;
|
|
class lcMesh;
|
|
class lcSynthInfo;
|
|
class lcMemFile;
|
|
class lcLibraryMeshData;
|
|
class Image;
|
|
class lcTexture;
|
|
enum class lcTextureLoadError;
|
|
|
|
struct lcPartSourceSnapshot
|
|
{
|
|
QString FileName;
|
|
QString LibraryDirectory;
|
|
QString CachePath;
|
|
std::vector<QString> TextureSearchDirectories;
|
|
QStringList InlineMeshLines;
|
|
bool InlineModel = false;
|
|
bool SkipCache = false;
|
|
lcZipFileType ZipFileType = lcZipFileType::Count;
|
|
int ZipFileIndex = -1;
|
|
lcStudStyle StudStyle = lcStudStyle::Plain;
|
|
bool StudCylinderColorEnabled = false;
|
|
};
|
|
|
|
struct lcPartBuildResult
|
|
{
|
|
lcPartBuildResult() = default;
|
|
~lcPartBuildResult();
|
|
lcPartBuildResult(lcPartBuildResult&&) = default;
|
|
lcPartBuildResult& operator=(lcPartBuildResult&&) = default;
|
|
lcPartBuildResult(const lcPartBuildResult&) = delete;
|
|
lcPartBuildResult& operator=(const lcPartBuildResult&) = delete;
|
|
|
|
quint64 RequestId = 0;
|
|
quint64 Generation = 0;
|
|
std::unique_ptr<lcLibraryMeshData> MeshData;
|
|
std::unique_ptr<lcMesh> Mesh;
|
|
std::unique_ptr<lcMemFile> CacheData;
|
|
std::vector<quint32> ColorCodes;
|
|
bool EmptyGeometry = false;
|
|
QStringList TextureDependencies;
|
|
QString Error;
|
|
};
|
|
|
|
struct lcTextureSourceSnapshot
|
|
{
|
|
QString Name;
|
|
QString FilePath;
|
|
};
|
|
|
|
struct lcTextureBuildResult
|
|
{
|
|
lcTextureBuildResult() = default;
|
|
~lcTextureBuildResult();
|
|
lcTextureBuildResult(lcTextureBuildResult&&) = default;
|
|
lcTextureBuildResult& operator=(lcTextureBuildResult&&) = default;
|
|
lcTextureBuildResult(const lcTextureBuildResult&) = delete;
|
|
lcTextureBuildResult& operator=(const lcTextureBuildResult&) = delete;
|
|
|
|
std::unique_ptr<Image> DecodedImage;
|
|
lcTextureLoadError Error{};
|
|
};
|
|
|
|
class lcAssetLoader : public QObject
|
|
{
|
|
public:
|
|
lcAssetLoader(lcPiecesLibrary* Library);
|
|
~lcAssetLoader() override;
|
|
|
|
bool LoadPieceInfo(PieceInfo* Info, lcPieceLoadFlags Flags);
|
|
void QueuePiece(PieceInfo* Info, bool Priority);
|
|
bool EnsurePieceReady(PieceInfo* Info);
|
|
bool EnsurePiecesReady(const std::vector<PieceInfo*>& Parts);
|
|
void QueueSynthMesh(lcPiece* Piece);
|
|
void CancelSynthMesh(lcPiece* Piece);
|
|
bool EnsureSynthMeshesReady(const std::vector<lcPiece*>& Pieces);
|
|
QString GetSynthMeshError(const lcPiece* Piece) const;
|
|
void ReloadSynthMeshes();
|
|
void QueueModelPiece(PieceInfo* Info);
|
|
void InvalidatePiece(PieceInfo* Info);
|
|
void SetPieceRequestsVisible(const std::vector<PieceInfo*>& Parts, bool Visible);
|
|
bool EnsureTextureReady(lcTexture* Texture);
|
|
void WaitForLoadQueue();
|
|
void CancelAndDrain();
|
|
void PauseQueuedWork();
|
|
void ResumeQueuedWork();
|
|
void OnConsumerReleased(PieceInfo* Info);
|
|
bool HasPendingWork();
|
|
|
|
private:
|
|
enum class Priority
|
|
{
|
|
Background, // Ordinary queued asset work.
|
|
Visible, // Assets requested for the visible model.
|
|
Blocking // Assets needed by a synchronous wait.
|
|
};
|
|
|
|
struct Request
|
|
{
|
|
PieceInfo* Info;
|
|
quint64 Id;
|
|
quint64 Generation;
|
|
lcPartSourceSnapshot Source;
|
|
Priority LoadPriority;
|
|
qint64 EnqueuedAt;
|
|
bool Running = false;
|
|
bool Obsolete = false;
|
|
bool Terminal = false;
|
|
bool Succeeded = false;
|
|
bool ConvertingMesh = false;
|
|
std::unique_ptr<lcLibraryMeshData> MeshData;
|
|
std::vector<bool> ColorTranslucency;
|
|
int DefaultColorIndex = 0;
|
|
std::unique_ptr<lcMesh> StagedMesh;
|
|
bool EmptyGeometry = false;
|
|
bool SaveCache = false;
|
|
QString Error;
|
|
};
|
|
|
|
struct TextureRequest
|
|
{
|
|
lcTexture* Texture;
|
|
quint64 Generation;
|
|
lcTextureSourceSnapshot Source;
|
|
Priority LoadPriority;
|
|
qint64 EnqueuedAt;
|
|
bool Running = false;
|
|
int UploadAttempts = 0;
|
|
qint64 RetryAt = 0;
|
|
};
|
|
|
|
struct SynthRequest
|
|
{
|
|
lcPiece* Piece;
|
|
std::shared_ptr<const lcSynthInfo> SynthInfo;
|
|
std::vector<lcPieceControlPoint> ControlPoints;
|
|
Priority LoadPriority;
|
|
qint64 EnqueuedAt;
|
|
quint64 Generation;
|
|
bool Running = false;
|
|
std::atomic_bool Cancelled = false;
|
|
bool Terminal = false;
|
|
bool ConvertingMesh = false;
|
|
std::unique_ptr<lcLibraryMeshData> MeshData;
|
|
std::vector<bool> ColorTranslucency;
|
|
int DefaultColorIndex = 0;
|
|
std::unique_ptr<lcMesh> StagedMesh;
|
|
QString Error;
|
|
};
|
|
|
|
using PartRequestMap = std::map<PieceInfo*, std::shared_ptr<Request>>;
|
|
using TextureRequestMap = std::map<lcTexture*, std::shared_ptr<TextureRequest>>;
|
|
using SynthRequestMap = std::map<lcPiece*, std::shared_ptr<SynthRequest>>;
|
|
|
|
struct Completion
|
|
{
|
|
std::shared_ptr<Request> RequestedPart;
|
|
lcPartBuildResult Result;
|
|
std::shared_ptr<TextureRequest> RequestedTexture;
|
|
lcTextureBuildResult TextureResult;
|
|
std::shared_ptr<SynthRequest> RequestedSynth;
|
|
std::unique_ptr<lcLibraryMeshData> SynthMeshData;
|
|
std::unique_ptr<lcMesh> SynthMesh;
|
|
};
|
|
|
|
struct Notification
|
|
{
|
|
std::shared_ptr<Request> RequestedPart;
|
|
bool Loaded;
|
|
QString Error;
|
|
};
|
|
|
|
struct SynthNotification
|
|
{
|
|
std::shared_ptr<SynthRequest> RequestedSynth;
|
|
PieceInfo* Info;
|
|
};
|
|
|
|
void QueuePieceLocked(PieceInfo* Info, Priority LoadPriority);
|
|
void SetRequestPriorityLocked(const std::shared_ptr<Request>& RequestedPart, Priority LoadPriority);
|
|
void QueueTexture(lcTexture* Texture, Priority LoadPriority);
|
|
static QString TextureFailureMessage(const lcTexture* Texture);
|
|
void CancelUnusedTextureRequests();
|
|
void StartWorkersLocked();
|
|
void LoadQueuedPieces();
|
|
bool ProcessCompletions();
|
|
void DispatchNotifications();
|
|
void FinishPart(const std::shared_ptr<Request>& RequestedPart);
|
|
void CheckWaitingParts();
|
|
void CheckWaitingSynths();
|
|
void FinishSynth(const std::shared_ptr<SynthRequest>& RequestedSynth);
|
|
void UploadTextureRequest(const std::shared_ptr<TextureRequest>& RequestedTexture);
|
|
void FinishTextureRequest(const std::shared_ptr<TextureRequest>& RequestedTexture);
|
|
void WaitForResultsLocked();
|
|
bool WaitForRequest(PieceInfo* Info);
|
|
bool event(QEvent* Event) override;
|
|
|
|
lcPiecesLibrary* const mLibrary;
|
|
QMutex mQueueMutex;
|
|
QWaitCondition mResultReady;
|
|
QMutex mDrainMutex;
|
|
PartRequestMap mRequests;
|
|
TextureRequestMap mTextureRequests;
|
|
SynthRequestMap mSynthRequests;
|
|
std::unordered_map<const lcPiece*, QString> mFailedSynthErrors;
|
|
std::unordered_set<lcPiece*> mSynthPieces;
|
|
std::deque<std::shared_ptr<Request>> mQueue;
|
|
std::deque<std::shared_ptr<Request>> mPausedQueue;
|
|
std::deque<std::shared_ptr<TextureRequest>> mTextureQueue;
|
|
std::deque<std::shared_ptr<TextureRequest>> mPausedTextureQueue;
|
|
std::deque<std::shared_ptr<SynthRequest>> mSynthQueue;
|
|
std::deque<std::shared_ptr<SynthRequest>> mPausedSynthQueue;
|
|
std::deque<Completion> mCompletions;
|
|
std::deque<std::shared_ptr<Request>> mStarted;
|
|
std::deque<std::shared_ptr<TextureRequest>> mStartedTextures;
|
|
std::deque<Notification> mNotifications;
|
|
std::deque<SynthNotification> mSynthNotifications;
|
|
std::vector<QFuture<void>> mFutures;
|
|
int mActiveWorkers = 0;
|
|
quint64 mNextRequestId = 1;
|
|
quint64 mGeneration = 1;
|
|
bool mPaused = false;
|
|
bool mStopping = false;
|
|
|
|
Q_DECLARE_TR_FUNCTIONS(lcAssetLoader)
|
|
};
|