Skip to content

Commit

Permalink
Update AE2, remove method handles from decompression service
Browse files Browse the repository at this point in the history
  • Loading branch information
62832 committed Aug 5, 2023
1 parent 47e7764 commit d6345f7
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 96 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
package gripe._90.megacells.service;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.invoke.VarHandle;
import java.util.Collections;
import java.util.List;
import java.util.Set;
Expand All @@ -15,132 +11,72 @@

import net.minecraft.world.item.ItemStack;

import appeng.api.implementations.blockentities.IChestOrDrive;
import appeng.api.networking.IGridNode;
import appeng.api.networking.IGridService;
import appeng.api.networking.IGridServiceProvider;
import appeng.api.stacks.AEItemKey;
import appeng.api.storage.MEStorage;
import appeng.api.storage.cells.StorageCell;
import appeng.blockentity.storage.ChestBlockEntity;
import appeng.blockentity.storage.DriveBlockEntity;
import appeng.me.storage.DelegatingMEInventory;
import appeng.me.storage.DriveWatcher;

import gripe._90.megacells.crafting.DecompressionPatternEncoding;
import gripe._90.megacells.definition.MEGAItems;
import gripe._90.megacells.item.cell.BulkCellInventory;

public class DecompressionService implements IGridService, IGridServiceProvider {
private static final VarHandle CHEST_MONITOR_HANDLE;
private static final VarHandle CHEST_CELL_HANDLE;
private static final MethodHandle DRIVE_DELEGATE_HANDLE;
private static final VarHandle DRIVE_WATCHERS_HANDLE;

static {
try {
var lookup = MethodHandles.lookup();

var chestMonitor = Class.forName("appeng.blockentity.storage.ChestBlockEntity$ChestMonitorHandler");
CHEST_MONITOR_HANDLE = MethodHandles.privateLookupIn(ChestBlockEntity.class, lookup)
.findVarHandle(ChestBlockEntity.class, "cellHandler", chestMonitor);
CHEST_CELL_HANDLE = MethodHandles.privateLookupIn(chestMonitor, lookup)
.findVarHandle(chestMonitor, "cellInventory", StorageCell.class);

DRIVE_WATCHERS_HANDLE = MethodHandles.privateLookupIn(DriveBlockEntity.class, lookup)
.findVarHandle(DriveBlockEntity.class, "invBySlot", DriveWatcher[].class);
DRIVE_DELEGATE_HANDLE = MethodHandles.privateLookupIn(DelegatingMEInventory.class, lookup)
.findVirtual(DelegatingMEInventory.class, "getDelegate", MethodType.methodType(MEStorage.class));
} catch (NoSuchFieldException | NoSuchMethodException | ClassNotFoundException | IllegalAccessException e) {
throw new RuntimeException("Failed to create DecompressionService method handles", e);
}
}

private final Set<Object2IntMap<AEItemKey>> decompressionChains = new ObjectLinkedOpenHashSet<>();
private final List<ChestBlockEntity> chests = new ObjectArrayList<>();
private final List<DriveBlockEntity> drives = new ObjectArrayList<>();
private final List<IChestOrDrive> cellHosts = new ObjectArrayList<>();

@Override
public void addNode(IGridNode node) {
if (node.getOwner() instanceof ChestBlockEntity chest) {
chests.add(chest);
}

if (node.getOwner() instanceof DriveBlockEntity drive) {
drives.add(drive);
if (node.getOwner() instanceof IChestOrDrive cellHost) {
cellHosts.add(cellHost);
}
}

@Override
public void removeNode(IGridNode node) {
if (node.getOwner() instanceof ChestBlockEntity chest) {
chests.remove(chest);
}

if (node.getOwner() instanceof DriveBlockEntity drive) {
drives.remove(drive);
if (node.getOwner() instanceof IChestOrDrive cellHost) {
cellHosts.remove(cellHost);
}
}

@Override
public void onServerStartTick() {
decompressionChains.clear();

try {
for (var chest : chests) {
addChain(getCellByChest(chest));
}
for (var cellHost : cellHosts) {
for (int i = 0; i < cellHost.getCellCount(); i++) {
var cell = cellHost.getOriginalCellInventory(i);

if (!(cell instanceof BulkCellInventory bulkCell)) {
continue;
}

for (var drive : drives) {
for (int i = 0; i < drive.getCellCount(); i++) {
addChain(getCellByDriveSlot(drive, i));
if (bulkCell.isCompressionEnabled()) {
addChain(bulkCell);
}
}
} catch (Throwable e) {
throw new RuntimeException("Failed to invoke DecompressionService method handles", e);
}
}

private StorageCell getCellByChest(ChestBlockEntity chest) {
var monitor = CHEST_MONITOR_HANDLE.get(chest);
return monitor != null ? (StorageCell) CHEST_CELL_HANDLE.get(monitor) : null;
}
private void addChain(BulkCellInventory cell) {
var chain = CompressionService.INSTANCE
.getChain(cell.getStoredItem())
.map(c -> {
var keys = new ObjectArrayList<>(c.keySet());
Collections.reverse(keys);

private StorageCell getCellByDriveSlot(DriveBlockEntity drive, int slot) throws Throwable {
var watchers = (DriveWatcher[]) DRIVE_WATCHERS_HANDLE.get(drive);
return watchers[slot] != null ? (StorageCell) DRIVE_DELEGATE_HANDLE.invoke(watchers[slot]) : null;
}
var decompressed = new Object2IntLinkedOpenHashMap<AEItemKey>();
var highest = keys.indexOf(cell.getHighestCompressed());

private Object2IntMap<AEItemKey> getChain(BulkCellInventory cell) {
if (cell.isCompressionEnabled()) {
return CompressionService.INSTANCE
.getChain(cell.getStoredItem())
.map(c -> {
var keys = new ObjectArrayList<>(c.keySet());
Collections.reverse(keys);

var decompressed = new Object2IntLinkedOpenHashMap<AEItemKey>();
var highest = keys.indexOf(cell.getHighestCompressed());

if (highest > -1) {
for (var key : keys.subList(highest, keys.size())) {
decompressed.put(key, c.getInt(key));
}
if (highest > -1) {
for (var key : keys.subList(highest, keys.size())) {
decompressed.put(key, c.getInt(key));
}
}

return decompressed;
})
.orElseGet(Object2IntLinkedOpenHashMap::new);
}

return new Object2IntLinkedOpenHashMap<>();
}

private void addChain(StorageCell cell) {
if (!(cell instanceof BulkCellInventory bulkCell)) {
return;
}

var chain = getChain(bulkCell);
return decompressed;
})
.orElseGet(Object2IntLinkedOpenHashMap::new);

if (!chain.isEmpty()) {
decompressionChains.add(chain);
Expand Down
4 changes: 2 additions & 2 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ dependencyResolutionManagement {
library("forge", "net.minecraftforge", "forge").version("$minecraftVersion-47.1.3")
library("mixin", "org.spongepowered", "mixin").version("0.8.5")

version("ae2", "15.0.5-beta")
version("ae2", "15.0.7-beta")
library("ae2-fabric", "appeng", "appliedenergistics2-fabric").versionRef("ae2")
library("ae2-forge", "appeng", "appliedenergistics2-forge").versionRef("ae2")
library("ae2-forge", "appeng", "appliedenergistics2-forge").version("15.0.8-beta")

// AE2WTLib
val ae2wtVersion = "15.0.1-beta"
Expand Down

0 comments on commit d6345f7

Please sign in to comment.