diff --git a/Makefile b/Makefile index 2e9b647..69472cf 100644 --- a/Makefile +++ b/Makefile @@ -65,7 +65,7 @@ debug: build gdb --nx -x .gdbinit --ex run --args builddir/runtests debug_run: build - gdb --nx -x .gdbinit --batch --ex run --ex bt --ex q --args builddir/under_the_dome + gdb --nx -x .gdbinit --batch --ex run --ex bt --ex q --args builddir/multiscreen debug_walk: build test gdb --nx -x .gdbinit --batch --ex run --ex bt --ex q --args builddir/under_the_dome t diff --git a/meson.build b/meson.build index b207239..340c00a 100644 --- a/meson.build +++ b/meson.build @@ -140,3 +140,11 @@ executable('fragviewer', include_directories: inc_dirs, override_options: exe_defaults, dependencies: dependencies) + +executable('multiscreen', + [ 'tools/multiscreen.cpp' ], + cpp_args: cpp_args, + link_args: link_args, + include_directories: inc_dirs, + override_options: exe_defaults, + dependencies: dependencies) diff --git a/src/graphics/scene.cpp b/src/graphics/scene.cpp index cde8434..959ca2c 100644 --- a/src/graphics/scene.cpp +++ b/src/graphics/scene.cpp @@ -58,8 +58,6 @@ namespace scene { } void Engine::init() { - dbc::log($F("initialized scene with background {}", $scene.background)); - $gui.position(SCENE_VIEW_X, SCENE_VIEW_Y, SCENE_VIEW_WIDTH, SCENE_VIEW_HEIGHT); $gui.set($gui.MAIN, {$gui.$parser, guecs::THEME.TRANSPARENT}); auto& background = $gui.get($gui.MAIN); diff --git a/src/gui/fsm.cpp b/src/gui/fsm.cpp index 8c8c393..c6e4f85 100644 --- a/src/gui/fsm.cpp +++ b/src/gui/fsm.cpp @@ -49,8 +49,8 @@ namespace gui { $main_ui.init(); $loot_ui.init(); - for(auto& [name, scene] : $scenes) { - scene->init(); + for(auto& name : $screens.screens.keys()) { + $screens.screens[name]->init(); } // BUG: maybe this is a function on main_ui? @@ -326,8 +326,8 @@ namespace gui { void FSM::mouse_action(guecs::Modifiers mods) { sf::Vector2f pos = mouse_position(); - if($cur_scene != nullptr) { - $cur_scene->mouse(pos.x, pos.y, mods); + if($screens.is_visible()) { + $screens.mouse(pos.x, pos.y, mods); return; } @@ -415,8 +415,8 @@ namespace gui { } void FSM::draw_gui() { - if($cur_scene != nullptr) { - $cur_scene->render($window); + if($screens.is_visible()) { + $screens.render($window); } else if($story != nullptr) { $story->render($window); } else { @@ -432,8 +432,8 @@ namespace gui { } void FSM::update() { - if($cur_scene != nullptr) { - $cur_scene->update(); + if($screens.is_visible()) { + $screens.update(); } else if($story != nullptr) { $story->update(); } @@ -564,12 +564,12 @@ namespace gui { } void FSM::show_scene(const std::string& name) { - dbc::check($scenes.contains(name), $F("$scenes does not contain {}", name)); - $cur_scene = $scenes[name]; + $screens.set_active(name); + $screens.set_visible(true); } void FSM::close_scene() { - $cur_scene = nullptr; + $screens.set_visible(false); } void FSM::player_died() { @@ -584,7 +584,7 @@ namespace gui { if(level.index < levels_to_win) { show_scene("NEXT_LEVEL"); - $cur_scene->set_text(fmt::format("ENTERING\nLEVEL\n{}", level.index+2)); + $screens.current_ui()->set_text(fmt::format("ENTERING\nLEVEL\n{}", level.index+2)); state(State::NEXT_LEVEL_SCENE); } else { show_scene("WIN"); diff --git a/src/gui/fsm.hpp b/src/gui/fsm.hpp index f71806d..b97d9ae 100644 --- a/src/gui/fsm.hpp +++ b/src/gui/fsm.hpp @@ -13,6 +13,7 @@ #include "events.hpp" #include "gui/scene_ui.hpp" #include "gui/storyboard.hpp" +#include "gui/uistack.hpp" namespace gui { enum class State { @@ -43,14 +44,14 @@ namespace gui { gui::routing::Router $router; DNDLoot $dnd_loot; System::Registry $systems; - std::unordered_map> $scenes{ + + gui::UIStack $screens{.screens={ {"STARTING", std::make_shared("STARTING")}, {"DEATH", std::make_shared("DEATH")}, {"WIN", std::make_shared("WIN")}, {"NEXT_LEVEL", std::make_shared("NEXT_LEVEL")}, - }; + }}; - std::shared_ptr $cur_scene = nullptr; std::shared_ptr $story = nullptr; bool $display_help = false; diff --git a/src/gui/uistack.cpp b/src/gui/uistack.cpp new file mode 100644 index 0000000..63759a5 --- /dev/null +++ b/src/gui/uistack.cpp @@ -0,0 +1,6 @@ +#include "multiscreen.hpp" + +namespace gui { + using namespace std::chrono_literals; + +} diff --git a/src/gui/uistack.hpp b/src/gui/uistack.hpp new file mode 100644 index 0000000..384a12b --- /dev/null +++ b/src/gui/uistack.hpp @@ -0,0 +1,90 @@ +#include +#include "dbc.hpp" +#include "constants.hpp" +#include + +namespace gui { + template + struct UIStack { + using UIStackMap = std::flat_map>; + + UIStackMap screens{}; + bool visible = false; + + UIStackMap::iterator $current{screens.begin()}; + SCREEN_TYPE* $active = nullptr; + + void add(const std::string& name, std::shared_ptr screen) { + screens.insert_or_assign(name, screen); + update_active(screens.begin()); + } + + void update_active(const UIStackMap::iterator& itr) { + $current = itr; + $active = (*$current).second.get(); + } + + void set_active(const std::string& name) { + dbc::check(screens.contains(name), $F("screen {} not in stack", name)); + update_active(screens.find(name)); + } + + void set_visible(bool new_value) { + visible = new_value; + } + + bool is_visible() { + return visible; + } + + void render(sf::RenderTarget& target) { + dbc::check($active != nullptr, "you didn't set active"); + $active->render(target); + } + + void update() { + dbc::check($active != nullptr, "you didn't set active"); + $active->update(); + } + + bool mouse(float x, float y, guecs::Modifiers mods = guecs::NO_MODS) { + dbc::check($active != nullptr, "you didn't set active"); + return $active->mouse(x, y, mods); + } + + bool move(const UIStackMap::iterator& itr, const UIStackMap::iterator& avoid, const UIStackMap::iterator& result) { + if(itr != avoid) { + update_active(result); + return true; + } else { + return false; + } + } + + bool next() { + return move($current + 1, screens.end(), $current + 1); + } + + bool prev() { + return move($current, screens.begin(), $current - 1); + } + + void first() { + update_active(screens.begin()); + } + + void last() { + update_active(screens.end() - 1); + } + + const std::string& current_name() { + dbc::check($active != nullptr, "you didn't set active"); + return (*$current).first; + } + + std::shared_ptr current_ui() { + dbc::check($active != nullptr, "you didn't set active"); + return (*$current).second; + } + }; +}