App uses a scene stack & owns scenes

This commit is contained in:
Nikita Lisitsa 2021-03-03 18:03:40 +03:00
parent 908b6cc5c9
commit 4ba85c9e79
2 changed files with 28 additions and 11 deletions

View file

@ -29,7 +29,8 @@ namespace psemek::app
void poll_events();
void run();
scene * set_scene(scene * s);
void push_scene(std::unique_ptr<scene> s);
std::unique_ptr<scene> pop_scene();
void show_cursor(bool show);
void vsync(bool on);

View file

@ -5,6 +5,8 @@
#include <SDL2/SDL.h>
#include <vector>
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<std::unique_ptr<scene>> 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<scene> 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<scene> 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);