Skip to content

Ingredient Collections

Ruben Taelman edited this page Jan 14, 2019 · 14 revisions

Using the Ingredient Components abstraction layer from CommonCapabilities, CyclopsCore introduces the Ingredient Collections API, which forms a set of interfaces and classes that make it possible to store and query ingredient component instances in a generic way.

Here's a short example of some things that are possible with this API:

IIngredientCollectionMutable<ItemStack, Integer> myCollection
    = new IngredientCollectionPrototypeMap<>(IngredientComponent.ITEMSTACK);

// Add an item to the collection
myCollection.add(new ItemStack(Items.APPLE, 1));

// The following item will stack with the previous instance
myCollection.add(new ItemStack(Items.APPLE, 1));

// The following will NOT stack, because it has a different meta value
myCollection.add(new ItemStack(Items.APPLE, 1, 1));

// Even though this is a different object, it _will_ reduce the stacksize of the internal apple.
myCollection.remove(new ItemStack(Items.APPLE, 1));

// This will return an iterator that emits all items that have the `Items.APPLE` item.
myCollection.iterator(new ItemStack(Items.APPLE, 1), ItemMatch.ITEM);

// This will return an iterator that emits all items that have the `Items.APPLE` item AND meta value 0.
myCollection.iterator(new ItemStack(Items.APPLE, 1, 0), ItemMatch.ITEM | ItemMatch.DAMAGE);

Obviously, there's much more you can do with this API. It supports different types of datastructures, compatibility with the Java Stream API, NBT serialization and other helpers, integration with the IIngredientComponentStorage interface, efficient algorithms to calculate diffs between collections, and more!

Datastructures

Two categories of datastructures exist within this API. On the one hand you have plain collections that handle ingredients as-is. On the other hand you have collections that will stack equal ingredients. These stacking collections implement the IIngredientCollapsedCollection interface.

Non-stacking collections

  • IngredientArrayList: An ingredient collection backed by an ArrayList. This is good for random-access in a collection of ingredients with a fixed order.
  • IngredientLinkedList: An ingredient collection backed by a LinkedList. This is good for iteration over collection of ingredients with a fixed order.
  • IngredientHashSet: An ingredient collection backed by a HashSet. This is good for very fast lookups by exact instance.
  • IngredientTreeSet: An ingredient collection backed by a TreeSet. This is good for fast lookups by exact instance, and efficiently maintaining a sorted collection.

Stacking collections

  • IngredientCollectionPrototypeMap: An ingredient collection backed by a mapping from ingredient prototype to its quantity. This is good for fast lookups and queries by exact instances.
  • IngredientCollectionSingleClassified: An ingredient collection that adds a single index based on a IngredientComponentCategoryType of the ingredient component. This is efficient for queries based on the given category's match condition, but requires more memory to store the index.
  • IngredientCollectionMultiClassified: Just like IngredientCollectionSingleClassified, but indexes over all category types of an ingredient component. As such, this requires even more memory, but allows efficient queries for any match condition.
  • IngredientCollectionQuantitativeGrouper: A wrapper over another ingredient collection that automatically (un)stacks instances for additions and deletions. This is less efficient, but useful if you want to quickly wrap over another already-existing ingredient collection.

Helpers

The IngredientCollections class offers several static helper methods. The most notable are the following:

  • serialize: Serializes an IIngredientCollection to NBT.
  • deserialize: Deserializes an IIngredientCollection from NBT.
  • sort: Creates an IngredientArrayList containing all instances from the given IIngredientCollection where all instances are sorted by the given comparator.

Difference Calculation

IngredientCollectionDiffHelpers provides methods to efficiently calculate the difference between two ingredient collections, and apply a difference to a mutable ingredient collection.

IngredientCollectionDiffManager is a stateful helper that allows easier continuous difference calculations. It is for example being used by the Integrated Dynamics IngredientObserver to efficiently observe the ingredients inside a network.

Clone this wiki locally