Skip to content

Commit ee1ee97

Browse files
committed
prettier progress bar for program execution
1 parent ed60afd commit ee1ee97

File tree

7 files changed

+236
-13
lines changed

7 files changed

+236
-13
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ set(SOURCES
4545
src/graphconverter.cpp
4646
src/filesystemutils.cpp
4747
src/resourcelocation.cpp
48+
src/globalutils.cpp
4849
)
4950

5051
add_executable(${PROJECT_NAME} ${SOURCES})

include/globalutils.hpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#pragma once
2+
3+
#ifndef GLOBAL_UTILS_H
4+
#define GLOBAL_UTILS_H
5+
6+
#include "progressbar.hpp"
7+
8+
class GlobalUtils
9+
{
10+
public:
11+
static void spc(progressbar& bar);
12+
};
13+
14+
15+
#endif //GLOBAL_UTILS_H

include/graphconverter.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
#include "resourcelocation.hpp"
1515
#include "filesystemutils.hpp"
1616
#include "inireader.hpp"
17-
#include <boost/timer/progress_display.hpp>
17+
#include "globalutils.hpp"
18+
#include "progressbar.hpp"
1819
#include <boost/log/trivial.hpp>
1920
#include <filesystem>
2021
#include <functional>
@@ -36,6 +37,8 @@ class GraphConverter
3637
void postactions();
3738
void convert();
3839
private:
40+
static const int GRAPHS_VOLUME;
41+
static const int DIR_VOLUME;
3942
void create_required_directories(std::filesystem::path path) const;
4043
};
4144

