diff --git a/Makefile b/Makefile index 41dedd7..16658a1 100644 --- a/Makefile +++ b/Makefile @@ -11,10 +11,14 @@ OBJDIR = objdir SOURCES = \ src/main.cc \ - src/game.cc + src/game.cc \ + src/screen.cc \ + src/screen_test.cc HEADERS = \ - src/game.h + src/game.h \ + src/screen.h \ + src/screen_test.h OBJECTS = $(addprefix ${OBJDIR}/,$(subst .cc,.cc.o,${SOURCES})) diff --git a/src/game.cc b/src/game.cc index c290b9d..95324d7 100644 --- a/src/game.cc +++ b/src/game.cc @@ -1,31 +1,20 @@ #include "game.h" -// standard library includes -#include - -// third party includes -#include +// local includes +#include "screen_test.h" Game::Game() - : prev_time(std::chrono::steady_clock::now()), TEMP_cached_dt(0.0F) {} + : screen_stack(ScreenStack::new_instance()), + prev_time(std::chrono::steady_clock::now()) { + screen_stack->push_screen(); +} void Game::update() { auto next_time = std::chrono::steady_clock::now(); auto duration = std::chrono::duration_cast( next_time - prev_time); prev_time = next_time; - update_impl(((float)duration.count()) / 1000000); + screen_stack->update(((float)duration.count()) / 1000000); } -void Game::draw() { - std::string dt_string = - std::string("Delta-time: ") + std::to_string(TEMP_cached_dt); - - BeginDrawing(); - ClearBackground(BLACK); - DrawText("Testing...", 100, 100, 30, RAYWHITE); - DrawText(dt_string.c_str(), 100, 140, 30, RAYWHITE); - EndDrawing(); -} - -void Game::update_impl(float dt) { TEMP_cached_dt = dt; } +void Game::draw() { screen_stack->draw(); } diff --git a/src/game.h b/src/game.h index 413641b..b3fd492 100644 --- a/src/game.h +++ b/src/game.h @@ -4,6 +4,9 @@ // standard library includes #include +// local includes +#include "screen.h" + class Game { public: Game(); @@ -20,10 +23,8 @@ class Game { void draw(); private: - void update_impl(float dt); - + ScreenStack::Ptr screen_stack; std::chrono::steady_clock::time_point prev_time; - float TEMP_cached_dt; }; #endif diff --git a/src/screen.cc b/src/screen.cc new file mode 100644 index 0000000..bd855cf --- /dev/null +++ b/src/screen.cc @@ -0,0 +1,34 @@ +#include "screen.h" + +Screen::Screen(std::weak_ptr stack) : stack(stack) {} + +ScreenStack::Ptr ScreenStack::new_instance() { + std::shared_ptr ptr = + std::shared_ptr(new ScreenStack{}); + ptr->self_weak = ptr; + return ptr; +} + +void ScreenStack::update(float dt) { + auto idx = stack.size(); + while (idx > 0 && stack.at(--idx)->update(dt)) { + } +} + +void ScreenStack::draw() { + auto idx = stack.size(); + while (idx > 0 && stack.at(--idx)->draw()) { + } +} + +void ScreenStack::push_screen(Screen::Ptr &&screen) { + stack.emplace_back(std::forward(screen)); +} + +void ScreenStack::pop_screen() { + if (!stack.empty()) { + stack.pop_back(); + } +} + +ScreenStack::ScreenStack() : self_weak(), stack() {} diff --git a/src/screen.h b/src/screen.h new file mode 100644 index 0000000..679ccd9 --- /dev/null +++ b/src/screen.h @@ -0,0 +1,81 @@ +#ifndef JUMPARTIFACT_DOT_COM_DEMO_0_SCREEN_H_ +#define JUMPARTIFACT_DOT_COM_DEMO_0_SCREEN_H_ + +#include +#include + +// Forward declaration. +class ScreenStack; + +class Screen { + public: + using Ptr = std::unique_ptr; + + template + static Ptr new_screen(std::weak_ptr stack); + + virtual ~Screen() {} + + // No copy. + Screen(const Screen&) = delete; + Screen& operator=(const Screen&) = delete; + + // Allow move. + Screen(Screen&&) = default; + Screen& operator=(Screen&&) = default; + + /// Return true if next screen should be updated. + virtual bool update(float dt) = 0; + /// Return true if next screen should be drawn. + virtual bool draw() = 0; + + protected: + Screen(std::weak_ptr stack); + + private: + std::weak_ptr stack; +}; + +class ScreenStack { + public: + using Ptr = std::shared_ptr; + using Weak = std::weak_ptr; + + static Ptr new_instance(); + + // No copy. + ScreenStack(const ScreenStack&) = delete; + ScreenStack& operator=(const ScreenStack&) = delete; + + // Allow move. + ScreenStack(ScreenStack&&) = default; + ScreenStack& operator=(ScreenStack&&) = default; + + void update(float dt); + void draw(); + + void push_screen(Screen::Ptr&& screen); + + template + void push_screen(); + + void pop_screen(); + + private: + ScreenStack(); + + Weak self_weak; + std::vector stack; +}; + +template +Screen::Ptr Screen::new_screen(std::weak_ptr stack) { + return std::unique_ptr(new SubScreen{stack}); +} + +template +void ScreenStack::push_screen() { + stack.emplace_back(Screen::new_screen(self_weak)); +} + +#endif diff --git a/src/screen_test.cc b/src/screen_test.cc new file mode 100644 index 0000000..0bf5569 --- /dev/null +++ b/src/screen_test.cc @@ -0,0 +1,28 @@ +#include "screen_test.h" + +// standard library includes +#include + +// third party includes +#include + +TestScreen::TestScreen(ScreenStack::Weak weak_ptr) + : Screen(weak_ptr), TEMP_cached_dt(0.0F) {} +TestScreen::~TestScreen() {} + +bool TestScreen::update(float dt) { + TEMP_cached_dt = dt; + return false; +} + +bool TestScreen::draw() { + std::string dt_string = + std::string("Delta-time: ") + std::to_string(TEMP_cached_dt); + + BeginDrawing(); + ClearBackground(BLACK); + DrawText("Testing...", 100, 100, 30, RAYWHITE); + DrawText(dt_string.c_str(), 100, 140, 30, RAYWHITE); + EndDrawing(); + return false; +} diff --git a/src/screen_test.h b/src/screen_test.h new file mode 100644 index 0000000..56469c5 --- /dev/null +++ b/src/screen_test.h @@ -0,0 +1,18 @@ +#ifndef JUMPARTIFACT_DOT_COM_DEMO_O_TEST_SCREEN_H_ +#define JUMPARTIFACT_DOT_COM_DEMO_O_TEST_SCREEN_H_ + +#include "screen.h" + +class TestScreen : public Screen { + public: + TestScreen(ScreenStack::Weak weak_ptr); + ~TestScreen() override; + + bool update(float dt) override; + bool draw() override; + + private: + float TEMP_cached_dt; +}; + +#endif diff --git a/wasm_build/Makefile b/wasm_build/Makefile index 482aae2..f4ffefe 100644 --- a/wasm_build/Makefile +++ b/wasm_build/Makefile @@ -7,11 +7,15 @@ endif SOURCES = \ ../src/main.cc \ ../src/ems.cc \ - ../src/game.cc + ../src/game.cc \ + ../src/screen.cc \ + ../src/screen_test.cc HEADERS = \ ../src/ems.h \ - ../src/game.h + ../src/game.h \ + ../src/screen.h \ + ../src/screen_test.h CXX = source ${HOME}/git/emsdk/emsdk_env.sh && em++