77#include < ftxui/component/component.hpp> // for Slider
88#include < ftxui/component/screen_interactive.hpp> // for ScreenInteractive
99
10+ #include < spdlog/sinks/base_sink.h>
1011#include < spdlog/spdlog.h>
1112
1213#include " bitmap.hpp"
@@ -87,13 +88,40 @@ struct Displayed_Menu
8788 ftxui::Component buttons;
8889};
8990
91+
92+ template <typename Mutex> class my_sink : public spdlog ::sinks::base_sink<Mutex>
93+ {
94+ public:
95+ my_sink () = default ;
96+ std::vector<std::string> event_log;
97+
98+ protected:
99+ void sink_it_ (const spdlog::details::log_msg &msg) override
100+ {
101+ spdlog::memory_buf_t formatted;
102+ spdlog::sinks::base_sink<Mutex>::formatter_->format (msg, formatted);
103+ event_log.insert (event_log.begin (), fmt::to_string (formatted));
104+ }
105+
106+ void flush_ () override {}
107+ };
108+
90109void game_iteration_canvas ()// NOLINT cognitive complexity
91110{
92111 auto game = make_game ();
93112
113+ // we want to take over as the main spdlog sink
114+ auto log_sink = std::make_shared<my_sink<std::mutex>>();
115+ // my_sink<std::mutex> log_sink;
116+ auto logger = std::make_shared<spdlog::logger>(" default" , log_sink);
117+ spdlog::set_default_logger (logger);
118+ spdlog::set_level (spdlog::level::trace);
119+
94120 Displayed_Menu current_menu{ Menu{}, game };
121+ bool show_log = false ;
95122
96123 auto clear_popup_button = ftxui::Button (" OK" , [&]() { game.popup_message .clear (); });
124+ auto close_log = ftxui::Button (" Close" , [&] { show_log = false ; });
97125
98126 // this should probably have a `bitmap` helper function that does what you expect
99127 // similar to the other parts of FTXUI
@@ -103,9 +131,8 @@ void game_iteration_canvas()// NOLINT cognitive complexity
103131 double fps = 0 ;
104132 auto start_time = std::chrono::steady_clock::now ();
105133
134+ std::vector<ftxui::Event> events;
106135
107- ftxui::Event last_event;
108- ftxui::Event current_event;
109136
110137 // to do, add total game time clock also, not just current elapsed time
111138 auto game_iteration = [&](const std::chrono::steady_clock::duration elapsed_time) {
@@ -121,16 +148,20 @@ void game_iteration_canvas()// NOLINT cognitive complexity
121148
122149 game.clock = game_clock;
123150
124- [&] {
125- if (game.has_menu ()) { return ; }
151+ while (!events.empty ()) {
152+ const auto current_event = events.front ();
153+ events.erase (events.begin ());
126154
127- if (current_event != last_event) {
155+ [&] {
128156 auto location = game.player .map_location ;
129157 const auto last_location = location;
130158
131159 Direction from{};
132160
133- if (current_event == ftxui::Event::ArrowUp) {
161+ if (current_event.is_character () && current_event.character () == " l" ) {
162+ show_log = true ;
163+ return ;
164+ } else if (current_event == ftxui::Event::ArrowUp) {
134165 --location.y ;
135166 from = Direction::South;
136167 } else if (current_event == ftxui::Event::ArrowDown) {
@@ -146,17 +177,20 @@ void game_iteration_canvas()// NOLINT cognitive complexity
146177 return ;
147178 }
148179
180+
149181 if (game.maps .at (game.current_map ).can_enter_from (game, location, from)) {
150182 auto exit_action = game.maps .at (game.current_map ).locations .at (last_location).exit_action ;
151183 if (exit_action) { exit_action (game, last_location, from); }
152184
153185 game.player .map_location = location;
154186
187+ spdlog::trace (" Moved to: {}, {}" , location.x , location.y );
188+
155189 auto enter_action = game.maps .at (game.current_map ).locations .at (location).enter_action ;
156190 if (enter_action) { enter_action (game, location, from); }
157191 }
158- }
159- }();
192+ }();
193+ }
160194
161195
162196 draw (*bm, game);
@@ -173,7 +207,7 @@ void game_iteration_canvas()// NOLINT cognitive complexity
173207 auto container = ftxui::Container::Vertical ({});
174208
175209 auto key_press = ftxui::CatchEvent (container, [&](const ftxui::Event &event) {
176- last_event = std::exchange (current_event, event);
210+ events. push_back ( event);
177211 return false ;
178212 });
179213
@@ -218,13 +252,24 @@ void game_iteration_canvas()// NOLINT cognitive complexity
218252 | ftxui::border;
219253 });
220254
255+ int selected_log_entry = 0 ;
256+ auto log_menu = ftxui::Menu (&log_sink->event_log , &selected_log_entry);
257+
258+ auto log_renderer = ftxui::Renderer (ftxui::Container::Vertical ({ log_menu, close_log }), [&] {
259+ return ftxui::vbox ({ log_menu->Render () | ftxui::vscroll_indicator | ftxui::frame
260+ | ftxui::size (ftxui::HEIGHT, ftxui::LESS_THAN, 15 ),// NOLINT magic numbers
261+ close_log->Render () })
262+ | ftxui::border;
263+ });
221264
222265 int depth = 0 ;
223266
224- auto main_container = ftxui::Container::Tab ({ game_renderer, menu_renderer, popup_renderer }, &depth);
267+ auto main_container = ftxui::Container::Tab ({ game_renderer, menu_renderer, popup_renderer, log_renderer }, &depth);
225268
226269 auto main_renderer = ftxui::Renderer (main_container, [&] {
227- if (game.has_popup_message ()) {
270+ if (show_log) {
271+ depth = 3 ;
272+ } else if (game.has_popup_message ()) {
228273 depth = 2 ;
229274 } else if (game.has_menu ()) {
230275 depth = 1 ;
@@ -252,6 +297,10 @@ void game_iteration_canvas()// NOLINT cognitive complexity
252297 }
253298 }
254299
300+ if (depth > 2 ) {
301+ document = ftxui::dbox ({ document, log_renderer->Render () | ftxui::clear_under | ftxui::center });
302+ }
303+
255304 return document;
256305 });
257306
@@ -290,6 +339,7 @@ int main(int argc, const char **argv)
290339 --version Show version.
291340)" ;
292341
342+
293343 std::map<std::string, docopt::value> args = docopt::docopt (USAGE,
294344 { std::next (argv), std::next (argv, argc) },
295345 true ,// show help if requested
0 commit comments