From ab7f35a9eee5a3e221d898a2f0fb7bbb5802b3e0 Mon Sep 17 00:00:00 2001 From: yueh Date: Sat, 14 Oct 2017 14:12:24 +0200 Subject: [PATCH] Further StorageChannel refactoring (#3152) Updated Drives to support more than Item and Fluid cells. Use Collections.emptyList() instead of creating empty ArrayLists. Fixes a NPE with uninitialized ME Chests. Fixes #3150 --- .../registries/cell/BasicCellHandler.java | 3 +- .../registries/cell/CellRegistry.java | 3 +- .../parts/automation/PartFormationPlane.java | 9 +-- .../appeng/parts/misc/PartStorageBus.java | 2 +- .../java/appeng/tile/storage/TileChest.java | 9 ++- .../java/appeng/tile/storage/TileDrive.java | 56 +++++++------------ 6 files changed, 36 insertions(+), 46 deletions(-) diff --git a/src/main/java/appeng/core/features/registries/cell/BasicCellHandler.java b/src/main/java/appeng/core/features/registries/cell/BasicCellHandler.java index 64e47a4a..e386cdd2 100644 --- a/src/main/java/appeng/core/features/registries/cell/BasicCellHandler.java +++ b/src/main/java/appeng/core/features/registries/cell/BasicCellHandler.java @@ -33,6 +33,7 @@ import appeng.api.storage.IMEInventoryHandler; import appeng.api.storage.ISaveProvider; import appeng.api.storage.IStorageChannel; import appeng.api.storage.channels.IItemStorageChannel; +import appeng.api.storage.data.IAEStack; import appeng.api.util.AEPartLocation; import appeng.core.sync.GuiBridge; import appeng.me.storage.CellInventory; @@ -50,7 +51,7 @@ public class BasicCellHandler implements ICellHandler } @Override - public IMEInventoryHandler getCellInventory( final ItemStack is, final ISaveProvider container, final IStorageChannel channel ) + public > IMEInventoryHandler getCellInventory( final ItemStack is, final ISaveProvider container, final IStorageChannel channel ) { if( channel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) { diff --git a/src/main/java/appeng/core/features/registries/cell/CellRegistry.java b/src/main/java/appeng/core/features/registries/cell/CellRegistry.java index 36e103f2..dd1726fe 100644 --- a/src/main/java/appeng/core/features/registries/cell/CellRegistry.java +++ b/src/main/java/appeng/core/features/registries/cell/CellRegistry.java @@ -29,6 +29,7 @@ import appeng.api.storage.ICellRegistry; import appeng.api.storage.IMEInventoryHandler; import appeng.api.storage.ISaveProvider; import appeng.api.storage.IStorageChannel; +import appeng.api.storage.data.IAEStack; public class CellRegistry implements ICellRegistry @@ -85,7 +86,7 @@ public class CellRegistry implements ICellRegistry } @Override - public IMEInventoryHandler getCellInventory( final ItemStack is, final ISaveProvider container, final IStorageChannel chan ) + public > IMEInventoryHandler getCellInventory( final ItemStack is, final ISaveProvider container, final IStorageChannel chan ) { if( is.isEmpty() ) { diff --git a/src/main/java/appeng/parts/automation/PartFormationPlane.java b/src/main/java/appeng/parts/automation/PartFormationPlane.java index 8e1300e5..0b6dbf8c 100644 --- a/src/main/java/appeng/parts/automation/PartFormationPlane.java +++ b/src/main/java/appeng/parts/automation/PartFormationPlane.java @@ -20,6 +20,7 @@ package appeng.parts.automation; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import net.minecraft.entity.Entity; @@ -400,11 +401,11 @@ public class PartFormationPlane extends PartUpgradeable implements ICellContaine { if( this.getProxy().isActive() && channel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) { - final List Handler = new ArrayList<>( 1 ); - Handler.add( this.myHandler ); - return Handler; + final List handler = new ArrayList<>( 1 ); + handler.add( this.myHandler ); + return handler; } - return new ArrayList<>(); + return Collections.emptyList(); } @Override diff --git a/src/main/java/appeng/parts/misc/PartStorageBus.java b/src/main/java/appeng/parts/misc/PartStorageBus.java index ca0af79e..0b1b4c8a 100644 --- a/src/main/java/appeng/parts/misc/PartStorageBus.java +++ b/src/main/java/appeng/parts/misc/PartStorageBus.java @@ -577,7 +577,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC return Collections.singletonList( out ); } } - return Arrays.asList( new IMEInventoryHandler[] {} ); + return Collections.emptyList(); } @Override diff --git a/src/main/java/appeng/tile/storage/TileChest.java b/src/main/java/appeng/tile/storage/TileChest.java index 0d49378d..b0a4fba1 100644 --- a/src/main/java/appeng/tile/storage/TileChest.java +++ b/src/main/java/appeng/tile/storage/TileChest.java @@ -643,14 +643,19 @@ public class TileChest extends AENetworkPowerTile implements IMEChest, ITerminal { try { - return Collections.singletonList( this.getHandler( channel ) ); + final IMEInventoryHandler handler = this.getHandler( channel ); + + if( handler != null ) + { + return Collections.singletonList( handler ); + } } catch( final ChestNoHandler e ) { // :P } } - return new ArrayList<>(); + return Collections.emptyList(); } @Override diff --git a/src/main/java/appeng/tile/storage/TileDrive.java b/src/main/java/appeng/tile/storage/TileDrive.java index 2c88c44e..0fb78799 100644 --- a/src/main/java/appeng/tile/storage/TileDrive.java +++ b/src/main/java/appeng/tile/storage/TileDrive.java @@ -21,8 +21,11 @@ package appeng.tile.storage; import java.io.IOException; import java.util.ArrayList; -import java.util.LinkedList; +import java.util.Collection; +import java.util.Collections; +import java.util.IdentityHashMap; import java.util.List; +import java.util.Map; import io.netty.buffer.ByteBuf; @@ -43,9 +46,8 @@ import appeng.api.storage.ICellHandler; import appeng.api.storage.IMEInventory; import appeng.api.storage.IMEInventoryHandler; import appeng.api.storage.IStorageChannel; -import appeng.api.storage.channels.IFluidStorageChannel; -import appeng.api.storage.channels.IItemStorageChannel; import appeng.api.storage.data.IAEItemStack; +import appeng.api.storage.data.IAEStack; import appeng.api.util.AECableType; import appeng.api.util.AEPartLocation; import appeng.api.util.DimensionalCoord; @@ -73,8 +75,7 @@ public class TileDrive extends AENetworkInvTile implements IChestOrDrive, IPrior private final DriveWatcher[] invBySlot = new DriveWatcher[10]; private final IActionSource mySrc; private boolean isCached = false; - private List items = new LinkedList<>(); - private List fluids = new LinkedList<>(); + private Map>, List> inventoryHandlers; private int priority = 0; private boolean wasActive = false; @@ -98,6 +99,7 @@ public class TileDrive extends AENetworkInvTile implements IChestOrDrive, IPrior this.mySrc = new MachineSource( this ); this.getProxy().setFlags( GridFlags.REQUIRE_CHANNEL ); this.inv.setFilter( new CellValidInventoryFilter() ); + this.inventoryHandlers = new IdentityHashMap<>(); } @Override @@ -151,20 +153,9 @@ public class TileDrive extends AENetworkInvTile implements IChestOrDrive, IPrior return 0; } - if( handler.getChannel() == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) + if( ch != null ) { - if( ch != null ) - { - return ch.getStatusForCell( cell, handler.getInternal() ); - } - } - - if( handler.getChannel() == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) ) - { - if( ch != null ) - { - return ch.getStatusForCell( cell, handler.getInternal() ); - } + return ch.getStatusForCell( cell, handler.getInternal() ); } return 0; @@ -295,8 +286,8 @@ public class TileDrive extends AENetworkInvTile implements IChestOrDrive, IPrior { if( !this.isCached ) { - this.items = new LinkedList(); - this.fluids = new LinkedList(); + final Collection>> storageChannels = AEApi.instance().storage().storageChannels(); + storageChannels.forEach( channel -> this.inventoryHandlers.put( channel, new ArrayList<>( 10 ) ) ); double power = 2.0; @@ -312,22 +303,10 @@ public class TileDrive extends AENetworkInvTile implements IChestOrDrive, IPrior if( this.handlersBySlot[x] != null ) { - IMEInventoryHandler cell = this.handlersBySlot[x].getCellInventory( is, this, - AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ); - - if( cell != null ) + for( IStorageChannel> channel : storageChannels ) { - power += this.handlersBySlot[x].cellIdleDrain( is, cell ); - final DriveWatcher ih = new DriveWatcher( cell, is, this.handlersBySlot[x], this ); - ih.setPriority( this.priority ); - this.invBySlot[x] = ih; - this.items.add( ih ); - } - else - { - cell = this.handlersBySlot[x].getCellInventory( is, this, - AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) ); + IMEInventoryHandler cell = this.handlersBySlot[x].getCellInventory( is, this, channel ); if( cell != null ) { @@ -336,7 +315,9 @@ public class TileDrive extends AENetworkInvTile implements IChestOrDrive, IPrior final DriveWatcher ih = new DriveWatcher( cell, is, this.handlersBySlot[x], this ); ih.setPriority( this.priority ); this.invBySlot[x] = ih; - this.fluids.add( ih ); + this.inventoryHandlers.get( channel ).add( ih ); + + break; } } } @@ -362,9 +343,10 @@ public class TileDrive extends AENetworkInvTile implements IChestOrDrive, IPrior if( this.getProxy().isActive() ) { this.updateState(); - return (List) ( channel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ? this.items : this.fluids ); + + return this.inventoryHandlers.get( channel ); } - return new ArrayList(); + return Collections.emptyList(); } @Override