-
-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Port large and indexed inventory to common
- Loading branch information
1 parent
394e3be
commit e3219e9
Showing
5 changed files
with
237 additions
and
0 deletions.
There are no files selected for viewing
33 changes: 33 additions & 0 deletions
33
loader-common/src/main/java/org/cyclops/cyclopscore/datastructure/WrappedIntIterator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package org.cyclops.cyclopscore.datastructure; | ||
|
||
import it.unimi.dsi.fastutil.ints.IntIterator; | ||
|
||
import java.util.PrimitiveIterator; | ||
|
||
/** | ||
* @author rubensworks | ||
*/ | ||
public class WrappedIntIterator implements PrimitiveIterator.OfInt { | ||
|
||
private final IntIterator it; | ||
|
||
public WrappedIntIterator(IntIterator it) { | ||
this.it = it; | ||
} | ||
|
||
@Override | ||
public int nextInt() { | ||
return it.nextInt(); | ||
} | ||
|
||
@Override | ||
public boolean hasNext() { | ||
return it.hasNext(); | ||
} | ||
|
||
@Override | ||
public Integer next() { | ||
return it.next(); | ||
} | ||
|
||
} |
137 changes: 137 additions & 0 deletions
137
loader-common/src/main/java/org/cyclops/cyclopscore/inventory/IndexedInventoryCommon.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
package org.cyclops.cyclopscore.inventory; | ||
|
||
import com.google.common.collect.Maps; | ||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; | ||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; | ||
import it.unimi.dsi.fastutil.ints.IntAVLTreeSet; | ||
import it.unimi.dsi.fastutil.ints.IntSet; | ||
import net.minecraft.core.HolderLookup; | ||
import net.minecraft.nbt.CompoundTag; | ||
import net.minecraft.world.item.Item; | ||
import net.minecraft.world.item.ItemStack; | ||
import org.cyclops.cyclopscore.datastructure.WrappedIntIterator; | ||
|
||
import java.util.Map; | ||
import java.util.PrimitiveIterator; | ||
|
||
/** | ||
* An inventory that adds an index from item to slot on a regular inventory. | ||
* @author rubensworks | ||
* | ||
*/ | ||
public class IndexedInventoryCommon extends LargeInventoryCommon { | ||
|
||
private final Map<Item, Int2ObjectMap<ItemStack>> index = Maps.newIdentityHashMap(); | ||
private IntSet emptySlots; | ||
private IntSet nonEmptySlots; | ||
|
||
/** | ||
* Default constructor for NBT persistence, don't call this yourself. | ||
*/ | ||
public IndexedInventoryCommon() { | ||
this(0, 0); | ||
} | ||
|
||
/** | ||
* Make a new instance. | ||
* @param size The amount of slots in the inventory. | ||
* @param stackLimit The stack limit for each slot. | ||
*/ | ||
public IndexedInventoryCommon(int size, int stackLimit) { | ||
super(size, stackLimit); | ||
this.emptySlots = new IntAVLTreeSet(); | ||
this.nonEmptySlots = new IntAVLTreeSet(); | ||
createIndex(); | ||
} | ||
|
||
protected void createIndex() { | ||
this.index.clear(); | ||
this.nonEmptySlots.clear(); | ||
this.emptySlots.clear(); | ||
for (int i = 0; i < getContainerSize(); i++) { | ||
ItemStack itemStack = getItem(i); | ||
if (!itemStack.isEmpty()) { | ||
Int2ObjectMap<ItemStack> stacks = index.get(itemStack.getItem()); | ||
if (stacks == null) { | ||
stacks = new Int2ObjectOpenHashMap<>(); | ||
index.put(itemStack.getItem(), stacks); | ||
} | ||
stacks.put(i, itemStack); | ||
this.nonEmptySlots.add(i); | ||
} else { | ||
this.emptySlots.add(i); | ||
} | ||
} | ||
} | ||
|
||
@Override | ||
public void readFromNBT(HolderLookup.Provider provider, CompoundTag data, String tag) { | ||
super.readFromNBT(provider, data, tag); | ||
createIndex(); | ||
} | ||
|
||
@Override | ||
public void setItem(int slotId, ItemStack itemStack) { | ||
// Update index | ||
ItemStack oldStack = getItem(slotId); | ||
boolean wasEmpty = oldStack.isEmpty(); | ||
boolean isEmpty = itemStack.isEmpty(); | ||
if (!oldStack.isEmpty()) { | ||
Int2ObjectMap<ItemStack> stacks = index.get(oldStack.getItem()); | ||
if (stacks != null) { | ||
stacks.remove(slotId); | ||
} | ||
if (stacks.isEmpty()) { | ||
index.remove(oldStack.getItem()); | ||
} | ||
} | ||
if (!itemStack.isEmpty()) { | ||
Int2ObjectMap<ItemStack> stacks = index.get(itemStack.getItem()); | ||
if (stacks == null) { | ||
stacks = new Int2ObjectOpenHashMap<>(); | ||
index.put(itemStack.getItem(), stacks); | ||
} | ||
stacks.put(slotId, itemStack); | ||
} | ||
|
||
// Call super | ||
super.setItem(slotId, itemStack); | ||
|
||
// Update first and last values | ||
if (wasEmpty && !isEmpty) { | ||
this.emptySlots.remove(slotId); | ||
this.nonEmptySlots.add(slotId); | ||
} | ||
if (!wasEmpty && isEmpty) { | ||
this.emptySlots.add(slotId); | ||
this.nonEmptySlots.remove(slotId); | ||
} | ||
|
||
// This is unit-tested, so this *should not* be able to happen. | ||
// If it happens, trigger a crash! | ||
if (this.nonEmptySlots.size() + this.emptySlots.size() != getContainerSize()) throw new IllegalStateException(String.format( | ||
"Indexed inventory at inconsistent state %s %s %s (slot: %s).", this.nonEmptySlots, this.emptySlots, this.getContainerSize(), slotId)); | ||
} | ||
|
||
@Override | ||
public void clearContent() { | ||
super.clearContent(); | ||
index.clear(); | ||
} | ||
|
||
public int getInventoryReferenceStackLimit() { | ||
return getMaxStackSize(); | ||
} | ||
|
||
public Map<Item, Int2ObjectMap<ItemStack>> getIndex() { | ||
return index; | ||
} | ||
|
||
public PrimitiveIterator.OfInt getEmptySlots() { | ||
return new WrappedIntIterator(this.emptySlots.iterator()); | ||
} | ||
|
||
public PrimitiveIterator.OfInt getNonEmptySlots() { | ||
return new WrappedIntIterator(this.nonEmptySlots.iterator()); | ||
} | ||
} |
65 changes: 65 additions & 0 deletions
65
loader-common/src/main/java/org/cyclops/cyclopscore/inventory/LargeInventoryCommon.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package org.cyclops.cyclopscore.inventory; | ||
|
||
import net.minecraft.core.HolderLookup; | ||
import net.minecraft.nbt.CompoundTag; | ||
import net.minecraft.nbt.ListTag; | ||
import net.minecraft.nbt.Tag; | ||
import net.minecraft.world.item.ItemStack; | ||
|
||
/** | ||
* A large inventory implementation. | ||
* @author rubensworks | ||
* | ||
*/ | ||
public class LargeInventoryCommon extends SimpleInventoryCommon { | ||
|
||
/** | ||
* Default constructor for NBT persistence, don't call this yourself. | ||
*/ | ||
public LargeInventoryCommon() { | ||
this(0, 0); | ||
} | ||
|
||
/** | ||
* Make a new instance. | ||
* @param size The amount of slots in the inventory. | ||
* @param stackLimit The stack limit for each slot. | ||
*/ | ||
public LargeInventoryCommon(int size, int stackLimit) { | ||
super(size, stackLimit); | ||
} | ||
|
||
public void readFromNBT(HolderLookup.Provider provider, CompoundTag data, String tag) { | ||
ListTag nbttaglist = data.getList(tag, Tag.TAG_COMPOUND); | ||
|
||
for (int j = 0; j < getContainerSize(); ++j) | ||
contents[j] = ItemStack.EMPTY; | ||
|
||
for (int j = 0; j < nbttaglist.size(); ++j) { | ||
CompoundTag slot = nbttaglist.getCompound(j); | ||
int index; | ||
if (slot.contains("index")) { | ||
index = slot.getInt("index"); | ||
} else { | ||
index = slot.getInt("Slot"); | ||
} | ||
if (index >= 0 && index < getContainerSize()) { | ||
contents[index] = ItemStack.parseOptional(provider, slot); | ||
} | ||
} | ||
} | ||
|
||
public void writeToNBT(HolderLookup.Provider provider, CompoundTag data, String tag) { | ||
ListTag slots = new ListTag(); | ||
for (int index = 0; index < getContainerSize(); ++index) { | ||
ItemStack itemStack = getItem(index); | ||
if (!itemStack.isEmpty() && itemStack.getCount() > 0) { | ||
CompoundTag slot = new CompoundTag(); | ||
slot.putInt("Slot", index); | ||
slots.add(itemStack.save(provider, slot)); | ||
} | ||
} | ||
data.put(tag, slots); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters