X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=scpubgit%2FObject-Remote.git;a=blobdiff_plain;f=lib%2FObject%2FRemote%2FMiniLoop.pm;h=de2515fe2f68db432d29928240971d036c9e4f77;hp=b74619c83fae571cd564d171bbb5f1ad63e50205;hb=befabdee3a3a75da8dd2fd21a2a6c80d8ed0bcff;hpb=f68888102d5c1cb2736a77f7df6fd7baa92ca4d8 diff --git a/lib/Object/Remote/MiniLoop.pm b/lib/Object/Remote/MiniLoop.pm index b74619c..de2515f 100644 --- a/lib/Object/Remote/MiniLoop.pm +++ b/lib/Object/Remote/MiniLoop.pm @@ -1,6 +1,7 @@ package Object::Remote::MiniLoop; use IO::Select; +use Time::HiRes qw(time); use Moo; # this is ro because we only actually set it using local in sub run @@ -10,6 +11,8 @@ has is_running => (is => 'ro', clearer => 'stop'); has _read_watches => (is => 'ro', default => sub { {} }); has _read_select => (is => 'ro', default => sub { IO::Select->new }); +has _timers => (is => 'ro', default => sub { [] }); + sub pass_watches_to { my ($self, $new_loop) = @_; foreach my $fh ($self->_read_select->handles) { @@ -36,6 +39,26 @@ sub unwatch_io { $self->_read_select->remove($fh); delete $self->_read_watches->{$fh}; } + return; +} + +sub watch_time { + my ($self, %watch) = @_; + my $at = $watch{at} || do { + die "watch_time requires at or after" unless my $after = $watch{after}; + time() + $after; + }; + die "watch_time requires code" unless my $code = $watch{code}; + my $timers = $self->_timers; + my $new = [ $at => $code ]; + @{$timers} = sort { $a->[0] <=> $b->[0] } @{$timers}, $new; + return "$new"; +} + +sub unwatch_time { + my ($self, $id) = @_; + @$_ = grep !($_ eq $id), @$_ for $self->_timers; + return; } sub loop_once { @@ -48,6 +71,12 @@ sub loop_once { foreach my $fh (@$readable) { $read->{$fh}(); } + my $timers = $self->_timers; + my $now = time(); + while (@$timers and $timers->[0][0] <= $now) { + (shift @$timers)->[1]->(); + } + return; } sub want_run { @@ -58,6 +87,7 @@ sub want_run { sub run_while_wanted { my ($self) = @_; $self->loop_once while $self->{want_running}; + return; } sub want_stop { @@ -71,6 +101,7 @@ sub run { while ($self->is_running) { $self->loop_once; } + return; } 1;