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   169613 use 5.010;
  1         8  
5 1     1   4 use strict;
  1         1  
  1         13  
6 1     1   3 use warnings;
  1         2  
  1         18  
7              
8 1     1   3 use Carp 'croak';
  1         1  
  1         36  
9 1     1   4 use Time::HiRes qw( time sleep );
  1         1  
  1         8  
10              
11             our $VERSION = '1.08'; # VERSION
12              
13             sub _input_handler {
14 9     9   15 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   44 };
21 13         22 $set = {};
22 9         22 };
23              
24 9         26 while (@_) {
25 19         25 my $thing = shift;
26 19 50 100     116 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       28 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       44 $push_input->() if ( exists $set->{$type} );
35 19         37 $set->{$type} = $thing;
36             }
37              
38 9         14 $push_input->();
39 9         23 return $input;
40             }
41              
42             {
43             my $singleton;
44              
45             sub new {
46 4 100   4 1 84 if ($singleton) {
47 3         6 my $input = _input_handler(@_);
48 3         13 $singleton->{$_} = $input->{$_} for ( keys %$input );
49 3         14 return $singleton;
50             }
51              
52 1         2 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 818 my $self = shift;
62 5         8 my $input = _input_handler(@_);
63 5         6 my $total_wait = 0;
64              
65 5         14 for my $label ( keys %$input ) {
66 5   100     22 $input->{$label}{wait} //= $self->{$label}{wait} // 0;
      33        
67 5   100 1   19 $input->{$label}{do} ||= $self->{$label}{do} || sub {};
      66        
68              
69 5 100       10 if ( $self->{$label}{last} ) {
70 3         3 my $wait;
71 3 50       6 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         4 $wait = $self->{$label}{wait};
78             }
79              
80 3         9 my $sleep = $wait - ( time - $self->{$label}{last} );
81 3 50       8 if ( $sleep > 0 ) {
82 0         0 $total_wait += $sleep;
83 0         0 sleep($sleep);
84             }
85             }
86              
87 5         12 $self->{$label}{last} = time;
88 5         13 $self->{$label}{$_} = $input->{$label}{$_} for ( qw( do wait ) );
89              
90 5         17 push( @{ $self->{history} }, {
91             label => $label,
92             do => $self->{$label}{do},
93             wait => $self->{$label}{wait},
94 5         6 time => time,
95             } );
96              
97 5         9 $self->{$label}{do}->();
98             }
99              
100 5         16 return $total_wait;
101             }
102              
103             sub now {
104 1     1 1 6 return time;
105             }
106              
107             sub last {
108 4     4 1 443 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       9 $$value_ref = $time if ( defined $time );
112              
113 4         15 return $$value_ref;
114             }
115              
116             sub history {
117 4     4 1 1095 my ( $self, $label, $last ) = @_;
118              
119 4   50     10 my $history = $self->{history} || [];
120 4 100       8 $history = [ grep { $_->{label} eq $label } @$history ] if ($label);
  10         17  
121 4 100       8 $history = [ grep { defined } @$history[ @$history - $last - 1, @$history - 1 ] ] if ( defined $last );
  4         8  
122              
123 4         9 return $history;
124             }
125              
126             sub sub {
127 3     3 1 208 my ( $self, $label, $sub ) = @_;
128              
129 3 50       7 my $value_ref = ( defined $label ) ? \$self->{$label}{do} : \$self->history( undef, 1 )->[0]{do};
130 3 100       18 $$value_ref = $sub if ( ref $sub eq 'CODE' );
131              
132 3         16 return $$value_ref;
133             }
134              
135             sub wait {
136 6     6 1 752 my ( $self, $label, $wait ) = @_;
137              
138 6 50       16 my $value_ref = ( defined $label ) ? \$self->{$label}{wait} : \$self->history( undef, 1 )->[0]{wait};
139 6 100       13 $$value_ref = $wait if ( defined $wait );
140              
141 6         23 return $$value_ref;
142             }
143              
144             sub wait_adjust {
145 3     3 1 38 my ( $self, $label, $wait_adjust ) = @_;
146              
147 3 50       9 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         2 $$value_ref += $wait_adjust;
153             }
154              
155 3         4 return $$value_ref;
156             }
157              
158             1;
159              
160             __END__