From 3f59528ecc11f3c8c821a71bef0ad9ec290a90a5 Mon Sep 17 00:00:00 2001 From: Brett Laptop Date: Mon, 10 Mar 2025 15:51:38 -0400 Subject: [PATCH] silly --- CMakeLists.txt | 2 +- include/blt/logging/ansi.h | 14 ++++- include/blt/logging/injector.h | 4 +- include/blt/logging/logging_config.h | 9 ++- include/blt/logging/status.h | 29 +++++++++ src/blt/logging/logging.cpp | 4 +- src/blt/logging/status.cpp | 90 +++++++++++++++++++++++++++- test.txt | 0 tests/logger_tests.cpp | 76 ++++++++++++++--------- 9 files changed, 188 insertions(+), 40 deletions(-) create mode 100644 test.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 7c65b6c..30af81c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.20) include(cmake/color.cmake) -set(BLT_VERSION 5.2.10) +set(BLT_VERSION 5.2.11) set(BLT_TARGET BLT) diff --git a/include/blt/logging/ansi.h b/include/blt/logging/ansi.h index d07c7f1..22b4cd9 100644 --- a/include/blt/logging/ansi.h +++ b/include/blt/logging/ansi.h @@ -249,8 +249,12 @@ namespace blt::logging::ansi namespace cursor { inline const std::string home = BLT_ANSI_CSI "H"; + inline const std::string lower_left_corner = BLT_ANSI_ESCAPE " F"; + inline const std::string hide_cursor = BLT_ANSI_CSI "?2 5l"; + inline const std::string show_cursor = BLT_ANSI_CSI "?2 5h"; + inline const std::string report_position = BLT_ANSI_CSI "6n"; - template + template std::string move_to(const i64 line, const i64 column) { if constexpr (UseH) @@ -302,6 +306,14 @@ namespace blt::logging::ansi inline const std::string restore_cursor_position_sco = BLT_ANSI_CSI "u"; } + namespace scroll + { + inline std::string scroll_up(const int lines) + { + return std::string(BLT_ANSI_CSI) + std::to_string(lines) + "S"; + }; + } + namespace erase { inline const std::string to_end_of_screen = BLT_ANSI_CSI "0J"; diff --git a/include/blt/logging/injector.h b/include/blt/logging/injector.h index 313f5bd..2d886ed 100644 --- a/include/blt/logging/injector.h +++ b/include/blt/logging/injector.h @@ -25,9 +25,9 @@ namespace blt::logging { std::string new_logging_output; // should we continue processing the injector call chain? - bool should_continue; + bool should_continue = true; // should we log the resulting string at the end of the injector call chain? If false for any injector, it becomes false for all injectors. - bool should_log; + bool should_log = true; }; class injector_t diff --git a/include/blt/logging/logging_config.h b/include/blt/logging/logging_config.h index b9b09f8..8acf31b 100644 --- a/include/blt/logging/logging_config.h +++ b/include/blt/logging/logging_config.h @@ -20,7 +20,6 @@ #define BLT_LOGGING_LOGGING_CONFIG_H #include -#include #include #include #include @@ -140,9 +139,9 @@ namespace blt::logging return *this; } - logging_config_t& add_injector(injector_t* injector) + logging_config_t& add_injector(injector_t& injector) { - m_injectors.push_back(std::unique_ptr(injector)); + m_injectors.push_back(&injector); return *this; } @@ -206,13 +205,13 @@ namespace blt::logging std::optional generate(const std::string& user_str, const std::string& thread_name, log_level_t level, const char* file, i32 line) const; - [[nodiscard]] const std::vector>& get_injectors() const + [[nodiscard]] const std::vector& get_injectors() const { return m_injectors; } private: - std::vector> m_injectors; + std::vector m_injectors; // wrappers for streams exist in blt/fs/stream_wrappers.h std::vector m_log_outputs = get_default_log_outputs(); std::string m_log_format = get_default_log_format(); diff --git a/include/blt/logging/status.h b/include/blt/logging/status.h index 3f0b999..8644888 100644 --- a/include/blt/logging/status.h +++ b/include/blt/logging/status.h @@ -19,9 +19,38 @@ #ifndef BLT_LOGGING_STATUS_H #define BLT_LOGGING_STATUS_H +#include +#include +#include + namespace blt::logging { + class status_item_t + { + public: + virtual ~status_item_t() = default; + + [[nodiscard]] virtual i32 lines_used() const + { + return 1; + } + + virtual std::string print(); + }; + + class status_bar_t final : public injector_t + { + public: + explicit status_bar_t(i32 status_size); + + injector_output_t inject(const std::string& input) override; + + virtual ~status_bar_t() override; + private: + i32 m_status_size; + }; + } #endif //BLT_LOGGING_STATUS_H diff --git a/src/blt/logging/logging.cpp b/src/blt/logging/logging.cpp index a668d0f..67e5a66 100644 --- a/src/blt/logging/logging.cpp +++ b/src/blt/logging/logging.cpp @@ -225,11 +225,11 @@ namespace blt::logging for (const auto& injector : config.get_injectors()) { auto [new_logging_output, should_continue, should_log] = injector->inject(str); - if (!should_continue) - break; if (!should_log) should_print = false; str = std::move(new_logging_output); + if (!should_continue) + break; } } if (should_print) diff --git a/src/blt/logging/status.cpp b/src/blt/logging/status.cpp index 8fc772b..aa73d26 100644 --- a/src/blt/logging/status.cpp +++ b/src/blt/logging/status.cpp @@ -15,9 +15,97 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ +#include +#include +#include +#include +#include +#include #include +#include namespace blt::logging { + vec2i get_cursor_position() + { + termios save{}, raw{}; -} \ No newline at end of file + tcgetattr(0, &save); + cfmakeraw(&raw); + tcsetattr(0,TCSANOW, &raw); + + char buf[32]; + char cmd[] = "\033[6n"; + + int row = 0; + int col = 0; + + if (isatty(fileno(stdin))) + { + write(1, cmd, sizeof(cmd)); + read(0, buf, sizeof(buf)); + + int sep = 0; + int end = 0; + for (int i = 2; i < 8; i++) + { + if (buf[i] == ';') + sep = i; + if (buf[i] == 'R') + { + end = i; + break; + } + } + row = std::stoi(std::string(buf + 2, buf + sep)); + col = std::stoi(std::string(buf + sep + 1, buf + end)); + // printf("{Row: %d, Col: %d}", row, col); + } + + tcsetattr(0,TCSANOW, &save); + + return vec2i{row, col}; + } + + vec2i get_screen_size() + { + std::cout << ansi::cursor::move_to(9999, 9999); + const auto pos = get_cursor_position(); + std::cout << ansi::cursor::lower_left_corner; + std::cout << " "; + return pos; + } + + status_bar_t::status_bar_t(const i32 status_size): m_status_size(status_size) + { + std::cout << ansi::cursor::hide_cursor; + } + + std::string status_item_t::print() + {} + + injector_output_t status_bar_t::inject(const std::string& input) + { + injector_output_t output{input, false, false}; + + std::cout << ansi::cursor::lower_left_corner; + std::cout << ansi::scroll::scroll_up(1); + for (int i = 0; i < m_status_size; i++) + std::cout << ansi::erase::entire_line << ansi::cursor::move_begin_up(1); + std::cout << output.new_logging_output; + std::cout << ansi::erase::entire_line; + std::cout << "[----status----]"; + std::cout << ansi::cursor::move_begin_down(1) << ansi::erase::entire_line; + std::cout << "[----Second Line----]"; + std::cout << std::flush; + + return output; + } + + status_bar_t::~status_bar_t() + { + // std::cout << "\033[" << m_scrolling_region + 1 << ";1H"; + std::cout << ansi::cursor::lower_left_corner; + std::cout << ansi::cursor::show_cursor; + } +} diff --git a/test.txt b/test.txt new file mode 100644 index 0000000..e69de29 diff --git a/tests/logger_tests.cpp b/tests/logger_tests.cpp index 6741770..319d3cb 100644 --- a/tests/logger_tests.cpp +++ b/tests/logger_tests.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -131,31 +132,31 @@ int main() blt::logging::println(ss, "This is a println with fill no alignment {:%20} end value", 46); blt::logging::println(ss, "This is a println with arg reference {0:{1}.{2}f}", 46.0232, 20, 2); blt::logging::println(ss, "This is a println with arg reference {0:&{1}}", "", 20); - blt::logging::print(ss.str()); + // blt::logging::print(ss.str()); auto [passed, error_msg] = compare_strings(expected_str, ss.str()); BLT_ASSERT_MSG(passed && "Logger logged string doesn't match precomputed expected string!", error_msg.c_str()); namespace ansi = blt::logging::ansi; namespace color = ansi::color; - for (blt::u8 r = 0; r < 6; r++) - { - for (blt::u8 g = 0; g < 6; g++) - { - for (blt::u8 b = 0; b < 6; b++) - { - blt::logging::println("{}This is a println with a color {:#3x} {:#3x} {:#3x}{}", - build(fg(color::color256{r, g, b}), bg(color::color256{ - static_cast(5 - r), - static_cast(5 - g), - static_cast(5 - b) - })), r, g, b, build(color::color_mode::RESET_ALL)); - } - } - } - blt::logging::println("{}This is a color now with background{}", - build(color::color_mode::BOLD, fg(color::color8::RED), color::color_mode::DIM, bg(color::color_rgb(0, 100, 255))), - build(color::color_mode::RESET_ALL)); + // for (blt::u8 r = 0; r < 6; r++) + // { + // for (blt::u8 g = 0; g < 6; g++) + // { + // for (blt::u8 b = 0; b < 6; b++) + // { + // blt::logging::println("{}This is a println with a color {:#3x} {:#3x} {:#3x}{}", + // build(fg(color::color256{r, g, b}), bg(color::color256{ + // static_cast(5 - r), + // static_cast(5 - g), + // static_cast(5 - b) + // })), r, g, b, build(color::color_mode::RESET_ALL)); + // } + // } + // } + // blt::logging::println("{}This is a color now with background{}", + // build(color::color_mode::BOLD, fg(color::color8::RED), color::color_mode::DIM, bg(color::color_rgb(0, 100, 255))), + // build(color::color_mode::RESET_ALL)); std::ofstream os("test.txt"); @@ -171,17 +172,36 @@ int main() writer.write("What about just a new line character?\n"); size_t charCount = 0; - blt::logging::println("Logged {} characters", charCount); + // blt::logging::println("Logged {} characters", charCount); + // + // BLT_TRACE("Hello this is am empty trace!"); + // BLT_TRACE("This is a trace with data {} {} {}", "bad at code", 413, "boy"); + // + // BLT_DEBUG("This is complete? {}", "this is working!"); + // BLT_INFO("Hello there!"); + // BLT_WARN("This is a warning!"); + // BLT_ERROR("This is an error!"); + // BLT_FATAL("This is a fatal error!"); + // BLT_TRACE("This is a pointer {:f}", &charCount); + // + // BLT_TRACE("Now time to test the logger status box"); - BLT_TRACE("Hello this is am empty trace!"); - BLT_TRACE("This is a trace with data {} {} {}", "bad at code", 413, "boy"); + blt::logging::status_bar_t status{2}; + blt::logging::get_global_config().add_injector(status); - BLT_DEBUG("This is complete? {}", "this is working!"); - BLT_INFO("Hello there!"); - BLT_WARN("This is a warning!"); - BLT_ERROR("This is an error!"); - BLT_FATAL("This is a fatal error!"); - BLT_TRACE("This is a pointer {:f}", &charCount); + BLT_TRACE("Hello There!"); + std::this_thread::sleep_for(std::chrono::milliseconds(1500)); + BLT_TRACE("I am printing stuff!"); + std::this_thread::sleep_for(std::chrono::milliseconds(1500)); + BLT_TRACE("How are you!?"); + + for (int i = 0; i < 100; i++) + { + BLT_INFO("I am printing some output {} times!", i + 1); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + + std::this_thread::sleep_for(std::chrono::milliseconds(5000)); /*std::cout << "\033[2J"; constexpr int totalRows = 24;