main
Brett 2025-03-12 12:19:19 -04:00
parent 8c88c6296f
commit a968a285e7
5 changed files with 117 additions and 15 deletions

View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.20) cmake_minimum_required(VERSION 3.20)
include(cmake/color.cmake) include(cmake/color.cmake)
set(BLT_VERSION 5.2.14) set(BLT_VERSION 5.2.15)
set(BLT_TARGET BLT) set(BLT_TARGET BLT)

View File

@ -19,42 +19,85 @@
#ifndef BLT_LOGGING_STATUS_H #ifndef BLT_LOGGING_STATUS_H
#define BLT_LOGGING_STATUS_H #define BLT_LOGGING_STATUS_H
#include <mutex>
#include <string> #include <string>
#include <blt/logging/injector.h> #include <blt/logging/injector.h>
#include <blt/std/types.h>
#include <blt/math/vectors.h> #include <blt/math/vectors.h>
#include <blt/std/types.h>
namespace blt::logging namespace blt::logging
{ {
class status_bar_t;
class status_item_t class status_item_t
{ {
public: public:
virtual ~status_item_t() = default; virtual ~status_item_t() = default;
void assign(status_bar_t* bar)
{
m_status = bar;
}
[[nodiscard]] virtual i32 lines_used() const [[nodiscard]] virtual i32 lines_used() const
{ {
return 1; return 1;
} }
virtual std::string print() = 0; [[nodiscard]] virtual std::string print(vec2i screen_size, i32 max_printed_length) const = 0;
protected:
status_bar_t* m_status = nullptr;
};
class status_progress_bar_t final : public status_item_t
{
public:
[[nodiscard]] std::string print(vec2i screen_size, i32 max_printed_length) const override;
void set_progress(double progress);
void add_progress(const double progress)
{
set_progress(get_progress() + progress);
}
[[nodiscard]] double get_progress() const
{
return m_progress;
}
private:
double m_progress = 0.0;
}; };
class status_bar_t final : public injector_t class status_bar_t final : public injector_t
{ {
public: public:
explicit status_bar_t(i32 status_size); explicit status_bar_t();
injector_output_t inject(const std::string& input) override; injector_output_t inject(const std::string& input) override;
void redraw(); status_bar_t& add(status_item_t& item)
{
item.assign(this);
m_status_items.push_back(&item);
compute_size();
return *this;
}
void redraw() const;
~status_bar_t() override; ~status_bar_t() override;
private: private:
i32 m_status_size; void compute_size();
std::vector<status_item_t*> m_status_items;
i32 m_status_size = 0;
i32 m_max_printed_length = 0;
vec2i m_screen_size; vec2i m_screen_size;
vec2i m_last_log_position; vec2i m_last_log_position;
vec2i m_begin_position; vec2i m_begin_position;
std::mutex m_print_mutex;
}; };
} }

@ -1 +1 @@
Subproject commit 93201da2ba5a6aba0a6e57ada64973555629b3e3 Subproject commit 7ef2e733416953b222851f9a360d7fc72d068ee5

View File

