File Coverage

blib/lib/ONE/Timer.pm
Criterion Covered Total %
statement 68 75 90.6
branch 11 16 68.7
condition n/a
subroutine 16 18 88.8
pod 7 7 100.0
total 102 116 87.9


line stmt bran cond sub pod time code
1             package ONE::Timer;
2             {
3             $ONE::Timer::VERSION = 'v0.2.0';
4             }
5             # Dist::Zilla: +PodWeaver
6             # ABSTRACT: Timer/timeout events for MooseX::Event
7 2     2   11 use AnyEvent ();
  2         3  
  2         39  
8 2     2   9 use MooseX::Event;
  2         4  
  2         12  
9 2     2   2669 use Scalar::Util ();
  2         4  
  2         153  
10              
11             has 'delay' => (isa=>'Num|CodeRef', is=>'ro', default=>0);
12              
13              
14             has 'interval' => (isa=>'Num', is=>'ro', default=>0);
15              
16             has '_guard' => (is=>'rw');
17              
18              
19             has_event 'timeout';
20              
21 2     2   8 no MooseX::Event; # Remove the moose helpers, so we can declare our own after method
  2         4  
  2         8  
22              
23 2     2   636 use Exporter;
  2         4  
  2         1817  
24             *import = \&Exporter::import;
25              
26             our @EXPORT_OK = qw( sleep sleep_until );
27              
28              
29             sub sleep {
30 4 50   4 1 130 return if $_[-1] <= 0;
31 4         131 my $cv = AE::cv;
32 4     4   190 my $w; $w=AE::timer( $_[-1], 0, sub { undef $w; $cv->send } );
  4         38  
  4         497823  
  4         59  
33 4         21 $cv->recv;
34             }
35              
36              
37             sub sleep_until {
38 1     1 1 22 my $for = $_[-1] - AE::time;
39 1 50       5 return if $for <= 0;
40 1         36 my $cv = AE::cv;
41 1     1   57 my $w; $w=AE::timer( $for, 0, sub { undef $w; $cv->send } );
  1         13  
  1         293543  
  1         12  
42 1         170 $cv->recv;
43             }
44              
45              
46             sub after {
47 3     3 1 11406 my $class = shift;
48 3         7 my( $after, $on_timeout ) = @_;
49 3         55 my $self = $class->new( delay=> $after );
50 3         282 $self->on( timeout => $on_timeout );
51 3         190 $self->start( defined(wantarray) );
52 3         10 return $self;
53             }
54              
55              
56             sub at {
57 1     1 1 20 my $class = shift;
58 1         12 my( $at, $on_timeout ) = @_;
59 1     1   17 my $self = $class->new( delay=> sub {$at - AE::time} );
  1         5  
60 1         21 $self->on( timeout => $on_timeout );
61 1         53 $self->start( defined(wantarray) );
62 1         3 return $self;
63             }
64              
65              
66             sub every {
67 3     3 1 24 my $class = shift;
68 3         8 my( $every, $on_timeout ) = @_;
69 3         34 my $self = $class->new( delay => $every, interval => $every );
70 3         47 $self->on( timeout => $on_timeout );
71 3         127 $self->start( defined(wantarray) );
72 3         9 return $self;
73             }
74              
75              
76             sub start {
77 7     7 1 13 my $self = shift;
78 7         12 my( $is_weak ) = @_;
79            
80 7 50       34 if ( defined $self->_guard ) {
81 0         0 require Carp;
82 0         0 Carp::croak( "Can't start a timer that's already running" );
83             }
84            
85 7         9 my $cb;
86 7 100       23 Scalar::Util::weaken($self) if $is_weak;
87 7 100       27 if ( $self->interval ) {
88 3     0   12 $cb = sub { $self->emit('timeout') };
  0         0  
89             }
90             else {
91 0     0   0 $cb = sub { $self->cancel; $self->emit('timeout'); }
  0         0  
92 4         16 }
93 7         11 my $delay;
94 7 100       25 if ( ref $self->delay ) {
95 1         5 $delay = $self->delay->();
96 1 50       6 $delay = 0 if $delay < 0;
97             }
98             else {
99 6         25 $delay = $self->delay;
100             }
101 7     8   87 my $w = AE::timer $delay, $self->interval, sub { $self->emit('timeout') };
  8         1097696  
102 7         5210 $self->_guard( $w );
103             }
104              
105              
106             sub cancel {
107 2     2 1 6552 my $self = shift;
108 2 50       17 unless (defined $self->_guard) {
109 0         0 require Carp;
110 0         0 Carp::croak( "Can't cancel a timer that's not running" );
111             }
112 2         11 $self->_guard( undef );
113             }
114              
115              
116             __PACKAGE__->meta->make_immutable();
117              
118             1;
119              
120              
121             __END__