include/progressbar.hpp

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
// The MIT License (MIT)
2+
//
3+
// Copyright (c) 2019 Luigi Pertoldi
4+
//
5+
// Permission is hereby granted, free of charge, to any person obtaining a copy
6+
// of this software and associated documentation files (the "Software"), to
7+
// deal in the Software without restriction, including without limitation the
8+
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9+
// sell copies of the Software, and to permit persons to whom the Software is
10+
// furnished to do so, subject to the following conditions:
11+
//
12+
// The above copyright notice and this permission notice shall be included in
13+
// all copies or substantial portions of the Software.
14+
//
15+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20+
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21+
// IN THE SOFTWARE.
22+
//
23+
// ============================================================================
24+
// ___ ___ ___ __ ___ ____ __ __ ___ __ ___
25+
// | |_) | |_) / / \ / /`_ | |_) | |_ ( (` ( (` | |_) / /\ | |_)
26+
// |_| |_| \ \_\_/ \_\_/ |_| \ |_|__ _)_) _)_) |_|_) /_/--\ |_| \_
27+
//
28+
// Very simple progress bar for c++ loops with internal running variable
29+
//
30+
// Author: Luigi Pertoldi
31+
// Created: 3 dic 2016
32+
//
33+
// Notes: The bar must be used when there's no other possible source of output
34+
// inside the for loop
35+
//
36+
37+
#ifndef __PROGRESSBAR_HPP
38+
#define __PROGRESSBAR_HPP
39+
40+
#include <iostream>
41+
#include <ostream>
42+
#include <string>
43+
#include <stdexcept>
44+
45+
class progressbar {
46+
47+
public:
48+
// default destructor
49+
~progressbar() = default;
50+
51+
// delete everything else
52+
progressbar (progressbar const&) = delete;
53+
progressbar& operator=(progressbar const&) = delete;
54+
progressbar (progressbar&&) = delete;
55+
progressbar& operator=(progressbar&&) = delete;
56+
57+
// default constructor, must call set_niter later
58+
inline progressbar();
59+
inline progressbar(int n, bool showbar=true, std::ostream& out=std::cerr);
60+
61+
// reset bar to use it again
62+
inline void reset();
63+
// set number of loop iterations
64+
inline void set_niter(int iter);
65+
// chose your style
66+
inline void set_done_char(const std::string& sym) {done_char = sym;}
67+
inline void set_todo_char(const std::string& sym) {todo_char = sym;}
68+
inline void set_opening_bracket_char(const std::string& sym) {opening_bracket_char = sym;}
69+
inline void set_closing_bracket_char(const std::string& sym) {closing_bracket_char = sym;}
70+
// to show only the percentage
71+
inline void show_bar(bool flag = true) {do_show_bar = flag;}
72+
// set the output stream
73+
inline void set_output_stream(const std::ostream& stream) {output.rdbuf(stream.rdbuf());}
74+
// main function
75+
inline void update();
76+
77+
private:
78+
int progress;
79+
int n_cycles;
80+
int last_perc;
81+
bool do_show_bar;
82+
bool update_is_called;
83+
84+
std::string done_char;
85+
std::string todo_char;
86+
std::string opening_bracket_char;
87+
std::string closing_bracket_char;
88+
89+
std::ostream& output;
90+
};
91+
92+
inline progressbar::progressbar() :
93+
progress(0),
94+
n_cycles(0),
95+
last_perc(0),
96+
do_show_bar(true),
97+
update_is_called(false),
98+
done_char("#"),
99+
todo_char(" "),
100+
opening_bracket_char("["),
101+
closing_bracket_char("]"),
102+
output(std::cerr) {}
103+
104+
inline progressbar::progressbar(int n, bool showbar, std::ostream& out) :
105+
progress(0),
106+
n_cycles(n),
107+
last_perc(0),
108+
do_show_bar(showbar),
109+
update_is_called(false),
110+
done_char("#"),
111+
todo_char(" "),
112+
opening_bracket_char("["),
113+
closing_bracket_char("]"),
114+
output(out) {}
115+
116+
inline void progressbar::reset() {
117+
progress = 0,
118+
update_is_called = false;
119+
last_perc = 0;
120+
return;
121+
}
122+
123+
inline void progressbar::set_niter(int niter) {
124+
if (niter <= 0) throw std::invalid_argument(
125+
"progressbar::set_niter: number of iterations null or negative");
126+
n_cycles = niter;
127+
return;
128+
}
129+
130+
inline void progressbar::update() {
131+
132+
if (n_cycles == 0) throw std::runtime_error(
133+
"progressbar::update: number of cycles not set");
134+
135+
if (!update_is_called) {
136+
if (do_show_bar == true) {
137+
output << opening_bracket_char;
138+
for (int _ = 0; _ < 50; _++) output << todo_char;
139+
output << closing_bracket_char << " 0%";
140+
}
141+
else output << "0%";
142+
}
143+
update_is_called = true;
144+
145+
int perc = 0;
146+
147+
// compute percentage, if did not change, do nothing and return
148+
perc = progress*100./(n_cycles-1);
149+
if (perc < last_perc) return;
150+
151+
// update percentage each unit
152+
if (perc == last_perc + 1) {
153+
// erase the correct number of characters
154+
if (perc <= 10) output << "\b\b" << perc << '%';
155+
else if (perc > 10 and perc < 100) output << "\b\b\b" << perc << '%';
156+
else if (perc == 100) output << "\b\b\b" << perc << '%';
157+
}
158+
if (do_show_bar == true) {
159+
// update bar every ten units
160+
if (perc % 2 == 0) {
161+
// erase closing bracket
162+
output << std::string(closing_bracket_char.size(), '\b');
163+
// erase trailing percentage characters
164+
if (perc < 10) output << "\b\b\b";
165+
else if (perc >= 10 && perc < 100) output << "\b\b\b\b";
166+
else if (perc == 100) output << "\b\b\b\b\b";
167+
168+
// erase 'todo_char'
169+
for (int j = 0; j < 50-(perc-1)/2; ++j) {
170+
output << std::string(todo_char.size(), '\b');
171+
}
172+
173+
// add one additional 'done_char'
174+
if (perc == 0) output << todo_char;
175+
else output << done_char;
176+
177+
// refill with 'todo_char'
178+
for (int j = 0; j < 50-(perc-1)/2-1; ++j) output << todo_char;
179+
180+
// readd trailing percentage characters
181+
output << closing_bracket_char << ' ' << perc << '%';
182+
}
183+
}
184+
last_perc = perc;
185+
++progress;
186+
output << std::flush;
187+
188+
return;
189+
}
190+
191+
#endif

