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

Author Topic: sf::Sprite / sf::Image pointer...  (Read 5929 times)

0 Members and 1 Guest are viewing this topic.

coolhome

  • Jr. Member
  • **
  • Posts: 59
    • View Profile
sf::Sprite / sf::Image pointer...
« on: April 16, 2010, 04:39:35 am »
Hello.  Okay so let me just explain my class setup real quick.

Screen with a virtual Destruct, Construct, Draw, Update functions. (Please not the function Destruct and Construct are not Screen() and ~Screen() and are implemented.)
Screen also has SetBase(Engine *base); to get the base functions.

ScreenManager which has a map of screen pointers. Screens are added for e.g.
sm->AddScreen("menu", new MenuScreen()); //ScreenManager also deletes them...

ImageManager which creates and deletes sf::Image.

So the engine dynamically loads image manager then screen manager.

So for example if my class Engine destruct deletes ImageManager then ScreenManager it all works fine. But if i do it the other way because it seems more logical I get a memory heap. I think ive pin pointed it down to sf::Sprite in MenuScreen. It uses a pointer from the image manager but nothing else is called (or is it...). So to remove this heap i have to

background = sf::Sprite();

Any suggestions? Im guessing it has to do with image pointers...

p.s. Sorry if you don't understand this i can post code if needed to help. Me translating code in English isn't that well lol.
CoderZilla - Everything Programming

Svenstaro

  • Full Member
  • ***
  • Posts: 222
    • View Profile
sf::Sprite / sf::Image pointer...
« Reply #1 on: April 16, 2010, 05:21:38 am »
It works the way because after you delete the ImageManager your image pointers are obviously invalidated and when drawing a Sprite you are drawing an invalid image.

coolhome

  • Jr. Member
  • **
  • Posts: 59
    • View Profile
sf::Sprite / sf::Image pointer...
« Reply #2 on: April 16, 2010, 05:52:34 am »
Quote from: "Svenstaro"
It works the way because after you delete the ImageManager your image pointers are obviously invalidated and when drawing a Sprite you are drawing an invalid image.


I understand that but there is no drawing this is at the end of the game execution. I have to delete the image manager before the screen manager even tho the screen manager isn't accessing any members of image manager in that destructor. If I want to delete the screen manager then the image manager i had to set every sprite to a new sf::Sprite. I dont understand why shouldn't it just delete >.<

Code: [Select]
delete this->sm;
delete this->im;

Wont work...

but
Code: [Select]
delete this->im;
delete this->sm;

will lol.
CoderZilla - Everything Programming

Svenstaro

  • Full Member
  • ***
  • Posts: 222
    • View Profile
sf::Sprite / sf::Image pointer...
« Reply #3 on: April 16, 2010, 06:04:02 am »
Can you post the callstack at the moment of the segfault then to let us see where exactly the problem occurs?

coolhome

  • Jr. Member
  • **
  • Posts: 59
    • View Profile
sf::Sprite / sf::Image pointer...
« Reply #4 on: April 16, 2010, 06:11:51 am »
Quote from: "Svenstaro"
Can you post the callstack at the moment of the segfault then to let us see where exactly the problem occurs?


Well if I release screens first then image manager the error is located here.

Code: [Select]
ImageManager::~ImageManager() {
std::cout << "[ImageManager] Releasing Images,,," << std::endl;
while( Images.begin() != Images.end() ) {
std::cout << "[ImageManager] Releasing " << Images.begin()->first << std::endl;
delete Images.begin()->second;
Images.erase( Images.begin() );
}
std::cout << "[ImageManager] Releasing Done" << std::endl;
}


At the delete Images.begin()->second;

and some more code
Code: [Select]
void MenuScreen::Construct() {
this->im->LoadImage("background", "./menuback.png");
sprBackground.SetImage(im->GetImage("background"));
}

void MenuScreen::Destruct() {
//sprBackground = sf::Sprite();
std::cout << "Good bye mean world!" << std::endl;
}

void MenuScreen::Update(float Delta) {

}

void MenuScreen::Draw() {
Window->Draw(sprBackground);
}

If I do it that way I need to uncomment the sprBackground in Destruct.
CoderZilla - Everything Programming

Svenstaro

  • Full Member
  • ***
  • Posts: 222
    • View Profile
sf::Sprite / sf::Image pointer...
« Reply #5 on: April 16, 2010, 06:17:45 am »
Is Images a private member map/set of ImageManager? Does Images.begin()->first/second point to anything valid (not 0x00000000)?

