Jump to content
  • Advertisement
Sign in to follow this  
GrimV5

cleaning up a state

This topic is 2078 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

that's pretty cool. I actually have a question about states.  I've read that states should have a clean up method of some sort that should be called when the game is closed or the currently running state is changed to a new state.  My question what exactly is supposed to happen in this clean up method? Its not like i can delete the variables or objects in a state , otherwise when i try to run the code I'll get a debug assertion error.

Share this post


Link to post
Share on other sites
Advertisement

I'm a little rusty on the whole patterns thing, but I think it depends entirely on what you're using it for. The question is a little broad.  But, why can't you clean up resource demanding objects?  They can always be reloaded/recreated on initialization.  If you have a very elaborate menu/configuration state which uses lots of graphics, animations, music and so on, it'd be wasteful to leave all that taking up resources while your game is executing.

Share this post


Link to post
Share on other sites

It seems the best I would be able to do is set them all to null. Because when I try to use delete on anything it would give me a debug assertion error when I run the program. Plus I would assume that the garbage collector would handle it after the state is popped off the vector. 

Edited by GrimV5

Share this post


Link to post
Share on other sites

What happens during the activation of a state? Is anything allocated into the memory? Are entities created with "new"? Are the textures of those entities' sprites loaded? Are sound effects or music loaded? As a general rule, whatever you allocate during the activation of a state should be deallocated during its deactivation.

Share this post


Link to post
Share on other sites

What's the context for this question? You're not really giving us much to go on.

 

 

 


Because when I try to use delete on anything it would give me a debug assertion error when I run the program.

 

Huh? Did you allocate something with new? If so, then you need to delete it when you're done using it. If you're getting a "debug assertion", you're probably deleting something you never allocated, or your heap is corrupted.

 

 

 


Plus I would assume that the garbage collector would handle it after the state is popped off the vector. 

 

C++ doesn't have a garbage collector, what are you talking about?

Edited by phil_t

Share this post


Link to post
Share on other sites


I've read that states should have a clean up method of some sort that should be called when the game is closed or the currently running state is changed to a new state.  My question what exactly is supposed to happen in this clean up method?

A state is a concept.  Exactly what it means is entirely up to you.

 

A state might be a single number or enumeration.  Your code may have something like "int state = 0; ... state = 1; ... state = 2..." or more likely it would be named: "int state = ThingState_PreInit; ... state = ThingState_Initialized; ... state = ThingState_Active".

 

A state might be an index to a data table. "StateEntry* currentState = AllPossibleStates[0]; ... currentState = currentState->Next.AfterSuccess;"

 

A state might be an object on a stack. A state might be an item in a queue. A state might be some other object or structure.

 


It seems the best I would be able to do is set them all to null. Because when I try to use delete on anything it would give me a debug assertion error when I run the program.

 

That has nothing to do with states and everything to do with memory management. In order to use the C++ language effectively you must understand memory management and object lifetimes.  If you create or allocate something it is your responsibility as the developer to ensure it is properly cleaned up. This is true on all languages; even those with automatic garbage collection require you to properly manage object lifetimes.

 

If you created objects and simply point them to null you are probably creating memory and resource leaks. Sometimes you can get away with those bugs for a short time, but they are bugs that can result in very nasty problems. 

Share this post


Link to post
Share on other sites

that's pretty cool. I actually have a question about states.  I've read that states should have a clean up method of some sort that should be called when the game is closed or the currently running state is changed to a new state.  My question what exactly is supposed to happen in this clean up method? Its not like i can delete the variables or objects in a state , otherwise when i try to run the code I'll get a debug assertion error.

 

In my states, I have Activated() and Deactivated(), and the gamestates also have constructors and destructors (destructors are mostly unused, since most dynamic memory uses smart pointers).

Activation is when gamestates get switched. Since my gamestates are hierarchical, the entire parent-child hierarchy is activated. 

 

Not every state needs to do something when activated or deactivated. If you're managing some heavy resources, you might want to allocate and free the resources there, but in general, I wouldn't do that unless you find (through actual use, not premature optimization) that you actually need the memory.

 

One non-memory related use for activation is this:

