-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathIOInventory.java
More file actions
215 lines (185 loc) · 7.16 KB
/
Copy pathIOInventory.java
File metadata and controls
215 lines (185 loc) · 7.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
/*******************************************************************************
* HellFirePvP / Modular Machinery 2019
*
* This project is licensed under GNU GENERAL PUBLIC LICENSE Version 3.
* The source code is available on github: https://github.com/HellFirePvP/ModularMachinery
* For further details, see the License file there.
******************************************************************************/
package hellfirepvp.modularmachinery.common.util;
import github.kasuminova.mmce.client.util.ItemStackUtils;
import github.kasuminova.mmce.common.util.concurrent.ReadWriteLockProvider;
import hellfirepvp.modularmachinery.common.tiles.base.SelectiveUpdateTileEntity;
import hellfirepvp.modularmachinery.common.tiles.base.TileEntitySynchronized;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.MathHelper;
import net.minecraftforge.common.util.Constants;
import javax.annotation.Nonnull;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.IntConsumer;
/**
* This class is part of the Modular Machinery Mod
* The complete source code for this mod can be found on github.
* Class: IOInventory
* Created by HellFirePvP
* Date: 28.06.2017 / 17:42
*/
public class IOInventory extends IItemHandlerImpl implements ReadWriteLockProvider {
private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
private final TileEntitySynchronized owner;
// TODO IntConsumer.
private IntConsumer listener = null;
private IOInventory(TileEntitySynchronized owner) {
this.owner = owner;
}
public IOInventory(TileEntitySynchronized owner, int[] inSlots, int[] outSlots) {
this(owner, inSlots, outSlots, EnumFacing.VALUES);
}
public IOInventory(TileEntitySynchronized owner, int[] inSlots, int[] outSlots, EnumFacing... accessibleFrom) {
super(inSlots, outSlots, accessibleFrom);
this.owner = owner;
}
public static IOInventory deserialize(TileEntitySynchronized owner, NBTTagCompound tag) {
IOInventory inv = new IOInventory(owner);
inv.readNBT(tag);
return inv;
}
public IOInventory setListener(IntConsumer listener) {
this.listener = listener;
return this;
}
public TileEntitySynchronized getOwner() {
return owner;
}
@Override
public void setStackInSlot(int slot, @Nonnull ItemStack stack) {
try {
rwLock.writeLock().lock();
super.setStackInSlot(slot, stack);
notifyOwner();
if (listener != null) {
listener.accept(slot);
}
} finally {
rwLock.writeLock().unlock();
}
}
@Override
@Nonnull
public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate) {
if (stack.isEmpty()) {
return stack;
}
try {
(simulate ? rwLock.writeLock() : rwLock.readLock()).lock();
ItemStack inserted = insertItemInternal(slot, stack, simulate);
if (!simulate) {
if (listener != null) {
listener.accept(slot);
}
notifyOwner();
}
return inserted;
} finally {
(simulate ? rwLock.writeLock() : rwLock.readLock()).unlock();
}
}
@Override
@Nonnull
public ItemStack extractItem(int slot, int amount, boolean simulate) {
try {
(simulate ? rwLock.writeLock() : rwLock.readLock()).lock();
ItemStack extracted = super.extractItem(slot, amount, simulate);
if (!simulate) {
if (listener != null) {
listener.accept(slot);
}
notifyOwner();
}
return extracted;
} finally {
(simulate ? rwLock.writeLock() : rwLock.readLock()).unlock();
}
}
private void notifyOwner() {
if (owner instanceof SelectiveUpdateTileEntity) {
owner.markNoUpdateSync();
} else {
owner.markForUpdateSync();
}
}
public NBTTagCompound writeNBT() {
NBTTagCompound tag = new NBTTagCompound();
tag.setIntArray("inSlots", this.inSlots);
tag.setIntArray("outSlots", this.outSlots);
tag.setIntArray("miscSlots", this.miscSlots);
NBTTagList inv = new NBTTagList();
for (int slot = 0; slot < inventory.length; slot++) {
SlotStackHolder holder = this.inventory[slot];
NBTTagCompound holderTag = new NBTTagCompound();
ItemStack stack = holder.itemStack.get();
holderTag.setInteger("holderId", slot);
if (stack.isEmpty()) {
holderTag.setBoolean("holderEmpty", true);
} else {
ItemStackUtils.writeNBTOversize(stack, holderTag);
}
inv.appendTag(holderTag);
}
tag.setTag("inventoryArray", inv);
int[] sides = new int[accessibleSides.length];
for (int i = 0; i < accessibleSides.length; i++) {
EnumFacing side = accessibleSides[i];
sides[i] = side.ordinal();
}
tag.setIntArray("sides", sides);
return tag;
}
public void readNBT(NBTTagCompound tag) {
this.inSlots = tag.getIntArray("inSlots");
this.outSlots = tag.getIntArray("outSlots");
this.miscSlots = tag.getIntArray("miscSlots");
NBTTagList list = tag.getTagList("inventoryArray", Constants.NBT.TAG_COMPOUND);
int tagCount = list.tagCount();
this.inventory = new SlotStackHolder[tagCount];
for (int i = 0; i < tagCount; i++) {
NBTTagCompound holderTag = list.getCompoundTagAt(i);
int slot = holderTag.getInteger("holderId");
checkInventoryLength(slot);
ItemStack stack = ItemStack.EMPTY;
if (!holderTag.getBoolean("holderEmpty")) {
stack = ItemStackUtils.readNBTOversize(holderTag);
}
SlotStackHolder holder = new SlotStackHolder(slot);
holder.itemStack.set(stack);
this.inventory[slot] = holder;
}
int[] sides = tag.getIntArray("sides");
this.accessibleSides = new EnumFacing[sides.length];
for (int index = 0; index < sides.length; index++) {
final int facingIndex = sides[index];
this.accessibleSides[index] = EnumFacing.values()[facingIndex];
}
}
public int calcRedstoneFromInventory() {
int i = 0;
float f = 0.0F;
for (int j = 0; j < getSlots(); ++j) {
ItemStack itemstack = getStackInSlot(j);
if (!itemstack.isEmpty()) {
f += (float) itemstack.getCount() / (float) Math.min(getSlotLimit(j), itemstack.getMaxStackSize());
++i;
}
}
f = f / (float) getSlots();
return MathHelper.floor(f * 14.0F) + (i > 0 ? 1 : 0);
}
@Nonnull
@Override
public ReadWriteLock getRWLock() {
return rwLock;
}
}