File Coverage

blib/lib/Term/Twiddle.pm
Criterion Covered Total %
statement 75 126 59.5
branch 18 44 40.9
condition 3 10 30.0
subroutine 19 24 79.1
pod 11 12 91.6
total 126 216 58.3


line stmt bran cond sub pod time code
1             package Term::Twiddle;
2              
3 1     1   22268 use 5.005;
  1         6  
  1         45  
4 1     1   6 use strict;
  1         2  
  1         40  
5 1     1   5 use vars qw( @ISA $VERSION );
  1         7  
  1         77  
6              
7             $VERSION = '2.73';
8              
9 1     1   3766 use Time::HiRes qw(setitimer ITIMER_REAL);
  1         8853  
  1         9  
10             #$SIG{'ALRM'} = \&_spin;
11             $SIG{'INT'} = $SIG{'TERM'} = \&_set_alarm(0);
12              
13             ## for normal spinning routines
14 1     1   1115 use vars qw( $thingy $rate $probability $stream $_step );
  1         3  
  1         89  
15              
16             ## for whole line motion routines (e.g., bounce, swish)
17 1     1   6 use vars qw( $width $delay $_dtime $_offset $_scale $_time $_xpos);
  1         1  
  1         3393  
18              
19             sub new {
20 1     1 1 138 my $self = {};
21 1         4 my $proto = shift;
22 1   33     9 my $class = ref($proto) || $proto;
23 1         3 bless $self, $class;
24              
25 1         6 $self->init(shift);
26              
27 1         17 return $self;
28             }
29              
30             sub init {
31 1     1 0 2 my $self = shift;
32 1         2 my $args = shift;
33              
34 1 50       9 $self->thingy( ( $args->{'thingy'} ? $args->{'thingy'} : [ "\\", "|", "/", "-" ] ) );
35 1 50       5 $self->rate( ( $args->{'rate'} ? $args->{'rate'} : 0.175 ) );
36 1 50       6 $self->probability( ( $args->{'probability'} ? $args->{'probability'} : 0 ) );
37 1 50       6 $self->stream( ( $args->{'stream'} ? $args->{'stream'} : *STDOUT ) );
38              
39 1 50       6 $self->type( ( $args->{'type'} ? $args->{'type'} : '' ) );
40 1 50       5 $self->width( ( $args->{'width'} ? $args->{'width'} : _get_max_width() ) );
41 1 50       75 $self->delay( ( $args->{'delay'} ? $args->{'delay'} : undef ) );
42             }
43              
44             sub start {
45 0     0 1 0 my $self = shift;
46 0         0 _set_alarm( $rate );
47             }
48              
49             sub stop {
50 1     1 1 3 my $self = shift;
51 1         7 _set_alarm(0);
52             }
53              
54             sub thingy {
55 1     1 1 14 my $self = shift;
56 1         2 my $new_thingy = shift;
57 1         3 $_step = 0;
58              
59 1 50       4 return $thingy = ( $new_thingy
60             ? $new_thingy
61             : $thingy );
62             }
63              
64             sub rate {
65 1     1 1 2 my $self = shift;
66 1         3 my $new_rate = shift;
67              
68 1 50       5 return $rate = ( defined $new_rate
69             ? $new_rate
70             : $rate );
71             }
72              
73             sub probability {
74 1     1 1 2 my $self = shift;
75 1         2 my $new_prob = shift;
76              
77 1 50       4 return $probability = ( defined $new_prob
78             ? $new_prob
79             : $probability );
80             }
81              
82             sub stream {
83 1     1 1 2 my $self = shift;
84 1         4 my $new_stream = shift;
85              
86 1 50       5 return $stream = ( defined $new_stream
87             ? $new_stream
88             : $stream );
89             }
90              
91             sub random {
92 0     0 1 0 my $self = shift;
93 0         0 my $prob = shift;
94 0 0       0 $prob = ( defined $prob ? $prob : 25 );
95 0         0 $self->probability($prob);
96             }
97              
98             sub type {
99 1     1 1 2 my $self = shift;
100 1   50     7 my $type = shift || '';
101              
102 1 50       4 if( $type eq 'bounce' ) {
    50          
103 0         0 $_offset = $width/2;
104 0         0 $_scale = $_offset/0.9;
105 0         0 $delay = 0.01;
106 0         0 $_dtime = 0.038;
107 0         0 $SIG{'ALRM'} = \&_bounce;
108             }
109              
110             elsif( $type eq 'swish' ) {
111 0         0 $_offset = $width/2;
112 0         0 $delay = 0.0001;
113 0         0 $_dtime = 0.1;
114 0         0 $SIG{'ALRM'} = \&_swish;
115             }
116              
117             else {
118 1         15 $SIG{'ALRM'} = \&_spin;
119 1         4 return 1;
120             }
121             }
122              
123             sub width {
124 1     1 1 5 my $self = shift;
125 1         6 my $new_width = shift;
126              
127 1 50       12 $width = ( defined $new_width
128             ? $new_width
129             : $width );
130              
131             ## set dependant package vars
132 1         12 $_offset = $width/2;
133 1         5 $_scale = $_offset/0.9;
134              
135 1         4 return $width;
136             }
137              
138             sub delay {
139 1     1 1 2 my $self = shift;
140 1         5 my $new_delay = shift;
141              
142 1 50       15 return $delay = ( defined $new_delay
143             ? $new_delay
144             : $delay );
145             }
146              
147             ## send me a SIGALRM in this many seconds (fractions ok)
148             sub _set_alarm {
149 2     2   16 return setitimer(ITIMER_REAL, shift, 0);
150             }
151              
152             sub _get_max_width {
153 1     1   2 my $width;
154              
155             ## suck in Term::Size, if possible
156 1         2 eval { require Term::Size };
  1         470  
157              
158             ## no Term::Size; try using tput to find terminal width
159 1 50       6 if( $@ ) {
160             ## find tput via poor man's "which"
161 1         8 for my $path ( split /:/, $ENV{'PATH'} ) {
162 4 100       89 next unless -x "$path/tput";
163 1         13591 $width = `$path/tput cols`;
164 1         17 chomp $width;
165 1         17 last;
166             }
167             }
168              
169             ## we have Term::Size; use it
170             else {
171 0         0 ($width, undef) = &Term::Size::chars(*STDERR);
172             }
173              
174             ## assign a default if not already assigned
175 1   50     26 $width ||= 80;
176              
177 1         30 return $width;
178             }
179              
180             sub _bounce {
181              
182 0         0 BOUNCE: {
183 0     0   0 my $old_fh = select($stream);
184 0         0 local $| = 1;
185              
186 0         0 my $oldx = $_xpos;
187              
188             ## original damped harmonic motion filched from some java
189             ## somewhere...please forgive me! I can't remember where!
190 0         0 $_time += $_dtime;
191 0         0 $_xpos = int( $_offset + ($_scale * ( abs(1.7 * cos $_time) - 0.9 ) ) );
192              
193 0         0 print $stream ' ' x $_xpos;
194 0         0 print $stream "*";
195 0 0       0 print $stream ' ' x ( $oldx > $_xpos ? $oldx-$_xpos : 0 );
196 0         0 print $stream "\r";
197              
198 0         0 select($old_fh);
199             }
200              
201 0         0 $SIG{'ALRM'} = \&_bounce;
202 0         0 _set_alarm($delay);
203             }
204              
205             sub _swish {
206              
207 0         0 SWISH: {
208 0     0   0 my $old_fh = select($stream);
209 0         0 local $| = 1;
210              
211 0         0 my $oldx = $_xpos;
212              
213             ## orignal swishing motion filched from Term::ReadKey test.pl
214             ## by Kenneth Albanowski
215 0         0 $_time += $_dtime;
216 0         0 $_xpos = int( $_offset * (cos($_time) + 1) );
217              
218 0         0 print $stream ' ' x $_xpos;
219 0         0 print $stream "*";
220 0 0       0 print $stream ' ' x ( $oldx > $_xpos ? $oldx-$_xpos : 0 );
221 0         0 print $stream "\r";
222              
223 0         0 select($old_fh);
224             }
225              
226 0         0 $SIG{'ALRM'} = \&_swish;
227 0         0 _set_alarm($delay);
228             }
229              
230             sub _spin {
231              
232 0         0 SPIN: {
233 0     0   0 my $old_fh = select($stream);
234 0         0 local $| = 1;
235 0         0 print $stream $$thingy[$_step],
236             chr(8) x length($$thingy[$_step]);
237 0         0 select($old_fh);
238             }
239              
240 0 0       0 $_step = ( $_step+1 > $#$thingy ? 0 : $_step+1 );
241              
242             ## randomize if required
243 0 0 0     0 $rate = rand(0.2)
244             if $probability && (rand() * 100) < $probability;
245              
246 0         0 $SIG{'ALRM'} = \&_spin;
247 0         0 _set_alarm($rate);
248             }
249              
250             sub DESTROY {
251 1     1   663 shift->stop;
252             }
253              
254             1;
255             __END__