Start refactoring to make Human v. Human support better

This commit is contained in:
drdev
2014-09-23 11:22:36 +00:00
parent edf8c58754
commit 6a5cd5f39f
28 changed files with 434 additions and 503 deletions

View File

@@ -22,12 +22,10 @@ import java.util.Observer;
import java.util.concurrent.atomic.AtomicReference;
import forge.FThreads;
import forge.game.Game;
import forge.interfaces.IGuiBase;
import forge.player.PlayerControllerHuman;
import forge.util.ITriggerEvent;
import forge.util.gui.SOptionPane;
import forge.view.CardView;
import forge.view.LocalGameView;
import forge.view.PlayerView;
import forge.view.SpellAbilityView;
@@ -43,48 +41,21 @@ public class InputProxy implements Observer {
/** The input. */
private AtomicReference<Input> input = new AtomicReference<Input>();
private final Game game;
private final LocalGameView gameView;
// private static final boolean DEBUG_INPUT = true; // false;
private final PlayerControllerHuman controller;
public InputProxy(final PlayerControllerHuman controller, final Game game) {
this.controller = controller;
this.game = game;
public InputProxy(final LocalGameView gameView0) {
this.gameView = gameView0;
}
private IGuiBase getGui() {
return this.controller.getGui();
}
public boolean passPriority() {
return passPriority(false);
}
public boolean passPriorityUntilEndOfTurn() {
return passPriority(true);
}
private boolean passPriority(final boolean passUntilEndOfTurn) {
final Input inp = getInput();
if (inp instanceof InputPassPriority) {
if (passUntilEndOfTurn) {
controller.autoPassUntilEndOfTurn();
}
inp.selectButtonOK();
return true;
}
FThreads.invokeInEdtNowOrLater(getGui(), new Runnable() {
@Override
public void run() {
SOptionPane.showMessageDialog(getGui(), "Cannot pass priority at this time.");
}
});
return false;
return this.gameView.getGui();
}
@Override
public final void update(final Observable observable, final Object obj) {
final Input nextInput = getGui().getInputQueue().getActualInput(game);
final Input nextInput = gameView.getInputQueue().getActualInput(gameView);
/* if(DEBUG_INPUT)
System.out.printf("%s ... \t%s on %s, \tstack = %s%n",
FThreads.debugGetStackTraceItem(6, true), nextInput == null ? "null" : nextInput.getClass().getSimpleName(),
@@ -137,7 +108,7 @@ public class InputProxy implements Observer {
public final void selectPlayer(final PlayerView player, final ITriggerEvent triggerEvent) {
final Input inp = getInput();
if (inp != null) {
inp.selectPlayer(controller.getPlayer(player), triggerEvent);
inp.selectPlayer(gameView.getPlayer(player), triggerEvent);
}
}
@@ -153,7 +124,7 @@ public class InputProxy implements Observer {
public final boolean selectCard(final CardView cardView, final ITriggerEvent triggerEvent) {
final Input inp = getInput();
if (inp != null) {
return inp.selectCard(controller.getCard(cardView), triggerEvent);
return inp.selectCard(gameView.getCard(cardView), triggerEvent);
}
return false;
}
@@ -161,7 +132,7 @@ public class InputProxy implements Observer {
public final void selectAbility(final SpellAbilityView ab) {
final Input inp = getInput();
if (inp != null) {
inp.selectAbility(controller.getSpellAbility(ab));
inp.selectAbility(gameView.getSpellAbility(ab));
}
}
@@ -180,7 +151,7 @@ public class InputProxy implements Observer {
}
/** @return {@link forge.gui.InputProxy.InputBase} */
private Input getInput() {
public Input getInput() {
return this.input.get();
}
}

View File

@@ -22,8 +22,7 @@ import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;
import forge.game.Game;
import forge.game.player.Player;
import forge.player.PlayerControllerHuman;
import forge.view.IGameView;
/**
* <p>
@@ -37,22 +36,18 @@ public class InputQueue extends Observable {
private final BlockingDeque<InputSynchronized> inputStack = new LinkedBlockingDeque<InputSynchronized>();
private final InputLockUI inputLock;
public InputQueue(final Game game) {
public InputQueue(final Game game, final InputProxy inputProxy) {
inputLock = new InputLockUI(game, this);
for (final Player p : game.getPlayers()) {
if (p.getController() instanceof PlayerControllerHuman) {
this.addObserver(((PlayerControllerHuman) p.getController()).getInputProxy());
}
}
addObserver(inputProxy);
}
public final void updateObservers() {
this.setChanged();
this.notifyObservers();
setChanged();
notifyObservers();
}
public final Input getInput() {
return inputStack.isEmpty() ? null : this.inputStack.peek();
return inputStack.isEmpty() ? null : inputStack.peek();
}
public final void removeInput(Input inp) {
@@ -71,9 +66,9 @@ public class InputQueue extends Observable {
*
* @return a {@link forge.gui.input.InputBase} object.
*/
public final Input getActualInput(final Game game) {
public final Input getActualInput(final IGameView gameView) {
Input topMost = inputStack.peek(); // incoming input to Control
if (topMost != null && !game.isGameOver()) {
if (topMost != null && !gameView.isGameOver()) {
return topMost;
}
return inputLock;
@@ -85,10 +80,10 @@ public class InputQueue extends Observable {
}
public void setInput(final InputSynchronized input) {
this.inputStack.push(input);
inputStack.push(input);
inputLock.setGui(input.getGui());
syncPoint();
this.updateObservers();
updateObservers();
}
public void syncPoint() {

View File

@@ -29,7 +29,6 @@ public abstract class InputSyncronizedBase extends InputBase implements InputSyn
cdlDone.countDown();
}
public void showAndWait() {
getGui().getInputQueue().setInput(this);
awaitLatchRelease();

View File

@@ -31,6 +31,7 @@ import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import forge.FThreads;
import forge.LobbyPlayer;
import forge.achievement.AchievementCollection;
import forge.card.CardCharacteristicName;
@@ -118,9 +119,6 @@ import forge.view.StackItemView;
* Handles phase skips for now.
*/
public class PlayerControllerHuman extends PlayerController {
private IGuiBase gui;
private final InputProxy inputProxy;
private final GameView gameView;
/**
* Cards this player may look at right now, for example when searching a
@@ -131,9 +129,7 @@ public class PlayerControllerHuman extends PlayerController {
public PlayerControllerHuman(final Game game0, final Player p, final LobbyPlayer lp, final IGuiBase gui) {
super(game0, p, lp);
this.gui = gui;
this.inputProxy = new InputProxy(this, game0);
this.gameView = new GameView(game0);
this.gameView = new GameView(game0, gui);
// aggressively cache a view for each player (also caches cards)
for (final Player player : game.getRegisteredPlayers()) {
@@ -142,11 +138,11 @@ public class PlayerControllerHuman extends PlayerController {
}
public IGuiBase getGui() {
return gui;
return gameView.getGui();
}
public InputProxy getInputProxy() {
return inputProxy;
return gameView.getInputProxy();
}
public LocalGameView getGameView() {
@@ -1334,8 +1330,8 @@ public class PlayerControllerHuman extends PlayerController {
* What follows are the View methods.
*/
private class GameView extends LocalGameView {
public GameView(Game game) {
super(game);
public GameView(Game game0, IGuiBase gui0) {
super(game0, gui0);
}
@Override
@@ -1395,12 +1391,29 @@ public class PlayerControllerHuman extends PlayerController {
@Override
public boolean passPriority() {
return getInputProxy().passPriority();
return passPriority(false);
}
@Override
public boolean passPriorityUntilEndOfTurn() {
return getInputProxy().passPriorityUntilEndOfTurn();
return passPriority(true);
}
private boolean passPriority(final boolean passUntilEndOfTurn) {
final Input inp = gameView.getInputProxy().getInput();
if (inp instanceof InputPassPriority) {
if (passUntilEndOfTurn) {
autoPassUntilEndOfTurn();
}
inp.selectButtonOK();
return true;
}
FThreads.invokeInEdtNowOrLater(getGui(), new Runnable() {
@Override
public void run() {
SOptionPane.showMessageDialog(getGui(), "Cannot pass priority at this time.");
}
});
return false;
}
@Override
@@ -1472,11 +1485,11 @@ public class PlayerControllerHuman extends PlayerController {
@Override
public boolean getDisableAutoYields() {
return this.getGame().getDisableAutoYields();
return game.getDisableAutoYields();
}
@Override
public void setDisableAutoYields(final boolean b) {
this.getGame().setDisableAutoYields(b);
game.setDisableAutoYields(b);
}
@Override

View File

@@ -27,16 +27,37 @@ import forge.game.player.RegisteredPlayer;
import forge.game.spellability.SpellAbility;
import forge.game.spellability.SpellAbilityStackInstance;
import forge.game.zone.ZoneType;
import forge.interfaces.IGuiBase;
import forge.match.input.InputProxy;
import forge.match.input.InputQueue;
public abstract class LocalGameView implements IGameView {
protected final Game game;
protected final IGuiBase gui;
protected final InputQueue inputQueue;
protected final InputProxy inputProxy;
private final Game game;
public LocalGameView(final Game game) {
this.game = game;
public LocalGameView(Game game0, IGuiBase gui0) {
game = game0;
gui = gui0;
inputProxy = new InputProxy(this);
inputQueue = new InputQueue(game, inputProxy);
}
protected final Game getGame() {
return this.game;
public final Game getGame() {
return game;
}
public final IGuiBase getGui() {
return gui;
}
public final InputQueue getInputQueue() {
return inputQueue;
}
public InputProxy getInputProxy() {
return inputProxy;
}
/** Cache of players. */
@@ -60,17 +81,17 @@ public abstract class LocalGameView implements IGameView {
*/
@Override
public GameType getGameType() {
return this.game.getMatch().getRules().getGameType();
return game.getMatch().getRules().getGameType();
}
@Override
public int getTurnNumber() {
return this.game.getPhaseHandler().getTurn();
return game.getPhaseHandler().getTurn();
}
@Override
public boolean isCommandZoneNeeded() {
return this.game.getMatch().getRules().getGameType().isCommandZoneNeeded();
return game.getMatch().getRules().getGameType().isCommandZoneNeeded();
}
@Override
@@ -93,37 +114,37 @@ public abstract class LocalGameView implements IGameView {
*/
@Override
public boolean isFirstGameInMatch() {
return this.game.getMatch().getPlayedGames().isEmpty();
return game.getMatch().getPlayedGames().isEmpty();
}
@Override
public boolean isMatchOver() {
return this.game.getMatch().isMatchOver();
return game.getMatch().isMatchOver();
}
@Override
public int getNumGamesInMatch() {
return this.game.getMatch().getRules().getGamesPerMatch();
return game.getMatch().getRules().getGamesPerMatch();
}
@Override
public int getNumPlayedGamesInMatch() {
return this.game.getMatch().getPlayedGames().size();
return game.getMatch().getPlayedGames().size();
}
@Override
public Iterable<GameOutcome> getOutcomesOfMatch() {
return Iterables.unmodifiableIterable(this.game.getMatch().getPlayedGames());
return Iterables.unmodifiableIterable(game.getMatch().getPlayedGames());
}
@Override
public boolean isMatchWonBy(final LobbyPlayer p) {
return this.game.getMatch().isWonBy(p);
return game.getMatch().isWonBy(p);
}
@Override
public int getGamesWonBy(final LobbyPlayer p) {
return this.game.getMatch().getGamesWonBy(p);
return game.getMatch().getGamesWonBy(p);
}
@Override
@@ -133,7 +154,7 @@ public abstract class LocalGameView implements IGameView {
@Override
public Deck getDeck(final LobbyPlayer player) {
for (final RegisteredPlayer rp : this.game.getMatch().getPlayers()) {
for (final RegisteredPlayer rp : game.getMatch().getPlayers()) {
if (rp.getPlayer().equals(player)) {
return rp.getDeck();
}

View File

@@ -5,6 +5,7 @@ package forge.view;
import forge.game.Game;
import forge.game.card.Card;
import forge.interfaces.IGuiBase;
import forge.match.input.Input;
import forge.match.input.InputPlaybackControl;
import forge.match.input.InputQueue;
@@ -16,9 +17,6 @@ import forge.util.ITriggerEvent;
*
*/
public class WatchLocalGame extends LocalGameView {
private final InputQueue inputQueue;
/**
* @param game
* the @{link Game} to attach to.
@@ -26,9 +24,8 @@ public class WatchLocalGame extends LocalGameView {
* the {@link InputQueue} of the game to enable playback
* controls, or {@code null} to disallow them.
*/
public WatchLocalGame(final Game game, final InputQueue inputQueue) {
super(game);
this.inputQueue = inputQueue;
public WatchLocalGame(Game game0, IGuiBase gui0) {
super(game0, gui0);
}
@Override