mirror of
https://github.com/p-ranav/indicators.git
synced 2025-12-16 04:18:51 +08:00
Merge pull request #12 from p-ranav/feature/multi_progress
Feature/multi progress
This commit is contained in:
106
README.md
106
README.md
@@ -141,7 +141,7 @@ int main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Multi-threaded Example
|
## Multi-threaded Update
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
#include <indicators/progress_bar.hpp>
|
#include <indicators/progress_bar.hpp>
|
||||||
@@ -297,6 +297,110 @@ int main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# MultiProgress
|
||||||
|
|
||||||
|
`indicators` supports management of multiple progress bars with the `MultiProgress` class.
|
||||||
|
|
||||||
|
`template <typename Indicator, size_t count> class MultiProgress` is a class template that holds references to multiple progress bars and provides a safe interface to update the state of each bar. `MultiProgress` works with both `ProgressBar` and `BlockProgressBar` classes.
|
||||||
|
|
||||||
|
Below is an example `MultiProgress` object that manages three `ProgressBar` objects.
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<img src="img/multi_progress.gif"/>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include <indicators/multi_progress.hpp>
|
||||||
|
#include <indicators/progress_bar.hpp>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
// Configure first progress bar
|
||||||
|
indicators::ProgressBar bar1;
|
||||||
|
bar1.set_bar_width(50);
|
||||||
|
bar1.start_bar_with("[");
|
||||||
|
bar1.fill_bar_progress_with("■");
|
||||||
|
bar1.lead_bar_progress_with("■");
|
||||||
|
bar1.fill_bar_remainder_with(" ");
|
||||||
|
bar1.end_bar_with(" ]");
|
||||||
|
bar1.set_foreground_color(indicators::Color::YELLOW);
|
||||||
|
bar1.show_elapsed_time();
|
||||||
|
bar1.show_remaining_time();
|
||||||
|
bar1.set_prefix_text("Progress Bar #1 ");
|
||||||
|
|
||||||
|
// Configure second progress bar
|
||||||
|
indicators::ProgressBar bar2;
|
||||||
|
bar2.set_bar_width(50);
|
||||||
|
bar2.start_bar_with("[");
|
||||||
|
bar2.fill_bar_progress_with("=");
|
||||||
|
bar2.lead_bar_progress_with(">");
|
||||||
|
bar2.fill_bar_remainder_with(" ");
|
||||||
|
bar2.end_bar_with(" ]");
|
||||||
|
bar2.set_foreground_color(indicators::Color::CYAN);
|
||||||
|
bar2.show_elapsed_time();
|
||||||
|
bar2.show_remaining_time();
|
||||||
|
bar2.set_prefix_text("Progress Bar #2 ");
|
||||||
|
|
||||||
|
// Configure third progress bar
|
||||||
|
indicators::ProgressBar bar3;
|
||||||
|
bar3.set_bar_width(50);
|
||||||
|
bar3.start_bar_with("[");
|
||||||
|
bar3.fill_bar_progress_with("#");
|
||||||
|
bar3.lead_bar_progress_with("#");
|
||||||
|
bar3.fill_bar_remainder_with(" ");
|
||||||
|
bar3.end_bar_with(" ]");
|
||||||
|
bar3.set_foreground_color(indicators::Color::RED);
|
||||||
|
bar3.show_elapsed_time();
|
||||||
|
bar3.show_remaining_time();
|
||||||
|
bar3.set_prefix_text("Progress Bar #3 ");
|
||||||
|
|
||||||
|
// Construct MultiProgress object
|
||||||
|
indicators::MultiProgress<indicators::ProgressBar, 3> bars;
|
||||||
|
bars.insert<0>(bar1);
|
||||||
|
bars.insert<1>(bar2);
|
||||||
|
bars.insert<2>(bar3);
|
||||||
|
|
||||||
|
std::cout << "Multiple Progress Bars:\n";
|
||||||
|
|
||||||
|
auto job1 = [&bars]() {
|
||||||
|
while (true) {
|
||||||
|
bars.tick<0>();
|
||||||
|
if (bars.is_completed<0>())
|
||||||
|
break;
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto job2 = [&bars]() {
|
||||||
|
while (true) {
|
||||||
|
bars.tick<1>();
|
||||||
|
if (bars.is_completed<1>())
|
||||||
|
break;
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto job3 = [&bars]() {
|
||||||
|
while (true) {
|
||||||
|
bars.tick<2>();
|
||||||
|
if (bars.is_completed<2>())
|
||||||
|
break;
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(60));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::thread first_job(job1);
|
||||||
|
std::thread second_job(job2);
|
||||||
|
std::thread third_job(job3);
|
||||||
|
|
||||||
|
first_job.join();
|
||||||
|
second_job.join();
|
||||||
|
third_job.join();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
# Progress Spinner
|
# Progress Spinner
|
||||||
|
|
||||||
To introduce a progress spinner in your application, include `indicators/progress_spinner.hpp` and create a `ProgressSpinner` object.
|
To introduce a progress spinner in your application, include `indicators/progress_spinner.hpp` and create a `ProgressSpinner` object.
|
||||||
|
|||||||
BIN
img/multi_progress.gif
Normal file
BIN
img/multi_progress.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 185 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 146 KiB |
@@ -131,7 +131,10 @@ private:
|
|||||||
std::atomic<bool> _saved_start_time{false};
|
std::atomic<bool> _saved_start_time{false};
|
||||||
std::chrono::time_point<std::chrono::high_resolution_clock> _start_time_point;
|
std::chrono::time_point<std::chrono::high_resolution_clock> _start_time_point;
|
||||||
std::mutex _mutex;
|
std::mutex _mutex;
|
||||||
Color _foreground_color;
|
Color _foreground_color{indicators::Color::WHITE};
|
||||||
|
|
||||||
|
template <typename Indicator, size_t count> friend class MultiProgress;
|
||||||
|
std::atomic<bool> _multi_progress_mode{false};
|
||||||
|
|
||||||
std::ostream &_print_duration(std::ostream &os, std::chrono::nanoseconds ns) {
|
std::ostream &_print_duration(std::ostream &os, std::chrono::nanoseconds ns) {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@@ -162,7 +165,13 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _print_progress() {
|
void _print_progress(bool from_multi_progress = false) {
|
||||||
|
if (_multi_progress_mode && !from_multi_progress) {
|
||||||
|
if (_progress > 100.0) {
|
||||||
|
_completed = true;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
std::unique_lock<std::mutex> lock{_mutex};
|
std::unique_lock<std::mutex> lock{_mutex};
|
||||||
auto now = std::chrono::high_resolution_clock::now();
|
auto now = std::chrono::high_resolution_clock::now();
|
||||||
auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(now - _start_time_point);
|
auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(now - _start_time_point);
|
||||||
@@ -231,6 +240,9 @@ private:
|
|||||||
auto remaining = eta > elapsed ? (eta - elapsed) : (elapsed - eta);
|
auto remaining = eta > elapsed ? (eta - elapsed) : (elapsed - eta);
|
||||||
_print_duration(std::cout, remaining);
|
_print_duration(std::cout, remaining);
|
||||||
std::cout << "]";
|
std::cout << "]";
|
||||||
|
} else {
|
||||||
|
if (_show_elapsed_time)
|
||||||
|
std::cout << "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_max_postfix_text_length == 0)
|
if (_max_postfix_text_length == 0)
|
||||||
@@ -240,7 +252,7 @@ private:
|
|||||||
if (_progress > 100.0) {
|
if (_progress > 100.0) {
|
||||||
_completed = true;
|
_completed = true;
|
||||||
}
|
}
|
||||||
if (_completed)
|
if (_completed && !from_multi_progress) // Don't std::endl if calling from MultiProgress
|
||||||
std::cout << termcolor::reset << std::endl;
|
std::cout << termcolor::reset << std::endl;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
92
include/indicators/multi_progress.hpp
Normal file
92
include/indicators/multi_progress.hpp
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
Activity Indicators for Modern C++
|
||||||
|
https://github.com/p-ranav/indicators
|
||||||
|
|
||||||
|
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||||
|
SPDX-License-Identifier: MIT
|
||||||
|
Copyright (c) 2019 Pranav Srinivas Kumar <pranav.srinivas.kumar@gmail.com>.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <atomic>
|
||||||
|
#include <functional>
|
||||||
|
#include <indicators/color.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
#include <mutex>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace indicators {
|
||||||
|
|
||||||
|
template <typename Indicator, size_t count> class MultiProgress {
|
||||||
|
public:
|
||||||
|
MultiProgress() { _bars.reserve(count); }
|
||||||
|
|
||||||
|
template <size_t index>
|
||||||
|
typename std::enable_if<(index < count), void>::type insert(Indicator &bar) {
|
||||||
|
_bars.insert(_bars.begin() + index, 1, bar);
|
||||||
|
bar._multi_progress_mode = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <size_t index>
|
||||||
|
typename std::enable_if<(index < count), void>::type set_progress(float value) {
|
||||||
|
if (!_bars[index].get().is_completed())
|
||||||
|
_bars[index].get().set_progress(value);
|
||||||
|
_print_progress();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <size_t index> typename std::enable_if<(index < count), void>::type tick() {
|
||||||
|
if (!_bars[index].get().is_completed())
|
||||||
|
_bars[index].get().tick();
|
||||||
|
_print_progress();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <size_t index>
|
||||||
|
typename std::enable_if<(index < count), bool>::type is_completed() const {
|
||||||
|
return _bars[index].get().is_completed();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::atomic<bool> _started{false};
|
||||||
|
std::mutex _mutex;
|
||||||
|
std::vector<std::reference_wrapper<Indicator>> _bars;
|
||||||
|
|
||||||
|
bool _all_completed() {
|
||||||
|
bool result{true};
|
||||||
|
for (size_t i = 0; i < count; ++i)
|
||||||
|
result &= _bars[i].get().is_completed();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _print_progress() {
|
||||||
|
std::unique_lock<std::mutex> lock{_mutex};
|
||||||
|
if (_started)
|
||||||
|
for (size_t i = 0; i < count; ++i)
|
||||||
|
std::cout << "\x1b[A";
|
||||||
|
for (auto &bar : _bars) {
|
||||||
|
bar.get()._print_progress(true);
|
||||||
|
std::cout << "\n";
|
||||||
|
}
|
||||||
|
std::cout << termcolor::reset;
|
||||||
|
if (!_started)
|
||||||
|
_started = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace indicators
|
||||||
@@ -145,7 +145,10 @@ private:
|
|||||||
std::atomic<bool> _saved_start_time{false};
|
std::atomic<bool> _saved_start_time{false};
|
||||||
std::chrono::time_point<std::chrono::high_resolution_clock> _start_time_point;
|
std::chrono::time_point<std::chrono::high_resolution_clock> _start_time_point;
|
||||||
std::mutex _mutex;
|
std::mutex _mutex;
|
||||||
Color _foreground_color;
|
Color _foreground_color{indicators::Color::WHITE};
|
||||||
|
|
||||||
|
template <typename Indicator, size_t count> friend class MultiProgress;
|
||||||
|
std::atomic<bool> _multi_progress_mode{false};
|
||||||
|
|
||||||
std::ostream &_print_duration(std::ostream &os, std::chrono::nanoseconds ns) {
|
std::ostream &_print_duration(std::ostream &os, std::chrono::nanoseconds ns) {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@@ -176,7 +179,13 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _print_progress() {
|
void _print_progress(bool from_multi_progress = false) {
|
||||||
|
if (_multi_progress_mode && !from_multi_progress) {
|
||||||
|
if (_progress > 100.0) {
|
||||||
|
_completed = true;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
std::unique_lock<std::mutex> lock{_mutex};
|
std::unique_lock<std::mutex> lock{_mutex};
|
||||||
auto now = std::chrono::high_resolution_clock::now();
|
auto now = std::chrono::high_resolution_clock::now();
|
||||||
auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(now - _start_time_point);
|
auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(now - _start_time_point);
|
||||||
@@ -239,6 +248,9 @@ private:
|
|||||||
auto remaining = eta > elapsed ? (eta - elapsed) : (elapsed - eta);
|
auto remaining = eta > elapsed ? (eta - elapsed) : (elapsed - eta);
|
||||||
_print_duration(std::cout, remaining);
|
_print_duration(std::cout, remaining);
|
||||||
std::cout << "]";
|
std::cout << "]";
|
||||||
|
} else {
|
||||||
|
if (_show_elapsed_time)
|
||||||
|
std::cout << "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_max_postfix_text_length == 0)
|
if (_max_postfix_text_length == 0)
|
||||||
@@ -248,7 +260,7 @@ private:
|
|||||||
if (_progress > 100.0) {
|
if (_progress > 100.0) {
|
||||||
_completed = true;
|
_completed = true;
|
||||||
}
|
}
|
||||||
if (_completed)
|
if (_completed && !from_multi_progress) // Don't std::endl if calling from MultiProgress
|
||||||
std::cout << termcolor::reset << std::endl;
|
std::cout << termcolor::reset << std::endl;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -207,6 +207,9 @@ private:
|
|||||||
auto remaining = eta > elapsed ? (eta - elapsed) : (elapsed - eta);
|
auto remaining = eta > elapsed ? (eta - elapsed) : (elapsed - eta);
|
||||||
_print_duration(std::cout, remaining);
|
_print_duration(std::cout, remaining);
|
||||||
std::cout << "]";
|
std::cout << "]";
|
||||||
|
} else {
|
||||||
|
if (_show_elapsed_time)
|
||||||
|
std::cout << "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_max_postfix_text_length == 0)
|
if (_max_postfix_text_length == 0)
|
||||||
|
|||||||
@@ -16,3 +16,9 @@ target_link_libraries(progress_spinner PRIVATE indica::indica)
|
|||||||
|
|
||||||
add_executable(time_meter time_meter.cpp)
|
add_executable(time_meter time_meter.cpp)
|
||||||
target_link_libraries(time_meter PRIVATE indica::indica)
|
target_link_libraries(time_meter PRIVATE indica::indica)
|
||||||
|
|
||||||
|
add_executable(multi_progress_bar multi_progress_bar.cpp)
|
||||||
|
target_link_libraries(multi_progress_bar PRIVATE indica::indica)
|
||||||
|
|
||||||
|
add_executable(multi_block_progress_bar multi_block_progress_bar.cpp)
|
||||||
|
target_link_libraries(multi_block_progress_bar PRIVATE indica::indica)
|
||||||
|
|||||||
70
samples/multi_block_progress_bar.cpp
Normal file
70
samples/multi_block_progress_bar.cpp
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
#include <indicators/block_progress_bar.hpp>
|
||||||
|
#include <indicators/multi_progress.hpp>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
indicators::BlockProgressBar bar1;
|
||||||
|
bar1.set_bar_width(50);
|
||||||
|
bar1.set_foreground_color(indicators::Color::YELLOW);
|
||||||
|
bar1.show_elapsed_time();
|
||||||
|
bar1.show_remaining_time();
|
||||||
|
bar1.set_prefix_text("Progress Bar #1 ");
|
||||||
|
|
||||||
|
indicators::BlockProgressBar bar2;
|
||||||
|
bar2.set_bar_width(50);
|
||||||
|
bar2.set_foreground_color(indicators::Color::CYAN);
|
||||||
|
bar2.show_elapsed_time();
|
||||||
|
bar2.show_remaining_time();
|
||||||
|
bar2.set_prefix_text("Progress Bar #2 ");
|
||||||
|
|
||||||
|
indicators::BlockProgressBar bar3;
|
||||||
|
bar3.set_bar_width(50);
|
||||||
|
bar3.set_foreground_color(indicators::Color::RED);
|
||||||
|
bar3.show_elapsed_time();
|
||||||
|
bar3.show_remaining_time();
|
||||||
|
bar3.set_prefix_text("Progress Bar #3 ");
|
||||||
|
|
||||||
|
indicators::MultiProgress<indicators::BlockProgressBar, 3> bars;
|
||||||
|
bars.insert<0>(bar1);
|
||||||
|
bars.insert<1>(bar2);
|
||||||
|
bars.insert<2>(bar3);
|
||||||
|
|
||||||
|
std::cout << "Multiple Progress Bars:\n";
|
||||||
|
|
||||||
|
auto job1 = [&bars]() {
|
||||||
|
while (true) {
|
||||||
|
bars.tick<0>();
|
||||||
|
if (bars.is_completed<0>())
|
||||||
|
break;
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto job2 = [&bars]() {
|
||||||
|
while (true) {
|
||||||
|
bars.tick<1>();
|
||||||
|
if (bars.is_completed<1>())
|
||||||
|
break;
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto job3 = [&bars]() {
|
||||||
|
while (true) {
|
||||||
|
bars.tick<2>();
|
||||||
|
if (bars.is_completed<2>())
|
||||||
|
break;
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(60));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::thread first_job(job1);
|
||||||
|
std::thread second_job(job2);
|
||||||
|
std::thread third_job(job3);
|
||||||
|
|
||||||
|
first_job.join();
|
||||||
|
second_job.join();
|
||||||
|
third_job.join();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
85
samples/multi_progress_bar.cpp
Normal file
85
samples/multi_progress_bar.cpp
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
#include <indicators/multi_progress.hpp>
|
||||||
|
#include <indicators/progress_bar.hpp>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
indicators::ProgressBar bar1;
|
||||||
|
bar1.set_bar_width(50);
|
||||||
|
bar1.start_bar_with("[");
|
||||||
|
bar1.fill_bar_progress_with("■");
|
||||||
|
bar1.lead_bar_progress_with("■");
|
||||||
|
bar1.fill_bar_remainder_with(" ");
|
||||||
|
bar1.end_bar_with(" ]");
|
||||||
|
bar1.set_foreground_color(indicators::Color::YELLOW);
|
||||||
|
bar1.show_elapsed_time();
|
||||||
|
bar1.show_remaining_time();
|
||||||
|
bar1.set_prefix_text("Progress Bar #1 ");
|
||||||
|
|
||||||
|
indicators::ProgressBar bar2;
|
||||||
|
bar2.set_bar_width(50);
|
||||||
|
bar2.start_bar_with("[");
|
||||||
|
bar2.fill_bar_progress_with("=");
|
||||||
|
bar2.lead_bar_progress_with(">");
|
||||||
|
bar2.fill_bar_remainder_with(" ");
|
||||||
|
bar2.end_bar_with(" ]");
|
||||||
|
bar2.set_foreground_color(indicators::Color::CYAN);
|
||||||
|
bar2.show_elapsed_time();
|
||||||
|
bar2.show_remaining_time();
|
||||||
|
bar2.set_prefix_text("Progress Bar #2 ");
|
||||||
|
|
||||||
|
indicators::ProgressBar bar3;
|
||||||
|
bar3.set_bar_width(50);
|
||||||
|
bar3.start_bar_with("[");
|
||||||
|
bar3.fill_bar_progress_with("#");
|
||||||
|
bar3.lead_bar_progress_with("#");
|
||||||
|
bar3.fill_bar_remainder_with(" ");
|
||||||
|
bar3.end_bar_with(" ]");
|
||||||
|
bar3.set_foreground_color(indicators::Color::RED);
|
||||||
|
bar3.show_elapsed_time();
|
||||||
|
bar3.show_remaining_time();
|
||||||
|
bar3.set_prefix_text("Progress Bar #3 ");
|
||||||
|
|
||||||
|
indicators::MultiProgress<indicators::ProgressBar, 3> bars;
|
||||||
|
bars.insert<0>(bar1);
|
||||||
|
bars.insert<1>(bar2);
|
||||||
|
bars.insert<2>(bar3);
|
||||||
|
|
||||||
|
std::cout << "Multiple Progress Bars:\n";
|
||||||
|
|
||||||
|
auto job1 = [&bars]() {
|
||||||
|
while (true) {
|
||||||
|
bars.tick<0>();
|
||||||
|
if (bars.is_completed<0>())
|
||||||
|
break;
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto job2 = [&bars]() {
|
||||||
|
while (true) {
|
||||||
|
bars.tick<1>();
|
||||||
|
if (bars.is_completed<1>())
|
||||||
|
break;
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto job3 = [&bars]() {
|
||||||
|
while (true) {
|
||||||
|
bars.tick<2>();
|
||||||
|
if (bars.is_completed<2>())
|
||||||
|
break;
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(60));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::thread first_job(job1);
|
||||||
|
std::thread second_job(job2);
|
||||||
|
std::thread third_job(job3);
|
||||||
|
|
||||||
|
first_job.join();
|
||||||
|
second_job.join();
|
||||||
|
third_job.join();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user