1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
|
package Demeter::UI::Screen::Progress;
=for Copyright
.
Copyright (c) 2006-2019 Bruce Ravel (http://bruceravel.github.io/home).
All rights reserved.
.
This file is free software; you can redistribute it and/or
modify it under the same terms as Perl itself. See The Perl
Artistic License.
.
This program 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.
=cut
use Moose::Role;
use Demeter::NumTypes qw( PosNum );
use Term::Twiddle;
use Term::Sk;
has 'rate' => (is => 'rw', isa => PosNum, default => 0.1);
has 'thingy' => (is => 'rw', isa => 'ArrayRef[Str]', default => sub{[
' -+- ',
' [ ] ',
' [ ] ',
' [ ] ',
'[ ]',
' [ ] ',
' [ ] ',
' [ ] ',
' -+- ',
]});
has 'progress' => (is => 'rw', isa => 'Str', default => 'Time elapsed: %8t %30b (%c of %m)');
my $spinner = new Term::Twiddle;
sub start_spinner {
my ($self, $text) = @_;
return if $self->get_mode('screen');
$text ||= 'Demeter is thinking ';
print $text, " ";
$spinner->rate($self->rate);
$spinner->thingy($self->thingy);
$spinner->start;
};
sub stop_spinner {
my ($self) = @_;
return if $self->get_mode('screen');
$spinner->stop;
print $/;
};
my $counter = q{};
sub start_counter {
my ($self, $text, $target) = @_;
return if $self->get_mode('screen');
$text ||= 'Demeter is thinking';
($text .= "\n") if ($text !~ m{\n$});
print $text;
$target ||= 100;
$counter = Term::Sk->new($self->progress, {freq => 's', base => 0})
or die "Error 0010: Term::Sk->new, (code $Term::Sk::errcode) $Term::Sk::errmsg";
$counter->{target} = $target;
$counter->{value} = 0;
};
sub count {
return if $_[0]->get_mode('screen');
$counter->up;
};
sub stop_counter {
return if $_[0]->get_mode('screen');
$counter->close;
$counter = q{}
};
1;
=head1 NAME
Demeter::UI::Screen::Progress - On screen indicators for lengthy operations
=head1 VERSION
This documentation refers to Demeter version 0.9.26.
=head1 SYNOPSIS
A spinner indicating and ongoing operation:
$fitobject->start_spinner("Demeter is performing a fit");
...
$fitobject->stop_spinner;
A counter indicating an operation of known length:
$n = 100;
$object->start_counter("Demeter is doing something $n times", $n);
...
loop {
$object->count;
}
...
$object->stop_counter;
Both spinner and counter are disabled if screen disposal mode is turned on.
=head1 DESCRIPTION
This role for a Demeter object provides some on-screen feedback for
lengthy procedures. This role is imported when the UI mode is set to
"screen". See L<Demeter/PRAGMATA>. The idea is to provide either a
spinny thing for the user to look at when running something time
consuming from the command line or a counter for when the number of
steps to the time consuming operation is known.
=head1 ATTRIBUTES
The spinner attributes of this role take their names from parameters
for L<Term::Twiddle>. Like all Moose attributes, their accessors take
the same names.
=over 4
=item C<thingy>
An array with the sequence of text strings comprising the spinner.
The default is a throbber that goes from S<"[ ]"> to "-+-" and
back.
=item C<rate>
The speed at which the thingy changes. Default is 0.1.
=item C<progress>
The text string which formats the progress meter. See L<Term::Sk> for
full details. The default is
Elapsed: %8t %30b (%c of %m)
This shows the elapsed time, a progress bar, and a count.
=back
=head1 METHODS
=over 4
=item C<start_spinner>
Start the spinner. This is typically called just before a time
consuming operation.
$fitobject->start_spinner("Demeter is performing a fit");
The optional argument is some text to print to the screen in front of
the spinner. This text would typically not include a new line.
=item C<stop_spinner>
Stop the spinner. This is typically called at the end of a time
consuming operation.
$fitobject->stop_spinner;
=item C<start_counter>
Start the counter. This is typically called just before a time
consuming operation of a known number of steps.
$object->start_spinner("Demeter is doing many things", 100);
The first argument is a bit of text describing what's going on. A new
line will be appended if the text does not end in a newline. The
second argument is the total number of steps in the operation.
=item C<count>
Update the counter.
$object->count;
=item C<stop_counter>
Stop the counter. This is typically called after the last step is
completed.
$object->stop_counter;
=back
=head1 DEPENDENCIES
Demeter's dependencies are in the F<Build.PL> file.
This module uses L<Term::Twiddle> to generate the indicator and
L<Term::Sk> for the counter.
=head1 BUGS AND LIMITATIONS
=over 4
=item *
Configuring the form and rate of the twiddler would be nice.
=item *
A way to access the L<Term::Sk> whisper method would be helpful.
=back
Please report problems to the Ifeffit Mailing List
(L<http://cars9.uchicago.edu/mailman/listinfo/ifeffit/>)
Patches are welcome.
=head1 AUTHOR
Bruce Ravel, L<http://bruceravel.github.io/home>
L<http://bruceravel.github.io/demeter/>
=head1 LICENCE AND COPYRIGHT
Copyright (c) 2006-2019 Bruce Ravel (L<http://bruceravel.github.io/home>). All rights reserved.
This module is free software; you can redistribute it and/or
modify it under the same terms as Perl itself. See L<perlgpl>.
This program 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.
=cut
|