2
\$\begingroup\$

Is there possibly a way to take out the nested if statements without losing the error reports? I am just learning SDL and would like to further simplify my code so that it is readable by me when I look at in a few days.

#include <SDL.h>
#include <iostream>
int main(int argc, char *argv[]) {
 SDL_Window *window = nullptr; //the window
 SDL_Surface *windowSurface = nullptr; //will store current window surface
 SDL_Surface *imageSurface = nullptr; //will store image to be applied to the window
 //inits video
 if (SDL_Init(SDL_INIT_VIDEO) < 0)
 std::cout << "Video Init Error: " << SDL_GetError() << std::endl; 
//if error
 else { //creates window
 window = SDL_CreateWindow("Slime Runner Prelim Tests", 
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_SHOWN);
 if (window == NULL)
 std::cout << "Window creation error: " << SDL_GetError() << 
std::endl; //if error
 else { // if all is good with window creation.
 //WINDOW HAS BEEN CREATED
 windowSurface = SDL_GetWindowSurface(window);
 imageSurface = SDL_LoadBMP("Images/Background.bmp");
 if (imageSurface == NULL) 
 std::cout << "Image load error: " << SDL_GetError() << 
std::endl;
 else {
 SDL_BlitSurface(imageSurface, NULL, windowSurface, NULL);
 SDL_UpdateWindowSurface(window);
 }
 }//end of window creation if
 }//end of SDL_INIT_VIDEOs
 SDL_Delay(4000);
 SDL_FreeSurface(imageSurface);
 imageSurface = nullptr;
 SDL_DestroyWindow(window);
 window = nullptr;
 SDL_Quit(); 
 return 0;
}
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Aug 28, 2017 at 21:25
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Is there possibly a way to take out the nested if statements without losing the error reports?

Use RAII to encapsulate your resources into objects that enforce the create/destroy pairing. You can write your own RAII wrapper objects or (better) use a resource factory that creates std::unique_ptr/std::shared_ptr's. A concrete factory for arbitrary SDL resources:

namespace sdl2 {
template <typename Creator, typename Destroyer, typename... Arguments>
auto make_resource(Creator c, Destroyer d, Arguments &&... args) {
 auto r = c(std::forward<Arguments>(args)...);
 if (!r) {
 throw std::system_error(errno, std::generic_category(), SDL_GetError());
 }
 return std::unique_ptr<std::decay_t<decltype(*r)>, decltype(d)>(r, d);
}
} // namespace sdl2

This factory attempts to create the resource, checks to ensure it was created, and returns a unique_ptr that destroys the resource correctly when the pointer goes out of scope. Specific helpers to provide higher levels of abstraction for resources like SDL_Window, SDL_Texture, SDL_Renderer, etc, can be created like so:

namespace sdl2 {
using WindowPtr = std::unique_ptr<SDL_Window, decltype(&SDL_DestroyWindow)>;
WindowPtr make_window(const char *title, int x, int y, int w, int h,
 std::uint32_t flags) {
 return make_resource(SDL_CreateWindow, SDL_DestroyWindow, title, x, y, w, h,
 flags);
}
} // namespace sdl2

You can write your own abstractions over SDL's C API to utilize some of the modern C++ constructs and ideally end with something like this:

int main() try {
 auto window = sdl2::make_window("Slime Runner Prelim Tests", 
 SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 
 640, 480, 
 SDL_WINDOW_SHOWN);
 auto screen = sdl2::get_surface(window);
 auto image = sdl2::load_bitmap("Images/Background.tmp");
 sdl2::blit_surface(image, nullptr, screen, nullptr);
 sdl2::update_surface(window);
 sdl2::delay(4s);
} catch (...) {
 std::cout << "Error: " << error.what() << '\n';
}

Note: You don't have to use exceptions, but RAII does provide you with the flexibility to choose whichever error handling system you want (exceptions, checked errors, etc) while simplifying the cleanup process.


int main(int argc, char *argv[])

If you are not using argc and argv, omit them.

int main()

std::endl

Be aware of what std::endl actually does. If you simply want to print a newline character, prefer '\n' since it's both shorter and correct.


SDL_BlitSurface(imageSurface, NULL, windowSurface, NULL);

Use nullptr instead of NULL.

answered Aug 29, 2017 at 2:13
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.