Foundation
Loading...
Searching...
No Matches
Details.hpp
Go to the documentation of this file.
1#pragma once
2#include <Core/AtomicPool.hpp>
3#include <Core/Logging.hpp>
7namespace Foundation::RHI
8{
9 using Handle = uintptr_t;
10 constexpr static Handle kInvalidHandle = static_cast<Handle>(-1);
17 {
18 public:
19 RHIObject() = default;
20 RHIObject(RHIObject const&) = delete;
21 RHIObject& operator=(const RHIObject&) = delete;
22 RHIObject(RHIObject&&) = delete;
24
25 virtual ~RHIObject() = default;
26 };
30 template <typename Factory, std::derived_from<RHIObject> T>
41 template <typename Factory, typename T>
43 {
44 public:
46 Factory* mFactory{nullptr};
53 template <typename U = T>
54 [[nodiscard]] U* Get() const
55 {
56 CHECK_MSG(IsValid(), "RHIHandle::Get called on an invalid handle");
58 CHECK_MSG(ptr, "RHIHandle::Get got nullptr");
59 return static_cast<U*>(ptr);
60 }
61 T* operator->() const { return Get(); }
62
63 constexpr Handle operator()() const { return mHandle; }
64 constexpr operator bool() const noexcept { return IsValid(); }
65 constexpr T* operator*() noexcept { return Get(); }
66 bool operator==(const RHIHandle& other) const { return mFactory == other.mFactory && mHandle == other.mHandle; }
67
73 [[nodiscard]] bool IsValid() const { return mFactory != nullptr && mHandle != kInvalidHandle; }
78 void Invalidate() { mFactory = nullptr, mHandle = kInvalidHandle; }
79 };
83 template <typename Factory, typename T>
84 class RHIScopedHandle : public RHIHandle<Factory, T>
85 {
86 public:
87 using RHIHandle<Factory, T>::mFactory;
88 using RHIHandle<Factory, T>::mHandle;
89 using RHIHandle<Factory, T>::Get;
90 using RHIHandle<Factory, T>::IsValid;
91 using RHIHandle<Factory, T>::Invalidate;
92
93 RHIScopedHandle() = default;
94 RHIScopedHandle(Factory* factory, Handle handle) : RHIHandle<Factory, T>(factory, handle) {}
95 RHIScopedHandle(RHIScopedHandle&& other) noexcept : RHIHandle<Factory, T>(std::move(other))
96 {
97 other.Invalidate();
98 }
100 {
101 if (this != &other)
102 {
103 mFactory = other.mFactory;
104 mHandle = other.mHandle;
105 other.Invalidate();
106 }
107 return *this;
108 }
112 [[nodiscard]] RHIHandle<Factory, T> View() const { return *this; }
118 {
119 RHIHandle<Factory, T> handle = *this;
120 Invalidate();
121 return handle;
122 }
126 void Reset()
127 {
128 if (IsValid())
129 {
131 Invalidate();
132 }
133 }
141 };
145 template <typename Base = RHIObject>
147 {
149
152
153 public:
154 RHIObjectPool(Core::Allocator* allocator) : mAllocator(allocator), mPool(allocator) {}
159 template <typename U, typename... Args>
160 Handle CreateObject(Args&&... args)
161 {
162 Base* obj = Core::ConstructBase<Base, U>(mAllocator, std::forward<Args>(args)...);
164 PointerType* pointer = mPool.Construct(std::move(owned));
165 return reinterpret_cast<Handle>(pointer);
166 }
172 template <typename U = Base>
173 static U* GetObjectPtr(Handle handle) noexcept
174 {
175 PointerType& pointer = *reinterpret_cast<PointerType*>(handle);
176 Base* obj = pointer.get();
177 return reinterpret_cast<U*>(obj);
178 }
183 {
184 auto* pointer = reinterpret_cast<PointerType*>(handle);
186 }
190 void Destroy()
191 {
192 mPool.Collect();
193 }
194 };
195} // namespace Foundation::RHI
196
197
198namespace Foundation::RHI
199{
200 class RHIApplication;
201 template <typename T>
203 template <typename T>
205
206 class RHIDevice;
207 template <typename T>
209 template <typename T>
211} // namespace Foundation::RHI
#define CHECK_MSG(expr, format_str,...)
Allocator interface (noexcept)
Definition Allocator.hpp:29
Mutex-protected, dynamically sized object pool with stable object pointers.
Definition AtomicPool.hpp:160
T * Construct(Args &&... args)
Constructs an object of type T in the pool with the given arguments.
Definition AtomicPool.hpp:180
void Destruct(T *ptr)
Destructs the object pointed to by ptr and releases its storage.
Definition AtomicPool.hpp:189
void Collect()
Destructs all allocated objects in the pool.
Definition AtomicPool.hpp:211
Definition Device.hpp:246
Handle type for RHI Objects.
Definition Details.hpp:43
bool IsValid() const
Check if the handle is valid (i.e. associated with a Factory and not kInvalidHandle)
Definition Details.hpp:73
constexpr Handle operator()() const
Definition Details.hpp:63
bool operator==(const RHIHandle &other) const
Definition Details.hpp:66
U * Get() const
Retrieves the underlying RHIObject pointer. It is undefined behavior to use the returned pointer afte...
Definition Details.hpp:54
T * operator->() const
Definition Details.hpp:61
void Invalidate()
Resets the handle to an invalid state. After calling this, the handle is no longer associated with an...
Definition Details.hpp:78
Handle mHandle
Definition Details.hpp:47
Factory * mFactory
Definition Details.hpp:46
constexpr T * operator*() noexcept
Definition Details.hpp:65
Thread-safe type-erased handle dereference facility for RHI Objects.
Definition Details.hpp:147
RHIObjectPool(Core::Allocator *allocator)
Definition Details.hpp:154
static U * GetObjectPtr(Handle handle) noexcept
Retrieves the raw pointer to the object within the storage.
Definition Details.hpp:173
Core::DynamicPool< PointerType > mPool
Definition Details.hpp:151
Core::UniquePtr< Base > PointerType
Definition Details.hpp:148
Core::Allocator * mAllocator
Definition Details.hpp:150
void Destroy()
Destroys all objects in the pool.
Definition Details.hpp:190
Handle CreateObject(Args &&... args)
Creates specified RHIObject of derived type T and retrieves its handle.
Definition Details.hpp:160
void DestroyObject(Handle handle)
Destroys the object associated with the given handle, and frees the handle for reuse.
Definition Details.hpp:182
Base class for all RHI objects.
Definition Details.hpp:17
RHIObject & operator=(const RHIObject &)=delete
RHIObject(RHIObject const &)=delete
virtual ~RHIObject()=default
RHIObject & operator=(RHIObject &&)=delete
RHIObject(RHIObject &&)=delete
Scoped move-only RAII handle wrapper for RHI Objects.
Definition Details.hpp:85
RHIScopedHandle & operator=(RHIScopedHandle &&other) noexcept
Definition Details.hpp:99
RHIScopedHandle(const RHIScopedHandle &)=delete
RHIScopedHandle(RHIScopedHandle &&other) noexcept
Definition Details.hpp:95
void Reset()
Destructs the underlying RHIObject, and invalidates the scoped handle.
Definition Details.hpp:126
RHIScopedHandle(Factory *factory, Handle handle)
Definition Details.hpp:94
~RHIScopedHandle()
Definition Details.hpp:136
RHIScopedHandle & operator=(const RHIScopedHandle &)=delete
RHIHandle< Factory, T > Release()
Releases the underlying RHIHandle, invalidating the scoped handle. NOTE: This may leak the resource i...
Definition Details.hpp:117
RHIHandle< Factory, T > View() const
Returns a non-owning view of the underlying RHIHandle.
Definition Details.hpp:112
void * pointer
Definition Allocator.hpp:8
std::unique_ptr< T, Deleter > UniquePtr
std::unique_ptr with custom deleter that uses a Foundation::Core::Allocator to deallocate memory.
Definition Allocator.hpp:180
Low-level Rendering Hardware Interface (RHI) abstractions.
Definition Application.hpp:3
uintptr_t Handle
Definition Details.hpp:9
static constexpr Handle kInvalidHandle
Definition Details.hpp:10
Custom deleter for Foundation::Core::UniquePtr and Foundation::Core::SharedPtr that uses a Foundation...
Definition Allocator.hpp:131
Provides type traits for types derived from RHIObject.
Definition Details.hpp:31