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
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) {
$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 {
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 {
sub run_while_wanted {
my ($self) = @_;
$self->loop_once while $self->{want_running};
+ return;
}
sub want_stop {
while ($self->is_running) {
$self->loop_once;
}
+ return;
}
1;
is(S1S->get_s2->get_s3, 'S3', 'Sync without start');
-open my $fh, '<', File::Spec->devnull;
-
-Object::Remote->current_loop->watch_io(
- handle => $fh,
- on_read_ready => sub {
- $S1F::C->() if defined $S1F::C;
- $S2F::C->() if defined $S2F::C;
+Object::Remote->current_loop->watch_time(
+ after => 0.1,
+ code => sub {
+ $S1F::C->();
+ Object::Remote->current_loop->watch_time(
+ after => 0.1,
+ code => sub { $S2F::C->() }
+ );
}
);