Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /// Header
- #ifndef PROGRESSSPINNER_H
- #define PROGRESSSPINNER_H
- #include <thread>
- #include <mutex>
- class ProgressSpinner {
- public:
- ProgressSpinner(unsigned);
- ProgressSpinner(const ProgressSpinner&) = delete;
- ~ProgressSpinner();
- bool start();
- bool stop();
- bool resume();
- bool pause();
- bool is_running();
- bool is_paused ();
- bool is_online ();
- unsigned get_speed();
- void set_speed(unsigned);
- private:
- unsigned speed;
- bool running, paused;
- int8_t spin;
- std::thread* runner;
- std::mutex lock;
- void run();
- bool moving();
- };
- #endif // PROGRESSSPINNER_H
- /// Source
- #include "ProgressSpinner.hpp"
- #include <cstdio>
- #include <chrono>
- const char spinner[9] = "|\\-/|\\-/";
- const int8_t spins=9;
- ProgressSpinner::ProgressSpinner(unsigned speedv) {
- this->running = false;
- this->paused = true ;
- this->speed = speedv? speedv:1;
- this->runner = nullptr;
- this->spin = 0;
- }
- ProgressSpinner::~ProgressSpinner() {
- this->stop();
- }
- bool ProgressSpinner::start() {
- this->lock.lock();
- bool out=false;
- if (!this->running) { // not already started
- try {
- this->runner = new std::thread(ProgressSpinner::run, this); // start thread
- } catch (...) { // bad_alloc or runtime_error?
- delete this->runner;
- this->runner = nullptr;
- goto _end;
- }
- this->running = (bool) (this->runner); // register start
- this->paused = !this->running; // go/stop
- this->spin = 1;
- out = this->running;
- }
- _end:
- this->lock.unlock();
- return out;
- }
- bool ProgressSpinner::stop() {
- this->lock.lock();
- bool out=false;
- if (this->running) { // not already stopped
- this->running = false; // queue to stop
- this->paused = false;
- // allow to stop
- this->lock.unlock();
- // wait for stop-confirmation
- while (true) {
- this->lock.lock();
- if (this->paused) { // confirmation received
- this->lock.unlock();
- break; // stop blocking
- }
- // or continue waiting
- this->lock.unlock();
- }
- // after stop
- this->lock.lock();
- // handle thread
- this->runner->join();
- delete this->runner;
- this->runner = nullptr;
- // success
- out = true;
- }
- this->lock.unlock();
- return out;
- }
- bool ProgressSpinner::resume() {
- this->lock.lock();
- bool out=false;
- if (this->paused) {
- this->paused = false;
- out = true;
- }
- this->lock.unlock();
- return out;
- }
- bool ProgressSpinner::pause() {
- this->lock.lock();
- bool out=false;
- if (!this->paused) {
- this->paused = true;
- out = true;
- }
- this->lock.unlock();
- return out;
- }
- bool ProgressSpinner::is_running() {
- this->lock.lock();
- bool running_tmp = this->running;
- this->lock.unlock();
- return running_tmp;
- }
- bool ProgressSpinner::is_paused() {
- this->lock.lock();
- bool paused_tmp = this->paused;
- this->lock.unlock();
- return paused_tmp;
- }
- bool ProgressSpinner::is_online() {
- this->lock.lock();
- bool online = this->moving();
- this->lock.unlock();
- return online;
- }
- unsigned ProgressSpinner::get_speed() {
- this->lock.lock();
- unsigned speed_tmp = this->speed;
- this->lock.unlock();
- return speed_tmp;
- }
- void ProgressSpinner::set_speed(unsigned speedv) {
- this->lock.lock();
- this->speed = speedv? speedv:1;
- this->lock.unlock();
- }
- void ProgressSpinner::run() {
- std::chrono::milliseconds speedv;
- while (true) {
- this->lock.lock();
- if (!this->paused) {
- if (this->spin == spins) {this->spin = (int8_t) 1;} // reset after display cycle
- printf("%c\b", spinner[(unsigned short) this->spin++]); // DO THE WHOLE POINT PT. 1
- fflush(stdout);
- }
- if (!this->running) { // stop
- this->paused = true; // give confirmation
- printf(" \b"); // clean up - WHOLE POINT PT. 2
- fflush(stdout);
- this->lock.unlock(); // allow ...
- break;
- }
- speedv = std::chrono::milliseconds(this->speed);
- this->lock.unlock();
- std::this_thread::sleep_for(speedv);
- }
- }
- bool ProgressSpinner::moving() {
- return this->running && !this->paused;
- }
- /// End
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement