SFML community forums

Help => Graphics => Topic started by: NGM88 on January 01, 2018, 11:01:54 pm

Title: Question about Textures when passing resource holders
Post by: NGM88 on January 01, 2018, 11:01:54 pm
So I stopped using that singleton resource manager from SFML essentials and made a simple resource holder class:

std::map<std::string, sf::Texture> Textures;

sf::Texture& Resources::get_texture(std::string const& filename)
{
        // See if the texture is already loaded
        auto pairFound = Textures.find(filename);

        // If yes, return the texture
        if (pairFound != Textures.end()) { return pairFound->second; }

        // Else, load the texture and return it
        else
        {
                // Create an element in the texture map
                auto& texture = Textures[filename];
                texture.loadFromFile(filename);
                return texture;
        }
}
 

It has the same design as the one from SFML essentials, but it's meant to work with raii.

In this example I pass a resource holder to a class through the constructor:

class A
{
        Resources Resource;

        B objB{ Resource };

        A::A() { Resource.get_texture("x.png"); }
}

class B : public sf::Drawable, public sf::Transformable
{
        B::B(Resources& Resource) { tex = Resource.get_texture("x.png"); }
       
        sf::Texture tex;     //  <- MY QUESTION IS ABOUT THIS
        sf::VertexArray va;    
}
 

My question is: Should class B have an sf::Texture or an sf::Texture* ?

I took a look at sf::Texture Class Reference to see what the = overload does, but I couldn't understand if it performs some sort of copy or what.

I remember reading somewhere here not to pass SFML resources around using pointers. Something to do with const references? This is a bit over my head c++ wise.
Title: Re: Question about Textures when passing resource holders
Post by: Laurent on January 02, 2018, 06:36:09 am
If you acquire the texture in the constructor, then use a reference; if it is acquired elsewhere or needs to be changed, use a pointer. Otherwise you'll duplicate the texture and ruin the benefit of using a manager.

By the way, you should avoid (or be extremelly careful with) members (objB) constructed from other members (Resource) of the same class; if you ever switch their declaration order in the header, then your code will become undefined behaviour.
Title: Re: Question about Textures when passing resource holders
Post by: NGM88 on January 02, 2018, 02:13:07 pm
If you acquire the texture in the constructor, then use a reference; if it is acquired elsewhere or needs to be changed, use a pointer. Otherwise you'll duplicate the texture and ruin the benefit of using a manager.

By the way, you should avoid (or be extremelly careful with) members (objB) constructed from other members (Resource) of the same class; if you ever switch their declaration order in the header, then your code will become undefined behaviour.

Just to be EXTREMELY clear: in class B, it should be
sf::Texture& tex
if I won't change it,

and
sf::Texture* tex
if I will?

sorry for being a noob who needs idiot-proof answers and thanks as always for your help.
Title: Re: Question about Textures when passing resource holders
Post by: eXpl0it3r on January 02, 2018, 02:26:07 pm
You can also change a reference, you just have to always reference a valid instance, from the construction of the object with the texture reference (i.e. needs to be set in the initialization list) to the destruction of said object. Where as with a pointer you can also have it set to a nullptr if there's no texture available at some point.
Title: Re: Question about Textures when passing resource holders
Post by: Laurent on January 02, 2018, 02:42:06 pm
Quote
You can also change a reference
To be clear, you can modify the referenced object, but you can't rebind the reference to a different object. That's what I meant in my previous message.
Title: Re: Question about Textures when passing resource holders
Post by: eXpl0it3r on January 02, 2018, 03:30:19 pm
To be clear, you can modify the referenced object, but you can't rebind the reference to a different object. That's what I meant in my previous message.
Not sure what you mean. Of course you can rebind (https://ideone.com/kwP02z) a reference to a different object. Or what did you mean?
Title: Re: Question about Textures when passing resource holders
Post by: Laurent on January 02, 2018, 05:12:31 pm
No you can't. What you do in your example is assigning the value of B to A through the foo reference. You're not making of foo a reference to B.
Title: Re: Question about Textures when passing resource holders
Post by: eXpl0it3r on January 02, 2018, 06:34:05 pm
You're right, I got confused. :)