Skip to content

Commit

Permalink
stop event poll loop from freezing window chrome
Browse files Browse the repository at this point in the history
If the event poll loop is allowed to run as while (poll) {}, it can have
the unfortunate side effect of somehow blocking the window chrome to events
such as move/resize/close window.

Introducing an additional variable that determines a minimum wait time
between event polls fixes this issue. This time is by default set to be a
tenth of that of the minimum frame refresh wait time.
  • Loading branch information
wchristian committed Apr 26, 2015
1 parent b9112b2 commit 95f35e0
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 3 deletions.
17 changes: 15 additions & 2 deletions lib/SDLx/Controller.pm
Expand Up @@ -15,6 +15,7 @@ use Scalar::Util 'refaddr';
# SDL::Surface subclass
my %_dt;
my %_min_t;
my %_event_min_t;
my %_current_time;
my %_stop;
my %_event;
Expand All @@ -39,6 +40,7 @@ sub new {

$_dt{ $ref } = defined $args{dt} ? $args{dt} : 0.1;
$_min_t{ $ref } = defined $args{min_t} ? $args{min_t} : 1 / 60;
$_event_min_t{ $ref } = defined $args{event_min_t} ? $args{event_min_t} : $_min_t{ $ref } / 10;
# $_current_time{ $ref } = $args{current_time} || 0; #no point
$_stop{ $ref } = $args{stop};
$_event{ $ref } = $args{event} || SDL::Event->new();
Expand Down Expand Up @@ -68,6 +70,7 @@ sub DESTROY {

delete $_dt{ $ref};
delete $_min_t{ $ref};
delete $_event_min_t{ $ref};
delete $_current_time{ $ref};
delete $_stop{ $ref};
delete $_event{ $ref};
Expand All @@ -84,17 +87,18 @@ sub run {
my $ref = refaddr $self;
my $dt = $_dt{ $ref };
my $min_t = $_min_t{ $ref };
my $event_min_t = $_event_min_t{ $ref };
my $t = 0.0;

#Allows us to do stop and run
$_stop{ $ref } = 0;

$_current_time{ $ref } = Time::HiRes::time;
while ( !$_stop{ $ref } ) {
$self->_event($ref);

my $new_time = Time::HiRes::time;
my $delta_time = $new_time - $_current_time{ $ref };

$self->_event($ref) if $delta_time < $event_min_t;
next if $delta_time < $min_t;
$_current_time{ $ref} = $new_time;
my $delta_copy = $delta_time;
Expand All @@ -112,6 +116,7 @@ sub run {

$dt = $_dt{ $ref}; #these can change
$min_t = $_min_t{ $ref}; #during the cycle
$event_min_t = $_event_min_t{ $ref}; #during the cycle
SDL::delay( $_sleep_cycle{ $ref } ) if $_sleep_cycle{ $ref };
}

Expand Down Expand Up @@ -266,6 +271,14 @@ sub min_t {
$_min_t{ $ref};
}

sub event_min_t {
my ($self, $arg) = @_;
my $ref = refaddr $self;
$_event_min_t{ $ref} = $arg if defined $arg;

$_event_min_t{ $ref};
}

sub current_time {
my ($self, $arg) = @_;
my $ref = refaddr $self;
Expand Down
7 changes: 6 additions & 1 deletion lib/pods/SDLx/Controller.pod
Expand Up @@ -71,6 +71,9 @@ Having the C<min_t> at 1 / 60 ensures that the controller can update the screen
A "V-Sync" such as this is necessary to prevent video "tear", which occurs when the app is updating faster than the monitor can display.
Setting it to 0, as seen above, will let the app run as fast as it possibly can.

C<event_min_t> specifies the minimum time, in seconds, that has to accumulate before any event handlers are called, and defaults to a tenth of C<min_t>.
This ensures that the event polling loop does not consume so much process time that the window chrome is blocked from receiving events such as move, resize or exit.

C<delay> specifies a loop delay in millisecs to place on the controller loop. B<NOTE:> Picking a good delay based on the needs can help reduce CPU load and pressure.

C<event> is a SDL::Event object that events going to the event callbacks are polled in to. It defaults to C<< SDL::Event->new() >>.
Expand Down Expand Up @@ -255,10 +258,12 @@ Quick access to removing all handlers at once.

=head2 min_t

=head2 event_min_t

=head2 current_time

If an argument is passed, modifies the corresponding value to the argument.
C<dt> and C<min_t> will keep their old value until the beginning of the next C<run> cycle.
C<dt>, C<min_t> and C<event_min_t> will keep their old value until the beginning of the next C<run> cycle.

Returns the corresponding value.

Expand Down

0 comments on commit 95f35e0

Please sign in to comment.