diff --git a/examples/run.hpp b/examples/run.hpp index 8d7f607..1296bed 100644 --- a/examples/run.hpp +++ b/examples/run.hpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -31,21 +32,17 @@ void run_example( { std::atexit(lib_exit); try { - bwidgets::SDLError::success_or_throw(SDL_Init(SDL_INIT_VIDEO), __FILE__, - __FUNCTION__, __LINE__); - bwidgets::SDLError::success_or_throw(TTF_Init(), __FILE__, __FUNCTION__, - __LINE__); + bwidgets::success_or_throw(SDL_Init(SDL_INIT_VIDEO)); + bwidgets::success_or_throw(TTF_Init()); const bwidgets::Size size_init {854, 480}; auto font = std::make_shared(bwidgets::Font::find("Monospace"), 16); // NOLINT(readability-magic-numbers) auto win = bwidgets::OpaqueStruct( - bwidgets::ptr_or_throw( - SDL_CreateWindow("basic_widgets example", SDL_WINDOWPOS_CENTERED, - SDL_WINDOWPOS_CENTERED, size_init.w, size_init.h, - SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE - | SDL_WINDOW_UTILITY), - __FILE__, __FUNCTION__, __LINE__), + bwidgets::ptr_or_throw(SDL_CreateWindow( + "basic_widgets example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + size_init.w, size_init.h, + SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_UTILITY)), [](auto ptr) noexcept { SDL_DestroyWindow(ptr); }); auto renderer = std::make_shared(win(), -1, SDL_RENDERER_ACCELERATED); @@ -93,8 +90,7 @@ void run_example( renderer->present(); } } catch (const bwidgets::SDLError& e) { - std::cerr << "Error: " << e.file << ":" << e.func << ":" << e.line << ": " - << e.what << std::endl; + std::cerr << "Error: " << e.what << std::endl; } } diff --git a/inc/basic_widgets/core/error_helper.hpp b/inc/basic_widgets/core/error_helper.hpp new file mode 100644 index 0000000..f7043e3 --- /dev/null +++ b/inc/basic_widgets/core/error_helper.hpp @@ -0,0 +1,35 @@ +#ifndef BWIDGETS_ERROR_HELPER +#define BWIDGETS_ERROR_HELPER + +#include +#include + +namespace bwidgets +{ + template + static inline auto ptr_or_throw(T* ptr, const std::string& w = "") -> T* + { + std::string what; + if constexpr (std::is_same_v) what = w.empty() ? SDL_GetError() : w; + else what = w; + + if (ptr == nullptr) throw E(what); + return ptr; + } + + template + static inline auto success_or_throw( + T code, const std::string& w = "", + std::function success = [](T code) { return code == 0; }) -> T + { + std::string what {w.empty() ? SDL_GetError() : w}; + if constexpr (std::is_same_v) { + if (code <= 0) throw E(what); + } + else if (!success(code)) throw E(what); + + return code; + } +} + +#endif diff --git a/inc/basic_widgets/core/renderer.hpp b/inc/basic_widgets/core/renderer.hpp index d59e70f..cf62eda 100644 --- a/inc/basic_widgets/core/renderer.hpp +++ b/inc/basic_widgets/core/renderer.hpp @@ -7,6 +7,7 @@ #include +#include #include #include #include @@ -23,8 +24,7 @@ namespace bwidgets static inline auto _info(SDL_Renderer* r) -> SDL_RendererInfo { SDL_RendererInfo info; - SDLError::success_or_throw(SDL_GetRendererInfo(r, &info), __FILE__, - __FUNCTION__, __LINE__); + success_or_throw(SDL_GetRendererInfo(r, &info)); return info; } diff --git a/inc/basic_widgets/core/texture.hpp b/inc/basic_widgets/core/texture.hpp index 7c6118a..1761376 100644 --- a/inc/basic_widgets/core/texture.hpp +++ b/inc/basic_widgets/core/texture.hpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -64,13 +65,11 @@ namespace bwidgets [[nodiscard]] static inline auto attributes(SDL_Texture* t) { Attr attr {}; - SDLError::success_or_throw( + success_or_throw( SDL_QueryTexture(t, &attr.format_raw, // NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast) - (int*)&attr.access, &attr.w, &attr.h), - __FILE__, __FUNCTION__, __LINE__); - attr.format = SDLError::ptr_or_throw(SDL_AllocFormat(attr.format_raw), - __FILE__, __FUNCTION__, __LINE__); + (int*)&attr.access, &attr.w, &attr.h)); + attr.format = ptr_or_throw(SDL_AllocFormat(attr.format_raw)); return attr; } diff --git a/inc/basic_widgets/core/type/exception.hpp b/inc/basic_widgets/core/type/exception.hpp index f119103..b419c38 100644 --- a/inc/basic_widgets/core/type/exception.hpp +++ b/inc/basic_widgets/core/type/exception.hpp @@ -12,36 +12,13 @@ namespace bwidgets { struct BaseException : std::exception { - const char* file; - const char* func; - const int line; - const char* what; + std::string what; - BaseException(const char* file, const char* func, int l, const char* w) noexcept - : file(file), func(func), line(l), what(w) - {} + BaseException(std::string w) noexcept : what(std::move(w)) {} }; template concept Exception = std::derived_from; - - template - static inline auto ptr_or_throw(T* ptr, const char* file, const char* func, int l, - const char* w = nullptr) -> T* - { - if (ptr == nullptr) throw E(file, func, l, w); - return ptr; - } - - template - static inline auto success_or_throw( - T code, const char* file, const char* func, int l, const char* w = nullptr, - std::function success = [](const T& code) { return code == 0; }) - -> T - { - if (!success(code)) throw E(file, func, l, w); - return code; - } } #endif diff --git a/inc/basic_widgets/core/type/fc_error.hpp b/inc/basic_widgets/core/type/fc_error.hpp index 62b6d6a..961d9ae 100644 --- a/inc/basic_widgets/core/type/fc_error.hpp +++ b/inc/basic_widgets/core/type/fc_error.hpp @@ -7,9 +7,7 @@ namespace bwidgets { struct FCError final : BaseException { - FCError(const char* file, const char* func, int l, const char* w = nullptr) - : BaseException(file, func, l, w) - {} + using BaseException::BaseException; }; } diff --git a/inc/basic_widgets/core/type/sdl_error.hpp b/inc/basic_widgets/core/type/sdl_error.hpp index 58f6508..cca7162 100644 --- a/inc/basic_widgets/core/type/sdl_error.hpp +++ b/inc/basic_widgets/core/type/sdl_error.hpp @@ -11,32 +11,7 @@ namespace bwidgets { struct SDLError final : BaseException { - SDLError(const char* file, const char* func, const int l, - const char* w = nullptr) noexcept - : BaseException(file, func, l, w) - {} - - template - [[nodiscard]] static inline auto ptr_or_throw(T* ptr, const char* file, - const char* func, int l, - const char* w = nullptr) -> T* - { - if (!ptr) { - if (!w) w = SDL_GetError(); - throw SDLError(file, func, l, w); - } - return ptr; - } - - static inline auto success_or_throw(int code, const char* file, const char* func, - int l, const char* w = nullptr) -> int - { - if (code < 0) { - if (w == nullptr) w = SDL_GetError(); - throw SDLError(file, func, l, w); - } - return code; - } + using BaseException::BaseException; }; } diff --git a/src/core/font.cpp b/src/core/font.cpp index 83c3222..ea0c94d 100644 --- a/src/core/font.cpp +++ b/src/core/font.cpp @@ -3,6 +3,7 @@ #include +#include #include #include #include @@ -13,8 +14,7 @@ const Color Font::default_color_bg {255, 255, 255, SDL_ALPHA_OPAQUE}; const Color Font::default_color_fg {0, 0, 0, SDL_ALPHA_OPAQUE}; Font::Font(TTF_Font* f) - : Wrapper(ptr_or_throw(f, __FILE__, __FUNCTION__, __LINE__), - [f](TTF_Font*) noexcept { TTF_CloseFont(f); }), + : Wrapper(ptr_or_throw(f), [f](TTF_Font*) noexcept { TTF_CloseFont(f); }), ascent(TTF_FontAscent(f)), descent(TTF_FontDescent(f)), faces(TTF_FontFaces(f)), @@ -84,7 +84,7 @@ auto Font::render(const RenderMode m, const std::string& str, const Color& fg, break; } - return ptr_or_throw(renderer(), __FILE__, __FUNCTION__, __LINE__); + return ptr_or_throw(renderer()); } auto Font::style() const noexcept -> uint8_t @@ -109,20 +109,18 @@ auto Font::find(const std::string& pat) -> std::string { std::stack> cleaners; - FcConfig* conf = ptr_or_throw(FcInitLoadConfigAndFonts(), __FILE__, - __FUNCTION__, __LINE__, "init failed"); + FcConfig* conf = ptr_or_throw(FcInitLoadConfigAndFonts(), "init failed"); cleaners.emplace([conf]() { FcConfigDestroy(conf); }); FcPattern* pattern = nullptr; try { - pattern = - ptr_or_throw(FcNameParse((FcChar8*)pat.c_str()), __FILE__, - __FUNCTION__, __LINE__, "pattern parsing failed"); + pattern = ptr_or_throw(FcNameParse((FcChar8*)pat.c_str()), + "pattern parsing failed"); cleaners.emplace([pattern]() { FcPatternDestroy(pattern); }); - if (FcConfigSubstitute(conf, pattern, FcMatchPattern) == FcFalse) - throw FCError {__FILE__, __FUNCTION__, __LINE__, - "FcConfigSubstitute failed"}; + success_or_throw( + FcConfigSubstitute(conf, pattern, FcMatchPattern), "FcConfigSubstitue failed", + [](FcBool code) { return code != FcFalse; }); } catch (const std::exception& e) { while (!cleaners.empty()) { cleaners.top()(); @@ -149,8 +147,7 @@ auto Font::find(const std::string& pat) -> std::string cleaners.pop(); } - if (file_path.empty()) - throw FCError {__FILE__, __FUNCTION__, __LINE__, "no font found"}; + if (file_path.empty()) throw FCError {"no font found"}; return file_path; } diff --git a/src/core/renderer.cpp b/src/core/renderer.cpp index 69d09eb..f963e05 100644 --- a/src/core/renderer.cpp +++ b/src/core/renderer.cpp @@ -4,37 +4,33 @@ using namespace bwidgets; Renderer::Renderer(SDL_Renderer* r) - : Wrapper(ptr_or_throw(r, __FILE__, __FUNCTION__, __LINE__), + : Wrapper(ptr_or_throw(r), [r](SDL_Renderer*) noexcept { SDL_DestroyRenderer(r); }), info(_info(r)) {} Renderer::Renderer(SDL_Window* w, const int index, const uint32_t flags = 0) - : Renderer(ptr_or_throw(SDL_CreateRenderer(w, index, flags), __FILE__, - __FUNCTION__, __LINE__)) + : Renderer(ptr_or_throw(SDL_CreateRenderer(w, index, flags))) {} auto Renderer::blend_mode() -> SDL_BlendMode { SDL_BlendMode mode {}; - SDLError::success_or_throw(SDL_GetRenderDrawBlendMode(_data(), &mode), __FILE__, - __FUNCTION__, __LINE__); + success_or_throw(SDL_GetRenderDrawBlendMode(_data(), &mode)); return mode; } auto Renderer::blend_mode(const SDL_BlendMode mode) -> Renderer* { - SDLError::success_or_throw(SDL_SetRenderDrawBlendMode(_data(), mode), __FILE__, - __FUNCTION__, __LINE__); + success_or_throw(SDL_SetRenderDrawBlendMode(_data(), mode)); return this; } auto Renderer::clear() -> Renderer* { - SDLError::success_or_throw(SDL_RenderClear(_data()), __FILE__, __FUNCTION__, - __LINE__); + success_or_throw(SDL_RenderClear(_data())); return this; } @@ -42,8 +38,7 @@ auto Renderer::clear() -> Renderer* auto Renderer::copy(const Texture* t, const SDL_Rect* src, const SDL_Rect* dst) -> Renderer* { - SDLError::success_or_throw(SDL_RenderCopy(_data(), t->_data(), src, dst), __FILE__, - __FUNCTION__, __LINE__); + success_or_throw(SDL_RenderCopy(_data(), t->_data(), src, dst)); return this; } @@ -51,51 +46,46 @@ auto Renderer::copy(const Texture* t, const SDL_Rect* src, const SDL_Rect* dst) auto Renderer::draw_color() -> Color { Color c; - SDLError::success_or_throw( - SDL_GetRenderDrawColor(_data(), &c().r, &c().g, &c().b, &c().a), __FILE__, - __FUNCTION__, __LINE__); + success_or_throw( + SDL_GetRenderDrawColor(_data(), &c().r, &c().g, &c().b, &c().a)); return c; } auto Renderer::draw_color(const Color& c) -> Renderer* { - SDLError::success_or_throw( - SDL_SetRenderDrawColor(_data(), c().r, c().g, c().b, c().a), __FILE__, - __FUNCTION__, __LINE__); + success_or_throw( + SDL_SetRenderDrawColor(_data(), c().r, c().g, c().b, c().a)); return this; } auto Renderer::draw_line(const SDL_Point& a, const SDL_Point& b) -> Renderer* { - SDLError::success_or_throw(SDL_RenderDrawLine(_data(), a.x, a.y, b.x, b.y), __FILE__, - __FUNCTION__, __LINE__); + success_or_throw(SDL_RenderDrawLine(_data(), a.x, a.y, b.x, b.y)); return this; } auto Renderer::draw_lines(const std::vector& pts) -> Renderer* { - SDLError::success_or_throw(SDL_RenderDrawLines(_data(), pts.data(), (int)pts.size()), - __FILE__, __FUNCTION__, __LINE__); + success_or_throw( + SDL_RenderDrawLines(_data(), pts.data(), (int)pts.size())); return this; } auto Renderer::draw_point(const SDL_Point& p) -> Renderer* { - SDLError::success_or_throw(SDL_RenderDrawPoint(_data(), p.x, p.y), __FILE__, - __FUNCTION__, __LINE__); + success_or_throw(SDL_RenderDrawPoint(_data(), p.x, p.y)); return this; } auto Renderer::draw_points(const std::vector& pts) -> Renderer* { - SDLError::success_or_throw( - SDL_RenderDrawPoints(_data(), pts.data(), (int)pts.size()), __FILE__, __FUNCTION__, - __LINE__); + success_or_throw( + SDL_RenderDrawPoints(_data(), pts.data(), (int)pts.size())); return this; } @@ -108,8 +98,7 @@ auto Renderer::draw_rect(const SDL_Rect* r) -> Renderer* // The second corner is missing a pixel. if (r != nullptr) viewport({vp.x + r->x, vp.y + r->y, r->w - 1, r->h - 1}); // crop extra pixel - SDLError::success_or_throw(SDL_RenderDrawRect(_data(), nullptr), __FILE__, - __FUNCTION__, __LINE__); + success_or_throw(SDL_RenderDrawRect(_data(), nullptr)); // add missing pixel. works sometimes… if (r != nullptr) draw_point({r->w - 1, r->h - 1}); else draw_point({vp.w - 1, vp.h - 1}); @@ -121,24 +110,21 @@ auto Renderer::draw_rect(const SDL_Rect* r) -> Renderer* auto Renderer::draw_rects(const std::vector& rs) -> Renderer* { - SDLError::success_or_throw(SDL_RenderDrawRects(_data(), rs.data(), (int)rs.size()), - __FILE__, __FUNCTION__, __LINE__); + success_or_throw(SDL_RenderDrawRects(_data(), rs.data(), (int)rs.size())); return this; } auto Renderer::fill_rect(const SDL_Rect* r) -> Renderer* { - SDLError::success_or_throw(SDL_RenderFillRect(_data(), r), __FILE__, __FUNCTION__, - __LINE__); + success_or_throw(SDL_RenderFillRect(_data(), r)); return this; } auto Renderer::fill_rects(const std::vector& rs) -> Renderer* { - SDLError::success_or_throw(SDL_RenderFillRects(_data(), rs.data(), (int)rs.size()), - __FILE__, __FUNCTION__, __LINE__); + success_or_throw(SDL_RenderFillRects(_data(), rs.data(), (int)rs.size())); return this; } @@ -146,8 +132,7 @@ auto Renderer::fill_rects(const std::vector& rs) -> Renderer* auto Renderer::output_size() -> Size { Size s {}; - SDLError::success_or_throw(SDL_GetRendererOutputSize(_data(), &s.w, &s.h), __FILE__, - __FUNCTION__, __LINE__); + success_or_throw(SDL_GetRendererOutputSize(_data(), &s.w, &s.h)); return s; } @@ -167,8 +152,7 @@ auto Renderer::viewport() noexcept -> SDL_Rect auto Renderer::viewport(const SDL_Rect* vp) -> Renderer* { - SDLError::success_or_throw(SDL_RenderSetViewport(_data(), vp), __FILE__, - __FUNCTION__, __LINE__); + success_or_throw(SDL_RenderSetViewport(_data(), vp)); return this; } diff --git a/src/core/texture.cpp b/src/core/texture.cpp index 1a1637a..f303674 100644 --- a/src/core/texture.cpp +++ b/src/core/texture.cpp @@ -4,7 +4,7 @@ using namespace bwidgets; Texture::Texture(SDL_Texture* t) - : Wrapper(ptr_or_throw(t, __FILE__, __FUNCTION__, __LINE__), + : Wrapper(ptr_or_throw(t), [t](SDL_Texture*) noexcept { SDL_DestroyTexture(t); }) { _attributes = attributes(t); @@ -30,16 +30,14 @@ Texture::~Texture() noexcept auto Texture::alpha_mode() -> uint8_t { uint8_t mode = 0; - SDLError::success_or_throw(SDL_GetTextureAlphaMod(_data(), &mode), __FILE__, - __FUNCTION__, __LINE__); + success_or_throw(SDL_GetTextureAlphaMod(_data(), &mode)); return mode; } auto Texture::alpha_mode(const uint8_t m) -> Texture* { - SDLError::success_or_throw(SDL_SetTextureAlphaMod(_data(), m), __FILE__, - __FUNCTION__, __LINE__); + success_or_throw(SDL_SetTextureAlphaMod(_data(), m)); return this; } @@ -47,16 +45,14 @@ auto Texture::alpha_mode(const uint8_t m) -> Texture* auto Texture::blend_mode() -> SDL_BlendMode { SDL_BlendMode mode {}; - SDLError::success_or_throw(SDL_GetTextureBlendMode(_data(), &mode), __FILE__, - __FUNCTION__, __LINE__); + success_or_throw(SDL_GetTextureBlendMode(_data(), &mode)); return mode; } auto Texture::blend_mode(const SDL_BlendMode m) -> Texture* { - SDLError::success_or_throw(SDL_SetTextureBlendMode(_data(), m), __FILE__, - __FUNCTION__, __LINE__); + success_or_throw(SDL_SetTextureBlendMode(_data(), m)); return this; } @@ -64,17 +60,15 @@ auto Texture::blend_mode(const SDL_BlendMode m) -> Texture* auto Texture::color_mode() -> Color { Color mode; - SDLError::success_or_throw( - SDL_GetTextureColorMod(_data(), &mode().r, &mode().g, &mode().b), __FILE__, - __FUNCTION__, __LINE__); + success_or_throw( + SDL_GetTextureColorMod(_data(), &mode().r, &mode().g, &mode().b)); return mode; } auto Texture::color_mode(const Color& m) -> Texture* { - SDLError::success_or_throw(SDL_SetTextureColorMod(_data(), m().r, m().g, m().b), - __FILE__, __FUNCTION__, __LINE__); + success_or_throw(SDL_SetTextureColorMod(_data(), m().r, m().g, m().b)); return this; } @@ -82,24 +76,21 @@ auto Texture::color_mode(const Color& m) -> Texture* auto Texture::scale_mode() -> SDL_ScaleMode { SDL_ScaleMode mode {}; - SDLError::success_or_throw(SDL_GetTextureScaleMode(_data(), &mode), __FILE__, - __FUNCTION__, __LINE__); + success_or_throw(SDL_GetTextureScaleMode(_data(), &mode)); return mode; } auto Texture::scale_mode(const SDL_ScaleMode m) -> Texture* { - SDLError::success_or_throw(SDL_SetTextureScaleMode(_data(), m), __FILE__, - __FUNCTION__, __LINE__); + success_or_throw(SDL_SetTextureScaleMode(_data(), m)); return this; } auto Texture::update(SDL_Rect* r, const void* pixels, const int pitch) -> Texture* { - SDLError::success_or_throw(SDL_UpdateTexture(_data(), r, pixels, pitch), __FILE__, - __FUNCTION__, __LINE__); + success_or_throw(SDL_UpdateTexture(_data(), r, pixels, pitch)); return this; }