Skip to content

Commit

Permalink
Resize progress bar when terminal size changes (fixes github #159)
Browse files Browse the repository at this point in the history
  • Loading branch information
mhx committed Jul 31, 2023
1 parent 4bef174 commit 2276eeb
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 11 deletions.
50 changes: 50 additions & 0 deletions include/dwarfs/cached_value.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/**
* \author Marcus Holland-Moritz ([email protected])
* \copyright Copyright (c) Marcus Holland-Moritz
*
* This file is part of dwarfs.
*
* dwarfs is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dwarfs is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with dwarfs. If not, see <https://www.gnu.org/licenses/>.
*/

#pragma once

#include <functional>
#include <variant>

namespace dwarfs {

template <typename T>
class cached_value {
public:
using function_type = std::function<T()>;

cached_value(function_type f)
: v_{f} {}

T const& get() {
if (std::holds_alternative<function_type>(v_)) [[unlikely]] {
v_ = std::get<function_type>(v_)();
}
return std::get<T>(v_);
}

T const& operator()() { return get(); }

private:
std::variant<function_type, T> v_;
};

} // namespace dwarfs
11 changes: 7 additions & 4 deletions include/dwarfs/console_writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#include <atomic>
#include <cstddef>
#include <functional>
#include <iosfwd>
#include <mutex>
#include <string>
Expand All @@ -36,12 +37,14 @@ class progress;

class console_writer : public logger {
public:
using get_term_width_type = std::function<size_t()>;

enum display_mode { NORMAL, REWRITE };
enum progress_mode { NONE, SIMPLE, ASCII, UNICODE };

console_writer(std::ostream& os, progress_mode pg_mode, size_t width,
level_type threshold, display_mode mode = NORMAL,
bool verbose = false);
console_writer(std::ostream& os, progress_mode pg_mode,
get_term_width_type get_term_width, level_type threshold,
display_mode mode = NORMAL, bool verbose = false);

void write(level_type level, const std::string& output, char const* file,
int line) override;
Expand All @@ -58,7 +61,7 @@ class console_writer : public logger {
double frac_;
std::atomic<size_t> counter_{0};
progress_mode const pg_mode_;
size_t const width_;
get_term_width_type get_term_width_;
display_mode const mode_;
bool const color_;
bool const with_context_;
Expand Down
16 changes: 10 additions & 6 deletions src/dwarfs/console_writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

#include <fmt/format.h>

#include "dwarfs/cached_value.h"
#include "dwarfs/console_writer.h"
#include "dwarfs/entry.h"
#include "dwarfs/entry_interface.h"
Expand Down Expand Up @@ -78,13 +79,14 @@ std::string progress_bar(size_t width, double frac, bool unicode) {
} // namespace

console_writer::console_writer(std::ostream& os, progress_mode pg_mode,
size_t width, level_type threshold,
display_mode mode, bool with_context)
get_term_width_type get_term_width,
level_type threshold, display_mode mode,
bool with_context)
: os_(os)
, threshold_(threshold)
, frac_(0.0)
, pg_mode_(pg_mode)
, width_(width)
, get_term_width_(get_term_width)
, mode_(mode)
, color_(stream_is_fancy_terminal(os))
, with_context_(with_context)
Expand Down Expand Up @@ -180,12 +182,13 @@ void console_writer::update(const progress& p, bool last) {
const char* newline = pg_mode_ != NONE ? "\x1b[K\n" : "\n";

std::ostringstream oss;
cached_value width(get_term_width_);

bool fancy = pg_mode_ == ASCII || pg_mode_ == UNICODE;

if (last || fancy) {
if (fancy) {
for (size_t i = 0; i < width_; ++i) {
for (size_t i = 0; i < width.get(); ++i) {
oss << (pg_mode_ == UNICODE ? "" : "-");
}
oss << "\n";
Expand All @@ -205,7 +208,8 @@ void console_writer::update(const progress& p, bool last) {
}

if (fancy) {
oss << terminal_colored(p.status(width_), termcolor::BOLD_CYAN, color_)
oss << terminal_colored(p.status(width.get()), termcolor::BOLD_CYAN,
color_)
<< newline;
}

Expand Down Expand Up @@ -305,7 +309,7 @@ void console_writer::update(const progress& p, bool last) {
os_ << oss.str();
}
} else {
oss << progress_bar(width_ - 6, frac_, pg_mode_ == UNICODE)
oss << progress_bar(width.get() - 6, frac_, pg_mode_ == UNICODE)
<< fmt::format("{:3.0f}% ", 100 * frac_) << "-\\|/"[counter_ % 4]
<< '\n';

Expand Down
2 changes: 1 addition & 1 deletion src/mkdwarfs_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -868,7 +868,7 @@ int mkdwarfs_main(int argc, sys_char** argv) {
auto pg_mode = DWARFS_NOTHROW(progress_modes.at(progress_mode));
auto log_level = logger::parse_level(log_level_str);

console_writer lgr(std::cerr, pg_mode, get_term_width(), log_level,
console_writer lgr(std::cerr, pg_mode, get_term_width, log_level,
recompress ? console_writer::REWRITE
: console_writer::NORMAL,
log_level >= logger::DEBUG);
Expand Down

0 comments on commit 2276eeb

Please sign in to comment.