File Coverage

blib/lib/Notification/Center.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             package Notification::Center;
2              
3 1     1   39556 use Moose;
  0            
  0            
4             use Scalar::Util qw(refaddr);
5             use Set::Object;
6              
7             our $AUTHORITY = 'CPAN:RLB';
8             our $VERSION = '0.0.5';
9              
10             has observers => (
11             is => 'ro',
12             isa => 'HashRef[Set::Object]',
13             default => sub {
14             { DEFAULT => Set::Object->new };
15             }
16             );
17              
18             has method_calls => (
19             is => 'ro',
20             isa => 'HashRef',
21             default => sub { {} }
22             );
23              
24             my $instance;
25             sub default {
26             return $instance ||= Notification::Center->new;
27             };
28              
29             sub add {
30             my ( $self, $args ) = @_;
31              
32             my $event = $args->{'event'} || 'DEFAULT';
33             my $observer = $args->{'observer'};
34             my $method = $args->{'method'} || 'update';
35              
36             $self->observers->{$event} ||= Set::Object->new;
37              
38             $self->observers->{$event}->insert($observer);
39             $self->method_calls->{ refaddr $observer }->{$event} = $method;
40             }
41              
42             sub remove {
43             my ( $self, $args ) = @_;
44              
45             my $event = $args->{'event'} || 'DEFAULT';
46             my $observer = $args->{'observer'};
47              
48             delete $self->method_calls->{ refaddr $observer }->{$event};
49             $self->observers->{$event}->remove($observer);
50             }
51              
52             sub notify {
53             my ( $self, $args ) = @_;
54              
55             my $event = $args->{'event'};
56              
57             return if !exists $self->observers->{$event};
58              
59             my $observers;
60             if ( $event ne 'DEFAULT' ) {
61             $observers = Set::Object->new( $self->observers->{$event}->members, $self->observers->{'DEFAULT'}->members );
62             }
63             else {
64             $observers = $self->observers->{$event};
65             }
66              
67             foreach my $observer ( $observers->members ) {
68             my $method = $self->method_calls->{ refaddr $observer }->{$event} ||
69             $self->method_calls->{ refaddr $observer }->{'DEFAULT'};
70             $observer->$method($args->{'args'}) if $observer->can($method);
71             }
72             }
73              
74             1;
75              
76             __END__
77              
78             =pod
79              
80             =head1 NAME
81              
82             Notification::Center - An observer/notification for perl
83              
84             =head1 SYNOPSIS
85              
86             {
87              
88             package Counter;
89              
90             use Moose;
91             use Notification::Center;
92              
93             has count => ( is => 'rw', isa => 'Int', default => 0 );
94              
95             sub inc {
96             my ($self) = @_;
97             $self->count( $self->count + 1 );
98             my $nc = Notification::Center->default;
99             $nc->notify( { event => 'count', args => $self->count } );
100             }
101              
102             sub dec {
103             my ($self) = @_;
104             $self->count( $self->count - 1 );
105             my $nc = Notification::Center->default;
106             $nc->notify( { event => 'count', args => $self->count } );
107             }
108              
109             no Moose;
110              
111             package TrackCount;
112              
113             use Moose;
114              
115             has count => ( is => 'rw', isa => 'Int', default => 0 );
116              
117             sub print {
118             my ($self) = @_;
119             print $self->count;
120             }
121              
122             sub get_count {
123             my ( $self, $count ) = @_;
124             $self->count($count);
125             }
126              
127             no Moose;
128             }
129              
130             my $count = Counter->new;
131              
132             my $mn = Notification::Center->default;
133             my $tc = TrackCount->new;
134             $mn->add(
135             {
136             observer => $tc,
137             event => 'count',
138             method => 'get_count',
139             }
140             );
141              
142             for ( 1 .. 10 ) {
143             $count->inc;
144             }
145             for ( 1 .. 5 ) {
146             $count->dec;
147             }
148              
149             $tc->print; # 5
150              
151              
152             or use IOC using Bread::Board
153              
154             use Bread::Board;
155              
156             my $c = container 'TestApp' => as {
157              
158             service 'fname' => 'Larry';
159             service 'lname' => 'Wall';
160              
161             service 'notification_center' => (
162             class => 'Notification::Center',
163             lifecycle => 'Singleton',
164             );
165              
166             service 'person' => (
167             class => 'Person',
168             dependencies => {
169             notification => depends_on('notification_center'),
170             fname => depends_on('fname'),
171             lname => depends_on('lname'),
172             },
173             );
174              
175             service 'upn' => (
176             class => 'UCPrintName',
177             dependencies => { notification => depends_on('notification_center') },
178             );
179              
180             service 'pn' => (
181             class => 'PrintName',
182             dependencies => { notification => depends_on('notification_center'), },
183             );
184             };
185              
186             my $pn = $c->fetch('pn')->get;
187             my $upn = $c->fetch('upn')->get;
188             my $person = $c->fetch('person')->get;
189             my $nc = $c->fetch('notification_center')->get;
190              
191             $person->print_name;
192             $nc->remove( { observer => $upn } );
193             $person->print_name;
194              
195              
196             =head1 DESCRIPTION
197              
198             An observer/notification center based on the objective-c NSNotificationCenter Class
199              
200             =over
201              
202             =item new
203              
204             The method creates a new instance of Notification::Center object
205              
206             =item default
207              
208             This method creates a singleton of the Notification::Center object
209              
210             =item add
211              
212             args keys: observer, event, method
213              
214             observer: the object that will observer events
215              
216             event: the name of the event that you are assigning the observer. Defaults to DEFAULT
217              
218             method: the method you want called on the observer when the event is called. Defaults to update
219              
220             =item remove
221              
222             args keys: observer, event
223              
224             observer: the object that you want to remove
225              
226             event: the name of the event that you are removing the observer. Defaults to DEFAULT
227              
228             =item notify
229              
230             args keys : event, args
231              
232             event: the event you want to trigger
233              
234             args: data you want to pass into observers
235              
236             =back
237              
238             =head1 GIT Repository
239              
240             http://github.com/rlb3/notification-center/tree/master
241              
242             =cut