1# $Id: Delay.pm 155 2007-02-15 05:09:17Z rcaputo $
2
3=head1 NAME
4
5POE::Watcher::Delay - wait for a length of time to pass
6
7=head1 SYNOPSIS
8
9	# Note, this is not a complete program.
10	# See the distribution's examples directory.
11
12	# Request a delay notification.
13	my $watcher :Req = POE::Watcher::Delay->new(
14		seconds     => 10,            # wait 10 seconds, then
15		on_success  => "time_is_up",  # call $self->time_is_up()
16		args        => {
17			param_1   => 123,           # with $args->{param_1}
18			param_2   => "abc",         # and $args->{param_2}
19		},
20	);
21
22	# Handle the delay notification.
23	sub time_is_up {
24		my ($self, $args) = @_;
25		print "$args->{param_1}\n";   # 123
26		print "$args->{param_2}\n";   # abc
27		my $watcher :Req = undef;     # Destroy the watcher.
28	}
29
30=head1 DESCRIPTION
31
32A POE::Watcher::Delay object waits a certain amount of time before
33invoking a method on the current Stage object.  Both the time to wait
34and the method to invoke are given as constructor parameters.
35Parameters included in the C<args> hash are passed unchanged to the
36desired callback method after the specified time has elapsed.
37
38=cut
39
40package POE::Watcher::Delay;
41
42use warnings;
43use strict;
44
45use POE::Watcher;
46use base qw(POE::Watcher);
47
48use Scalar::Util qw(weaken);
49use Carp qw(croak);
50use POE::Kernel;
51
52=head1 PUBLIC METHODS
53
54These methods are invoked directly on the watcher object.
55
56=head2 new seconds => SECONDS, on_success => METHOD_NAME
57
58Construct a new POE::Watcher::Delay object.  The constructor takes two
59parameters: "seconds" is the number of seconds to wait.  "on_success"
60is the name of the mothod in the current Stage to invoke when length
61seconds have elapsed.
62
63Like every other watcher object, this one must be saved in order to
64remain active.  Destroy this object to cancel it.
65
66=cut
67
68sub init {
69	my ($class, %args) = @_;
70
71	my $seconds = delete $args{seconds};
72	croak "$class requires a 'seconds' parameter" unless defined $seconds;
73
74	my $on_success = delete $args{on_success};
75	croak "$class requires an 'on_success' parameter" unless defined $on_success;
76
77	# XXX - Only used for the request object.
78	my $request = POE::Request->_get_current_request();
79	croak "Can't create a $class without an active request" unless $request;
80
81	# TODO - Make sure no other class arguments exist.
82
83	# Wrap a weak copy of the request reference in a strong envelope so
84	# it can be passed around.
85
86	my $req_envelope = [ $request ];
87	weaken $req_envelope->[0];
88
89	my $self = bless {
90		request     => $req_envelope,
91		on_success  => $on_success,
92		args        => { %{ $args{args} || {} } },
93	}, $class;
94
95	# Post out a timer.
96	# Wrap a weak $self in a strong envelope for passing around.
97
98	my $self_envelope = [ $self ];
99	weaken $self_envelope->[0];
100
101	$self->{delay_id} = $poe_kernel->delay_set(
102		stage_timer => $seconds, $self_envelope
103	);
104
105	# Owner gets a strong reference.
106	return $self;
107}
108
109sub DESTROY {
110	my $self = shift;
111
112	if (exists $self->{delay_id}) {
113		$poe_kernel->alarm_remove(delete $self->{delay_id});
114	}
115}
116
117# Resource delivery redelivers the request the resource was created
118# in, but to a new method.
119# TODO - Rename to _deliver, since this is an internal method.
120
121sub deliver {
122	my ($self, %args) = @_;
123
124	# Open the envelope.
125	my $request = $self->{request}[0];
126	$request->deliver($self->{on_success}, $self->{args});
127}
128
1291;
130
131=head1 BUGS
132
133See L<http://thirdlobe.com/projects/poe-stage/report/1> for known
134issues.  See L<http://thirdlobe.com/projects/poe-stage/newticket> to
135report one.
136
137POE::Stage is too young for production use.  For example, its syntax
138is still changing.  You probably know what you don't like, or what you
139need that isn't included, so consider fixing or adding that, or at
140least discussing it with the people on POE's mailing list or IRC
141channel.  Your feedback and contributions will bring POE::Stage closer
142to usability.  We appreciate it.
143
144=head1 SEE ALSO
145
146L<POE::Watcher> describes concepts that are common to all POE::Watcher
147classes.  It's required reading if you want to fully understand what's
148going on.
149
150=head1 AUTHORS
151
152Rocco Caputo <rcaputo@cpan.org>.
153
154=head1 LICENSE
155
156POE::Watcher::Delay is Copyright 2005-2006 by Rocco Caputo.  All
157rights are reserved.  You may use, modify, and/or distribute this
158module under the same terms as Perl itself.
159
160=cut
161