psemek/libs/sdl2/source/init.cpp

74 lines
1.4 KiB
C++

#include <psemek/sdl2/init.hpp>
#include <psemek/log/log.hpp>
#include <psemek/util/exception.hpp>
#include <SDL2/SDL.h>
namespace psemek::sdl2
{
namespace
{
struct sdl_initializer
{
sdl_initializer()
{
if (SDL_Init(0) != 0)
fail("Failed to initialize SDL2: ");
SDL_version version;
SDL_GetVersion(&version);
log::info() << "Initialized SDL " << (int)version.major << '.' << (int)version.minor << '.' << (int)version.patch;
}
~sdl_initializer()
{
SDL_Quit();
}
static std::shared_ptr<sdl_initializer> instance()
{
static std::weak_ptr<sdl_initializer> ptr;
if (auto p = ptr.lock(); p)
return p;
auto p = std::make_shared<sdl_initializer>();
ptr = p;
return p;
}
};
struct subsystem_initializer
{
std::shared_ptr<sdl_initializer> sdl_init;
std::uint32_t subsystems;
subsystem_initializer(std::uint32_t subsystems)
: sdl_init(sdl_initializer::instance())
, subsystems(subsystems)
{
if (SDL_InitSubSystem(subsystems) != 0)
fail("Failed to initialize SDL2 subsystems: ");
}
~subsystem_initializer()
{
SDL_QuitSubSystem(subsystems);
}
};
}
[[noreturn]] void fail(std::string const & message)
{
throw util::exception(message + SDL_GetError());
}
std::shared_ptr<void> init(std::uint32_t subsystems)
{
return std::make_shared<subsystem_initializer>(subsystems);
}
}