#!/usr/bin/perl -w package SCX::Track; use strict; use Carp; use Time::HiRes qw(gettimeofday); use Glib qw(TRUE FALSE); use SCX::Car; our $SEMAPHORE_STEP = 1000; sub new { my ($class, $args) = @_; my $self; $self->{gui} = $args->{gui} or croak; $self->{race_running} = 0; $self->{lap_counting_up} = 1; bless $self, $class; for my $i (0..5) { $self->{cars}->[$i] = SCX::Car->new({ gui => $self->{gui}, id => $i, track => $self, }); $self->car($i)->set_order($i); } return $self; } sub car { return shift->{cars}->[shift]; } sub race_start { my ($self) = @_; return if $self->{race_running} || $self->{start_in_progress}; $self->{race_running} = 0; $self->{start_in_progress} = 1; $self->{semaphore} = 0; $self->{gui}->show_semaphore(0); Glib::Timeout->add($SEMAPHORE_STEP, \&semaphore_step, $self); } sub semaphore_step { my ($self) = @_; return FALSE if !$self->{start_in_progress} && !$self->{race_running}; $self->{semaphore}++; if ($self->{semaphore} <= 5) { $self->{gui}->show_semaphore($self->{semaphore}); my $timeout = $SEMAPHORE_STEP; $timeout += $SEMAPHORE_STEP * rand() if $self->{semaphore} == 5; Glib::Timeout->add($timeout, \&semaphore_step, $self); } elsif ($self->{semaphore} == 6) { $self->{race_running} = 1; $self->{race_running_since} = gettimeofday; $self->{start_in_progress} = undef; $self->{gui}->show_semaphore(0); Glib::Timeout->add(3*$SEMAPHORE_STEP, \&semaphore_step, $self); } else { $self->{gui}->show_semaphore(undef); $self->{semaphore} = undef; } return FALSE; } sub race_end { my ($self) = @_; $self->{race_running} = 0; } sub race_setup { my ($self, $rounds) = @_; if ($rounds) { $self->{gui}->rounds('0/' . $rounds); $self->{race_rounds} = $rounds; } else { $self->{gui}->rounds('0'); $self->{race_rounds} = 0; } $self->{race_time} = 0; $self->{best_lap} = undef; $self->{gui}->show_semaphore(undef); $self->{race_running} = 0; $self->{start_in_progress} = 0; $self->{gui}->time('00:00'); $self->{gui}->best_lap('0.00'); for my $car (0..5) { $self->car($car)->set_order($car); $self->car($car)->set_lap(0); $self->car($car)->set_laptime(undef); } } sub check_best_lap { my ($self, $time, $who) = @_; return if !defined $time || $time == 0; if (!defined $self->{best_lap} || $time < $self->{best_lap}) { $self->{best_lap} = $time; $self->{gui}->best_lap(sprintf("%.2f", $time), $who); return 1; } return 0; } sub qualification_start { my ($self) = @_; return if $self->{qualification_running}; for my $car (0..5) { $self->car($car)->set_lap(undef); $self->car($car)->set_laptime(undef); } $self->{qualification_running}; $self->{gui}->lap('Qualification'); $self->{gui}->time('00:00'); $self->{gui}->best_lap('0:00'); } 1;