Plasma Engine  2.0
Loading...
Searching...
No Matches
ResourceHandle.h
1#pragma once
2
3#include <Core/CoreDLL.h>
4#include <Core/ResourceManager/Implementation/Declarations.h>
5#include <Foundation/Reflection/Reflection.h>
6#include <Foundation/Strings/String.h>
7
11#define PL_RESOURCEHANDLE_STACK_TRACES PL_OFF
12
13class plResource;
14
15template <typename T>
16class plResourceLock;
17
18// These out-of-line helper functions allow to forward declare resource handles without knowledge about the resource class.
19PL_CORE_DLL void IncreaseResourceRefCount(plResource* pResource, const void* pOwner);
20PL_CORE_DLL void DecreaseResourceRefCount(plResource* pResource, const void* pOwner);
21
22#if PL_ENABLED(PL_RESOURCEHANDLE_STACK_TRACES)
23PL_CORE_DLL void MigrateResourceRefCount(plResource* pResource, const void* pOldOwner, const void* pNewOwner);
24#else
25PL_ALWAYS_INLINE void MigrateResourceRefCount(plResource* pResource, const void* pOldOwner, const void* pNewOwner)
26{
27}
28#endif
29
31class PL_CORE_DLL plTypelessResourceHandle
32{
33public:
34 PL_ALWAYS_INLINE plTypelessResourceHandle() = default;
35
38
41 {
42 m_pResource = rhs.m_pResource;
43
44 if (m_pResource)
45 {
46 IncreaseResourceRefCount(m_pResource, this);
47 }
48 }
49
52 {
53 m_pResource = rhs.m_pResource;
54 rhs.m_pResource = nullptr;
55
56 if (m_pResource)
57 {
58 MigrateResourceRefCount(m_pResource, &rhs, this);
59 }
60 }
61
63 PL_ALWAYS_INLINE ~plTypelessResourceHandle() { Invalidate(); }
64
66 PL_ALWAYS_INLINE bool IsValid() const { return m_pResource != nullptr; }
67
69 void Invalidate();
70
73 plUInt64 GetResourceIDHash() const;
74
77 const plString& GetResourceID() const;
78
80 void operator=(const plTypelessResourceHandle& rhs);
81
83 void operator=(plTypelessResourceHandle&& rhs);
84
86 PL_ALWAYS_INLINE bool operator==(const plTypelessResourceHandle& rhs) const { return m_pResource == rhs.m_pResource; }
87
89 PL_ALWAYS_INLINE bool operator!=(const plTypelessResourceHandle& rhs) const { return m_pResource != rhs.m_pResource; }
90
92 PL_ALWAYS_INLINE bool operator<(const plTypelessResourceHandle& rhs) const { return m_pResource < rhs.m_pResource; }
93
95 PL_ALWAYS_INLINE bool operator==(const plResource* rhs) const { return m_pResource == rhs; }
96
98 PL_ALWAYS_INLINE bool operator!=(const plResource* rhs) const { return m_pResource != rhs; }
99
101 const plRTTI* GetResourceType() const;
102
103protected:
104 plResource* m_pResource = nullptr;
105
106private:
107 // you must go through the resource manager to get access to the resource pointer
108 friend class plResourceManager;
109 friend class plResourceHandleWriteContext;
110 friend class plResourceHandleReadContext;
112};
113
114template <>
116{
117 PL_ALWAYS_INLINE static plUInt32 Hash(const plTypelessResourceHandle& value) { return plHashingUtils::StringHashTo32(value.GetResourceIDHash()); }
118
119 PL_ALWAYS_INLINE static bool Equal(const plTypelessResourceHandle& a, const plTypelessResourceHandle& b) { return a == b; }
120};
121
134template <typename RESOURCE_TYPE>
136{
137public:
138 using ResourceType = RESOURCE_TYPE;
139
142
144 explicit plTypedResourceHandle(ResourceType* pResource)
145 : m_hTypeless(pResource)
146 {
147 }
148
151 : m_hTypeless(rhs.m_hTypeless)
152 {
153 }
154
157 : m_hTypeless(std::move(rhs.m_hTypeless))
158 {
159 }
160
161 template <typename BaseOrDerivedType>
163 : m_hTypeless(rhs.m_hTypeless)
164 {
165 static_assert(std::is_base_of<ResourceType, BaseOrDerivedType>::value || std::is_base_of<BaseOrDerivedType, ResourceType>::value, "Only related types can be assigned to handles of this type");
166
167#if PL_ENABLED(PL_COMPILE_FOR_DEBUG)
168 if (std::is_base_of<BaseOrDerivedType, ResourceType>::value)
169 {
170 PL_ASSERT_DEBUG(rhs.IsValid(), "Cannot cast invalid base handle to derived type!");
171 plResourceLock<BaseOrDerivedType> lock(rhs, plResourceAcquireMode::PointerOnly);
172 PL_ASSERT_DEBUG(plDynamicCast<const ResourceType*>(lock.GetPointer()) != nullptr, "Types are not related!");
173 }
174#endif
175 }
176
178 void operator=(const plTypedResourceHandle<ResourceType>& rhs) { m_hTypeless = rhs.m_hTypeless; }
179
181 void operator=(plTypedResourceHandle<ResourceType>&& rhs) { m_hTypeless = std::move(rhs.m_hTypeless); }
182
184 PL_ALWAYS_INLINE bool operator==(const plTypedResourceHandle<ResourceType>& rhs) const { return m_hTypeless == rhs.m_hTypeless; }
185
187 PL_ALWAYS_INLINE bool operator!=(const plTypedResourceHandle<ResourceType>& rhs) const { return m_hTypeless != rhs.m_hTypeless; }
188
190 PL_ALWAYS_INLINE bool operator<(const plTypedResourceHandle<ResourceType>& rhs) const { return m_hTypeless < rhs.m_hTypeless; }
191
193 PL_ALWAYS_INLINE bool operator==(const plResource* rhs) const { return m_hTypeless == rhs; }
194
196 PL_ALWAYS_INLINE bool operator!=(const plResource* rhs) const { return m_hTypeless != rhs; }
197
198
200 PL_ALWAYS_INLINE operator const plTypelessResourceHandle() const { return m_hTypeless; }
201
203 PL_ALWAYS_INLINE operator plTypelessResourceHandle() { return m_hTypeless; }
204
206 PL_ALWAYS_INLINE bool IsValid() const { return m_hTypeless.IsValid(); }
207
209 PL_ALWAYS_INLINE explicit operator bool() const { return m_hTypeless.IsValid(); }
210
212 PL_ALWAYS_INLINE void Invalidate() { m_hTypeless.Invalidate(); }
213
216 PL_ALWAYS_INLINE plUInt64 GetResourceIDHash() const { return m_hTypeless.GetResourceIDHash(); }
217
220 PL_ALWAYS_INLINE const plString& GetResourceID() const { return m_hTypeless.GetResourceID(); }
221
226 {
227 if (!hHandle.IsValid())
228 return;
229
230 PL_ASSERT_DEV(hHandle.GetResourceType()->IsDerivedFrom<RESOURCE_TYPE>(), "Type '{}' does not match resource type '{}' in typeless handle.", plGetStaticRTTI<RESOURCE_TYPE>()->GetTypeName(), hHandle.GetResourceType()->GetTypeName());
231
232 m_hTypeless = hHandle;
233 }
234
235private:
236 template <typename T>
237 friend class plTypedResourceHandle;
238
239 // you must go through the resource manager to get access to the resource pointer
240 friend class plResourceManager;
241 friend class plResourceHandleWriteContext;
242 friend class plResourceHandleReadContext;
244
245 plTypelessResourceHandle m_hTypeless;
246};
247
248template <typename T>
250{
251 PL_ALWAYS_INLINE static plUInt32 Hash(const plTypedResourceHandle<T>& value) { return plHashingUtils::StringHashTo32(value.GetResourceIDHash()); }
252
253 PL_ALWAYS_INLINE static bool Equal(const plTypedResourceHandle<T>& a, const plTypedResourceHandle<T>& b) { return a == b; }
254};
255
256// Stream operations
257class plResource;
258
260{
261public:
262 template <typename ResourceType>
263 static void WriteHandle(plStreamWriter& inout_stream, const plTypedResourceHandle<ResourceType>& hResource)
264 {
265 WriteHandle(inout_stream, hResource.m_hTypeless.m_pResource);
266 }
267
268 template <typename ResourceType>
269 static void ReadHandle(plStreamReader& inout_stream, plTypedResourceHandle<ResourceType>& ref_hResourceHandle)
270 {
271 ReadHandle(inout_stream, ref_hResourceHandle.m_hTypeless);
272 }
273
274private:
275 static void WriteHandle(plStreamWriter& Stream, const plResource* pResource);
276 static void ReadHandle(plStreamReader& Stream, plTypelessResourceHandle& ResourceHandle);
277};
278
280template <typename ResourceType>
281void operator<<(plStreamWriter& inout_stream, const plTypedResourceHandle<ResourceType>& hValue)
282{
283 plResourceHandleStreamOperations::WriteHandle(inout_stream, hValue);
284}
285
287template <typename ResourceType>
288void operator>>(plStreamReader& inout_stream, plTypedResourceHandle<ResourceType>& ref_hValue)
289{
290 plResourceHandleStreamOperations::ReadHandle(inout_stream, ref_hValue);
291}
static constexpr plUInt32 StringHashTo32(plUInt64 uiHash)
Truncates a 64 bit string hash to 32 bit.
Definition HashingUtils_inl.h:138
This class holds information about reflected types. Each instance represents one type that is known t...
Definition RTTI.h:30
PL_ALWAYS_INLINE plStringView GetTypeName() const
Returns the name of this type.
Definition RTTI.h:48
PL_ALWAYS_INLINE bool IsDerivedFrom(const plRTTI *pBaseType) const
Returns true if this type is derived from the given type (or of the same type).
Definition RTTI.h:60
Definition ResourceHandle.h:260
The base class for all resources.
Definition Resource.h:10
Helper class to acquire and release a resource safely.
Definition ResourceLock.h:21
The central class for managing all types derived from plResource.
Definition ResourceManager.h:16
Interface for binary in (read) streams.
Definition Stream.h:22
Interface for binary out (write) streams.
Definition Stream.h:107
The plTypedResourceHandle controls access to an plResource.
Definition ResourceHandle.h:136
plTypedResourceHandle(plTypedResourceHandle< ResourceType > &&rhs)
Move constructor, no refcount change is necessary.
Definition ResourceHandle.h:156
PL_ALWAYS_INLINE void Invalidate()
Clears any reference to a resource and reduces its refcount.
Definition ResourceHandle.h:212
PL_ALWAYS_INLINE bool operator<(const plTypedResourceHandle< ResourceType > &rhs) const
For storing handles as keys in maps.
Definition ResourceHandle.h:190
plTypedResourceHandle(ResourceType *pResource)
Increases the refcount of the given resource.
Definition ResourceHandle.h:144
PL_ALWAYS_INLINE bool operator==(const plTypedResourceHandle< ResourceType > &rhs) const
Checks whether the two handles point to the same resource.
Definition ResourceHandle.h:184
PL_ALWAYS_INLINE bool operator==(const plResource *rhs) const
Checks whether the handle points to the given resource.
Definition ResourceHandle.h:193
PL_ALWAYS_INLINE bool IsValid() const
Returns whether the handle stores a valid pointer to a resource.
Definition ResourceHandle.h:206
void operator=(const plTypedResourceHandle< ResourceType > &rhs)
Releases the current reference and increases the refcount of the given resource.
Definition ResourceHandle.h:178
plTypedResourceHandle(const plTypedResourceHandle< ResourceType > &rhs)
Increases the refcount of the given resource.
Definition ResourceHandle.h:150
PL_ALWAYS_INLINE bool operator!=(const plResource *rhs) const
Checks whether the handle points to the given resource.
Definition ResourceHandle.h:196
void operator=(plTypedResourceHandle< ResourceType > &&rhs)
Move operator, no refcount change is necessary.
Definition ResourceHandle.h:181
PL_ALWAYS_INLINE plUInt64 GetResourceIDHash() const
Returns the Resource ID hash of the exact resource that this handle points to, without acquiring the ...
Definition ResourceHandle.h:216
PL_ALWAYS_INLINE bool operator!=(const plTypedResourceHandle< ResourceType > &rhs) const
Checks whether the two handles point to the same resource.
Definition ResourceHandle.h:187
plTypedResourceHandle()=default
A default constructed handle is invalid and does not reference any resource.
void AssignFromTypelessHandle(const plTypelessResourceHandle &hHandle)
Attempts to copy the given typeless handle to this handle.
Definition ResourceHandle.h:225
PL_ALWAYS_INLINE const plString & GetResourceID() const
Returns the Resource ID of the exact resource that this handle points to, without acquiring the resou...
Definition ResourceHandle.h:220
The typeless implementation of resource handles. A typed interface is provided by plTypedResourceHand...
Definition ResourceHandle.h:32
PL_ALWAYS_INLINE bool operator==(const plResource *rhs) const
Checks whether the handle points to the given resource.
Definition ResourceHandle.h:95
PL_ALWAYS_INLINE plTypelessResourceHandle(plTypelessResourceHandle &&rhs)
Move constructor, no refcount change is necessary.
Definition ResourceHandle.h:51
const plRTTI * GetResourceType() const
Returns the type information of the resource or nullptr if the handle is invalid.
Definition ResourceHandle.cpp:35
plUInt64 GetResourceIDHash() const
Returns the Resource ID hash of the exact resource that this handle points to, without acquiring the ...
Definition ResourceHandle.cpp:25
PL_ALWAYS_INLINE bool operator!=(const plResource *rhs) const
Checks whether the handle points to the given resource.
Definition ResourceHandle.h:98
PL_ALWAYS_INLINE ~plTypelessResourceHandle()
Releases any referenced resource.
Definition ResourceHandle.h:63
PL_ALWAYS_INLINE plTypelessResourceHandle(const plTypelessResourceHandle &rhs)
Increases the refcount of the given resource.
Definition ResourceHandle.h:40
PL_ALWAYS_INLINE bool operator==(const plTypelessResourceHandle &rhs) const
Checks whether the two handles point to the same resource.
Definition ResourceHandle.h:86
PL_ALWAYS_INLINE bool IsValid() const
Returns whether the handle stores a valid pointer to a resource.
Definition ResourceHandle.h:66
PL_ALWAYS_INLINE bool operator!=(const plTypelessResourceHandle &rhs) const
Checks whether the two handles point to the same resource.
Definition ResourceHandle.h:89
const plString & GetResourceID() const
Returns the Resource ID of the exact resource that this handle points to, without acquiring the resou...
Definition ResourceHandle.cpp:30
PL_ALWAYS_INLINE bool operator<(const plTypelessResourceHandle &rhs) const
For storing handles as keys in maps.
Definition ResourceHandle.h:92
void Invalidate()
Clears any reference to a resource and reduces its refcount.
Definition ResourceHandle.cpp:15
Helper struct to calculate the Hash of different types.
Definition HashingUtils.h:75