File Coverage

blib/lib/Time/DoAfter.pm
Criterion Covered Total %
statement 78 83 93.9
branch 31 38 81.5
condition 14 24 58.3
subroutine 16 16 100.0
pod 8 8 100.0
total 147 169 86.9


line stmt bran cond sub pod time code
1             package Time::DoAfter;
2             # ABSTRACT: Wait before doing by label contoller singleton
3              
4 1     1   215402 use 5.010;
  1         9  
5 1     1   4 use strict;
  1         1  
  1         27  
6 1     1   4 use warnings;
  1         2  
  1         23  
7              
8 1     1   4 use Carp 'croak';
  1         1  
  1         53  
9 1     1   449 use Time::HiRes qw( time sleep );
  1         1242  
  1         3  
10              
11             our $VERSION = '1.07'; # VERSION
12              
13             sub _input_handler {
14 9     9   16 my ( $input, $set ) = ( {}, {} );
15              
16             my $push_input = sub {
17             $input->{ $set->{label} || '_label' } = {
18             wait => $set->{wait},
19             do => $set->{do},
20 13   100 13   47 };
21 13         22 $set = {};
22 9         26 };
23              
24 9         21 while (@_) {
25 19         24 my $thing = shift;
26 19 50 100     145 my $type =
    100 33        
    100          
27             ( ref $thing eq 'CODE' ) ? 'do' :
28             ( ref $thing eq 'ARRAY' or not ref $thing and defined $thing and $thing =~ m/^[\d\.]+$/ ) ? 'wait' :
29             ( not ref $thing and defined $thing and $thing !~ m/^[\d\.]+$/ ) ? 'label' : 'error';
30              
31 19 50       31 croak('Unable to understand input provided; at least one thing provided is not a proper input')
32             if ( $type eq 'error' );
33              
34 19 100       34 $push_input->() if ( exists $set->{$type} );
35 19         40 $set->{$type} = $thing;
36             }
37              
38 9         17 $push_input->();
39 9         27 return $input;
40             }
41              
42             {
43             my $singleton;
44              
45             sub new {
46 4 100   4 1 88 if ($singleton) {
47 3         7 my $input = _input_handler(@_);
48 3         15 $singleton->{$_} = $input->{$_} for ( keys %$input );
49 3         14 return $singleton;
50             }
51              
52 1         3 shift;
53              
54 1         4 my $self = bless( _input_handler(@_), __PACKAGE__ );
55 1         2 $singleton = $self;
56 1         6 return $self;
57             }
58             }
59              
60             sub do {
61 5     5 1 967 my $self = shift;
62 5         11 my $input = _input_handler(@_);
63 5         6 my $total_wait = 0;
64              
65 5         14 for my $label ( keys %$input ) {
66 5   100     24 $input->{$label}{wait} //= $self->{$label}{wait} // 0;
      33        
67 5   100 1   21 $input->{$label}{do} ||= $self->{$label}{do} || sub {};
      66        
68              
69 5 100       9 if ( $self->{$label}{last} ) {
70 3         3 my $wait;
71 3 50       13 if ( ref $self->{$label}{wait} ) {
72 0   0     0 my $min = $self->{$label}{wait}[0] // 0;
73 0   0     0 my $max = $self->{$label}{wait}[1] // 0;
74 0         0 $wait = rand( $max - $min ) + $min;
75             }
76             else {
77 3         6 $wait = $self->{$label}{wait};
78             }
79              
80 3         10 my $sleep = $wait - ( time - $self->{$label}{last} );
81 3 50       7 if ( $sleep > 0 ) {
82 0         0 $total_wait += $sleep;
83 0         0 sleep($sleep);
84             }
85             }
86              
87 5         11 $self->{$label}{last} = time;
88 5         15 $self->{$label}{$_} = $input->{$label}{$_} for ( qw( do wait ) );
89              
90 5         18 push( @{ $self->{history} }, {
91             label => $label,
92             do => $self->{$label}{do},
93             wait => $self->{$label}{wait},
94 5         7 time => time,
95             } );
96              
97 5         10 $self->{$label}{do}->();
98             }
99              
100 5         18 return $total_wait;
101             }
102              
103             sub now {
104 1     1 1 5 return time;
105             }
106              
107             sub last {
108 4     4 1 517 my ( $self, $label, $time ) = @_;
109              
110 4 100       11 my $value_ref = ( defined $label ) ? \$self->{$label}{last} : \$self->history( undef, 1 )->[0]{time};
111 4 100       11 $$value_ref = $time if ( defined $time );
112              
113 4         14 return $$value_ref;
114             }
115              
116             sub history {
117 4     4 1 1270 my ( $self, $label, $last ) = @_;
118              
119 4   50     12 my $history = $self->{history} || [];
120 4 100       8 $history = [ grep { $_->{label} eq $label } @$history ] if ($label);
  10         16  
121 4 100       12 $history = [ grep { defined } @$history[ @$history - $last - 1, @$history - 1 ] ] if ( defined $last );
  4         7  
122              
123 4         9 return $history;
124             }
125              
126             sub sub {
127 3     3 1 236 my ( $self, $label, $sub ) = @_;
128              
129 3 50       9 my $value_ref = ( defined $label ) ? \$self->{$label}{do} : \$self->history( undef, 1 )->[0]{do};
130 3 100       8 $$value_ref = $sub if ( ref $sub eq 'CODE' );
131              
132 3         14 return $$value_ref;
133             }
134              
135             sub wait {
136 6     6 1 861 my ( $self, $label, $wait ) = @_;
137              
138 6 50       18 my $value_ref = ( defined $label ) ? \$self->{$label}{wait} : \$self->history( undef, 1 )->[0]{wait};
139 6 100       14 $$value_ref = $wait if ( defined $wait );
140              
141 6         22 return $$value_ref;
142             }
143              
144             sub wait_adjust {
145 3     3 1 40 my ( $self, $label, $wait_adjust ) = @_;
146              
147 3 50       8 my $value_ref = ( defined $label ) ? \$self->{$label}{wait} : \$self->history( undef, 1 )->[0]{wait};
148 3 100       9 if ( ref $$value_ref eq 'ARRAY' ) {
149 2         6 $_ += $wait_adjust for (@$$value_ref);
150             }
151             else {
152 1         3 $$value_ref += $wait_adjust;
153             }
154              
155 3         6 return $$value_ref;
156             }
157              
158             1;
159              
160             __END__