summaryrefslogtreecommitdiff
path: root/lib/IO/Async/Timer/Absolute.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/IO/Async/Timer/Absolute.pm')
-rw-r--r--lib/IO/Async/Timer/Absolute.pm142
1 files changed, 142 insertions, 0 deletions
diff --git a/lib/IO/Async/Timer/Absolute.pm b/lib/IO/Async/Timer/Absolute.pm
new file mode 100644
index 0000000..a925415
--- /dev/null
+++ b/lib/IO/Async/Timer/Absolute.pm
@@ -0,0 +1,142 @@
+# You may distribute under the terms of either the GNU General Public License
+# or the Artistic License (the same terms as Perl itself)
+#
+# (C) Paul Evans, 2010-2015 -- leonerd@leonerd.org.uk
+
+package IO::Async::Timer::Absolute;
+
+use strict;
+use warnings;
+use base qw( IO::Async::Timer );
+
+our $VERSION = '0.67';
+
+use Carp;
+
+=head1 NAME
+
+C<IO::Async::Timer::Absolute> - event callback at a fixed future time
+
+=head1 SYNOPSIS
+
+ use IO::Async::Timer::Absolute;
+
+ use POSIX qw( mktime );
+
+ use IO::Async::Loop;
+ my $loop = IO::Async::Loop->new;
+
+ my @time = gmtime;
+
+ my $timer = IO::Async::Timer::Absolute->new(
+ time => mktime( 0, 0, 0, $time[3]+1, $time[4], $time[5] ),
+
+ on_expire => sub {
+ print "It's midnight\n";
+ $loop->stop;
+ },
+ );
+
+ $loop->add( $timer );
+
+ $loop->run;
+
+=head1 DESCRIPTION
+
+This subclass of L<IO::Async::Timer> implements one-shot events at a fixed
+time in the future. The object waits for a given timestamp, and invokes its
+callback at that point in the future.
+
+For a C<Timer> object that waits for a delay relative to the time it is
+started, see instead L<IO::Async::Timer::Countdown>.
+
+=cut
+
+=head1 EVENTS
+
+The following events are invoked, either using subclass methods or CODE
+references in parameters:
+
+=head2 on_expire
+
+Invoked when the timer expires.
+
+=cut
+
+=head1 PARAMETERS
+
+The following named parameters may be passed to C<new> or C<configure>:
+
+=head2 on_expire => CODE
+
+CODE reference for the C<on_expire> event.
+
+=head2 time => NUM
+
+The epoch time at which the timer will expire.
+
+Once constructed, the timer object will need to be added to the C<Loop> before
+it will work.
+
+Unlike other timers, it does not make sense to C<start> this object, because
+its expiry time is absolute, and not relative to the time it is started.
+
+=cut
+
+sub configure
+{
+ my $self = shift;
+ my %params = @_;
+
+ if( exists $params{on_expire} ) {
+ my $on_expire = delete $params{on_expire};
+ ref $on_expire or croak "Expected 'on_expire' as a reference";
+
+ $self->{on_expire} = $on_expire;
+ undef $self->{cb}; # Will be lazily constructed when needed
+ }
+
+ if( exists $params{time} ) {
+ my $time = delete $params{time};
+
+ $self->stop if $self->is_running;
+
+ $self->{time} = $time;
+
+ $self->start if !$self->is_running;
+ }
+
+ unless( $self->can_event( 'on_expire' ) ) {
+ croak 'Expected either a on_expire callback or an ->on_expire method';
+ }
+
+ $self->SUPER::configure( %params );
+}
+
+sub _make_cb
+{
+ my $self = shift;
+
+ return $self->_capture_weakself( sub {
+ my $self = shift or return;
+
+ undef $self->{id};
+
+ $self->invoke_event( "on_expire" );
+ } );
+}
+
+sub _make_enqueueargs
+{
+ my $self = shift;
+
+ return at => $self->{time};
+}
+
+=head1 AUTHOR
+
+Paul Evans <leonerd@leonerd.org.uk>
+
+=cut
+
+0x55AA;