From 4ba85c9e79ae8cbac13546206a757d2de0f4d3ce Mon Sep 17 00:00:00 2001 From: lisyarus Date: Wed, 3 Mar 2021 18:03:40 +0300 Subject: [PATCH] App uses a scene stack & owns scenes --- libs/app/include/psemek/app/app.hpp | 3 ++- libs/app/source/app.cpp | 36 +++++++++++++++++++++-------- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/libs/app/include/psemek/app/app.hpp b/libs/app/include/psemek/app/app.hpp index 9f5a07ca..7c4d9c2b 100644 --- a/libs/app/include/psemek/app/app.hpp +++ b/libs/app/include/psemek/app/app.hpp @@ -29,7 +29,8 @@ namespace psemek::app void poll_events(); void run(); - scene * set_scene(scene * s); + void push_scene(std::unique_ptr s); + std::unique_ptr pop_scene(); void show_cursor(bool show); void vsync(bool on); diff --git a/libs/app/source/app.cpp b/libs/app/source/app.cpp index 4eafd637..d92a3038 100644 --- a/libs/app/source/app.cpp +++ b/libs/app/source/app.cpp @@ -5,6 +5,8 @@ #include +#include + namespace psemek::app { @@ -18,7 +20,7 @@ namespace psemek::app SDL_Window * window = nullptr; SDL_GLContext gl_context = nullptr; - scene * current_scene = nullptr; + std::vector> scene_stack; bool running = false; @@ -39,8 +41,8 @@ namespace psemek::app scene * get_scene() { - if (current_scene) - return current_scene; + if (!scene_stack.empty()) + return scene_stack.back().get(); return parent; } }; @@ -199,36 +201,50 @@ namespace psemek::app { SDL_ShowWindow(impl().window); impl().running = true; - if (impl().current_scene == nullptr) + if (impl().get_scene() == this) on_scene_enter(this); while (running()) { poll_events(); - auto handler = impl().get_scene(); + auto handler = [this]{ return impl().get_scene(); }; if (!impl().had_initial_resize) { int w, h; SDL_GetWindowSize(impl().window, &w, &h); impl().had_initial_resize = true; - handler->on_resize(w, h); + handler()->on_resize(w, h); } if (!running()) break; - handler->update(); - handler->present(); + handler()->update(); + handler()->present(); SDL_GL_SwapWindow(impl().window); } impl().get_scene()->on_scene_exit(); } - scene * app::set_scene(scene * s) + void app::push_scene(std::unique_ptr s) { impl().get_scene()->on_scene_exit(); impl().had_initial_resize = false; - std::swap(s, impl().current_scene); + impl().scene_stack.push_back(std::move(s)); + + impl().get_scene()->on_scene_enter(this); + } + + std::unique_ptr app::pop_scene() + { + if (impl().scene_stack.empty()) + return nullptr; + + impl().get_scene()->on_scene_exit(); + + impl().had_initial_resize = false; + auto s = std::move(impl().scene_stack.back()); + impl().scene_stack.pop_back(); impl().get_scene()->on_scene_enter(this);