mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 10:48:00 +00:00
Remove global Player cache, instead make it hang off the Game object.
This commit is contained in:
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -280,6 +280,7 @@ forge-game/src/main/java/forge/game/GameAction.java svneol=native#text/plain
|
||||
forge-game/src/main/java/forge/game/GameActionUtil.java svneol=native#text/plain
|
||||
forge-game/src/main/java/forge/game/GameEndReason.java -text
|
||||
forge-game/src/main/java/forge/game/GameEntity.java -text
|
||||
forge-game/src/main/java/forge/game/GameEntityCache.java -text
|
||||
forge-game/src/main/java/forge/game/GameEntityView.java -text
|
||||
forge-game/src/main/java/forge/game/GameFormat.java -text
|
||||
forge-game/src/main/java/forge/game/GameLog.java -text
|
||||
|
||||
@@ -53,6 +53,7 @@ import forge.game.phase.Untap;
|
||||
import forge.game.phase.Upkeep;
|
||||
import forge.game.player.IGameEntitiesFactory;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.PlayerView;
|
||||
import forge.game.player.RegisteredPlayer;
|
||||
import forge.game.replacement.ReplacementHandler;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
@@ -102,9 +103,16 @@ public class Game {
|
||||
|
||||
private final GameView view;
|
||||
|
||||
private GameEntityCache<Player, PlayerView> playerCache = new GameEntityCache<>();
|
||||
public Player getPlayer(PlayerView playerView) {
|
||||
return playerCache.get(playerView);
|
||||
}
|
||||
public void addPlayer(Integer id, Player player) {
|
||||
playerCache.put(id, player);
|
||||
}
|
||||
|
||||
public Game(List<RegisteredPlayer> players0, GameRules rules0, Match match0) { /* no more zones to map here */
|
||||
Card.clearCache();
|
||||
Player.clearCache();
|
||||
|
||||
rules = rules0;
|
||||
match = match0;
|
||||
|
||||
@@ -19,28 +19,15 @@ package forge.game;
|
||||
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardCollection;
|
||||
import forge.game.card.CardView;
|
||||
import forge.game.card.CardCollectionView;
|
||||
import forge.game.event.GameEventCardAttachment;
|
||||
import forge.game.event.GameEventCardAttachment.AttachMethod;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.PlayerView;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
|
||||
public abstract class GameEntity extends GameObject implements IIdentifiable {
|
||||
public static GameEntity get(GameEntityView gameEntityView) {
|
||||
if (gameEntityView instanceof CardView) {
|
||||
return Card.get((CardView)gameEntityView);
|
||||
}
|
||||
if (gameEntityView instanceof PlayerView) {
|
||||
return Player.get((PlayerView)gameEntityView);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected final int id;
|
||||
private String name = "";
|
||||
private int preventNextDamage = 0;
|
||||
|
||||
33
forge-game/src/main/java/forge/game/GameEntityCache.java
Normal file
33
forge-game/src/main/java/forge/game/GameEntityCache.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package forge.game;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class GameEntityCache<Entity extends GameEntity, View extends GameEntityView> {
|
||||
private HashMap<Integer, Entity> entityCache = new HashMap<Integer, Entity>();
|
||||
|
||||
public void put(Integer id, Entity entity) {
|
||||
entityCache.put(id, entity);
|
||||
}
|
||||
|
||||
public Entity get(View entityView) {
|
||||
if (entityView == null) { return null; }
|
||||
return entityCache.get(entityView.getId());
|
||||
}
|
||||
|
||||
public void addToList(Iterable<View> views, List<Entity> list) {
|
||||
for (View view : views) {
|
||||
Entity entity = get(view);
|
||||
if (entity != null) {
|
||||
list.add(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<Entity> getList(Iterable<View> views) {
|
||||
List<Entity> list = new ArrayList<Entity>();
|
||||
addToList(views, list);
|
||||
return list;
|
||||
}
|
||||
}
|
||||
@@ -209,6 +209,6 @@ public class GameView extends TrackableObject {
|
||||
}
|
||||
|
||||
public AnteResult getAnteResult(PlayerView player) {
|
||||
return game.getOutcome().anteResult.get(Player.get(player));
|
||||
return game.getOutcome().anteResult.get(game.getPlayer(player));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,25 +82,6 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
ZoneType.Library, ZoneType.Graveyard, ZoneType.Hand, ZoneType.Exile, ZoneType.Command, ZoneType.Ante,
|
||||
ZoneType.Sideboard, ZoneType.PlanarDeck, ZoneType.SchemeDeck));
|
||||
|
||||
private static HashMap<Integer, Player> playerCache = new HashMap<Integer, Player>();
|
||||
public static Player get(PlayerView playerView) {
|
||||
if (playerView == null) { return null; }
|
||||
return playerCache.get(playerView.getId());
|
||||
}
|
||||
public static List<Player> getList(Iterable<PlayerView> playerViews) {
|
||||
List<Player> list = new ArrayList<Player>();
|
||||
for (PlayerView pv : playerViews) {
|
||||
Player p = get(pv);
|
||||
if (p != null) {
|
||||
list.add(p);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
public static void clearCache() {
|
||||
playerCache.clear();
|
||||
}
|
||||
|
||||
private final Map<Card, Integer> commanderDamage = new HashMap<Card, Integer>();
|
||||
|
||||
private int poisonCounters = 0;
|
||||
@@ -174,7 +155,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
view.updateKeywords(this);
|
||||
setName(chooseName(name0));
|
||||
if (id0 >= 0) {
|
||||
playerCache.put(id0, this);
|
||||
game.addPlayer(id, this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2214,6 +2195,8 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
controllerCreator = ctrlr;
|
||||
controller = ctrlr;
|
||||
view.updateAvatarIndex(this);
|
||||
view.updateIsAI(this);
|
||||
view.updateLobbyPlayerName(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -41,6 +41,23 @@ public class PlayerView extends GameEntityView {
|
||||
set(TrackableProperty.Mana, Maps.newHashMapWithExpectedSize(MagicColor.NUMBER_OR_COLORS + 1));
|
||||
}
|
||||
|
||||
public boolean isAI() {
|
||||
return get(TrackableProperty.IsAI);
|
||||
}
|
||||
void updateIsAI(Player p) {
|
||||
set(TrackableProperty.IsAI, p.getController().isAI());
|
||||
}
|
||||
|
||||
public String getLobbyPlayerName() {
|
||||
return get(TrackableProperty.LobbyPlayerName);
|
||||
}
|
||||
void updateLobbyPlayerName(Player p) {
|
||||
set(TrackableProperty.LobbyPlayerName, p.getLobbyPlayer().getName());
|
||||
}
|
||||
public boolean isLobbyPlayer(LobbyPlayer p) {
|
||||
return getLobbyPlayerName().equals(p.getName());
|
||||
}
|
||||
|
||||
public int getAvatarIndex() {
|
||||
return get(TrackableProperty.AvatarIndex);
|
||||
}
|
||||
@@ -257,9 +274,4 @@ public class PlayerView extends GameEntityView {
|
||||
}
|
||||
set(TrackableProperty.Mana, mana);
|
||||
}
|
||||
|
||||
//TODO: Find better way to do this
|
||||
public LobbyPlayer getLobbyPlayer() {
|
||||
return Player.get(this).getLobbyPlayer();
|
||||
}
|
||||
}
|
||||
@@ -85,6 +85,8 @@ public enum TrackableProperty {
|
||||
FoilIndex(TrackableTypes.IntegerType),
|
||||
|
||||
//Player
|
||||
IsAI(TrackableTypes.BooleanType),
|
||||
LobbyPlayerName(TrackableTypes.StringType),
|
||||
AvatarIndex(TrackableTypes.IntegerType),
|
||||
Opponents(TrackableTypes.PlayerViewCollectionType),
|
||||
Life(TrackableTypes.IntegerType),
|
||||
|
||||
@@ -304,6 +304,6 @@ public class GuiDesktop implements IGuiBase {
|
||||
|
||||
@Override
|
||||
public void setPlayerAvatar(LobbyPlayer player, IHasIcon ihi) {
|
||||
CMatchUI.SINGLETON_INSTANCE.avatarImages.put(player, ihi.getIconImageKey());
|
||||
CMatchUI.SINGLETON_INSTANCE.avatarImages.put(player.getName(), ihi.getIconImageKey());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,6 @@ import forge.match.IMatchController;
|
||||
import forge.match.MatchUtil;
|
||||
import forge.menus.IMenuProvider;
|
||||
import forge.model.FModel;
|
||||
import forge.player.LobbyPlayerHuman;
|
||||
import forge.properties.ForgePreferences;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.screens.match.controllers.CAntes;
|
||||
@@ -110,11 +109,11 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController {
|
||||
private boolean showOverlay = true;
|
||||
|
||||
private IVDoc<? extends ICDoc> selectedDocBeforeCombat;
|
||||
public final Map<LobbyPlayer, String> avatarImages = new HashMap<LobbyPlayer, String>();
|
||||
|
||||
private SkinImage getPlayerAvatar(final LobbyPlayer p, final int defaultIndex) {
|
||||
if (avatarImages.containsKey(p)) {
|
||||
return ImageCache.getIcon(avatarImages.get(p));
|
||||
public final Map<String, String> avatarImages = new HashMap<String, String>();
|
||||
|
||||
private SkinImage getPlayerAvatar(final PlayerView p, final int defaultIndex) {
|
||||
if (avatarImages.containsKey(p.getLobbyPlayerName())) {
|
||||
return ImageCache.getIcon(avatarImages.get(p.getLobbyPlayerName()));
|
||||
}
|
||||
|
||||
int avatarIdx = p.getAvatarIndex();
|
||||
@@ -147,7 +146,7 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController {
|
||||
commands.add(c);
|
||||
|
||||
//setAvatar(f, new ImageIcon(FSkin.getAvatars().get()));
|
||||
setAvatar(f, getPlayerAvatar(p.getLobbyPlayer(), Integer.parseInt(indices[i > 2 ? 1 : 0])));
|
||||
setAvatar(f, getPlayerAvatar(p, Integer.parseInt(indices[i > 2 ? 1 : 0])));
|
||||
f.getLayoutControl().initialize();
|
||||
c.getLayoutControl().initialize();
|
||||
i++;
|
||||
@@ -167,7 +166,7 @@ public enum CMatchUI implements ICDoc, IMenuProvider, IMatchController {
|
||||
|
||||
int i = 0;
|
||||
for (final PlayerView p : sortedPlayers) {
|
||||
if (allHands || p.getLobbyPlayer() instanceof LobbyPlayerHuman || CardView.mayViewAny(p.getHand(), p)) {
|
||||
if (allHands || !p.isAI() || CardView.mayViewAny(p.getHand(), p)) {
|
||||
VHand newHand = new VHand(EDocID.Hands[i], p);
|
||||
newHand.getLayoutControl().initialize();
|
||||
hands.add(newHand);
|
||||
|
||||
@@ -80,7 +80,7 @@ public class QuestDraftWinLose extends ControlWinLose {
|
||||
final Iterable<PlayerView> players = lastGame.getPlayers();
|
||||
boolean gameHadHumanPlayer = false;
|
||||
for (final PlayerView p : players) {
|
||||
if (p.getLobbyPlayer().equals(questLobbyPlayer)) {
|
||||
if (p.isLobbyPlayer(questLobbyPlayer)) {
|
||||
gameHadHumanPlayer = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -199,7 +199,7 @@ public class VAssignDamage {
|
||||
}
|
||||
else if (defender instanceof PlayerView) {
|
||||
final PlayerView p = (PlayerView)defender;
|
||||
fakeCard = new CardView(-1, defender.toString(), p, CMatchUI.SINGLETON_INSTANCE.avatarImages.get(p.getLobbyPlayer()));
|
||||
fakeCard = new CardView(-1, defender.toString(), p, CMatchUI.SINGLETON_INSTANCE.avatarImages.get(p.getLobbyPlayerName()));
|
||||
}
|
||||
addPanelForDefender(pnlDefenders, fakeCard);
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ public class CField implements ICDoc {
|
||||
|
||||
Function<Byte, Boolean> manaAction = new Function<Byte, Boolean>() {
|
||||
public Boolean apply(Byte colorCode) {
|
||||
if (CField.this.player.getLobbyPlayer() == Singletons.getControl().getGuiPlayer()) {
|
||||
if (CField.this.player.isLobbyPlayer(Singletons.getControl().getGuiPlayer())) {
|
||||
return MatchUtil.getHumanController().useMana(colorCode.byteValue());
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -20,7 +20,6 @@ package forge.view.arcane;
|
||||
import forge.Singletons;
|
||||
import forge.assets.FSkinProp;
|
||||
import forge.game.card.CardView;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.PlayerView;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.gui.framework.SDisplayUtil;
|
||||
@@ -169,7 +168,7 @@ public class FloatingCardArea extends CardArea {
|
||||
player = player0;
|
||||
title = Lang.getPossessedObject(player0.getName(), zone.name()) + " (%d)";
|
||||
|
||||
boolean isAi = Player.get(player0).getController().isAI();
|
||||
boolean isAi = player0.isAI();
|
||||
switch (zone) {
|
||||
case Exile:
|
||||
locPref = isAi ? FPref.ZONE_LOC_AI_EXILE : FPref.ZONE_LOC_HUMAN_EXILE;
|
||||
|
||||
@@ -100,7 +100,7 @@ public class InputProxy implements Observer {
|
||||
public final void selectPlayer(final PlayerView playerView, final ITriggerEvent triggerEvent) {
|
||||
final Input inp = getInput();
|
||||
if (inp != null) {
|
||||
final Player player = Player.get(playerView);
|
||||
final Player player = controller.getGame().getPlayer(playerView);
|
||||
if (player != null) {
|
||||
inp.selectPlayer(player, triggerEvent);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ import java.util.concurrent.BlockingDeque;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
|
||||
import forge.game.Game;
|
||||
import forge.game.player.Player;
|
||||
import forge.match.MatchUtil;
|
||||
import forge.player.PlayerControllerHuman;
|
||||
|
||||
@@ -37,9 +36,11 @@ import forge.player.PlayerControllerHuman;
|
||||
public class InputQueue extends Observable {
|
||||
private final BlockingDeque<InputSynchronized> inputStack = new LinkedBlockingDeque<InputSynchronized>();
|
||||
private final InputLockUI inputLock;
|
||||
private final Game game;
|
||||
|
||||
public InputQueue(final Game game, final InputProxy inputProxy) {
|
||||
inputLock = new InputLockUI(game, this);
|
||||
this.game = game;
|
||||
addObserver(inputProxy);
|
||||
}
|
||||
|
||||
@@ -76,7 +77,7 @@ public class InputQueue extends Observable {
|
||||
|
||||
public void setInput(final InputSynchronized input) {
|
||||
if (MatchUtil.getHumanCount() > 1) { //update current player if needed
|
||||
MatchUtil.setCurrentPlayer(Player.get(input.getOwner()));
|
||||
MatchUtil.setCurrentPlayer(game.getPlayer(input.getOwner()));
|
||||
}
|
||||
inputStack.push(input);
|
||||
InputBase.waitForOtherPlayer();
|
||||
|
||||
@@ -297,7 +297,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
if (nNeeded == 0) {
|
||||
return PaymentDecision.number(0);
|
||||
}
|
||||
final Player p = Player.get(SGuiChoose.oneOrNone(String.format("Exile from whose %s?", cost.getFrom()), PlayerView.getCollection(payableZone)));
|
||||
final Player p = controller.getGame().getPlayer(SGuiChoose.oneOrNone(String.format("Exile from whose %s?", cost.getFrom()), PlayerView.getCollection(payableZone)));
|
||||
if (p == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -489,7 +489,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append(source.getName()).append(" - Choose an opponent to gain ").append(c).append(" life:");
|
||||
|
||||
final Player chosenToGain = Player.get(SGuiChoose.oneOrNone(sb.toString(), PlayerView.getCollection(oppsThatCanGainLife)));
|
||||
final Player chosenToGain = controller.getGame().getPlayer(SGuiChoose.oneOrNone(sb.toString(), PlayerView.getCollection(oppsThatCanGainLife)));
|
||||
if (chosenToGain == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -614,7 +614,7 @@ public class HumanCostDecision extends CostDecisionMakerBase {
|
||||
return PaymentDecision.number(0);
|
||||
}
|
||||
|
||||
final Player p = Player.get(SGuiChoose.oneOrNone(String.format("Put cards from whose %s?", fromZone), PlayerView.getCollection(payableZone)));
|
||||
final Player p = controller.getGame().getPlayer(SGuiChoose.oneOrNone(String.format("Put cards from whose %s?", fromZone), PlayerView.getCollection(payableZone)));
|
||||
if (p == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -524,7 +524,7 @@ public class HumanPlay {
|
||||
payableZone.add(player);
|
||||
}
|
||||
}
|
||||
Player chosen = Player.get(SGuiChoose.oneOrNone(String.format("Put cards from whose %s?", from), PlayerView.getCollection(payableZone)));
|
||||
Player chosen = controller.getGame().getPlayer(SGuiChoose.oneOrNone(String.format("Put cards from whose %s?", from), PlayerView.getCollection(payableZone)));
|
||||
if (chosen == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -418,7 +418,13 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
|
||||
final GameEntityView result = GuiBase.getInterface().chooseSingleEntityForEffect(title, optionList, delayedReveal, isOptional, this);
|
||||
endTempShowCards(); //assume tempShow called by GuiBase.getInterface().chooseSingleEntityForEffect
|
||||
return (T) GameEntity.get(result);
|
||||
if (result instanceof CardView) {
|
||||
return (T) Card.get((CardView)result);
|
||||
}
|
||||
if (result instanceof PlayerView) {
|
||||
return (T) game.getPlayer((PlayerView)result);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1539,7 +1545,7 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
}
|
||||
|
||||
public void setPlayerLife() {
|
||||
final Player player = Player.get(SGuiChoose.oneOrNone("Set life for which player?", PlayerView.getCollection(game.getPlayers())));
|
||||
final Player player = game.getPlayer(SGuiChoose.oneOrNone("Set life for which player?", PlayerView.getCollection(game.getPlayers())));
|
||||
if (player == null) { return; }
|
||||
|
||||
final Integer life = SGuiChoose.getInteger("Set life to what?", 0);
|
||||
@@ -1569,7 +1575,7 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
}
|
||||
|
||||
public void addCardToHand() {
|
||||
final Player p = Player.get(SGuiChoose.oneOrNone("Put card in hand for which player?", PlayerView.getCollection(game.getPlayers())));
|
||||
final Player p = game.getPlayer(SGuiChoose.oneOrNone("Put card in hand for which player?", PlayerView.getCollection(game.getPlayers())));
|
||||
if (p == null) {
|
||||
return;
|
||||
}
|
||||
@@ -1589,7 +1595,7 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
}
|
||||
|
||||
public void addCardToBattlefield() {
|
||||
final Player p = Player.get(SGuiChoose.oneOrNone("Put card in play for which player?", PlayerView.getCollection(game.getPlayers())));
|
||||
final Player p = game.getPlayer(SGuiChoose.oneOrNone("Put card in play for which player?", PlayerView.getCollection(game.getPlayers())));
|
||||
if (p == null) {
|
||||
return;
|
||||
}
|
||||
@@ -1637,7 +1643,7 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
}
|
||||
|
||||
public void riggedPlanarRoll() {
|
||||
final Player player = Player.get(SGuiChoose.oneOrNone("Which player should roll?", PlayerView.getCollection(game.getPlayers())));
|
||||
final Player player = game.getPlayer(SGuiChoose.oneOrNone("Which player should roll?", PlayerView.getCollection(game.getPlayers())));
|
||||
if (player == null) { return; }
|
||||
|
||||
final PlanarDice res = SGuiChoose.oneOrNone("Choose result", PlanarDice.values());
|
||||
|
||||
@@ -63,7 +63,7 @@ public class QuestWinLoseController {
|
||||
final LobbyPlayer questLobbyPlayer = GamePlayerUtil.getQuestPlayer();
|
||||
PlayerView player = null;
|
||||
for (final PlayerView p : lastGame.getPlayers()) {
|
||||
if (p.getLobbyPlayer().equals(questLobbyPlayer)) {
|
||||
if (p.isLobbyPlayer(questLobbyPlayer)) {
|
||||
player = p;
|
||||
}
|
||||
}
|
||||
@@ -97,7 +97,7 @@ public class QuestWinLoseController {
|
||||
if (anteResult.lostCards != null) {
|
||||
qc.getCards().loseCards(anteResult.lostCards);
|
||||
}
|
||||
anteReport(anteResult.wonCards, anteResult.lostCards, questPlayer.getLobbyPlayer().equals(lastGame.getWinningPlayer()));
|
||||
anteReport(anteResult.wonCards, anteResult.lostCards, questPlayer.isLobbyPlayer(lastGame.getWinningPlayer()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user