File Coverage

blib/lib/Serengeti/NotificationCenter.pm
Criterion Covered Total %
statement 37 43 86.0
branch 10 22 45.4
condition 6 19 31.5
subroutine 8 9 88.8
pod 0 5 0.0
total 61 98 62.2


line stmt bran cond sub pod time code
1             package Serengeti::NotificationCenter;
2              
3 1     1   30828 use strict;
  1         2  
  1         43  
4 1     1   5 use warnings;
  1         2  
  1         30  
5              
6 1     1   4 use Carp qw(croak);
  1         2  
  1         70  
7 1     1   5 use Scalar::Util qw(blessed refaddr);
  1         2  
  1         672  
8              
9             {
10             my $DefaultCenter;
11             sub default_center {
12 4 100   4 0 23 return $DefaultCenter if $DefaultCenter;
13            
14 1   50     6 my $pkg = shift || __PACKAGE__;
15 1         4 $DefaultCenter = $pkg->new;
16            
17 1         7 return $DefaultCenter;
18             }
19             }
20              
21             sub new {
22 1     1 0 4 my ($pkg) = @_;
23            
24 1         4 return bless [], $pkg;
25             }
26              
27             sub add_observer {
28 2     2 0 39 my ($self, $target, %args) = @_;
29            
30             # Default to default_center
31 2 50       14 $self = default_center unless blessed $self;
32            
33 2 50       5 croak "Missing 'selector' argument" unless $args{selector};
34            
35 2         4 my $for = $args{for};
36 2 50 0     6 if ($for && !(ref $for eq "CODE" || ref $for eq "")) {
      33        
37 0         0 croak "Invalid argument 'for'. Must be scalar or code reference";
38             }
39            
40 2   50     15 my $from = refaddr $args{sender} || 0;
41 2         5 my $selector = $args{selector};
42            
43 2         5 push @$self, [$target, $selector, $for, $from];
44            
45 2         7 1;
46             }
47              
48             sub post_notification {
49 1     1 0 2 my ($self, $sender, $notification, $data, $target) = @_;
50            
51             # Default to default_center
52 1 50       10 $self = default_center unless blessed $self;
53            
54 1         3 for my $observation (@$self) {
55 2         4 my ($observer, $selector, $for, $from) = @$observation;
56 2 50 33     6 next if $for && $for ne $notification;
57 2 50 33     6 next if $from && $from != refaddr $sender;
58 2 50 33     6 next if $target && $target != refaddr $observer;
59            
60 2         3 eval {
61 2         6 $observer->$selector($sender, $notification, $data);
62             };
63            
64 2 50       11 warn "$@" if $@;
65             }
66             }
67              
68             sub remove_observer {
69 0     0 0   my ($self, $target) = @_;
70            
71             # Default to default_center
72 0 0         $self = default_center unless blessed $self;
73              
74 0 0         @$self = grep { defined $_->[0] && refaddr $_->[0] != refaddr $target } @$self;
  0            
75            
76 0           1;
77             }
78              
79             1;