I'm trying to program a basic game with SDL2 library and I am getting a little bit confused with a basic concept.
Basically I would like to make a function:
void quit_clean (SDL_Window *window, SDL_Renderer *renderer)
{
if (renderer != NULL)
SDL_DestroyRenderer(renderer);
if (window != NULL)
SDL_DestroyWindow(window);
exit(EXIT_FAILURE);
}
I would call this function each time there is an error so I can free the renderer and the window properly before to quit the program e.g.
texture = SDL_CreateTextureFromSurface(renderer, tmp);
if(texture==NULL){
printf ("SDL_CreateTextureFromSurface Error: : %s\n", SDL_GetError());
quit_clean (&window, &renderer);
}
Where I am getting confused is if I need to call this function from another function how does it work ?
To be precise I would have:
The way I see it, in order to pass my window and my renderer from main() to quit_clean() using my_function() the prototypes would be then:
void my_function (SDL_Window **window, SDL_Renderer **renderer);
void quit_clean (SDL_Window ***window, SDL_Renderer ***renderer);
Am I correct or not? If yes then how could I call this function from main() if needed.
If I call "quit_clean (&window, &renderer);" from my main() the types are not correct anymore then.
Or maybe I could create pointers from window and renderer and pass those pointers to quit_clean(). I don't know I'm confused, I'm not sure if my thought process is correct.
Do you have any tips for this kind of situation?
You don't need the double pointer as arguments to your functions:
int my_function (SDL_Window *window, SDL_Renderer *renderer);
int quit_clean (SDL_Window *window, SDL_Renderer *renderer);
As you might have noticed, i've added a return type (int), because every function should return a result, indicating success or failure.
Secondly, it would be better not to call the quit_clean
function from other functions, instead, if you encounter an error in for e.g. my_function
, return an error and call the quit_clean
function in the main function.
Like this:
int main()
{
SDL_Window *window = NULL;
SDL_Renderer *renderer = NULL;
window = SDL_CreateWindow(...);
if (window) {
renderer = SDL_CreateRenderer(window, ...);
if (renderer) {
int err = my_function(window, renderer);
if (!err) { //success: 0, error: -1
//do what is needed to be done
}
}
}
//finally clean up,
//no matter the case (either due to error or program termination)
quit_clean(window, renderer);
return 0;
}
In the quit_clean
function you have to check the passed arguments (although i think that SDL checks them too, but better than sorry):
int quit_clean (SDL_Window *window, SDL_Renderer *renderer)
{
//other cleanup first
//finally
if (renderer != NULL)
SDL_DestroyRenderer(renderer);
if (window != NULL)
SDL_DestroyWindow(window);
SDL_Quit();
}
And for clarity an example of my_function
:
int my_function (SDL_Window *window, SDL_Renderer *renderer)
{
if (some_condition_does_not_hold)
return -1;
//do your stuff
//never call quit_clean if something goes wrong, return either -1 or
//some other (previously defined) negative error number
//finally
return 0; //success
}