aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2025-04-04 15:23:50 +0200
committerGitHub Enterprise <[email protected]>2025-04-04 15:23:50 +0200
commitd142c80beb9cc5c43192ba978198280906c5bd39 (patch)
tree6f26fbb7807f5bfcf630e741d0eda53b13bc8068 /src
parentblobstore size limit (#342) (diff)
downloadzen-d142c80beb9cc5c43192ba978198280906c5bd39.tar.xz
zen-d142c80beb9cc5c43192ba978198280906c5bd39.zip
progress bar improvements (#346)
* hide ETA until at least 5% is complete * dynamically adjust progres output length
Diffstat (limited to 'src')
-rw-r--r--src/zen/zen.cpp100
1 files changed, 82 insertions, 18 deletions
diff --git a/src/zen/zen.cpp b/src/zen/zen.cpp
index 6f831349b..50ee43341 100644
--- a/src/zen/zen.cpp
+++ b/src/zen/zen.cpp
@@ -58,7 +58,8 @@ ZEN_THIRD_PARTY_INCLUDES_END
#include <zencore/memory/newdelete.h>
-#ifndef ZEN_PLATFORM_WINDOWS
+#if ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC
+# include <sys/ioctl.h>
# include <unistd.h>
#endif
@@ -329,29 +330,92 @@ ProgressBar::UpdateState(const State& NewState, bool DoLinebreak)
{
size_t ProgressBarSize = 20;
- size_t ProgressBarCount = (ProgressBarSize * PercentDone) / 100;
- uint64_t Completed = NewState.TotalCount - NewState.RemainingCount;
- uint64_t ETAMS = (Completed > 0) ? (ElapsedTimeMS * NewState.RemainingCount) / Completed : 0;
- std::string ETA = (ETAMS > 0) ? fmt::format(" ETA {}", NiceTimeSpanMs(ETAMS)) : "";
-
- std::string Output = fmt::format("\r{} {:#3}%: |{}{}|: {}{}{}",
- NewState.Task,
- PercentDone,
- std::string(ProgressBarCount, '#'),
- std::string(ProgressBarSize - ProgressBarCount, ' '),
- NiceTimeSpanMs(ElapsedTimeMS),
- ETA,
- NewState.Details.empty() ? "" : fmt::format(". {}", NewState.Details));
+ size_t ProgressBarCount = (ProgressBarSize * PercentDone) / 100;
+ uint64_t Completed = NewState.TotalCount - NewState.RemainingCount;
+ uint64_t ETAMS = (PercentDone > 5) ? (ElapsedTimeMS * NewState.RemainingCount) / Completed : 0;
+
+#if ZEN_PLATFORM_WINDOWS
+ static HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
+ CONSOLE_SCREEN_BUFFER_INFO csbi;
+ GetConsoleScreenBufferInfo(hStdOut, &csbi);
+ uint32_t ConsoleColumns = (uint32_t)(csbi.srWindow.Right - csbi.srWindow.Left + 1);
+#else
+ struct winsize w;
+ ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
+ uint32_t ConsoleColumns = (uint32_t)w.ws_col;
+#endif
+
+ std::string_view TaskString = NewState.Task;
+
+ const std::string PercentString = fmt::format("{:#3}%", PercentDone);
+
+ const std::string ProgressBarString =
+ fmt::format(": |{}{}|", std::string(ProgressBarCount, '#'), std::string(ProgressBarSize - ProgressBarCount, ' '));
+
+ const std::string ElapsedString = fmt::format(": {}", NiceTimeSpanMs(ElapsedTimeMS));
+
+ const std::string ETAString = (ETAMS > 0) ? fmt::format(" ETA {}", NiceTimeSpanMs(ETAMS)) : "";
+
+ const std::string DetailsString = (!NewState.Details.empty()) ? fmt::format(". {}", NewState.Details) : "";
+
+ ExtendableStringBuilder<256> OutputBuilder;
+
+ OutputBuilder << "\r" << TaskString << PercentString;
+ if (OutputBuilder.Size() + 1 < ConsoleColumns)
+ {
+ size_t RemainingSpace = ConsoleColumns - (OutputBuilder.Size() + 1);
+ bool ElapsedFits = RemainingSpace >= ElapsedString.length();
+ RemainingSpace -= ElapsedString.length();
+ bool ETAFits = ElapsedFits && RemainingSpace >= ETAString.length();
+ RemainingSpace -= ETAString.length();
+ bool DetailsFits = ETAFits && RemainingSpace >= DetailsString.length();
+ RemainingSpace -= DetailsString.length();
+ bool ProgressBarFits = DetailsFits && RemainingSpace >= ProgressBarString.length();
+ RemainingSpace -= ProgressBarString.length();
+
+ if (ProgressBarFits)
+ {
+ OutputBuilder << ProgressBarString;
+ }
+ if (ElapsedFits)
+ {
+ OutputBuilder << ElapsedString;
+ }
+ if (ETAFits)
+ {
+ OutputBuilder << ETAString;
+ }
+ if (DetailsFits)
+ {
+ OutputBuilder << DetailsString;
+ }
+ }
+
+ std::string_view Output = OutputBuilder.ToView();
std::string::size_type EraseLength = m_LastOutputLength > Output.length() ? (m_LastOutputLength - Output.length()) : 0;
- ExtendableStringBuilder<128> LineToPrint;
- LineToPrint << Output << std::string(EraseLength, ' ');
+ ExtendableStringBuilder<256> LineToPrint;
+
+ if (Output.length() + EraseLength >= ConsoleColumns)
+ {
+ if (m_LastOutputLength > 0)
+ {
+ LineToPrint << "\n";
+ }
+ LineToPrint << Output.substr(1);
+ DoLinebreak = true;
+ }
+ else
+ {
+ LineToPrint << Output << std::string(EraseLength, ' ');
+ }
+
if (DoLinebreak)
+ {
LineToPrint << "\n";
+ }
#if ZEN_PLATFORM_WINDOWS
- static HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
-
if (m_StdoutIsTty)
{
WriteConsoleA(hStdOut, LineToPrint.c_str(), (DWORD)LineToPrint.Size(), 0, 0);