From 6276b8c4f2a74ed1478cf87e9534edc9c1b39af1 Mon Sep 17 00:00:00 2001 From: r3w0p Date: Sun, 19 May 2024 22:59:45 +0100 Subject: [PATCH] ftxui moved to View; Publisher template; etc --- CMakeLists.txt | 10 +++- include/caravan/core/common.h | 16 ++++-- include/caravan/view/tui.h | 8 ++- include/caravan/view/view.h | 21 +++++-- src/caravan/controller/controller.cpp | 57 +------------------ src/caravan/core/common.cpp | 5 ++ src/caravan/main.cpp | 66 ++++----------------- src/caravan/view/ftxui.cpp | 0 src/caravan/view/tui.cpp | 82 +++++++++++++++++++++++++++ src/caravan/view/view.cpp | 5 -- 10 files changed, 139 insertions(+), 131 deletions(-) delete mode 100644 src/caravan/view/ftxui.cpp create mode 100644 src/caravan/view/tui.cpp delete mode 100644 src/caravan/view/view.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 421197e..97d571d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,9 +76,15 @@ add_library(user ) add_library(view + "include/caravan/view/tui.h" "include/caravan/view/view.h" - "src/caravan/view/view.cpp" + "src/caravan/view/tui.cpp" +) + +target_link_libraries(view + PRIVATE ftxui::dom + PRIVATE ftxui::component ) # --- @@ -94,8 +100,6 @@ target_link_libraries(caravan PRIVATE model PRIVATE user PRIVATE view - PRIVATE ftxui::dom - PRIVATE ftxui::component ) # --- diff --git a/include/caravan/core/common.h b/include/caravan/core/common.h index 77f8d82..bd39971 100644 --- a/include/caravan/core/common.h +++ b/include/caravan/core/common.h @@ -30,10 +30,6 @@ const uint8_t HAND_SIZE_MAX_POST_START = 5; const uint8_t HAND_POS_MIN = 1; const uint8_t TABLE_CARAVANS_MAX = 6; const uint8_t PLAYER_CARAVANS_MAX = 3; -const uint8_t VIEW_Y_MIN = 68; -const uint8_t VIEW_X_MIN = 106; - -const uint8_t VIEW_STDSCR_ROW_OPTION = 68; /* * ENUMS @@ -122,4 +118,16 @@ bool is_numeral_card(Card c); bool is_face_card(Card c); +/* + * CLASSES + */ + +template +class Publisher { +protected: + std::vector subscribers; +public: + void subscribe(T *sub); +}; + #endif //CARAVAN_CORE_COMMON_H diff --git a/include/caravan/view/tui.h b/include/caravan/view/tui.h index 3a5c1bb..b674ef6 100644 --- a/include/caravan/view/tui.h +++ b/include/caravan/view/tui.h @@ -8,10 +8,14 @@ #include #include "caravan/model/game.h" #include "caravan/user/user.h" +#include "caravan/view/view.h" -class TUI { +class TUI : public View { public: - explicit TUI(); + explicit TUI(User *utop, User *ubottom) : + View(utop, ubottom) {}; + + void run() override; }; #endif //CARAVAN_VIEW_TUI_H diff --git a/include/caravan/view/view.h b/include/caravan/view/view.h index 07fea0e..02bf7e6 100644 --- a/include/caravan/view/view.h +++ b/include/caravan/view/view.h @@ -8,13 +8,24 @@ #include #include "caravan/model/game.h" #include "caravan/user/user.h" +#include "caravan/core/common.h" -class View { +class ViewSubscriber { public: - virtual void update(Game *g, User *ubottom, User *utop, GameOption* go_bottom, GameOption* go_top) = 0; - virtual GameOption option(Game *g, User *u) = 0; - virtual void close() = 0; - virtual void error_message(std::string msg) = 0; + virtual void on_view_update() = 0; // TODO +}; + +class View : Publisher { +protected: + User *user_top_ptr; + User *user_bottom_ptr; + bool closed; +public: + explicit View(User *utop, User *ubottom) : + user_top_ptr(utop), user_bottom_ptr(ubottom), closed(false) {} + + virtual void run() = 0; + void close() { closed = true; }; }; #endif //CARAVAN_VIEW_H diff --git a/src/caravan/controller/controller.cpp b/src/caravan/controller/controller.cpp index 8f60261..d49bc56 100644 --- a/src/caravan/controller/controller.cpp +++ b/src/caravan/controller/controller.cpp @@ -7,60 +7,5 @@ void Controller::run() { - GameOption go_bottom; - GameOption go_top; - GameOption go_temp; - User *user_turn; - PlayerCaravanNames cvns; - - go_bottom = {NO_OPTION}; - go_top = {NO_OPTION}; - - do { - user_turn = game_ptr->get_player_turn() == user_a_ptr->get_name() ? - user_a_ptr : user_b_ptr; - - // Only update view if current user is a human - if (user_turn->is_human()) - view_ptr->update(game_ptr, user_a_ptr, user_b_ptr, - &go_bottom, &go_top); - - try { - // Get user's next move - if (user_turn->get_name() == PLAYER_BOTTOM) { - go_temp = go_bottom; - go_bottom = view_ptr->option(game_ptr, user_turn); - - // Immediately quit on exit request - if (go_bottom.type == OPTION_EXIT) - return; - - // Attempt to play user's desired move - game_ptr->play_option(&go_bottom); - - } else { - go_temp = go_top; - go_top = view_ptr->option(game_ptr, user_turn); - - // Immediately quit on exit request - if (go_top.type == OPTION_EXIT) - return; - - // Attempt to play user's desired move - game_ptr->play_option(&go_top); - } - - } catch (CaravanException &e) { - view_ptr->error_message(e.what()); - - if (user_turn->get_name() == PLAYER_BOTTOM) - go_bottom = go_temp; - else - go_top = go_temp; - } - - } while (game_ptr->get_winner() == NO_PLAYER); - - // Update one last time in order to display the winner - view_ptr->update(game_ptr, user_a_ptr, user_b_ptr, &go_bottom, &go_top); + // TODO } diff --git a/src/caravan/core/common.cpp b/src/caravan/core/common.cpp index 17d1047..9ade294 100644 --- a/src/caravan/core/common.cpp +++ b/src/caravan/core/common.cpp @@ -12,3 +12,8 @@ bool is_numeral_card(Card c) { bool is_face_card(Card c) { return (c.rank >= JACK and c.rank <= JOKER); } + +template +void Publisher::subscribe(T *sub) { + subscribers.push_back(sub); +} diff --git a/src/caravan/main.cpp b/src/caravan/main.cpp index 48985fc..0aed557 100644 --- a/src/caravan/main.cpp +++ b/src/caravan/main.cpp @@ -2,65 +2,19 @@ // The following code can be redistributed and/or // modified under the terms of the GPL-3.0 License. -#include // for allocator, __shared_ptr_access -#include // for char_traits, operator+, string, basic_string - -#include "ftxui/component/component.hpp" // for Input, Renderer, Vertical -#include "ftxui/component/component_options.hpp" // for InputOption -#include "ftxui/component/screen_interactive.hpp" // for Component, ScreenInteractive -#include "ftxui/dom/elements.hpp" // for text, hbox, separator, Element, operator|, vbox, border +#include "caravan/view/tui.h" +#include "caravan/user/bot_easy.h" int main() { - using namespace ftxui; - - // Input data - std::string user_input; - - // User input component - Component comp_user_input = Input(&user_input, "user_input"); - - // Ensure input is alphanumeric only - comp_user_input |= CatchEvent([&](Event event) { - return event.is_character() && !std::isalnum(event.character()[0]); - }); - - // Ensure maximum input length - comp_user_input |= CatchEvent([&](Event event) { - return event.is_character() && user_input.size() >= 5; // TODO what is max input size? - }); - - // Component tree - auto component = Container::Vertical({ - comp_user_input - }); - - // Tweak how the component tree is rendered: - auto renderer = Renderer(component, [&] { - auto terminal_size = Terminal::Size(); - auto min_terminal_x = 150; - auto min_terminal_y = 50; + auto *utop = new UserHuman(PLAYER_TOP); + auto *ubottom = new UserHuman(PLAYER_BOTTOM); + + auto *v = new TUI(utop, ubottom); - // Ensure minimum terminal dimensions - if (terminal_size.dimx < min_terminal_x || terminal_size.dimy < min_terminal_y) - return vbox({ - text("Terminal too small"), - separatorEmpty(), - text("Width: " + std::to_string(terminal_size.dimx) + " < " + std::to_string(min_terminal_x)), - text("Height: " + std::to_string(terminal_size.dimy) + " < " + std::to_string(min_terminal_y)), - separatorEmpty(), - text("Resize terminal or press Ctrl+C"), - }) | center; + v->run(); - // Generate game as normal - return vbox({ - hbox(text(" YOU > "), comp_user_input->Render()), - separator(), - text("Curr input: " + user_input), - text("Terminal: x=" + std::to_string(terminal_size.dimx) + " y=" + std::to_string(terminal_size.dimy)), - }) | border; - }); - - auto screen = ScreenInteractive::Fullscreen(); - screen.Loop(renderer); + delete v; + delete utop; + delete ubottom; } diff --git a/src/caravan/view/ftxui.cpp b/src/caravan/view/ftxui.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/src/caravan/view/tui.cpp b/src/caravan/view/tui.cpp new file mode 100644 index 0000000..acb91f8 --- /dev/null +++ b/src/caravan/view/tui.cpp @@ -0,0 +1,82 @@ +// Copyright (c) 2022-2024 r3w0p +// The following code can be redistributed and/or +// modified under the terms of the GPL-3.0 License. + +#include "caravan/user/user.h" +#include "caravan/view/view.h" +#include "caravan/view/tui.h" + +#include +#include + +#include "ftxui/component/component.hpp" +#include "ftxui/component/component_options.hpp" +#include "ftxui/component/screen_interactive.hpp" +#include "ftxui/dom/elements.hpp" + + +void TUI::run() { + using namespace ftxui; + + // Input data + std::string user_input; + std::string command; + + // User input component + Component comp_user_input = Input(&user_input, ""); + + // Ensure input is alphanumeric only + comp_user_input |= CatchEvent([&](Event event) { + return event.is_character() && !std::isalnum(event.character()[0]); + }); + + // Ensure maximum input length + comp_user_input |= CatchEvent([&](Event event) { + return event.is_character() && user_input.size() >= 5; // TODO what is max input size? + }); + + // Component tree + auto component = Container::Vertical({ comp_user_input }); + + // Tweak how the component tree is rendered: + auto renderer = Renderer(component, [&] { + auto terminal_size = Terminal::Size(); + auto min_terminal_x = 150; + auto min_terminal_y = 50; + + // Ensure minimum terminal dimensions + // TODO prevent user input change during this display + if (terminal_size.dimx < min_terminal_x || terminal_size.dimy < min_terminal_y) { + user_input = ""; + return vbox({ + text("Terminal too small"), + separatorEmpty(), + text("Width: " + std::to_string(terminal_size.dimx) + " < " + + std::to_string(min_terminal_x)), + text("Height: " + std::to_string(terminal_size.dimy) + " < " + + std::to_string(min_terminal_y)), + separatorEmpty(), + text("Resize terminal or press Ctrl+C"), + }) | center; + } + + if(user_input.ends_with('\n')) { + command = user_input; + user_input = ""; + } + + // TODO immediately wipe command once passed to controller + + // Generate game as normal + return vbox({ + hbox(text(" YOU > "), comp_user_input->Render()), + separator(), + text("Current: " + user_input), + text("Command: " + command), + text("Terminal: x=" + std::to_string(terminal_size.dimx) + " y=" + std::to_string(terminal_size.dimy)), + }) | border; + }); + + auto screen = ScreenInteractive::Fullscreen(); + screen.Loop(renderer); +} diff --git a/src/caravan/view/view.cpp b/src/caravan/view/view.cpp deleted file mode 100644 index 3b8b963..0000000 --- a/src/caravan/view/view.cpp +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright (c) 2022-2024 r3w0p -// The following code can be redistributed and/or -// modified under the terms of the GPL-3.0 License. - -#include "caravan/view/view.h"