]> git.seodisparate.com - jumpartifact.com_demo_0/commitdiff
Impl. "construct screen" fn for Screen/ScreenStack
authorStephen Seo <seo.disparate@gmail.com>
Thu, 17 Aug 2023 03:58:52 +0000 (12:58 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Thu, 17 Aug 2023 04:00:42 +0000 (13:00 +0900)
Minor fix to push_screen() fn in ScreenStack.

src/game.cc
src/screen.cc
src/screen.h

index 5620b6ca294cff9e5935dd3fdef03ec1d47a8e8d..72359dc1b7e787ca1ed9401cfc18c80f51b8d712 100644 (file)
@@ -9,7 +9,7 @@
 Game::Game()
     : screen_stack(ScreenStack::new_instance()),
       prev_time(std::chrono::steady_clock::now()) {
-  screen_stack->push_screen<TRunnerScreen>();
+  screen_stack->push_constructing_screen<TRunnerScreen>();
 }
 
 void Game::update() {
index 290760833f5b873db765dfc776dc4930d64a9279..c37ff9d868ff11587c1a0438390a7a9939846842 100644 (file)
@@ -19,6 +19,11 @@ ScreenStack::PendingAction::PendingAction(Action action)
 ScreenStack::PendingAction::PendingAction(Screen::Ptr &&screen)
     : screen(std::forward<Screen::Ptr>(screen)), action(Action::PUSH_SCREEN) {}
 
+ScreenStack::PendingAction::PendingAction(
+    std::function<Screen::Ptr(ScreenStack::Weak)> &&fn)
+    : screen(std::forward<std::function<Screen::Ptr(ScreenStack::Weak)> >(fn)),
+      action(Action::CONSTRUCT_SCREEN) {}
+
 ScreenStack::Ptr ScreenStack::new_instance() {
   std::shared_ptr<ScreenStack> ptr =
       std::shared_ptr<ScreenStack>(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<Screen::Ptr>(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<std::function<Screen::Ptr(ScreenStack::Weak)> >(
+                actions.front().screen)(self_weak));
+        break;
       case Action::NOP:
         // Intentionally left blank.
         break;
index f9f9e7b5f96d6195852e9d43fe56013c6cfefeaa..9c29c384825cfcb772c393347dc61542ea0b3548 100644 (file)
@@ -2,7 +2,9 @@
 #define JUMPARTIFACT_DOT_COM_DEMO_0_SCREEN_H_
 
 #include <deque>
+#include <functional>
 #include <memory>
+#include <variant>
 #include <vector>
 
 // Forward declaration.
@@ -36,13 +38,18 @@ class Screen {
 };
 
 class ScreenStack {
+ public:
+  using Ptr = std::shared_ptr<ScreenStack>;
+  using Weak = std::weak_ptr<ScreenStack>;
+
  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<Screen::Ptr(ScreenStack::Weak)>&&);
 
     // 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::Ptr, std::function<Screen::Ptr(ScreenStack::Weak)> >
+        screen;
     Action action;
   };
 
  public:
-  using Ptr = std::shared_ptr<ScreenStack>;
-  using Weak = std::weak_ptr<ScreenStack>;
-
   static Ptr new_instance();
 
   // No copy.
@@ -78,6 +83,9 @@ class ScreenStack {
   template <typename SubScreen>
   void push_screen();
 
+  template <typename SubScreen>
+  void push_constructing_screen();
+
   void pop_screen();
 
   void clear_screens();
@@ -99,7 +107,14 @@ Screen::Ptr Screen::new_screen(std::weak_ptr<ScreenStack> stack) {
 
 template <typename SubScreen>
 void ScreenStack::push_screen() {
-  stack.emplace_back(Screen::new_screen<SubScreen>(self_weak));
+  actions.emplace_back(Screen::new_screen<SubScreen>(self_weak));
+}
+
+template <typename SubScreen>
+void ScreenStack::push_constructing_screen() {
+  actions.emplace_back([](ScreenStack::Weak ss) -> Screen::Ptr {
+    return Screen::new_screen<SubScreen>(ss);
+  });
 }
 
 #endif