AnyEvent-Collect
view release on metacpan or search on metacpan
lib/AnyEvent/Collect.pm view on Meta::CPAN
use AnyEvent;
use Event::Wrappable;
use Sub::Exporter -setup => {
exports => [qw( collect collect_all collect_any event )],
groups => { default => [qw( collect collect_all collect_any event )] },
};
use constant COLLECT_TYPE => 0;
use constant COLLECT_CV => 1;
my @cvs;
sub collect_all(&) {
my( $todo ) = @_;
my $cv = AE::cv;
Event::Wrappable->wrap_events( $todo, sub {
my( $listener ) = @_;
$cv->begin;
my $ended = 0;
return sub { $listener->(@_); $cv->end unless $ended++ };
} );
$cv->recv;
}
*collect = *collect_all;
sub collect_any(&) {
my( $todo ) = @_;
my $cv = AE::cv;
Event::Wrappable->wrap_events( $todo, sub {
my( $listener ) = @_;
return sub { $listener->(@_); $cv->send };
} );
$cv->recv;
}
1;
__END__
=pod
=encoding utf-8
=head1 NAME
AnyEvent::Collect - Block till one or more events fire
=head1 VERSION
version 0.1.0
=head1 SYNOPSIS
use AnyEvent;
use AnyEvent::Collect;
# Wait for all of a collection of events to trigger once:
my( $w1, $w2 );
collect {
$w1 = AE::timer 2, 0, event { say "two" };
$w2 = AE::timer 3, 0, event { say "three" };
}; # Returns after 3 seconds having printed "two" and "three"
# Wait for any of a collection of events to trigger:
my( $w3, $w4 );
collect_any {
$w3 = AE::timer 2, 0, event { say "two" };
$w4 = AE::timer 3, 0, event { say "three" };
};
# Returns after 2 seconds, having printed 2. Note however that
# the other event will still be emitted in another second. If
# you were to then execute the sleep below, it would print three.
# Or using L<ONE>
use ONE::Timer;
use AnyEvent::Collect;
collect {
ONE::Timer->after( 2 => event { say "two" } );
ONE::Timer->after( 3 => event { say "three" } );
}; # As above, returns after three seconds having printed "two" and
# "three"
# And because L<ONE> is based on L<MooseX::Event> and L<MooseX::Event>
# is integrated with L<Event::Wrappable>, you can just pass in raw subs
# rather then using the event helper:
collect_any {
ONE::Timer->after( 2 => sub { say "two" } );
ONE::Timer->after( 3 => sub { say "three" } );
}; # Returns after 2 seconds having printed "two"
=head1 DESCRIPTION
This allows you to reduce a group of unrelated events into a single event.
Either when the first event is emitted, or after all events have been
emitted at least once.
For your convenience this re-exports the event helper from
L<Event::Wrappable>. Only event listeners created with it or via a class
that integrates with Event::Wrappable (eg, L<MooseX::Event>) will be
captured.
=head1 HELPERS
=head2 sub event( CodeRef $todo )
See L<Event::Wrappable> for details.
=head2 sub collect( CodeRef $todo )
=head2 sub collect_all( CodeRef $todo )
Will return after all of the events declared inside the collect block have
been emitted at least once.
=head2 sub collect_any( CodeRef $todo )
Will return after any of the events declared inside the collect block have
been emitted at least once. Note that it doesn't actually cancel the
unemitted events-- you'll have to do that yourself, if that's what you want.
=for test_synopsis use 5.10.0;
=head1 SEE ALSO
=over 4
=item *
L<Event::Wrappable|Event::Wrappable>
=back
=head1 SOURCE
The development version is on github at L<http://https://github.com/iarna/AnyEvent-Collect>
and may be cloned from L<git://https://github.com/iarna/AnyEvent-Collect.git>
=for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan
=head1 SUPPORT
=head2 Websites
More information can be found at:
=over 4
( run in 1.676 second using v1.01-cache-2.11-cpan-a1f116cd669 )