Skip to content

Commit dceaecb

Browse files
committed
tick更新库存
1 parent e53bdff commit dceaecb

9 files changed

Lines changed: 62 additions & 122 deletions

File tree

src/main/java/com/xinyihl/functionalstoragelegacy/common/integration/ae2/AE2CapabilityHelper.java

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,7 @@ public static boolean isStorageAccessor(Capability<?> capability) {
2727

2828
@SuppressWarnings("unchecked")
2929
public static <T> T castAccessor(IStorageMonitorableAccessor accessor) {
30-
return Capabilities.STORAGE_MONITORABLE_ACCESSOR.cast(accessor);
31-
}
32-
33-
public static void notifyChange(Object accessor) {
34-
if (accessor instanceof DrawerStorageAccessor) {
35-
((DrawerStorageAccessor) accessor).notifyChange();
36-
}
30+
return (T) Capabilities.STORAGE_MONITORABLE_ACCESSOR.cast(accessor);
3731
}
3832

3933
public static Object createAccessor(ControllableDrawerTile tile) {

src/main/java/com/xinyihl/functionalstoragelegacy/common/integration/ae2/AE2Compat.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,4 @@ public static boolean isStorageAccessorCapability(Capability<?> capability) {
2626
public static Object createAccessor(ControllableDrawerTile tile) {
2727
return AE2CapabilityHelper.createAccessor(tile);
2828
}
29-
30-
public static void notifyChange(Object accessor) {
31-
AE2CapabilityHelper.notifyChange(accessor);
32-
}
3329
}

src/main/java/com/xinyihl/functionalstoragelegacy/common/integration/ae2/DrawerMEMonitor.java

Lines changed: 59 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -3,116 +3,103 @@
33
import appeng.api.config.AccessRestriction;
44
import appeng.api.config.Actionable;
55
import appeng.api.networking.security.IActionSource;
6+
import appeng.api.networking.ticking.TickRateModulation;
67
import appeng.api.storage.IMEInventoryHandler;
78
import appeng.api.storage.IMEMonitor;
89
import appeng.api.storage.IMEMonitorHandlerReceiver;
910
import appeng.api.storage.IStorageChannel;
1011
import appeng.api.storage.data.IAEStack;
1112
import appeng.api.storage.data.IItemList;
13+
import appeng.me.storage.ITickingMonitor;
1214

1315
import java.util.*;
1416

1517
/**
1618
* Generic IMEMonitor implementation wrapping an IMEInventoryHandler.
17-
* Manages change listeners for AE2 network notifications.
18-
* Supports detecting external inventory changes via {@link #forceUpdate()}.
19+
* Implements ITickingMonitor so AE2 storage bus can poll for external changes
20+
* (e.g. hopper, pipe, player interaction) via periodic onTick() calls.
21+
* Pattern follows AE2's ItemHandlerAdapter + InventoryCache approach.
1922
*/
20-
public class DrawerMEMonitor<T extends IAEStack<T>> implements IMEMonitor<T> {
23+
public class DrawerMEMonitor<T extends IAEStack<T>> implements IMEMonitor<T>, ITickingMonitor {
2124

2225
private final IMEInventoryHandler<T> handler;
2326
private final IStorageChannel<T> channel;
2427
private final Map<IMEMonitorHandlerReceiver<T>, Object> listeners = new HashMap<>();
28+
private IActionSource mySource;
2529
private IItemList<T> cachedList;
26-
private boolean suppressExternalNotify = false;
2730

2831
public DrawerMEMonitor(IMEInventoryHandler<T> handler, IStorageChannel<T> channel) {
2932
this.handler = handler;
3033
this.channel = channel;
34+
this.cachedList = channel.createList();
35+
handler.getAvailableItems(this.cachedList);
3136
}
3237

38+
// ---- ITickingMonitor ----
39+
40+
@Override
41+
public TickRateModulation onTick() {
42+
IItemList<T> currentList = channel.createList();
43+
handler.getAvailableItems(currentList);
44+
45+
// Compute diff: negate cached, add current, collect non-zero
46+
for (T cached : cachedList) {
47+
cached.setStackSize(-cached.getStackSize());
48+
}
49+
for (T current : currentList) {
50+
cachedList.add(current);
51+
}
52+
53+
List<T> changes = new ArrayList<>();
54+
for (T entry : cachedList) {
55+
if (entry.getStackSize() != 0) {
56+
changes.add(entry);
57+
}
58+
}
59+
60+
cachedList = currentList;
61+
62+
if (!changes.isEmpty()) {
63+
postDifference(changes);
64+
return TickRateModulation.URGENT;
65+
}
66+
return TickRateModulation.SLOWER;
67+
}
68+
69+
@Override
70+
public void setActionSource(IActionSource source) {
71+
this.mySource = source;
72+
}
73+
74+
// ---- IMEInventory ----
75+
3376
@Override
3477
public T injectItems(T input, Actionable type, IActionSource src) {
35-
suppressExternalNotify = true;
3678
T result = handler.injectItems(input, type, src);
37-
suppressExternalNotify = false;
3879
if (type == Actionable.MODULATE) {
3980
long injected = input.getStackSize() - (result != null ? result.getStackSize() : 0);
4081
if (injected > 0) {
4182
T diff = input.copy();
4283
diff.setStackSize(injected);
43-
notifyListeners(diff, src);
84+
cachedList.add(diff);
85+
postDifference(Collections.singletonList(diff));
4486
}
45-
refreshCache();
4687
}
4788
return result;
4889
}
4990

5091
@Override
5192
public T extractItems(T request, Actionable mode, IActionSource src) {
52-
suppressExternalNotify = true;
5393
T result = handler.extractItems(request, mode, src);
54-
suppressExternalNotify = false;
5594
if (mode == Actionable.MODULATE && result != null) {
5695
T diff = result.copy();
5796
diff.setStackSize(-result.getStackSize());
58-
notifyListeners(diff, src);
59-
refreshCache();
97+
cachedList.add(diff);
98+
postDifference(Collections.singletonList(diff));
6099
}
61100
return result;
62101
}
63102

64-
/**
65-
* Detect external inventory changes (e.g. hopper, pipe, player interaction)
66-
* by comparing current state against cached snapshot.
67-
* Called from the tile entity when the underlying inventory changes.
68-
*/
69-
public void forceUpdate() {
70-
if (suppressExternalNotify || listeners.isEmpty()) return;
71-
72-
IItemList<T> currentList = channel.createList();
73-
handler.getAvailableItems(currentList);
74-
75-
if (cachedList == null) {
76-
cachedList = currentList;
77-
return;
78-
}
79-
80-
List<T> changes = new ArrayList<>();
81-
82-
// Find increases and new items
83-
for (T current : currentList) {
84-
T old = cachedList.findPrecise(current);
85-
long oldSize = old != null ? old.getStackSize() : 0;
86-
long diff = current.getStackSize() - oldSize;
87-
if (diff != 0) {
88-
T change = current.copy();
89-
change.setStackSize(diff);
90-
changes.add(change);
91-
}
92-
}
93-
94-
// Find removed items
95-
for (T old : cachedList) {
96-
T current = currentList.findPrecise(old);
97-
if (current == null) {
98-
T change = old.copy();
99-
change.setStackSize(-old.getStackSize());
100-
changes.add(change);
101-
}
102-
}
103-
104-
cachedList = currentList;
105-
106-
if (!changes.isEmpty()) {
107-
postChanges(changes, null);
108-
}
109-
}
110-
111-
private void refreshCache() {
112-
cachedList = channel.createList();
113-
handler.getAvailableItems(cachedList);
114-
}
115-
116103
@Override
117104
public IItemList<T> getAvailableItems(IItemList<T> out) {
118105
return handler.getAvailableItems(out);
@@ -121,16 +108,16 @@ public IItemList<T> getAvailableItems(IItemList<T> out) {
121108
@Override
122109
public IItemList<T> getStorageList() {
123110
IItemList<T> list = channel.createList();
124-
getAvailableItems(list);
125-
refreshCache();
126-
return list;
111+
return getAvailableItems(list);
127112
}
128113

129114
@Override
130115
public IStorageChannel<T> getChannel() {
131116
return channel;
132117
}
133118

119+
// ---- IMEInventoryHandler delegated ----
120+
134121
@Override
135122
public AccessRestriction getAccess() {
136123
return handler.getAccess();
@@ -161,6 +148,8 @@ public boolean validForPass(int pass) {
161148
return handler.validForPass(pass);
162149
}
163150

151+
// ---- IBaseMonitor ----
152+
164153
@Override
165154
public void addListener(IMEMonitorHandlerReceiver<T> l, Object verificationToken) {
166155
listeners.put(l, verificationToken);
@@ -171,18 +160,15 @@ public void removeListener(IMEMonitorHandlerReceiver<T> l) {
171160
listeners.remove(l);
172161
}
173162

174-
private void notifyListeners(T changed, IActionSource src) {
175-
if (changed == null) return;
176-
postChanges(Collections.singletonList(changed), src);
177-
}
163+
// ---- Internal ----
178164

179-
private void postChanges(Iterable<T> changes, IActionSource src) {
165+
private void postDifference(Iterable<T> changes) {
180166
Iterator<Map.Entry<IMEMonitorHandlerReceiver<T>, Object>> it = listeners.entrySet().iterator();
181167
while (it.hasNext()) {
182168
Map.Entry<IMEMonitorHandlerReceiver<T>, Object> entry = it.next();
183169
IMEMonitorHandlerReceiver<T> receiver = entry.getKey();
184170
if (receiver.isValid(entry.getValue())) {
185-
receiver.postChange(this, changes, src);
171+
receiver.postChange(this, changes, mySource);
186172
} else {
187173
it.remove();
188174
}

src/main/java/com/xinyihl/functionalstoragelegacy/common/integration/ae2/DrawerStorageAccessor.java

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,4 @@ public <T extends IAEStack<T>> IMEMonitor<T> getInventory(IStorageChannel<T> sto
4242
}
4343
};
4444
}
45-
46-
/**
47-
* Notify the AE2 monitors that the underlying inventory has changed externally.
48-
* Called when items/fluids are inserted or extracted outside of the ME system.
49-
*/
50-
public void notifyChange() {
51-
if (itemMonitor != null) itemMonitor.forceUpdate();
52-
if (fluidMonitor != null) fluidMonitor.forceUpdate();
53-
}
5445
}

src/main/java/com/xinyihl/functionalstoragelegacy/common/tile/EnderDrawerTile.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ public void update() {
5252

5353
if (storage != null && storage.needUpdate()) {
5454
sendUpdatePacket();
55-
onInventoryContentsChanged();
5655
}
5756
}
5857
}

src/main/java/com/xinyihl/functionalstoragelegacy/common/tile/FluidDrawerTile.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ private BigFluidHandler createFluidHandler() {
4646
public void onChange() {
4747
FluidDrawerTile.this.markDirty();
4848
FluidDrawerTile.this.sendUpdatePacket();
49-
FluidDrawerTile.this.onInventoryContentsChanged();
5049
}
5150

5251
@Override

src/main/java/com/xinyihl/functionalstoragelegacy/common/tile/WoodDrawerTile.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ private BigInventoryHandler createHandler() {
5151
public void onChange() {
5252
WoodDrawerTile.this.markDirty();
5353
WoodDrawerTile.this.sendUpdatePacket();
54-
WoodDrawerTile.this.onInventoryContentsChanged();
5554
}
5655

5756
@Override

src/main/java/com/xinyihl/functionalstoragelegacy/common/tile/base/ControllableDrawerTile.java

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44
import com.xinyihl.functionalstoragelegacy.api.UpgradeState;
55
import com.xinyihl.functionalstoragelegacy.api.upgrade.ModifierType;
66
import com.xinyihl.functionalstoragelegacy.client.render.DrawerOptions;
7-
import com.xinyihl.functionalstoragelegacy.common.integration.ae2.AE2Compat;
87
import com.xinyihl.functionalstoragelegacy.common.item.ConfigurationToolItem;
98
import com.xinyihl.functionalstoragelegacy.common.item.upgrade.StorageUpgradeItem;
109
import com.xinyihl.functionalstoragelegacy.common.item.upgrade.UpgradeItem;
1110
import com.xinyihl.functionalstoragelegacy.common.item.upgrade.UtilityUpgradeItem;
11+
import com.xinyihl.functionalstoragelegacy.common.integration.ae2.AE2Compat;
12+
import com.xinyihl.functionalstoragelegacy.misc.Configurations;
1213
import com.xinyihl.functionalstoragelegacy.misc.RegistrationHandler;
1314
import com.xinyihl.functionalstoragelegacy.util.ItemUtil;
1415
import net.minecraft.block.state.IBlockState;
@@ -570,30 +571,6 @@ public void invalidateAE2Accessor() {
570571
ae2Accessor = null;
571572
}
572573

573-
/**
574-
* Notify the AE2 monitor that the underlying inventory has changed.
575-
* Safe to call even when AE2 is not loaded.
576-
*/
577-
public void notifyAE2Change() {
578-
if (ae2Accessor != null && AE2Compat.isLoaded()) {
579-
AE2Compat.notifyChange(ae2Accessor);
580-
}
581-
}
582-
583-
/**
584-
* Called when the drawer's inventory contents change.
585-
* Notifies both this tile's AE2 monitor and the controller's monitor (if connected).
586-
*/
587-
protected void onInventoryContentsChanged() {
588-
notifyAE2Change();
589-
if (controllerPos != null && world != null && world.isBlockLoaded(controllerPos)) {
590-
TileEntity te = world.getTileEntity(controllerPos);
591-
if (te instanceof ControllableDrawerTile) {
592-
((ControllableDrawerTile) te).notifyAE2Change();
593-
}
594-
}
595-
}
596-
597574
/**
598575
* Get the item handler for this drawer (for capability).
599576
*/

src/main/java/com/xinyihl/functionalstoragelegacy/common/tile/compact/CompactingDrawerTile.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ protected CompactingInventoryHandler createHandler(int slots) {
5050
public void onChange() {
5151
CompactingDrawerTile.this.markDirty();
5252
CompactingDrawerTile.this.sendUpdatePacket();
53-
CompactingDrawerTile.this.onInventoryContentsChanged();
5453
}
5554

5655
@Override

0 commit comments

Comments
 (0)