File Coverage

blib/lib/AnyEvent/Delay/Simple.pm
Criterion Covered Total %
statement 129 130 99.2
branch 47 52 90.3
condition 2 3 66.6
subroutine 18 18 100.0
pod 2 2 100.0
total 198 205 96.5


line stmt bran cond sub pod time code
1             package AnyEvent::Delay::Simple;
2              
3 8     8   454213 use strict;
  8         19  
  8         408  
4 8     8   48 use warnings;
  8         17  
  8         396  
5              
6 8     8   1633 use AnyEvent ();
  8         6331  
  8         165  
7 8     8   48 use Scalar::Util qw(blessed);
  8         12  
  8         764  
8              
9 8     8   7493 use parent qw(Exporter);
  8         3308  
  8         46  
10              
11              
12             our $VERSION = '0.06';
13              
14              
15             our @EXPORT = qw(delay);
16             our @EXPORT_OK = qw(easy_delay);
17              
18              
19             sub import {
20 8     8   87 my ($class, @args) = @_;
21              
22 8         17 my (@ae, @up);
23              
24 8         23 foreach (@args) {
25 11 100 66     104 if ($_ && /^AE::(.+)?/) {
26 2         7 push(@ae, $1);
27             }
28             else {
29 9         31 push(@up, $_);
30             }
31             }
32 8 100       38 if (@ae) {
33 1         127 $class->export('AE', @ae);
34             }
35 8 100       1872 if (@up) {
36 6         470911 $class->export_to_level(1, undef, @up);
37             }
38             }
39              
40             sub delay {
41 8     8 1 41568 my ($obj, $fin);
42              
43 8 100       55 if (blessed($_[0])) {
44 2         4 $obj = shift();
45             }
46 8         18 $fin = pop();
47              
48 8 50       31 return unless $fin;
49              
50 8         18 my ($subs, $err);
51              
52 8 100       37 if (ref($_[0]) eq 'ARRAY') {
53 3         6 $subs = shift();
54 3         7 $err = pop();
55             }
56             else {
57 5         9 $err = pop();
58 5         15 $subs = \@_;
59             }
60              
61 8         213 my $cv = AE::cv;
62              
63 8         186 $cv->begin();
64             $cv->cb(sub {
65 3     3   29 _delay_step($obj, [$fin], undef, [$cv->recv()], $cv);
66 8         337 });
67 8         126 _delay_step($obj, $subs, $err, $cv);
68 8         45 $cv->end();
69              
70 8         43 return;
71             }
72              
73             sub _delay_step {
74 49     49   435 my $cv = pop();
75 49         82 my ($obj, $subs, $err, $args) = @_;
76              
77 49         76 my $sub = shift(@$subs);
78              
79 49 100       203 unless (defined($args)) {
80 8         16 $args = [];
81             }
82 49 100       108 unless ($sub) {
83 11         43 $cv->send(@$args);
84              
85 11         84 return;
86             }
87              
88 38         114 $cv->begin();
89             AE::postpone {
90 38     38   11156 my @res;
91 38         1206 my $xcv = AE::cv;
92              
93 38         332 $xcv->begin();
94 38 100       284 if ($err) {
95 20         29 eval {
96 20 100       93 $sub->($obj ? $obj : (), @$args, $xcv);
97             };
98 20 100       14483 if ($@) {
99 4         14 _delay_err($obj, $err, $@, $cv);
100 4         73 undef($xcv);
101             }
102             else {
103 16         74 _delay_step_ex($obj, $subs, $err, $xcv, $cv);
104             }
105             }
106             else {
107 18 100       86 $sub->($obj ? $obj : (), @$args, $xcv);
108 18         23373 _delay_step_ex($obj, $subs, $err, $xcv, $cv);
109             }
110 38         327 };
111              
112 38         335 return;
113             }
114              
115             sub _delay_step_ex {
116 34     34   83 my ($obj, $subs, $err, $xcv, $cv) = @_;
117              
118 34         138 my $cb = $xcv->cb();
119              
120             $xcv->cb(sub {
121 34 100   34   460 if ($cb) {
122 1 50       3 if ($err) {
123 1         2 eval {
124 1         3 $cb->();
125             };
126 1 50       20 if ($@) {
127 1         5 _delay_err($obj, $err, $@, $cv);
128              
129 1         3 return;
130             }
131             }
132             else {
133 0         0 $cb->();
134             }
135             }
136 33         138 _delay_step($obj, $subs, $err, [$xcv->recv()], $cv);
137 33         171 $cv->end();
138 34         765 });
139 34         479 $xcv->end();
140              
141 34         807 return;
142             }
143              
144             sub _delay_err {
145 5     5   14 my ($obj, $err, $msg, $cv) = @_;
146              
147 5         22 AE::log error => $msg;
148              
149             $cv->cb(sub {
150 5     5   132 _delay_step($obj, [$err], undef, [$msg], $cv);
151 5         44727 });
152 5         101 $cv->end();
153              
154 5         46 return;
155             }
156              
157             sub easy_delay {
158 7     7 1 36514 my ($obj, $fin);
159              
160 7 100       47 if (blessed($_[0])) {
161 2         4 $obj = shift();
162             }
163 7         16 $fin = pop();
164              
165 7 50       23 return unless $fin;
166              
167 7         10 my ($subs, $err);
168              
169 7 100       28 if (ref($_[0]) eq 'ARRAY') {
170 3         7 $subs = shift();
171 3         4 $err = pop();
172             }
173             else {
174 4         8 $err = pop();
175 4         11 $subs = \@_;
176             }
177              
178 7         182 my $cv = AE::cv;
179              
180 7         59 $cv->begin();
181             $cv->cb(sub {
182 3 100   3   35 $fin->($obj ? $obj : (), $cv->recv());
183 7         149 });
184 7         62 _easy_delay_step($obj, $subs, $err, $cv);
185 7         28 $cv->end();
186              
187 7         34 return;
188             }
189              
190             sub _easy_delay_step {
191 31     31   43 my ($cv) = pop();
192 31         45 my ($obj, $subs, $err, $args) = @_;
193              
194 31         44 my $sub = shift(@$subs);
195              
196 31 100       74 unless (defined($args)) {
197 7         13 $args = [];
198             }
199 31 100       60 unless ($sub) {
200 3         11 $cv->send(@$args);
201              
202 3         3855 return;
203             }
204              
205 28         79 $cv->begin();
206             AE::postpone {
207 28     28   6244 my @res;
208              
209 28 100       55 if ($err) {
210 18         21 eval {
211 18 100       70 @res = $sub->($obj ? $obj : (), @$args);
212             };
213 18 100       10961 if ($@) {
214 4         10 my $msg = $@;
215              
216 4         19 AE::log error => $msg;
217              
218             $cv->cb(sub {
219 4 100       71 $err->($obj ? $obj : (), $msg);
220 4         6396 });
221 4         97 $cv->send(@$args);
222             }
223             else {
224 14         39 _easy_delay_step($obj, $subs, $err, \@res, $cv);
225             }
226             }
227             else {
228 10 50       29 @res = $sub->($obj ? $obj : (), @$args);
229 10         39 _easy_delay_step($obj, $subs, $err, \@res, $cv);
230             }
231 28         3457 $cv->end();
232 28         278 };
233              
234 28         206 return;
235             }
236              
237              
238             1;
239              
240              
241             __END__