8 use Time::HiRes qw(gettimeofday);
9 use Glib qw(TRUE FALSE);
12 our $SEMAPHORE_STEP = 1000;
15 my ($class, $args) = @_;
19 $self->{gui} = $args->{gui} or croak;
20 $self->{race_running} = 0;
21 $self->{lap_counting_up} = 1;
26 $self->{cars}->[$i] = SCX::Car->new({
31 $self->car($i)->set_order($i);
37 sub car { return shift->{cars}->[shift]; }
42 return if $self->{race_running} || $self->{start_in_progress}
43 || $self->{qualification_running};
44 $self->{race_running} = 0;
45 $self->{start_in_progress} = 1;
46 $self->{semaphore} = 0;
47 $self->{gui}->show_semaphore(0);
48 Glib::Timeout->add($SEMAPHORE_STEP, \&semaphore_step, $self);
54 return FALSE if !$self->{start_in_progress} && !$self->{race_running};
57 if ($self->{semaphore} <= 5) {
58 $self->{gui}->show_semaphore($self->{semaphore});
59 my $timeout = $SEMAPHORE_STEP;
60 $timeout += $SEMAPHORE_STEP * rand()
61 if $self->{semaphore} == 5;
62 Glib::Timeout->add($timeout, \&semaphore_step, $self);
63 } elsif ($self->{semaphore} == 6) {
64 $self->{race_running} = 1;
65 $self->{race_running_since} = gettimeofday;
66 $self->{start_in_progress} = undef;
67 $self->{gui}->show_semaphore(0);
68 Glib::Timeout->add($SEMAPHORE_STEP, \&semaphore_step, $self);
70 $self->{gui}->show_semaphore(undef);
71 $self->{semaphore} = undef;
78 $self->{race_running} = 0;
82 my ($self, $rounds) = @_;
86 $self->{race_rounds} = $rounds;
88 $self->{race_rounds} = 0;
92 $self->{best_lap} = undef;
94 $self->{gui}->show_semaphore(undef);
95 $self->{race_running} = 0;
96 $self->{start_in_progress} = 0;
98 $self->{gui}->time(undef);
99 $self->{gui}->best_lap(undef);
105 $self->{race_running} = 0;
106 $self->{start_in_progress} = 0;
107 $self->{best_lap} = undef;
111 $self->{gui}->best_lap(undef);
112 $self->{gui}->time(undef);
115 $self->car($car)->reset;
122 $self->{gui}->rounds($self->{qualification_running}
124 : $self->{race_rounds}
125 ? $self->{round} . '/' . $self->{race_rounds}
131 my ($self, $time, $who) = @_;
133 return if !defined $time || $time == 0;
135 # print "Check_best_lap $time $who vs ",
136 # defined $self->{best_lap} ? $self->{best_lap} : 'undef',
138 if (!defined $self->{best_lap}
139 || $time < $self->{best_lap}) {
140 $self->{best_lap} = $time;
141 $self->{gui}->best_lap($time, $who);
147 sub qualification_start {
150 return if $self->{qualification_running};
152 $self->car($car)->set_lap(undef);
153 $self->car($car)->set_laptime(undef);
156 $self->{qualification_running} = 1;
157 $self->{gui}->rounds('Qualification');
158 $self->{gui}->time(undef);
159 $self->{gui}->best_lap(undef);
162 sub packet_received {
163 my ($self, $time) = @_;
165 if ($self->{race_running}) {
166 $self->{gui}->time($time - $self->{race_running_since});
171 my ($self, $now) = @_;
173 return if !$self->{race_running};
178 $laps[$id] = $self->car($id)->{lap} // -1;
179 $times[$id] = $self->car($id)->{first_finish_time} // $now;
182 my @new_order = sort {
183 $laps[$b] <=> $laps[$a]
185 $times[$a] <=> $times[$b]
190 my $lap_max = $laps[$new_order[0]];
191 if (defined $lap_max && $lap_max != $self->{round}
192 && (!$self->{race_rounds}
193 || $lap_max <= $self->{race_rounds})) {
194 $self->{round} = $lap_max;
199 my $car = $new_order[$id];
200 if ($self->car($car)->{order} != $id) {
201 $self->car($car)->set_order($id);
204 return ($new_order[0], $lap_max, $times[$new_order[0]]);
208 my ($self, $time, $regular, @cars) = @_;
211 for my $car (@cars) {
212 push @processed, $car
213 if $self->car($car)->finish_line($time, $regular);
217 my ($first_car, $lap_max, $time_min)
218 = $self->recalc_order($time);
220 for my $car (@processed) {
221 $self->car($car)->recalc_distance($lap_max, $time_min);