Also, since you are apparently dynamically allocating the images, why are you not using a safe_ptr like boost::shared_ptr or even better boost::ptr_map? It would spare you from even having to manually delete all the images.

coolhome

  • Jr. Member
  • **
  • Posts: 59
    • View Profile
sf::Sprite / sf::Image pointer...
« Reply #6 on: April 16, 2010, 06:19:58 am »
Quote from: "Svenstaro"
Is Images a private member map/set of ImageManager? Does Images.begin()->first/second point to anything valid (not 0x00000000)?

Also, since you are apparently dynamically allocating the images, why are you not using a safe_ptr like boost::shared_ptr or even better boost::ptr_map? It would spare you from even having to manually delete all the images.


Umm the images map is private... but everyone draws? Could this be the issue? I dont know never used those before. Really just creating a loop to delete them works just as fine... (or does it lol)

p.s. If you dynamically create sprites this issue also doesn't happen. Im starting to think it has to do with sfml and image pointers.
CoderZilla - Everything Programming

Svenstaro

  • Full Member
  • ***
  • Posts: 222
    • View Profile
sf::Sprite / sf::Image pointer...
« Reply #7 on: April 16, 2010, 06:26:06 am »
I'd recommend you rethink your architecture. Keep in mind this is all meant as constructive criticism :).

Use a singleton for all your global manager so that they are constructed first (even before a call to main()) and destructed last.
Use a Boost.Ptr_container for storing dynamically allocated data (stuff you constructed with new).
Use a stack of states that does not need to destroy another state on change (for example by going from intro to menu to game and back to menu) but rather suspend and resume those states.

Manual allocation and deallocation of memory is probably not a thing you want to worry about when doing very high-level C++ in a game or such.

coolhome

  • Jr. Member
  • **
  • Posts: 59
    • View Profile
sf::Sprite / sf::Image pointer...
« Reply #8 on: April 17, 2010, 12:41:46 am »
Quote from: "Svenstaro"
I'd recommend you rethink your architecture. Keep in mind this is all meant as constructive criticism :).

Use a singleton for all your global manager so that they are constructed first (even before a call to main()) and destructed last.
Use a Boost.Ptr_container for storing dynamically allocated data (stuff you constructed with new).
Use a stack of states that does not need to destroy another state on change (for example by going from intro to menu to game and back to menu) but rather suspend and resume those states.

Manual allocation and deallocation of memory is probably not a thing you want to worry about when doing very high-level C++ in a game or such.


Thanks for the suggestions. Im going to learn about singleton. Do you know any good tutorials or examples for this? Also I heard about factories? Are those design patterns any good?

Im going to try the boost map pointer container.

Well the stack thing the construct should only be ran once during the game and destruct at the end.
CoderZilla - Everything Programming

Svenstaro

  • Full Member
  • ***
  • Posts: 222
    • View Profile
sf::Sprite / sf::Image pointer...
« Reply #9 on: April 17, 2010, 09:24:28 am »
See this fine tutorial for game states: http://gamedevgeek.com/tutorials/managing-game-states-in-c/

See here for singletons and other awesome game programming patterns and tips: http://gameprogrammingpatterns.com/singleton.html

Also, as always, do not overengineer. Do not use a design pattern for everything you do. If a function with a few overloads does fine, use that. There are, however, a bunch of examples in game programming where you almost always apply the same patterns, like singletons for resource managers.

coolhome

  • Jr. Member
  • **
  • Posts: 59
    • View Profile
sf::Sprite / sf::Image pointer...
« Reply #10 on: April 19, 2010, 04:43:03 am »
Quote from: "Svenstaro"
See this fine tutorial for game states: http://gamedevgeek.com/tutorials/managing-game-states-in-c/

See here for singletons and other awesome game programming patterns and tips: http://gameprogrammingpatterns.com/singleton.html

Also, as always, do not overengineer. Do not use a design pattern for everything you do. If a function with a few overloads does fine, use that. There are, however, a bunch of examples in game programming where you almost always apply the same patterns, like singletons for resource managers.


Okay so im still a little confused about what design patterns to use. I did a lot more research and I kind of like the Service Locator one. However I like the concept of my structure.

I have an engine class that creates an instance of a ImageManager and ScreenManager. Then in the main thread you add the screens to the manager and use the run command. The rest is done in the Screen classes.

You opened my head to different ways of structuring and the hardest part is figuring out which one best fits my needs.

Edit: p.s. looks like im changing the subject and probably should create a new topic on game structure XD
CoderZilla - Everything Programming

 

anything