Skip to content

Commit

Permalink
ftxui moved to View; Publisher template; etc
Browse files Browse the repository at this point in the history
  • Loading branch information
r3w0p committed May 19, 2024
1 parent bc44642 commit 6276b8c
Show file tree
Hide file tree
Showing 10 changed files with 139 additions and 131 deletions.
10 changes: 7 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
# ---

Expand All @@ -94,8 +100,6 @@ target_link_libraries(caravan
PRIVATE model
PRIVATE user
PRIVATE view
PRIVATE ftxui::dom
PRIVATE ftxui::component
)
# ---

Expand Down
16 changes: 12 additions & 4 deletions include/caravan/core/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -122,4 +118,16 @@ bool is_numeral_card(Card c);

bool is_face_card(Card c);

/*
* CLASSES
*/

template <typename T>
class Publisher {
protected:
std::vector<T*> subscribers;
public:
void subscribe(T *sub);
};

#endif //CARAVAN_CORE_COMMON_H
8 changes: 6 additions & 2 deletions include/caravan/view/tui.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@
#include <string>
#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
21 changes: 16 additions & 5 deletions include/caravan/view/view.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,24 @@
#include <string>
#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<ViewSubscriber> {
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
57 changes: 1 addition & 56 deletions src/caravan/controller/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
5 changes: 5 additions & 0 deletions src/caravan/core/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<typename T>
void Publisher<T>::subscribe(T *sub) {
subscribers.push_back(sub);
}
66 changes: 10 additions & 56 deletions src/caravan/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,65 +2,19 @@
// The following code can be redistributed and/or
// modified under the terms of the GPL-3.0 License.

#include <memory> // for allocator, __shared_ptr_access
#include <string> // 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;
}
Empty file removed src/caravan/view/ftxui.cpp
Empty file.
82 changes: 82 additions & 0 deletions src/caravan/view/tui.cpp
Original file line number Diff line number Diff line change
@@ -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 <memory>
#include <string>

#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);
}
5 changes: 0 additions & 5 deletions src/caravan/view/view.cpp

This file was deleted.

0 comments on commit 6276b8c

Please sign in to comment.