ulfben

SDL wrappers for C++11

Oct 17th, 2016
139
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #pragma once
  2. #include <memory>
  3. #include <cerrno>
  4. #include <system_error>
  5. #include "SDL.h"
  6. /*
  7. A namespace for wrapping SDL in C++11 convenience, like:
  8.     1. unique and shared pointers for all SDL resource types
  9.             http://swarminglogic.com/jotting/2015_05_smartwrappers
  10.     2. templatized unique_ptr factory for arbitrary types: "make_resource"
  11.             https://eb2.co/blog/2014/04/c-plus-plus-14-and-sdl2-managing-resources/
  12.     3. exception classes that wraps the SDL_GetError-message
  13. */
  14. namespace sdl2 {
  15.     class SDLError : public std::exception {
  16.         std::string _msg;
  17.     public:
  18.         SDLError::SDLError() : exception(), _msg(SDL_GetError()) {}
  19.         SDLError::SDLError(const std::string& m) : exception(), _msg(m) {}
  20.         virtual ~SDLError() {};
  21.         virtual const char* what() const {
  22.             return _msg.c_str();
  23.         }
  24.     };
  25.     class InitError : public SDLError {    
  26.     public:
  27.         InitError::InitError() : SDLError() {};
  28.         InitError::InitError(const std::string& m) : SDLError(m){}         
  29.         virtual ~InitError() {};
  30.     };
  31.     struct SDL_Deleter {
  32.         void operator()(SDL_Surface*  ptr) { if (ptr) SDL_FreeSurface(ptr); }
  33.         void operator()(SDL_Texture*  ptr) { if (ptr) SDL_DestroyTexture(ptr); }
  34.         void operator()(SDL_Renderer* ptr) { if (ptr) SDL_DestroyRenderer(ptr); }
  35.         void operator()(SDL_Window*   ptr) { if (ptr) SDL_DestroyWindow(ptr); }
  36.         void operator()(SDL_RWops*    ptr) { if (ptr) SDL_RWclose(ptr); }
  37.         void operator()(char*         ptr) { if (ptr) SDL_free(ptr); } //for paths
  38.     }; 
  39.     //extending shared_ptr to support custom deletion
  40.     template<class T, class D = std::default_delete<T>>
  41.     struct shared_ptr_with_deleter : public std::shared_ptr<T>  {
  42.         explicit shared_ptr_with_deleter(T* t = nullptr) : std::shared_ptr<T>(t, D()) {}
  43.         void reset(T* t = nullptr) {
  44.             std::shared_ptr<T>::reset(t, D());
  45.         }
  46.     };
  47.     // unique pointers
  48.     using SurfacePtr    = std::unique_ptr<SDL_Surface,  SDL_Deleter>;
  49.     using TexturePtr    = std::unique_ptr<SDL_Texture,  SDL_Deleter>;
  50.     using RendererPtr   = std::unique_ptr<SDL_Renderer, SDL_Deleter>;
  51.     using WindowPtr     = std::unique_ptr<SDL_Window,   SDL_Deleter>;
  52.     using RWopsPtr      = std::unique_ptr<SDL_RWops,    SDL_Deleter>;
  53.     using CharPtr       = std::unique_ptr<char,         SDL_Deleter>;  
  54.     //shared pointers
  55.     using SurfaceShPtr  = shared_ptr_with_deleter<SDL_Surface,  SDL_Deleter>;
  56.     using TextureShPtr  = shared_ptr_with_deleter<SDL_Texture,  SDL_Deleter>;
  57.     using RendererShPtr = shared_ptr_with_deleter<SDL_Renderer, SDL_Deleter>;
  58.     using WindowShPtr   = shared_ptr_with_deleter<SDL_Window,   SDL_Deleter>;
  59.     using RWopsShPtr    = shared_ptr_with_deleter<SDL_RWops,    SDL_Deleter>;
  60.     using CharShPtr     = shared_ptr_with_deleter<char,         SDL_Deleter>;
  61.    
  62.     //templatized unique_ptr factory for arbitrary types
  63.         //unique_ptr<t> make_t(...);                       
  64.     template<typename Creator, typename Destructor, typename... Arguments>
  65.     auto make_resource(Creator c, Destructor d, Arguments&&... args) {
  66.         auto r = c(std::forward<Arguments>(args)...);
  67.         if (!r) {
  68.             throw std::system_error(errno, std::generic_category());
  69.         }
  70.         return std::unique_ptr<std::decay_t<decltype(*r)>, decltype(d)>(r, d);
  71.     }  
  72.     using window_ptr = std::unique_ptr<SDL_Window, decltype(&SDL_DestroyWindow)>;
  73.     using renderer_ptr = std::unique_ptr<SDL_Renderer, decltype(&SDL_DestroyRenderer)>;
  74.     using texture_ptr = std::unique_ptr<SDL_Texture, decltype(&SDL_DestroyTexture)>;
  75.     using surface_ptr = std::unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)>;
  76.  
  77.     inline window_ptr make_window(const char* title, int w, int h, Uint32 flags=SDL_WINDOW_OPENGL,
  78.                                     int x = SDL_WINDOWPOS_UNDEFINED, int y = SDL_WINDOWPOS_UNDEFINED) {
  79.         return make_resource(SDL_CreateWindow, SDL_DestroyWindow, title, x, y, w, h, flags);
  80.     }
  81.     inline renderer_ptr make_renderer(SDL_Window& w, Uint32 flags = SDL_RENDERER_ACCELERATED, int index = -1) {    
  82.         return make_resource(SDL_CreateRenderer, SDL_DestroyRenderer, &w, index, flags);
  83.     }      
  84.     inline texture_ptr make_texture(SDL_Renderer& r, Uint32 format /*SDL_PixelFormatEnum*/, int access /*SDL_TextureAccess*/,
  85.                                     int width, int height) {
  86.         return make_resource(SDL_CreateTexture, SDL_DestroyTexture, &r, format, access, width, height);
  87.     }
  88.     inline texture_ptr make_texture(SDL_Renderer& r, SDL_Surface* surface) {
  89.         return make_resource(SDL_CreateTextureFromSurface, SDL_DestroyTexture, &r, surface);
  90.     }
  91.     inline surface_ptr make_surface(Uint32 flags, int width, int height, int depth,
  92.                                     Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) {
  93.         return make_resource(SDL_CreateRGBSurface, SDL_FreeSurface, flags, width, height, depth, Rmask, Gmask, Bmask, Amask);
  94.     }
  95.     inline surface_ptr make_surface(void* pixels, int width, int height, int depth, int pitch,
  96.                                     Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) {
  97.         return make_resource(SDL_CreateRGBSurfaceFrom, SDL_FreeSurface, pixels, width, height, depth, pitch, Rmask, Gmask, Bmask, Amask);
  98.     }
  99. };
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×