Reworked IO Port to handle StorageChannels better. (#3284)

* Reworked IO Port to handle custom StorageChannels in a better way.
* Added a transferFactor to `IStorageChannel` to allow addons to speedup the IO Port to transfer faster. E.g. 1000 mB fluid as fast as transfering 1 bucket (item) per operation, not just 1 mB. 
* Also some changes to avoid moving fluids being 1000x as energy expensive as items.
This commit is contained in:
yueh
2017-12-21 19:12:45 +01:00
committed by GitHub
parent e243c8e9a2
commit 7956872d1d
4 changed files with 89 additions and 83 deletions
@@ -43,6 +43,19 @@ import appeng.api.storage.data.IItemList;
public interface IStorageChannel<T extends IAEStack<T>> public interface IStorageChannel<T extends IAEStack<T>>
{ {
/**
* Can be used as factor for transferring stacks of a channel.
*
* E.g. used by IO Ports to transfer 1000 mB, not 1 mB to match the
* item channel transferring a full bucket per operation.
*
* @return
*/
default int transferFactor()
{
return 1;
}
/** /**
* Create a new {@link IItemList} of the specific type. * Create a new {@link IItemList} of the specific type.
* *
@@ -160,6 +160,12 @@ public class ApiStorage implements IStorageHelper
private static final class FluidStorageChannel implements IFluidStorageChannel private static final class FluidStorageChannel implements IFluidStorageChannel
{ {
@Override
public int transferFactor()
{
return 1000;
}
@Override @Override
public IItemList<IAEFluidStack> createList() public IItemList<IAEFluidStack> createList()
{ {
@@ -195,7 +201,7 @@ public class ApiStorage implements IStorageHelper
Preconditions.checkNotNull( request ); Preconditions.checkNotNull( request );
Preconditions.checkNotNull( src ); Preconditions.checkNotNull( src );
return null; return Platform.poweredExtraction( energy, cell, request, src );
} }
@Override @Override
@@ -206,7 +212,7 @@ public class ApiStorage implements IStorageHelper
Preconditions.checkNotNull( input ); Preconditions.checkNotNull( input );
Preconditions.checkNotNull( src ); Preconditions.checkNotNull( src );
return input; return Platform.poweredInsert( energy, cell, input, src );
} }
} }
@@ -19,7 +19,9 @@
package appeng.tile.storage; package appeng.tile.storage;
import java.util.IdentityHashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
@@ -48,10 +50,6 @@ import appeng.api.networking.ticking.TickingRequest;
import appeng.api.storage.IMEInventory; import appeng.api.storage.IMEInventory;
import appeng.api.storage.IMEMonitor; import appeng.api.storage.IMEMonitor;
import appeng.api.storage.IStorageChannel; import appeng.api.storage.IStorageChannel;
import appeng.api.storage.channels.IFluidStorageChannel;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IAEStack; import appeng.api.storage.data.IAEStack;
import appeng.api.storage.data.IItemList; import appeng.api.storage.data.IItemList;
import appeng.api.util.AECableType; import appeng.api.util.AECableType;
@@ -68,7 +66,6 @@ import appeng.tile.inventory.AppEngInternalInventory;
import appeng.util.ConfigManager; import appeng.util.ConfigManager;
import appeng.util.IConfigManagerHost; import appeng.util.IConfigManagerHost;
import appeng.util.InventoryAdaptor; import appeng.util.InventoryAdaptor;
import appeng.util.Platform;
import appeng.util.helpers.ItemHandlerUtil; import appeng.util.helpers.ItemHandlerUtil;
import appeng.util.inv.AdaptorItemHandler; import appeng.util.inv.AdaptorItemHandler;
import appeng.util.inv.InvOperation; import appeng.util.inv.InvOperation;
@@ -79,10 +76,13 @@ import appeng.util.inv.filter.AEItemFilters;
public class TileIOPort extends AENetworkInvTile implements IUpgradeableHost, IConfigManagerHost, IGridTickable public class TileIOPort extends AENetworkInvTile implements IUpgradeableHost, IConfigManagerHost, IGridTickable
{ {
private static final int NUMBER_OF_CELL_SLOTS = 6;
private static final int NUMBER_OF_UPGRADE_SLOTS = 3;
private final ConfigManager manager; private final ConfigManager manager;
private final AppEngInternalInventory inputCells = new AppEngInternalInventory( this, 6 ); private final AppEngInternalInventory inputCells = new AppEngInternalInventory( this, NUMBER_OF_CELL_SLOTS );
private final AppEngInternalInventory outputCells = new AppEngInternalInventory( this, 6 ); private final AppEngInternalInventory outputCells = new AppEngInternalInventory( this, NUMBER_OF_CELL_SLOTS );
private final IItemHandler combinedInventory = new WrapperChainedItemHandler( this.inputCells, this.outputCells ); private final IItemHandler combinedInventory = new WrapperChainedItemHandler( this.inputCells, this.outputCells );
private final IItemHandler inputCellsExt = new WrapperFilteredItemHandler( this.inputCells, AEItemFilters.INSERT_ONLY ); private final IItemHandler inputCellsExt = new WrapperFilteredItemHandler( this.inputCells, AEItemFilters.INSERT_ONLY );
@@ -92,8 +92,7 @@ public class TileIOPort extends AENetworkInvTile implements IUpgradeableHost, IC
private final IActionSource mySrc; private final IActionSource mySrc;
private YesNo lastRedstoneState; private YesNo lastRedstoneState;
private ItemStack currentCell; private ItemStack currentCell;
private IMEInventory<IAEFluidStack> cachedFluid; private Map<IStorageChannel<?>, IMEInventory<?>> cachedInventories;
private IMEInventory<IAEItemStack> cachedItem;
public TileIOPort() public TileIOPort()
{ {
@@ -106,7 +105,7 @@ public class TileIOPort extends AENetworkInvTile implements IUpgradeableHost, IC
this.lastRedstoneState = YesNo.UNDECIDED; this.lastRedstoneState = YesNo.UNDECIDED;
final Block ioPortBlock = AEApi.instance().definitions().blocks().iOPort().maybeBlock().get(); final Block ioPortBlock = AEApi.instance().definitions().blocks().iOPort().maybeBlock().get();
this.upgrades = new BlockUpgradeInventory( ioPortBlock, this, 3 ); this.upgrades = new BlockUpgradeInventory( ioPortBlock, this, NUMBER_OF_UPGRADE_SLOTS );
} }
@Override @Override
@@ -277,87 +276,84 @@ public class TileIOPort extends AENetworkInvTile implements IUpgradeableHost, IC
return TickRateModulation.IDLE; return TickRateModulation.IDLE;
} }
long ItemsToMove = 256; TickRateModulation ret = TickRateModulation.SLEEP;
long itemsToMove = 256;
switch( this.getInstalledUpgrades( Upgrades.SPEED ) ) switch( this.getInstalledUpgrades( Upgrades.SPEED ) )
{ {
case 1: case 1:
ItemsToMove *= 2; itemsToMove *= 2;
break; break;
case 2: case 2:
ItemsToMove *= 4; itemsToMove *= 4;
break; break;
case 3: case 3:
ItemsToMove *= 8; itemsToMove *= 8;
break; break;
} }
try try
{ {
final IMEInventory<IAEItemStack> itemNet = this.getProxy().getStorage().getInventory(
AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
final IMEInventory<IAEFluidStack> fluidNet = this.getProxy().getStorage().getInventory(
AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) );
final IEnergySource energy = this.getProxy().getEnergy(); final IEnergySource energy = this.getProxy().getEnergy();
for( int x = 0; x < 6; x++ ) for( int x = 0; x < NUMBER_OF_CELL_SLOTS; x++ )
{ {
final ItemStack is = this.inputCells.getStackInSlot( x ); final ItemStack is = this.inputCells.getStackInSlot( x );
if( !is.isEmpty() ) if( !is.isEmpty() )
{ {
if( ItemsToMove > 0 ) boolean shouldMove = true;
for( IStorageChannel<? extends IAEStack<?>> c : AEApi.instance().storage().storageChannels() )
{ {
final IMEInventory<IAEItemStack> itemInv = this.getInv( is, AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ); if( itemsToMove > 0 )
final IMEInventory<IAEFluidStack> fluidInv = this.getInv( is,
AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) );
if( this.manager.getSetting( Settings.OPERATION_MODE ) == OperationMode.EMPTY )
{ {
if( itemInv != null ) final IMEMonitor<? extends IAEStack<?>> network = this.getProxy().getStorage().getInventory( c );
final IMEInventory<?> inv = this.getInv( is, c );
if( inv == null )
{ {
ItemsToMove = this.transferContents( energy, itemInv, itemNet, ItemsToMove, continue;
AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
} }
if( fluidInv != null )
if( this.manager.getSetting( Settings.OPERATION_MODE ) == OperationMode.EMPTY )
{ {
ItemsToMove = this.transferContents( energy, fluidInv, fluidNet, ItemsToMove, itemsToMove = this.transferContents( energy, inv, network, itemsToMove, c );
AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) ); }
} else
} {
else itemsToMove = this.transferContents( energy, network, inv, itemsToMove, c );
{ }
if( itemInv != null )
{ shouldMove &= this.shouldMove( inv );
ItemsToMove = this.transferContents( energy, itemNet, itemInv, ItemsToMove,
AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ); if( itemsToMove > 0 )
} {
if( fluidInv != null ) ret = TickRateModulation.IDLE;
{ }
ItemsToMove = this.transferContents( energy, fluidNet, fluidInv, ItemsToMove, else
AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) ); {
ret = TickRateModulation.URGENT;
} }
} }
}
if( ItemsToMove > 0 && this.shouldMove( itemInv, fluidInv ) && !this.moveSlot( x ) ) if( itemsToMove > 0 && shouldMove && this.moveSlot( x ) )
{ {
return TickRateModulation.IDLE; ret = TickRateModulation.URGENT;
}
return TickRateModulation.URGENT;
} }
else else
{ {
return TickRateModulation.URGENT; ret = TickRateModulation.URGENT;
} }
} }
} }
} }
catch( final GridAccessException e ) catch( final GridAccessException e )
{ {
return TickRateModulation.IDLE; ret = TickRateModulation.IDLE;
} }
// nothing left to do... return ret;
return TickRateModulation.SLEEP;
} }
@Override @Override
@@ -366,23 +362,20 @@ public class TileIOPort extends AENetworkInvTile implements IUpgradeableHost, IC
return this.upgrades.getInstalledUpgrades( u ); return this.upgrades.getInstalledUpgrades( u );
} }
private IMEInventory getInv( final ItemStack is, final IStorageChannel chan ) private IMEInventory<?> getInv( final ItemStack is, final IStorageChannel<?> chan )
{ {
if( this.currentCell != is ) if( this.currentCell != is )
{ {
this.currentCell = is; this.currentCell = is;
this.cachedFluid = AEApi.instance().registries().cell().getCellInventory( is, null, this.cachedInventories = new IdentityHashMap<>();
AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) );
this.cachedItem = AEApi.instance().registries().cell().getCellInventory( is, null, for( IStorageChannel<? extends IAEStack<?>> c : AEApi.instance().storage().storageChannels() )
AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ); {
this.cachedInventories.put( c, AEApi.instance().registries().cell().getCellInventory( is, null, c ) );
}
} }
if( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) == chan ) return this.cachedInventories.get( chan );
{
return this.cachedItem;
}
return this.cachedFluid;
} }
private long transferContents( final IEnergySource energy, final IMEInventory src, final IMEInventory destination, long itemsToMove, final IStorageChannel chan ) private long transferContents( final IEnergySource energy, final IMEInventory src, final IMEInventory destination, long itemsToMove, final IStorageChannel chan )
@@ -397,6 +390,8 @@ public class TileIOPort extends AENetworkInvTile implements IUpgradeableHost, IC
myList = src.getAvailableItems( src.getChannel().createList() ); myList = src.getAvailableItems( src.getChannel().createList() );
} }
itemsToMove *= chan.transferFactor();
boolean didStuff; boolean didStuff;
do do
@@ -429,7 +424,7 @@ public class TileIOPort extends AENetworkInvTile implements IUpgradeableHost, IC
if( extracted != null ) if( extracted != null )
{ {
possible = extracted.getStackSize(); possible = extracted.getStackSize();
final IAEStack failed = Platform.poweredInsert( energy, destination, extracted, this.mySrc ); final IAEStack failed = chan.poweredInsert( energy, destination, extracted, this.mySrc );
if( failed != null ) if( failed != null )
{ {
@@ -451,24 +446,16 @@ public class TileIOPort extends AENetworkInvTile implements IUpgradeableHost, IC
} }
while( itemsToMove > 0 && didStuff ); while( itemsToMove > 0 && didStuff );
return itemsToMove; return itemsToMove / chan.transferFactor();
} }
private boolean shouldMove( final IMEInventory<IAEItemStack> itemInv, final IMEInventory<IAEFluidStack> fluidInv ) private boolean shouldMove( final IMEInventory<?> inv )
{ {
final FullnessMode fm = (FullnessMode) this.manager.getSetting( Settings.FULLNESS_MODE ); final FullnessMode fm = (FullnessMode) this.manager.getSetting( Settings.FULLNESS_MODE );
if( itemInv != null && fluidInv != null ) if( inv != null )
{ {
return this.matches( fm, itemInv ) && this.matches( fm, fluidInv ); return this.matches( fm, inv );
}
else if( itemInv != null )
{
return this.matches( fm, itemInv );
}
else if( fluidInv != null )
{
return this.matches( fm, fluidInv );
} }
return true; return true;
+3 -3
View File
@@ -1174,13 +1174,13 @@ public class Platform
stored -= possible.getStackSize(); stored -= possible.getStackSize();
} }
final double availablePower = energy.extractAEPower( stored, Actionable.SIMULATE, PowerMultiplier.CONFIG ); final int energyFactor = Math.min( 1, input.getChannel().transferFactor() );
final double availablePower = energy.extractAEPower( stored / energyFactor, Actionable.SIMULATE, PowerMultiplier.CONFIG );
final long itemToAdd = Math.min( (long) ( availablePower + 0.9 ), stored ); final long itemToAdd = Math.min( (long) ( availablePower + 0.9 ), stored );
if( itemToAdd > 0 ) if( itemToAdd > 0 )
{ {
energy.extractAEPower( stored, Actionable.MODULATE, PowerMultiplier.CONFIG ); energy.extractAEPower( stored / energyFactor, Actionable.MODULATE, PowerMultiplier.CONFIG );
if( itemToAdd < input.getStackSize() ) if( itemToAdd < input.getStackSize() )
{ {