Compare commits

...

17 Commits

Author SHA1 Message Date
Salomão 31a3afc18b revert inventory merging code to keep compatibility with ae2fc 2021-05-14 12:43:34 -03:00
Salomão 9d6026635d level emitter changes 2021-05-13 19:32:03 -03:00
Salomão 39038ac935 revert iitemrepository cache changes 2021-05-12 23:22:54 -03:00
Salomão 4f627b234c invert comparison 2021-05-12 03:26:12 -03:00
Salomão 6180c188e6 Revert "remove crafting failure penalty"
This reverts commit 0240a5d76a.
2021-05-12 02:42:34 -03:00
Salomão 7ada6d18ee small optimizations 2021-05-12 00:19:55 -03:00
Salomão f493767243 fix out of bounds crash 2021-05-09 22:00:20 -03:00
Salomão ba4cdbcb85 fix #16 2021-05-09 10:59:31 -03:00
Salomão f3877aa1ec Merge branch 'iir-cache' into AE2-Omnifactory 2021-05-08 22:46:56 -03:00
Salomão 366b31b3aa import bus optimization 2021-05-08 22:11:13 -03:00
Salomão 533fb5c34b initial test 2021-05-08 19:40:58 -03:00
Salomão 62d1d904c6 update item cache directly on insert/removal
import bus fails faster and throttles down when inventory is full
2021-05-08 19:08:21 -03:00
Salomão 03fb43db16 revert blocking mode to previous implementation 2021-05-05 19:45:25 -03:00
Salomão 9576bec855 renamed method. fixed round robin while blocking mode on 2021-05-04 22:51:20 -03:00
Salomão b5da6730a1 loop optimization 2021-05-04 15:15:09 -03:00
Salomão 039bab4811 drop items waiting to be injected when interface is broken 2021-05-04 11:07:31 -03:00
Salomão 4b5bdf9893 fix NPE 2021-05-04 10:57:01 -03:00
15 changed files with 576 additions and 223 deletions
@@ -264,18 +264,19 @@ public class PartFluidStorageBus extends PartSharedStorageBus implements IMEMoni
@Override
public void postChange( final IBaseMonitor<IAEFluidStack> monitor, final Iterable<IAEFluidStack> change, final IActionSource source )
{
try
if( source == this.source || source.machine().map( machine -> machine == this ).orElse( false ) )
{
if( this.getProxy().isActive() )
try
{
this.getProxy()
.getStorage()
.postAlterationOfStoredItems( AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ), change, this.source );
if( this.getProxy().isActive() )
{
this.getProxy().getStorage().postAlterationOfStoredItems( AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ), change, this.source );
}
}
catch( final GridAccessException e )
{
// :(
}
}
catch( final GridAccessException e )
{
// :(
}
}
@@ -24,6 +24,7 @@ import java.util.stream.Collectors;
import javax.annotation.Nullable;
import appeng.integration.modules.gregtech.GTCEInventoryAdaptor;
import appeng.util.*;
import appeng.util.inv.*;
import com.google.common.collect.ImmutableSet;
@@ -106,6 +107,8 @@ import static gregtech.api.block.machines.BlockMachine.getMetaTileEntity;
public class DualityInterface implements IGridTickable, IStorageMonitorable, IInventoryDestination, IAEAppEngInventory, IConfigManagerHost, ICraftingProvider, IUpgradeableHost
{
private int[] failedCraftTriesSlot = {0,0,0,0,0,0,0,0,0};
public static final int NUMBER_OF_STORAGE_SLOTS = 9;
public static final int NUMBER_OF_CONFIG_SLOTS = 9;
public static final int NUMBER_OF_PATTERN_SLOTS = 9;
@@ -137,6 +140,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
private final Accessor accessor = new Accessor();
private EnumSet<EnumFacing> visitedFaces = EnumSet.noneOf( EnumFacing.class );
private EnumMap<EnumFacing,List<ItemStack>> waitingToSendFacing = new EnumMap<>(EnumFacing.class);
private GTCEInventoryAdaptor GTad;
public DualityInterface( final AENetworkProxy networkProxy, final IInterfaceHost ih )
{
@@ -726,8 +730,8 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
private void pushItemsOut( final EnumFacing s )
{
if( this.waitingToSendFacing.get(s) == null || this.waitingToSendFacing.get( s ).isEmpty() )
{
if (!this.waitingToSendFacing.containsKey(s) ||
(this.waitingToSendFacing.containsKey(s) && this.waitingToSendFacing.get( s ).isEmpty())) {
return;
}
@@ -761,7 +765,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
if( this.waitingToSendFacing.get( s ).isEmpty() )
{
this.waitingToSendFacing.get( s ).clear();
this.waitingToSendFacing.remove( s );
}
}
@@ -884,8 +888,17 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
{
if( this.getInstalledUpgrades( Upgrades.CRAFTING ) > 0 && itemStack != null )
{
return this.craftingTracker.handleCrafting( x, itemStack.getStackSize(), itemStack, d, this.iHost.getTileEntity().getWorld(),
if (this.failedCraftTriesSlot[x] <= 0)
{
boolean crafted = this.craftingTracker.handleCrafting( x, itemStack.getStackSize(), itemStack, d, this.iHost.getTileEntity().getWorld(),
this.gridProxy.getGrid(), this.gridProxy.getCrafting(), this.mySource );
if (crafted) this.failedCraftTriesSlot[x] = 0;
else{
this.failedCraftTriesSlot[x] += 2;
}
}
this.failedCraftTriesSlot[x] -= 1;
}
}
catch( final GridAccessException e )
@@ -1020,20 +1033,12 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
private boolean invIsBlocked( InventoryAdaptor inv )
{
final Iterator<ICraftingPatternDetails> i = this.craftingList.iterator();
ICraftingPatternDetails patt = i.next();
for ( ItemSlot itemSlot : inv)
{
if (itemSlot.getItemStack().isEmpty()){
continue;
}
for ( IAEItemStack iaeItemStack : patt.getCondensedInputs()){
if (iaeItemStack.isSameType( itemSlot.getItemStack() )){
return true;
}
}
}
return false;
return (inv.containsItems());
}
private static boolean invIsBlockedGTCE( GTCEInventoryAdaptor inv )
{
return ( !inv.canRemoveAllExceptCircuits() );
}
@Override
@@ -1076,12 +1081,11 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
final ICraftingMachine cm = (ICraftingMachine) te;
if( cm.acceptsPlans() )
{
visitedFaces.remove( s );
if( cm.pushPattern( patternDetails, table, s.getOpposite() ) )
{
visitedFaces.remove( s );
return true;
}
visitedFaces.remove( s );
continue;
}
}
@@ -1089,17 +1093,27 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
final InventoryAdaptor ad = InventoryAdaptor.getAdaptor( te, s.getOpposite() );
if( ad != null )
{
boolean isDrawer = te.getBlockType().getRegistryName().getResourceDomain().equals( "storagedrawers" );
if( this.isBlocking() )
{
if( invIsBlocked( ad ) )
if( te.getBlockType().getRegistryName().getResourceDomain().equals( "gregtech" ) )
{
GTad = GTCEInventoryAdaptor.getAdaptor( te, s.getOpposite() );
if( GTad != null && !invIsBlockedGTCE( GTad ) )
{
visitedFaces.remove( s );
continue;
}
}
else if ( invIsBlocked( ad ) )
{
visitedFaces.remove( s );
continue;
}
}
if( this.acceptsItems( ad, patternDetails, isDrawer ) )
if( this.acceptsItems( ad, table ) )
{
visitedFaces.remove( s );
for( int x = 0; x < table.getSizeInventory(); x++ )
{
final ItemStack is = table.getStackInSlot( x );
@@ -1107,9 +1121,8 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
{
addToSendListFacing( is, s );
}
pushItemsOut( s );
}
visitedFaces.remove( s );
pushItemsOut( s );
return true;
}
}
@@ -1143,7 +1156,16 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
final InventoryAdaptor ad = InventoryAdaptor.getAdaptor( te, s.getOpposite() );
if( ad != null )
{
if( !invIsBlocked( ad ) )
if( te.getBlockType().getRegistryName().getResourceDomain().equals( "gregtech" ) )
{
GTad = GTCEInventoryAdaptor.getAdaptor( te, s.getOpposite() );
if( GTad != null && !invIsBlockedGTCE( GTad ) )
{
allAreBusy = false;
break;
}
}
else if( !invIsBlocked( ad ) )
{
allAreBusy = false;
break;
@@ -1165,85 +1187,23 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
return this.cm.getSetting( Settings.BLOCK ) == YesNo.YES;
}
private boolean acceptsItems( final InventoryAdaptor ad, final ICraftingPatternDetails patternDetails, boolean isDrawer )
private boolean acceptsItems( final InventoryAdaptor ad, final InventoryCrafting table )
{
List<ItemStack> patternedStacks = Arrays.stream( patternDetails.getCondensedInputs() ).map( IAEItemStack::createItemStack ).collect( Collectors.toList() );
List<ItemSlot> copiedItemSlots = new ArrayList<>();
if( patternedStacks.size() == 1 )
for( int x = 0; x < table.getSizeInventory(); x++ )
{
return ad.simulateAdd( patternedStacks.get( 0 ) ).isEmpty();
}
else
{
Iterator<ItemSlot> adit = ad.iterator();
while ( adit.hasNext() )
final ItemStack is = table.getStackInSlot( x );
if( is.isEmpty() )
{
ItemSlot is = adit.next();
//skip storage drawers slot 0 to avoid voiding items due to broken itemhandler implementation
if( isDrawer && is.getSlot() == 0 ) is = adit.next();
//some inventory may expose their special slots ( for upgrades, etc )
//if its empty AND we cant fit any of the items in the recipes, skip it.
if( is.getItemStack().isEmpty() )
{
boolean validInputSlotForIngredients = false;
for( IAEItemStack aeItemStack : patternDetails.getCondensedInputs() )
{
if( is.insertItem( aeItemStack.getDefinition() ).isEmpty() )
{
validInputSlotForIngredients = true;
break;
}
}
if( validInputSlotForIngredients )
{
copiedItemSlots.add( is.copy() );
}
}
else if( !is.getItemStack().isEmpty() && is.getItemStack().getCount() < is.getSlotLimit() )
{
copiedItemSlots.add( is.copy() );
}
continue;
}
Iterator<ItemSlot> copiedItemSlotIterator = copiedItemSlots.iterator();
while ( copiedItemSlotIterator.hasNext() )
if( !ad.simulateAdd( is.copy() ).isEmpty() )
{
ItemSlot copiedItemSlot = copiedItemSlotIterator.next();
Iterator<ItemStack> psi = patternedStacks.iterator();
while ( psi.hasNext() )
{
ItemStack patternedStack = psi.next();
ItemStack remainder = copiedItemSlot.insertItem( patternedStack );
if( !remainder.isEmpty() )
{
patternedStack.setCount( patternedStack.getCount() - ( patternedStack.getCount() - remainder.getCount() ) );
if( copiedItemSlot.getSlotLimit() == copiedItemSlot.getItemStack().getCount() )
{
copiedItemSlotIterator.remove();
break;
}
}
else
{
if( copiedItemSlot.getSlotLimit() == copiedItemSlot.getItemStack().getCount() )
{
copiedItemSlotIterator.remove();
}
psi.remove();
break;
}
}
if( patternedStacks.size() == 0 )
{
return true;
}
return false;
}
return false;
}
return true;
}
@Override
@@ -1272,6 +1232,20 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
}
}
if( this.waitingToSendFacing != null )
{
for (List<ItemStack> itemList : waitingToSendFacing.values())
{
for (final ItemStack is : itemList)
{
if (!is.isEmpty())
{
drops.add(is);
}
}
}
}
for( final ItemStack is : this.upgrades )
{
if( !is.isEmpty() )
@@ -0,0 +1,26 @@
package appeng.integration.modules.gregtech;
import appeng.util.inv.ItemSlot;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
public abstract class GTCEInventoryAdaptor implements Iterable<ItemSlot>
{
public static GTCEInventoryAdaptor getAdaptor(final TileEntity te, final EnumFacing d)
{
if (te != null && te.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, d))
{
// Attempt getting an IItemHandler for the given side via caps
IItemHandler itemHandler = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, d);
if (itemHandler != null)
{
return new GTCEItemHandler(itemHandler);
}
}
return null;
}
public abstract boolean canRemoveAllExceptCircuits();
}
@@ -0,0 +1,58 @@
package appeng.integration.modules.gregtech;
import appeng.util.inv.ItemHandlerIterator;
import appeng.util.inv.ItemSlot;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.items.IItemHandler;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
public class GTCEItemHandler extends GTCEInventoryAdaptor
{
ArrayList<Integer> GTCElenses = new ArrayList<>(Arrays.asList(15085,15214,15092,15111,15113,15219,15218,15243,15244,15209,15117,15206,15216,15331,15212,15213,15154,15122,15157,15190,15247));
ArrayList<Integer> GTCEmolds = new ArrayList<>(Arrays.asList(32301,32303,32304,32305,32306,32307,32308,32309,32313,32314,32315,32317,32350,32351,32352,32353,32354,32355,32356,32358,32359,32360,32361,32363,32364,32365,32366,32367,32368,32369,32370,32371,32372,32373));
Item smallGearExtruderShape = Item.getByNameOrId("contenttweaker:smallgearextrudershape");
Item creativePortableTankMold = Item.getByNameOrId("contenttweaker:creativeportabletankmold");
protected final IItemHandler itemHandler;
public GTCEItemHandler(IItemHandler itemHandler)
{
this.itemHandler = itemHandler;
}
boolean isBlockableItem(ItemStack stack)
{
if ( stack.getItem() == Item.getByNameOrId("gregtech:meta_item_1") ) {
int metadata = stack.getItemDamage();
if ( metadata == 32766 || GTCElenses.contains(metadata) || GTCEmolds.contains(metadata)) {
return false;
}
}
if ( stack.getItem() == smallGearExtruderShape ) return false;
if ( stack.getItem() == creativePortableTankMold) return false;
return true;
}
@Override
public boolean canRemoveAllExceptCircuits()
{
int slots = this.itemHandler.getSlots();
for ( int slot = 0; slot < slots; slot++ ) {
ItemStack is = this.itemHandler.getStackInSlot(slot);
if ( is.isEmpty() || !isBlockableItem(is) ) continue;
return false;
}
return true;
}
@Override
public Iterator<ItemSlot> iterator()
{
return new ItemHandlerIterator( this.itemHandler );
}
}
+4 -2
View File
@@ -44,6 +44,8 @@ import appeng.api.storage.IStorageChannel;
import appeng.api.storage.data.IAEStack;
import appeng.api.storage.data.IItemList;
import appeng.me.storage.ItemWatcher;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
@@ -58,7 +60,7 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
@Nonnull
private final IItemList<T> cachedList;
@Nonnull
private final Map<IMEMonitorHandlerReceiver<T>, Object> listeners;
private final Object2ObjectMap<IMEMonitorHandlerReceiver<T>, Object> listeners;
private boolean sendEvent = false;
private boolean hasChanged = false;
@@ -70,7 +72,7 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
this.myGridCache = cache;
this.myChannel = chan;
this.cachedList = chan.createList();
this.listeners = new HashMap<>();
this.listeners = new Object2ObjectOpenHashMap<>();
}
@Override
@@ -70,6 +70,8 @@ import appeng.util.item.AEItemStack;
public class PartExportBus extends PartSharedItemBus implements ICraftingRequester
{
private final int[] failedCraftTriesSlot = {0,0,0,0,0,0,0,0,0};
public static final ResourceLocation MODEL_BASE = new ResourceLocation( AppEng.MOD_ID, "part/export_bus_base" );
@PartModels
@@ -140,7 +142,7 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
if( destination != null )
{
int x;
int x = 0;
for( x = 0; x < this.availableSlots() && this.itemToSend > 0; x++ )
{
@@ -151,8 +153,16 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
if( ais == null || this.itemToSend <= 0 ) continue;
if ( this.craftOnly() ) {
this.didSomething = this.craftingTracker.handleCrafting(slotToExport, this.itemToSend, ais, destination, this.getTile().getWorld(),
this.getProxy().getGrid(), cg, this.mySrc) || this.didSomething;
if (this.failedCraftTriesSlot[x] <= 0) {
this.didSomething = this.craftingTracker.handleCrafting(slotToExport, this.itemToSend, ais, destination, this.getTile().getWorld(),
this.getProxy().getGrid(), cg, this.mySrc) || this.didSomething;
if (this.didSomething) this.failedCraftTriesSlot[x] = 0;
else this.failedCraftTriesSlot[x] += 2;
}
this.failedCraftTriesSlot[x] -= 1;
continue;
}
final long before = this.itemToSend;
@@ -175,8 +185,15 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
if( this.itemToSend == before && this.isCraftingEnabled() )
{
this.didSomething = this.craftingTracker.handleCrafting(slotToExport, this.itemToSend, ais, destination, this.getTile().getWorld(),
if (this.failedCraftTriesSlot[x] <= 0) {
this.didSomething = this.craftingTracker.handleCrafting(slotToExport, this.itemToSend, ais, destination, this.getTile().getWorld(),
this.getProxy().getGrid(), cg, this.mySrc) || this.didSomething;
if (this.didSomething) this.failedCraftTriesSlot[x] = 0;
else this.failedCraftTriesSlot[x] += 2;
}
this.failedCraftTriesSlot[x] -= 1;
}
}
@@ -218,6 +218,12 @@ public class PartImportBus extends PartSharedItemBus implements IInventoryDestin
private boolean importStuff( final InventoryAdaptor myAdaptor, final IAEItemStack whatToImport, final IMEMonitor<IAEItemStack> inv, final IEnergySource energy, final FuzzyMode fzMode )
{
final int toSend = this.calculateMaximumAmountToImport( myAdaptor, whatToImport, inv, fzMode );
if( toSend == 0 )
{
return true;
}
final ItemStack newItems;
if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
@@ -286,8 +292,17 @@ public class PartImportBus extends PartSharedItemBus implements IInventoryDestin
itemAmountNotStorable = inv.injectItems( AEItemStack.fromItemStack( simResult ), Actionable.SIMULATE, this.source );
}
if( simResult.isEmpty() )
{
return 0;
}
if( itemAmountNotStorable != null )
{
if( simResult.getCount() == itemAmountNotStorable.getStackSize() )
{
return 0;
}
return (int) Math.min( simResult.getCount() - itemAmountNotStorable.getStackSize(), toSend );
}
@@ -19,6 +19,7 @@
package appeng.parts.automation;
import java.util.ArrayList;
import java.util.Random;
import appeng.me.Grid;
@@ -26,6 +27,7 @@ import appeng.me.GridNode;
import appeng.util.item.AEItemStack;
import it.unimi.dsi.fastutil.objects.Object2LongMap;
import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.InventoryCrafting;
@@ -126,6 +128,8 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
static Object2LongMap<Grid> gridItemCount = new Object2LongOpenHashMap<>();
static Object2ObjectOpenHashMap<Grid, Object2LongMap<AEItemStack>> fuzzyAEItemStackCount = new Object2ObjectOpenHashMap<>();
static Object2ObjectOpenHashMap<Grid, Object2LongMap<AEItemStack>> preciseAEItemStackCount = new Object2ObjectOpenHashMap<>();
static Object2ObjectMap<Grid,Iterable<IAEItemStack>> previousChange = new Object2ObjectOpenHashMap<>();
static Object2ObjectMap<Grid,IItemList<IAEItemStack>> cachedStorageList = new Object2ObjectOpenHashMap<>();
@Reflected
public PartLevelEmitter( final ItemStack is )
@@ -324,54 +328,90 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
private void updateReportingValue( final IMEMonitor<IAEItemStack> monitor )
{
updateReportingValue( monitor,null );
updateReportingValue( monitor, new ArrayList<>() );
}
private void updateReportingValue( final IMEMonitor<IAEItemStack> monitor, Iterable<IAEItemStack> change )
{
final IAEItemStack myStack = this.config.getAEStackInSlot( 0 );
GridNode node = (GridNode) (this.getGridNode());
GridNode node = (GridNode) ( this.getGridNode() );
if( node != null )
{
final Grid g = node.getInternalGrid();
IItemList<IAEItemStack> l;
boolean alreadyEvaluated = false;
if( previousChange.containsKey( g ) )
{
if( change.iterator().hasNext() && previousChange.get( g ).iterator().hasNext() )
{
IAEItemStack a = change.iterator().next();
IAEItemStack b = previousChange.get( g ).iterator().next();
if( a == b )
{
alreadyEvaluated = true;
}
}
else {
alreadyEvaluated = true;
}
}
if( alreadyEvaluated )
{
l = cachedStorageList.get( g );
}
else
{
l = monitor.getStorageList();
cachedStorageList.put( g, l );
if ( change.iterator().hasNext() )
{
previousChange.put( g, change );
}
else
{
previousChange.put( g, new ArrayList<>() );
}
}
if( myStack == null )
{
if( change != null )
if( gridItemCount.containsKey( g ) )
{
if( gridItemCount.containsKey( g ) )
{
change.forEach( iaeItemStack -> lastReportedValue += iaeItemStack.getStackSize() );
}
change.forEach( iaeItemStack -> lastReportedValue += iaeItemStack.getStackSize() );
}
gridItemCount.computeIfAbsent( g, ( aLong ) -> {
this.lastReportedValue = 0;
monitor.getStorageList().forEach( iaeItemStack -> lastReportedValue += iaeItemStack.getStackSize() );
l.forEach( iaeItemStack -> lastReportedValue += iaeItemStack.getStackSize() );
return ( lastReportedValue );
} );
this.lastReportedValue = gridItemCount.get( g );
}
else if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
{
final FuzzyMode fzMode = (FuzzyMode) this.getConfigManager().getSetting( Settings.FUZZY_MODE );
if( change != null )
if( fuzzyAEItemStackCount.containsKey( g ) )
{
if( fuzzyAEItemStackCount.containsKey( g ) )
{
change.forEach( iaeItemStack -> {
if( iaeItemStack.sameOre( myStack ) ) lastReportedValue += iaeItemStack.getStackSize();
} );
}
change.forEach( iaeItemStack -> {
if( iaeItemStack.sameOre( myStack ) )
{
lastReportedValue += iaeItemStack.getStackSize();
}
} );
}
fuzzyAEItemStackCount.computeIfAbsent( g, ( grid -> new Object2LongOpenHashMap<>() ) );
fuzzyAEItemStackCount.get( g ).computeIfAbsent( (AEItemStack) myStack, ( aLong -> {
this.lastReportedValue = 0;
monitor.getStorageList().findFuzzy( myStack, fzMode ).forEach( iaeItemStack -> lastReportedValue += iaeItemStack.getStackSize() );
l.findFuzzy( myStack, fzMode ).forEach( iaeItemStack -> lastReportedValue += iaeItemStack.getStackSize() );
return ( lastReportedValue );
} ) );
@@ -384,19 +424,17 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
}
else
{
if( change != null )
if( preciseAEItemStackCount.containsKey( g ) )
{
if( preciseAEItemStackCount.containsKey( g ) )
{
change.forEach( iaeItemStack -> {
if( iaeItemStack.isSameType( myStack ) ) lastReportedValue += iaeItemStack.getStackSize();
} );
}
change.forEach( iaeItemStack -> {
if( iaeItemStack.isSameType( myStack ) ) lastReportedValue += iaeItemStack.getStackSize();
} );
}
preciseAEItemStackCount.computeIfAbsent( g, ( grid -> new Object2LongOpenHashMap<>() ) );
preciseAEItemStackCount.get( g ).computeIfAbsent( (AEItemStack) myStack, ( aLong -> {
this.lastReportedValue = 0;
IAEItemStack precise = monitor.getStorageList().findPrecise( myStack );
IAEItemStack precise = l.findPrecise( myStack );
if( precise != null ) lastReportedValue = precise.getStackSize();
return ( lastReportedValue );
} ) );
@@ -19,15 +19,12 @@
package appeng.parts.misc;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.*;
import appeng.api.config.Settings;
import appeng.api.config.StorageFilter;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.minecraft.item.ItemStack;
import net.minecraftforge.items.IItemHandler;
@@ -42,11 +39,11 @@ import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
import appeng.core.AELog;
import appeng.me.GridAccessException;
import appeng.me.helpers.IGridProxyable;
import appeng.me.storage.ITickingMonitor;
import appeng.util.Platform;
import appeng.util.item.AEItemStack;
import org.apache.commons.lang3.tuple.Pair;
/**
@@ -54,7 +51,7 @@ import appeng.util.item.AEItemStack;
*/
class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAEItemStack>, ITickingMonitor
{
private final Map<IMEMonitorHandlerReceiver<IAEItemStack>, Object> listeners = new HashMap<>();
private final Object2ObjectMap<IMEMonitorHandlerReceiver<IAEItemStack>, Object> listeners = new Object2ObjectOpenHashMap<>();
private IActionSource mySource;
private final IItemHandler itemHandler;
private final IGridProxyable proxyable;
@@ -76,16 +73,28 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
@Override
public IAEItemStack injectItems( IAEItemStack iox, Actionable type, IActionSource src )
{
ItemStack orgInput = iox.createItemStack();
ItemStack remaining = orgInput;
int slotCount = this.itemHandler.getSlots();
boolean simulate = ( type == Actionable.SIMULATE );
List<Pair<Integer, Integer>> injectedList = new ArrayList<>();
// This uses a brute force approach and tries to jam it in every slot the inventory exposes.
for( int i = 0; i < slotCount && !remaining.isEmpty(); i++ )
{
int countPre = remaining.getCount();
remaining = this.itemHandler.insertItem( i, remaining, simulate );
int countPos = remaining.getCount();
if( remaining.isEmpty() )
{
injectedList.add( Pair.of( i, countPre ) );
break;
}
else if( countPos < countPre )
{
injectedList.add( Pair.of( i, countPre - countPos ) );
}
}
// At this point, we still have some items left...
@@ -97,14 +106,30 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
if( type == Actionable.MODULATE )
{
try
if( this.cache.cachedAeStacks.length == 0 )
{
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
this.cache.update();
}
catch( GridAccessException ex )
else
{
// meh
for( Pair<Integer, Integer> pair : injectedList )
{
if( pair.getKey() >= this.cache.cachedAeStacks.length )
{
this.cache.update();
break;
}
if( this.cache.cachedAeStacks[pair.getKey()] == null )
{
this.cache.cachedAeStacks[pair.getKey()] = iox.copy().setStackSize( pair.getValue() );
}
else
{
this.cache.cachedAeStacks[pair.getKey()].incStackSize( pair.getValue() );
}
}
}
}
return AEItemStack.fromItemStack( remaining );
@@ -113,7 +138,6 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
@Override
public IAEItemStack extractItems( IAEItemStack request, Actionable mode, IActionSource src )
{
ItemStack requestedItemStack = request.createItemStack();
int remainingSize = requestedItemStack.getCount();
@@ -121,8 +145,10 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
ItemStack gathered = ItemStack.EMPTY;
final boolean simulate = ( mode == Actionable.SIMULATE );
List<Pair<Integer, Integer>> extractedList = new ArrayList<>();
for( int i = 0; i < this.itemHandler.getSlots(); i++ )
for ( int i = 0; i < this.itemHandler.getSlots(); i++ )
{
ItemStack stackInInventorySlot = this.itemHandler.getStackInSlot( i );
@@ -140,6 +166,7 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
do
{
extracted = this.itemHandler.extractItem( i, remainingCurrentSlot, simulate );
if( !extracted.isEmpty() )
{
if( extracted.getCount() > remainingCurrentSlot )
@@ -165,10 +192,15 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
remainingCurrentSlot -= extracted.getCount();
}
}
while( !extracted.isEmpty() && remainingCurrentSlot > 0 );
while ( !extracted.isEmpty() && remainingCurrentSlot > 0 );
remainingSize -= stackSizeCurrentSlot - remainingCurrentSlot;
if (!gathered.isEmpty())
{
extractedList.add( Pair.of( i, gathered.getCount() ) );
}
// Done?
if( remainingSize <= 0 )
{
@@ -180,13 +212,23 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
{
if( mode == Actionable.MODULATE )
{
try
if( this.cache.cachedAeStacks.length == 0 )
{
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
this.cache.update();
}
catch( GridAccessException ex )
else
{
// meh
for( Pair<Integer, Integer> pair : extractedList )
{
if( this.cache.cachedAeStacks[pair.getKey()] != null )
{
this.cache.cachedAeStacks[pair.getKey()].decStackSize( pair.getValue() );
if( this.cache.cachedAeStacks[pair.getKey()].getStackSize() == 0 )
{
this.cache.cachedAeStacks[pair.getKey()] = null;
}
}
}
}
}
@@ -364,7 +406,7 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
if( oldAeIS != null )
{
oldAeIS.setStackSize( -oldAeIS.getStackSize() );
changes.add( oldAeIS );
changes.add( oldAeIS.copy() );
}
// Notify the network about the new stack. Note that this is null if newIS was null
@@ -1,17 +1,14 @@
package appeng.parts.misc;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
import appeng.api.storage.IStorageChannel;
import appeng.core.AELog;
import com.jaquadro.minecraft.storagedrawers.api.capabilities.IItemRepository;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.minecraft.item.ItemStack;
import appeng.api.AEApi;
@@ -38,7 +35,7 @@ import javax.annotation.Nonnull;
class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAEItemStack>, ITickingMonitor
{
private final Map<IMEMonitorHandlerReceiver<IAEItemStack>, Object> listeners = new HashMap<>();
private final Object2ObjectMap<IMEMonitorHandlerReceiver<IAEItemStack>, Object> listeners = new Object2ObjectOpenHashMap<>();
private IActionSource mySource;
private final IItemRepository itemRepository;
private final IGridProxyable proxyable;
@@ -88,13 +85,12 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
@Override
public IAEItemStack extractItems( IAEItemStack request, Actionable mode, IActionSource src )
{
ItemStack requestedItemStack = request.createItemStack();
int remainingSize = requestedItemStack.getCount();
ItemStack requestedItemStack = request.getDefinition();
int remainingSize = (int) Math.min( Integer.MAX_VALUE, request.getStackSize());
final boolean simulate = ( mode == Actionable.SIMULATE );
ItemStack extracted;
extracted = this.itemRepository.extractItem( requestedItemStack, remainingSize, simulate );
ItemStack extracted = this.itemRepository.extractItem( requestedItemStack, remainingSize, simulate );
if( extracted.getCount() > remainingSize )
{
@@ -118,10 +114,8 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
// meh
}
}
return AEItemStack.fromItemStack( extracted );
}
return null;
}
@@ -290,7 +284,7 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
if( oldAeIS != null )
{
oldAeIS.setStackSize( -oldAeIS.getStackSize() );
changes.add( oldAeIS );
changes.add( oldAeIS.copy() );
}
// Notify the network about the new stack. Note that this is null if newIS was null
@@ -258,19 +258,19 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
@Override
public void postChange( final IBaseMonitor<IAEItemStack> monitor, final Iterable<IAEItemStack> change, final IActionSource source )
{
try
if( source == this.mySrc || source.machine().map( machine -> machine == this ).orElse( false ) )
{
if( this.getProxy().isActive() )
try
{
this.getProxy()
.getStorage()
.postAlterationOfStoredItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), change,
this.mySrc );
if( this.getProxy().isActive() )
{
this.getProxy().getStorage().postAlterationOfStoredItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), change, this.mySrc );
}
}
catch( final GridAccessException e )
{
// :(
}
}
catch( final GridAccessException e )
{
// :(
}
}
@@ -20,10 +20,13 @@ package appeng.util;
import appeng.util.inv.*;
import com.jaquadro.minecraft.storagedrawers.api.capabilities.IItemRepository;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityInject;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
@@ -37,12 +40,23 @@ import appeng.api.config.FuzzyMode;
*/
public abstract class InventoryAdaptor implements Iterable<ItemSlot>
{
@CapabilityInject( IItemRepository.class)
public static Capability<IItemRepository> ITEM_REPOSITORY_CAPABILITY = null;
public static InventoryAdaptor getAdaptor( final TileEntity te, final EnumFacing d )
{
if( te != null )
{
if( te.hasCapability( CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, d ) )
if( ITEM_REPOSITORY_CAPABILITY != null && te.hasCapability( ITEM_REPOSITORY_CAPABILITY, d ) )
{
IItemRepository itemRepository = te.getCapability( ITEM_REPOSITORY_CAPABILITY, d );
if (itemRepository != null){
return new AdaptorItemRepository( itemRepository );
}
}
else if( te.hasCapability( CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, d ) )
{
// Attempt getting an IItemHandler for the given side via caps
IItemHandler itemHandler = te.getCapability( CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, d );
if( itemHandler != null )
@@ -0,0 +1,209 @@
package appeng.util.inv;
import appeng.api.config.FuzzyMode;
import appeng.util.InventoryAdaptor;
import appeng.util.Platform;
import com.jaquadro.minecraft.storagedrawers.api.capabilities.IItemRepository;
import net.minecraft.item.ItemStack;
import java.util.Iterator;
public class AdaptorItemRepository extends InventoryAdaptor
{
protected final IItemRepository itemRepository;
public AdaptorItemRepository( IItemRepository itemRepository )
{
this.itemRepository = itemRepository;
}
@Override
public ItemStack removeItems( int amount, ItemStack filter, IInventoryDestination destination )
{
ItemStack rv = ItemStack.EMPTY;
ItemStack extracted = ItemStack.EMPTY;
if( !filter.isEmpty() )
{
extracted = this.itemRepository.extractItem( filter, amount, true );
}
else
{
for( IItemRepository.ItemRecord record : this.itemRepository.getAllItems() )
{
extracted = this.itemRepository.extractItem( record.itemPrototype, amount, true );
if( !extracted.isEmpty() )
{
break;
}
}
}
if( destination != null )
{
if( extracted.isEmpty() || !destination.canInsert( extracted ) )
{
return rv;
}
}
extracted = this.itemRepository.extractItem( filter, amount, false );
return extracted;
}
@Override
public ItemStack simulateRemove( int amount, ItemStack filter, IInventoryDestination destination )
{
ItemStack rv = ItemStack.EMPTY;
ItemStack extracted = ItemStack.EMPTY;
if( !filter.isEmpty() )
{
extracted = this.itemRepository.extractItem( filter, amount, true );
}
else
{
for( IItemRepository.ItemRecord record : this.itemRepository.getAllItems() )
{
extracted = this.itemRepository.extractItem( record.itemPrototype, amount, true );
if( !extracted.isEmpty() )
{
break;
}
}
}
if( destination != null )
{
if( extracted.isEmpty() || !destination.canInsert( extracted ) )
{
return rv;
}
}
return extracted;
}
@Override
public ItemStack removeSimilarItems( int amount, ItemStack filter, FuzzyMode fuzzyMode, IInventoryDestination destination )
{
ItemStack rv = ItemStack.EMPTY;
ItemStack extracted = ItemStack.EMPTY;
for( IItemRepository.ItemRecord record : this.itemRepository.getAllItems() )
{
if( Platform.itemComparisons().isFuzzyEqualItem( record.itemPrototype, filter, fuzzyMode ) )
{
extracted = this.itemRepository.extractItem( record.itemPrototype, amount, true );
}
if( !extracted.isEmpty() )
{
break;
}
}
if( destination != null )
{
if( extracted.isEmpty() || !destination.canInsert( extracted ) )
{
return rv;
}
}
extracted = this.itemRepository.extractItem( extracted, amount, false );
return extracted;
}
@Override
public ItemStack simulateSimilarRemove( int amount, ItemStack filter, FuzzyMode fuzzyMode, IInventoryDestination destination )
{
ItemStack rv = ItemStack.EMPTY;
ItemStack extracted = ItemStack.EMPTY;
for( IItemRepository.ItemRecord record : this.itemRepository.getAllItems() )
{
if( Platform.itemComparisons().isFuzzyEqualItem( record.itemPrototype, filter, fuzzyMode ) )
{
extracted = this.itemRepository.extractItem( record.itemPrototype, amount, true );
}
if( !extracted.isEmpty() )
{
break;
}
}
if( destination != null )
{
if( extracted.isEmpty() || !destination.canInsert( extracted ) )
{
return rv;
}
}
return extracted;
}
@Override
public ItemStack addItems( ItemStack toBeAdded )
{
return this.addItems( toBeAdded, false );
}
protected ItemStack addItems( final ItemStack itemsToAdd, final boolean simulate )
{
if( itemsToAdd.isEmpty() )
{
return ItemStack.EMPTY;
}
ItemStack left = itemsToAdd.copy();
left = this.itemRepository.insertItem( left, simulate );
if( left.isEmpty() )
{
return ItemStack.EMPTY;
}
return left;
}
@Override
public ItemStack simulateAdd( ItemStack toBeSimulated )
{
return this.addItems( toBeSimulated, true );
}
@Override
public boolean containsItems()
{
return !this.itemRepository.getAllItems().isEmpty();
}
@Override
public boolean hasSlots()
{
return true;
}
@Override
public Iterator<ItemSlot> iterator()
{
return null;
}
}
@@ -25,7 +25,7 @@ import java.util.NoSuchElementException;
import net.minecraftforge.items.IItemHandler;
class ItemHandlerIterator implements Iterator<ItemSlot>
public class ItemHandlerIterator implements Iterator<ItemSlot>
{
private final IItemHandler itemHandler;
@@ -34,7 +34,7 @@ class ItemHandlerIterator implements Iterator<ItemSlot>
private int slot = 0;
ItemHandlerIterator( IItemHandler itemHandler )
public ItemHandlerIterator( IItemHandler itemHandler )
{
this.itemHandler = itemHandler;
}
@@ -55,8 +55,6 @@ class ItemHandlerIterator implements Iterator<ItemSlot>
this.itemSlot.setExtractable( !this.itemHandler.extractItem( this.slot, 1, true ).isEmpty() );
this.itemSlot.setItemStack( this.itemHandler.getStackInSlot( this.slot ) );
this.itemSlot.setSlot( this.slot );
this.itemSlot.setSlotLimit( this.itemHandler.getSlotLimit( this.slot ) );
this.itemSlot.setItemHandler( this.itemHandler );
this.slot++;
return this.itemSlot;
}
@@ -23,7 +23,6 @@ import net.minecraft.item.ItemStack;
import appeng.api.storage.data.IAEItemStack;
import appeng.util.item.AEItemStack;
import net.minecraftforge.items.IItemHandler;
public class ItemSlot
@@ -35,25 +34,6 @@ public class ItemSlot
private IAEItemStack aeItemStack;
private ItemStack itemStack;
public void setItemHandler( IItemHandler itemHandler )
{
this.itemHandler = itemHandler;
}
private IItemHandler itemHandler;
public int getSlotLimit()
{
return slotLimit;
}
public void setSlotLimit( int slotLimit )
{
this.slotLimit = slotLimit;
}
private int slotLimit;
public ItemStack getItemStack()
{
return this.itemStack
@@ -97,19 +77,4 @@ public class ItemSlot
{
this.slot = slot;
}
public ItemSlot copy()
{
ItemSlot copy = new ItemSlot();
copy.setSlot( this.slot );
copy.setSlotLimit( this.slotLimit );
copy.setItemStack( this.getItemStack() );
copy.setExtractable( this.isExtractable );
copy.setItemHandler( this.itemHandler );
return copy;
}
public ItemStack insertItem( ItemStack sourceItemStack){
return this.itemHandler.insertItem( this.slot, sourceItemStack , true );
}
}