Plasma Engine  2.0
Loading...
Searching...
No Matches
ResourceManager.h
1#pragma once
2
3#include <Core/ResourceManager/Implementation/WorkerTasks.h>
4#include <Core/ResourceManager/Resource.h>
5#include <Core/ResourceManager/ResourceHandle.h>
6#include <Core/ResourceManager/ResourceTypeLoader.h>
7#include <Foundation/Configuration/Plugin.h>
8#include <Foundation/Containers/HashTable.h>
9#include <Foundation/Threading/LockedObject.h>
10#include <Foundation/Types/UniquePtr.h>
11
13
15class PL_CORE_DLL plResourceManager
16{
17 friend class plResourceManagerState;
19
22
23public:
26 static const plEvent<const plResourceEvent&, plMutex>& GetResourceEvents();
27
29 static const plEvent<const plResourceManagerEvent&, plMutex>& GetManagerEvents();
30
34 static void BroadcastExistsEvent();
35
39
40public:
47 template <typename ResourceType>
48 static plTypedResourceHandle<ResourceType> LoadResource(plStringView sResourceID);
49
57 template <typename ResourceType>
58 static plTypedResourceHandle<ResourceType> LoadResource(plStringView sResourceID, plTypedResourceHandle<ResourceType> hLoadingFallback);
59
60
63 static plTypelessResourceHandle LoadResourceByType(const plRTTI* pResourceType, plStringView sResourceID);
64
66 static bool IsAnyLoadingInProgress();
67
72 static plString GenerateUniqueResourceID(plStringView sResourceIDPrefix);
73
80 template <typename ResourceType, typename DescriptorType>
81 static plTypedResourceHandle<ResourceType> CreateResource(plStringView sResourceID, DescriptorType&& descriptor, plStringView sResourceDescription = nullptr);
82
88 template <typename ResourceType, typename DescriptorType>
89 static plTypedResourceHandle<ResourceType> GetOrCreateResource(plStringView sResourceID, DescriptorType&& descriptor, plStringView sResourceDescription = nullptr);
90
95 template <typename ResourceType>
96 static plTypedResourceHandle<ResourceType> GetExistingResource(plStringView sResourceID);
97
99 static plTypelessResourceHandle GetExistingResourceByType(const plRTTI* pResourceType, plStringView sResourceID);
100
101 template <typename ResourceType>
102 static plTypedResourceHandle<ResourceType> GetExistingResourceOrCreateAsync(plStringView sResourceID, plUniquePtr<plResourceTypeLoader>&& pLoader, plTypedResourceHandle<ResourceType> hLoadingFallback = {})
103 {
104 plTypelessResourceHandle hTypeless = GetExistingResourceOrCreateAsync(plGetStaticRTTI<ResourceType>(), sResourceID, std::move(pLoader));
105
106 auto hTyped = plTypedResourceHandle<ResourceType>((ResourceType*)hTypeless.m_pResource);
107
108 if (hLoadingFallback.IsValid())
109 {
110 ((ResourceType*)hTypeless.m_pResource)->SetLoadingFallbackResource(hLoadingFallback);
111 }
112
113 return hTyped;
114 }
115
116 static plTypelessResourceHandle GetExistingResourceOrCreateAsync(const plRTTI* pResourceType, plStringView sResourceID, plUniquePtr<plResourceTypeLoader>&& pLoader);
117
120 static void PreloadResource(const plTypelessResourceHandle& hResource);
121
123 static void ForceLoadResourceNow(const plTypelessResourceHandle& hResource);
124
126 static plResourceState GetLoadingState(const plTypelessResourceHandle& hResource);
127
131
132public:
135 static plUInt32 ReloadAllResources(bool bForce);
136
139 template <typename ResourceType>
140 static plUInt32 ReloadResourcesOfType(bool bForce);
141
144 static plUInt32 ReloadResourcesOfType(const plRTTI* pType, bool bForce);
145
147 template <typename ResourceType>
148 static bool ReloadResource(const plTypedResourceHandle<ResourceType>& hResource, bool bForce);
149
151 static bool ReloadResource(const plRTTI* pType, const plTypelessResourceHandle& hResource, bool bForce);
152
153
160 static void UpdateResourceWithCustomLoader(const plTypelessResourceHandle& hResource, plUniquePtr<plResourceTypeLoader>&& pLoader);
161
165 static void RestoreResource(const plTypelessResourceHandle& hResource);
166
170
171public:
181 template <typename ResourceType>
182 static ResourceType* BeginAcquireResource(const plTypedResourceHandle<ResourceType>& hResource, plResourceAcquireMode mode,
184 plResourceAcquireResult* out_pAcquireResult = nullptr);
185
187 static plResource* BeginAcquireResourcePointer(const plRTTI* pType, const plTypelessResourceHandle& hResource);
188
191 template <typename ResourceType>
192 static void EndAcquireResource(ResourceType* pResource);
193
195 static void EndAcquireResourcePointer(plResource* pResource);
196
199 static void ForceNoFallbackAcquisition(plUInt32 uiNumFrames = 0xFFFFFFFF);
200
203 static plUInt32 GetForceNoFallbackAcquisition();
204
208 template <typename ResourceType>
209 static plLockedObject<plMutex, plDynamicArray<plResource*>> GetAllResourcesOfType();
210
214
215public:
217 static plUInt32 FreeAllUnusedResources();
218
220 static plUInt32 FreeUnusedResources(plTime timeout, plTime lastAcquireThreshold);
221
223 static void SetAutoFreeUnused(plTime timeout, plTime lastAcquireThreshold);
224
226 template <typename ResourceType>
227 static void SetIncrementalUnloadForResourceType(bool bActive);
228
229 template <typename TypeBeingUpdated, typename TypeItWantsToAcquire>
230 static void AllowResourceTypeAcquireDuringUpdateContent()
231 {
232 AllowResourceTypeAcquireDuringUpdateContent(plGetStaticRTTI<TypeBeingUpdated>(), plGetStaticRTTI<TypeItWantsToAcquire>());
233 }
234
235 static void AllowResourceTypeAcquireDuringUpdateContent(const plRTTI* pTypeBeingUpdated, const plRTTI* pTypeItWantsToAcquire);
236
237 static bool IsResourceTypeAcquireDuringUpdateContentAllowed(const plRTTI* pTypeBeingUpdated, const plRTTI* pTypeItWantsToAcquire);
238
239private:
240 static plResult DeallocateResource(plResource* pResource);
241
245
246public:
249 static plMutex& GetMutex() { return s_ResourceMutex; }
250
252 static void PerFrameUpdate();
253
255 static void EngineAboutToShutdown();
256
260 static void ResetAllResources();
261
271 static void SetResourceLowResData(const plTypelessResourceHandle& hResource, plStreamReader* pStream);
272
276
277public:
279 static void SetDefaultResourceLoader(plResourceTypeLoader* pDefaultLoader);
280
282 static plResourceTypeLoader* GetDefaultResourceLoader();
283
287 template <typename ResourceType>
288 static void SetResourceTypeLoader(plResourceTypeLoader* pCreator);
289
293
294public:
300 static void RegisterNamedResource(plStringView sLookupName, plStringView sRedirectionResource);
301
303 static void UnregisterNamedResource(plStringView sLookupName);
304
305
309
310public:
312 static void RegisterResourceForAssetType(plStringView sAssetTypeName, const plRTTI* pResourceType);
313
316 static const plRTTI* FindResourceForAssetType(plStringView sAssetTypeName);
317
321
322public:
325 static void EnableExportMode(bool bEnable);
326
328 static bool IsExportModeEnabled();
329
333 template <typename ResourceType>
334 static plTypedResourceHandle<ResourceType> GetResourceHandleForExport(plStringView sResourceID);
335
336
340
341public:
354 static void RegisterResourceOverrideType(const plRTTI* pDerivedTypeToUse, plDelegate<bool(const plStringBuilder&)> overrideDecider);
355
359 static void UnregisterResourceOverrideType(const plRTTI* pDerivedTypeToUse);
360
364
365public:
367 template <typename RESOURCE_TYPE>
369 {
370 RESOURCE_TYPE::SetResourceTypeLoadingFallback(hResource);
371 }
372
374 template <typename RESOURCE_TYPE>
376 {
377 return RESOURCE_TYPE::GetResourceTypeLoadingFallback();
378 }
379
383 template <typename RESOURCE_TYPE>
385 {
386 RESOURCE_TYPE::SetResourceTypeMissingFallback(hResource);
387 }
388
390 template <typename RESOURCE_TYPE>
392 {
393 return RESOURCE_TYPE::GetResourceTypeMissingFallback();
394 }
395
396 using ResourceCleanupCB = plDelegate<void()>;
397
399 static void AddResourceCleanupCallback(ResourceCleanupCB cb);
400
402 static void ClearResourceCleanupCallback(ResourceCleanupCB cb);
403
406 static void ExecuteAllResourceCleanupCallbacks();
407
411
412public:
414 template <typename RESOURCE_TYPE>
415 static void SetResourceTypeDefaultPriority(plResourcePriority priority)
416 {
417 GetResourceTypePriorities()[plGetStaticRTTI<RESOURCE_TYPE>()] = priority;
418 }
419
420private:
421 static plMap<const plRTTI*, plResourcePriority>& GetResourceTypePriorities();
423
427
428private:
429 friend class plResource;
432 friend class plResourceHandleReadContext;
433
434 // Events
435private:
436 static void BroadcastResourceEvent(const plResourceEvent& e);
437
438 // Miscellaneous
439private:
440 static plMutex s_ResourceMutex;
441
442 // Startup / shutdown
443private:
444 PL_MAKE_SUBSYSTEM_STARTUP_FRIEND(Core, ResourceManager);
445 static void OnEngineShutdown();
446 static void OnCoreShutdown();
447 static void OnCoreStartup();
448 static void PluginEventHandler(const plPluginEvent& e);
449
450 // Loading / reloading / creating resources
451private:
452 struct LoadedResources
453 {
455 };
456
457 struct LoadingInfo
458 {
459 float m_fPriority = 0;
460 plResource* m_pResource = nullptr;
461
462 PL_ALWAYS_INLINE bool operator==(const LoadingInfo& rhs) const { return m_pResource == rhs.m_pResource; }
463 PL_ALWAYS_INLINE bool operator<(const LoadingInfo& rhs) const { return m_fPriority < rhs.m_fPriority; }
464 };
465 static void EnsureResourceLoadingState(plResource* pResource, const plResourceState RequestedState);
466 static void PreloadResource(plResource* pResource);
467 static void InternalPreloadResource(plResource* pResource, bool bHighestPriority);
468
469 template <typename ResourceType>
470 static ResourceType* GetResource(plStringView sResourceID, bool bIsReloadable);
471 static plResource* GetResource(const plRTTI* pRtti, plStringView sResourceID, bool bIsReloadable);
472 static void RunWorkerTask(plResource* pResource);
473 static void UpdateLoadingDeadlines();
474 static void ReverseBubbleSortStep(plDeque<LoadingInfo>& data);
475 static bool ReloadResource(plResource* pResource, bool bForce);
476
477 static void SetupWorkerTasks();
478 static plTime GetLastFrameUpdate();
479 static plHashTable<const plRTTI*, LoadedResources>& GetLoadedResources();
480 static plDynamicArray<plResource*>& GetLoadedResourceOfTypeTempContainer();
481
482 PL_ALWAYS_INLINE static bool IsQueuedForLoading(plResource* pResource) { return pResource->m_Flags.IsSet(plResourceFlags::IsQueuedForLoading); }
483 [[nodiscard]] static plResult RemoveFromLoadingQueue(plResource* pResource);
484 static void AddToLoadingQueue(plResource* pResource, bool bHighPriority);
485
486 struct ResourceTypeInfo
487 {
488 bool m_bIncrementalUnload = true;
489 bool m_bAllowNestedAcquireCached = false;
490
492 };
493
494 static ResourceTypeInfo& GetResourceTypeInfo(const plRTTI* pRtti);
495
496 // Type loaders
497private:
498 static plResourceTypeLoader* GetResourceTypeLoader(const plRTTI* pRTTI);
499
500 static plMap<const plRTTI*, plResourceTypeLoader*>& GetResourceTypeLoaders();
501
502 // Override / derived resources
503private:
504 struct DerivedTypeInfo
505 {
506 const plRTTI* m_pDerivedType = nullptr;
507 plDelegate<bool(const plStringBuilder&)> m_Decider;
508 };
509
511 static const plRTTI* FindResourceTypeOverride(const plRTTI* pRtti, plStringView sResourceID);
512};
513
514#include <Core/ResourceManager/Implementation/ResourceLock.h>
515#include <Core/ResourceManager/Implementation/ResourceManager_inl.h>
Definition Deque.h:270
Definition DynamicArray.h:81
Definition Event.h:177
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
This class holds information about reflected types. Each instance represents one type that is known t...
Definition RTTI.h:30
The base class for all resources.
Definition Resource.h:10
The central class for managing all types derived from plResource.
Definition ResourceManager.h:16
static void SetResourceTypeDefaultPriority(plResourcePriority priority)
Specifies which resource to use as a loading fallback for the given type, while a resource is not yet...
Definition ResourceManager.h:415
static const plTypedResourceHandle< RESOURCE_TYPE > & GetResourceTypeMissingFallback()
Definition ResourceManager.h:391
static void SetResourceTypeLoadingFallback(const plTypedResourceHandle< RESOURCE_TYPE > &hResource)
Specifies which resource to use as a loading fallback for the given type, while a resource is not yet...
Definition ResourceManager.h:368
static void SetResourceTypeMissingFallback(const plTypedResourceHandle< RESOURCE_TYPE > &hResource)
Specifies which resource to use as a missing fallback for the given type, when a resource cannot be l...
Definition ResourceManager.h:384
static const plTypedResourceHandle< RESOURCE_TYPE > & GetResourceTypeLoadingFallback()
Definition ResourceManager.h:375
static plMutex & GetMutex()
Returns the resource manager mutex. Allows to lock the manager on a thread when multiple operations n...
Definition ResourceManager.h:249
Definition ResourceManagerState.h:9
[internal] Worker task for loading resources (typically from disk).
Definition WorkerTasks.h:10
[internal] Worker task for uploading resource data. Depending on the resource type,...
Definition WorkerTasks.h:26
Base class for all resource loaders.
Definition ResourceTypeLoader.h:29
Interface for binary in (read) streams.
Definition Stream.h:22
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
The plTypedResourceHandle controls access to an plResource.
Definition ResourceHandle.h:136
PL_ALWAYS_INLINE bool IsValid() const
Returns whether the handle stores a valid pointer to a resource.
Definition ResourceHandle.h:206
The typeless implementation of resource handles. A typed interface is provided by plTypedResourceHand...
Definition ResourceHandle.h:32
A Unique ptr manages an object and destroys that object when it goes out of scope....
Definition UniquePtr.h:10
PL_ALWAYS_INLINE bool IsSet(Enum flag) const
Checks if certain flags are set within the bitfield.
Definition Bitflags.h:127
A generic delegate class which supports static functions and member functions.
Definition Delegate.h:76
The data that is broadcast whenever a plugin is (un-) loaded.
Definition Plugin.h:11
These events may be sent by a specific plResource or by the plResourceManager.
Definition Declarations.h:22
Default enum for returning failure or success, instead of using a bool.
Definition Types.h:54
The time class encapsulates a double value storing the time in seconds.
Definition Time.h:12