Async-Selector
view release on metacpan or search on metacpan
lib/Async/Selector.pm view on Meta::CPAN
=head1 CLASS METHODS
=head2 $selector = Async::Selector->new();
Creates an L<Async::Selector> object. It takes no parameters.
=cut
sub new {
my ($class) = @_;
my $self = bless {
resources => {},
watchers => {},
}, $class;
return $self;
}
sub _check {
my ($self, $watcher_id_or_watcher, @triggers) = @_;
my %results = ();
my $fired = 0;
my $watcher_entry = $self->{watchers}{"$watcher_id_or_watcher"};
return 0 if not defined($watcher_entry);
my $watcher = $watcher_entry->{object};
my %conditions = $watcher->conditions;
if($watcher->get_check_all) {
@triggers = $watcher->resources;
}
foreach my $res_key (@triggers) {
next if not defined $res_key;
next if not exists($conditions{$res_key});
next if not defined($self->{resources}{$res_key});
my $input = $conditions{$res_key};
my $result = $self->{resources}{$res_key}->($input);
if(defined($result)) {
$fired = 1;
$results{$res_key} = $result;
}
}
return 0 if !$fired;
$watcher_entry->{callback}->($watcher, %results);
return 1;
}
=pod
=head1 OBJECT METHODS
=head2 $selector->register($name => $provider->($condition_input), ...);
Registers resources with the object.
A resource is described as a pair of resource name and resource provider.
You can register as many resources as you like.
The resource name (C<$name>) is an arbitrary string.
It is used to select the resource in C<watch()> method.
If C<$name> is already registered with C<$selector>,
the resource provider is updated with C<$provider> and the old one is discarded.
The resource provider (C<$provider>) is a subroutine reference.
Its return value is supposed to be a scalar data of the resource if it's available,
or C<undef> if it's NOT available.
C<$provider> subroutine takes a scalar argument (C<$condition_input>),
which is given by the user in arguments of C<watch()> method.
C<$provider> can decide whether to provide the resource according to C<$condition_input>.
C<register()> method returns C<$selector> object itself.
=cut
sub register {
my ($self, %providers) = @_;
my @error_keys = ();
while(my ($key, $provider) = each(%providers)) {
if(!_isa_coderef($provider)) {
push(@error_keys, $key);
}
}
if(@error_keys) {
croak("Providers must be coderef for keys: " . join(",", @error_keys));
return;
}
@{$self->{resources}}{keys %providers} = values %providers;
return $self;
}
=pod
=head2 $selector->unregister($name, ...);
Unregister resources from C<$selector> object.
C<$name> is the name of the resource you want to unregister.
You can unregister as many resources as you like.
C<unregister()> returns C<$selector> object itself.
=cut
sub unregister {
my ($self, @names) = @_;
delete @{$self->{resources}}{grep { defined($_) } @names};
return $self;
}
=pod
=head2 $watcher = $selector->watch($name => $condition_input, ..., $callback->($watcher, %resources));
Starts to watch resources.
A watch is described as pairs of resource names and condition inputs for the resources.
C<$name> is the resource name that you want to watch. It is the name given in C<register()> method.
( run in 0.485 second using v1.01-cache-2.11-cpan-39bf76dae61 )