Extract progress scale writing code into separate classes

This commit is contained in:
hyperxor
2020-01-21 07:49:47 +03:00
parent d4dea6db2a
commit 0939406db4
4 changed files with 84 additions and 35 deletions

View File

@@ -26,20 +26,18 @@ SOFTWARE.
*/ */
#pragma once #pragma once
#include <indicators/color.hpp>
#include <indicators/details/stream_helper.hpp> #include <indicators/details/stream_helper.hpp>
#define NOMINMAX #define NOMINMAX
#include <algorithm> #include <algorithm>
#include <atomic> #include <atomic>
#include <chrono> #include <chrono>
#include <cmath>
#include <indicators/color.hpp>
#include <iomanip> #include <iomanip>
#include <iostream> #include <iostream>
#include <mutex> #include <mutex>
#include <string> #include <string>
#include <thread> #include <thread>
#include <vector>
namespace indicators { namespace indicators {
@@ -124,9 +122,6 @@ private:
size_t _bar_width{100}; size_t _bar_width{100};
std::string _prefix_text{""}; std::string _prefix_text{""};
std::string _start{"["}; std::string _start{"["};
std::string _fill{""};
std::string _lead{" "};
std::string _remainder{" "};
std::string _end{"]"}; std::string _end{"]"};
std::string _postfix_text{""}; std::string _postfix_text{""};
std::atomic<size_t> _max_postfix_text_length{0}; std::atomic<size_t> _max_postfix_text_length{0};
@@ -165,19 +160,8 @@ private:
std::cout << _prefix_text; std::cout << _prefix_text;
std::cout << _start; std::cout << _start;
std::vector<std::string> lead_characters{" ", "", "", "", "", "", "", ""}; details::BlockProgressScaleWriter writer{std::cout, _bar_width};
auto progress = std::min(1.0f, std::max(0.0f, _progress / 100.0f)); writer.write(_progress);
auto whole_width = std::floor(progress * _bar_width);
auto remainder_width = fmod((progress * _bar_width), 1.0f);
auto part_width = std::floor(remainder_width * lead_characters.size());
_lead = lead_characters[size_t(part_width)];
if ((_bar_width - whole_width - 1) < 0)
_lead = "";
for (size_t i = 0; i < whole_width; ++i)
std::cout << _fill;
std::cout << _lead;
for (size_t i = 0; i < (_bar_width - whole_width - 1); ++i)
std::cout << " ";
std::cout << _end; std::cout << _end;
if (_show_percentage) { if (_show_percentage) {
@@ -186,7 +170,7 @@ private:
if (_show_elapsed_time) { if (_show_elapsed_time) {
std::cout << " ["; std::cout << " [";
details::print_duration(std::cout, elapsed); details::write_duration(std::cout, elapsed);
} }
if (_show_remaining_time) { if (_show_remaining_time) {
@@ -197,7 +181,7 @@ private:
auto eta = std::chrono::nanoseconds( auto eta = std::chrono::nanoseconds(
_progress > 0 ? static_cast<long long>(elapsed.count() * 100 / _progress) : 0); _progress > 0 ? static_cast<long long>(elapsed.count() * 100 / _progress) : 0);
auto remaining = eta > elapsed ? (eta - elapsed) : (elapsed - eta); auto remaining = eta > elapsed ? (eta - elapsed) : (elapsed - eta);
details::print_duration(std::cout, remaining); details::write_duration(std::cout, remaining);
std::cout << "]"; std::cout << "]";
} else { } else {
if (_show_elapsed_time) if (_show_elapsed_time)

View File

@@ -3,11 +3,15 @@
#include <indicators/color.hpp> #include <indicators/color.hpp>
#include <indicators/termcolor.hpp> #include <indicators/termcolor.hpp>
#include <algorithm>
#include <chrono> #include <chrono>
#include <iomanip> #include <iomanip>
#include <ostream> #include <ostream>
#include <string>
#include <vector>
#include <cassert> #include <cassert>
#include <cmath>
namespace indicators { namespace indicators {
namespace details { namespace details {
@@ -43,7 +47,7 @@ inline void set_stream_color(std::ostream &os, Color color) {
} }
} }
std::ostream &print_duration(std::ostream &os, std::chrono::nanoseconds ns) { inline std::ostream &write_duration(std::ostream &os, std::chrono::nanoseconds ns) {
using namespace std; using namespace std;
using namespace std::chrono; using namespace std::chrono;
using days = duration<int, ratio<86400>>; using days = duration<int, ratio<86400>>;
@@ -65,5 +69,69 @@ std::ostream &print_duration(std::ostream &os, std::chrono::nanoseconds ns) {
return os; return os;
}; };
class BlockProgressScaleWriter
{
public:
BlockProgressScaleWriter(std::ostream& os, size_t bar_width)
: os(os)
, bar_width(bar_width)
{}
std::ostream &write(float progress) {
std::string fill_text{""};
std::vector<std::string> lead_characters{" ", "", "", "", "", "", "", ""};
auto value = std::min(1.0f, std::max(0.0f, progress / 100.0f));
auto whole_width = std::floor(value * bar_width);
auto remainder_width = fmod((value * bar_width), 1.0f);
auto part_width = std::floor(remainder_width * lead_characters.size());
std::string lead_text = lead_characters[size_t(part_width)];
if ((bar_width - whole_width - 1) < 0)
lead_text = "";
for (size_t i = 0; i < whole_width; ++i)
os << fill_text;
os << lead_text;
for (size_t i = 0; i < (bar_width - whole_width - 1); ++i)
os << " ";
}
private:
std::ostream& os;
size_t bar_width = 0;
};
class ProgressScaleWriter
{
public:
ProgressScaleWriter(std::ostream& os,
size_t bar_width,
std::string fill,
std::string lead,
std::string remainder)
: os(os)
, bar_width(bar_width)
, fill(fill)
, lead(lead)
, remainder(remainder)
{}
std::ostream &write(float progress) {
auto pos = static_cast<size_t>(progress * static_cast<float>(bar_width) / 100.0);
for (size_t i = 0; i < bar_width; ++i) {
if (i < pos)
std::cout << fill;
else if (i == pos)
std::cout << lead;
else
std::cout << remainder;
}
}
private:
std::ostream& os;
size_t bar_width = 0;
std::string fill;
std::string lead;
std::string remainder;
};
} }
} }

View File

@@ -177,24 +177,21 @@ private:
std::cout << termcolor::bold; std::cout << termcolor::bold;
details::set_stream_color(std::cout, _foreground_color); details::set_stream_color(std::cout, _foreground_color);
std::cout << _prefix_text; std::cout << _prefix_text;
std::cout << _start; std::cout << _start;
auto pos = static_cast<size_t>(_progress * static_cast<float>(_bar_width) / 100.0);
for (size_t i = 0; i < _bar_width; ++i) { details::ProgressScaleWriter writer{std::cout, _bar_width, _fill, _lead, _remainder};
if (i < pos) writer.write(_progress);
std::cout << _fill;
else if (i == pos)
std::cout << _lead;
else
std::cout << _remainder;
}
std::cout << _end; std::cout << _end;
if (_show_percentage) { if (_show_percentage) {
std::cout << " " << std::min(static_cast<size_t>(_progress), size_t(100)) << "%"; std::cout << " " << std::min(static_cast<size_t>(_progress), size_t(100)) << "%";
} }
if (_show_elapsed_time) { if (_show_elapsed_time) {
std::cout << " ["; std::cout << " [";
details::print_duration(std::cout, elapsed); details::write_duration(std::cout, elapsed);
} }
if (_show_remaining_time) { if (_show_remaining_time) {
@@ -205,7 +202,7 @@ private:
auto eta = std::chrono::nanoseconds( auto eta = std::chrono::nanoseconds(
_progress > 0 ? static_cast<long long>(elapsed.count() * 100 / _progress) : 0); _progress > 0 ? static_cast<long long>(elapsed.count() * 100 / _progress) : 0);
auto remaining = eta > elapsed ? (eta - elapsed) : (elapsed - eta); auto remaining = eta > elapsed ? (eta - elapsed) : (elapsed - eta);
details::print_duration(std::cout, remaining); details::write_duration(std::cout, remaining);
std::cout << "]"; std::cout << "]";
} else { } else {
if (_show_elapsed_time) if (_show_elapsed_time)

View File

@@ -153,7 +153,7 @@ private:
if (_show_elapsed_time) { if (_show_elapsed_time) {
std::cout << " ["; std::cout << " [";
details::print_duration(std::cout, elapsed); details::write_duration(std::cout, elapsed);
} }
if (_show_remaining_time) { if (_show_remaining_time) {
@@ -164,7 +164,7 @@ private:
auto eta = std::chrono::nanoseconds( auto eta = std::chrono::nanoseconds(
_progress > 0 ? static_cast<long long>(elapsed.count() * 100 / _progress) : 0); _progress > 0 ? static_cast<long long>(elapsed.count() * 100 / _progress) : 0);
auto remaining = eta > elapsed ? (eta - elapsed) : (elapsed - eta); auto remaining = eta > elapsed ? (eta - elapsed) : (elapsed - eta);
details::print_duration(std::cout, remaining); details::write_duration(std::cout, remaining);
std::cout << "]"; std::cout << "]";
} else { } else {
if (_show_elapsed_time) if (_show_elapsed_time)