monniasza.collects.Collects Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of multimachinebuilder Show documentation
Show all versions of multimachinebuilder Show documentation
Dependency for the MultiMachineBuilder, a voxel game about building an industrial empire in a finite world.
THIS RELEASE IS NOT PLAYABLE. To play the game, donwload from >ITCH.IO LINK HERE< or >GH releases link here<
The newest version!
/**
*
*/
package monniasza.collects;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collector;
import javax.swing.DefaultListModel;
import javax.swing.ListModel;
import javax.swing.event.ListDataListener;
import com.google.common.collect.Iterators;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multiset;
import com.google.common.collect.SetMultimap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import mmb.NN;
import mmb.Nil;
import mmb.engine.item.ItemEntry;
import mmb.engine.recipe.RecipeOutput;
import monniasza.collects.grid.Grid;
import monniasza.collects.selfset.SelfSet;
/**
* A set of operations on collections used in MultiMachineBuilder
* @author oskar
*/
public class Collects {
private Collects() {}
//Iterators
/**
* Down-casts the iterator
* @param type of the output iterator
* @param iter iterator
* @return downcasted iterator
*/
@SuppressWarnings("unchecked")
@NN public static Iterator downcastIterator(Iterator extends T> iter) {
return (Iterator) iter;
}
/**
* Converts an {@link Iterator} to an {@link Iterable}
* @param type of iterator
* @param iter iterator to be converted
* @return wrapped iterator object
*/
@NN public static Iterable iter(Iterator iter){
return () -> iter;
}
/**
* Converts an {@link Enumeration} to an {@link Iterable}
* @param type of enumeration
* @param iter enumeration to be converted
* @return wrapped enumeration object
*/
@SuppressWarnings("null")
public static Iterable iter(Enumeration iter) {
return iter::asIterator;
}
//List models
/**
* Wraps the {@link ListModel} in a {@link List}, to allow Java Collections Framework operations to be used
* @param
* @param list the ListModel to be wrapped
* @return the wrapped list
*/
@NN public static List fromListModel(ListModel list){
return new AbstractList<>() {
@Override public T get(int index) {
return list.getElementAt(index);
}
@Override public int size() {
return list.getSize();
}
};
}
/**
* Wraps the list to a list model
* @param type of the list
* @param list list to wrap
* @return a list model
* @apiNote The list model does not support listeners
*/
@NN public static ListModel toListModel(List list){
return new ListModel<>() {
@Override
public void addListDataListener(@Nil ListDataListener l) {
throw new UnsupportedOperationException("ListModel from List does not support listeners");
}
@Override
public T getElementAt(int index) {
return list.get(index);
}
@Override
public int getSize() {
return list.size();
}
@Override
public void removeListDataListener(@Nil ListDataListener l) {
throw new UnsupportedOperationException("ListModel from List oes not support listeners");
}
};
}
/**
* Wraps a list model
* @param type of the list model
* @param list list model
* @return a list wrapper
*/
@NN public static List toWritableList(DefaultListModel list){
return new AbstractList<>() {
@Override
public T get(int index) {
return list.get(index);
}
@Override
public int size() {
return list.getSize();
}
@Override
public void add(int index, @Nil T element) {
list.add(index, element);
}
@Override
public boolean add(@Nil T e) {
list.addElement(e);
return true;
}
@Override
public T remove(int index) {
return list.remove(index);
}
@Override
public T set(int index, @SuppressWarnings("null") @Nil T e) {
return list.set(index, e);
}
@Override
public boolean isEmpty() {
return list.isEmpty();
}
@Override
public boolean contains(@Nil Object o) {
return list.contains(list);
}
@SuppressWarnings("null")
@Override
public @NN Iterator iterator() {
return list.elements().asIterator();
}
@SuppressWarnings("null")
@Override
public Object @NN [] toArray() {
return list.toArray();
}
@Override
public U @NN [] toArray(U[] a) {
list.copyInto(a);
return a;
}
@Override
public boolean remove(@Nil Object o) {
return list.removeElement(o);
}
@Override
public boolean containsAll(Collection> c) {
for(Object e: c) {
if(!list.contains(e)) return false;
}
return true;
}
@Override
public boolean addAll(Collection extends T> c) {
list.addAll(c);
return true;
}
@Override
public boolean addAll(int index, Collection extends T> c) {
list.addAll(index, c);
return true;
}
@Override
public boolean removeAll(Collection> c) {
boolean result = false;
for(Object e: c) {
result |= list.removeElement(e);
}
return result;
}
@Override
public boolean retainAll(Collection> c) {
List copy = new ArrayList<>(this);
boolean result = copy.retainAll(c);
list.addAll(copy);
return result;
}
@Override
public void clear() {
list.removeAllElements();
}
@Override
public int indexOf(@Nil Object o) {
return list.indexOf(o);
}
@Override
public int lastIndexOf(@Nil Object o) {
return list.lastIndexOf(o);
}
};
}
@NN public static DefaultListModel newListModel(Collection extends T> list){
DefaultListModel model = new DefaultListModel<>();
model.addAll(list);
return model;
}
//Self-sets
/**
* @param type of keys of the output set
* @param type of values of the output set
* @param set self-set to wrap
* @return an unmodifiable wrapper around the self-set
*/
@NN public static SelfSet unmodifiableSelfSet(SelfSet extends K, ? extends V> set){
return new SelfSet<>() {
@Override
public boolean add(@Nil V e) {
return false;
}
@Override
public boolean addAll(Collection extends V> c) {
throw new UnsupportedOperationException();
}
@Override
public void clear() {
throw new UnsupportedOperationException();
}
@Override
public boolean containsAll(Collection> c) {
return set.containsAll(c);
}
@Override
public boolean isEmpty() {
return set.isEmpty();
}
@Override
public Iterator iterator() {
return downcastIterator(set.iterator());
}
@Override
public boolean removeAll(Collection> c) {
throw new UnsupportedOperationException();
}
@Override
public boolean retainAll(Collection> c) {
throw new UnsupportedOperationException();
}
@Override
public int size() {
return set.size();
}
@Override
public Object[] toArray() {
return set.toArray();
}
@Override
public T[] toArray(T[] a) {
return set.toArray(a);
}
@Override
public Set keys() {
return Collections.unmodifiableSet(set.keys());
}
@Override
public Set values() {
return Collections.unmodifiableSet(set.values());
}
@Override
public V get(@Nil Object key) {
return set.get(key);
}
@SuppressWarnings("unchecked") //cast is required to accept a supertype, it will never fail
@Override
public V getOrDefault(@Nil Object key, V defalt) {
return ((SelfSet)set).getOrDefault(key, defalt);
}
@Override
public boolean removeKey(K key) {
throw new UnsupportedOperationException();
}
@Override
public boolean containsKey(@Nil Object key) {
return set.containsKey(key);
}
@Override
public boolean test(@Nil Object o) {
return set.test(o);
}
@Override
public K id(Object value) {
return set.id(value);
}
@Override
public boolean nullable() {
return set.nullable();
}
@SuppressWarnings("unchecked")
@Override
public Class type() {
return (Class) set.type();
}
};
}
//Lists
/**
* Adds the second input to the first one in-place
* @param type of elements
* @param list list to add to
* @param collect elements to be added
* @return first input
*/
@NN public static List inplaceAddLists(List list, Collection extends T> collect){
list.addAll(collect);
return list;
}
/**
* Adds two inputs out of place
* @param
* @param a first half of the list
* @param b second half of the list
* @param supplier creates lists
* @return a new list
*/
@NN public static List ooplaceAddLists(Collection extends T> a, Collection extends T> b, Supplier> supplier){
List list0 = supplier.get();
list0.addAll(a);
list0.addAll(b);
return list0;
}
/**
* Creates an out-of-place list added
* @param type of values
* @param supplier creates lists
* @return a list addition function
*/
@NN public static BiFunction<@NN Collection extends T>, @NN Collection extends T>, List> ooplaceListAdder(Supplier> supplier){
return (a, b) -> ooplaceAddLists(a, b, supplier);
}
//Multimaps
/**
* Creates an empty multimap
* @param type of keys
* @param type of values
* @return an empty, immutable multimap
*/
@SuppressWarnings("unchecked")
@NN public static SetMultimap emptyMultimap(){
return (SetMultimap) emptyMultiMap;
}
@NN private static final SetMultimap, ?> emptyMultiMap = new EmptySetMultimap();
/**
* Creates an empty multiset
* @param type of values
* @return an empty, immutable multiset
*/
@SuppressWarnings("unchecked")
@NN public static Multiset emptyMultiset(){
return (Multiset) emptyMultiSet;
}
@NN private static final Multiset> emptyMultiSet = new EmptyMultiSet();
//Maps
/**
* Creates an int-to-any map from a stream
* @param type of values
* @param type of maps
* @param mapsup creates maps
* @return an int/obj map collector
*/
@NN public static > Collector, Object2IntMap, M> collectToIntMap(Supplier mapsup){
return new IntMapCollector<>(mapsup);
}
/**
* Adds the second input to the first input
* @param type of values
* @param type of the modified map
* @param list map to be modified
* @param collect map to be added to the first input
* @return first input
*/
@NN public static > M inplaceAddIntMaps(M list, Object2IntMap extends T> collect){
list.putAll(collect);
return list;
}
//Grids
/**
* Prevents changes to a grid
* @param grid grid to prevent changes to
* @return an unmodifiable view of the input grid
*/
public static Grid unmodifiableGrid(Grid grid) {
return new Grid<>() {
@Override
public void set(int x, int y, T data) {
throw new UnsupportedOperationException();
}
@Override
public T get(int x, int y) {
return grid.get(x, y);
}
@Override
public int width() {
return grid.width();
}
@Override
public int height() {
return grid.height();
}
@SuppressWarnings("null")
@Override
public Iterator iterator() {
return Iterators.unmodifiableIterator(grid.iterator());
}
};
}
/**
* Creates a dynamically-mapped view of a grid
* @param type of the input grid
* @param type of the output grid
* @param forward forward mapper
* @param backward backward mapper
* @param grid input grid
* @return a transformed view of the grid. The view is backed by the grid, so any changes made to the original are reflected in the view and vice versa
*/
public static Grid mapGrid(Function super Tin, ? extends Tout> forward, @Nil Function super Tout, ? extends Tin> backward, Grid grid){
return new Grid<>() {
@Override
public void set(int x, int y, Tout data) {
if(backward == null) throw new UnsupportedOperationException("no backwards function");
grid.set(x, y, backward.apply(data));
}
@Override
public Tout get(int x, int y) {
return forward.apply(grid.get(x, y));
}
@Override
public int width() {
return grid.width();
}
@Override
public int height() {
return grid.height();
}
@Override
public Iterator iterator() {
Iterator iter = grid.iterator();
return new Iterator<>() {
@Override
public boolean hasNext() {
return iter.hasNext();
}
@Override
public Tout next() {
return forward.apply(iter.next());
}
@Override
public void remove() {
iter.remove();
}
};
}
};
}
//Iteration
/**
* Gets the first item using iteration
* @param c collection to get items from
* @return the first item
* @throws NoSuchElementException when there is no requested item
*/
public static T first(Iterable c) {
return c.iterator().next();
}
//All/any boolean operations
/**
* Checks if all values meet a predicate
* @param type of values
* @param collection collection to test
* @param predicate condition
* @return do all items meet a criterion?
*/
public static boolean isAll(Iterable extends T> collection, Predicate predicate) {
for(T value: collection)
if(!predicate.test(value)) return false;
return true;
}
/**
* Checks if any value meets a predicate
* @param type of values
* @param collection collection to test
* @param predicate condition
* @return does any items meet a criterion?
*/
public static boolean isAny(Iterable extends T> collection, Predicate predicate) {
for(T value: collection)
if(predicate.test(value)) return true;
return false;
}
}
class IntMapCollector> implements Collector, Object2IntMap, M>{
@NN private final Supplier mapsup;
public IntMapCollector(Supplier mapsup) {
this.mapsup = mapsup;
}
@Override
public Supplier> supplier() {
return Object2IntOpenHashMap::new;
}
@Override
public BiConsumer, Object2IntMap.Entry> accumulator() {
return (map, entry) -> map.put(entry.getKey(), entry.getIntValue());
}
@Override
public BinaryOperator> combiner() {
return Collects::inplaceAddIntMaps;
}
@SuppressWarnings("null")
@Override
public Function, M> finisher() {
return map -> {
M result = mapsup.get();
return Collects.inplaceAddIntMaps(result, map);
};
}
@Override
public Set characteristics() {
return Set.of(Characteristics.UNORDERED);
}
}
class EmptyMultiSet implements Multiset