Permalink
Browse files

basically working

  • Loading branch information...
1 parent 6cec7e1 commit 98d639db3effb6f8b5a3b94f444f0edadee286d0 @jrockway committed Mar 15, 2010
Showing with 112 additions and 1 deletion.
  1. +1 −1 .eproject
  2. +84 −0 lib/AnyEvent/Debounce.pm
  3. +27 −0 t/basic.t
View
@@ -1 +1 @@
-:mxdeclare-project-p t
+:mxdeclare-project-p nil
View
@@ -0,0 +1,84 @@
+package AnyEvent::Debounce;
+use Moose;
+
+use AnyEvent;
+
+has 'delay' => (
+ is => 'ro',
+ isa => 'Num',
+ default => 1,
+);
+
+has 'maximum_delays' => (
+ is => 'ro',
+ isa => 'Int',
+ default => 4,
+);
+
+has 'cb' => (
+ is => 'ro',
+ isa => 'CodeRef',
+ required => 1,
+);
+
+has '_queued_events' => (
+ traits => ['Array'],
+ reader => 'queued_events',
+ isa => 'ArrayRef',
+ default => sub { [] },
+ clearer => 'clear_queued_events',
+ handles => { 'queue_event' => 'push' },
+);
+
+has '_delays' => (
+ reader => 'delays',
+ traits => ['Counter'],
+ isa => 'Int',
+ default => 0,
+ trigger => sub {
+ my ($self, $new, $old) = @_;
+ if ($new >= $self->maximum_delays){
+ $self->send_events_now;
+ }
+ },
+ handles => {
+ 'clear_delays' => 'reset',
+ 'record_delay' => 'inc',
+ },
+);
+
+has '_timer' => (
+ writer => '_timer',
+ clearer => 'clear_timer',
+);
+
+sub reset_timer {
+ my $self = shift;
+ $self->_timer(
+ AnyEvent->timer(
+ after => $self->delay,
+ interval => 0,
+ cb => sub { $self->send_events_now },
+ ),
+ );
+}
+
+sub send_events_now {
+ my $self = shift;
+ $self->clear_timer;
+ $self->clear_delays;
+ my $events = $self->queued_events;
+ $self->clear_queued_events;
+ $self->cb->(@$events);
+ return;
+}
+
+sub send {
+ my ($self, @args) = @_;
+ $self->queue_event([@args]);
+ $self->reset_timer;
+ $self->record_delay;
+ return;
+}
+
+1;
View
@@ -0,0 +1,27 @@
+use strict;
+use warnings;
+use Test::More;
+
+use AnyEvent;
+use AnyEvent::Debounce;
+
+my $sent = 0;
+my $done = AnyEvent->condvar;
+my $d = AnyEvent::Debounce->new(
+ delay => 0.5,
+ maximum_delays => 20,
+ cb => sub { $done->send([@_]) },
+);
+
+my $sender; $sender = AnyEvent->timer( after => 0, interval => 0.1, cb => sub {
+ diag "sending";
+ $d->send($sent);
+ undef $sender if ++$sent > 9;
+});
+
+my $result = $done->recv;
+
+is $sent, 10, 'got 10 events before cb was called';
+is_deeply $result, [map { [$_] } 0..9], 'got the events we expected';
+
+done_testing;

0 comments on commit 98d639d

Please sign in to comment.