This bit us. This bit us hard and I blame myself for not catching it. Looking at it after a good night's sleep sets off tons of loud, Star Trek-esque "red alert" klaxons. Why it's bad is left as an exercise for the reader.
################################################################################ # contract: Player, index -> Turn # let the player take its turn and do validation/contract checking/timeouts sub give_turn_to_player { my ($self, $player, $index) = @_;
my $turn = Game::Turn->new({ index => $index, player => $player, admin => $self, });
try { local $SIG{ALRM} = sub { throw Game::Exception::PlayerTimeout( 'Player timed out after '.PLAYER_TIMEOUT.' seconds' ); }; alarm PLAYER_TIMEOUT;
$player->is_taking_turn(1); $player->take_turn($turn); $player->is_taking_turn(0); }
catch Game::Exception::ContractViolation with { $self->kick_out_player($player, "You have violated a contract: ".shift); return; }
catch Game::Exception::PlayerTimeout with { $self->kick_out_player($player, "You have timed out after ".PLAYER_TIMEOUT." seconds."); return; }
otherwise { die "asking the player to take a turn failed: ".shift; }
finally { alarm 0; };
unless ($turn->chosen_tile) { $self->kick_out_player($player, "You have attempted to place an undefined tile."); return; }
return $turn; }