improved null safety

This commit is contained in:
2022-01-12 11:35:02 +01:00
parent c75cf03762
commit 0f3d3e929d
40 changed files with 157 additions and 113 deletions

View File

@@ -42,7 +42,7 @@ public class LobbyCommand {
if (count == 1) builder.append("There is one open session:\n");
else builder.append("There are ").append(count).append(" open sessions:\n");
sessions.forEach((session) -> builder.append(session).append('\n'));
sessions.forEach((uuid, session) -> builder.append(session).append('\n'));
client.println(builder);
} else {
client.println("No sessions.");
@@ -106,7 +106,7 @@ public class LobbyCommand {
@NotNull
@Override
public Iterator<String> iterator() {
return lobby.getSessions().stream().map(SessionData::getUuid).map(UUID::toString).iterator();
return lobby.getSessions().values().stream().map(SessionData::getUuid).map(UUID::toString).iterator();
}
}
}

View File

@@ -10,10 +10,10 @@ import java.util.*;
public final class Lobby extends BaseState {
@Getter
private final Set<SessionData> sessions = new HashSet<>();
private final Map<UUID, SessionData> sessions = new HashMap<>();
public Lobby(SessionListMessage list) {
sessions.addAll(list.getSessions());
list.getSessions().forEach(session -> sessions.put(session.getUuid(), session));
}
@Override
@@ -30,18 +30,18 @@ public final class Lobby extends BaseState {
public Optional<ClientState> onMessage(Client client, ServerMessage message) {
if (message instanceof SessionCreatedMessage created) {
var session = created.getSession();
sessions.add(session);
sessions.put(session.getUuid(), session);
return Optional.empty();
} else if (message instanceof SessionRemovedMessage removed) {
sessions.remove(new SessionData(removed.getSession(), null, 0, null));
sessions.remove(removed.getSession());
return Optional.empty();
} else if (message instanceof SessionModifiedMessage modified) {
sessions.remove(modified.getSession());
sessions.add(modified.getSession());
var session = modified.getSession();
sessions.put(session.getUuid(), session);
return Optional.empty();
} else if (message instanceof SessionListMessage list) {
sessions.clear();
sessions.addAll(list.getSessions());
list.getSessions().forEach(session -> sessions.put(session.getUuid(), session));
return Optional.empty();
} else {
return unexpectedMessage(client, message);

View File

@@ -8,6 +8,7 @@ import eu.jonahbauer.wizard.client.libgdx.GameAtlas;
import eu.jonahbauer.wizard.common.model.Card;
import lombok.Getter;
import lombok.Setter;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.EnumMap;
@@ -115,23 +116,23 @@ public class CardActor extends Actor {
setOrigin(PREF_WIDTH / 2, PREF_HEIGHT / 2);
}
public CardActor(Card card, TextureAtlas atlas) {
public CardActor(@NotNull Card card, @NotNull TextureAtlas atlas) {
this(atlas);
setCard(card);
}
public CardActor(Card.Suit suit, TextureAtlas atlas) {
public CardActor(@NotNull Card.Suit suit, @NotNull TextureAtlas atlas) {
this(atlas);
setCard(suit);
}
public void setCard(Card card) {
public void setCard(@NotNull Card card) {
this.card = card;
this.background = atlas.findRegion(ATLAS_PATHS.get(card));
if (this.background == null) throw new NoSuchElementException("Could not find texture for card " + card + ".");
}
public void setCard(Card.Suit suit) {
public void setCard(@NotNull Card.Suit suit) {
this.card = null;
this.background = atlas.findRegion(switch (suit) {
case NONE -> GameAtlas.CARDS_BACKGROUND;

View File

@@ -13,6 +13,8 @@ import eu.jonahbauer.wizard.client.libgdx.util.Pair;
import eu.jonahbauer.wizard.common.model.Card;
import lombok.Getter;
import lombok.Setter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.function.Consumer;
@@ -180,7 +182,7 @@ public class CardsGroup extends WidgetGroup {
animate = false;
}
public Pair<List<CardActor>, List<CardActor>> update(List<Card> cards) {
public @NotNull Pair<List<CardActor>, List<CardActor>> update(@NotNull List<Card> cards) {
var added = new ArrayList<>(cards);
var removed = new ArrayList<Card>();
@@ -203,7 +205,7 @@ public class CardsGroup extends WidgetGroup {
return Pair.of(removedActors, addedActors);
}
public CardActor remove(Card card) {
public @Nullable CardActor remove(Card card) {
var actor = find(card);
if (actor == null) return null;
@@ -223,7 +225,7 @@ public class CardsGroup extends WidgetGroup {
return actor;
}
public CardActor find(Card card) {
public @Nullable CardActor find(Card card) {
var children = getChildren();
for (int i = 0; i < children.size; i++) {
if (children.get(i) instanceof CardActor cardActor && cardActor.getCard() == card) {

View File

@@ -4,10 +4,11 @@ import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup;
import eu.jonahbauer.wizard.client.libgdx.actors.game.CardActor;
import eu.jonahbauer.wizard.client.libgdx.screens.GameScreen;
import eu.jonahbauer.wizard.common.model.Card;
import org.jetbrains.annotations.NotNull;
public class ChangePredictionOverlay extends MakePredictionOverlay {
public ChangePredictionOverlay(GameScreen gameScreen, long timeout, int round, int oldPrediction) {
public ChangePredictionOverlay(@NotNull GameScreen gameScreen, long timeout, int round, int oldPrediction) {
super(
gameScreen,
timeout,

View File

@@ -7,7 +7,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import eu.jonahbauer.wizard.client.libgdx.screens.GameScreen;
import eu.jonahbauer.wizard.common.messages.player.PredictMessage;
import org.jetbrains.annotations.NotNull;
import java.util.stream.IntStream;
@@ -16,11 +16,11 @@ public class MakePredictionOverlay extends Overlay implements InteractionOverlay
private final int[] values;
private final TextButton[] buttons;
public MakePredictionOverlay(GameScreen gameScreen, long timeout, int round) {
public MakePredictionOverlay(@NotNull GameScreen gameScreen, long timeout, int round) {
this(gameScreen, timeout, IntStream.range(0, round + 2).toArray());
}
protected MakePredictionOverlay(GameScreen gameScreen, long timeout, int[] values) {
protected MakePredictionOverlay(@NotNull GameScreen gameScreen, long timeout, int[] values) {
super(gameScreen, timeout);
this.values = values;
this.buttons = new TextButton[values.length];

View File

@@ -13,6 +13,7 @@ import eu.jonahbauer.wizard.client.libgdx.WizardGame;
import eu.jonahbauer.wizard.client.libgdx.screens.GameScreen;
import lombok.AccessLevel;
import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import static com.badlogic.gdx.scenes.scene2d.actions.Actions.*;
@@ -29,7 +30,7 @@ public abstract class Overlay extends Action {
private boolean closing;
private boolean closed;
public Overlay(GameScreen gameScreen, long timeout) {
public Overlay(@NotNull GameScreen gameScreen, long timeout) {
this.screen = gameScreen;
this.data = gameScreen.getData();
this.messages = gameScreen.getMessages();

View File

@@ -9,6 +9,7 @@ import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import eu.jonahbauer.wizard.client.libgdx.actors.game.CardActor;
import eu.jonahbauer.wizard.client.libgdx.screens.GameScreen;
import eu.jonahbauer.wizard.common.model.Card;
import org.jetbrains.annotations.NotNull;
import java.util.EnumMap;
@@ -18,7 +19,7 @@ public class PickTrumpOverlay extends Overlay implements InteractionOverlay {
private final EnumMap<Card.Suit, CardActor> cards = new EnumMap<>(Card.Suit.class);
public PickTrumpOverlay(GameScreen gameScreen, long timeout, boolean allowNone) {
public PickTrumpOverlay(@NotNull GameScreen gameScreen, long timeout, boolean allowNone) {
super(gameScreen, timeout);
this.allowNone = allowNone;
}

View File

@@ -11,6 +11,7 @@ import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import eu.jonahbauer.wizard.client.libgdx.actors.game.CardActor;
import eu.jonahbauer.wizard.client.libgdx.screens.GameScreen;
import eu.jonahbauer.wizard.common.model.Card;
import org.jetbrains.annotations.NotNull;
import java.util.EnumMap;
@@ -21,7 +22,9 @@ public class PlayColoredCardOverlay extends Overlay implements InteractionOverla
private final Card card;
public PlayColoredCardOverlay(GameScreen gameScreen, long timeout, Card card, Card red, Card green, Card blue, Card yellow) {
public PlayColoredCardOverlay(@NotNull GameScreen gameScreen, long timeout, @NotNull Card card,
@NotNull Card red, @NotNull Card green, @NotNull Card blue, @NotNull Card yellow)
{
super(gameScreen, timeout);
this.card = card;
this.cards.put(Card.Suit.RED, red);

View File

@@ -6,6 +6,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup;
import eu.jonahbauer.wizard.client.libgdx.AnimationTimings;
import eu.jonahbauer.wizard.client.libgdx.screens.GameScreen;
import org.jetbrains.annotations.NotNull;
import static com.badlogic.gdx.scenes.scene2d.actions.Actions.*;
@@ -13,7 +14,7 @@ public class StartRoundOverlay extends Overlay {
private final int round;
public StartRoundOverlay(GameScreen gameScreen, int round) {
public StartRoundOverlay(@NotNull GameScreen gameScreen, int round) {
super(gameScreen, Long.MAX_VALUE);
this.round = round;
}

View File

@@ -12,8 +12,11 @@ import eu.jonahbauer.wizard.client.libgdx.actions.MyActions;
import eu.jonahbauer.wizard.client.libgdx.actors.game.CardActor;
import eu.jonahbauer.wizard.client.libgdx.screens.GameScreen;
import eu.jonahbauer.wizard.common.model.Card;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
import java.util.Objects;
import static com.badlogic.gdx.scenes.scene2d.actions.Actions.*;
import static eu.jonahbauer.wizard.client.libgdx.actions.MyActions.*;
@@ -81,22 +84,22 @@ public class TrumpOverlay extends Overlay {
Map.entry(Card.FAIRY, Card.Suit.NONE)
);
private final String player;
private final Card card;
private final Card.Suit suit;
private final @Nullable String player;
private final @NotNull Card card;
private final @Nullable Card.Suit suit;
private final CardActor trumpCardActor;
private final CardActor trumpSuitActor;
private final @NotNull CardActor trumpCardActor;
private final @NotNull CardActor trumpSuitActor;
private boolean animateCard = true;
public TrumpOverlay(GameScreen gameScreen, String player, Card card, Card.Suit suit) {
public TrumpOverlay(@NotNull GameScreen gameScreen, @Nullable String player, @NotNull Card card, @Nullable Card.Suit suit) {
super(gameScreen, Long.MAX_VALUE);
this.player = player;
this.card = card;
this.suit = suit;
this.trumpCardActor = gameScreen.getTrumpCardActor();
this.trumpSuitActor = gameScreen.getTrumpSuitActor();
this.trumpCardActor = Objects.requireNonNull(gameScreen.getTrumpCardActor());
this.trumpSuitActor = Objects.requireNonNull(gameScreen.getTrumpSuitActor());
}
@Override
@@ -141,7 +144,7 @@ public class TrumpOverlay extends Overlay {
}
trumpSuitActor.remove();
if (suit != DEFAULT_SUITES.get(card)) {
if (suit != null && suit != DEFAULT_SUITES.get(card)) {
trumpSuitActor.setRotation(0);
trumpSuitActor.setOrigin(0, 0);
cardGroup.addActor(trumpSuitActor);
@@ -164,7 +167,7 @@ public class TrumpOverlay extends Overlay {
));
}
if (suit != DEFAULT_SUITES.get(card)) {
if (suit != null && suit != DEFAULT_SUITES.get(card)) {
cardAnimation.addAction(sequence(
targeting(trumpSuitActor, removeActorSilently()),
targeting(trumpSuitActor, changeParent(parent)),

View File

@@ -203,11 +203,11 @@ public class GameScreen extends MenuScreen {
return self.equals(uuid);
}
public void onCardClicked(Card card) {
public void onCardClicked(@NotNull Card card) {
game.getClient().execute(Game.class, (s, c) -> s.onCardClicked(c, card));
}
public void onSuitClicked(Card.Suit suit) {
public void onSuitClicked(@NotNull Card.Suit suit) {
game.getClient().execute(Game.class, (s, c) -> s.onSuitClicked(c, suit));
}
@@ -241,7 +241,7 @@ public class GameScreen extends MenuScreen {
execute(() -> cardStack.clearChildren());
}
public void finishTrick(UUID player) {
public void finishTrick(@NotNull UUID player) {
var seat = seats.getOrDefault(player, Seat.FALLBACK);
var action = parallel();
@@ -272,7 +272,7 @@ public class GameScreen extends MenuScreen {
/**
* Updates the given players hand cards.
*/
public void setHand(UUID player, List<Card> cards, boolean juggle) {
public void setHand(@NotNull UUID player, @NotNull List<Card> cards, boolean juggle) {
if (isSelf(player)) {
var sequence = sequence();
sequence.addAction(run(() -> {
@@ -291,7 +291,7 @@ public class GameScreen extends MenuScreen {
* Adds the prediction for the given round and player to the {@linkplain #padOfTruth pad of truth} and
* shows a corresponding message.
*/
public void addPrediction(int round, UUID player, int prediction, boolean changed) {
public void addPrediction(int round, @NotNull UUID player, int prediction, boolean changed) {
if (isSelf(player)) {
addMessage(game.messages.format("game.action." + (changed ? "change" : "make") + "_prediction.self", prediction));
} else {
@@ -299,13 +299,16 @@ public class GameScreen extends MenuScreen {
addMessage(game.messages.format("game.action." + (changed ? "change" : "make") + "_prediction.other", name, prediction));
}
execute(() -> padOfTruth.setPrediction(orderedPlayers.indexOf(player), round, prediction));
var index = orderedPlayers.indexOf(player);
if (index == -1) throw new NoSuchElementException();
execute(() -> padOfTruth.setPrediction(index, round, prediction));
}
/**
* Removes the card from the players hand and puts it into the {@linkplain #cardStack stack}.
*/
public void playCard(UUID player, Card card) {
public void playCard(@NotNull UUID player, @NotNull Card card) {
if (isSelf(player)) {
addMessage(game.messages.get("game.action.play_card.self"));
} else {
@@ -336,11 +339,11 @@ public class GameScreen extends MenuScreen {
/**
* Adds the scores for a round to the corresponding row of the {@linkplain #padOfTruth pad of truth}.
*/
public void addScores(int round, Map<UUID, Integer> scores) {
public void addScores(int round, @NotNull Map<UUID, Integer> scores) {
execute(() -> {
for (int i = 0; i < orderedPlayers.size(); i++) {
UUID player = orderedPlayers.get(i);
padOfTruth.setScore(i, round, scores.get(player));
padOfTruth.setScore(i, round, scores.getOrDefault(player, 0));
}
});
}
@@ -356,10 +359,10 @@ public class GameScreen extends MenuScreen {
* Highlights the given players label and sets the {@linkplain #setPersistentMessage(String) persistent message}
* accordingly.
*/
public void setActivePlayer(UUID player, UserInputMessage.Action action, long timeout) {
public void setActivePlayer(@Nullable UUID player, @Nullable UserInputMessage.Action action, long timeout) {
execute(() -> nameLabels.forEach((p, l) -> l.setStyle(p.equals(player) ? labelStyleActive : labelStyleDefault)));
if (isSelf(player) || player == null && action == null) {
if (isSelf(player) || action == null) {
setPersistentMessage(null);
} else {
var key = switch (action) {
@@ -390,7 +393,7 @@ public class GameScreen extends MenuScreen {
* Swaps the current {@linkplain #trumpCardActor trump card} (if present) with a {@linkplain Card#WEREWOLF werewolf}
* card on the given players hand.
*/
public void swapTrumpCard(UUID player) {
public void swapTrumpCard(@NotNull UUID player) {
var seat = seats.getOrDefault(player, Seat.FALLBACK);
var sequence = sequence();
@@ -448,7 +451,7 @@ public class GameScreen extends MenuScreen {
}
//<editor-fold desc="Overlays" defaultstate="collapsed">
public void showTrumpOverlay(UUID player, Card trumpCard, Card.Suit trumpSuit) {
public void showTrumpOverlay(@Nullable UUID player, @NotNull Card trumpCard, @Nullable Card.Suit trumpSuit) {
if (trumpCardActor == null) {
trumpCardActor = new CardActor(Card.HIDDEN, atlas);
}
@@ -460,7 +463,7 @@ public class GameScreen extends MenuScreen {
execute(new TrumpOverlay(this, players.get(player), trumpCard, trumpSuit));
}
public void showColoredCardOverlay(Card card, long timeout) {
public void showColoredCardOverlay(@NotNull Card card, long timeout) {
if (card == Card.JUGGLER) {
execute(new PlayColoredCardOverlay(this, timeout, card, Card.JUGGLER_RED, Card.JUGGLER_GREEN, Card.JUGGLER_BLUE, Card.JUGGLER_YELLOW));
} else if (card == Card.CLOUD) {
@@ -587,7 +590,7 @@ public class GameScreen extends MenuScreen {
return game.messages;
}
private Action animateJuggle(List<CardActor> removed, List<CardActor> added) {
private Action animateJuggle(@NotNull List<CardActor> removed, @NotNull List<CardActor> added) {
// find left- and rightmost seat
Seat tmpLeft = null, tmpRight = null;
for (Seat seat : seats.values()) {