diff --git a/dbc.hpp b/dbc.hpp index a964b75..759793b 100644 --- a/dbc.hpp +++ b/dbc.hpp @@ -1,3 +1,5 @@ +#pragma once + #include #include #include diff --git a/escape_turings_tarpit.cpp b/escape_turings_tarpit.cpp index 32cf91f..5bcf2ad 100644 --- a/escape_turings_tarpit.cpp +++ b/escape_turings_tarpit.cpp @@ -1,4 +1,5 @@ #include "dbc.hpp" +#include "gui.hpp" #include "game_engine.hpp" #include // for milliseconds #include @@ -35,14 +36,8 @@ namespace fs = std::filesystem; const auto ERROR = fmt::emphasis::bold | fg(fmt::color::red); -vector lines; - #define BUF_MAX 1024 -void output(const string &msg) { - lines.push_back(msg); -} - class UpdateListener : public efsw::FileWatchListener { public: bool changes = false; @@ -131,88 +126,6 @@ void run_build(GameEngine &game, const char* command) { } -ButtonOption Style() { - auto option = ButtonOption::Animated(); - option.transform = [](const EntryState& s) { - auto element = paragraph(s.label); - if (s.focused) { - element |= bold; - } - return element | center | borderEmpty | flex; - }; - return option; -} - -int main_loop(UpdateListener* listener, efsw::FileWatcher* fileWatcher, GameEngine &game, const char *build_cmd) { - auto screen = ScreenInteractive::Fullscreen(); - screen.TrackMouse(true); - - // Create a component counting the number of frames drawn and event handled. - float scroll_x = 0.1; - float scroll_y = 1.0; - - auto status = Renderer([&] { - return vbox({ - paragraph(fmt::format("HP {}", game.hit_points)), - separator(), - hbox({ - text("HP"), - gauge(game.hit_points / 100.0f), - }), - }); - }); - - auto content = Renderer([&] { - vector output; - - for(const auto line : lines) { - output.push_back(text(line)); - } - - return vbox(output); - }); - - auto scrollable_content = Renderer(content, - [&, content] { - return content->Render() - | focusPositionRelative(scroll_x, scroll_y) - | frame | flex; - }); - - auto component = Renderer(scrollable_content, [&] { - return vbox({ - status->Render(), - separator(), - scrollable_content->Render() | vscroll_indicator | yframe | size(HEIGHT, LESS_THAN, 20), - }) | - border; - }); - - component |= CatchEvent([&](Event) -> bool { - return false; - }); - - Loop loop(&screen, component); - - while (!loop.HasQuitted()) { - fileWatcher->watch(); - - if(listener->changes) { - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - output(format("CHANGES! Running build {}", build_cmd)); - run_build(game, build_cmd); - listener->reset_state(); - } - - loop.RunOnce(); - screen.Post(Event::Custom); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - - return EXIT_SUCCESS; -} - - int main(int argc, char *argv[]) { git_repository* repo = nullptr; @@ -239,7 +152,18 @@ int main(int argc, char *argv[]) GameEngine game{100}; - int rc = main_loop(listener, fileWatcher, game, build_cmd); + int rc = main_loop(game, [&] { + fileWatcher->watch(); + + if(listener->changes) { + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + output(format("CHANGES! Running build {}", build_cmd)); + run_build(game, build_cmd); + listener->reset_state(); + } + return 0; + }); + dbc::check(rc == 0, "Invalid return from main_loop."); git_libgit2_shutdown(); diff --git a/game_engine.hpp b/game_engine.hpp index abbf3d4..1311c0f 100644 --- a/game_engine.hpp +++ b/game_engine.hpp @@ -1,3 +1,5 @@ +#pragma once + #include #include #include diff --git a/gui.cpp b/gui.cpp new file mode 100644 index 0000000..7faa860 --- /dev/null +++ b/gui.cpp @@ -0,0 +1,99 @@ +#include "gui.hpp" +#include // for EXIT_SUCCESS +#include // for milliseconds +#include +#include // for Event +#include // for ftxui +#include // for text, separator, Element, operator|, vbox, border +#include // for allocator, shared_ptr +#include // for operator+, to_string +#include // for sleep_for + +#include "ftxui/component/component.hpp" // for CatchEvent, Renderer, operator|= +#include "ftxui/component/loop.hpp" // for Loop +#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive +#include + +using namespace ftxui; +using namespace std; +using namespace fmt; +namespace fs = std::filesystem; + +vector lines; + +void output(const string &msg) { + lines.push_back(msg); +} + +ButtonOption Style() { + auto option = ButtonOption::Animated(); + option.transform = [](const EntryState& s) { + auto element = paragraph(s.label); + if (s.focused) { + element |= bold; + } + return element | center | borderEmpty | flex; + }; + return option; +} + +int main_loop(GameEngine &game, std::function runner) { + auto screen = ScreenInteractive::Fullscreen(); + screen.TrackMouse(true); + + // Create a component counting the number of frames drawn and event handled. + float scroll_x = 0.1; + float scroll_y = 1.0; + + auto status = Renderer([&] { + return vbox({ + paragraph(fmt::format("HP {}", game.hit_points)), + separator(), + hbox({ + text("HP"), + gauge(game.hit_points / 100.0f), + }), + }); + }); + + auto content = Renderer([&] { + vector output; + + for(const auto line : lines) { + output.push_back(text(line)); + } + + return vbox(output); + }); + + auto scrollable_content = Renderer(content, + [&, content] { + return content->Render() + | focusPositionRelative(scroll_x, scroll_y) + | frame | flex; + }); + + auto component = Renderer(scrollable_content, [&] { + return vbox({ + status->Render(), + separator(), + scrollable_content->Render() | vscroll_indicator | yframe | size(HEIGHT, LESS_THAN, 20), + }) | + border; + }); + + component |= CatchEvent([&](Event) -> bool { + return false; + }); + + Loop loop(&screen, component); + + while (!loop.HasQuitted()) { + int run_error = runner(); + loop.RunOnce(); + screen.Post(Event::Custom); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + + return EXIT_SUCCESS; +} diff --git a/gui.hpp b/gui.hpp new file mode 100644 index 0000000..e29d1b0 --- /dev/null +++ b/gui.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include +#include "game_engine.hpp" +#include +#include + +void output(const string &msg); + +int main_loop(GameEngine &game, std::function runner); diff --git a/meson.build b/meson.build index 73e5c78..da24eeb 100644 --- a/meson.build +++ b/meson.build @@ -29,6 +29,7 @@ dependencies = [ executable('escape_turings_tarpit', ['game_engine.cpp', + 'gui.cpp', 'escape_turings_tarpit.cpp'], dependencies: dependencies)