Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: [SFML 2.0 RC] Correct way of using sf::Texture pointer? Does it deallocate?  (Read 16651 times)

0 Members and 1 Guest are viewing this topic.

Moonkis

  • Jr. Member
  • **
  • Posts: 58
    • View Profile
Hi! As most of you have seen I'v been posting quite a few topics lately.
This time it's about deallocation with sf::Texture pointers. The problem arise when I'd try loading and setting all the "sprites" textures inside my games "initialize()" function.

It basically looked like:
Code: [Select]
void Game::initialize()
{
  sf::Texture texture;
  texture.loadFromFile("image.png");
  this->drawableObject.setTexture(texture);
}

void Game::run()
{
  initialize();
 
  while(window.isOpen())
  {
    // Generic game-loop code here
    window.clear(sf::Color::Black);
    window.draw(drawableObject);
    window.display();
  }
}
At first I thought I had problems loading the image but soon realized it was "RAll" ( spelling? ) kicking in. As soon as the "initialize()" scope ended the image was de-allocated and thus their existed no texture for my "drawableObject" ( drawableObject is an sf::Sprite ).

Since it's convenient to have the loading separated from the scope of it's use. I realized that either a local sf::Texture for ALL my objects OR pointers to sf::Texture(s) de-allocate until I say so. Unfortunately the sf::Sprite doesn't take a sf::Texture pointer, which can be solved with this:
Code: [Select]
drawableObject.setTexture((*texture));
This way I can load all my resources and go out of scope whilst still keeping the data intact. My question is will I need to call the delete operation or does the sf::Sprite "RAll" take care of the de-allocation?

Also if I do this:
Code: [Select]
void RandomFunction()
{
sf:: Image image;
image.loadFromFile("myimage.png");
image.createMaskFrom(sf::Color::Magenta);

sf::Texture texture;
texture.loadFromImage(image);

drawableObject.setTexture(image);
}
Will the code above also de-allocate both image and texture allocated memory? Are image and texture pointing to the same image in memory OR do they create a copy ( So that their is basically 2 of the same file in memory that they are each pointing to. ) of them?

Kind regards Moonkis

EDIT:
Apparently the sf::Sprite class does not de-allocate the sf::Texture, can someone confirm this?
« Last Edit: April 24, 2012, 08:26:13 pm by Moonkis »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11032
    • View Profile
    • development blog
    • Email
I really suggest you to read a book about C++!
Also you can highlight your code by adding '=cpp' within the opening code tag.
And third it's more common to use delete instead of deallocate.

Now for your problem:
sf::Sprite does take the reference to the texture, thus you can't hand over the pointer directly and you need to dereference it, as you did.
Since a reference is in some way also just a pointer to the original object, the object won't be copied and the sprite doesn't care about it's lifetime etc.
Thus a resource manager could load all the textures and resources, then you can hand the textures to the sprites and at the end the resource manager takes care of the destruction.
If you don't want to implement your own resource manager you could also use the one from Thor, but maybe that's again a bit overkill.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Jove

  • Full Member
  • ***
  • Posts: 114
    • View Profile
    • http://www.jestofevekites.com/
There's also a pretty simple manager in the wiki here :

https://github.com/SFML/SFML/wiki/TutorialImageManager

You'd need to convert it to SFML2, but that's no big deal as the class is short and to the point.
{much better code}

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11032
    • View Profile
    • development blog
    • Email
There's also a pretty simple manager in the wiki here :

https://github.com/SFML/SFML/wiki/TutorialImageManager

You'd need to convert it to SFML2, but that's no big deal as the class is short and to the point.

Yes it's quite simple but you'll have keep in mind, that every resources gets loaded into memory whether you use it or not. Although you can manage this by organizing the resources in folders according to their usage. For a bigger project this could get quite complicated, since you often want to share resources between states.
Additionally if you remove a directory or delete an image/texture and there's still an object using it, SFML will just draw a white rectangle. Instead the resource manager should keep the resource alive as long as it is in use.

But I guess it's fairly simple to understand specially for beginners.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
It's sad to see that resource managers are overused. Now they seem to be the universal answer to any problem that deal with scope / lifetime / management problem. Basically they are just a way to forget about proper management and get things working in a black box.

They are becoming like singletons: make everything global and everybody's happy...

A better answer would be "you have to clearly define and properly manage the lifetime of your resources; if it happens that some resources need to have shared ownership among unrelated objects, you can use a centralized manager".
Laurent Gomila - SFML developer

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11032
    • View Profile
    • development blog
    • Email
It's sad to see that resource managers are overused. Now they seem to be the universal answer to any problem that deal with scope / lifetime / management problem. Basically they are just a way to forget about proper management and get things working in a black box.

They are becoming like singletons: make everything global and everybody's happy...

A better answer would be "you have to clearly define and properly manage the lifetime of your resources; if it happens that some resources need to have shared ownership among unrelated objects, you can use a centralized manager".

