File Coverage

blib/lib/Time/DoAfter.pm
Criterion Covered Total %
statement 76 81 93.8
branch 31 38 81.5
condition 13 24 54.1
subroutine 15 15 100.0
pod 8 8 100.0
total 143 166 86.1


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