@ -89,7 +89,7 @@ namespace blt::logging
changed.c_cc[VTIME] = 0; changed.c_cc[VTIME] = 0;
tcsetattr( STDIN_FILENO, TCSANOW, &changed); tcsetattr( STDIN_FILENO, TCSANOW, &changed);
// printf ( "\033[2J"); //clear screen printf ( "\033[2J"); //clear screen
printf ( "\033[9999;9999H"); // cursor should move as far as it can printf ( "\033[9999;9999H"); // cursor should move as far as it can
@ -115,7 +115,53 @@ namespace blt::logging
throw std::runtime_error("Could not get screen size"); throw std::runtime_error("Could not get screen size");
} }
status_bar_t::status_bar_t(const i32 status_size): m_status_size(status_size) i32 get_size_no_ansi(const std::string& str)
{
i32 size = 0;
for (size_t i = 0; i < str.size(); i++)
{
if (str[i] == BLT_ANSI_ESCAPE[0])
{
while (i < str.size())
{
if (std::isalpha(str[i++]))
break;
}
}
++size;
}
return size;
}
std::string status_progress_bar_t::print(const vec2i screen_size, const i32 max_printed_length) const
{
std::string output = "[";
output.reserve(max_printed_length);
const auto amount_filled = (max_printed_length - 2) * m_progress;
auto amount_filled_int = static_cast<i64>(amount_filled);
const auto frac = amount_filled - static_cast<double>(amount_filled_int);
for (i64 i = 0; i < amount_filled_int; i++)
output += '#';
if (frac >= 0.5)
{
output += '|';
++amount_filled_int;
}
for (i64 i = amount_filled_int; i < max_printed_length - 2; i++)
output += ' ';
output += ']';
return output;
}
void status_progress_bar_t::set_progress(const double progress)
{
m_progress = progress;
// m_status->redraw();
}
status_bar_t::status_bar_t()
{ {
m_screen_size = get_screen_size(); m_screen_size = get_screen_size();
std::cout << ansi::cursor::home << std::flush; std::cout << ansi::cursor::home << std::flush;
@ -126,6 +172,7 @@ namespace blt::logging
injector_output_t status_bar_t::inject(const std::string& input) injector_output_t status_bar_t::inject(const std::string& input)
{ {
std::scoped_lock lock{m_print_mutex};
injector_output_t output{input, false, false}; injector_output_t output{input, false, false};
if (output.new_logging_output.back() != '\n') if (output.new_logging_output.back() != '\n')
output.new_logging_output += '\n'; output.new_logging_output += '\n';
@ -137,19 +184,25 @@ namespace blt::logging
} }
std::cout << ansi::erase::entire_line << std::flush; std::cout << ansi::erase::entire_line << std::flush;
std::cout << output.new_logging_output << std::flush; std::cout << output.new_logging_output << std::flush;
m_max_printed_length = std::max(get_size_no_ansi(output.new_logging_output), m_max_printed_length);
m_last_log_position = get_cursor_position(); m_last_log_position = get_cursor_position();
redraw(); redraw();
return output; return output;
} }
void status_bar_t::redraw() void status_bar_t::compute_size()
{
m_status_size = 0;
for (const auto* ptr : m_status_items)
m_status_size += ptr->lines_used();
}
void status_bar_t::redraw() const
{ {
std::cout << ansi::cursor::move_to(m_last_log_position.x(), m_last_log_position.y()); std::cout << ansi::cursor::move_to(m_last_log_position.x(), m_last_log_position.y());
std::cout << ansi::erase::entire_line << std::flush; for (const auto* ptr : m_status_items)
std::cout << "[----status----]" << std::endl; std::cout << ansi::erase::entire_line << ptr->print(m_screen_size, m_max_printed_length) << std::endl;
std::cout << ansi::erase::entire_line << std::flush;
std::cout << "[----Second Line----]" << std::endl;
std::cout << std::flush; std::cout << std::flush;
} }

View File

@ -185,17 +185,23 @@ int main()
// //
// BLT_TRACE("Now time to test the logger status box"); // BLT_TRACE("Now time to test the logger status box");
blt::logging::status_bar_t status{2}; blt::logging::status_progress_bar_t progress;
blt::logging::status_bar_t status;
status.add(progress);
blt::logging::get_global_config().add_injector(status); blt::logging::get_global_config().add_injector(status);
progress.set_progress(1.0 / 103.0);
BLT_TRACE("Hello There!"); BLT_TRACE("Hello There!");
std::this_thread::sleep_for(std::chrono::milliseconds(1500)); std::this_thread::sleep_for(std::chrono::milliseconds(1500));
progress.set_progress(2.0 / 103.0);
BLT_TRACE("I am printing stuff!"); BLT_TRACE("I am printing stuff!");
std::this_thread::sleep_for(std::chrono::milliseconds(1500)); std::this_thread::sleep_for(std::chrono::milliseconds(1500));
progress.set_progress(3.0 / 103.0);
BLT_TRACE("How are you!?"); BLT_TRACE("How are you!?");
for (int i = 0; i < 100; i++) for (int i = 0; i < 100; i++)
{ {
progress.set_progress((4.0 + i) / 103.0);
BLT_INFO("I am printing some output {} times!", i + 1); 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(100));
} }