install.bat

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,11 @@ REM
1111
cd /d "%BUILD_DIR%"
1212

1313
REM
14-
cmake "%SOURCE_DIR%"
14+
cmake .. -G "MinGW Makefiles"
1515

1616
REM
1717
cmake --build .
1818

1919
REM
2020
REM
21-
"%BUILD_DIR%\graphiso-extractor.exe"
22-
23-
REM
24-
pause
21+
"%BUILD_DIR%\graphiso-extractor.exe"

src/globalutils.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#include "globalutils.hpp"
2+
3+
void GlobalUtils::spc(progressbar &bar)
4+
{
5+
bar.set_todo_char(" ");
6+
bar.set_done_char("");
7+
bar.set_opening_bracket_char("[");
8+
bar.set_closing_bracket_char("]");
9+
}

src/graphconverter.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
#include "graphconverter.hpp"
22

3+
const int GraphConverter::GRAPHS_VOLUME = 145600;
4+
const int GraphConverter::DIR_VOLUME = 84;
5+
36
GraphConverter::GraphConverter()
47
{
58
this->resource.set_source(std::filesystem::path(this->config.read_property(FileIO::CONFIG_DB_SOURCE)));
@@ -9,7 +12,7 @@ GraphConverter::GraphConverter()
912

1013
void GraphConverter::initially() const
1114
{
12-
std::cout << "GraphISO-Extractor by Kacper Liżewski©" << std::endl;
15+
std::cout << std::endl << "GraphISO-Extractor by Kacper Liżewski©" << std::endl;
1316
std::cout << FileIO::APP_TITLE << std::endl;
1417
BOOST_LOG_TRIVIAL(info) << "Starting the conversion process";
1518
}
@@ -35,7 +38,9 @@ void GraphConverter::postactions()
3538
reader.set_context(std::make_unique<GroundReader>());
3639
writer.set_context(std::make_unique<GroundWriter>());
3740

38-
boost::timer::progress_display progress_bar(84);
41+
progressbar progress(DIR_VOLUME);
42+
GlobalUtils::spc(progress);
43+
3944
GroundFile* ground;
4045

4146
for (const auto& entry : std::filesystem::recursive_directory_iterator(this->resource.get_ground())) {
@@ -55,18 +60,20 @@ void GraphConverter::postactions()
5560
BOOST_LOG_TRIVIAL(error) << ex.what();
5661
}
5762

58-
++progress_bar;
63+
progress.update();
5964
}
6065
}
61-
BOOST_LOG_TRIVIAL(info) << "Ground truth files were processed";
66+
BOOST_LOG_TRIVIAL(info) << std::endl << "Ground truth files were processed";
6267
}
6368

6469
void GraphConverter::convert()
6570
{
6671
reader.set_context(std::make_unique<GraphReader>());
6772
writer.set_context(std::make_unique<GraphWriter>());
6873

69-
boost::timer::progress_display progress_bar(145600);
74+
progressbar progress(GRAPHS_VOLUME);
75+
GlobalUtils::spc(progress);
76+
7077
GraphFile* graph;
7178

7279
for (const auto& entry : std::filesystem::recursive_directory_iterator(this->resource.get_source())) {
@@ -86,10 +93,10 @@ void GraphConverter::convert()
8693
BOOST_LOG_TRIVIAL(error) << ex.what();
8794
}
8895

89-
++progress_bar;
96+
progress.update();
9097
}
9198
}
92-
BOOST_LOG_TRIVIAL(info) << "Database was processed";
99+
BOOST_LOG_TRIVIAL(info) << std::endl << "Database was processed";
93100
}
94101

95102
void GraphConverter::create_required_directories(std::filesystem::path path) const

0 commit comments

Comments
 (0)