feat: implemented Lifetime- and TimeoutTimer
This commit is contained in:
parent
6b10287808
commit
11923b89a0
@ -0,0 +1,34 @@
|
|||||||
|
package uulm.teamname.marvelous.server.lobby;
|
||||||
|
|
||||||
|
import uulm.teamname.marvelous.server.Server;
|
||||||
|
import uulm.teamname.marvelous.server.lobbymanager.Participant;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.ThreadFactory;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A timer meant to time the entire Lifetime of the lobby, and if it is higher than the maximum permitted value,
|
||||||
|
* call a callback given by the lobby to compute a winner, and quit the lobby.
|
||||||
|
*/
|
||||||
|
public class LifetimeTimer {
|
||||||
|
|
||||||
|
private final ScheduledExecutorService timer;
|
||||||
|
private final int maxGameTime;
|
||||||
|
private final Runnable callback;
|
||||||
|
|
||||||
|
LifetimeTimer(int maxGameTime, Runnable callback) {
|
||||||
|
String lobbyThreadName = Thread.currentThread().getName();
|
||||||
|
ThreadFactory threadFactory = r -> new Thread(r, lobbyThreadName + "-LifetimeTimerThread");
|
||||||
|
this.timer = Executors.newSingleThreadScheduledExecutor(threadFactory);
|
||||||
|
|
||||||
|
this.maxGameTime = maxGameTime;
|
||||||
|
this.callback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void startTimer() {
|
||||||
|
timer.schedule(callback, maxGameTime, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,89 @@
|
|||||||
|
package uulm.teamname.marvelous.server.lobby;
|
||||||
|
|
||||||
|
import org.tinylog.Logger;
|
||||||
|
import uulm.teamname.marvelous.server.Server;
|
||||||
|
import uulm.teamname.marvelous.server.lobbymanager.Participant;
|
||||||
|
|
||||||
|
import java.util.concurrent.*;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public class TimeoutTimer {
|
||||||
|
|
||||||
|
private final ScheduledExecutorService timer;
|
||||||
|
|
||||||
|
private ScheduledFuture<Participant> player1AlmostTimeout, player1Timeout;
|
||||||
|
private ScheduledFuture<Participant> player2AlmostTimeout, player2Timeout;
|
||||||
|
|
||||||
|
private final BiConsumer<Participant, Integer> almostTimeoutCallback;
|
||||||
|
private final Consumer<Participant> timeoutCallback;
|
||||||
|
|
||||||
|
private final int almostTimeoutTime, timeoutTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class that manages timeouts of players after not sending a message for a long time.
|
||||||
|
*
|
||||||
|
* @param timeoutTime is the time that a player has to send any message
|
||||||
|
* @param almostTimeoutCallback is the callback that is called if the timeoutTime is almost over
|
||||||
|
* @param timeoutCallback is the callback that is called when the timeoutTime is over
|
||||||
|
*/
|
||||||
|
public TimeoutTimer(int timeoutTime,
|
||||||
|
BiConsumer<Participant, Integer> almostTimeoutCallback,
|
||||||
|
Consumer<Participant> timeoutCallback) {
|
||||||
|
this.almostTimeoutCallback = almostTimeoutCallback;
|
||||||
|
this.timeoutCallback = timeoutCallback;
|
||||||
|
|
||||||
|
this.timeoutTime = timeoutTime;
|
||||||
|
this.almostTimeoutTime = Math.max(timeoutTime - 15, Math.min(timeoutTime, 5));
|
||||||
|
|
||||||
|
String lobbyThreadName = Thread.currentThread().getName();
|
||||||
|
ThreadFactory threadFactory = r -> new Thread(r, lobbyThreadName + "-timeoutTimer");
|
||||||
|
timer = Executors.newSingleThreadScheduledExecutor(threadFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Refreshes the timeout timer for the given Participant. This is meant to be used for Players, not Spectators. */
|
||||||
|
public void refreshTimer(Participant participant) {
|
||||||
|
Logger.debug("Refreshing turnTimer for participant of type '{}'", participant.type);
|
||||||
|
switch (participant.type) {
|
||||||
|
case PlayerOne -> {
|
||||||
|
Logger.trace("Was playerOne, refreshing...");
|
||||||
|
if (player1AlmostTimeout != null) player1AlmostTimeout.cancel(false);
|
||||||
|
player1AlmostTimeout =
|
||||||
|
timer.schedule(() -> {
|
||||||
|
almostTimeoutCallback.accept(participant, almostTimeoutTime - timeoutTime);
|
||||||
|
return participant;
|
||||||
|
}, this.almostTimeoutTime, TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
if (player1Timeout != null) player1Timeout.cancel(false);
|
||||||
|
player1Timeout =
|
||||||
|
timer.schedule(() -> {
|
||||||
|
timeoutCallback.accept(participant);
|
||||||
|
return participant;
|
||||||
|
}, this.timeoutTime, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
case PlayerTwo -> {
|
||||||
|
Logger.trace("Was playerOne, refreshing...");
|
||||||
|
if (player2AlmostTimeout != null) player2AlmostTimeout.cancel(false);
|
||||||
|
player2AlmostTimeout =
|
||||||
|
timer.schedule(() -> {
|
||||||
|
almostTimeoutCallback.accept(participant, almostTimeoutTime - timeoutTime);
|
||||||
|
return participant;
|
||||||
|
}, this.almostTimeoutTime, TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
if (player2Timeout != null) player2Timeout.cancel(false);
|
||||||
|
player2Timeout =
|
||||||
|
timer.schedule(() -> {
|
||||||
|
timeoutCallback.accept(participant);
|
||||||
|
return participant;
|
||||||
|
}, this.timeoutTime, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
case Spectator -> Logger.warn("Timeout called on spectator '{}'. This is probably a bug.",
|
||||||
|
participant.id.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user