Imagine you had one or more timers associated with a state. The states get switched, the pause menu gets displayed, and the old state with the timers is no longer active. Depending on what those timers are doing, some of them you'll want to pause() and resume() when the state gets deactivated() and activated(), and others you'll want to continue to let running even when the state isn't active.

 

Any directly time-based changes to a state you can manipulate through the Update(deltaTime) function calls (which in my code doesn't get called when the state is deactivated), but if you want to do something like "Do X every five minutes", or "Y was triggered, so in 30 seconds trigger function Z one time", I'd use a timer for that.

Edited by Servant of the Lord

Share this post


Link to post
Share on other sites
This sounds so familiar I can’t help but wonder if this stems from something on my site or something I posted some time ago.

Breaking your game into states is a good idea.
If you have managed your memory properly, when a state starts and ends, the amount of memory allocated should be the same.
This is a good way to detect leaks and pinpoint where they are. If you detect a leak when you change from the main menu to the game-start screen, you know you have a leak in your main menu state class and it should be easy to track down.


But there is nothing really tricky about how to implement this.
All classes have a constructor and destructor, but I recommend requiring them to implement a Create() and Destroy() instead, because some resources require a pointer to a higher-level object, such as CGame, and you won’t necessarily have the option to release those resources inside a destructor (which can’t accept parameters). You could implement only Destroy() and use the constructor to replace Create(), but it’s just cleaner to let the constructor and destructor be its own pair and let Create() and Destroy() be their own pair.


Otherwise there is nothing about it.
If the state has released everything it has allocated, the state manager can check how much memory has been allocated before and after a state and if there are any discrepancies it should print a warning.


L. Spiro Edited by L. Spiro

Share this post


Link to post
Share on other sites

sorry for taking so long to reply here is one of states I made:

 

#include "MainMenuState.h"
#include "State.h"
#include "SEngine.h"
#include <SFML/Graphics.hpp>
 
MainMenuState MainMenuState::mainMenuStart; // static MainMenuState variable
 
/* Load() method for MainMenuState, initializes all variables in MainMenuState.
 */
void MainMenuState::Load(){
backGround = sf::RectangleShape(sf::Vector2f(640.0f,480.0f));
menu = backGround.getLocalBounds();
backGround.setOrigin(menu.left,menu.top);
button1 = sf::RectangleShape(sf::Vector2f(100.0f,50.0f));
button2 = sf::RectangleShape(sf::Vector2f(100.0f,50.0f));
button1.setPosition(menu.left + 270.0f, menu.top + 300.0f);
button2.setPosition(menu.left + 270.0f, menu.top + 390.0f);
backGround.setFillColor(sf::Color::Blue);
button1.setFillColor(sf::Color::Red);
button2.setFillColor(sf::Color::Red);
};//Load()
 
/* Handling method for MainMenuState, handles events that may occur in the
   MainMenuState. The only parameter it takes is a reference to the state
   machine, SEngine.*/
void MainMenuState::Handling(SEngine* gameEng){
 
};//Handling()
 
/* Paint method for MainMenuState, draws the components of this state onto the screen.
   The only parameter it takes is a reference to the state machine, SEngine.*/
void MainMenuState::Paint(SEngine* gameEng){
gameEng->getWindow()->clear();
gameEng->getWindow()->draw(backGround);
gameEng->getWindow()->draw(button1);
gameEng->getWindow()->draw(button2);
gameEng->getWindow()->display();
};//Paint()
 
/* Update method for MainMenuState, updates certain values or components that may
   have been affected by events in Handling method. The only parameter it takes
   is a reference to the state machine, SEngine.*/
void MainMenuState::Update(SEngine* gameEng){
 
};//Update()
 
void MainMenuState::TidyUp(){
};//TidyUp()
 
void MainMenuState::Halt(){
};//Halt()
 
void MainMenuState::Continue(){
};//Continue()
 
button1 and button2 are both RectangleShape objects from the SFML library.  I tried putting the following lines in TidyUp():
delete button1;
delete button2;
 
The compiler doesn't have an issue with this but if I try to run the program then I get the debug assertion error.

Share this post


Link to post
Share on other sites

 

 

C++ doesn't have a garbage collector, what are you talking about?

 

This only proves to me that my C++ teacher wasn't that great, he never clarified certain things so I was left to assume.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!