Plasma Engine  2.0
Loading...
Searching...
No Matches
AssetCurator.h
1#pragma once
2
3#include <Core/Configuration/PlatformProfile.h>
4#include <EditorFramework/Assets/AssetDocumentInfo.h>
5#include <EditorFramework/Assets/AssetDocumentManager.h>
6#include <EditorFramework/Assets/Declarations.h>
7#include <EditorFramework/EditorFrameworkDLL.h>
8#include <Foundation/Algorithm/HashHelperString.h>
9#include <Foundation/Application/Config/FileSystemConfig.h>
10#include <Foundation/Configuration/Singleton.h>
11#include <Foundation/Containers/HashTable.h>
12#include <Foundation/IO/DirectoryWatcher.h>
13#include <Foundation/Logging/LogEntry.h>
14#include <Foundation/Profiling/Profiling.h>
15#include <Foundation/Threading/AtomicInteger.h>
16#include <Foundation/Threading/DelegateTask.h>
17#include <Foundation/Threading/LockedObject.h>
18#include <Foundation/Threading/Mutex.h>
19#include <Foundation/Threading/TaskSystem.h>
20#include <Foundation/Time/Timestamp.h>
21#include <ToolsFoundation/Document/DocumentManager.h>
22#include <ToolsFoundation/FileSystem/DataDirPath.h>
23#include <ToolsFoundation/FileSystem/Declarations.h>
24
25#include <tuple>
26
27class plUpdateTask;
28class plTask;
30class plDirectoryWatcher;
31class plProcessTask;
32struct plFileStats;
34class plFileSystemWatcher;
36struct plFileChangedEvent;
37class plFileSystemModel;
38
39
40#if 0 // Define to enable extensive curator profile scopes
41# define CURATOR_PROFILE(szName) PL_PROFILE_SCOPE(szName)
42
43#else
44# define CURATOR_PROFILE(Name)
45
46#endif
47
49class plCuratorMutex : public plMutex
50{
51public:
52 void Lock()
53 {
54 CURATOR_PROFILE("plCuratorMutex");
56 }
57
58 void Unlock() { plMutex::Unlock(); }
59};
60
61struct PL_EDITORFRAMEWORK_DLL plAssetInfo
62{
63 plAssetInfo() = default;
64 void Update(plUniquePtr<plAssetInfo>& rhs);
65
66 plAssetDocumentManager* GetManager() { return static_cast<plAssetDocumentManager*>(m_pDocumentTypeDescriptor->m_pManager); }
67
68 enum TransformState : plUInt8
69 {
70 Unknown = 0,
71 UpToDate,
72 NeedsImport,
73 NeedsTransform,
74 NeedsThumbnail,
75 TransformError,
76 MissingTransformDependency,
77 MissingThumbnailDependency,
78 CircularDependency,
79 COUNT,
80 };
81
82 plUInt8 m_LastStateUpdate = 0;
83 plAssetExistanceState::Enum m_ExistanceState = plAssetExistanceState::FileAdded;
84 TransformState m_TransformState = TransformState::Unknown;
85 plUInt64 m_AssetHash = 0;
86 plUInt64 m_ThumbHash = 0;
87
88 plDynamicArray<plLogEntry> m_LogEntries;
89
90 const plAssetDocumentTypeDescriptor* m_pDocumentTypeDescriptor = nullptr;
91 plDataDirPath m_Path;
92
94
95 plSet<plString> m_MissingTransformDeps;
96 plSet<plString> m_MissingThumbnailDeps;
97 plSet<plString> m_CircularDependencies;
98
100
101private:
102 PL_DISALLOW_COPY_AND_ASSIGN(plAssetInfo);
103};
104
106struct PL_EDITORFRAMEWORK_DLL plSubAsset
107{
108 plStringView GetName() const;
109 void GetSubAssetIdentifier(plStringBuilder& out_sPath) const;
110
111 plAssetExistanceState::Enum m_ExistanceState = plAssetExistanceState::FileAdded;
112 plAssetInfo* m_pAssetInfo = nullptr;
113 plTime m_LastAccess;
114 bool m_bMainAsset = true;
115
116 plSubAssetData m_Data;
117};
118
119
120
122{
123 enum class Type
124 {
125 AssetAdded,
126 AssetRemoved,
127 AssetMoved,
128 AssetUpdated,
129 AssetListReset,
130 ActivePlatformChanged,
131 };
132
133 plUuid m_AssetGuid;
134 const plSubAsset* m_pInfo;
135 Type m_Type;
136};
137
138class PL_EDITORFRAMEWORK_DLL plAssetCurator
139{
140 PL_DECLARE_SINGLETON(plAssetCurator);
141
142public:
145
148
150 void StartInitialize(const plApplicationFileSystemConfig& cfg);
152 void WaitForInitialize();
153 void Deinitialize();
154
155 void MainThreadTick(bool bTopLevel);
156
160
161public:
165 const plPlatformProfile* GetDevelopmentAssetProfile() const;
166
168 const plPlatformProfile* GetActiveAssetProfile() const;
169
171 plUInt32 GetActiveAssetProfileIndex() const;
172
174 plUInt32 FindAssetProfileByName(const char* szPlatform);
175
176 plUInt32 GetNumAssetProfiles() const;
177
179 const plPlatformProfile* GetAssetProfile(plUInt32 uiIndex) const;
180
182 plPlatformProfile* GetAssetProfile(plUInt32 uiIndex);
183
185 plPlatformProfile* CreateAssetProfile();
186
191 plResult DeleteAssetProfile(plPlatformProfile* pProfile);
192
196 void SetActiveAssetProfileByIndex(plUInt32 uiIndex, bool bForceReevaluation = false);
197
199 plResult SaveAssetProfiles();
200
201 void SaveRuntimeProfiles();
202
203private:
204 void ClearAssetProfiles();
205 void SetupDefaultAssetProfiles();
206 plResult LoadAssetProfiles();
207 void ComputeAllDocumentManagerAssetProfileHashes();
208
210
214
215public:
216 plDateTime GetLastFullTransformDate() const;
217 void StoreFullTransformDate();
218
220 plStatus TransformAllAssets(plBitflags<plTransformFlags> transformFlags, const plPlatformProfile* pAssetProfile = nullptr);
221 void ResaveAllAssets();
222 plTransformStatus TransformAsset(const plUuid& assetGuid, plBitflags<plTransformFlags> transformFlags, const plPlatformProfile* pAssetProfile = nullptr);
223 plTransformStatus CreateThumbnail(const plUuid& assetGuid);
224
227 void TransformAssetsForSceneExport(const plPlatformProfile* pAssetProfile = nullptr);
228
230 plResult WriteAssetTables(const plPlatformProfile* pAssetProfile = nullptr, bool bForce = false);
231
236
242 const plLockedSubAsset FindSubAsset(plStringView sPathOrGuid, bool bExhaustiveSearch = false) const;
243
245 const plLockedSubAsset GetSubAsset(const plUuid& assetGuid) const;
246
248
250 const plLockedSubAssetTable GetKnownSubAssets() const;
251
253
255 const plLockedAssetTable GetKnownAssets() const;
256
258 plUInt64 GetAssetDependencyHash(plUuid assetGuid);
259
261 plUInt64 GetAssetReferenceHash(plUuid assetGuid);
262
263 plAssetInfo::TransformState IsAssetUpToDate(const plUuid& assetGuid, const plPlatformProfile* pAssetProfile, const plAssetDocumentTypeDescriptor* pTypeDescriptor, plUInt64& out_uiAssetHash, plUInt64& out_uiThumbHash, bool bForce = false);
265 void GetAssetTransformStats(plUInt32& out_uiNumAssets, plHybridArray<plUInt32, plAssetInfo::TransformState::COUNT>& out_count);
266
268 plString FindDataDirectoryForAsset(plStringView sAbsoluteAssetPath) const;
269
274 plResult FindBestMatchForFile(plStringBuilder& ref_sFile, plArrayPtr<plString> allowedFileExtensions) const;
275
286 void FindAllUses(plUuid assetGuid, plSet<plUuid>& ref_uses, bool bTransitive) const;
287
291 void FindAllUses(plStringView sAbsolutePath, plSet<plUuid>& ref_uses) const;
292
296 bool IsReferenced(plStringView sAbsolutePath) const;
297
298
302
304 void NotifyOfFileChange(plStringView sAbsolutePath);
306 void NotifyOfAssetChange(const plUuid& assetGuid);
307 void UpdateAssetLastAccessTime(const plUuid& assetGuid);
308
310 void CheckFileSystem();
311
312 void NeedsReloadResources(const plUuid& assetGuid);
313
314 void InvalidateAssetsWithTransformState(plAssetInfo::TransformState state);
315
316
318
321
323 void GenerateTransitiveHull(const plStringView sAssetOrPath, plSet<plString>& inout_deps, bool bIncludeTransformDeps = false, bool bIncludeThumbnailDeps = false, bool bIncludePackageDeps = false) const;
324
326 void GenerateInverseTransitiveHull(const plAssetInfo* pAssetInfo, plSet<plUuid>& inout_inverseDeps, bool bIncludeTransformDeps = false, bool bIncludeThumbnailDeps = false) const;
327
329 void WriteDependencyDGML(const plUuid& guid, plStringView sOutputFile) const;
330
332
333public:
335
336private:
339
340 plTransformStatus ProcessAsset(plAssetInfo* pAssetInfo, const plPlatformProfile* pAssetProfile, plBitflags<plTransformFlags> transformFlags);
341 plStatus ResaveAsset(plAssetInfo* pAssetInfo);
343 plAssetInfo* GetAssetInfo(const plUuid& assetGuid);
344 const plAssetInfo* GetAssetInfo(const plUuid& assetGuid) const;
345
346 plSubAsset* GetSubAssetInternal(const plUuid& assetGuid);
347
349 plAssetInfo* GetAssetInfo(const plString& sAssetGuid);
350
351 void OnFileChangedEvent(const plFileChangedEvent& e);
352
355 void ProcessAllCoreAssets();
356
360
361 void RestartUpdateTask();
362 void ShutdownUpdateTask();
363
364 bool GetNextAssetToUpdate(plUuid& out_guid, plStringBuilder& out_sAbsPath);
365 void OnUpdateTaskFinished(const plSharedPtr<plTask>& pTask);
366 void RunNextUpdateTask();
367
371
372 plAssetInfo::TransformState HashAsset(
373 plUInt64 uiSettingsHash, const plHybridArray<plString, 16>& assetTransformDeps, const plHybridArray<plString, 16>& assetThumbnailDeps, plSet<plString>& missingTransformDeps, plSet<plString>& missingThumbnailDeps, plUInt64& out_AssetHash, plUInt64& out_ThumbHash, bool bForce);
374 bool AddAssetHash(plString& sPath, bool bIsReference, plUInt64& out_AssetHash, plUInt64& out_ThumbHash, bool bForce);
375
376 plResult EnsureAssetInfoUpdated(const plDataDirPath& absFilePath, const plFileStatus& stat, bool bForce = false);
377 void TrackDependencies(plAssetInfo* pAssetInfo);
378 void UntrackDependencies(plAssetInfo* pAssetInfo);
379 plResult CheckForCircularDependencies(plAssetInfo* pAssetInfo);
380 void UpdateTrackedFiles(const plUuid& assetGuid, const plSet<plString>& files, plMap<plString, plHybridArray<plUuid, 1>>& inverseTracker, plSet<std::tuple<plUuid, plUuid>>& unresolved, bool bAdd);
381 void UpdateUnresolvedTrackedFiles(plMap<plString, plHybridArray<plUuid, 1>>& inverseTracker, plSet<std::tuple<plUuid, plUuid>>& unresolved);
382 plResult ReadAssetDocumentInfo(const plDataDirPath& absFilePath, const plFileStatus& stat, plUniquePtr<plAssetInfo>& assetInfo);
383 void UpdateSubAssets(plAssetInfo& assetInfo);
384
385 void RemoveAssetTransformState(const plUuid& assetGuid);
386 void InvalidateAssetTransformState(const plUuid& assetGuid);
387
388 plAssetInfo::TransformState UpdateAssetTransformState(plUuid assetGuid, plUInt64& out_AssetHash, plUInt64& out_ThumbHash, bool bForce);
389 void UpdateAssetTransformState(const plUuid& assetGuid, plAssetInfo::TransformState state);
390 void UpdateAssetTransformLog(const plUuid& assetGuid, plDynamicArray<plLogEntry>& logEntries);
391 void SetAssetExistanceState(plAssetInfo& assetInfo, plAssetExistanceState::Enum state);
392
396 void SetAllAssetStatusUnknown();
399 static void BuildFileExtensionSet(plSet<plString>& AllExtensions);
400
404
405public:
411 void ClearAssetCaches(plAssetDocumentManager::OutputReliability threshold);
412
414
415private:
416 friend class plUpdateTask;
417 friend class plAssetProcessor;
418 friend class plProcessTask;
419
420 mutable plCuratorMutex m_CuratorMutex; // Global lock
421 plTaskGroupID m_InitializeCuratorTaskID;
422
423 plUInt32 m_uiActiveAssetProfile = 0;
424
425 // Actual data stored in the curator
427 plHashTable<plUuid, plSubAsset> m_KnownSubAssets;
428
429 // Derived dependency lookup tables
430 plMap<plString, plHybridArray<plUuid, 1>> m_InverseTransformDeps; // [Absolute path -> asset Guid]
431 plMap<plString, plHybridArray<plUuid, 1>> m_InverseThumbnailDeps; // [Absolute path -> asset Guid]
432 plSet<std::tuple<plUuid, plUuid>> m_UnresolvedTransformDeps;
433 plSet<std::tuple<plUuid, plUuid>> m_UnresolvedThumbnailDeps;
434
435 // State caches
436 plHashSet<plUuid> m_TransformState[plAssetInfo::TransformState::COUNT];
437 plHashSet<plUuid> m_SubAssetChanged;
438 plHashSet<plUuid> m_TransformStateStale;
439 plHashSet<plUuid> m_Updating;
440
441 // Serialized cache
442 mutable plCuratorMutex m_CachedAssetsMutex;
444 plMap<plString, plFileStatus> m_CachedFiles;
445
446 // Immutable data after StartInitialize
447 plApplicationFileSystemConfig m_FileSystemConfig;
448 plUniquePtr<plAssetTableWriter> m_pAssetTableWriter;
449 plSet<plString> m_ValidAssetExtensions;
450
451 // Update task
452 bool m_bRunUpdateTask = false;
453 plSharedPtr<plUpdateTask> m_pUpdateTask;
454 plTaskGroupID m_UpdateTaskGroup;
455};
456
457class plUpdateTask final : public plTask
458{
459public:
462
463private:
464 plStringBuilder m_sAssetPath;
465
466 virtual void Execute() override;
467};
Definition FileSystemConfig.h:8
This class encapsulates an array and it's size. It is recommended to use this class instead of plain ...
Definition ArrayPtr.h:37
Definition AssetCurator.h:139
Definition AssetDocumentManager.h:13
OutputReliability
Definition AssetDocumentManager.h:84
Background asset processing is handled by this class. Creates EditorProcessor processes.
Definition AssetProcessor.h:104
Log for all background processing results.
Definition AssetProcessor.h:21
Keeps track of all asset tables and their state as well as reloading modified resources.
Definition AssetTableWriter.h:44
Custom mutex that allows to profile the time in the curator lock.
Definition AssetCurator.h:50
A reference to a file or folder inside a data directory.
Definition DataDirPath.h:18
The plDateTime class can be used to convert plTimestamp into a human readable form.
Definition Timestamp.h:103
Definition DynamicArray.h:81
Definition Event.h:177
Definition HashSet.h:191
Definition HashTable.h:333
A hybrid array uses in-place storage to handle the first few elements without any allocation....
Definition HybridArray.h:12
Provides access to an object while managing a lock (e.g. a mutex) that ensures that during its lifeti...
Definition LockedObject.h:7
Definition Map.h:408
Provides a simple mechanism for mutual exclusion to prevent multiple threads from accessing a shared ...
Definition Mutex.h:13
void Unlock()
Releases a lock that has been previously acquired.
Definition Mutex_posix.h:34
void Lock()
Acquires an exclusive lock for this mutex object.
Definition Mutex_posix.h:18
Definition PlatformProfile.h:25
Definition AssetProcessor.h:54
Definition Set.h:238
A Shared ptr manages a shared object and destroys that object when no one references it anymore....
Definition SharedPtr.h:10
plStringBuilder is a class that is meant for creating and modifying strings.
Definition StringBuilder.h:35
plStringView represent a read-only sub-string of a larger string, as it can store a dedicated string ...
Definition StringView.h:34
Given out by plTaskSystem::CreateTaskGroup to identify a task group.
Definition TaskSystemDeclarations.h:103
Base class for custom tasks.
Definition Task.h:10
A Unique ptr manages an object and destroys that object when it goes out of scope....
Definition UniquePtr.h:10
Definition AssetCurator.h:458
virtual void Execute() override
Override this to implement the task's supposed functionality.
Definition AssetUpdates.cpp:693
This data type is the abstraction for 128-bit Uuid (also known as GUID) instances.
Definition Uuid.h:11
Definition AssetCurator.h:122
Definition Declarations.h:89
Definition AssetCurator.h:62
plSet< plUuid > m_SubAssets
Main asset uses the same GUID as this (see m_Info), but is NOT stored in m_SubAssets.
Definition AssetCurator.h:99
The plBitflags class allows you to work with type-safe bitflags.
Definition Bitflags.h:82
Holds the stats for a file.
Definition OSFile.h:34
Information about a single file on disk. The file might be a document or any other file found in the ...
Definition Declarations.h:20
Default enum for returning failure or success, instead of using a bool.
Definition Types.h:54
An plResult with an additional message for the reason of failure.
Definition Status.h:12
Definition Declarations.h:82
Information about an asset or sub-asset.
Definition AssetCurator.h:107
The time class encapsulates a double value storing the time in seconds.
Definition Time.h:12
Definition Declarations.h:114