I’ve been creating a simple wrapper for OpenGL to help me with some common things. While I’m not a huge fan of archetypal object orientation, I chose to write this wrapper in that way for ease of prototyping. However wrapping OpenGL (or any C style resource) is not as easy as you might think.
Simple Resource Wrap
Its easy right? I just initialize the resource in the constructor and release it in the destructor. RAII is all you need right?
We’re done! - No we aren’t. What if I copy this texture? Then the first copy to go out of scope will take the resource with it. Well that can be solved by making the copy and assignment private, and defining a move and move assignment. This works to a degree, however you’d be surprised how many implicit copy’s you make, so it invalidates my need for a simple wrapper for quick prototyping. However I’d consider this the most correct in an academic sense, but not an engineering one.
I Know, Shared_ptrs!
Apparently shared_ptrs solve everything.
This is horrid, but it does fit the ‘easier’ for prototyping angle, there is a tweak we can do to make this less horrid though.
This makes things somewhat cleaner. I’m not passing shared_ptr’s around everywhere, and at the same time the resource isn’t destroyed until all copies have vanished, but it still suffers from the whole shared_ptr thing. It is in essence a global, its state can be changed by who knows what, who knows where.
This isn’t ideal. One possible solution would be to make the internal shared_ptr const (I am a fan of immutable objects), and then the RAII thing comes back to life a little. However the issue with RAII is that it assumes all resources are equal. Its quite often the case with textures that you would want to update them, so this doesn’t solve the issue where copies can change the state.
Its very easy to get caught up with what is the ‘correct’ way to do something. And while that is certainly something worthy to stive to, I tend to think that I am an engineer first and foremost. This wrapper was supposed to be a simple tool to allow me to use textures and shaders quickly. So to that end the internal shared_ptr wins. It may hurt my eyes slightly, it may not be nice (I find OOP rarely is anyway), but it works with minimum fuss.