mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 19:28:01 +00:00
Make LocalGameView a bit faster, plus some minor refactoring.
This commit is contained in:
@@ -326,25 +326,26 @@ public class GuiDesktop implements IGuiBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SpellAbilityView getAbilityToPlay(List<SpellAbilityView> abilities, ITriggerEvent triggerEvent) {
|
public int getAbilityToPlay(List<SpellAbilityView> abilities, ITriggerEvent triggerEvent) {
|
||||||
if (triggerEvent == null) {
|
if (triggerEvent == null) {
|
||||||
if (abilities.isEmpty()) {
|
if (abilities.isEmpty()) {
|
||||||
return null;
|
return -1;
|
||||||
}
|
}
|
||||||
if (abilities.size() == 1) {
|
if (abilities.size() == 1) {
|
||||||
return abilities.get(0);
|
return abilities.get(0).getId();
|
||||||
}
|
}
|
||||||
return GuiChoose.oneOrNone("Choose ability to play", abilities);
|
final SpellAbilityView choice = GuiChoose.oneOrNone("Choose ability to play", abilities);
|
||||||
|
return choice == null ? -1 : choice.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (abilities.isEmpty()) {
|
if (abilities.isEmpty()) {
|
||||||
return null;
|
return -1;
|
||||||
}
|
}
|
||||||
if (abilities.size() == 1 && !abilities.get(0).isPromptIfOnlyPossibleAbility()) {
|
if (abilities.size() == 1 && !abilities.get(0).isPromptIfOnlyPossibleAbility()) {
|
||||||
if (abilities.get(0).canPlay()) {
|
if (abilities.get(0).canPlay()) {
|
||||||
return abilities.get(0); //only return ability if it's playable, otherwise return null
|
return abilities.get(0).getId(); //only return ability if it's playable, otherwise return null
|
||||||
}
|
}
|
||||||
return null;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//show menu if mouse was trigger for ability
|
//show menu if mouse was trigger for ability
|
||||||
@@ -383,7 +384,7 @@ public class GuiDesktop implements IGuiBase {
|
|||||||
menu.show(mouseEvent.getComponent(), mouseEvent.getX(), mouseEvent.getY());
|
menu.show(mouseEvent.getComponent(), mouseEvent.getX(), mouseEvent.getY());
|
||||||
}
|
}
|
||||||
|
|
||||||
return null; //delay ability until choice made
|
return -1; //delay ability until choice made
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -314,14 +314,15 @@ public class GuiMobile implements IGuiBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SpellAbilityView getAbilityToPlay(List<SpellAbilityView> abilities, ITriggerEvent triggerEvent) {
|
public int getAbilityToPlay(List<SpellAbilityView> abilities, ITriggerEvent triggerEvent) {
|
||||||
if (abilities.isEmpty()) {
|
if (abilities.isEmpty()) {
|
||||||
return null;
|
return -1;
|
||||||
}
|
}
|
||||||
if (abilities.size() == 1) {
|
if (abilities.size() == 1) {
|
||||||
return abilities.get(0);
|
return abilities.get(0).getId();
|
||||||
}
|
}
|
||||||
return SGuiChoose.oneOrNone(this, "Choose ability to play", abilities);
|
final SpellAbilityView choice = SGuiChoose.oneOrNone(this, "Choose ability to play", abilities);
|
||||||
|
return choice == null ? -1 : choice.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ public interface IGuiBase {
|
|||||||
void setPanelSelection(CardView hostCard);
|
void setPanelSelection(CardView hostCard);
|
||||||
Map<CardView, Integer> getDamageToAssign(CardView attacker, List<CardView> blockers,
|
Map<CardView, Integer> getDamageToAssign(CardView attacker, List<CardView> blockers,
|
||||||
int damageDealt, GameEntityView defender, boolean overrideOrder);
|
int damageDealt, GameEntityView defender, boolean overrideOrder);
|
||||||
SpellAbilityView getAbilityToPlay(List<SpellAbilityView> abilities, ITriggerEvent triggerEvent);
|
int getAbilityToPlay(List<SpellAbilityView> abilities, ITriggerEvent triggerEvent);
|
||||||
void hear(LobbyPlayer player, String message);
|
void hear(LobbyPlayer player, String message);
|
||||||
int getAvatarCount();
|
int getAvatarCount();
|
||||||
void copyToClipboard(String text);
|
void copyToClipboard(String text);
|
||||||
|
|||||||
@@ -176,7 +176,7 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
* Uses GUI to learn which spell the player (human in our case) would like to play
|
* Uses GUI to learn which spell the player (human in our case) would like to play
|
||||||
*/
|
*/
|
||||||
public SpellAbility getAbilityToPlay(final List<SpellAbility> abilities, final ITriggerEvent triggerEvent) {
|
public SpellAbility getAbilityToPlay(final List<SpellAbility> abilities, final ITriggerEvent triggerEvent) {
|
||||||
final SpellAbilityView choice = getGui().getAbilityToPlay(gameView.getSpellAbilityViews(abilities), triggerEvent);
|
final int choice = getGui().getAbilityToPlay(gameView.getSpellAbilityViews(abilities), triggerEvent);
|
||||||
return gameView.getSpellAbility(choice);
|
return gameView.getSpellAbility(choice);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ public class Cache<K extends IIdentifiable, V extends IIdentifiable> {
|
|||||||
* @return a value equal to value, if such a value is present in the Cache;
|
* @return a value equal to value, if such a value is present in the Cache;
|
||||||
* {@code null} otherwise.
|
* {@code null} otherwise.
|
||||||
*/
|
*/
|
||||||
public synchronized V getValue(final V value) {
|
public synchronized V getCurrentValue(final V value) {
|
||||||
for (final V currentValue : cache.values()) {
|
for (final V currentValue : cache.values()) {
|
||||||
if (currentValue.equals(value)) {
|
if (currentValue.equals(value)) {
|
||||||
return currentValue;
|
return currentValue;
|
||||||
@@ -106,16 +106,42 @@ public class Cache<K extends IIdentifiable, V extends IIdentifiable> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
final int valueId = value.getId();
|
final int keyId = key.getId(), valueId = value.getId();
|
||||||
|
|
||||||
|
// remove value mapping if it exists already
|
||||||
if (inverseCache.containsKey(valueId)) {
|
if (inverseCache.containsKey(valueId)) {
|
||||||
cache.remove(inverseCache.get(valueId).getId());
|
cache.values().remove(value);
|
||||||
inverseCache.remove(valueId);
|
inverseCache.remove(valueId);
|
||||||
}
|
}
|
||||||
|
|
||||||
final V oldValue = cache.put(key.getId(), value);
|
// remove key mapping if it exists already
|
||||||
if (oldValue != null) {
|
if (cache.containsKey(keyId)) {
|
||||||
inverseCache.remove(oldValue.getId());
|
inverseCache.values().remove(key);
|
||||||
|
cache.remove(keyId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// put the new values
|
||||||
|
cache.put(keyId, value);
|
||||||
|
inverseCache.put(valueId, key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the key of a particular entry. If the supplied key is {@code null}
|
||||||
|
* or if the Cache didn't already contain a mapping for the supplied id,
|
||||||
|
* this method silently returns.
|
||||||
|
*
|
||||||
|
* @param valueId
|
||||||
|
* the id of the value to which the key is associated.
|
||||||
|
* @param key
|
||||||
|
* the new key.
|
||||||
|
*/
|
||||||
|
public void updateKey(final int valueId, final K key) {
|
||||||
|
if (key == null || !inverseCache.containsKey(valueId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (this) {
|
||||||
inverseCache.put(valueId, key);
|
inverseCache.put(valueId, key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package forge.view;
|
package forge.view;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -12,8 +11,6 @@ import com.google.common.collect.ImmutableList;
|
|||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Iterators;
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
|
|
||||||
import forge.ImageKeys;
|
import forge.ImageKeys;
|
||||||
import forge.card.CardEdition;
|
import forge.card.CardEdition;
|
||||||
@@ -34,19 +31,7 @@ import forge.game.zone.ZoneType;
|
|||||||
*/
|
*/
|
||||||
public class CardView extends GameEntityView {
|
public class CardView extends GameEntityView {
|
||||||
|
|
||||||
private static final List<Integer> randomInts = Lists.newArrayListWithCapacity(1024);
|
public static final CardView EMPTY = new CardView(true);
|
||||||
static {
|
|
||||||
for (int i = 1; i < 1025; i++) {
|
|
||||||
randomInts.add(Integer.valueOf(i));
|
|
||||||
}
|
|
||||||
Collections.shuffle(randomInts);
|
|
||||||
}
|
|
||||||
private static final Iterator<Integer> randomIntsIterator = Iterators.cycle(randomInts);
|
|
||||||
private static int nextRandomInt() {
|
|
||||||
synchronized (randomIntsIterator) {
|
|
||||||
return randomIntsIterator.next().intValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final CardStateView
|
private final CardStateView
|
||||||
original = new CardStateView(),
|
original = new CardStateView(),
|
||||||
@@ -90,7 +75,7 @@ public class CardView extends GameEntityView {
|
|||||||
|
|
||||||
public void reset() {
|
public void reset() {
|
||||||
final Iterable<CardView> emptyIterable = ImmutableSet.of();
|
final Iterable<CardView> emptyIterable = ImmutableSet.of();
|
||||||
this.id = -nextRandomInt();
|
this.id = 0;
|
||||||
this.hasAltState = false;
|
this.hasAltState = false;
|
||||||
this.owner = null;
|
this.owner = null;
|
||||||
this.controller = null;
|
this.controller = null;
|
||||||
@@ -100,15 +85,15 @@ public class CardView extends GameEntityView {
|
|||||||
this.isFlipped = false;
|
this.isFlipped = false;
|
||||||
this.isSplitCard = false;
|
this.isSplitCard = false;
|
||||||
this.isTransformed = false;
|
this.isTransformed = false;
|
||||||
this.setCode = StringUtils.EMPTY;
|
this.setCode = "";
|
||||||
this.rarity = CardRarity.Unknown;
|
this.rarity = CardRarity.Unknown;
|
||||||
this.isAttacking = this.isBlocking = this.isPhasedOut = this.isSick = this.isTapped = false;
|
this.isAttacking = this.isBlocking = this.isPhasedOut = this.isSick = this.isTapped = false;
|
||||||
this.counters = ImmutableMap.of();
|
this.counters = ImmutableMap.of();
|
||||||
this.damage = this.assignedDamage = this.regenerationShields = this.preventNextDamage = 0;
|
this.damage = this.assignedDamage = this.regenerationShields = this.preventNextDamage = 0;
|
||||||
this.chosenType = StringUtils.EMPTY;
|
this.chosenType = "";
|
||||||
this.chosenColors = ImmutableList.of();
|
this.chosenColors = ImmutableList.of();
|
||||||
this.chosenPlayer = null;
|
this.chosenPlayer = null;
|
||||||
this.namedCard = StringUtils.EMPTY;
|
this.namedCard = "";
|
||||||
this.equipping = null;
|
this.equipping = null;
|
||||||
this.equippedBy = emptyIterable;
|
this.equippedBy = emptyIterable;
|
||||||
this.enchantingCard = null;
|
this.enchantingCard = null;
|
||||||
@@ -139,17 +124,6 @@ public class CardView extends GameEntityView {
|
|||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(final Object obj) {
|
|
||||||
return obj instanceof CardView && this.getId() == ((CardView) obj).getId()
|
|
||||||
&& (this.getId() > 0 || this == obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return id > 0 ? id : super.hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isUiDisplayable() {
|
public boolean isUiDisplayable() {
|
||||||
return isUiDisplayable;
|
return isUiDisplayable;
|
||||||
}
|
}
|
||||||
@@ -773,7 +747,7 @@ public class CardView extends GameEntityView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void reset() {
|
public void reset() {
|
||||||
this.name = StringUtils.EMPTY;
|
this.name = "";
|
||||||
this.colors = ColorSet.getNullColor();
|
this.colors = ColorSet.getNullColor();
|
||||||
this.imageKey = ImageKeys.TOKEN_PREFIX + ImageKeys.MORPH_IMAGE;
|
this.imageKey = ImageKeys.TOKEN_PREFIX + ImageKeys.MORPH_IMAGE;
|
||||||
this.type = Collections.emptyList();
|
this.type = Collections.emptyList();
|
||||||
@@ -781,7 +755,7 @@ public class CardView extends GameEntityView {
|
|||||||
this.power = 0;
|
this.power = 0;
|
||||||
this.toughness = 0;
|
this.toughness = 0;
|
||||||
this.loyalty = 0;
|
this.loyalty = 0;
|
||||||
this.text = StringUtils.EMPTY;
|
this.text = "";
|
||||||
this.changedColorWords = ImmutableMap.of();
|
this.changedColorWords = ImmutableMap.of();
|
||||||
this.changedTypes = ImmutableMap.of();
|
this.changedTypes = ImmutableMap.of();
|
||||||
this.hasDeathtouch = false;
|
this.hasDeathtouch = false;
|
||||||
@@ -957,7 +931,6 @@ public class CardView extends GameEntityView {
|
|||||||
this.changedTypes = Collections.unmodifiableMap(changedTypes);
|
this.changedTypes = Collections.unmodifiableMap(changedTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the hasDeathtouch
|
* @return the hasDeathtouch
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -424,23 +424,30 @@ public abstract class LocalGameView implements IGameView {
|
|||||||
final boolean mayShow = mayShowCard(c);
|
final boolean mayShow = mayShowCard(c);
|
||||||
|
|
||||||
CardView view = cards.get(c.getId());
|
CardView view = cards.get(c.getId());
|
||||||
|
final boolean isNewView;
|
||||||
if (view != null) {
|
if (view != null) {
|
||||||
// Put here again to ensure the Card reference in the cache
|
// Update to ensure the Card reference in the cache
|
||||||
// is not an outdated Card.
|
// is not an outdated Card.
|
||||||
cards.put(c, view);
|
if (view.getId() > 0) {
|
||||||
}
|
cards.updateKey(view.getId(), c);
|
||||||
else {
|
|
||||||
view = new CardView(isDisplayable);
|
|
||||||
if (isDisplayable && mayShow) {
|
|
||||||
cards.put(c, view);
|
|
||||||
}
|
}
|
||||||
|
isNewView = false;
|
||||||
|
} else if (isDisplayable && mayShow) {
|
||||||
|
view = new CardView(isDisplayable);
|
||||||
|
view.setId(c.getId());
|
||||||
|
cards.put(c, view);
|
||||||
|
isNewView = true;
|
||||||
|
} else {
|
||||||
|
return CardView.EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mayShow) {
|
if (mayShow) {
|
||||||
writeCardToView(cUi, view);
|
writeCardToView(cUi, view);
|
||||||
}
|
}
|
||||||
else if (isDisplayable) {
|
else if (isDisplayable) {
|
||||||
view.reset();
|
if (!isNewView) {
|
||||||
|
view.reset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return null;
|
return null;
|
||||||
@@ -464,7 +471,7 @@ public abstract class LocalGameView implements IGameView {
|
|||||||
return ViewUtil.transformIfNotNull(cardViews, new Function<CardView, CardView>() {
|
return ViewUtil.transformIfNotNull(cardViews, new Function<CardView, CardView>() {
|
||||||
@Override
|
@Override
|
||||||
public CardView apply(final CardView input) {
|
public CardView apply(final CardView input) {
|
||||||
return cards.getValue(input);
|
return cards.getCurrentValue(input);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -478,8 +485,7 @@ public abstract class LocalGameView implements IGameView {
|
|||||||
if (mayShowCard(c)) {
|
if (mayShowCard(c)) {
|
||||||
return view;
|
return view;
|
||||||
} else if (view.isUiDisplayable()) {
|
} else if (view.isUiDisplayable()) {
|
||||||
view.reset();
|
return CardView.EMPTY;
|
||||||
return view;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -569,11 +575,14 @@ public abstract class LocalGameView implements IGameView {
|
|||||||
return ViewUtil.transformIfNotNull(cards, FN_GET_SPAB_VIEW);
|
return ViewUtil.transformIfNotNull(cards, FN_GET_SPAB_VIEW);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SpellAbility getSpellAbility(final SpellAbilityView c) {
|
public SpellAbility getSpellAbility(final SpellAbilityView spabView) {
|
||||||
if (c == null) {
|
if (spabView == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return spabs.getKey(c.getId());
|
return getSpellAbility(spabView.getId());
|
||||||
|
}
|
||||||
|
public SpellAbility getSpellAbility(final int id) {
|
||||||
|
return id >= 0 ? spabs.getKey(id) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Function<SpellAbilityView, SpellAbility> FN_GET_SPAB = new Function<SpellAbilityView, SpellAbility>() {
|
private final Function<SpellAbilityView, SpellAbility> FN_GET_SPAB = new Function<SpellAbilityView, SpellAbility>() {
|
||||||
|
|||||||
Reference in New Issue
Block a user