From 0962ef839f88e22b04984b4b11c95f794f4b53fd Mon Sep 17 00:00:00 2001 From: "Kyle J. McKay" Date: Wed, 3 Mar 2021 19:59:17 -0700 Subject: [PATCH] Girocco/CLIUtil.pm: add Girocco::CLIUtil::Progress class Move and improve the Progress class from lint-all-readme.pl into Girocco/CLIUtil.pm as Girocco::CLIUtil::Progress. Signed-off-by: Kyle J. McKay --- Girocco/CLIUtil.pm | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) diff --git a/Girocco/CLIUtil.pm b/Girocco/CLIUtil.pm index 416e2cc..da68c93 100644 --- a/Girocco/CLIUtil.pm +++ b/Girocco/CLIUtil.pm @@ -89,6 +89,122 @@ BEGIN {eval{ } } +{ + package Girocco::CLIUtil::Progress; + + use Scalar::Util qw(looks_like_number); + use Time::HiRes qw(gettimeofday); + + sub fractime() { return scalar(gettimeofday) } + + my $_init; + BEGIN { $_init = sub { + my $self = shift; + my $max = shift; + looks_like_number($max) && $max >= 0 or $max = 100; + my $title = shift; + defined($title) or $title = ""; + $title =~ s/:+$//; + $title ne "" or $title = "Progress"; + my $lastupd = $self->{lastupd}; + my $shown1 = $self->{shown1}; + looks_like_number($lastupd) or $lastupd = fractime + 2; + %$self = ( + title => $title, + max => $max, + cur => 0, + len => 0, + lastupd => $lastupd + ); + defined($shown1) and $self->{shown1} = $shown1; + $self; + } } + + sub new { + my $class = shift || __PACKAGE__; + my $self = bless {}, $class; + unshift(@_, $self); + select((select(STDERR),$|=1)[0]); + select((select(STDOUT),$|=1)[0]); + return &$_init; + } + + sub reset { + my $self = $_[0]; + $self->clear; + my $wasvis = $self->{wasvis}; + &$_init; + $wasvis and $self->show; + $self; + } + + sub val { $_[0]->{cur} } + sub done { $_[0]->{cur} >= $_[0]->{max} } + + sub update { + my $self = shift; + !$self->{max} and return; + my $last = $self->{cur}; + my $newcur = shift; + looks_like_number($newcur) or $newcur = $last + 1; + $newcur >= $last or $newcur = $last; + $newcur > $self->{max} and $newcur = $self->{max}; + $self->{cur} = $newcur unless $newcur == $last; + my $now = fractime; + if ($self->{shown1} && $newcur > $last && $newcur >= $self->{max} || + $now >= $self->{lastupd} + 1) { + $self->{lastupd} = $now; + !$self->{len} || $newcur != $last and $self->show; + } + } + + sub show { + my $self = shift; + delete $self->{wasvis}; + !$self->{max} and return; + my $p = int((100 * $self->{cur} / $self->{max}) + 0.5); + $p > 100 and $p = 100; + $p == 100 && $self->{cur} < $self->{max} and $p = 99; + my $status = sprintf("%s: %3d%% (%d/%d)", $self->{title}, + $p, $self->{cur}, $self->{max}); + my $newlen = length($status); + $self->{len} > $newlen and $status .= " " x ($self->{len} - $newlen); + printf STDERR "%s\r", $status; + $self->{len} = $newlen; + $self->{shown1} = 1; + } + + sub clear { + my $self = shift; + if ($self->{len}) { + printf STDERR "%s\r", " " x $self->{len}; + $self->{len} = 0; + $self->{wasvis} = 1; + } + } + + sub restore { + my $self = shift; + $self->{wasvis} and $self->show; + } + + sub emit { + my $self = shift; + my $msg = shift; + defined($msg) && $msg ne "" or return; + $msg =~ /\n$/ or $msg .= "\n"; + $self->clear; + printf "%s", $msg; + $self->restore; + } + + sub DESTROY { + my $self = shift; + $self->clear; + } + +}# END package Girocco::CLIUtil::Progress + my $diename; BEGIN {$diename = ""} sub diename { -- 2.11.4.GIT