Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
libcifpp
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open
libcifpp
Commits
85dfdf41
Unverified
Commit
85dfdf41
authored
Apr 21, 2023
by
Maarten L. Hekkelman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Better progress bar
parent
505f0fdd
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
155 additions
and
140 deletions
+155
-140
include/cif++/utilities.hpp
+6
-6
src/utilities.cpp
+149
-134
No files found.
include/cif++/utilities.hpp
View file @
85dfdf41
...
@@ -157,11 +157,11 @@ inline auto coloured(std::basic_string<CharT, Traits, Alloc> &s, StringColour fo
...
@@ -157,11 +157,11 @@ inline auto coloured(std::basic_string<CharT, Traits, Alloc> &s, StringColour fo
// --------------------------------------------------------------------
// --------------------------------------------------------------------
// A progress bar
// A progress bar
class
Progress
class
progress_bar
{
{
public
:
public
:
Progress
(
int64_t
inMax
,
const
std
::
string
&
inAction
);
progress_bar
(
int64_t
inMax
,
const
std
::
string
&
inAction
);
virtual
~
Progress
();
~
progress_bar
();
void
consumed
(
int64_t
inConsumed
);
// consumed is relative
void
consumed
(
int64_t
inConsumed
);
// consumed is relative
void
progress
(
int64_t
inProgress
);
// progress is absolute
void
progress
(
int64_t
inProgress
);
// progress is absolute
...
@@ -169,10 +169,10 @@ class Progress
...
@@ -169,10 +169,10 @@ class Progress
void
message
(
const
std
::
string
&
inMessage
);
void
message
(
const
std
::
string
&
inMessage
);
private
:
private
:
Progress
(
const
Progress
&
)
=
delete
;
progress_bar
(
const
progress_bar
&
)
=
delete
;
Progress
&
operator
=
(
const
Progress
&
)
=
delete
;
progress_bar
&
operator
=
(
const
progress_bar
&
)
=
delete
;
struct
ProgressI
mpl
*
m_impl
;
struct
progress_bar_i
mpl
*
m_impl
;
};
};
// --------------------------------------------------------------------
// --------------------------------------------------------------------
...
...
src/utilities.cpp
View file @
85dfdf41
...
@@ -31,6 +31,7 @@
...
@@ -31,6 +31,7 @@
#include <atomic>
#include <atomic>
#include <cassert>
#include <cassert>
#include <cmath>
#include <cmath>
#include <condition_variable>
#include <cstring>
#include <cstring>
#include <deque>
#include <deque>
#include <fstream>
#include <fstream>
...
@@ -135,41 +136,41 @@ std::string get_executable_path()
...
@@ -135,41 +136,41 @@ std::string get_executable_path()
// --------------------------------------------------------------------
// --------------------------------------------------------------------
struct
ProgressI
mpl
struct
progress_bar_i
mpl
{
{
ProgressI
mpl
(
int64_t
inMax
,
const
std
::
string
&
inAction
)
progress_bar_i
mpl
(
int64_t
inMax
,
const
std
::
string
&
inAction
)
:
m
Max
(
inMax
)
:
m
_max_value
(
inMax
)
,
m
C
onsumed
(
0
)
,
m
_c
onsumed
(
0
)
,
m
A
ction
(
inAction
)
,
m
_a
ction
(
inAction
)
,
m
M
essage
(
inAction
)
,
m
_m
essage
(
inAction
)
,
m
Thread
(
std
::
bind
(
&
ProgressImpl
::
R
un
,
this
))
,
m
_thread
(
std
::
bind
(
&
progress_bar_impl
::
r
un
,
this
))
{
{
}
}
void
Run
();
void
run
();
void
Stop
()
void
stop
();
{
mStop
=
true
;
if
(
mThread
.
joinable
())
mThread
.
join
();
}
void
PrintProgress
();
void
consumed
(
int64_t
n
);
void
PrintDone
();
void
progress
(
int64_t
p
);
void
message
(
const
std
::
string
&
msg
);
int64_t
mMax
;
void
print_progress
();
std
::
atomic
<
int64_t
>
mConsumed
;
void
print_done
();
int64_t
mLastConsumed
=
0
;
int
mSpinnerIndex
=
0
;
int64_t
m_max_value
;
std
::
string
mAction
,
mMessage
;
std
::
atomic
<
int64_t
>
m_consumed
;
std
::
mutex
mMutex
;
int64_t
m_last_consumed
=
0
;
std
::
thread
mThread
;
int
m_spinner_index
=
0
;
std
::
string
m_action
,
m_message
;
std
::
mutex
m_mutex
;
std
::
thread
m_thread
;
std
::
condition_variable
m_cv
;
std
::
chrono
::
time_point
<
std
::
chrono
::
system_clock
>
std
::
chrono
::
time_point
<
std
::
chrono
::
system_clock
>
m
S
tart
=
std
::
chrono
::
system_clock
::
now
();
m
_s
tart
=
std
::
chrono
::
system_clock
::
now
();
bool
m
S
top
=
false
;
bool
m
_s
top
=
false
;
};
};
void
ProgressImpl
::
R
un
()
void
progress_bar_impl
::
r
un
()
{
{
using
namespace
std
::
literals
;
using
namespace
std
::
literals
;
...
@@ -179,19 +180,21 @@ void ProgressImpl::Run()
...
@@ -179,19 +180,21 @@ void ProgressImpl::Run()
{
{
for
(;;)
for
(;;)
{
{
std
::
this_thread
::
sleep_for
(
10
ms
);
std
::
unique_lock
lock
(
m_mutex
);
std
::
unique_lock
lock
(
mMutex
);
m_cv
.
wait_for
(
lock
,
100
ms
);
if
(
m
Stop
or
mConsumed
==
mMax
)
if
(
m
_stop
or
m_consumed
>=
m_max_value
)
break
;
break
;
auto
elapsed
=
std
::
chrono
::
system_clock
::
now
()
-
mStart
;
if
(
std
::
chrono
::
system_clock
::
now
()
-
m_start
<
2
s
)
if
(
elapsed
<
std
::
chrono
::
seconds
(
5
))
continue
;
continue
;
if
(
not
printedAny
and
isatty
(
STDOUT_FILENO
))
fputs
(
"\e[?25l"
,
stdout
);
print_progress
();
PrintProgress
();
printedAny
=
true
;
printedAny
=
true
;
}
}
}
}
...
@@ -200,93 +203,114 @@ void ProgressImpl::Run()
...
@@ -200,93 +203,114 @@ void ProgressImpl::Run()
}
}
if
(
printedAny
)
if
(
printedAny
)
PrintDone
();
{
print_done
();
if
(
isatty
(
STDOUT_FILENO
))
fputs
(
"\e[?25h"
,
stdout
);
}
}
}
void
ProgressImpl
::
PrintProgress
()
void
progress_bar_impl
::
stop
()
{
{
// const char* kBlocks[] = {
{
// " ", // 0
std
::
unique_lock
lock
(
m_mutex
);
// u8"\u258F", // 1
// u8"\u258E", // 2
m_stop
=
true
;
// u8"\u258D", // 3
m_cv
.
notify_one
();
// u8"\u258C", // 4
}
// u8"\u258B", // 5
// u8"\u258A", // 6
if
(
m_thread
.
joinable
())
// u8"\u2589", // 7
m_thread
.
join
();
// u8"\u2588", // 8
}
// };
void
progress_bar_impl
::
consumed
(
int64_t
n
)
{
std
::
unique_lock
lock
(
m_mutex
);
m_consumed
+=
n
;
m_cv
.
notify_one
();
}
void
progress_bar_impl
::
progress
(
int64_t
p
)
{
std
::
unique_lock
lock
(
m_mutex
);
m_consumed
=
p
;
m_cv
.
notify_one
();
}
void
progress_bar_impl
::
message
(
const
std
::
string
&
msg
)
{
std
::
unique_lock
lock
(
m_mutex
);
m_message
=
msg
;
m_cv
.
notify_one
();
}
const
char
*
kSpinner
[]
=
{
// "▉", "▊", "▋", "▌", "▍", "▎", "▏", "▎", "▍", "▌", "▋", "▊", "▉"
"."
,
"o"
,
"O"
,
"0"
,
"O"
,
"o"
,
"."
,
" "
};
const
size_t
kSpinnerCount
=
sizeof
(
kSpinner
)
/
sizeof
(
char
*
);
const
uint32_t
kMinBarWidth
=
40
,
kMinMsgWidth
=
12
;
void
progress_bar_impl
::
print_progress
()
{
const
char
*
kBlocks
[]
=
{
const
char
*
kBlocks
[]
=
{
" "
,
// 0
// "▯", // 0
" "
,
// 1
// "▮", // 1
" "
,
// 2
"="
,
"-"
,
// 3
"-"
"-"
,
// 4
"-"
,
// 5
"="
,
// 6
"="
,
// 7
"="
,
// 8
};
};
uint32_t
width
=
get_terminal_width
();
uint32_t
width
=
get_terminal_width
();
std
::
string
msg
;
float
progress
=
static_cast
<
float
>
(
m_consumed
)
/
m_max_value
;
msg
.
reserve
(
width
+
1
);
if
(
mMessage
.
length
()
<=
20
)
if
(
width
<
kMinBarWidth
)
{
std
::
cout
<<
(
100
*
progress
)
<<
'%'
<<
std
::
endl
;
msg
=
mMessage
;
if
(
msg
.
length
()
<
20
)
msg
.
append
(
20
-
msg
.
length
(),
' '
);
}
else
else
msg
=
mMessage
.
substr
(
0
,
17
)
+
"..."
;
{
uint32_t
bar_width
=
7
*
width
/
10
;
uint32_t
pct_width
=
7
;
uint32_t
msg_width
=
width
-
bar_width
-
pct_width
-
1
;
msg
+=
" |"
;
if
(
msg_width
<
kMinMsgWidth
)
{
bar_width
+=
kMinMsgWidth
-
msg_width
;
msg_width
=
kMinMsgWidth
;
}
int64_t
consumed
=
mConsumed
;
std
::
ostringstream
msg
;
float
progress
=
static_cast
<
float
>
(
consumed
)
/
mMax
;
int
pi
=
static_cast
<
int
>
(
std
::
ceil
(
progress
*
33
*
8
));
// int tw = width - 28;
// int twd = static_cast<int>(tw * progress + 0.5f);
// msg.append(twd, '=');
// msg.append(tw - twd, ' ');
for
(
int
i
=
0
;
i
<
33
;
++
i
)
if
(
m_message
.
length
()
<=
msg_width
)
{
{
if
(
pi
<=
0
)
msg
<<
m_message
;
msg
+=
kBlocks
[
0
];
if
(
m_message
.
length
()
<
msg_width
)
else
if
(
pi
>=
8
)
msg
<<
std
::
string
(
msg_width
-
m_message
.
length
(),
' '
);
msg
+=
kBlocks
[
8
];
}
else
else
msg
+=
kBlocks
[
pi
];
msg
<<
m_message
.
substr
(
0
,
msg_width
-
3
)
<<
"..."
;
pi
-=
8
;
}
msg
.
append
(
"| "
)
;
msg
<<
' '
;
const
char
kSpinner
[]
=
{
' '
,
'.'
,
'o'
,
'O'
,
'0'
,
'O'
,
'o'
,
'.'
};
uint32_t
pi
=
static_cast
<
uint32_t
>
(
std
::
ceil
(
progress
*
bar_width
));
const
size_t
kSpinnerCount
=
sizeof
(
kSpinner
);
if
(
mLastConsumed
<
consumed
)
for
(
uint32_t
i
=
0
;
i
<
bar_width
;
++
i
)
{
msg
<<
kBlocks
[
i
>
pi
?
1
:
0
];
mLastConsumed
=
consumed
;
mSpinnerIndex
=
(
mSpinnerIndex
+
1
)
%
kSpinnerCount
;
msg
<<
' '
;
}
msg
<<
std
::
setw
(
3
)
<<
static_cast
<
int
>
(
std
::
ceil
(
progress
*
100
))
<<
"% "
;
const
char
spinner
[
2
]
=
{
kSpinner
[
mSpinnerIndex
],
0
}
;
auto
now
=
std
::
chrono
::
system_clock
::
now
()
;
msg
.
append
(
spinner
)
;
m_spinner_index
=
(
std
::
chrono
::
duration_cast
<
std
::
chrono
::
milliseconds
>
(
now
-
m_start
).
count
()
/
200
)
%
kSpinnerCount
;
// int perc = static_cast<int>(100 * progress);
msg
<<
kSpinner
[
m_spinner_index
];
// if (perc < 100)
// msg += ' ';
// if (perc < 10)
// msg += ' ';
// msg += to_string(perc);
// msg += '%';
std
::
cout
<<
'\r'
<<
msg
;
std
::
cout
<<
'\r'
<<
msg
.
str
();
std
::
cout
.
flush
();
std
::
cout
.
flush
();
}
}
}
namespace
namespace
...
@@ -325,12 +349,12 @@ namespace
...
@@ -325,12 +349,12 @@ namespace
}
// namespace
}
// namespace
void
ProgressImpl
::
PrintD
one
()
void
progress_bar_impl
::
print_d
one
()
{
{
std
::
chrono
::
duration
<
double
>
elapsed
=
std
::
chrono
::
system_clock
::
now
()
-
m
S
tart
;
std
::
chrono
::
duration
<
double
>
elapsed
=
std
::
chrono
::
system_clock
::
now
()
-
m
_s
tart
;
std
::
ostringstream
msgstr
;
std
::
ostringstream
msgstr
;
msgstr
<<
m
A
ction
<<
" done in "
<<
elapsed
<<
" seconds"
;
msgstr
<<
m
_a
ction
<<
" done in "
<<
elapsed
<<
" seconds"
;
auto
msg
=
msgstr
.
str
();
auto
msg
=
msgstr
.
str
();
uint32_t
width
=
get_terminal_width
();
uint32_t
width
=
get_terminal_width
();
...
@@ -341,46 +365,37 @@ void ProgressImpl::PrintDone()
...
@@ -341,46 +365,37 @@ void ProgressImpl::PrintDone()
std
::
cout
<<
'\r'
<<
msg
<<
std
::
endl
;
std
::
cout
<<
'\r'
<<
msg
<<
std
::
endl
;
}
}
Progress
::
Progress
(
int64_t
inMax
,
const
std
::
string
&
inAction
)
progress_bar
::
progress_bar
(
int64_t
inMax
,
const
std
::
string
&
inAction
)
:
m_impl
(
nullptr
)
:
m_impl
(
nullptr
)
{
{
if
(
isatty
(
STDOUT_FILENO
)
and
VERBOSE
>=
0
)
if
(
isatty
(
STDOUT_FILENO
)
and
VERBOSE
>=
0
)
m_impl
=
new
ProgressI
mpl
(
inMax
,
inAction
);
m_impl
=
new
progress_bar_i
mpl
(
inMax
,
inAction
);
}
}
Progress
::~
Progress
()
progress_bar
::~
progress_bar
()
{
{
if
(
m_impl
!=
nullptr
)
if
(
m_impl
!=
nullptr
)
m_impl
->
S
top
();
m_impl
->
s
top
();
delete
m_impl
;
delete
m_impl
;
}
}
void
Progress
::
consumed
(
int64_t
inConsumed
)
void
progress_bar
::
consumed
(
int64_t
inConsumed
)
{
{
if
(
m_impl
!=
nullptr
and
if
(
m_impl
!=
nullptr
)
(
m_impl
->
mConsumed
+=
inConsumed
)
>=
m_impl
->
mMax
)
m_impl
->
consumed
(
inConsumed
);
{
m_impl
->
Stop
();
}
}
}
void
Progress
::
progress
(
int64_t
inProgress
)
void
progress_bar
::
progress
(
int64_t
inProgress
)
{
{
if
(
m_impl
!=
nullptr
and
if
(
m_impl
!=
nullptr
)
(
m_impl
->
mConsumed
=
inProgress
)
>=
m_impl
->
mMax
)
m_impl
->
progress
(
inProgress
);
{
m_impl
->
Stop
();
}
}
}
void
Progress
::
message
(
const
std
::
string
&
inMessage
)
void
progress_bar
::
message
(
const
std
::
string
&
inMessage
)
{
{
if
(
m_impl
!=
nullptr
)
if
(
m_impl
!=
nullptr
)
{
m_impl
->
message
(
inMessage
);
std
::
unique_lock
lock
(
m_impl
->
mMutex
);
m_impl
->
mMessage
=
inMessage
;
}
}
}
}
// namespace cif
}
// namespace cif
...
@@ -822,12 +837,12 @@ namespace cif
...
@@ -822,12 +837,12 @@ namespace cif
// --------------------------------------------------------------------
// --------------------------------------------------------------------
class
ResourceP
ool
class
resource_p
ool
{
{
public
:
public
:
static
ResourceP
ool
&
instance
()
static
resource_p
ool
&
instance
()
{
{
static
std
::
unique_ptr
<
ResourcePool
>
s_instance
(
new
ResourceP
ool
);
static
std
::
unique_ptr
<
resource_pool
>
s_instance
(
new
resource_p
ool
);
return
*
s_instance
;
return
*
s_instance
;
}
}
...
@@ -857,7 +872,7 @@ class ResourcePool
...
@@ -857,7 +872,7 @@ class ResourcePool
std
::
unique_ptr
<
std
::
istream
>
load
(
fs
::
path
name
);
std
::
unique_ptr
<
std
::
istream
>
load
(
fs
::
path
name
);
private
:
private
:
ResourceP
ool
();
resource_p
ool
();
std
::
unique_ptr
<
std
::
ifstream
>
open
(
fs
::
path
&
p
)
std
::
unique_ptr
<
std
::
ifstream
>
open
(
fs
::
path
&
p
)
{
{
...
@@ -883,7 +898,7 @@ class ResourcePool
...
@@ -883,7 +898,7 @@ class ResourcePool
std
::
deque
<
fs
::
path
>
mDirs
;
std
::
deque
<
fs
::
path
>
mDirs
;
};
};
ResourcePool
::
ResourceP
ool
()
resource_pool
::
resource_p
ool
()
{
{
#if defined(DATA_DIR)
#if defined(DATA_DIR)
pushDir
(
DATA_DIR
);
pushDir
(
DATA_DIR
);
...
@@ -900,7 +915,7 @@ ResourcePool::ResourcePool()
...
@@ -900,7 +915,7 @@ ResourcePool::ResourcePool()
#endif
#endif
}
}
std
::
unique_ptr
<
std
::
istream
>
ResourceP
ool
::
load
(
fs
::
path
name
)
std
::
unique_ptr
<
std
::
istream
>
resource_p
ool
::
load
(
fs
::
path
name
)
{
{
std
::
unique_ptr
<
std
::
istream
>
result
;
std
::
unique_ptr
<
std
::
istream
>
result
;
std
::
error_code
ec
;
std
::
error_code
ec
;
...
@@ -932,17 +947,17 @@ std::unique_ptr<std::istream> ResourcePool::load(fs::path name)
...
@@ -932,17 +947,17 @@ std::unique_ptr<std::istream> ResourcePool::load(fs::path name)
void
add_data_directory
(
std
::
filesystem
::
path
dataDir
)
void
add_data_directory
(
std
::
filesystem
::
path
dataDir
)
{
{
ResourceP
ool
::
instance
().
pushDir
(
dataDir
);
resource_p
ool
::
instance
().
pushDir
(
dataDir
);
}
}
void
add_file_resource
(
const
std
::
string
&
name
,
std
::
filesystem
::
path
dataFile
)
void
add_file_resource
(
const
std
::
string
&
name
,
std
::
filesystem
::
path
dataFile
)
{
{
ResourceP
ool
::
instance
().
pushAlias
(
name
,
dataFile
);
resource_p
ool
::
instance
().
pushAlias
(
name
,
dataFile
);
}
}
std
::
unique_ptr
<
std
::
istream
>
load_resource
(
std
::
filesystem
::
path
name
)
std
::
unique_ptr
<
std
::
istream
>
load_resource
(
std
::
filesystem
::
path
name
)
{
{
return
ResourceP
ool
::
instance
().
load
(
name
);
return
resource_p
ool
::
instance
().
load
(
name
);
}
}
}
// namespace cif
}
// namespace cif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment