File Coverage

blib/lib/AnyEvent/Delay/Simple.pm
Criterion Covered Total %
statement 122 122 100.0
branch 44 48 91.6
condition 2 3 66.6
subroutine 16 16 100.0
pod 2 2 100.0
total 186 191 97.3


line stmt bran cond sub pod time code
1             package AnyEvent::Delay::Simple;
2              
3 4     4   257628 use strict;
  4         11  
  4         155  
4 4     4   22 use warnings;
  4         10  
  4         121  
5              
6 4     4   1998 use AnyEvent ();
  4         7350  
  4         88  
7 4     4   28 use Scalar::Util qw(blessed);
  4         8  
  4         343  
8              
9 4     4   4168 use parent qw(Exporter);
  4         1466  
  4         22  
10              
11              
12             our $VERSION = '0.05';
13              
14              
15             our @EXPORT = qw(delay);
16             our @EXPORT_OK = qw(easy_delay);
17              
18              
19             sub import {
20 4     4   44 my ($class, @args) = @_;
21              
22 4         9 my (@ae, @up);
23              
24 4         11 foreach (@args) {
25 6 100 66     53 if ($_ && /^AE::(.+)?/) {
26 2         9 push(@ae, $1);
27             }
28             else {
29 4         9 push(@up, $_);
30             }
31             }
32 4 100       223 if (@ae) {
33 1         126 $class->export('AE', @ae);
34             }
35 4 100       2389 if (@up) {
36 2         6981 $class->export_to_level(1, undef, @up);
37             }
38             }
39              
40             sub delay {
41 7     7 1 46638 my ($obj, $fin);
42              
43 7 100       47 if (blessed($_[0])) {
44 2         4 $obj = shift();
45             }
46 7         14 $fin = pop();
47              
48 7 50       29 return unless $fin;
49              
50 7         12 my ($subs, $err);
51              
52 7 100       32 if (ref($_[0]) eq 'ARRAY') {
53 4         9 $subs = shift();
54 4         9 $err = pop();
55             }
56             else {
57 3         7 $err = pop();
58 3         7 $subs = \@_;
59             }
60              
61 7         200 my $cv = AE::cv;
62              
63 7         71 $cv->begin();
64             $cv->cb(sub {
65 3     3   33 _delay_step($obj, [$fin], undef, [$cv->recv()], $cv);
66 7         196 });
67 7         74 _delay_step($obj, $subs, $err, $cv);
68 7         38 $cv->end();
69              
70 7         40 return;
71             }
72              
73             sub _delay_step {
74 49     49   337 my $cv = pop();
75 49         82 my ($obj, $subs, $err, $args) = @_;
76              
77 49         83 my $sub = shift(@$subs);
78              
79 49 100       120 unless (defined($args)) {
80 7         18 $args = [];
81             }
82 49 100       120 unless ($sub) {
83 10         46 $cv->send(@$args);
84              
85 10         94 return;
86             }
87              
88 39         119 $cv->begin();
89             AE::postpone {
90 39     39   7341 my @res;
91 39         1147 my $xcv = AE::cv;
92              
93 39         272 $xcv->begin();
94 39 100       254 if ($err) {
95 22         29 eval {
96 22 100       91 $sub->($obj ? $obj : (), @$args, $xcv);
97             };
98 22 100       14854 if ($@) {
99 4         7 my $msg = $@;
100              
101 4         20 AE::log error => $msg;
102             $cv->cb(sub {
103 4         52 _delay_step($obj, [$err], undef, [$msg], $cv);
104 4         46199 });
105 4         79 $cv->send(@$args);
106 4         41 $cv->end();
107              
108 4         97 undef($xcv);
109             }
110             else {
111 18         69 _delay_step_ex($obj, $subs, $err, $xcv, $cv);
112             }
113             }
114             else {
115 17 100       76 $sub->($obj ? $obj : (), @$args, $xcv);
116 17         19276 _delay_step_ex($obj, $subs, $err, $xcv, $cv);
117             }
118 39         361 };
119              
120 39         356 return;
121             }
122              
123             sub _delay_step_ex {
124 35     35   85 my ($obj, $subs, $err, $xcv, $cv) = @_;
125              
126 35         101 my $cb = $xcv->cb();
127              
128             $xcv->cb(sub {
129 35 50   35   467 $cb->() if $cb;
130 35         116 _delay_step($obj, $subs, $err, [$xcv->recv()], $cv);
131 35         119 $cv->end();
132 35         330 });
133 35         370 $xcv->end();
134              
135 35         799 return;
136             }
137              
138             sub easy_delay {
139 7     7 1 34204 my ($obj, $fin);
140              
141 7 100       43 if (blessed($_[0])) {
142 2         5 $obj = shift();
143             }
144 7         23 $fin = pop();
145              
146 7 50       22 return unless $fin;
147              
148 7         13 my ($subs, $err);
149              
150 7 100       31 if (ref($_[0]) eq 'ARRAY') {
151 4         7 $subs = shift();
152 4         10 $err = pop();
153             }
154             else {
155 3         6 $err = pop();
156 3         8 $subs = \@_;
157             }
158              
159 7         265 my $cv = AE::cv;
160              
161 7         75 $cv->begin();
162             $cv->cb(sub {
163 4 100   4   53 $fin->($obj ? $obj : (), $cv->recv());
164 7         78 });
165 7         65 _easy_delay_step($obj, $subs, $err, $cv);
166 7         22 $cv->end();
167              
168 7         37 return;
169             }
170              
171             sub _easy_delay_step {
172 40     40   62 my ($cv) = pop();
173 40         59 my ($obj, $subs, $err, $args) = @_;
174              
175 40         52 my $sub = shift(@$subs);
176              
177 40 100       99 unless (defined($args)) {
178 7         16 $args = [];
179             }
180 40 100       79 unless ($sub) {
181 4         18 $cv->send(@$args);
182              
183 4         3572 return;
184             }
185              
186 36         108 $cv->begin();
187             AE::postpone {
188 36     36   6134 my @res;
189              
190 36 100       79 if ($err) {
191 16         22 eval {
192 16 100       144 @res = $sub->($obj ? $obj : (), @$args);
193             };
194 16 100       5701 if ($@) {
195 3         5 my $msg = $@;
196              
197 3         17 AE::log error => $msg;
198             $cv->cb(sub {
199 3 100       38 $err->($obj ? $obj : (), $msg);
200 3         237 });
201 3         41 $cv->send(@$args);
202             }
203             else {
204 13         50 _easy_delay_step($obj, $subs, $err, \@res, $cv);
205             }
206             }
207             else {
208 20 50       64 @res = $sub->($obj ? $obj : (), @$args);
209 20         91 _easy_delay_step($obj, $subs, $err, \@res, $cv);
210             }
211 36         2389 $cv->end();
212 36         313 };
213              
214 36         203 return;
215             }
216              
217              
218             1;
219              
220              
221             __END__