From 89e19cf084cc886b460ee27fe88db7766a6b4e73 Mon Sep 17 00:00:00 2001 From: Stephen Seo Date: Thu, 17 Aug 2023 12:58:52 +0900 Subject: [PATCH] Impl. "construct screen" fn for Screen/ScreenStack Minor fix to push_screen() fn in ScreenStack. --- src/game.cc | 2 +- src/screen.cc | 13 ++++++++++++- src/screen.h | 27 +++++++++++++++++++++------ 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/game.cc b/src/game.cc index 5620b6c..72359dc 100644 --- a/src/game.cc +++ b/src/game.cc @@ -9,7 +9,7 @@ Game::Game() : screen_stack(ScreenStack::new_instance()), prev_time(std::chrono::steady_clock::now()) { - screen_stack->push_screen(); + screen_stack->push_constructing_screen(); } void Game::update() { diff --git a/src/screen.cc b/src/screen.cc index 2907608..c37ff9d 100644 --- a/src/screen.cc +++ b/src/screen.cc @@ -19,6 +19,11 @@ ScreenStack::PendingAction::PendingAction(Action action) ScreenStack::PendingAction::PendingAction(Screen::Ptr &&screen) : screen(std::forward(screen)), action(Action::PUSH_SCREEN) {} +ScreenStack::PendingAction::PendingAction( + std::function &&fn) + : screen(std::forward >(fn)), + action(Action::CONSTRUCT_SCREEN) {} + ScreenStack::Ptr ScreenStack::new_instance() { std::shared_ptr ptr = std::shared_ptr(new ScreenStack{}); @@ -66,7 +71,8 @@ void ScreenStack::handle_pending_actions() { while (!actions.empty()) { switch (actions.front().action) { case Action::PUSH_SCREEN: - stack.push_back(std::move(actions.front().screen)); + stack.emplace_back( + std::move(std::get(actions.front().screen))); break; case Action::POP_SCREEN: if (!stack.empty()) { @@ -86,6 +92,11 @@ void ScreenStack::handle_pending_actions() { #endif stack.clear(); break; + case Action::CONSTRUCT_SCREEN: + stack.emplace_back( + std::get >( + actions.front().screen)(self_weak)); + break; case Action::NOP: // Intentionally left blank. break; diff --git a/src/screen.h b/src/screen.h index f9f9e7b..9c29c38 100644 --- a/src/screen.h +++ b/src/screen.h @@ -2,7 +2,9 @@ #define JUMPARTIFACT_DOT_COM_DEMO_0_SCREEN_H_ #include +#include #include +#include #include // Forward declaration. @@ -36,13 +38,18 @@ class Screen { }; class ScreenStack { + public: + using Ptr = std::shared_ptr; + using Weak = std::weak_ptr; + private: - enum Action { PUSH_SCREEN, POP_SCREEN, CLEAR_SCREENS, NOP }; + enum Action { PUSH_SCREEN, POP_SCREEN, CLEAR_SCREENS, CONSTRUCT_SCREEN, NOP }; struct PendingAction { PendingAction(); PendingAction(Action action); PendingAction(Screen::Ptr&&); + PendingAction(std::function&&); // No copy. PendingAction(const PendingAction&) = delete; @@ -52,14 +59,12 @@ class ScreenStack { PendingAction(PendingAction&&) = default; PendingAction& operator=(PendingAction&&) = default; - Screen::Ptr screen; + std::variant > + screen; Action action; }; public: - using Ptr = std::shared_ptr; - using Weak = std::weak_ptr; - static Ptr new_instance(); // No copy. @@ -78,6 +83,9 @@ class ScreenStack { template void push_screen(); + template + void push_constructing_screen(); + void pop_screen(); void clear_screens(); @@ -99,7 +107,14 @@ Screen::Ptr Screen::new_screen(std::weak_ptr stack) { template void ScreenStack::push_screen() { - stack.emplace_back(Screen::new_screen(self_weak)); + actions.emplace_back(Screen::new_screen(self_weak)); +} + +template +void ScreenStack::push_constructing_screen() { + actions.emplace_back([](ScreenStack::Weak ss) -> Screen::Ptr { + return Screen::new_screen(ss); + }); } #endif