Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 18dfdf2

Browse files
committed
Update VDeleter code and explanation in base code chapter
1 parent 550b68f commit 18dfdf2

1 file changed

Lines changed: 43 additions & 11 deletions

File tree

03_Drawing_a_triangle/00_Setup/00_Base_code.md

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,26 @@ The template argument specifies the type of Vulkan object we want to wrap and
8787
the constructor argument specifies the function to use to clean up the object
8888
when it goes out of scope.
8989
90-
To assign an object to the wrapper, simply pass its pointer to the creation
91-
function as if it was a normal `VkInstance` variable:
90+
To assign an object to the wrapper, we would simply want to pass its pointer to
91+
the creation function as if it was a normal `VkInstance` variable:
9292
9393
```c++
9494
vkCreateInstance(&instanceCreateInfo, nullptr, &instance);
9595
```
9696

97+
Unfortunately, taking the address of the handle in the wrapper doesn't
98+
necessarily mean that we want to overwrite its existing value. A common pattern
99+
is to simply use `&instance` as short-hand for an array of instances with 1
100+
item. If we intend to write a new handle, then the wrapper should clean up any
101+
previous object to not leak memory. Therefore it would be better to have the `&`
102+
operator return a constant pointer and have an explicit function to state that
103+
we wish to replace the handle. The `replace` function calls clean up for any
104+
existing handle and then gives you a non-const pointer to overwrite the handle:
105+
106+
```c++
107+
vkCreateInstance(&instanceCreateInfo, nullptr, instance.replace());
108+
```
109+
97110
Just like that we can now use the `instance` variable wherever a `VkInstance`
98111
would normally be accepted. We no longer have to worry about cleaning up
99112
anymore, because that will automatically happen once the `instance` variable
@@ -125,7 +138,11 @@ public:
125138
cleanup();
126139
}
127140
128-
T* operator &() {
141+
const T* operator &() const {
142+
return &object;
143+
}
144+
145+
T* replace() {
129146
cleanup();
130147
return &object;
131148
}
@@ -134,6 +151,16 @@ public:
134151
return object;
135152
}
136153
154+
void operator=(T rhs) {
155+
cleanup();
156+
object = rhs;
157+
}
158+
159+
template<typename V>
160+
bool operator==(V rhs) {
161+
return object == T(rhs);
162+
}
163+
137164
private:
138165
T object{VK_NULL_HANDLE};
139166
std::function<void(T)> deleter;
@@ -165,14 +192,19 @@ can see in the `VDeleter` definition.
165192
All of the constructors initialize the object handle with the equivalent of
166193
`nullptr` in Vulkan: `VK_NULL_HANDLE`. Any extra arguments that are needed for
167194
the deleter functions must also be passed, usually the parent object. It
168-
overloads the address-of and casting operators to make the wrapper as
169-
transparent as possible. When the wrapped object goes out of scope, the
170-
destructor is invoked, which in turn calls the cleanup function we specified.
171-
Note that the address-of operator should only be used to create a new Vulkan
172-
object as shown above. It invokes the cleanup function as well because we may
173-
want to use it to recreate an existing object. There is also a default
174-
constructor with a dummy deleter function that can be used to initialize it
175-
later, which will be useful for lists of deleters.
195+
overloads the address-of, assignment, comparison and casting operators to make
196+
the wrapper as transparent as possible. When the wrapped object goes out of
197+
scope, the destructor is invoked, which in turn calls the cleanup function we
198+
specified.
199+
200+
The address-of operator returns a constant pointer to make sure that the object
201+
within the wrapper is not unexpectedly changed. If you want to replace the
202+
handle within the wrapper through a pointer, then you should use the `replace()`
203+
function instead. It will invoke the cleanup function for the existing handle so
204+
that you can safely overwrite it afterwards.
205+
206+
There is also a default constructor with a dummy deleter function that can be
207+
used to initialize it later, which will be useful for lists of deleters.
176208

177209
I've added the class code between the headers and the `HelloTriangleApplication`
178210
class definition. You can also choose to put it in a separate header file. We'll

0 commit comments

Comments
 (0)