Defer ScreenStack actions to start of update
This commit is contained in:
parent
a617ef3fb6
commit
7a4c8ea0f5
3 changed files with 77 additions and 10 deletions
|
@ -5,9 +5,7 @@
|
|||
|
||||
Game::Game()
|
||||
: screen_stack(ScreenStack::new_instance()),
|
||||
prev_time(std::chrono::steady_clock::now()) {
|
||||
screen_stack->push_screen<TestScreen>();
|
||||
}
|
||||
prev_time(std::chrono::steady_clock::now()) {}
|
||||
|
||||
void Game::update() {
|
||||
auto next_time = std::chrono::steady_clock::now();
|
||||
|
|
|
@ -1,7 +1,24 @@
|
|||
#include "screen.h"
|
||||
|
||||
// standard library includes
|
||||
#include <cassert>
|
||||
#ifndef NDEBUG
|
||||
#include <iostream>
|
||||
#endif // NDEBUG
|
||||
|
||||
// local includes
|
||||
#include "screen_test.h"
|
||||
|
||||
Screen::Screen(std::weak_ptr<ScreenStack> stack) : stack(stack) {}
|
||||
|
||||
ScreenStack::PendingAction::PendingAction() : screen(), action(Action::NOP) {}
|
||||
|
||||
ScreenStack::PendingAction::PendingAction(Action action)
|
||||
: screen(), action(action) {}
|
||||
|
||||
ScreenStack::PendingAction::PendingAction(Screen::Ptr &&screen)
|
||||
: screen(std::forward<Screen::Ptr>(screen)), action(Action::PUSH_SCREEN) {}
|
||||
|
||||
ScreenStack::Ptr ScreenStack::new_instance() {
|
||||
std::shared_ptr<ScreenStack> ptr =
|
||||
std::shared_ptr<ScreenStack>(new ScreenStack{});
|
||||
|
@ -10,7 +27,17 @@ ScreenStack::Ptr ScreenStack::new_instance() {
|
|||
}
|
||||
|
||||
void ScreenStack::update(float dt) {
|
||||
handle_pending_actions();
|
||||
|
||||
auto idx = stack.size();
|
||||
if (idx == 0) {
|
||||
#ifndef NDEBUG
|
||||
std::cerr << "WARNING: Stack is empty, pushing TestScreen...\n";
|
||||
#endif // NDEBUG
|
||||
push_screen(Screen::new_screen<TestScreen>(self_weak));
|
||||
update(dt);
|
||||
return;
|
||||
}
|
||||
while (idx > 0 && stack.at(--idx)->update(dt)) {
|
||||
}
|
||||
}
|
||||
|
@ -22,13 +49,33 @@ void ScreenStack::draw() {
|
|||
}
|
||||
|
||||
void ScreenStack::push_screen(Screen::Ptr &&screen) {
|
||||
stack.emplace_back(std::forward<Screen::Ptr>(screen));
|
||||
actions.push_back(PendingAction(std::forward<Screen::Ptr>(screen)));
|
||||
}
|
||||
|
||||
void ScreenStack::pop_screen() {
|
||||
if (!stack.empty()) {
|
||||
stack.pop_back();
|
||||
}
|
||||
actions.push_back(PendingAction(Action::POP_SCREEN));
|
||||
}
|
||||
|
||||
ScreenStack::ScreenStack() : self_weak(), stack() {}
|
||||
ScreenStack::ScreenStack() : self_weak(), stack(), actions() {}
|
||||
|
||||
void ScreenStack::handle_pending_actions() {
|
||||
while (!actions.empty()) {
|
||||
switch (actions.front().action) {
|
||||
case Action::PUSH_SCREEN:
|
||||
stack.push_back(std::move(actions.front().screen));
|
||||
break;
|
||||
case Action::POP_SCREEN:
|
||||
if (!stack.empty()) {
|
||||
stack.pop_back();
|
||||
}
|
||||
break;
|
||||
case Action::NOP:
|
||||
// Intentionally left blank.
|
||||
break;
|
||||
default:
|
||||
assert(!"unreachable");
|
||||
break;
|
||||
}
|
||||
actions.pop_front();
|
||||
}
|
||||
}
|
||||
|
|
26
src/screen.h
26
src/screen.h
|
@ -1,6 +1,7 @@
|
|||
#ifndef JUMPARTIFACT_DOT_COM_DEMO_0_SCREEN_H_
|
||||
#define JUMPARTIFACT_DOT_COM_DEMO_0_SCREEN_H_
|
||||
|
||||
#include <deque>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
|
@ -31,12 +32,30 @@ class Screen {
|
|||
|
||||
protected:
|
||||
Screen(std::weak_ptr<ScreenStack> stack);
|
||||
|
||||
private:
|
||||
std::weak_ptr<ScreenStack> stack;
|
||||
};
|
||||
|
||||
class ScreenStack {
|
||||
private:
|
||||
enum Action { PUSH_SCREEN, POP_SCREEN, NOP };
|
||||
|
||||
struct PendingAction {
|
||||
PendingAction();
|
||||
PendingAction(Action action);
|
||||
PendingAction(Screen::Ptr&&);
|
||||
|
||||
// No copy.
|
||||
PendingAction(const PendingAction&) = delete;
|
||||
PendingAction& operator=(const PendingAction&) = delete;
|
||||
|
||||
// Allow move.
|
||||
PendingAction(PendingAction&&) = default;
|
||||
PendingAction& operator=(PendingAction&&) = default;
|
||||
|
||||
Screen::Ptr screen;
|
||||
Action action;
|
||||
};
|
||||
|
||||
public:
|
||||
using Ptr = std::shared_ptr<ScreenStack>;
|
||||
using Weak = std::weak_ptr<ScreenStack>;
|
||||
|
@ -64,8 +83,11 @@ class ScreenStack {
|
|||
private:
|
||||
ScreenStack();
|
||||
|
||||
void handle_pending_actions();
|
||||
|
||||
Weak self_weak;
|
||||
std::vector<Screen::Ptr> stack;
|
||||
std::deque<PendingAction> actions;
|
||||
};
|
||||
|
||||
template <typename SubScreen>
|
||||
|
|
Loading…
Reference in a new issue