HAL
progress_printer.cpp
Go to the documentation of this file.
2 
4 
5 #include <iostream>
6 #include <sstream>
7 #include <sys/ioctl.h> //ioctl() and TIOCGWINSZ
8 #include <unistd.h> // for STDOUT_FILENO
9 
11 
12 namespace hal
13 {
14  namespace dataflow
15  {
16  ProgressPrinter::ProgressPrinter(u32 max_message_size) : m_bar_width(0), m_max_message_size(max_message_size), m_terminal_width(get_terminal_width())
17  {
18  if (m_terminal_width <= 8)
19  {
20  return;
21  }
22 
23  m_bar_width = m_terminal_width - 7;
24  if (max_message_size != 0)
25  {
26  m_bar_width -= max_message_size + 1;
27  }
28  reset();
29  }
30 
31  void ProgressPrinter::print_progress(float progress, const std::string& message)
32  {
33  progress = std::clamp(progress, 0.f, 1.f);
34  u32 int_progress = (u32)(progress * 100.0f);
36  {
37  GuiExtensionDataflow::s_progress_indicator_function(int_progress < 100 ? int_progress : 99, "dataflow analysis running ...");
38  }
39 
40  if (m_terminal_width <= 8)
41  {
42  return;
43  }
44 
45  u32 pos = (u32)(m_bar_width * progress);
46 
47  if (pos <= m_printed_progress && m_last_message == message)
48  {
49  return;
50  }
51 
52  m_last_message = message;
53  m_printed_progress = pos;
54 
55  std::string bar;
56  if (pos)
57  {
58  bar += std::string(pos, '=');
59  }
60  if (pos < m_bar_width)
61  {
62  bar += '>';
63  }
64  if (pos + 1 < m_bar_width)
65  {
66  bar += std::string(m_bar_width - pos - 1, ' ');
67  }
68 
69  auto print_message = message;
70  if (print_message.size() > m_max_message_size)
71  {
72  if (m_max_message_size <= 3)
73  {
74  print_message = std::string(m_max_message_size, '.');
75  }
76  else
77  {
78  print_message = print_message.substr(0, m_max_message_size - 3) + "...";
79  }
80  }
81 
82  std::stringstream str;
83  str << "[" << bar << "] ";
84 
85  str << std::right << std::setw(3) << int_progress << '%';
86 
87  if (!print_message.empty())
88  {
89  str << " " << print_message;
90  }
91 
92  auto output = str.str();
93 
94  std::cerr << output;
95  if (output.size() < (u32)m_terminal_width)
96  {
97  std::cerr << std::string(m_terminal_width - output.size(), ' ');
98  }
99 
100  std::cerr << "\r" << std::flush;
101  }
102 
104  {
105  if (m_terminal_width <= 8)
106  {
107  return;
108  }
109  std::cerr << std::string(m_terminal_width, ' ') << "\r" << std::flush;
110  }
111 
113  {
114  m_printed_progress = 0;
115  m_last_message = "$^äü+";
116  }
117 
118  int ProgressPrinter::get_terminal_width()
119  {
120  struct winsize size;
121  int retval = ioctl(STDERR_FILENO, TIOCGWINSZ, &size);
122  if (retval < 0)
123  {
124  return -1;
125  }
127  {
128  return -1;
129  }
130  return size.ws_col;
131  }
132  } // namespace dataflow
133 } // namespace hal
static std::function< void(int, const std::string &)> s_progress_indicator_function
void print_progress(float progress, const std::string &message="")
ProgressPrinter(u32 max_message_size=0)
quint32 u32
message(VERBOSE "Qt5Widgets_LIBRARIES: ${Qt5Widgets_LIBRARIES}") elseif(NOT Qt5Widgets_FOUND) set(Missing_package "TRUE") if(APPLE AND CMAKE_HOST_APPLE) message(STATUS "To install qt5 on MacOS using homebrew run following command
Definition: CMakeLists.txt:15
const int dont_believe_in_terminal_width_bigger_than_this_value