From 32ac8b4e0f403951d0280ebb9de0f13aa3a0eb23 Mon Sep 17 00:00:00 2001 From: Bob Polis Date: Fri, 13 Nov 2020 16:54:49 +0100 Subject: [PATCH] refactored event handling; added _dirty flag to only update when dirty --- src/Window.cpp | 45 ++++++++++++++++++++++++++++++--------------- src/Window.hpp | 9 ++++++++- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/src/Window.cpp b/src/Window.cpp index f539cfe..9447945 100644 --- a/src/Window.cpp +++ b/src/Window.cpp @@ -53,18 +53,12 @@ bool Window::handle_global_event(const SDL_Event& event) { } } switch (event.window.event) { - case SDL_WINDOWEVENT_CLOSE: { - // remove window from window list - SDL_Window* w {SDL_GetWindowFromID(event.window.windowID)}; - auto it = std::remove_if(_windows.begin(), _windows.end(), [w](Window& win) { - return win.window() == w; - }); - _windows.erase(it, _windows.end()); - if (_windows.size() == 0) { - quit = true; - } + case SDL_WINDOWEVENT_CLOSE: + quit = close(event); + break; + case SDL_WINDOWEVENT_EXPOSED: + quit = expose(event); break; - } default: break; } @@ -81,6 +75,24 @@ void Window::add_global_event_handler(WindowEventHandler handler, SDL_WindowEven } } +bool Window::expose(const SDL_Event& event) { + Window* w {from_sdl(event.window.windowID)}; + if (w) w->dirty(true); + return false; +} + +bool Window::close(const SDL_Event& event) { + // remove window from window list + SDL_Window* w {SDL_GetWindowFromID(event.window.windowID)}; + auto it = std::remove_if(_windows.begin(), _windows.end(), [w](Window& win) { + return win.window() == w; + }); + _windows.erase(it, _windows.end()); + + // quit if it was the last window + return _windows.size() == 0; +} + Window::Window(const std::string& title) : _title {title} { SDL_Window* win = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, @@ -94,10 +106,13 @@ void Window::set_size(int w, int h) { SDL_SetWindowSize(_w.get(), w, h); } -void Window::update() const { - SDL_RenderClear(_r.get()); - SDL_RenderCopy(_r.get(), _t.get(), nullptr, nullptr); - SDL_RenderPresent(_r.get()); +void Window::update() { + if (_dirty) { + _dirty = false; + SDL_RenderClear(_r.get()); + SDL_RenderCopy(_r.get(), _t.get(), nullptr, nullptr); + SDL_RenderPresent(_r.get()); + } } void Window::show_image(const Image& image) { diff --git a/src/Window.hpp b/src/Window.hpp index 312041a..a2dec84 100644 --- a/src/Window.hpp +++ b/src/Window.hpp @@ -43,18 +43,25 @@ namespace sc { int width() const; int height() const; - void update() const; + void update(); void show_image(const Image& image); + void dirty(bool flag) { _dirty = flag; } + bool dirty() const { return _dirty; } + private: static std::vector _windows; static std::map> _global_event_handlers; + bool _dirty {true}; std::string _title; std::unique_ptr _w {nullptr, SDL_DestroyWindow}; std::unique_ptr _r {nullptr, SDL_DestroyRenderer}; std::unique_ptr _t {nullptr, SDL_DestroyTexture}; std::map> _event_handlers; + + static bool close(const SDL_Event& event); + static bool expose(const SDL_Event& event); }; } }