This repository has been archived by the owner on Sep 16, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added fabricated-forge-item-api module
- Loading branch information
Showing
24 changed files
with
2,289 additions
and
0 deletions.
There are no files selected for viewing
132 changes: 132 additions & 0 deletions
132
...orge-item-api/src/main/java/net/fabricatedforgeapi/transfer/item/IItemHandlerStorage.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,132 @@ | ||
package net.fabricatedforgeapi.transfer.item; | ||
|
||
import net.fabricmc.fabric.api.transfer.v1.item.ItemVariant; | ||
import net.fabricmc.fabric.api.transfer.v1.storage.Storage; | ||
import net.fabricmc.fabric.api.transfer.v1.storage.StorageView; | ||
import net.fabricmc.fabric.api.transfer.v1.transaction.TransactionContext; | ||
import net.minecraft.world.item.ItemStack; | ||
import net.minecraftforge.items.IItemHandler; | ||
import net.minecraftforge.items.ItemHandlerHelper; | ||
|
||
import javax.annotation.Nullable; | ||
import java.util.ArrayList; | ||
import java.util.Iterator; | ||
import java.util.List; | ||
import java.util.concurrent.atomic.AtomicLong; | ||
|
||
@SuppressWarnings("UnstableApiUsage") | ||
public interface IItemHandlerStorage extends Storage<ItemVariant>, Iterable<StorageView<ItemVariant>> { | ||
IItemHandler getHandler(); | ||
|
||
@Override | ||
default long insert(ItemVariant resource, long maxAmount, TransactionContext transaction) { | ||
AtomicLong atomicLong = new AtomicLong(0); | ||
transaction.addCloseCallback((t, result) -> { | ||
if (result.wasCommitted()) { | ||
ItemStack toInsert = resource.toStack((int) maxAmount); | ||
ItemStack remainder = ItemHandlerHelper.insertItemStacked(getHandler(), toInsert, false); | ||
atomicLong.set(maxAmount - remainder.getCount()); | ||
} | ||
}); | ||
return atomicLong.get(); | ||
} | ||
|
||
@Override | ||
default long extract(ItemVariant resource, long maxAmount, TransactionContext transaction) { | ||
AtomicLong atomicLong = new AtomicLong(0); | ||
transaction.addCloseCallback((t, result) -> { | ||
if (result.wasCommitted()) { | ||
ItemStack toExtract = resource.toStack((int) maxAmount); | ||
ItemStack extracted = ItemHandlerHelper.extract(getHandler(), toExtract, false); | ||
atomicLong.set(extracted.getCount()); | ||
} | ||
}); | ||
return atomicLong.get(); | ||
} | ||
|
||
@Override | ||
default Iterable<StorageView<ItemVariant>> iterable(TransactionContext transaction) { | ||
return this; | ||
} | ||
|
||
@Override | ||
default Iterator<StorageView<ItemVariant>> iterator(TransactionContext transaction) { | ||
return iterator(); | ||
} | ||
@Override | ||
default Iterator<StorageView<ItemVariant>> iterator() { | ||
int slots = getHandler().getSlots(); | ||
List<StorageView<ItemVariant>> views = new ArrayList<>(); | ||
for (int i = 0; i < slots; i++) { | ||
views.add(new SlotStorageView(i, getHandler())); | ||
} | ||
return views.iterator(); | ||
} | ||
|
||
@Override | ||
@Nullable | ||
default StorageView<ItemVariant> exactView(TransactionContext transaction, ItemVariant resource) { | ||
for (StorageView<ItemVariant> view : this) { | ||
if (view.getResource().equals(resource)) { | ||
return view; | ||
} | ||
} | ||
return null; | ||
} | ||
|
||
//@Override | ||
@Nullable | ||
default StorageView<ItemVariant> exactView(ItemVariant resource) { | ||
for (StorageView<ItemVariant> view : this) { | ||
if (view.getResource().equals(resource)) { | ||
return view; | ||
} | ||
} | ||
return null; | ||
} | ||
|
||
class SlotStorageView implements StorageView<ItemVariant> { | ||
protected final int slotIndex; | ||
protected final IItemHandler owner; | ||
|
||
public SlotStorageView(int index, IItemHandler owner) { | ||
this.owner = owner; | ||
this.slotIndex = index; | ||
} | ||
|
||
@Override | ||
public long extract(ItemVariant resource, long maxAmount, TransactionContext transaction) { | ||
long actual = 0; | ||
ItemStack extracted = owner.extractItem(slotIndex, (int) maxAmount, true); | ||
if (extracted.is(resource.getItem())) { | ||
actual = extracted.getCount(); | ||
transaction.addCloseCallback((t, result) -> { | ||
if (result.wasCommitted()) { | ||
owner.extractItem(slotIndex, (int) maxAmount, false); | ||
} | ||
}); | ||
} | ||
return actual; | ||
} | ||
|
||
@Override | ||
public boolean isResourceBlank() { | ||
return owner.getStackInSlot(slotIndex).isEmpty(); | ||
} | ||
|
||
@Override | ||
public ItemVariant getResource() { | ||
return ItemVariant.of(owner.getStackInSlot(slotIndex)); | ||
} | ||
|
||
@Override | ||
public long getAmount() { | ||
return owner.getStackInSlot(slotIndex).getCount(); | ||
} | ||
|
||
@Override | ||
public long getCapacity() { | ||
return owner.getSlotLimit(slotIndex); | ||
} | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
...forge-item-api/src/main/java/net/fabricatedforgeapi/transfer/item/ItemHandlerStorage.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,28 @@ | ||
package net.fabricatedforgeapi.transfer.item; | ||
|
||
import net.minecraftforge.items.IItemHandler; | ||
import net.minecraftforge.items.wrapper.EmptyHandler; | ||
|
||
import javax.annotation.Nonnull; | ||
import javax.annotation.Nullable; | ||
|
||
@SuppressWarnings("UnstableApiUsage") | ||
public class ItemHandlerStorage implements IItemHandlerStorage { | ||
@Nonnull | ||
protected IItemHandler handler; | ||
|
||
public ItemHandlerStorage(@Nullable IItemHandler handler) { | ||
if (handler == null) { | ||
this.handler = EmptyHandler.INSTANCE; | ||
} else { | ||
this.handler = handler; | ||
} | ||
} | ||
|
||
@Override | ||
@Nonnull | ||
public IItemHandler getHandler() { | ||
return handler; | ||
} | ||
|
||
} |
161 changes: 161 additions & 0 deletions
161
...forge-item-api/src/main/java/net/fabricatedforgeapi/transfer/item/ItemStorageHandler.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,161 @@ | ||
package net.fabricatedforgeapi.transfer.item; | ||
|
||
import net.fabricmc.fabric.api.transfer.v1.item.ItemVariant; | ||
import net.fabricmc.fabric.api.transfer.v1.storage.Storage; | ||
import net.fabricmc.fabric.api.transfer.v1.storage.StorageView; | ||
import net.fabricmc.fabric.api.transfer.v1.transaction.Transaction; | ||
import net.minecraft.world.item.ItemStack; | ||
import net.minecraftforge.items.IItemHandlerModifiable; | ||
import net.minecraftforge.items.ItemHandlerHelper; | ||
import org.jetbrains.annotations.NotNull; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Iterator; | ||
import java.util.List; | ||
|
||
@SuppressWarnings("UnstableApiUsage") | ||
public class ItemStorageHandler implements IItemHandlerModifiable { | ||
protected final Storage<ItemVariant> storage; | ||
protected long version; | ||
protected int slots; | ||
protected ItemStack[] stacks; | ||
protected Long[] capacities; | ||
|
||
public ItemStorageHandler(Storage<ItemVariant> storage) { | ||
this.storage = storage; | ||
this.version = storage.getVersion(); | ||
updateContents(); | ||
} | ||
|
||
public boolean shouldUpdate() { | ||
return storage.getVersion() != version; | ||
} | ||
|
||
private void updateContents() { | ||
List<ItemStack> stacks = new ArrayList<>(); | ||
List<Long> capacities = new ArrayList<>(); | ||
try (Transaction t = Transaction.openOuter()) { | ||
for (StorageView<ItemVariant> view : storage.iterable(t)) { | ||
stacks.add(view.getResource().toStack((int) view.getAmount())); | ||
capacities.add(view.getCapacity()); | ||
} | ||
t.abort(); | ||
} | ||
this.stacks = stacks.toArray(ItemStack[]::new); | ||
this.capacities = capacities.toArray(Long[]::new); | ||
this.slots = stacks.size(); | ||
this.version = storage.getVersion(); | ||
} | ||
|
||
private boolean validIndex(int slot) { | ||
return slot >= 0 && slot < slots; | ||
} | ||
|
||
@Override | ||
public int getSlots() { | ||
if (shouldUpdate()) | ||
updateContents(); | ||
return slots; | ||
} | ||
|
||
@NotNull | ||
@Override | ||
public ItemStack getStackInSlot(int slot) { | ||
if (validIndex(slot)) { | ||
if (shouldUpdate()) | ||
updateContents(); | ||
return stacks[slot].copy(); | ||
} | ||
return ItemStack.EMPTY; | ||
} | ||
|
||
@NotNull | ||
@Override | ||
public ItemStack insertItem(int slot, ItemStack stack, boolean sim) { | ||
if (!validIndex(slot)) // first check valid slot index | ||
return stack; | ||
if (stack.isEmpty()) // check stack is not empty | ||
return stack; | ||
if (!isItemValid(slot, stack)) // make sure this stack can be stored | ||
return stack; | ||
if (!storage.supportsInsertion()) // make sure insertion is supported | ||
return stack; | ||
ItemStack current = getStackInSlot(slot); | ||
int limit = Math.min(getSlotLimit(slot), current.getMaxStackSize()); | ||
if (limit <= 0 || !ItemHandlerHelper.canItemStacksStack(current, stack)) // make sure there's room | ||
return stack; | ||
// finally insert | ||
ItemStack finalVal = ItemStack.EMPTY; | ||
try (Transaction t = Transaction.openOuter()) { | ||
// this technically breaks spec and ignores 'slot' but thanks FAPI, we literally have no choice! | ||
long remainder = stack.getCount() - storage.insert(ItemVariant.of(stack), stack.getCount(), t); | ||
if (remainder != 0) { | ||
finalVal = new ItemStack(stack.getItem(), (int) remainder); | ||
} | ||
|
||
if (sim) t.abort(); | ||
else { | ||
t.commit(); | ||
if (shouldUpdate()) | ||
updateContents(); | ||
} | ||
} | ||
return finalVal; | ||
} | ||
|
||
@NotNull | ||
@Override | ||
public ItemStack extractItem(int slot, int amount, boolean sim) { | ||
if (amount <= 0) | ||
return ItemStack.EMPTY; | ||
if (!validIndex(slot)) // check valid slot index | ||
return ItemStack.EMPTY; | ||
if (!storage.supportsExtraction()) // make sure insertion is supported | ||
return ItemStack.EMPTY; | ||
|
||
ItemStack finalVal = ItemStack.EMPTY; | ||
try (Transaction t = Transaction.openOuter()) { | ||
int index = 0; | ||
for (StorageView<ItemVariant> view : storage.iterable(t)) { | ||
if (index == slot) { | ||
ItemVariant variant = view.getResource(); | ||
long extracted = view.isResourceBlank() ? 0 : view.extract(variant, amount, t); | ||
if (extracted != 0) { | ||
finalVal = variant.toStack((int) extracted); | ||
} | ||
break; | ||
} | ||
index++; | ||
} | ||
if (sim) t.abort(); | ||
else { | ||
t.commit(); | ||
if (shouldUpdate()) | ||
updateContents(); | ||
} | ||
} | ||
return finalVal; | ||
} | ||
|
||
@Override | ||
public int getSlotLimit(int slot) { | ||
if (validIndex(slot)) { | ||
if (shouldUpdate()) | ||
updateContents(); | ||
return (int) (long) capacities[slot]; | ||
} | ||
return 0; | ||
} | ||
|
||
@Override | ||
public boolean isItemValid(int slot, ItemStack stack) { | ||
return true; | ||
} | ||
|
||
@Override | ||
public void setStackInSlot(int slot, ItemStack stack) { | ||
// jank | ||
extractItem(slot, getSlotLimit(slot), false); | ||
insertItem(slot, stack, false); | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
fabricated-forge-item-api/src/main/java/net/minecraftforge/common/util/INBTSerializable.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,18 @@ | ||
/* | ||
* Copyright (c) Forge Development LLC and contributors | ||
* SPDX-License-Identifier: LGPL-2.1-only | ||
*/ | ||
|
||
package net.minecraftforge.common.util; | ||
|
||
import net.minecraft.nbt.Tag; | ||
|
||
/** | ||
* An interface designed to unify various things in the Minecraft | ||
* code base that can be serialized to and from a NBT tag. | ||
*/ | ||
public interface INBTSerializable<T extends Tag> { | ||
T serializeNBT(); | ||
|
||
void deserializeNBT(T nbt); | ||
} |
Oops, something went wrong.