File Coverage

blib/lib/POE/Component/Pluggable/Pipeline.pm
Criterion Covered Total %
statement 12 196 6.1
branch 0 88 0.0
condition 0 4 0.0
subroutine 4 20 20.0
pod 13 13 100.0
total 29 321 9.0


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