10 #include <sys/ioctl.h>
15 namespace user_feedback
20 constexpr
int MAX_PLAUSIBLE_TERMINAL_WIDTH = 4096;
23 constexpr
int MIN_TERMINAL_WIDTH = 8;
30 ui_plugin->set_progress(percent, message);
36 if (m_ui_plugin !=
nullptr)
44 if (m_ui_plugin !=
nullptr)
50 std::atomic<u32> ProgressScope::s_depth(0);
71 : m_scope(message), m_message(message), m_printed_progress(0), m_bar_width(0), m_max_detail_size(max_detail_size), m_last_percentage(0), m_terminal_width(get_terminal_width())
73 if (m_terminal_width > MIN_TERMINAL_WIDTH)
76 m_bar_width = m_terminal_width - 7;
77 if (max_detail_size != 0)
79 m_bar_width -= max_detail_size + 1;
99 progress = std::clamp(progress, 0.0f, 1.0f);
100 m_last_percentage = (int)(progress * 100.0f);
106 if (m_terminal_width <= MIN_TERMINAL_WIDTH)
111 const u32 pos = (
u32)(m_bar_width * progress);
112 if (pos <= m_printed_progress && m_last_detail == detail)
118 m_last_detail = detail;
119 m_printed_progress = pos;
124 bar += std::string(pos,
'=');
126 if (pos < m_bar_width)
130 if (pos + 1 < m_bar_width)
132 bar += std::string(m_bar_width - pos - 1,
' ');
135 auto printed_detail = detail;
136 if (printed_detail.size() > m_max_detail_size)
138 printed_detail = (m_max_detail_size <= 3) ? std::string(m_max_detail_size,
'.') : printed_detail.substr(0, m_max_detail_size - 3) +
"...";
141 std::stringstream str;
142 str <<
"[" << bar <<
"] " << std::right << std::setw(3) << m_last_percentage <<
'%';
143 if (!printed_detail.empty())
145 str <<
" " << printed_detail;
148 const auto output = str.str();
150 if (
output.size() < (
u32)m_terminal_width)
152 std::cerr << std::string(m_terminal_width -
output.size(),
' ');
154 std::cerr <<
"\r" << std::flush;
159 if (m_terminal_width <= MIN_TERMINAL_WIDTH)
163 std::cerr << std::string(m_terminal_width,
' ') <<
"\r" << std::flush;
168 m_printed_progress = 0;
171 m_last_detail = std::string(
"\0redraw", 7);
174 int ProgressPrinter::get_terminal_width()
177 if (ioctl(STDERR_FILENO, TIOCGWINSZ, &
size) < 0)
181 if (
size.ws_col > MAX_PLAUSIBLE_TERMINAL_WIDTH)
virtual void set_layout_locker(bool enable)=0
void set_message(const std::string &message)
ProgressPrinter(const std::string &message, u32 max_detail_size=0)
void report(float progress, const std::string &detail="")
ProgressScope(const std::string &message)
UIPluginInterface * get_ui_plugin()
void report_progress(int percent, const std::string &message)