mirror of
https://github.com/pragma-/pbot.git
synced 2024-11-29 23:39:24 +01:00
Timer: intelligently wait for next tick; eventqueue
command can now filter
This commit is contained in:
parent
bc79f3a69d
commit
5624d2d166
@ -25,12 +25,12 @@ use feature 'unicode_strings';
|
|||||||
use Time::Duration qw/concise duration/;
|
use Time::Duration qw/concise duration/;
|
||||||
|
|
||||||
our $seconds ||= 0;
|
our $seconds ||= 0;
|
||||||
|
our $waitfor ||= 1;
|
||||||
our @timer_funcs;
|
our @timer_funcs;
|
||||||
|
|
||||||
# alarm signal handler (poor-man's timer)
|
# alarm signal handler (poor-man's timer)
|
||||||
$SIG{ALRM} = sub {
|
$SIG{ALRM} = sub {
|
||||||
$seconds += 1;
|
$seconds += $waitfor;
|
||||||
alarm 1;
|
|
||||||
foreach my $func (@timer_funcs) { &$func; }
|
foreach my $func (@timer_funcs) { &$func; }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -53,18 +53,33 @@ sub event_queue_cmd {
|
|||||||
|
|
||||||
return "No events queued." if not @{$self->{event_queue}};
|
return "No events queued." if not @{$self->{event_queue}};
|
||||||
|
|
||||||
my $text = "Queued events:\n";
|
my $result = eval {
|
||||||
|
my $text = "Queued events:\n";
|
||||||
|
|
||||||
my $i = 0;
|
my $i = 0;
|
||||||
foreach my $event (@{$self->{event_queue}}) {
|
foreach my $event (@{$self->{event_queue}}) {
|
||||||
my $duration = concise duration $event->{timeout} - $seconds;
|
$i++;
|
||||||
$text .= " $i) in $duration: $event->{id}";
|
|
||||||
$text .= ' [R]' if $event->{repeating};
|
if ($arguments) {
|
||||||
$text .= ";\n";
|
next unless $event->{id} =~ /$arguments/;
|
||||||
$i++;
|
}
|
||||||
|
|
||||||
|
my $duration = concise duration $event->{timeout} - $seconds;
|
||||||
|
$text .= " $i) in $duration: $event->{id}";
|
||||||
|
$text .= ' [R]' if $event->{repeating};
|
||||||
|
$text .= ";\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $text;
|
||||||
|
};
|
||||||
|
|
||||||
|
if ($@) {
|
||||||
|
my $error = $@;
|
||||||
|
$error =~ s/ at PBot.*//;
|
||||||
|
return "Bad regex: $error";
|
||||||
}
|
}
|
||||||
|
|
||||||
return $text;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub start {
|
sub start {
|
||||||
@ -104,6 +119,9 @@ sub find_enqueue_position {
|
|||||||
} elsif ($value > $self->{event_queue}->[$mid]->{timeout}) {
|
} elsif ($value > $self->{event_queue}->[$mid]->{timeout}) {
|
||||||
$lo = $mid + 1;
|
$lo = $mid + 1;
|
||||||
} else {
|
} else {
|
||||||
|
while ($mid < @{$self->{event_queue}} and $self->{event_queue}->[$mid]->{timeout} == $value) {
|
||||||
|
$mid++;
|
||||||
|
}
|
||||||
return $mid;
|
return $mid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -128,6 +146,10 @@ sub enqueue_event {
|
|||||||
my $i = $self->find_enqueue_position($event->{timeout});
|
my $i = $self->find_enqueue_position($event->{timeout});
|
||||||
splice @{$self->{event_queue}}, $i, 0, $event;
|
splice @{$self->{event_queue}}, $i, 0, $event;
|
||||||
|
|
||||||
|
if ($interval < $waitfor) {
|
||||||
|
$self->waitfor($interval);
|
||||||
|
}
|
||||||
|
|
||||||
my $debug = $self->{pbot}->{registry}->get_value('timer', 'debug') // 0;
|
my $debug = $self->{pbot}->{registry}->get_value('timer', 'debug') // 0;
|
||||||
if ($debug > 1) {
|
if ($debug > 1) {
|
||||||
$self->{pbot}->{logger}->log("Enqueued new timer event $id at position $i: timeout=$event->{timeout} interval=$interval repeating=$repeating\n");
|
$self->{pbot}->{logger}->log("Enqueued new timer event $id at position $i: timeout=$event->{timeout} interval=$interval repeating=$repeating\n");
|
||||||
@ -160,6 +182,17 @@ sub unregister {
|
|||||||
$self->dequeue_event($id);
|
$self->dequeue_event($id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub update_repeating {
|
||||||
|
my ($self, $id, $repeating) = @_;
|
||||||
|
|
||||||
|
for (my $i = 0; $i < @{$self->{event_queue}}; $i++) {
|
||||||
|
if ($self->{event_queue}->[$i]->{id} eq $id) {
|
||||||
|
$self->{event_queue}->[$i]->{repeating} = $repeating;
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sub update_interval {
|
sub update_interval {
|
||||||
my ($self, $id, $interval, $dont_enqueue) = @_;
|
my ($self, $id, $interval, $dont_enqueue) = @_;
|
||||||
|
|
||||||
@ -176,6 +209,13 @@ sub update_interval {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub waitfor {
|
||||||
|
my ($self, $duration) = @_;
|
||||||
|
$duration = 1 if $duration < 1;
|
||||||
|
alarm $duration;
|
||||||
|
$waitfor = $duration;
|
||||||
|
}
|
||||||
|
|
||||||
sub on_tick_handler {
|
sub on_tick_handler {
|
||||||
my ($self) = @_;
|
my ($self) = @_;
|
||||||
return if not $self->{enabled};
|
return if not $self->{enabled};
|
||||||
@ -183,23 +223,28 @@ sub on_tick_handler {
|
|||||||
my $debug = $self->{pbot}->{registry}->get_value('timer', 'debug') // 0;
|
my $debug = $self->{pbot}->{registry}->get_value('timer', 'debug') // 0;
|
||||||
$self->{pbot}->{logger}->log("$self->{name} tick $seconds\n") if $debug;
|
$self->{pbot}->{logger}->log("$self->{name} tick $seconds\n") if $debug;
|
||||||
|
|
||||||
|
my $next_tick = 1;
|
||||||
if (@{$self->{event_queue}}) {
|
if (@{$self->{event_queue}}) {
|
||||||
my @enqueue = ();
|
my @enqueue = ();
|
||||||
for (my $i = 0; $i < @{$self->{event_queue}}; $i++) {
|
for (my $i = 0; $i < @{$self->{event_queue}}; $i++) {
|
||||||
if ($seconds >= $self->{event_queue}->[$i]->{timeout}) {
|
if ($seconds >= $self->{event_queue}->[$i]->{timeout}) {
|
||||||
my $event = $self->{event_queue}->[$i];
|
my $event = $self->{event_queue}->[$i];
|
||||||
$self->{pbot}->{logger}->log("Processing timer event $i: $event->{id}\n") if $debug > 1;
|
$self->{pbot}->{logger}->log("Processing timer event $i: $event->{id}\n") if $debug > 1;
|
||||||
$event->{subref}->($self);
|
$event->{subref}->($event);
|
||||||
splice @{$self->{event_queue}}, $i--, 1;
|
splice @{$self->{event_queue}}, $i--, 1;
|
||||||
push @enqueue, $event if $event->{repeating};
|
push @enqueue, $event if $event->{repeating};
|
||||||
} else {
|
} else {
|
||||||
if ($debug > 2) {
|
if ($debug > 2) {
|
||||||
$self->{pbot}->{logger}->log("Event not ready yet: $self->{event_queue}->[$i]->{id} (timeout=$self->{event_queue}->[$i]->{timeout})\n");
|
$self->{pbot}->{logger}->log("Event not ready yet: $self->{event_queue}->[$i]->{id} (timeout=$self->{event_queue}->[$i]->{timeout})\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$next_tick = $self->{event_queue}->[$i]->{timeout} - $seconds;
|
||||||
last;
|
last;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$self->waitfor($next_tick);
|
||||||
|
|
||||||
foreach my $event (@enqueue) {
|
foreach my $event (@enqueue) {
|
||||||
$self->enqueue_event($event->{subref}, $event->{interval}, $event->{id}, 1);
|
$self->enqueue_event($event->{subref}, $event->{interval}, $event->{id}, 1);
|
||||||
}
|
}
|
||||||
@ -209,6 +254,8 @@ sub on_tick_handler {
|
|||||||
$self->{last} = $seconds;
|
$self->{last} = $seconds;
|
||||||
$self->on_tick;
|
$self->on_tick;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$self->waitfor($self->{timeout} - $seconds - $self->{last});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user