File Coverage

blib/lib/POE/Component/Pluggable/Pipeline.pm
Criterion Covered Total %
statement 63 196 32.1
branch 15 88 17.0
condition 0 4 0.0
subroutine 10 20 50.0
pod 13 13 100.0
total 101 321 31.4


line stmt bran cond sub pod time code
1             package POE::Component::Pluggable::Pipeline;
2             $POE::Component::Pluggable::Pipeline::VERSION = '1.28';
3             #ABSTRACT: the plugin pipeline for POE::Component::Pluggable
4              
5 1     1   6 use strict;
  1         2  
  1         41  
6 1     1   6 use warnings;
  1         1  
  1         30  
7 1     1   5 use Carp;
  1         2  
  1         71  
8 1     1   6 use Scalar::Util qw(weaken);
  1         1  
  1         2310  
9              
10             sub new {
11 1     1 1 2 my ($package, $pluggable) = @_;
12              
13 1         6 my $self = bless {
14             PLUGS => {},
15             PIPELINE => [],
16             HANDLES => {},
17             OBJECT => $pluggable,
18             }, $package;
19              
20 1         6 weaken($self->{OBJECT});
21              
22 1         3 return $self;
23             }
24              
25             sub push {
26 1     1 1 2 my ($self, $alias, $plug) = @_;
27              
28 1 50       3 if ($self->{PLUGS}{$alias}) {
29 0         0 $@ = "Plugin named '$alias' already exists ($self->{PLUGS}{$alias})";
30 0         0 return;
31             }
32              
33 1         10 my $return = $self->_register($alias, $plug);
34 1 50       3 return if !$return;
35              
36 1         1 push @{ $self->{PIPELINE} }, $plug;
  1         2  
37 1         1 return scalar @{ $self->{PIPELINE} };
  1         2  
38             }
39              
40             sub pop {
41 0     0 1 0 my ($self) = @_;
42              
43 0 0       0 return if !@{ $self->{PIPELINE} };
  0         0  
44              
45 0         0 my $plug = pop @{ $self->{PIPELINE} };
  0         0  
46 0         0 my $alias = $self->{PLUGS}{$plug};
47 0         0 $self->_unregister($alias, $plug);
48              
49 0 0       0 return wantarray ? ($plug, $alias) : $plug;
50             }
51              
52             sub unshift {
53 0     0 1 0 my ($self, $alias, $plug) = @_;
54              
55 0 0       0 if ($self->{PLUGS}{$alias}) {
56 0         0 $@ = "Plugin named '$alias' already exists ($self->{PLUGS}{$alias}";
57 0         0 return;
58             }
59              
60 0         0 my $return = $self->_register($alias, $plug);
61 0 0       0 return if !$return;
62              
63 0         0 unshift @{ $self->{PIPELINE} }, $plug;
  0         0  
64 0         0 return scalar @{ $self->{PIPELINE} };
  0         0  
65             }
66              
67             sub shift {
68 0     0 1 0 my ($self) = @_;
69              
70 0 0       0 return if !@{ $self->{PIPELINE} };
  0         0  
71              
72 0         0 my $plug = shift @{ $self->{PIPELINE} };
  0         0  
73 0         0 my $alias = $self->{PLUGS}{$plug};
74 0         0 $self->_unregister($alias, $plug);
75              
76 0 0       0 return wantarray ? ($plug, $alias) : $plug;
77             }
78              
79             sub replace {
80 0     0 1 0 my ($self, $old, $new_a, $new_p) = @_;
81              
82             my ($old_a, $old_p) = ref $old
83             ? ($self->{PLUGS}{$old}, $old)
84 0 0       0 : ($old, $self->{PLUGS}{$old})
85             ;
86              
87 0 0       0 if (!$old_p) {
88 0         0 $@ = "Plugin '$old_a' does not exist";
89 0         0 return;
90             }
91              
92 0         0 $self->_unregister($old_a, $old_p);
93              
94 0 0       0 if ($self->{PLUGS}{$new_a}) {
95 0         0 $@ = "Plugin named '$new_a' already exists ($self->{PLUGS}{$new_a}";
96 0         0 return;
97             }
98              
99 0         0 my $return = $self->_register($new_a, $new_p);
100 0 0       0 return if !$return;
101              
102 0         0 for my $plugin (@{ $self->{PIPELINE} }) {
  0         0  
103 0 0       0 if ($plugin == $old_p) {
104 0         0 $plugin = $new_p;
105 0         0 last;
106             }
107             }
108              
109 0         0 return 1;
110             }
111              
112             sub remove {
113 1     1 1 1 my ($self, $old) = @_;
114             my ($old_a, $old_p) = ref $old
115             ? ($self->{PLUGS}{$old}, $old)
116 1 50       8 : ($old, $self->{PLUGS}{$old})
117             ;
118              
119 1 50       3 if (!$old_p) {
120 0         0 $@ = "Plugin '$old_a' does not exist";
121 0         0 return;
122             }
123              
124 1         2 my $i = 0;
125 1         1 for my $plugin (@{ $self->{PIPELINE} }) {
  1         3  
126 1 50       3 if ($plugin == $old_p) {
127 1         1 splice(@{ $self->{PIPELINE} }, $i, 1);
  1         2  
128 1         2 last;
129             }
130 0         0 $i++;
131             }
132              
133 1         4 $self->_unregister($old_a, $old_p);
134              
135 1 50       3 return wantarray ? ($old_p, $old_a) : $old_p;
136             }
137              
138             sub get {
139 4     4 1 5 my ($self, $old) = @_;
140              
141             my ($old_a, $old_p) = ref $old
142             ? ($self->{PLUGS}{$old}, $old)
143 4 50       14 : ($old, $self->{PLUGS}{$old})
144             ;
145              
146              
147 4 50       5 if (!$old_p) {
148 0         0 $@ = "Plugin '$old_a' does not exist";
149 0         0 return;
150             }
151              
152 4 50       13 return wantarray ? ($old_p, $old_a) : $old_p;
153             }
154              
155             sub get_index {
156 0     0 1 0 my ($self, $old) = @_;
157              
158             my ($old_a, $old_p) = ref $old
159             ? ($self->{PLUGS}{$old}, $old)
160 0 0       0 : ($old, $self->{PLUGS}{$old})
161             ;
162              
163 0 0       0 if (!$old_p) {
164 0         0 $@ = "Plugin '$old_a' does not exist";
165 0         0 return -1;
166             }
167              
168 0         0 my $i = 0;
169 0         0 for my $plugin (@{ $self->{PIPELINE} }) {
  0         0  
170 0 0       0 return $i if $plugin == $old_p;
171 0         0 $i++;
172             }
173              
174 0         0 return -1;
175             }
176              
177             sub insert_before {
178 0     0 1 0 my ($self, $old, $new_a, $new_p) = @_;
179              
180             my ($old_a, $old_p) = ref $old
181             ? ($self->{PLUGS}{$old}, $old)
182 0 0       0 : ($old, $self->{PLUGS}{$old})
183             ;
184              
185 0 0       0 if (!$old_p) {
186 0         0 $@ = "Plugin '$old_a' does not exist";
187 0         0 return;
188             }
189              
190 0 0       0 if ($self->{PLUGS}{$new_a}) {
191 0         0 $@ = "Plugin named '$new_a' already exists ($self->{PLUGS}{$new_a}";
192 0         0 return;
193             }
194              
195 0         0 my $return = $self->_register($new_a, $new_p);
196 0 0       0 return if !$return;
197              
198 0         0 my $i = 0;
199 0         0 for my $plugin (@{ $self->{PIPELINE} }) {
  0         0  
200 0 0       0 if ($plugin == $old_p) {
201 0         0 splice(@{ $self->{PIPELINE} }, $i, 0, $new_p);
  0         0  
202 0         0 last;
203             }
204 0         0 $i++;
205             }
206              
207 0         0 return 1;
208             }
209              
210             sub insert_after {
211 0     0 1 0 my ($self, $old, $new_a, $new_p) = @_;
212             my ($old_a, $old_p) = ref $old
213             ? ($self->{PLUGS}{$old}, $old)
214 0 0       0 : ($old, $self->{PLUGS}{$old})
215             ;
216              
217 0 0       0 if (!$old_p) {
218 0         0 $@ = "Plugin '$old_a' does not exist";
219 0         0 return;
220             }
221              
222 0 0       0 if ($self->{PLUGS}{$new_a}) {
223 0         0 $@ = "Plugin named '$new_a' already exists ($self->{PLUGS}{$new_a}";
224 0         0 return;
225             }
226              
227 0         0 my $return = $self->_register($new_a, $new_p);
228 0 0       0 return if !$return;
229              
230 0         0 my $i = 0;
231 0         0 for my $plugin (@{ $self->{PIPELINE} }) {
  0         0  
232 0 0       0 if ($plugin == $old_p) {
233 0         0 splice(@{ $self->{PIPELINE} }, $i+1, 0, $new_p);
  0         0  
234 0         0 last;
235             }
236 0         0 $i++;
237             }
238              
239 0         0 return 1;
240             }
241              
242             sub bump_up {
243 0     0 1 0 my ($self, $old, $diff) = @_;
244 0         0 my $idx = $self->get_index($old);
245              
246 0 0       0 return -1 if $idx < 0;
247              
248 0         0 my $pipeline = $self->{PIPELINE};
249 0   0     0 $diff ||= 1;
250              
251 0         0 my $pos = $idx - $diff;
252              
253 0 0       0 if ($pos < 0) {
254 0         0 carp "$idx - $diff is negative, moving to head of the pipeline";
255             }
256              
257 0         0 splice(@$pipeline, $pos, 0, splice(@$pipeline, $idx, 1));
258 0         0 return $pos;
259             }
260              
261             sub bump_down {
262 0     0 1 0 my ($self, $old, $diff) = @_;
263 0         0 my $idx = $self->get_index($old);
264              
265 0 0       0 return -1 if $idx < 0;
266              
267 0         0 my $pipeline = $self->{PIPELINE};
268 0   0     0 $diff ||= 1;
269              
270 0         0 my $pos = $idx + $diff;
271              
272 0 0       0 if ($pos >= @$pipeline) {
273 0         0 carp "$idx + $diff is too high, moving to back of the pipeline";
274             }
275              
276 0         0 splice(@$pipeline, $pos, 0, splice(@$pipeline, $idx, 1));
277 0         0 return $pos;
278             }
279              
280             sub _register {
281 1     1   2 my ($self, $alias, $plug) = @_;
282 1 50       4 return if !defined $self->{OBJECT};
283              
284 1         1 my $return;
285 1         3 my $sub = "$self->{OBJECT}{_pluggable_reg_prefix}register";
286 1         1 eval { $return = $plug->$sub($self->{OBJECT}) };
  1         6  
287              
288 1 50       9 if ($@) {
    50          
289 0         0 chomp $@;
290 0         0 my $error = "$sub call on plugin '$alias' failed: $@";
291 0         0 $self->_handle_error($error, $plug, $alias);
292             }
293             elsif (!$return) {
294 0         0 my $error = "$sub call on plugin '$alias' did not return a true value";
295 0         0 $self->_handle_error($error, $plug, $alias);
296             }
297              
298 1         2 $self->{PLUGS}{$plug} = $alias;
299 1         2 $self->{PLUGS}{$alias} = $plug;
300              
301             $self->{OBJECT}->_pluggable_event(
302 1         6 "$self->{OBJECT}{_pluggable_prefix}plugin_add",
303             $alias, $plug,
304             );
305              
306 1         85 return $return;
307             }
308              
309             sub _unregister {
310 1     1   2 my ($self, $alias, $plug) = @_;
311 1 50       2 return if !defined $self->{OBJECT};
312              
313 1         2 my $return;
314 1         3 my $sub = "$self->{OBJECT}{_pluggable_reg_prefix}unregister";
315 1         1 eval { $return = $plug->$sub($self->{OBJECT}) };
  1         5  
316              
317 1 50       182 if ($@) {
    50          
318 0         0 chomp $@;
319 0         0 my $error = "$sub call on plugin '$alias' failed: $@";
320 0         0 $self->_handle_error($error, $plug, $alias);
321             }
322             elsif (!$return) {
323 0         0 my $error = "$sub call on plugin '$alias' did not return a true value";
324 0         0 $self->_handle_error($error, $plug, $alias);
325             }
326              
327 1         3 delete $self->{PLUGS}{$plug};
328 1         2 delete $self->{PLUGS}{$alias};
329 1         2 delete $self->{HANDLES}{$plug};
330              
331             $self->{OBJECT}->_pluggable_event(
332 1         4 "$self->{OBJECT}{_pluggable_prefix}plugin_del",
333             $alias, $plug,
334             );
335              
336 1         53 return $return;
337             }
338              
339             sub _handle_error {
340 0     0     my ($self, $error, $plugin, $alias) = @_;
341              
342 0 0         warn "$error\n" if $self->{OBJECT}{_pluggable_debug};
343             $self->{OBJECT}->_pluggable_event(
344 0           "$self->{OBJECT}{_pluggable_prefix}plugin_error",
345             $error, $plugin, $alias,
346             );
347              
348 0           return;
349             }
350              
351             qq[Pipey McPipeline];
352              
353             __END__