8 use Time::HiRes qw(gettimeofday);
9 use Glib qw(TRUE FALSE);
12 our $SEMAPHORE_STEP = 1000;
15 my ($class, $args) = @_;
27 $self->{cars}->[$i] = SCX::Car->new({
35 $self->{gui}->time(undef);
36 $self->{gui}->best_lap(undef, undef);
41 sub car { return shift->{cars}->[shift]; }
46 return if $self->{race_running} || $self->{start_in_progress}
47 || $self->{qualification_running};
49 $self->{race_running} = 0;
50 $self->{start_in_progress} = 1;
51 $self->{semaphore} = 0;
52 $self->{gui}->show_semaphore(0);
53 Glib::Timeout->add($SEMAPHORE_STEP, \&semaphore_step, $self);
59 return FALSE if !$self->{start_in_progress} && !$self->{race_running};
62 if ($self->{semaphore} <= 5) {
63 $self->{gui}->show_semaphore($self->{semaphore});
64 my $timeout = $SEMAPHORE_STEP;
65 $timeout += $SEMAPHORE_STEP * rand()
66 if $self->{semaphore} == 5;
67 Glib::Timeout->add($timeout, \&semaphore_step, $self);
68 } elsif ($self->{semaphore} == 6) {
69 $self->{race_running} = 1;
70 $self->{race_running_since} = gettimeofday;
71 $self->{start_in_progress} = undef;
72 $self->{gui}->show_semaphore(0);
73 Glib::Timeout->add($SEMAPHORE_STEP, \&semaphore_step, $self);
75 $self->{gui}->show_semaphore(undef);
76 $self->{semaphore} = undef;
83 $self->{race_running} = 0;
87 my ($self, $rounds) = @_;
91 $self->{race_rounds} = $rounds;
93 $self->{race_rounds} = 0;
97 $self->{best_lap} = undef;
99 $self->{gui}->show_semaphore(undef);
100 $self->{race_running} = 0;
101 $self->{start_in_progress} = 0;
103 $self->{gui}->time(undef);
104 $self->{gui}->best_lap(undef);
110 $self->{race_running} = 0;
111 $self->{start_in_progress} = 0;
112 $self->{race_finishing} = 0;
113 $self->{best_lap} = undef;
117 $self->{gui}->best_lap(undef);
118 $self->{gui}->time(undef);
121 $self->car($car)->reset;
129 if ($self->{qualification_running}) {
130 $msg = 'Qualification';
131 } elsif ($self->{race_rounds}) {
132 $msg = $self->{round} . '/' . $self->{race_rounds};
134 $msg = $self->{round};
137 $self->{gui}->rounds($msg);
141 my ($self, $time, $who) = @_;
143 return if !defined $time || $time == 0;
145 # print "Check_best_lap $time $who vs ",
146 # defined $self->{best_lap} ? $self->{best_lap} : 'undef',
148 if (!defined $self->{best_lap}
149 || $time < $self->{best_lap}) {
150 $self->{best_lap} = $time;
151 $self->{gui}->best_lap($time, $who);
157 sub qualification_start {
160 return if $self->{qualification_running};
162 $self->car($car)->set_lap(undef);
163 $self->car($car)->set_laptime(undef);
166 $self->{qualification_running} = 1;
167 $self->{gui}->rounds('Qualification');
168 $self->{gui}->time(undef);
169 $self->{gui}->best_lap(undef);
172 sub packet_received {
173 my ($self, $time) = @_;
175 if ($self->{race_running}) {
176 $self->{gui}->time($time - $self->{race_running_since});
181 my ($self, $now) = @_;
183 return if !$self->{race_running};
188 $laps[$id] = $self->car($id)->{lap} // -1;
189 $times[$id] = $self->car($id)->{first_finish_time} // $now;
192 my @new_order = sort {
193 $laps[$b] <=> $laps[$a]
195 $times[$a] <=> $times[$b]
200 my $lap_max = $laps[$new_order[0]];
201 my $lap_max_changed = 0;
202 if (defined $lap_max && defined $self->{round}
203 && $lap_max != $self->{round}) {
204 $self->{round} = $lap_max;
205 $lap_max_changed = 1;
209 if ($self->{round} && $self->{race_rounds}
210 && $self->{round} > $self->{race_rounds}) {
211 $self->{race_finishing} = 1;
215 my $car = $new_order[$id];
216 if ($self->car($car)->{order} != $id) {
217 $self->car($car)->set_order($id);
220 return ($lap_max_changed, $lap_max, $times[$new_order[0]]);
224 my ($self, $time, $regular, @cars) = @_;
229 for my $car (@cars) {
230 if ($self->car($car)->finish_line($time, $regular)) {
231 $processed{$car} = 1;
236 return if !$was_processed;
238 my ($lap_max_changed, $lap_max, $time_min)
239 = $self->recalc_order($time);
242 if ($processed{$car}) {
243 $self->car($car)->recalc_distance(
244 $lap_max, $time_min, $self->{race_finishing},
246 } elsif ($lap_max_changed) {
247 $self->car($car)->greyout_distance;