File Coverage

blib/lib/Deeme.pm
Criterion Covered Total %
statement 88 92 95.6
branch 26 28 92.8
condition 7 16 43.7
subroutine 16 17 94.1
pod 10 10 100.0
total 147 163 90.1


line stmt bran cond sub pod time code
1             package Deeme;
2 4     4   32258 use strict;
  4         7  
  4         130  
3 4     4   68 use 5.008_005;
  4         12  
  4         247  
4             our $VERSION = '0.05';
5 4     4   783 use Deeme::Obj -base;
  4         9  
  4         42  
6 4     4   20 use Carp 'croak';
  4         4  
  4         271  
7             has 'backend';
8 4     4   19 use Scalar::Util qw(blessed);
  4         6  
  4         372  
9 4   50 4   19 use constant DEBUG => $ENV{DEEME_DEBUG} || 0;
  4         460  
  4         4732  
10              
11             sub new {
12 4     4 1 516 my $self = shift;
13 4         31 $self = $self->SUPER::new(@_);
14 4 100       143 if ( !$self->backend ) {
15 2         503 require Deeme::Backend::Memory;
16 2         19 $self->backend( Deeme::Backend::Memory->new );
17             }
18 4         63 $self->backend->deeme($self);
19 4         7 return $self;
20             }
21              
22 1 50   1 1 457 sub catch { $_[0]->on( error => $_[1] ) and return $_[0] }
23              
24             sub emit {
25 30     30 1 1296 my ( $self, $name ) = ( shift, shift );
26              
27 30 100       674 if ( my $s = $self->backend->events_get($name) ) {
28 18         13 warn "-- Emit $name in @{[blessed $self]} (@{[scalar @$s]})\n"
29             if DEBUG;
30 18         300 my @onces = $self->backend->events_onces($name);
31 18         22 my $i = 0;
32 18         28 for my $cb (@$s) {
33 23 100 33     67 ( $onces[$i] == 1 )
34             ? ( splice( @onces, $i, 1 )
35             and $self->_unsubscribe_index( $name => $i ) )
36             : $i++;
37 23         51 $self->$cb(@_);
38             }
39             }
40             else {
41 12         12 warn "-- Emit $name in @{[blessed $self]} (0)\n" if DEBUG;
42 12 100       29 die "@{[blessed $self]}: $_[0]" if $name eq 'error';
  2         19  
43             }
44              
45 26         82 return $self;
46             }
47              
48             sub emit_safe {
49 5     5 1 427 my ( $self, $name ) = ( shift, shift );
50              
51 5 100       99 if ( my $s = $self->backend->events_get($name) ) {
52 4         6 warn "-- Emit $name in @{[blessed $self]} safely (@{[scalar @$s]})\n"
53             if DEBUG;
54 4         59 my @onces = $self->backend->events_onces($name);
55 4         5 my $i = 0;
56 4         7 for my $cb (@$s) {
57             $self->emit( error => qq{Event "$name" failed: $@} )
58 9 100       10 unless eval {
59 9 100 33     17 ( $onces[$i] == 1 )
60             ? ( splice( @onces, $i, 1 )
61             and $self->_unsubscribe_index( $name => $i ) )
62             : $i++;
63 9         19 $self->$cb(@_);
64 6         26 1;
65             };
66             }
67             }
68             else {
69 1         1 warn "-- Emit $name in @{[blessed $self]} safely (0)\n" if DEBUG;
70 1 50       4 die "@{[blessed $self]}: $_[0]" if $name eq 'error';
  1         11  
71             }
72              
73 3         9 return $self;
74             }
75              
76 3     3 1 7 sub has_subscribers { !!@{ shift->subscribers(shift) } }
  3         8  
77              
78             sub on {
79 11     11 1 811 my ( $self, $name, $cb ) = @_;
80 11         9 warn "-- on $name in @{[blessed $self]}\n"
81             if DEBUG;
82 11   50     201 return $self->backend->event_add( $name, $cb ||= [], 0 );
83             }
84              
85             sub once {
86 18     18 1 1362 my ( $self, $name, $cb ) = @_;
87 18         15 warn "-- once $name in @{[blessed $self]}\n"
88             if DEBUG;
89 18   50     361 return $self->backend->event_add( $name, $cb ||= [], 1 );
90             }
91              
92 18 100   18 1 365 sub subscribers { shift->backend->events_get( shift, 0 ) || [] }
93              
94             sub unsubscribe {
95 6     6 1 10 my ( $self, $name, $cb ) = @_;
96 6         6 warn "-- unsubscribe $name in @{[blessed $self]}\n"
97             if DEBUG;
98             # One
99 6 100       44 if ($cb) {
100 5         5 my @events = @{ $self->backend->events_get( $name, 0 ) };
  5         105  
101 5         82 my @onces = $self->backend->events_onces($name);
102              
103 5         17 my ($index) = grep { $cb eq $events[$_] } 0 .. $#events;
  12         28  
104 5 100       13 if ( defined $index ) {
105              
106 4         8 splice @events, $index, 1;
107 4         5 splice @onces, $index, 1;
108 4 100 50     23 $self->backend->event_delete($name) and return $self
109             unless @events;
110 3         53 $self->backend->event_update( $name, \@events, 0 );
111 3         57 $self->backend->once_update( $name, \@onces );
112             }
113             }
114              
115             # All
116 1         25 else { $self->backend->event_delete($name); }
117              
118 5         12 return $self;
119             }
120              
121             sub reset {
122 0     0 1 0 my $self = shift;
123 0         0 warn "-- events reset called in @{[blessed $self]}\n"
124             if DEBUG;
125 0         0 $self->backend->events_reset;
126 0         0 return $self;
127             }
128              
129             sub _unsubscribe_index {
130 17     17   19 my ( $self, $name, $index ) = @_;
131              
132 17         14 warn "-- unsubscribing $name (# $index) in @{[blessed $self]}\n"
133             if DEBUG;
134 17         12 my @events = @{ $self->backend->events_get( $name, 0 ) };
  17         275  
135 17         252 my @onces = $self->backend->events_onces($name);
136              
137 17         23 splice @events, $index, 1;
138 17         19 splice @onces, $index, 1;
139 17 100 50     213 $self->backend->event_delete($name) and return $self
140             unless @events;
141 4         66 $self->backend->event_update( $name, [@events], 0 );
142 4         65 $self->backend->once_update( $name, \@onces );
143              
144 4         10 return $self;
145             }
146              
147              
148             1;
149             __END__