Impl. "construct screen" fn for Screen/ScreenStack
All checks were successful
Build and Publish WASM version of demo / Build-And-Deploy (push) Successful in 19s

Minor fix to push_screen() fn in ScreenStack.
This commit is contained in:
Stephen Seo 2023-08-17 12:58:52 +09:00
parent 11c7dec3ed
commit 89e19cf084
3 changed files with 34 additions and 8 deletions

View 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() {

View 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;

View 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