mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 20:58:03 +00:00
Use caching for CombatView (plus some random NPE and concurrency fixes).
This commit is contained in:
@@ -28,6 +28,7 @@ import forge.game.event.GameEventCardDamaged;
|
||||
import forge.game.event.GameEventCardPhased;
|
||||
import forge.game.event.GameEventCardStatsChanged;
|
||||
import forge.game.event.GameEventCardTapped;
|
||||
import forge.game.event.GameEventCombatChanged;
|
||||
import forge.game.event.GameEventCombatEnded;
|
||||
import forge.game.event.GameEventGameFinished;
|
||||
import forge.game.event.GameEventGameOutcome;
|
||||
@@ -97,8 +98,13 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
private final AtomicBoolean combatUpdPlanned = new AtomicBoolean(false);
|
||||
@Override
|
||||
public Void visit(GameEventPlayerPriority event) {
|
||||
if (!isMainHandler || combatUpdPlanned.getAndSet(true)) { return null; }
|
||||
updateCombat();
|
||||
return null;
|
||||
}
|
||||
|
||||
public void updateCombat() {
|
||||
if (!isMainHandler || combatUpdPlanned.getAndSet(true)) { return; }
|
||||
|
||||
FThreads.invokeInEdtNowOrLater(gameView.getGui(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -106,7 +112,6 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
MatchUtil.getController().showCombat(gameView.getCombat());
|
||||
}
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
private final AtomicBoolean turnUpdPlanned = new AtomicBoolean(false);
|
||||
@@ -352,9 +357,19 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
return super.visit(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventCombatChanged event) {
|
||||
gameView.refreshCombat();
|
||||
updateCombat();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(GameEventCombatEnded event) {
|
||||
if (!isMainHandler) { return null; }
|
||||
|
||||
gameView.refreshCombat();
|
||||
updateCombat();
|
||||
|
||||
// This should remove sword/shield icons from combatants by the time game moves to M2
|
||||
updateManyCards(gameView.getCardViews(event.attackers));
|
||||
|
||||
@@ -60,6 +60,7 @@ import forge.util.NameGenerator;
|
||||
import forge.util.gui.SOptionPane;
|
||||
import forge.view.Cache;
|
||||
import forge.view.CardView;
|
||||
import forge.view.CombatView;
|
||||
import forge.view.GameEntityView;
|
||||
import forge.view.LocalGameView;
|
||||
import forge.view.PlayerView;
|
||||
@@ -80,6 +81,8 @@ public class MatchUtil {
|
||||
public static final Cache<SpellAbility, SpellAbilityView> spabs = new Cache<>();
|
||||
/** Cache of stack items. */
|
||||
public static final Cache<SpellAbilityStackInstance, StackItemView> stackItems = new Cache<>();
|
||||
/** Cache of combat. */
|
||||
public static CombatView cachedCombatView = null;
|
||||
|
||||
private static int humanCount;
|
||||
private static final EventBus uiEvents;
|
||||
|
||||
@@ -313,6 +313,6 @@ public class InputAttack extends InputSyncronizedBase {
|
||||
showMessage(message);
|
||||
|
||||
updatePrompt();
|
||||
MatchUtil.getController().showCombat(getController().getCombat(combat)); // redraw sword icons
|
||||
MatchUtil.getController().showCombat(getController().getCombat()); // redraw sword icons
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import forge.game.card.CardLists;
|
||||
import forge.game.card.CardPredicates.Presets;
|
||||
import forge.game.combat.Combat;
|
||||
import forge.game.combat.CombatUtil;
|
||||
import forge.game.event.GameEventCombatChanged;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.match.MatchUtil;
|
||||
@@ -86,7 +87,7 @@ public class InputBlock extends InputSyncronizedBase {
|
||||
showMessage(message);
|
||||
}
|
||||
|
||||
MatchUtil.getController().showCombat(getController().getCombat(combat));
|
||||
MatchUtil.getController().showCombat(getController().getCombat());
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@@ -147,7 +148,9 @@ public class InputBlock extends InputSyncronizedBase {
|
||||
}
|
||||
}
|
||||
|
||||
if (!isCorrectAction) {
|
||||
if (isCorrectAction) {
|
||||
card.getGame().fireEvent(new GameEventCombatChanged());
|
||||
} else {
|
||||
flashIncorrectAction();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1080,11 +1080,11 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
*/
|
||||
@Override
|
||||
public List<AbilitySub> chooseModeForAbility(SpellAbility sa, int min, int num) {
|
||||
List<AbilitySub> choices = CharmEffect.makePossibleOptions(sa);
|
||||
List<SpellAbilityView> choices = getSpellAbilityViews(CharmEffect.makePossibleOptions(sa));
|
||||
String modeTitle = String.format("%s activated %s - Choose a mode", sa.getActivatingPlayer(), sa.getHostCard());
|
||||
List<AbilitySub> chosen = new ArrayList<AbilitySub>();
|
||||
List<AbilitySub> chosen = Lists.newArrayListWithCapacity(num);
|
||||
for (int i = 0; i < num; i++) {
|
||||
AbilitySub a;
|
||||
SpellAbilityView a;
|
||||
if (i < min) {
|
||||
a = SGuiChoose.one(getGui(), modeTitle, choices);
|
||||
}
|
||||
@@ -1096,7 +1096,7 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
}
|
||||
|
||||
choices.remove(a);
|
||||
chosen.add(a);
|
||||
chosen.add((AbilitySub) getSpellAbility(a));
|
||||
}
|
||||
return chosen;
|
||||
}
|
||||
@@ -1556,8 +1556,8 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
* @return
|
||||
* @see forge.view.LocalGameView#getCombat(forge.game.combat.Combat)
|
||||
*/
|
||||
public CombatView getCombat(Combat c) {
|
||||
return gameView.getCombat(c);
|
||||
public CombatView getCombat() {
|
||||
return gameView.getCombat();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1663,8 +1663,8 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
* @see forge.view.LocalGameView#getSpellAbilityViews(java.util.List)
|
||||
*/
|
||||
public final List<SpellAbilityView> getSpellAbilityViews(
|
||||
List<SpellAbility> cards) {
|
||||
return gameView.getSpellAbilityViews(cards);
|
||||
final List<? extends SpellAbility> spabs) {
|
||||
return gameView.getSpellAbilityViews(spabs);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -186,30 +186,39 @@ public abstract class LocalGameView implements IGameView {
|
||||
|
||||
@Override
|
||||
public CombatView getCombat() {
|
||||
return getCombat(game.getCombat());
|
||||
synchronized (MatchUtil.class) {
|
||||
if (MatchUtil.cachedCombatView != null) {
|
||||
return MatchUtil.cachedCombatView;
|
||||
}
|
||||
|
||||
final Combat combat = game.getCombat();
|
||||
final CombatView combatView;
|
||||
if (combat == null) {
|
||||
combatView = null;
|
||||
} else {
|
||||
combatView = new CombatView();
|
||||
for (final AttackingBand b : combat.getAttackingBands()) {
|
||||
if (b == null) continue;
|
||||
final GameEntity defender = combat.getDefenderByAttacker(b);
|
||||
final List<Card> blockers = combat.getBlockers(b);
|
||||
final boolean isBlocked = b.isBlocked() == Boolean.TRUE;
|
||||
combatView.addAttackingBand(
|
||||
getCardViews(b.getAttackers()),
|
||||
getGameEntityView(defender),
|
||||
blockers == null || !isBlocked ? null : getCardViews(blockers),
|
||||
blockers == null ? null : getCardViews(blockers));
|
||||
}
|
||||
}
|
||||
MatchUtil.cachedCombatView = combatView;
|
||||
return combatView;
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.view.IGameView#getCombat()
|
||||
*/
|
||||
public CombatView getCombat(final Combat combat) {
|
||||
if (combat == null) {
|
||||
return null;
|
||||
public final void refreshCombat() {
|
||||
synchronized (MatchUtil.class) {
|
||||
MatchUtil.cachedCombatView = null;
|
||||
this.getCombat();
|
||||
}
|
||||
|
||||
final CombatView combatView = new CombatView();
|
||||
for (final AttackingBand b : combat.getAttackingBands()) {
|
||||
if (b == null) continue;
|
||||
final GameEntity defender = combat.getDefenderByAttacker(b);
|
||||
final List<Card> blockers = combat.getBlockers(b);
|
||||
final boolean isBlocked = b.isBlocked() == Boolean.TRUE;
|
||||
combatView.addAttackingBand(
|
||||
getCardViews(b.getAttackers()),
|
||||
getGameEntityView(defender),
|
||||
blockers == null || !isBlocked ? null : getCardViews(blockers),
|
||||
blockers == null ? null : getCardViews(blockers));
|
||||
}
|
||||
return combatView;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -559,7 +568,7 @@ public abstract class LocalGameView implements IGameView {
|
||||
}
|
||||
};
|
||||
|
||||
public final List<SpellAbilityView> getSpellAbilityViews(final List<SpellAbility> cards) {
|
||||
public final List<SpellAbilityView> getSpellAbilityViews(final List<? extends SpellAbility> cards) {
|
||||
return ViewUtil.transformIfNotNull(cards, FN_GET_SPAB_VIEW);
|
||||
}
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ public final class ViewUtil {
|
||||
return view;
|
||||
}
|
||||
|
||||
public static <T,V> List<V> transformIfNotNull(final Iterable<T> input, final Function<T, V> transformation) {
|
||||
public static <T,V> List<V> transformIfNotNull(final Iterable<? extends T> input, final Function<T, V> transformation) {
|
||||
final List<V> ret = Lists.newLinkedList();
|
||||
synchronized (input) {
|
||||
for (final T t : input) {
|
||||
|
||||
Reference in New Issue
Block a user