File Coverage

blib/lib/Time/DoAfter.pm
Criterion Covered Total %
statement 78 83 93.9
branch 31 38 81.5
condition 14 25 56.0
subroutine 16 16 100.0
pod 8 8 100.0
total 147 170 86.4


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