owned_handle.hpp
1 2 3 4 5 6 7 8 9 10 11 | #pragma once #include <planet/vk/helpers.hpp> #include <utility> #include <vulkan/vulkan.h> namespace planet::vk { |
A Vulkan handle that is owned by some other handle
Examples of these include the surface, which is owned by an Instance and semaphore, which is owned by a device.
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | template<typename O, typename T, void (*D)(O, T, VkAllocationCallbacks const *)> class owned_handle final { O owner_handle = VK_NULL_HANDLE; T handle = VK_NULL_HANDLE; VkAllocationCallbacks const *allocator = nullptr; owned_handle(O o, T h, VkAllocationCallbacks const *a) noexcept : owner_handle{o}, handle{h}, allocator{a} {} public: owned_handle() noexcept {} owned_handle(owned_handle const &) = delete; owned_handle(owned_handle &&h) noexcept : owner_handle{std::exchange(h.owner_handle, VK_NULL_HANDLE)}, handle{std::exchange(h.handle, VK_NULL_HANDLE)}, allocator{std::exchange(h.allocator, nullptr)} {} ~owned_handle() noexcept { reset(); } owned_handle &operator=(owned_handle const &) = delete; owned_handle &operator=(owned_handle &&h) noexcept { reset(); owner_handle = std::exchange(h.owner_handle, VK_NULL_HANDLE); handle = std::exchange(h.handle, VK_NULL_HANDLE); allocator = std::exchange(h.allocator, nullptr); return *this; } T get() const noexcept { return handle; } T const *address() const noexcept { return &handle; } O owner() const noexcept { return owner_handle; } |
Remove the current content (if any)
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | void reset() noexcept { if (owner_handle and handle) { D(std::exchange(owner_handle, VK_NULL_HANDLE), std::exchange(handle, VK_NULL_HANDLE), std::exchange(allocator, nullptr)); } } template<auto C, typename I> void create(O h, I const &info, VkAllocationCallbacks const *alloc, felspar::source_location const &loc = felspar::source_location::current()) { reset(); owner_handle = h; allocator = alloc; worked(C(h, &info, alloc, &handle), loc); } template<auto C, typename I> void create(O h, I const &info, felspar::source_location const &loc = felspar::source_location::current()) { create<C, I>(h, info, nullptr, loc); } static owned_handle bind(O o, T h) noexcept { return {o, h, nullptr}; } }; |
Shorter names for common owners of handles
89 90 91 92 93 | template<typename T, void (*D)(VkDevice, T, VkAllocationCallbacks const *)> using device_handle = owned_handle<VkDevice, T, D>; } |