diff --git a/.gitattributes b/.gitattributes index 77356b87260..11dcd9c0a80 100644 --- a/.gitattributes +++ b/.gitattributes @@ -261,12 +261,15 @@ forge-core/src/main/java/forge/util/Settable.java -text forge-core/src/main/java/forge/util/TextUtil.java -text forge-core/src/main/java/forge/util/ThreadUtil.java -text forge-core/src/main/java/forge/util/Visitor.java -text +forge-core/src/main/java/forge/util/collect/FCollection.java -text +forge-core/src/main/java/forge/util/collect/FCollectionView.java -text forge-core/src/main/java/forge/util/maps/EnumMapOfLists.java -text forge-core/src/main/java/forge/util/maps/EnumMapToAmount.java -text forge-core/src/main/java/forge/util/maps/HashMapOfLists.java -text forge-core/src/main/java/forge/util/maps/LinkedHashMapToAmount.java -text forge-core/src/main/java/forge/util/maps/MapOfLists.java -text forge-core/src/main/java/forge/util/maps/MapToAmount.java -text +forge-core/src/main/java/forge/util/maps/MapToAmountUtil.java -text forge-core/src/main/java/forge/util/maps/package-info.java -text forge-core/src/main/java/forge/util/storage/IStorage.java -text forge-core/src/main/java/forge/util/storage/StorageBase.java -text @@ -724,9 +727,6 @@ forge-game/src/main/java/forge/trackable/TrackableSerializer.java -text forge-game/src/main/java/forge/trackable/TrackableTypes.java -text forge-game/src/main/java/forge/trackable/Tracker.java -text forge-game/src/main/java/forge/util/Expressions.java -text -forge-game/src/main/java/forge/util/FCollection.java -text -forge-game/src/main/java/forge/util/FCollectionView.java -text -forge-game/src/main/java/forge/util/MapToAmountUtil.java -text forge-game/src/main/java/forge/util/MessageUtil.java -text forge-game/src/test/java/forge/game/mana/ManaCostBeingPaidTest.java -text forge-gui-android/.classpath -text diff --git a/forge-ai/src/main/java/forge/ai/AiAttackController.java b/forge-ai/src/main/java/forge/ai/AiAttackController.java index 7a9c1a3a0ea..420ebe8194c 100644 --- a/forge-ai/src/main/java/forge/ai/AiAttackController.java +++ b/forge-ai/src/main/java/forge/ai/AiAttackController.java @@ -40,7 +40,7 @@ import forge.game.spellability.SpellAbility; import forge.game.trigger.Trigger; import forge.game.trigger.TriggerType; import forge.game.zone.ZoneType; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; import forge.util.MyRandom; diff --git a/forge-ai/src/main/java/forge/ai/AiBlockController.java b/forge-ai/src/main/java/forge/ai/AiBlockController.java index 362397a5b72..ce145f84d56 100644 --- a/forge-ai/src/main/java/forge/ai/AiBlockController.java +++ b/forge-ai/src/main/java/forge/ai/AiBlockController.java @@ -21,15 +21,24 @@ import com.google.common.base.Predicate; import com.google.common.base.Predicates; import forge.game.CardTraitBase; import forge.game.GameEntity; -import forge.game.card.*; +import forge.game.card.Card; +import forge.game.card.CardCollection; +import forge.game.card.CardCollectionView; +import forge.game.card.CardLists; +import forge.game.card.CardPredicates; +import forge.game.card.CounterType; import forge.game.combat.Combat; import forge.game.combat.CombatUtil; import forge.game.player.Player; import forge.game.trigger.Trigger; import forge.game.trigger.TriggerType; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Map; /** diff --git a/forge-ai/src/main/java/forge/ai/AiController.java b/forge-ai/src/main/java/forge/ai/AiController.java index c3a2b305a7b..f5120fbcf80 100644 --- a/forge-ai/src/main/java/forge/ai/AiController.java +++ b/forge-ai/src/main/java/forge/ai/AiController.java @@ -87,7 +87,7 @@ import forge.game.zone.ZoneType; import forge.item.PaperCard; import forge.util.Aggregates; import forge.util.Expressions; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; import forge.util.MyRandom; /** diff --git a/forge-ai/src/main/java/forge/ai/AiCostDecision.java b/forge-ai/src/main/java/forge/ai/AiCostDecision.java index 45fce391952..7a53821bc35 100644 --- a/forge-ai/src/main/java/forge/ai/AiCostDecision.java +++ b/forge-ai/src/main/java/forge/ai/AiCostDecision.java @@ -17,7 +17,7 @@ import forge.game.player.Player; import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbilityStackInstance; import forge.game.zone.ZoneType; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; import java.util.ArrayList; import java.util.Collections; diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtil.java b/forge-ai/src/main/java/forge/ai/ComputerUtil.java index aa6e7047a2a..f264dc1dee1 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtil.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtil.java @@ -70,7 +70,7 @@ import forge.game.trigger.TriggerType; import forge.game.zone.Zone; import forge.game.zone.ZoneType; import forge.util.Aggregates; -import forge.util.FCollection; +import forge.util.collect.FCollection; import forge.util.MyRandom; diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java b/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java index 024fca889e8..3fb4eaca236 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilCombat.java @@ -19,7 +19,7 @@ package forge.ai; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; - + import forge.game.CardTraitBase; import forge.game.Game; import forge.game.GameEntity; @@ -44,7 +44,7 @@ import forge.game.trigger.Trigger; import forge.game.trigger.TriggerHandler; import forge.game.trigger.TriggerType; import forge.game.zone.ZoneType; -import forge.util.FCollection; +import forge.util.collect.FCollection; import java.util.ArrayList; import java.util.HashMap; diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilCost.java b/forge-ai/src/main/java/forge/ai/ComputerUtilCost.java index 28ccf4d63dc..0328cdf97b6 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilCost.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilCost.java @@ -1,6 +1,5 @@ package forge.ai; -import forge.ai.AiAttackController; import forge.game.ability.AbilityUtils; import forge.game.card.Card; import forge.game.card.CardCollection; @@ -12,7 +11,7 @@ import forge.game.player.Player; import forge.game.spellability.Spell; import forge.game.spellability.SpellAbility; import forge.game.zone.ZoneType; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; import forge.util.MyRandom; import forge.util.TextUtil; diff --git a/forge-ai/src/main/java/forge/ai/GameState.java b/forge-ai/src/main/java/forge/ai/GameState.java index 3c8d1192f12..de1d6fd2d46 100644 --- a/forge-ai/src/main/java/forge/ai/GameState.java +++ b/forge-ai/src/main/java/forge/ai/GameState.java @@ -22,7 +22,7 @@ import forge.game.player.Player; import forge.game.trigger.TriggerType; import forge.game.zone.ZoneType; import forge.item.IPaperCard; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; public abstract class GameState { private static final Map ZONES = new HashMap(); diff --git a/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java b/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java index 06666787442..e95654d0360 100644 --- a/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java +++ b/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java @@ -44,8 +44,8 @@ import forge.game.trigger.WrappedAbility; import forge.game.zone.ZoneType; import forge.item.PaperCard; import forge.util.Aggregates; -import forge.util.FCollection; -import forge.util.FCollectionView; +import forge.util.collect.FCollection; +import forge.util.collect.FCollectionView; import forge.util.ITriggerEvent; import forge.util.MyRandom; diff --git a/forge-ai/src/main/java/forge/ai/ability/AnimateAi.java b/forge-ai/src/main/java/forge/ai/ability/AnimateAi.java index c5fb2a492ca..3cd6dd78736 100644 --- a/forge-ai/src/main/java/forge/ai/ability/AnimateAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/AnimateAi.java @@ -30,7 +30,7 @@ import forge.game.staticability.StaticAbilityLayer; import forge.game.trigger.Trigger; import forge.game.trigger.TriggerHandler; import forge.game.zone.ZoneType; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; import java.util.ArrayList; import java.util.Arrays; diff --git a/forge-ai/src/main/java/forge/ai/ability/ChooseGenericEffectAi.java b/forge-ai/src/main/java/forge/ai/ability/ChooseGenericEffectAi.java index f2ce94bd6a4..cbd6734705a 100644 --- a/forge-ai/src/main/java/forge/ai/ability/ChooseGenericEffectAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/ChooseGenericEffectAi.java @@ -6,7 +6,7 @@ import forge.game.cost.Cost; import forge.game.player.Player; import forge.game.spellability.SpellAbility; import forge.util.Aggregates; -import forge.util.FCollection; +import forge.util.collect.FCollection; import java.util.List; diff --git a/forge-ai/src/main/java/forge/ai/ability/LifeLoseAi.java b/forge-ai/src/main/java/forge/ai/ability/LifeLoseAi.java index 201445ca0fb..1e3a96422b8 100644 --- a/forge-ai/src/main/java/forge/ai/ability/LifeLoseAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/LifeLoseAi.java @@ -11,7 +11,7 @@ import forge.game.phase.PhaseType; import forge.game.player.Player; import forge.game.spellability.SpellAbility; import forge.game.spellability.TargetRestrictions; -import forge.util.FCollection; +import forge.util.collect.FCollection; import java.util.List; diff --git a/forge-ai/src/main/java/forge/ai/ability/TwoPilesAi.java b/forge-ai/src/main/java/forge/ai/ability/TwoPilesAi.java index d5ab17c9ae1..a1328865354 100644 --- a/forge-ai/src/main/java/forge/ai/ability/TwoPilesAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/TwoPilesAi.java @@ -11,7 +11,7 @@ import forge.game.player.Player; import forge.game.spellability.SpellAbility; import forge.game.spellability.TargetRestrictions; import forge.game.zone.ZoneType; -import forge.util.FCollection; +import forge.util.collect.FCollection; public class TwoPilesAi extends SpellAbilityAi { @Override diff --git a/forge-core/src/main/java/forge/util/collect/FCollection.java b/forge-core/src/main/java/forge/util/collect/FCollection.java new file mode 100644 index 00000000000..e96765e5ed5 --- /dev/null +++ b/forge-core/src/main/java/forge/util/collect/FCollection.java @@ -0,0 +1,624 @@ +package forge.util.collect; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import com.google.common.collect.Ordering; +import com.google.common.collect.Sets; +import org.apache.commons.lang3.ArrayUtils; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; +import java.util.NoSuchElementException; +import java.util.Set; + +/** + * Collection with unique elements ({@link Set}) that maintains the order in + * which the elements are added to it ({@link List}). + * + * This object is serializable if all elements it contains are. + * + * @param the type of the elements this collection contains. + * @see FCollectionView + */ +public class FCollection implements List, Set, FCollectionView, Cloneable, Serializable { + private static final long serialVersionUID = -1664555336364294106L; + + private static final FCollection EMPTY = new EmptyFCollection(); + + @SuppressWarnings("unchecked") + public static FCollection getEmpty() { + return (FCollection) EMPTY; + } + + /** + * The {@link Set} representation of this collection. + */ + private final Set set = Sets.newHashSet(); + + /** + * The {@link List} representation of this collection. + */ + private final LinkedList list = Lists.newLinkedList(); + + /** + * Create an empty {@link FCollection}. + */ + public FCollection() { + } + + /** + * Create an {@link FCollection} containing a single element. + * + * @param e + * the single element the new collection contains. + */ + public FCollection(final T e) { + add(e); + } + + /** + * Create an {@link FCollection} from an array. The order of the elements in + * the array is preserved in the new collection. + * + * @param c + * an array, whose elements will be in the collection upon its + * creation. + */ + public FCollection(final T[] c) { + for (final T e : c) { + add(e); + } + } + + /** + * Create an {@link FCollection} from an {@link Iterable}. The order of the + * elements in the iterable is preserved in the new collection. + * + * @param i + * an iterable, whose elements will be in the collection upon its + * creation. + */ + public FCollection(final Iterable i) { + for (final T e : i) { + add(e); + } + } + + /** + * Check whether an {@link Iterable} contains any iterable, silently + * returning {@code false} when {@code null} is passed as an argument. + * + * @param iterable + * a card collection. + */ + public static boolean hasElements(final Iterable iterable) { + return iterable != null && !Iterables.isEmpty(iterable); + } + + /** + * Check whether a {@link Collection} contains a particular element, silently + * returning {@code false} when {@code null} is passed as the first argument. + * + * @param collection + * a collection. + * @param element + * a possible element of the collection. + */ + public static boolean hasElement(final Collection collection, final T element) { + return collection != null && collection.contains(element); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(final Object obj) { + return obj instanceof FCollection && hashCode() == obj.hashCode(); + } + + /** + *

This implementation uses the hash code of the backing list.

+ * + * {@inheritDoc} + */ + @Override + public int hashCode() { + return list.hashCode(); + } + + /** + * Return a string representation of this {@link FCollection}, by + * concatenating the elements, in order, using a comma {@code ,}, and + * wrapping it in brackets {@code [ ]}. + */ + @Override + public String toString() { + return list.toString(); + } + + /** + * Create a new {@link FCollection} containing the same objects as this + * instance, in the same order. Note that objects are shallowly copied. + */ + @Override + public final FCollection clone() { + return new FCollection<>(list); + } + + /** + * Get the first object in this {@link FCollection}. + * + * @throws NoSuchElementException + * if the collection is empty. + */ + @Override + public T getFirst() { + return list.getFirst(); + } + + /** + * Get the last object in this {@link FCollection}. + * + * @throws NoSuchElementException + * if the collection is empty. + */ + @Override + public T getLast() { + return list.getLast(); + } + + /** + * Get the number of elements in this collection. + */ + @Override + public int size() { + return set.size(); + } + + /** + * Check whether this collection is empty. + */ + @Override + public boolean isEmpty() { + return set.isEmpty(); + } + + /** + * Check whether this collection contains a particular object. + * + * @param o + * an object. + */ + @Override + public boolean contains(final Object o) { + return set.contains(o); + } + + /** + * {@inheritDoc} + */ + @Override + public Iterator iterator() { + return list.iterator(); + } + + /** + * {@inheritDoc} + */ + @Override + public Object[] toArray() { + return list.toArray(); + } + + /** + * {@inheritDoc} + */ + @Override + public T[] toArray(final T[] a) { + return list.toArray(a); + } + + /** + * Add an element to this collection, if it isn't already present. + * + * @param e + * the object to add. + * @return whether the collection changed as a result of this method call. + */ + @Override + public boolean add(final T e) { + if (set.add(e)) { + list.add(e); + return true; + } + return false; + } + + /** + * Remove an element from this collection. + * + * @param o + * the object to remove. + * @return whether the collection changed as a result of this method call. + */ + @Override + public boolean remove(final Object o) { + if (set.remove(o)) { + list.remove(o); + return true; + } + return false; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean containsAll(final Collection c) { + return set.containsAll(c); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean addAll(final Collection c) { + return addAll((Iterable) c); + } + + /** + * Add all the elements in the specified {@link Iterator} to this + * collection, in the order in which they appear. + * + * @param i + * an iterator. + * @return whether this collection changed as a result of this method call. + * @see #addAll(Collection) + */ + public boolean addAll(final Iterable i) { + boolean changed = false; + for (final T e : i) { + changed |= add(e); + } + return changed; + } + + /** + * Add all the elements in the specified array to this collection, + * respecting the ordering. + * + * @param c + * an array. + * @return whether this collection changed as a result of this method call. + */ + public boolean addAll(final T[] c) { + boolean changed = false; + for (final T e : c) { + changed |= add(e); + } + return changed; + } + + /** + * {@inheritDoc} + */ + @SuppressWarnings("unchecked") + @Override + public boolean addAll(final int index, final Collection c) { + if (c == null) { + return false; + } + + final List list; + if (c instanceof List) { + list = (List) c; + } else { + list = Lists.newArrayList(c); + } + + boolean changed = false; + for (int i = list.size() - 1; i >= 0; i--) { //must add in reverse order so they show up in the right place + changed |= insert(index, list.get(i)); + } + return changed; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean removeAll(final Collection c) { + return removeAll((Iterable) c); + } + + /** + * Remove all objects appearing in an {@link Iterable}. + * + * @param c + * an iterable. + * @return whether this collection changed as a result of this method call. + */ + public boolean removeAll(final Iterable c) { + boolean changed = false; + for (final Object o : c) { + changed |= remove(o); + } + return changed; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean retainAll(final Collection c) { + if (set.retainAll(c)) { + list.retainAll(c); + return true; + } + return false; + } + + /** + * {@inheritDoc} + */ + @Override + public void clear() { + if (set.isEmpty()) { return; } + set.clear(); + list.clear(); + } + + /** + * {@inheritDoc} + */ + @Override + public T get(final int index) { + return list.get(index); + } + + /** + * Set the element at an index to a value. WARNING: this method doesn't + * update the set and should only be used in a situation where the set of + * elements in this collection is invariant. + */ + @Override + public T set(final int index, final T element) { //assume this isn't called except when changing list order, so don't worry about updating set + return list.set(index, element); + } + + /** + * {@inheritDoc} + */ + @Override + public void add(final int index, final T element) { + insert(index, element); + } + + /** + * Helper method to insert an element at a particular index. + * + * @param index + * the index to insert the element at. + * @param element + * the element to insert. + * @return whether this collection changed as a result of this method call. + */ + private boolean insert(int index, final T element) { + if (set.add(element)) { + list.add(index, element); + return true; + } + //re-position in list if needed + final int oldIndex = list.indexOf(element); + if (index == oldIndex) { + return false; + } + + if (index > oldIndex) { + index--; //account for being removed + } + list.remove(oldIndex); + list.add(index, element); + return true; + } + + /** + * {@inheritDoc} + */ + @Override + public T remove(final int index) { + final T removedItem = list.remove(index); + if (removedItem != null) { + set.remove(removedItem); + } + return removedItem; + } + + /** + * {@inheritDoc} + */ + @Override + public int indexOf(final Object o) { + return list.indexOf(o); + } + + /** + * {@inheritDoc} + */ + @Override + public int lastIndexOf(final Object o) { + return list.lastIndexOf(o); + } + + /** + * {@inheritDoc} + */ + @Override + public ListIterator listIterator() { + return list.listIterator(); + } + + /** + * {@inheritDoc} + */ + @Override + public ListIterator listIterator(final int index) { + return list.listIterator(index); + } + + /** + *

+ * Note This method breaks the contract of {@link List#subList(int, int)} + * by returning a static collection, rather than a view, of the sublist. + *

+ * + * {@inheritDoc} + */ + @Override + public List subList(final int fromIndex, final int toIndex) { + return ImmutableList.copyOf(list.subList(fromIndex, toIndex)); + } + + /** + * Sort this collection on the string representations of the resepctive + * elements. + * + * @see Object#toString() + * @see #sort(Comparator) + * @see Ordering#usingToString() + */ + public void sort() { + sort(Ordering.usingToString()); + } + + /** + * {@inheritDoc} + */ + public void sort(final Comparator comparator) { + Collections.sort(list, comparator); + } + + /** + * {@inheritDoc} + */ + @Override + public Iterable threadSafeIterable() { + //create a new linked list for iterating to make it thread safe and avoid concurrent modification exceptions + return Iterables.unmodifiableIterable(new LinkedList(list)); + } + + /** + * An unmodifiable, empty {@link FCollection}. Overrides all methods with + * default implementations suitable for an empty collection, to improve + * performance. + */ + public static class EmptyFCollection extends FCollection { + private static final long serialVersionUID = 8667965158891635997L; + public EmptyFCollection() { + super(); + } + @Override public final void add(final int index, final T element) { + } + @Override public final boolean add(final T e) { + return false; + } + @Override public final boolean addAll(final Collection c) { + return false; + } + @Override public final boolean addAll(final int index, final Collection c) { + return false; + } + @Override public final boolean addAll(final Iterable i) { + return false; + } + @Override public final boolean addAll(final T[] c) { + return false; + } + @Override public final void clear() { + } + @Override public final boolean contains(final Object o) { + return false; + } + @Override public final boolean containsAll(final Collection c) { + return c.isEmpty(); + } + @Override public final T get(final int index) { + throw new IndexOutOfBoundsException("Any index is out of bounds for an empty collection"); + } + @Override public final T getFirst() { + throw new NoSuchElementException("Collection is empty"); + } + @Override public final T getLast() { + throw new NoSuchElementException("Collection is empty"); + } + @Override public final int indexOf(final Object o) { + return -1; + } + @Override public final boolean isEmpty() { + return true; + } + @Override public final Iterator iterator() { + return Collections.emptyIterator(); + } + @Override public final int lastIndexOf(final Object o) { + return -1; + } + @Override public final ListIterator listIterator() { + return Collections.emptyListIterator(); + } + @Override public final ListIterator listIterator(final int index) { + return Collections.emptyListIterator(); + } + @Override public final T remove(final int index) { + throw new IndexOutOfBoundsException("Any index is out of bounds for an empty collection"); + } + @Override public final boolean remove(final Object o) { + return false; + } + @Override public boolean removeAll(final Collection c) { + return false; + } + @Override public final boolean removeAll(final Iterable c) { + return false; + } + @Override public final boolean retainAll(final Collection c) { + return false; + } + @Override public final T set(final int index, final T element) { + throw new IndexOutOfBoundsException("Any index is out of bounds for an empty collection"); + } + @Override public final int size() { + return 0; + } + @Override public final void sort() { + } + @Override public final void sort(final Comparator comparator) { + } + @Override public final List subList(final int fromIndex, final int toIndex) { + if (fromIndex == 0 && toIndex == 0) { + return this; + } + throw new IndexOutOfBoundsException("Any index is out of bounds for an empty collection"); + } + @Override public final Iterable threadSafeIterable() { + return this; + } + @Override public final Object[] toArray() { return ArrayUtils.EMPTY_OBJECT_ARRAY; } + @Override public final T[] toArray(final T[] a) { + if (a.length > 0) { + a[0] = null; + } + return a; + } + @Override public final String toString() { + return "[]"; + } + } +} diff --git a/forge-core/src/main/java/forge/util/collect/FCollectionView.java b/forge-core/src/main/java/forge/util/collect/FCollectionView.java new file mode 100644 index 00000000000..ee218fcc7b2 --- /dev/null +++ b/forge-core/src/main/java/forge/util/collect/FCollectionView.java @@ -0,0 +1,77 @@ +package forge.util.collect; + +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; + +/** + * Read-only interface to an {@link FCollection}. + */ +public interface FCollectionView extends Iterable { + /** + * @see Collection#isEmpty() + */ + boolean isEmpty(); + + /** + * @see Collection#size() + */ + int size(); + + /** + * @see List#get(int) + */ + T get(int index); + + /** + * Get the first object in this {@link FCollectionView}. + * + * @throws NoSuchElementException + * if the collection is empty. + */ + T getFirst(); + + /** + * Get the last object in this {@link FCollectionView}. + * + * @throws NoSuchElementException + * if the collection is empty. + */ + T getLast(); + + /** + * @see List#indexOf(Object) + */ + int indexOf(Object o); + + /** + * @see List#lastIndexOf(Object) + */ + int lastIndexOf(Object o); + + /** + * @see Collection#contains(Object) + */ + boolean contains(Object o); + + /** + * Return an unmodifiable list with shallow copies of the elements in a + * particular range of this collection. + * + * @param fromIndex + * the first index to appear in the list. + * @param toIndex + * the lowest index not to appear in the list. + * @return a sublist. + */ + List subList(int fromIndex, int toIndex); + + /** + * Get a thread-safe {@link Iterable}, ie. one that is not backed by this + * collection, but rather represents the state at the time this method is + * called. The iterator is read-only (does not support + * {@link Iterator#remove()}), as such an operation would have no meaning. + */ + Iterable threadSafeIterable(); +} \ No newline at end of file diff --git a/forge-game/src/main/java/forge/util/MapToAmountUtil.java b/forge-core/src/main/java/forge/util/maps/MapToAmountUtil.java similarity index 94% rename from forge-game/src/main/java/forge/util/MapToAmountUtil.java rename to forge-core/src/main/java/forge/util/maps/MapToAmountUtil.java index d6d34ec2d9e..83f0ce31c15 100755 --- a/forge-game/src/main/java/forge/util/MapToAmountUtil.java +++ b/forge-core/src/main/java/forge/util/maps/MapToAmountUtil.java @@ -1,4 +1,9 @@ -package forge.util; +package forge.util.maps; + +import com.google.common.collect.Lists; +import forge.util.collect.FCollection; +import forge.util.collect.FCollectionView; +import org.apache.commons.lang3.tuple.Pair; import java.util.Collections; import java.util.Comparator; @@ -6,13 +11,6 @@ import java.util.List; import java.util.Map.Entry; import java.util.NoSuchElementException; -import org.apache.commons.lang3.tuple.Pair; - -import com.google.common.collect.Lists; - -import forge.util.maps.LinkedHashMapToAmount; -import forge.util.maps.MapToAmount; - public final class MapToAmountUtil { diff --git a/forge-game/src/main/java/forge/game/Game.java b/forge-game/src/main/java/forge/game/Game.java index 0c38e30763a..9900c757922 100644 --- a/forge-game/src/main/java/forge/game/Game.java +++ b/forge-game/src/main/java/forge/game/Game.java @@ -68,8 +68,8 @@ import forge.game.zone.Zone; import forge.game.zone.ZoneType; import forge.trackable.Tracker; import forge.util.Aggregates; -import forge.util.FCollection; -import forge.util.FCollectionView; +import forge.util.collect.FCollection; +import forge.util.collect.FCollectionView; import forge.util.Visitor; /** diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index cb9f9ce3375..31ed0f89e98 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -22,7 +22,6 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; - import forge.GameCommand; import forge.card.CardStateName; import forge.card.CardType; @@ -30,8 +29,23 @@ import forge.game.ability.AbilityFactory; import forge.game.ability.AbilityUtils; import forge.game.ability.ApiType; import forge.game.ability.effects.AttachEffect; -import forge.game.card.*; -import forge.game.event.*; +import forge.game.card.Card; +import forge.game.card.CardCollection; +import forge.game.card.CardCollectionView; +import forge.game.card.CardFactory; +import forge.game.card.CardFactoryUtil; +import forge.game.card.CardLists; +import forge.game.card.CardPredicates; +import forge.game.card.CardUtil; +import forge.game.card.CounterType; +import forge.game.event.GameEventCardChangeZone; +import forge.game.event.GameEventCardDestroyed; +import forge.game.event.GameEventCardRegenerated; +import forge.game.event.GameEventCardSacrificed; +import forge.game.event.GameEventCardStatsChanged; +import forge.game.event.GameEventCardTapped; +import forge.game.event.GameEventFlipCoin; +import forge.game.event.GameEventGameStarted; import forge.game.player.GameLossReason; import forge.game.player.Player; import forge.game.replacement.ReplacementEffect; @@ -51,15 +65,25 @@ import forge.item.PaperCard; import forge.util.Aggregates; import forge.util.CollectionSuppliers; import forge.util.Expressions; -import forge.util.FCollection; -import forge.util.FCollectionView; +import forge.util.collect.FCollection; +import forge.util.collect.FCollectionView; import forge.util.ThreadUtil; import forge.util.Visitor; import forge.util.maps.HashMapOfLists; import forge.util.maps.MapOfLists; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; import java.util.Map.Entry; +import java.util.Set; /** * Methods for common actions performed during a game. @@ -643,7 +667,7 @@ public class GameAction { } for (Player p : game.getPlayers()) { - for (Card c : p.getCardsIn(ZoneType.Battlefield).threadSafeIterator()) { + for (Card c : p.getCardsIn(ZoneType.Battlefield).threadSafeIterable()) { if (!c.getController().equals(p)) { controllerChangeZoneCorrection(c); affectedCards.add(c); @@ -699,13 +723,13 @@ public class GameAction { checkStaticAbilities(false, affectedCards); boolean checkAgain = false; - for (Player p : game.getPlayers()) { - for (ZoneType zt : ZoneType.values()) { + for (final Player p : game.getPlayers()) { + for (final ZoneType zt : ZoneType.values()) { if (zt == ZoneType.Battlefield) { continue; } - Iterable cards = p.getCardsIn(zt).threadSafeIterator(); - for (Card c : cards) { + final Iterable cards = p.getCardsIn(zt).threadSafeIterable(); + for (final Card c : cards) { // If a token is in a zone other than the battlefield, it ceases to exist. checkAgain |= stateBasedAction704_5d(c); } diff --git a/forge-game/src/main/java/forge/game/GameEntity.java b/forge-game/src/main/java/forge/game/GameEntity.java index c192b03bcb0..d1d8054c0ff 100644 --- a/forge-game/src/main/java/forge/game/GameEntity.java +++ b/forge-game/src/main/java/forge/game/GameEntity.java @@ -22,6 +22,7 @@ import forge.game.card.CardCollection; import forge.game.card.CardCollectionView; import forge.game.event.GameEventCardAttachment; import forge.game.event.GameEventCardAttachment.AttachMethod; +import forge.util.collect.FCollection; import java.util.Map; import java.util.TreeMap; @@ -154,10 +155,10 @@ public abstract class GameEntity extends GameObject implements IIdentifiable { getView().updateEnchantedBy(this); } public final boolean isEnchanted() { - return CardCollection.hasCard(enchantedBy); + return FCollection.hasElements(enchantedBy); } public final boolean isEnchantedBy(Card c) { - return CardCollection.hasCard(enchantedBy, c); + return FCollection.hasElement(enchantedBy, c); } public final boolean isEnchantedBy(final String cardName) { for (final Card aura : getEnchantedBy(false)) { diff --git a/forge-game/src/main/java/forge/game/GameView.java b/forge-game/src/main/java/forge/game/GameView.java index 09b02c67596..679483df891 100644 --- a/forge-game/src/main/java/forge/game/GameView.java +++ b/forge-game/src/main/java/forge/game/GameView.java @@ -21,7 +21,7 @@ import forge.game.zone.MagicStack; import forge.trackable.TrackableCollection; import forge.trackable.TrackableObject; import forge.trackable.TrackableProperty; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; public class GameView extends TrackableObject { private static final long serialVersionUID = 8522884512960961528L; diff --git a/forge-game/src/main/java/forge/game/Match.java b/forge-game/src/main/java/forge/game/Match.java index d230cd24471..6aaf443b3e1 100644 --- a/forge-game/src/main/java/forge/game/Match.java +++ b/forge-game/src/main/java/forge/game/Match.java @@ -31,7 +31,7 @@ import forge.game.trigger.Trigger; import forge.game.zone.PlayerZone; import forge.game.zone.ZoneType; import forge.item.PaperCard; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; import forge.util.MyRandom; public class Match { diff --git a/forge-game/src/main/java/forge/game/StaticEffect.java b/forge-game/src/main/java/forge/game/StaticEffect.java index 45bee41134c..22096367eb8 100644 --- a/forge-game/src/main/java/forge/game/StaticEffect.java +++ b/forge-game/src/main/java/forge/game/StaticEffect.java @@ -1003,7 +1003,7 @@ public class StaticEffect { // remove abilities if (params.containsKey("AddAbility") || params.containsKey("GainsAbilitiesOf")) { - for (final SpellAbility s : affectedCard.getSpellAbilities().threadSafeIterator()) { + for (final SpellAbility s : affectedCard.getSpellAbilities().threadSafeIterable()) { if (s.isTemporary()) { affectedCard.removeSpellAbility(s); } diff --git a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java index 80c5ce61625..22a7d46977f 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java @@ -20,8 +20,8 @@ import forge.game.spellability.SpellAbilityRestriction; import forge.game.spellability.SpellAbilityStackInstance; import forge.game.zone.ZoneType; import forge.util.Expressions; -import forge.util.FCollection; -import forge.util.FCollectionView; +import forge.util.collect.FCollection; +import forge.util.collect.FCollectionView; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.text.WordUtils; diff --git a/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java b/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java index 0a0da694da1..f6a0a73f41b 100644 --- a/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java +++ b/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java @@ -15,7 +15,7 @@ import forge.game.card.CardFactoryUtil; import forge.game.player.Player; import forge.game.spellability.AbilitySub; import forge.game.spellability.SpellAbility; -import forge.util.FCollection; +import forge.util.collect.FCollection; /** *

diff --git a/forge-game/src/main/java/forge/game/ability/effects/ActivateAbilityEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ActivateAbilityEffect.java index ea390ec32ec..ee50a2773d7 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ActivateAbilityEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ActivateAbilityEffect.java @@ -7,7 +7,7 @@ import forge.game.player.Player; import forge.game.spellability.SpellAbility; import forge.game.spellability.TargetRestrictions; import forge.game.zone.ZoneType; -import forge.util.FCollection; +import forge.util.collect.FCollection; import forge.util.Lang; import org.apache.commons.lang3.StringUtils; diff --git a/forge-game/src/main/java/forge/game/ability/effects/AnimateAllEffect.java b/forge-game/src/main/java/forge/game/ability/effects/AnimateAllEffect.java index 1fb307fc76a..9328bf6625f 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/AnimateAllEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/AnimateAllEffect.java @@ -18,7 +18,7 @@ import forge.game.staticability.StaticAbility; import forge.game.trigger.Trigger; import forge.game.trigger.TriggerHandler; import forge.game.zone.ZoneType; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; import java.util.ArrayList; import java.util.Arrays; diff --git a/forge-game/src/main/java/forge/game/ability/effects/AnimateEffect.java b/forge-game/src/main/java/forge/game/ability/effects/AnimateEffect.java index 9ef87d293c8..0b862b3d241 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/AnimateEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/AnimateEffect.java @@ -18,7 +18,7 @@ import forge.game.spellability.SpellAbility; import forge.game.staticability.StaticAbility; import forge.game.trigger.Trigger; import forge.game.trigger.TriggerHandler; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; import java.util.ArrayList; import java.util.Arrays; diff --git a/forge-game/src/main/java/forge/game/ability/effects/AttachEffect.java b/forge-game/src/main/java/forge/game/ability/effects/AttachEffect.java index c0ee8e6cdcc..091773ef6c9 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/AttachEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/AttachEffect.java @@ -15,7 +15,7 @@ import forge.game.player.Player; import forge.game.spellability.SpellAbility; import forge.game.spellability.TargetRestrictions; import forge.game.zone.ZoneType; -import forge.util.FCollection; +import forge.util.collect.FCollection; import forge.util.Lang; import java.util.List; diff --git a/forge-game/src/main/java/forge/game/ability/effects/BalanceEffect.java b/forge-game/src/main/java/forge/game/ability/effects/BalanceEffect.java index 4ffbd520905..4916cc7e5e9 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/BalanceEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/BalanceEffect.java @@ -8,7 +8,7 @@ import forge.game.card.CardLists; import forge.game.player.Player; import forge.game.spellability.SpellAbility; import forge.game.zone.ZoneType; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; import java.util.ArrayList; import java.util.List; diff --git a/forge-game/src/main/java/forge/game/ability/effects/BidLifeEffect.java b/forge-game/src/main/java/forge/game/ability/effects/BidLifeEffect.java index cd510716252..d4baf264cd2 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/BidLifeEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/BidLifeEffect.java @@ -10,7 +10,7 @@ import forge.game.player.Player; import forge.game.player.PlayerActionConfirmMode; import forge.game.spellability.AbilitySub; import forge.game.spellability.SpellAbility; -import forge.util.FCollection; +import forge.util.collect.FCollection; public class BidLifeEffect extends SpellAbilityEffect { @Override diff --git a/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java index 0d48fc903fc..64f6dd4c020 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java @@ -25,7 +25,7 @@ import forge.game.trigger.TriggerType; import forge.game.zone.Zone; import forge.game.zone.ZoneType; import forge.util.Aggregates; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; import forge.util.Lang; import forge.util.MessageUtil; diff --git a/forge-game/src/main/java/forge/game/ability/effects/CharmEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CharmEffect.java index 182460ad520..6e5793b28f2 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CharmEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CharmEffect.java @@ -6,7 +6,7 @@ import forge.game.card.Card; import forge.game.player.Player; import forge.game.spellability.AbilitySub; import forge.game.spellability.SpellAbility; -import forge.util.FCollection; +import forge.util.collect.FCollection; import java.util.ArrayList; import java.util.List; diff --git a/forge-game/src/main/java/forge/game/ability/effects/ChooseDirectionEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ChooseDirectionEffect.java index 65ad83f4400..b2bf0f36a9c 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ChooseDirectionEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ChooseDirectionEffect.java @@ -9,7 +9,7 @@ import forge.game.card.Card; import forge.game.player.Player; import forge.game.player.PlayerController.BinaryChoiceType; import forge.game.spellability.SpellAbility; -import forge.util.FCollection; +import forge.util.collect.FCollection; public class ChooseDirectionEffect extends SpellAbilityEffect { @Override diff --git a/forge-game/src/main/java/forge/game/ability/effects/ChoosePlayerEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ChoosePlayerEffect.java index 602967bf4bd..820670f9647 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ChoosePlayerEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ChoosePlayerEffect.java @@ -7,7 +7,7 @@ import forge.game.player.Player; import forge.game.spellability.SpellAbility; import forge.game.spellability.TargetRestrictions; import forge.util.Aggregates; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; import java.util.List; diff --git a/forge-game/src/main/java/forge/game/ability/effects/CopyPermanentEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CopyPermanentEffect.java index c5cd60ce564..3a7e53aed9f 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CopyPermanentEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CopyPermanentEffect.java @@ -25,7 +25,7 @@ import forge.game.trigger.TriggerHandler; import forge.game.zone.ZoneType; import forge.item.PaperCard; import forge.util.Aggregates; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; import forge.util.PredicateString.StringOp; import org.apache.commons.lang3.StringUtils; diff --git a/forge-game/src/main/java/forge/game/ability/effects/DamageEachEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DamageEachEffect.java index fed75762384..60680de5b06 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DamageEachEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DamageEachEffect.java @@ -9,7 +9,7 @@ import forge.game.card.CardLists; import forge.game.player.Player; import forge.game.spellability.SpellAbility; import forge.game.zone.ZoneType; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; import java.util.List; diff --git a/forge-game/src/main/java/forge/game/ability/effects/RepeatEachEffect.java b/forge-game/src/main/java/forge/game/ability/effects/RepeatEachEffect.java index eeb56538418..c88cfb054e2 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/RepeatEachEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/RepeatEachEffect.java @@ -24,7 +24,7 @@ import forge.game.spellability.AbilitySub; import forge.game.spellability.SpellAbility; import forge.game.zone.ZoneType; import forge.util.Aggregates; -import forge.util.FCollection; +import forge.util.collect.FCollection; public class RepeatEachEffect extends SpellAbilityEffect { diff --git a/forge-game/src/main/java/forge/game/ability/effects/RestartGameEffect.java b/forge-game/src/main/java/forge/game/ability/effects/RestartGameEffect.java index 5a90a22399b..9ec0b925bdb 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/RestartGameEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/RestartGameEffect.java @@ -14,9 +14,13 @@ import forge.game.spellability.SpellAbility; import forge.game.trigger.TriggerHandler; import forge.game.trigger.TriggerType; import forge.game.zone.ZoneType; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; public class RestartGameEffect extends SpellAbilityEffect { @Override diff --git a/forge-game/src/main/java/forge/game/ability/effects/TapOrUntapAllEffect.java b/forge-game/src/main/java/forge/game/ability/effects/TapOrUntapAllEffect.java index b9a13ee3a70..9c6c184e065 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/TapOrUntapAllEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/TapOrUntapAllEffect.java @@ -10,7 +10,7 @@ import forge.game.player.Player; import forge.game.player.PlayerController; import forge.game.spellability.SpellAbility; import forge.game.zone.ZoneType; -import forge.util.FCollection; +import forge.util.collect.FCollection; import org.apache.commons.lang3.StringUtils; import java.util.List; diff --git a/forge-game/src/main/java/forge/game/ability/effects/TokenEffect.java b/forge-game/src/main/java/forge/game/ability/effects/TokenEffect.java index 14d2493cdec..c9e5009dc59 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/TokenEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/TokenEffect.java @@ -41,7 +41,7 @@ import forge.game.trigger.Trigger; import forge.game.trigger.TriggerHandler; import forge.game.trigger.TriggerType; import forge.item.PaperToken; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; import forge.util.MyRandom; public class TokenEffect extends SpellAbilityEffect { diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index e0f0d5d90ae..ca5d9ea251e 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -105,8 +105,8 @@ import forge.item.PaperCard; import forge.trackable.TrackableProperty; import forge.util.CollectionSuppliers; import forge.util.Expressions; -import forge.util.FCollection; -import forge.util.FCollectionView; +import forge.util.collect.FCollection; +import forge.util.collect.FCollectionView; import forge.util.Lang; import forge.util.TextUtil; import forge.util.Visitor; @@ -686,10 +686,10 @@ public class Card extends GameEntity implements Comparable { return CardCollection.getView(imprintedCards); } public final boolean hasImprintedCard() { - return CardCollection.hasCard(imprintedCards); + return FCollection.hasElements(imprintedCards); } public final boolean hasImprintedCard(Card c) { - return CardCollection.hasCard(imprintedCards, c); + return FCollection.hasElement(imprintedCards, c); } public final void addImprintedCard(final Card c) { imprintedCards = view.addCard(imprintedCards, c, TrackableProperty.ImprintedCards); @@ -711,10 +711,10 @@ public class Card extends GameEntity implements Comparable { return CardCollection.getView(encodedCards); } public final boolean hasEncodedCard() { - return CardCollection.hasCard(encodedCards); + return FCollection.hasElements(encodedCards); } public final boolean hasEncodedCard(Card c) { - return CardCollection.hasCard(encodedCards, c); + return FCollection.hasElement(encodedCards, c); } public final void addEncodedCard(final Card c) { if (encodedCards == null) { @@ -1216,10 +1216,10 @@ public class Card extends GameEntity implements Comparable { chosenCards = view.setCards(chosenCards, cards, TrackableProperty.ChosenColors); } public boolean hasChosenCard() { - return CardCollection.hasCard(chosenCards); + return FCollection.hasElements(chosenCards); } public boolean hasChosenCard(Card c) { - return CardCollection.hasCard(chosenCards, c); + return FCollection.hasElement(chosenCards, c); } public Direction getChosenDirection() { @@ -1257,10 +1257,10 @@ public class Card extends GameEntity implements Comparable { gainControlTargets = view.removeCard(gainControlTargets, c, TrackableProperty.GainControlTargets); } public final boolean hasGainControlTarget() { - return CardCollection.hasCard(gainControlTargets); + return FCollection.hasElements(gainControlTargets); } public final boolean hasGainControlTarget(Card c) { - return CardCollection.hasCard(gainControlTargets, c); + return FCollection.hasElement(gainControlTargets, c); } public final String getSpellText() { @@ -2281,10 +2281,10 @@ public class Card extends GameEntity implements Comparable { equippedBy = view.setCards(equippedBy, cards, TrackableProperty.EquippedBy); } public final boolean isEquipped() { - return CardCollection.hasCard(equippedBy); + return FCollection.hasElements(equippedBy); } public final boolean isEquippedBy(Card c) { - return CardCollection.hasCard(equippedBy, c); + return FCollection.hasElement(equippedBy, c); } public final CardCollectionView getFortifiedBy(boolean allowModify) { @@ -2297,10 +2297,10 @@ public class Card extends GameEntity implements Comparable { fortifiedBy = view.setCards(fortifiedBy, cards, TrackableProperty.FortifiedBy); } public final boolean isFortified() { - return CardCollection.hasCard(fortifiedBy); + return FCollection.hasElements(fortifiedBy); } public final boolean isFortifiedBy(Card c) { - return CardCollection.hasCard(fortifiedBy, c); + return FCollection.hasElement(fortifiedBy, c); } public final Card getEquipping() { @@ -5923,10 +5923,10 @@ public class Card extends GameEntity implements Comparable { return CardCollection.getView(hauntedBy); } public final boolean isHaunted() { - return CardCollection.hasCard(hauntedBy); + return FCollection.hasElements(hauntedBy); } public final boolean isHauntedBy(Card c) { - return CardCollection.hasCard(hauntedBy, c); + return FCollection.hasElement(hauntedBy, c); } public final void addHauntedBy(Card c) { hauntedBy = view.addCard(hauntedBy, c, TrackableProperty.HauntedBy); diff --git a/forge-game/src/main/java/forge/game/card/CardCollection.java b/forge-game/src/main/java/forge/game/card/CardCollection.java index 438fbe6647f..fe1342b6280 100644 --- a/forge-game/src/main/java/forge/game/card/CardCollection.java +++ b/forge-game/src/main/java/forge/game/card/CardCollection.java @@ -1,45 +1,82 @@ package forge.game.card; -import java.util.Collection; -import forge.util.FCollection; +import forge.util.collect.FCollection; + +import java.util.Objects; public class CardCollection extends FCollection implements CardCollectionView { private static final long serialVersionUID = -8133537013727100275L; - public static final CardCollectionView EMPTY = new CardCollection(); + /** + * An empty, immutable {@link CardCollectionView}. + */ + public static final CardCollectionView EMPTY = new EmptyCardCollection(); - public static boolean hasCard(CardCollection cards) { - return cards != null && !cards.isEmpty(); - } - public static boolean hasCard(CardCollection cards, Card c) { - return cards != null && cards.contains(c); - } - public static CardCollectionView getView(CardCollection cards) { + /** + * Get the view corresponding to an {@link Iterable} of {@link Card} + * objects. + * + * @param cards + * a collection. + * @return an unmodifiable view of the collection. + */ + public static CardCollectionView getView(final Iterable cards) { return getView(cards, false); } - public static CardCollectionView getView(CardCollection cards, boolean allowModify) { + + /** + * Get the view corresponding to an {@link Iterable} of {@link Card} + * objects. + * + * @param cards + * a collection. + * @param allowModify + * whether to make a shallow copy of the collection to make the + * returned view independent from the original collection. + * @return an unmodifiable view of the collection. + */ + public static CardCollectionView getView(final Iterable cards, final boolean allowModify) { if (cards == null) { return EMPTY; } if (allowModify) { //create copy to allow modifying original set while iterating return new CardCollection(cards); } - return cards; + + if (cards instanceof CardCollectionView) { + return (CardCollectionView) cards; + } + return new CardCollection(cards); } - public static CardCollectionView combine(CardCollectionView... views) { + + /** + * Combine multiple instances of {@link CardCollectionView} into a single + * view. The returned value is a view of the collections at the moment this + * method is called, and is not backed by those collections. The returned + * collection does respect the order, both of the order in which the + * collections are supplied, and of the elements of those collections. + * + * @param views + * an array of card collections. + * @return the elements of the collections in {@code views} combined into a + * single collection. + * @throws NullPointerException + * if {@code views} is {@code null}. + */ + public static CardCollectionView combine(final CardCollectionView... views) { + Objects.requireNonNull(views); + CardCollection newCol = null; CardCollectionView viewWithCards = null; - for (CardCollectionView v : views) { + for (final CardCollectionView v : views) { if (!v.isEmpty()) { if (viewWithCards == null) { viewWithCards = v; - } - else if (newCol == null) { //if multiple views have cards, we need to create a new collection + } else if (newCol == null) { //if multiple views have cards, we need to create a new collection newCol = new CardCollection(viewWithCards); newCol.addAll(v); viewWithCards = newCol; - } - else { + } else { newCol.addAll(v); } } @@ -50,25 +87,50 @@ public class CardCollection extends FCollection implements CardCollectionV return viewWithCards; } + /** + * Construct a new, empty {@link CardCollection}. + */ public CardCollection() { super(); } - public CardCollection(Card card) { + + /** + * Construct a new {@link CardCollection} containing a single element. + * + * @param card + * the element contained by the new collection. + */ + public CardCollection(final Card card) { super(card); } - public CardCollection(Collection cards) { - super(cards); - } - public CardCollection(Iterable cards) { + + /** + * Construct a new {@link CardCollection} from an iterable of {@link Card} + * objects, respecting the order in which those objects appear. + * + * @param cards + * an {@link Iterable}. + */ + public CardCollection(final Iterable cards) { super(cards); } + /** + * {@inheritDoc} + */ @Override - protected FCollection createNew() { - return new CardCollection(); + public CardCollection subList(final int fromIndex, final int toIndex) { + return new CardCollection(super.subList(fromIndex, toIndex)); } - public CardCollection subList(int fromIndex, int toIndex) { - return (CardCollection)super.subList(fromIndex, toIndex); + /** + * An unmodifiable, empty {@link CardCollection}. + */ + private final static class EmptyCardCollection extends EmptyFCollection implements CardCollectionView { + private static final long serialVersionUID = -3218771134502034727L; + + private EmptyCardCollection() { + super(); + } } } diff --git a/forge-game/src/main/java/forge/game/card/CardCollectionView.java b/forge-game/src/main/java/forge/game/card/CardCollectionView.java index 41354bb8724..1bae6ed910f 100644 --- a/forge-game/src/main/java/forge/game/card/CardCollectionView.java +++ b/forge-game/src/main/java/forge/game/card/CardCollectionView.java @@ -1,6 +1,6 @@ package forge.game.card; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; //Simplified interface for card collection views public interface CardCollectionView extends FCollectionView { diff --git a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java index 89ccb4c170f..fd62e44fef2 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -71,7 +71,7 @@ import forge.game.zone.Zone; import forge.game.zone.ZoneType; import forge.item.PaperCard; import forge.util.Aggregates; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; import forge.util.Lang; /** diff --git a/forge-game/src/main/java/forge/game/card/CardLists.java b/forge-game/src/main/java/forge/game/card/CardLists.java index 21a91ba4120..3cb07a0a6b5 100644 --- a/forge-game/src/main/java/forge/game/card/CardLists.java +++ b/forge-game/src/main/java/forge/game/card/CardLists.java @@ -27,7 +27,7 @@ import com.google.common.collect.Iterables; import forge.game.player.Player; import forge.game.spellability.SpellAbility; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; import forge.util.MyRandom; /** diff --git a/forge-game/src/main/java/forge/game/card/CardPredicates.java b/forge-game/src/main/java/forge/game/card/CardPredicates.java index 5f3e9154210..4439c878871 100644 --- a/forge-game/src/main/java/forge/game/card/CardPredicates.java +++ b/forge-game/src/main/java/forge/game/card/CardPredicates.java @@ -24,7 +24,7 @@ import com.google.common.collect.Iterables; import forge.game.combat.CombatUtil; import forge.game.player.Player; import forge.game.spellability.SpellAbility; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; import forge.util.PredicateString; diff --git a/forge-game/src/main/java/forge/game/card/CardState.java b/forge-game/src/main/java/forge/game/card/CardState.java index 65ffe90b5ee..268c898a7b5 100644 --- a/forge-game/src/main/java/forge/game/card/CardState.java +++ b/forge-game/src/main/java/forge/game/card/CardState.java @@ -38,8 +38,8 @@ import forge.game.replacement.ReplacementEffect; import forge.game.spellability.SpellAbility; import forge.game.staticability.StaticAbility; import forge.game.trigger.Trigger; -import forge.util.FCollection; -import forge.util.FCollectionView; +import forge.util.collect.FCollection; +import forge.util.collect.FCollectionView; public class CardState { private String name = ""; diff --git a/forge-game/src/main/java/forge/game/card/CardUtil.java b/forge-game/src/main/java/forge/game/card/CardUtil.java index a62b99115ff..0f22489026d 100644 --- a/forge-game/src/main/java/forge/game/card/CardUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardUtil.java @@ -42,7 +42,7 @@ import forge.game.spellability.AbilitySub; import forge.game.spellability.SpellAbility; import forge.game.spellability.TargetRestrictions; import forge.game.zone.ZoneType; -import forge.util.FCollection; +import forge.util.collect.FCollection; public final class CardUtil { // disable instantiation diff --git a/forge-game/src/main/java/forge/game/card/CardView.java b/forge-game/src/main/java/forge/game/card/CardView.java index 142a9589c99..01758ca7623 100644 --- a/forge-game/src/main/java/forge/game/card/CardView.java +++ b/forge-game/src/main/java/forge/game/card/CardView.java @@ -30,7 +30,7 @@ import forge.trackable.TrackableCollection; import forge.trackable.TrackableObject; import forge.trackable.TrackableProperty; import forge.trackable.Tracker; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; public class CardView extends GameEntityView { private static final long serialVersionUID = -3624090829028979255L; diff --git a/forge-game/src/main/java/forge/game/combat/AttackConstraints.java b/forge-game/src/main/java/forge/game/combat/AttackConstraints.java index 8dee47c28c0..c1285264a35 100644 --- a/forge-game/src/main/java/forge/game/combat/AttackConstraints.java +++ b/forge-game/src/main/java/forge/game/combat/AttackConstraints.java @@ -31,9 +31,9 @@ import forge.game.card.CardLists; import forge.game.card.CardPredicates; import forge.game.card.CounterType; import forge.game.zone.ZoneType; -import forge.util.FCollection; -import forge.util.FCollectionView; -import forge.util.MapToAmountUtil; +import forge.util.collect.FCollection; +import forge.util.collect.FCollectionView; +import forge.util.maps.MapToAmountUtil; import forge.util.maps.LinkedHashMapToAmount; import forge.util.maps.MapToAmount; diff --git a/forge-game/src/main/java/forge/game/combat/AttackRequirement.java b/forge-game/src/main/java/forge/game/combat/AttackRequirement.java index 95faceaa5eb..33ee0891517 100644 --- a/forge-game/src/main/java/forge/game/combat/AttackRequirement.java +++ b/forge-game/src/main/java/forge/game/combat/AttackRequirement.java @@ -14,8 +14,8 @@ import forge.game.ability.AbilityUtils; import forge.game.card.Card; import forge.game.player.Player; import forge.game.zone.ZoneType; -import forge.util.FCollectionView; -import forge.util.MapToAmountUtil; +import forge.util.collect.FCollectionView; +import forge.util.maps.MapToAmountUtil; import forge.util.maps.LinkedHashMapToAmount; import forge.util.maps.MapToAmount; diff --git a/forge-game/src/main/java/forge/game/combat/AttackRestriction.java b/forge-game/src/main/java/forge/game/combat/AttackRestriction.java index cc0f51eb623..2f47ffd92e2 100644 --- a/forge-game/src/main/java/forge/game/combat/AttackRestriction.java +++ b/forge-game/src/main/java/forge/game/combat/AttackRestriction.java @@ -12,8 +12,8 @@ import forge.game.GameEntity; import forge.game.card.Card; import forge.game.card.CardLists; import forge.game.card.CardPredicates; -import forge.util.FCollection; -import forge.util.FCollectionView; +import forge.util.collect.FCollection; +import forge.util.collect.FCollectionView; public class AttackRestriction { diff --git a/forge-game/src/main/java/forge/game/combat/Combat.java b/forge-game/src/main/java/forge/game/combat/Combat.java index a799ed19f28..de4f71b0613 100644 --- a/forge-game/src/main/java/forge/game/combat/Combat.java +++ b/forge-game/src/main/java/forge/game/combat/Combat.java @@ -40,8 +40,8 @@ import forge.game.card.CardCollection; import forge.game.card.CardCollectionView; import forge.game.player.Player; import forge.game.trigger.TriggerType; -import forge.util.FCollection; -import forge.util.FCollectionView; +import forge.util.collect.FCollection; +import forge.util.collect.FCollectionView; /** *

diff --git a/forge-game/src/main/java/forge/game/combat/CombatLki.java b/forge-game/src/main/java/forge/game/combat/CombatLki.java index 236423b27ab..fa47100092e 100644 --- a/forge-game/src/main/java/forge/game/combat/CombatLki.java +++ b/forge-game/src/main/java/forge/game/combat/CombatLki.java @@ -1,7 +1,7 @@ package forge.game.combat; -import forge.util.FCollection; -import forge.util.FCollectionView; +import forge.util.collect.FCollection; +import forge.util.collect.FCollectionView; /** * TODO: Write javadoc for this type. diff --git a/forge-game/src/main/java/forge/game/combat/CombatUtil.java b/forge-game/src/main/java/forge/game/combat/CombatUtil.java index 1d814b2dda9..9da53e19dee 100644 --- a/forge-game/src/main/java/forge/game/combat/CombatUtil.java +++ b/forge-game/src/main/java/forge/game/combat/CombatUtil.java @@ -50,8 +50,8 @@ import forge.game.staticability.StaticAbility; import forge.game.trigger.TriggerType; import forge.game.zone.ZoneType; import forge.util.Expressions; -import forge.util.FCollection; -import forge.util.FCollectionView; +import forge.util.collect.FCollection; +import forge.util.collect.FCollectionView; import forge.util.Lang; import forge.util.TextUtil; import forge.util.maps.MapToAmount; diff --git a/forge-game/src/main/java/forge/game/combat/CombatView.java b/forge-game/src/main/java/forge/game/combat/CombatView.java index 1739a3e8aee..44a44b8cc8a 100644 --- a/forge-game/src/main/java/forge/game/combat/CombatView.java +++ b/forge-game/src/main/java/forge/game/combat/CombatView.java @@ -14,7 +14,7 @@ import forge.game.card.CardView; import forge.trackable.TrackableObject; import forge.trackable.TrackableProperty; import forge.trackable.Tracker; -import forge.util.FCollection; +import forge.util.collect.FCollection; public class CombatView extends TrackableObject { private static final long serialVersionUID = 68085618912864941L; diff --git a/forge-game/src/main/java/forge/game/combat/GlobalAttackRestrictions.java b/forge-game/src/main/java/forge/game/combat/GlobalAttackRestrictions.java index 5b2db5cab0d..f79d6dac0a8 100644 --- a/forge-game/src/main/java/forge/game/combat/GlobalAttackRestrictions.java +++ b/forge-game/src/main/java/forge/game/combat/GlobalAttackRestrictions.java @@ -11,8 +11,8 @@ import forge.game.GlobalRuleChange; import forge.game.card.Card; import forge.game.player.Player; import forge.game.zone.ZoneType; -import forge.util.FCollectionView; -import forge.util.MapToAmountUtil; +import forge.util.collect.FCollectionView; +import forge.util.maps.MapToAmountUtil; import forge.util.maps.LinkedHashMapToAmount; import forge.util.maps.MapToAmount; diff --git a/forge-game/src/main/java/forge/game/cost/CostExile.java b/forge-game/src/main/java/forge/game/cost/CostExile.java index d8838af3827..aa8bce2193c 100644 --- a/forge-game/src/main/java/forge/game/cost/CostExile.java +++ b/forge-game/src/main/java/forge/game/cost/CostExile.java @@ -25,7 +25,7 @@ import forge.game.card.CardPredicates; import forge.game.player.Player; import forge.game.spellability.SpellAbility; import forge.game.zone.ZoneType; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; /** * The Class CostExile. diff --git a/forge-game/src/main/java/forge/game/cost/CostPutCardToLib.java b/forge-game/src/main/java/forge/game/cost/CostPutCardToLib.java index db6fd04e52a..b8d1fa48fe8 100644 --- a/forge-game/src/main/java/forge/game/cost/CostPutCardToLib.java +++ b/forge-game/src/main/java/forge/game/cost/CostPutCardToLib.java @@ -26,7 +26,7 @@ import forge.game.card.CardPredicates; import forge.game.player.Player; import forge.game.spellability.SpellAbility; import forge.game.zone.ZoneType; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; /** * This is for the "PutCardToLib" Cost. diff --git a/forge-game/src/main/java/forge/game/phase/PhaseHandler.java b/forge-game/src/main/java/forge/game/phase/PhaseHandler.java index 650b7ccc9d5..b9325cd5f10 100644 --- a/forge-game/src/main/java/forge/game/phase/PhaseHandler.java +++ b/forge-game/src/main/java/forge/game/phase/PhaseHandler.java @@ -42,7 +42,7 @@ import forge.game.trigger.Trigger; import forge.game.trigger.TriggerType; import forge.game.zone.ZoneType; import forge.util.CollectionSuppliers; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; import forge.util.maps.HashMapOfLists; import forge.util.maps.MapOfLists; diff --git a/forge-game/src/main/java/forge/game/phase/Untap.java b/forge-game/src/main/java/forge/game/phase/Untap.java index c7bb322a7f1..73cdb29e676 100644 --- a/forge-game/src/main/java/forge/game/phase/Untap.java +++ b/forge-game/src/main/java/forge/game/phase/Untap.java @@ -41,7 +41,7 @@ import forge.game.player.Player; import forge.game.player.PlayerController.BinaryChoiceType; import forge.game.spellability.SpellAbility; import forge.game.zone.ZoneType; -import forge.util.FCollection; +import forge.util.collect.FCollection; /** *

diff --git a/forge-game/src/main/java/forge/game/player/Player.java b/forge-game/src/main/java/forge/game/player/Player.java index e9ff6dfdd39..4331c2e4dc2 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -61,7 +61,7 @@ import forge.game.zone.Zone; import forge.game.zone.ZoneType; import forge.item.IPaperCard; import forge.util.Aggregates; -import forge.util.FCollection; +import forge.util.collect.FCollection; import forge.util.Lang; import forge.util.MyRandom; diff --git a/forge-game/src/main/java/forge/game/player/PlayerController.java b/forge-game/src/main/java/forge/game/player/PlayerController.java index 8ffbe575f8f..54d30010a83 100644 --- a/forge-game/src/main/java/forge/game/player/PlayerController.java +++ b/forge-game/src/main/java/forge/game/player/PlayerController.java @@ -41,7 +41,7 @@ import forge.game.trigger.Trigger; import forge.game.trigger.WrappedAbility; import forge.game.zone.ZoneType; import forge.item.PaperCard; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; import forge.util.ITriggerEvent; /** diff --git a/forge-game/src/main/java/forge/game/player/PlayerView.java b/forge-game/src/main/java/forge/game/player/PlayerView.java index cf233192674..b70b9ab4af8 100644 --- a/forge-game/src/main/java/forge/game/player/PlayerView.java +++ b/forge-game/src/main/java/forge/game/player/PlayerView.java @@ -24,8 +24,8 @@ import forge.game.zone.ZoneType; import forge.trackable.TrackableCollection; import forge.trackable.TrackableProperty; import forge.trackable.Tracker; -import forge.util.FCollection; -import forge.util.FCollectionView; +import forge.util.collect.FCollection; +import forge.util.collect.FCollectionView; import forge.util.Lang; public class PlayerView extends GameEntityView { diff --git a/forge-game/src/main/java/forge/game/spellability/AbilityActivated.java b/forge-game/src/main/java/forge/game/spellability/AbilityActivated.java index 6d92c63f2ef..51ea9feff88 100644 --- a/forge-game/src/main/java/forge/game/spellability/AbilityActivated.java +++ b/forge-game/src/main/java/forge/game/spellability/AbilityActivated.java @@ -25,7 +25,7 @@ import forge.game.cost.CostPayment; import forge.game.player.Player; import forge.game.staticability.StaticAbility; import forge.game.zone.ZoneType; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; /** *

diff --git a/forge-game/src/main/java/forge/game/spellability/Spell.java b/forge-game/src/main/java/forge/game/spellability/Spell.java index 96c7bab99a7..6b3e8ac5fa8 100644 --- a/forge-game/src/main/java/forge/game/spellability/Spell.java +++ b/forge-game/src/main/java/forge/game/spellability/Spell.java @@ -26,7 +26,7 @@ import forge.game.cost.CostPayment; import forge.game.player.Player; import forge.game.staticability.StaticAbility; import forge.game.zone.ZoneType; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; /** *

diff --git a/forge-game/src/main/java/forge/game/spellability/StackItemView.java b/forge-game/src/main/java/forge/game/spellability/StackItemView.java index 490095b6e4f..61b431b3b13 100644 --- a/forge-game/src/main/java/forge/game/spellability/StackItemView.java +++ b/forge-game/src/main/java/forge/game/spellability/StackItemView.java @@ -6,7 +6,7 @@ import forge.game.player.PlayerView; import forge.trackable.TrackableCollection; import forge.trackable.TrackableObject; import forge.trackable.TrackableProperty; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; public class StackItemView extends TrackableObject implements IHasCardView { private static final long serialVersionUID = 6733415646691356052L; diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerVote.java b/forge-game/src/main/java/forge/game/trigger/TriggerVote.java index e6c7defe84c..5b8e689f1d6 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerVote.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerVote.java @@ -26,7 +26,7 @@ import com.google.common.collect.ListMultimap; import forge.game.card.Card; import forge.game.player.Player; import forge.game.spellability.SpellAbility; -import forge.util.FCollection; +import forge.util.collect.FCollection; /** *

diff --git a/forge-game/src/main/java/forge/trackable/TrackableCollection.java b/forge-game/src/main/java/forge/trackable/TrackableCollection.java index a5d1c30e24b..a6b85400081 100644 --- a/forge-game/src/main/java/forge/trackable/TrackableCollection.java +++ b/forge-game/src/main/java/forge/trackable/TrackableCollection.java @@ -2,7 +2,7 @@ package forge.trackable; import java.util.Collection; -import forge.util.FCollection; +import forge.util.collect.FCollection; public class TrackableCollection extends FCollection { private static final long serialVersionUID = 1528674215758232314L; diff --git a/forge-game/src/main/java/forge/util/FCollection.java b/forge-game/src/main/java/forge/util/FCollection.java deleted file mode 100644 index 10580705c4e..00000000000 --- a/forge-game/src/main/java/forge/util/FCollection.java +++ /dev/null @@ -1,280 +0,0 @@ -package forge.util; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.ListIterator; -import java.util.Set; - -//base class for a collection with quick lookup and that maintains order -public class FCollection implements List, Set, FCollectionView, Cloneable, Serializable { - private static final long serialVersionUID = -1664555336364294106L; - - private final Set set = new HashSet(); - private final LinkedList list = new LinkedList(); - - public FCollection() { - } - public FCollection(T e) { - add(e); - } - public FCollection(T[] c) { - for (T e : c) { - add(e); - } - } - public FCollection(Collection c) { - for (T e : c) { - add(e); - } - } - public FCollection(Iterable i) { - for (T e : i) { - add(e); - } - } - - @Override - public int hashCode() { - return list.hashCode(); - } - - @Override - public String toString() { - return list.toString(); - } - - protected FCollection createNew() { - return new FCollection(); - } - - @Override - public final Object clone() { - FCollection clone = createNew(); - clone.addAll(this); - return clone; - } - - public T getFirst() { - return list.getFirst(); - } - public T getLast() { - return list.getLast(); - } - - @Override - public int size() { - return set.size(); - } - - @Override - public boolean isEmpty() { - return set.isEmpty(); - } - - @Override - public boolean contains(Object o) { - return set.contains(o); - } - - @Override - public Iterator iterator() { - return list.iterator(); - } - - @Override - public Object[] toArray() { - return list.toArray(); - } - - @Override - public V[] toArray(V[] a) { - return list.toArray(a); - } - - @Override - public boolean add(T e) { - if (set.add(e)) { - list.add(e); - return true; - } - return false; - } - - @Override - public boolean remove(Object o) { - if (set.remove(o)) { - list.remove(o); - return true; - } - return false; - } - @Override - public boolean containsAll(Collection c) { - return set.containsAll(c); - } - @Override - public boolean addAll(Collection c) { - boolean changed = false; - for (T e : c) { - if (add(e)) { - changed = true; - } - } - return changed; - } - public boolean addAll(Iterable c) { - boolean changed = false; - for (T e : c) { - if (add(e)) { - changed = true; - } - } - return changed; - } - public boolean addAll(T[] c) { - boolean changed = false; - for (T e : c) { - if (add(e)) { - changed = true; - } - } - return changed; - } - @SuppressWarnings("unchecked") - @Override - public boolean addAll(int index, Collection c) { - if (c == null) { return false; } - List list; - if (c instanceof List) { - list = (List)c; - } - else { - list = new ArrayList(c); - } - boolean changed = false; - for (int i = list.size() - 1; i >= 0; i--) { //must add in reverse order so they show up in the right place - if (insert(index, list.get(i))) { - changed = true; - } - } - return changed; - } - @Override - public boolean removeAll(Collection c) { - boolean changed = false; - for (Object o : c) { - if (remove(o)) { - changed = true; - } - } - return changed; - } - public boolean removeAll(Iterable c) { - boolean changed = false; - for (T o : c) { - if (remove(o)) { - changed = true; - } - } - return changed; - } - @Override - public boolean retainAll(Collection c) { - if (set.retainAll(c)) { - list.retainAll(c); - return true; - } - return false; - } - @Override - public void clear() { - if (set.isEmpty()) { return; } - set.clear(); - list.clear(); - } - @Override - public T get(int index) { - return list.get(index); - } - @Override - public T set(int index, T element) { //assume this isn't called except when changing list order, so don't worry about updating set - return list.set(index, element); - } - @Override - public void add(int index, T element) { - insert(index, element); - } - private boolean insert(int index, T element) { - if (set.add(element)) { - list.add(index, element); - return true; - } - //re-position in list if needed - int oldIndex = list.indexOf(element); - if (index == oldIndex) { return false; } - - if (index > oldIndex) { - index--; //account for being removed - } - list.remove(oldIndex); - list.add(index, element); - return true; - } - @Override - public T remove(int index) { - T removedItem = list.remove(index); - if (removedItem != null) { - set.remove(removedItem); - } - return removedItem; - } - @Override - public int indexOf(Object o) { - return list.indexOf(o); - } - @Override - public int lastIndexOf(Object o) { - return list.lastIndexOf(o); - } - @Override - public ListIterator listIterator() { - return list.listIterator(); - } - @Override - public ListIterator listIterator(int index) { - return list.listIterator(index); - } - @Override - public List subList(int fromIndex, int toIndex) { - FCollection subList = createNew(); - for (int i = fromIndex; i < toIndex; i++) { - subList.add(list.get(i)); - } - return subList; - } - - public void sort() { - sort(new Comparator() { - @Override - public int compare(T o1, T o2) { - return o1.toString().compareTo(o2.toString()); - } - }); - } - public void sort(final Comparator comparator) { - Collections.sort(list, comparator); - } - - @Override - public Iterable threadSafeIterator() { - //create a new linked list for iterating to make it thread safe and avoid concurrent modification exceptions - return new LinkedList(list); - } -} diff --git a/forge-game/src/main/java/forge/util/FCollectionView.java b/forge-game/src/main/java/forge/util/FCollectionView.java deleted file mode 100644 index 24515260300..00000000000 --- a/forge-game/src/main/java/forge/util/FCollectionView.java +++ /dev/null @@ -1,17 +0,0 @@ -package forge.util; - -import java.util.List; - -//Interface to expose only the desired functions of CardType without allowing modification -public interface FCollectionView extends Iterable { - boolean isEmpty(); - int size(); - T get(int index); - T getFirst(); - T getLast(); - int indexOf(Object o); - int lastIndexOf(Object o); - boolean contains(Object o); - List subList(int fromIndex, int toIndex); - Iterable threadSafeIterator(); -} \ No newline at end of file diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java b/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java index 80163ef7f25..3914cbc8827 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java @@ -95,8 +95,8 @@ import forge.toolbox.FSkin.SkinImage; import forge.toolbox.special.PhaseIndicator; import forge.toolbox.special.PhaseLabel; import forge.trackable.TrackableCollection; -import forge.util.FCollection; -import forge.util.FCollectionView; +import forge.util.collect.FCollection; +import forge.util.collect.FCollectionView; import forge.util.ITriggerEvent; import forge.util.gui.SOptionPane; import forge.view.FView; diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CCombat.java b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CCombat.java index 7f538c8cd44..057526ae3f2 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CCombat.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/controllers/CCombat.java @@ -11,7 +11,7 @@ import forge.game.combat.CombatView; import forge.game.player.PlayerView; import forge.gui.framework.ICDoc; import forge.screens.match.views.VCombat; -import forge.util.FCollection; +import forge.util.collect.FCollection; import forge.util.Lang; /** diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/views/VStack.java b/forge-gui-desktop/src/main/java/forge/screens/match/views/VStack.java index 4818bd38c7a..e14e5500d32 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/views/VStack.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/views/VStack.java @@ -51,7 +51,7 @@ import forge.toolbox.FMouseAdapter; import forge.toolbox.FScrollPanel; import forge.toolbox.FSkin; import forge.toolbox.FSkin.SkinnedTextArea; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; /** * Assembles Swing components of stack report. diff --git a/forge-gui-desktop/src/main/java/forge/view/arcane/FloatingCardArea.java b/forge-gui-desktop/src/main/java/forge/view/arcane/FloatingCardArea.java index ec7b334e3b2..7555b82b813 100644 --- a/forge-gui-desktop/src/main/java/forge/view/arcane/FloatingCardArea.java +++ b/forge-gui-desktop/src/main/java/forge/view/arcane/FloatingCardArea.java @@ -45,7 +45,7 @@ import forge.toolbox.FMouseAdapter; import forge.toolbox.FScrollPane; import forge.toolbox.FSkin; import forge.toolbox.MouseTriggerEvent; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; import forge.util.Lang; import forge.view.FDialog; import forge.view.FFrame; diff --git a/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java b/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java index 22805579479..13e681ea0bc 100644 --- a/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java +++ b/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java @@ -69,7 +69,7 @@ import forge.gamesimulationtests.util.playeractions.DeclareBlockersAction; import forge.gamesimulationtests.util.playeractions.PlayerActions; import forge.item.PaperCard; import forge.player.HumanPlay; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; import forge.util.ITriggerEvent; import forge.util.MyRandom; diff --git a/forge-gui-mobile/src/forge/card/CardZoom.java b/forge-gui-mobile/src/forge/card/CardZoom.java index 27d1804481d..1e6343101c7 100644 --- a/forge-gui-mobile/src/forge/card/CardZoom.java +++ b/forge-gui-mobile/src/forge/card/CardZoom.java @@ -22,7 +22,7 @@ import forge.screens.match.MatchController; import forge.toolbox.FCardPanel; import forge.toolbox.FDialog; import forge.toolbox.FOverlay; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; import forge.util.Utils; public class CardZoom extends FOverlay { diff --git a/forge-gui-mobile/src/forge/screens/match/MatchController.java b/forge-gui-mobile/src/forge/screens/match/MatchController.java index 21b317e1fa8..f2d05cb0fb1 100644 --- a/forge-gui-mobile/src/forge/screens/match/MatchController.java +++ b/forge-gui-mobile/src/forge/screens/match/MatchController.java @@ -54,7 +54,7 @@ import forge.toolbox.FButton; import forge.toolbox.FDisplayObject; import forge.toolbox.FOptionPane; import forge.trackable.TrackableCollection; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; import forge.util.ITriggerEvent; import forge.util.MessageUtil; import forge.util.WaitCallback; diff --git a/forge-gui-mobile/src/forge/screens/match/views/VStack.java b/forge-gui-mobile/src/forge/screens/match/views/VStack.java index 1566013dcc9..945aad8fc34 100644 --- a/forge-gui-mobile/src/forge/screens/match/views/VStack.java +++ b/forge-gui-mobile/src/forge/screens/match/views/VStack.java @@ -40,7 +40,7 @@ import forge.toolbox.FDisplayObject; import forge.toolbox.FEvent; import forge.toolbox.FEvent.FEventHandler; import forge.toolbox.FLabel; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; import forge.util.Utils; public class VStack extends FDropDown { diff --git a/forge-gui-mobile/src/forge/screens/planarconquest/ConquestMapScreen.java b/forge-gui-mobile/src/forge/screens/planarconquest/ConquestMapScreen.java index aaf64357655..f677cda165c 100644 --- a/forge-gui-mobile/src/forge/screens/planarconquest/ConquestMapScreen.java +++ b/forge-gui-mobile/src/forge/screens/planarconquest/ConquestMapScreen.java @@ -19,7 +19,7 @@ import forge.planarconquest.ConquestPlane.Region; import forge.screens.FScreen; import forge.toolbox.FList; import forge.toolbox.FList.ListItemRenderer; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; public class ConquestMapScreen extends FScreen { private static final Color FOG_OF_WAR_COLOR = FSkinColor.alphaColor(Color.BLACK, 0.6f); diff --git a/forge-gui/src/main/java/forge/match/HostedMatch.java b/forge-gui/src/main/java/forge/match/HostedMatch.java index 01390921314..7655c37f97f 100644 --- a/forge-gui/src/main/java/forge/match/HostedMatch.java +++ b/forge-gui/src/main/java/forge/match/HostedMatch.java @@ -45,7 +45,7 @@ import forge.sound.MusicPlaylist; import forge.sound.SoundSystem; import forge.trackable.TrackableCollection; import forge.util.CollectionSuppliers; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; import forge.util.maps.HashMapOfLists; import forge.util.maps.MapOfLists; diff --git a/forge-gui/src/main/java/forge/match/input/InputAttack.java b/forge-gui/src/main/java/forge/match/input/InputAttack.java index c5ae25e2ced..1733b7db93c 100644 --- a/forge-gui/src/main/java/forge/match/input/InputAttack.java +++ b/forge-gui/src/main/java/forge/match/input/InputAttack.java @@ -40,7 +40,7 @@ import forge.game.player.Player; import forge.game.player.PlayerView; import forge.game.zone.ZoneType; import forge.player.PlayerControllerHuman; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; import forge.util.ITriggerEvent; /** diff --git a/forge-gui/src/main/java/forge/match/input/InputSelectCardsFromList.java b/forge-gui/src/main/java/forge/match/input/InputSelectCardsFromList.java index f4513ccb225..52022d53d1b 100644 --- a/forge-gui/src/main/java/forge/match/input/InputSelectCardsFromList.java +++ b/forge-gui/src/main/java/forge/match/input/InputSelectCardsFromList.java @@ -2,7 +2,7 @@ package forge.match.input; import forge.game.card.Card; import forge.player.PlayerControllerHuman; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; public class InputSelectCardsFromList extends InputSelectEntitiesFromList { private static final long serialVersionUID = 6230360322294805986L; diff --git a/forge-gui/src/main/java/forge/match/input/InputSelectEntitiesFromList.java b/forge-gui/src/main/java/forge/match/input/InputSelectEntitiesFromList.java index 76b700ca08e..a807f01e1cb 100644 --- a/forge-gui/src/main/java/forge/match/input/InputSelectEntitiesFromList.java +++ b/forge-gui/src/main/java/forge/match/input/InputSelectEntitiesFromList.java @@ -7,8 +7,8 @@ import forge.game.GameEntity; import forge.game.card.Card; import forge.game.player.Player; import forge.player.PlayerControllerHuman; -import forge.util.FCollection; -import forge.util.FCollectionView; +import forge.util.collect.FCollection; +import forge.util.collect.FCollectionView; import forge.util.ITriggerEvent; public class InputSelectEntitiesFromList extends InputSelectManyBase { diff --git a/forge-gui/src/main/java/forge/planarconquest/ConquestPlane.java b/forge-gui/src/main/java/forge/planarconquest/ConquestPlane.java index b731520ffa0..7bb95d402fd 100644 --- a/forge-gui/src/main/java/forge/planarconquest/ConquestPlane.java +++ b/forge-gui/src/main/java/forge/planarconquest/ConquestPlane.java @@ -30,8 +30,8 @@ import forge.deck.generation.DeckGenPool; import forge.item.PaperCard; import forge.model.FModel; import forge.util.Aggregates; -import forge.util.FCollection; -import forge.util.FCollectionView; +import forge.util.collect.FCollection; +import forge.util.collect.FCollectionView; public enum ConquestPlane { diff --git a/forge-gui/src/main/java/forge/player/HumanCostDecision.java b/forge-gui/src/main/java/forge/player/HumanCostDecision.java index 5fefb7f0204..1f22195feda 100644 --- a/forge-gui/src/main/java/forge/player/HumanCostDecision.java +++ b/forge-gui/src/main/java/forge/player/HumanCostDecision.java @@ -60,7 +60,7 @@ import forge.game.zone.ZoneType; import forge.match.input.InputSelectCardsFromList; import forge.match.input.InputSelectManyBase; import forge.util.Aggregates; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; import forge.util.ITriggerEvent; import forge.util.Lang; diff --git a/forge-gui/src/main/java/forge/player/HumanPlay.java b/forge-gui/src/main/java/forge/player/HumanPlay.java index 102b0784667..f02c39afbc5 100644 --- a/forge-gui/src/main/java/forge/player/HumanPlay.java +++ b/forge-gui/src/main/java/forge/player/HumanPlay.java @@ -62,7 +62,7 @@ import forge.match.input.InputPayMana; import forge.match.input.InputPayManaOfCostPayment; import forge.match.input.InputPayManaSimple; import forge.match.input.InputSelectCardsFromList; -import forge.util.FCollectionView; +import forge.util.collect.FCollectionView; import forge.util.Lang; import forge.util.gui.SGuiChoose; diff --git a/forge-gui/src/main/java/forge/player/HumanPlaySpellAbility.java b/forge-gui/src/main/java/forge/player/HumanPlaySpellAbility.java index b5e2695829e..3d2e190e174 100644 --- a/forge-gui/src/main/java/forge/player/HumanPlaySpellAbility.java +++ b/forge-gui/src/main/java/forge/player/HumanPlaySpellAbility.java @@ -41,7 +41,7 @@ import forge.game.spellability.Spell; import forge.game.spellability.SpellAbility; import forge.game.spellability.TargetRestrictions; import forge.game.zone.Zone; -import forge.util.FCollection; +import forge.util.collect.FCollection; /** *

diff --git a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java index 12213ce6aab..b41a9727dc6 100644 --- a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java +++ b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java @@ -107,8 +107,8 @@ import forge.match.input.InputSelectEntitiesFromList; import forge.model.FModel; import forge.properties.ForgeConstants; import forge.properties.ForgePreferences.FPref; -import forge.util.FCollection; -import forge.util.FCollectionView; +import forge.util.collect.FCollection; +import forge.util.collect.FCollectionView; import forge.util.ITriggerEvent; import forge.util.Lang; import forge.util.MessageUtil;