3
\$\begingroup\$

First time in game dev, so go easy on me. I understand it's senseless to copy textures, but I'm trying to see this from a copy/move perspective since there is a lot of that going on in my code and in general, for proper memory management.

Deep copying an SDL_Texture is a no-no since its implementation is hidden. Besides I mostly initialize and destroy it using SDL_CreateTextureFromSurface and SDL_DestroyTexture. My next approach was wherever there would be an SDL_Texture* class member I would try to wrap it in a std::shared_ptr<SDL_Texture>, but even that didn't work because of the incomplete type error.

My main question is this:
Would the proper way of handling a raw SDL_Texture* pointer getting passed around everywhere, be to create a wrapper_class, for example

class WTexture {
    public:
    // constructor, destructor and everything else needed

    private:
    SDL_Texture* tex;
    //...

}

so, that in every class that has an SDL_Texture* tex; member I would swap it with std::make_shared<WTexture> tex;? Meaning that I can safely pass around the texture and it will only be deleted at the end of the program when the reference count reaches zero?

\$\endgroup\$
  • \$\begingroup\$ You should be able to create a shared_ptr with a custom deleter. \$\endgroup\$ – user253751 Dec 9 '19 at 13:58
  • \$\begingroup\$ I'd make the wrapper class move-only. \$\endgroup\$ – HolyBlackCat Dec 9 '19 at 18:52
3
\$\begingroup\$

Shared pointers make sense when you have unclear ownership and unclear lifespan; otherwise they're just a dead weight you're dragging around. For most games you want to have a defined build-up and tear-down points where you load all your data and dump all your data. For example, at level load and level complete.

In this case you can just use a nice, clean, raw pointer throughout your code and have another object responsible for loading and deleting the textures (or whatever) at either end of the level. Providing you clean up everything referencing the pointer before calling the cleanup this is perfectly fine.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ So, let's say I build my Tile objects from a Tileset object that has a pointer to a texture. As long as Tileset's destructor cleans up the pointer, I don't have to worry about Tile objects releasing memory (basically they share a texture). Did I understand this correctly ? \$\endgroup\$ – monolith937 Dec 9 '19 at 13:46
  • \$\begingroup\$ Sort of. It's all about managing lifetimes. If you have a pointer to a texture owned by the Tileset in the Tile object, then all the Tile objects needs to be destructed before the Tileset (or, at least, effectively simultaneously with them). Usually this is relatively easy to manage in games because you have predictable points where its appropriate to create and destroy all the objects, such as a level change. \$\endgroup\$ – Jack Aidley Dec 9 '19 at 14:13
  • \$\begingroup\$ Wouldn't it make sense to use unique_ptrs instead? Since everything is owned by the level, it would be cleaner than using raw pointers. \$\endgroup\$ – Noctiphobia Dec 9 '19 at 22:06
  • \$\begingroup\$ @Noctiphobia: You could use a unique_ptr to manage the destruction of the objects in the class responsible for managing the lifetime of the object, yes, but you would not want to pass them down from this level as unique_ptr as only one object at a time should hold those. For this purpose, raw pointers are entirely appropriate. \$\endgroup\$ – Jack Aidley Dec 10 '19 at 13:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.