renderer_vulkan/wrapper: Add owning handle templated class
This commit is contained in:
parent
60f351084a
commit
d8d392b39a
|
@ -278,4 +278,148 @@ void Destroy(VkInstance, VkSurfaceKHR, const InstanceDispatch&) noexcept;
|
||||||
VkResult Free(VkDevice, VkDescriptorPool, Span<VkDescriptorSet>, const DeviceDispatch&) noexcept;
|
VkResult Free(VkDevice, VkDescriptorPool, Span<VkDescriptorSet>, const DeviceDispatch&) noexcept;
|
||||||
VkResult Free(VkDevice, VkCommandPool, Span<VkCommandBuffer>, const DeviceDispatch&) noexcept;
|
VkResult Free(VkDevice, VkCommandPool, Span<VkCommandBuffer>, const DeviceDispatch&) noexcept;
|
||||||
|
|
||||||
|
template <typename Type, typename OwnerType, typename Dispatch>
|
||||||
|
class Handle;
|
||||||
|
|
||||||
|
/// Handle with an owning type.
|
||||||
|
/// Analogue to std::unique_ptr.
|
||||||
|
template <typename Type, typename OwnerType, typename Dispatch>
|
||||||
|
class Handle {
|
||||||
|
public:
|
||||||
|
/// Construct a handle and hold it's ownership.
|
||||||
|
explicit Handle(Type handle_, OwnerType owner_, const Dispatch& dld_) noexcept
|
||||||
|
: handle{handle_}, owner{owner_}, dld{&dld_} {}
|
||||||
|
|
||||||
|
/// Construct an empty handle.
|
||||||
|
Handle() = default;
|
||||||
|
|
||||||
|
/// Copying Vulkan objects is not supported and will never be.
|
||||||
|
Handle(const Handle&) = delete;
|
||||||
|
Handle& operator=(const Handle&) = delete;
|
||||||
|
|
||||||
|
/// Construct a handle transfering the ownership from another handle.
|
||||||
|
Handle(Handle&& rhs) noexcept
|
||||||
|
: handle{std::exchange(rhs.handle, nullptr)}, owner{rhs.owner}, dld{rhs.dld} {}
|
||||||
|
|
||||||
|
/// Assign the current handle transfering the ownership from another handle.
|
||||||
|
/// Destroys any previously held object.
|
||||||
|
Handle& operator=(Handle&& rhs) noexcept {
|
||||||
|
Release();
|
||||||
|
handle = std::exchange(rhs.handle, nullptr);
|
||||||
|
owner = rhs.owner;
|
||||||
|
dld = rhs.dld;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Destroys the current handle if it existed.
|
||||||
|
~Handle() noexcept {
|
||||||
|
Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Destroys any held object.
|
||||||
|
void reset() noexcept {
|
||||||
|
Release();
|
||||||
|
handle = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the address of the held object.
|
||||||
|
/// Intended for Vulkan structures that expect a pointer to an array.
|
||||||
|
const Type* address() const noexcept {
|
||||||
|
return &handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the held Vulkan handle.
|
||||||
|
Type operator*() const noexcept {
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true when there's a held object.
|
||||||
|
operator bool() const noexcept {
|
||||||
|
return handle != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Type handle = nullptr;
|
||||||
|
OwnerType owner = nullptr;
|
||||||
|
const Dispatch* dld = nullptr;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// Destroys the held object if it exists.
|
||||||
|
void Release() noexcept {
|
||||||
|
if (handle) {
|
||||||
|
Destroy(owner, handle, *dld);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Dummy type used to specify a handle has no owner.
|
||||||
|
struct NoOwner {};
|
||||||
|
|
||||||
|
/// Handle without an owning type.
|
||||||
|
/// Analogue to std::unique_ptr
|
||||||
|
template <typename Type, typename Dispatch>
|
||||||
|
class Handle<Type, NoOwner, Dispatch> {
|
||||||
|
public:
|
||||||
|
/// Construct a handle and hold it's ownership.
|
||||||
|
explicit Handle(Type handle_, const Dispatch& dld_) noexcept : handle{handle_}, dld{&dld_} {}
|
||||||
|
|
||||||
|
/// Construct an empty handle.
|
||||||
|
Handle() noexcept = default;
|
||||||
|
|
||||||
|
/// Copying Vulkan objects is not supported and will never be.
|
||||||
|
Handle(const Handle&) = delete;
|
||||||
|
Handle& operator=(const Handle&) = delete;
|
||||||
|
|
||||||
|
/// Construct a handle transfering ownership from another handle.
|
||||||
|
Handle(Handle&& rhs) noexcept : handle{std::exchange(rhs.handle, nullptr)}, dld{rhs.dld} {}
|
||||||
|
|
||||||
|
/// Assign the current handle transfering the ownership from another handle.
|
||||||
|
/// Destroys any previously held object.
|
||||||
|
Handle& operator=(Handle&& rhs) noexcept {
|
||||||
|
Release();
|
||||||
|
handle = std::exchange(rhs.handle, nullptr);
|
||||||
|
dld = rhs.dld;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Destroys the current handle if it existed.
|
||||||
|
~Handle() noexcept {
|
||||||
|
Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Destroys any held object.
|
||||||
|
void reset() noexcept {
|
||||||
|
Release();
|
||||||
|
handle = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the address of the held object.
|
||||||
|
/// Intended for Vulkan structures that expect a pointer to an array.
|
||||||
|
const Type* address() const noexcept {
|
||||||
|
return &handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the held Vulkan handle.
|
||||||
|
Type operator*() const noexcept {
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true when there's a held object.
|
||||||
|
operator bool() const noexcept {
|
||||||
|
return handle != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Type handle = nullptr;
|
||||||
|
const Dispatch* dld = nullptr;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// Destroys the held object if it exists.
|
||||||
|
void Release() noexcept {
|
||||||
|
if (handle) {
|
||||||
|
Destroy(handle, *dld);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace Vulkan::vk
|
} // namespace Vulkan::vk
|
||||||
|
|
Loading…
Reference in a new issue