I agree a resource manager is not the direct answer to his problems.
Although if you look at any software that's more than just an example or badly programmed you'll find some sort of resource management.
If you make the resource manager global (which you shouldn't) or not is up the programmer.

Also where's the difference in creating a class that handles all the work with resources vs. a game class filled up with functions and vectors/maps that handle and hold all the resources?
At some point you just need to load resources, store resources and delete resources if you now crunch that into a class that has a completly diffrent functionality it's just bad design.

Since the knowledge about handling the scope/lifetime of objects/variables are one of the basics of C++ and I don't feel like explaining basic stuff that can be read in a book in better ways, I just advice people to read more about C++ and then explain a concept he could use.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
The key concept of a resource manager (or, at least those that are usually shown here) is that is deals with shared resources without duplicating them. However, in most examples that can be found on this forum, shared ownership is not part of the problem, and is often not required at all.

If a resource is specific to a particular class there's no reason to make it managed by some outside, global object (managers are often singletons -- again, because of laziness).

Someone said (don't know who):
Quote
If a class has the word "manager" in its name, then it probably shouldn't exist
Not that I totally agree with that, but it's good to keep in mind.
« Last Edit: April 25, 2012, 11:04:36 am by Laurent »
Laurent Gomila - SFML developer

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11032
    • View Profile
    • development blog
    • Email
Ah okay now I see what you mean and you're right, most people just want to load X textures, use them and get rid of them at the end. They mostly have just one class and one state that work with those resoruces and thus a resource manager seems like an overkill.
For such a limited application it maybe okay to handle the resources on 'your own' but it actually doesn't hurt using a class that does it for you. Next to the effect that it's way easier to get your application to a more complex state with a resoure manager it can also be a good way to learn how resources are managed in a lager enviroment.

As I already said if one uses a singletone or make it globally in another way, the applicaction design is just wrong and/or that programmer is lazy.

You can also rename it as suggested for Thor to 'provider' or similar, if one does not like the word 'manager'.
Although I don't fully understand the meaning of it and I can't think of any other 'managers'?

(So 'managed' code shouldn't exist either? :P)
« Last Edit: April 25, 2012, 11:29:44 am by eXpl0it3r »
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Lo-X

  • Hero Member
  • *****
  • Posts: 618
    • View Profile
    • My personal website, with CV, portfolio and projects
I well understand why "managers" aren't a good solution but reading you I can't find what is the good solution.

If all my drawables components were carrying their own texture, there will be twice the same texture in memory or more.

ATM I use a texture manager that isn't a singleton, I pass it to whatever needs it in a GameState and when his state ends, I clear all textures that I don't need anymore. I'm stuck wih that idea and can't fins another one

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Quote
If all my drawables components were carrying their own texture, there will be twice the same texture in memory or more.
If your design requires multiple unrelated classes to potentially share the same resource, then you're exactly in the scope of the resource manager so I have nothing to say against this ;)
Laurent Gomila - SFML developer

Moonkis

  • Jr. Member
  • **
  • Posts: 58
    • View Profile
Quote
If all my drawables components were carrying their own texture, there will be twice the same texture in memory or more.
If your design requires multiple unrelated classes to potentially share the same resource, then you're exactly in the scope of the resource manager so I have nothing to say against this ;)
My Engish is not the greatest but what exactly are classed as unrelated classes? If I have a lot of different characters in my game say for example "Enemies" and usually a lot of instances shares the same resources are they defined as unrelated or related classes?


I like resource managers ( static/singleton/namespace ) because It gathers ALL of my loading code into one metod which makes it easy to add/delete and re-use the code into another project. Now I'v heard from multiple ways that they are bad( Usually just like this one vauge example of why it's bad. "It just is." ).

Most of the tutorials you come across teaches us using the "managers" since it simplifies a lot. How are we supposed to load/unload and manage our resources in an easy way otherwise?

A lot of the more experienced programmers ( Including most of you that replied in this topic ) tells us that it's bad but you don't provide a good explanation or "tutorial" on how to actually implement or how the "better"/"correct" way actually looks like.

Their are like zero tutorials that show us "beginners" of how to manage game resources, object creation without managers in a good and accepted way.

I'm not trying to be rude, just find it frustrating :)
« Last Edit: April 25, 2012, 08:17:02 pm by Moonkis »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Yeah, I know it can be very frustrating :)

But there's no universal answer. Each project, probably even each module or class will need its own specific solution to correctly load and manage resources.

The best answer is then probably: experiment, try by yourself, and when you realize that managers are not the best answer to all problems then you'll find the better solution that fits your specific design. For now, if you like the simplicity of global managers, just use them.

My point was more to avoid throwing "manager" in every post where there's a scope/lifetime problem. Since it doesn't solve the problem but rather avoids it with something that is not always relevant. Learning how to properly handle objects lifetime is crucial for well-designed and robust programs.
Laurent Gomila - SFML developer

Moonkis

  • Jr. Member
  • **
  • Posts: 58
    • View Profile
Yeah, I know it can be very frustrating :)

But there's no universal answer. Each project, probably even each module or class will need its own specific solution to correctly load and manage resources.

The best answer is then probably: experiment, try by yourself, and when you realize that managers are not the best answer to all problems then you'll find the better solution that fits your specific design. For now, if you like the simplicity of global managers, just use them.

My point was more to avoid throwing "manager" in every post where there's a scope/lifetime problem. Since it doesn't solve the problem but rather avoids it with something that is not always relevant. Learning how to properly handle objects lifetime is crucial for well-designed and robust programs.
Although I have a hard time seeing it now how I would realize it is not suited for all applications I guess it will come to me in time.

I'm already quite found of "Interfaces" which allows me to pass ( pointer/reference to ) a local instantiated Resource Manager which also limits the access to it ( And THAT I like! Because I'm not found of passing entire objects when the object that is going to use it only needs one function and the rest is quite "no-no" for the object to use. ).

That way if Resource Manager implements IRequestTexture ( Which haves the pure virtual "getTexture(name)" ) then I can with calm in my body pass it to my Game objects that needs to get their textures at creation because they will ( and can only ) access the getTexture() function.

I'm guessing I'm on the right track? :)
« Last Edit: April 25, 2012, 10:17:52 pm by Moonkis »