Compare commits

..

4 Commits

50 changed files with 743 additions and 1083 deletions
+2 -13
View File
@@ -15,10 +15,6 @@ Fixes:
- Exclusive Blocking mode for GTCE ( shapes, molds and configured circuits do not block GTCE machines )
- Blocking modes default to block on any item in the iventory the entity exposes
- Fuzzy includes items that report that they're damageable, but report a maxDamage of 0 ( auto-crafting of basic capacitors -> resonant capacitors is now possible ) <- Broken item implementation.
- Fix CME exceptions on the energy grid
- Fix AE going offline even with enough power by extracting from the local buffer always last
- Fix IO-Port copying craftable flag into items
- Fix NBT of old items not clearing on drives that reached 64 types once
Performance:
@@ -28,9 +24,6 @@ Performance:
- Count items set in interfaces before queuing crafting for them needlessly
- Backported b7ca98d ( Avoid copying items on simulated item extraction )
- Cache some level emitters functions
- Reduced import bus insert simulation to 1 before real insertion (if possible)
- Backported itemlist re-implementation along with pattern changes to avoid CraftingManager fallback issues
- Instead of recalculating all the content of the network on every change, track the changes properly and apply them to the cached list of items
QOL:
@@ -38,7 +31,7 @@ QOL:
- Added bar on the interface terminal that search by inputs ( The one on the LEFT, also searchs by interface name )
- Shortcut to molecular assemblers with free slots on the terminal interface by @Theisyat
- Toggle button on interface terminal to hide full interfaces
- JEI "U", "R" and "A" (Usages/Recipes/Bookmark) now work on the Crafting Status GUI. ( the one that shows the total items to craft, and whats missing)
- JEI "U""R" and "A" (Usages/Recipes/Bookmark) now work on the Crafting Status GUI. ( the one that shows the total items to craft, and whats missing)
- Patterns can now be made with items currently showing on JEI. ( This is overriden by Just Enough Energistics. )
- Added multiplier buttons to processing pattern gui
- Switched crafting terminal JEI search to fuzzy mode. If the recipe uses a damageable item, AE will try to grab it ( damaged tools )
@@ -46,11 +39,7 @@ QOL:
- Encoded patterns can be draggred on the interface terminal.
- Storage Monitor and Conversion Monitor now also ccepts fluids
- Draggable JEI ghost items (also works on bookmarked items. SHIFT + Click will move the hovered item into the first free target slot)
- JEI auto switches between crafting and processing patterns
- GTCE Blocking mode work through phantom itemfaces
- Shift-clicking blank patterns into the pattern terminal will try to fill the blank pattern slots first
- Mismached simulated/real item count ( most often due to compacting drawers ) will now tell the player wich item cause the failure when trying to start a craft
- Added 'pattern expansion' cards that adds an extra row of patterns to interfaces. up to 3 card on an interface. (each card will increase the interface idle power draw by 4 times)
-JEI auto switches between crafting and processing patterns
HOTKEYS:
+1 -1
View File
@@ -3,7 +3,7 @@ aechannel=stable
aebuild=7
aegroup=appeng
aebasename=appliedenergistics2
trousers=omni-fixes-v46aa
trousers=omni-fixes-v44
#########################################################
# Versions #
@@ -47,5 +47,5 @@ public interface IStackWatcherHost
* @param diffStack new stack
* @param chan storage channel
*/
void onStackChange( IItemList<?> o, IAEStack<?> fullStack, IAEStack<?> diffStack, IActionSource src, IStorageChannel<?> chan );
void onStackChange( IAEStack<?> diffStack, IStorageChannel<?> chan );
}
@@ -51,7 +51,6 @@ public interface IStorageGrid extends IGridCache, IStorageMonitorable
* @param input injected items
*/
void postAlterationOfStoredItems( IStorageChannel<?> chan, Iterable<? extends IAEStack<?>> input, IActionSource src );
void postCraftablesChanges( IStorageChannel<?> chan, Iterable<? extends IAEStack<?>> input, IActionSource src);
/**
* Used to add a cell provider to the storage system
@@ -52,4 +52,9 @@ public interface IMEMonitorHandlerReceiver<T extends IAEStack<T>>
* called when the list updates its contents, this is mostly for handling power events.
*/
void onListUpdate();
default boolean hasListeners()
{
return true;
}
}
@@ -237,11 +237,7 @@ public class GuiInterfaceTerminal extends AEBaseGui
int interfaceDim = dimHashMap.get( guiButtonHashMap.get( this.selectedButton ) );
if( playerDim != interfaceDim )
{
try {
mc.player.sendStatusMessage( new TextComponentString( "Interface located at dimension: " + interfaceDim + " [" + DimensionManager.getWorld( interfaceDim ).provider.getDimensionType().getName() + "] and cant be highlighted" ), false );
} catch(Exception e){
mc.player.sendStatusMessage( new TextComponentString( "Interface is located in another dimension and cannot be highlighted" ), false );
}
mc.player.sendStatusMessage( new TextComponentString( "Interface located at dimension: " + interfaceDim + " [" + DimensionManager.getWorld( interfaceDim ).provider.getDimensionType().getName() + "] and cant be highlighted" ), false );
}
else
{
@@ -270,15 +270,12 @@ public class GuiUpgradeable extends AEBaseGui implements IJEIGhostIngredients
@Override
public Rectangle getArea()
{
if( slot instanceof SlotFake && ( (SlotFake) slot ).isSlotEnabled() )
{
if( slot instanceof SlotFake )
return new Rectangle( getGuiLeft() + ( (SlotFake) slot ).xPos, getGuiTop() + ( (SlotFake) slot ).yPos, 16, 16 );
}
else if( slot instanceof GuiFluidSlot && ( (GuiFluidSlot) slot ).isSlotEnabled() )
else
{
return new Rectangle( getGuiLeft() + ( (GuiFluidSlot) slot ).xPos(), getGuiTop() + ( (GuiFluidSlot) slot ).yPos(), 16, 16 );
}
return new Rectangle();
}
@Override
@@ -287,7 +284,7 @@ public class GuiUpgradeable extends AEBaseGui implements IJEIGhostIngredients
PacketInventoryAction p = null;
try
{
if( slot instanceof SlotFake && ( (SlotFake) slot ).isSlotEnabled() )
if( slot instanceof SlotFake )
{
if( finalItemStack.isEmpty() && finalFluidStack != null )
{
@@ -10,9 +10,9 @@ import net.minecraft.item.ItemStack;
public abstract class GuiCustomSlot extends Gui implements ITooltip
{
protected final int x;
protected final int y;
protected final int id;
private final int x;
private final int y;
private final int id;
public GuiCustomSlot( final int id, final int x, final int y )
{
@@ -22,10 +22,9 @@ package appeng.client.render;
import appeng.api.storage.data.IAEFluidStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.renderer.*;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.RenderItem;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
@@ -33,7 +32,6 @@ import appeng.api.storage.data.IAEItemStack;
import appeng.util.IWideReadableNumberConverter;
import appeng.util.ReadableNumberConverter;
import net.minecraftforge.fluids.FluidStack;
import org.lwjgl.opengl.GL11;
/**
@@ -123,49 +121,6 @@ public class TesrRenderHelper
}
}
public static void renderFluid2d( FluidStack fluidStack, float scale )
{
if( fluidStack != null )
{
GlStateManager.pushMatrix();
int color = fluidStack.getFluid().getColor( fluidStack );
float r = ( color >> 16 & 255 ) / 255.0f;
float g = ( color >> 8 & 255 ) / 255.0f;
float b = ( color & 255 ) / 255.0f;
TextureAtlasSprite sprite = Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite( fluidStack.getFluid().getStill( fluidStack ).toString() );
GlStateManager.enableBlend();
GlStateManager.blendFunc( GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA );
GlStateManager.disableAlpha();
GlStateManager.disableLighting();
Minecraft.getMinecraft().getTextureManager().bindTexture( TextureMap.LOCATION_BLOCKS_TEXTURE );
Tessellator tess = Tessellator.getInstance();
BufferBuilder buf = tess.getBuffer();
float width = 0.4f;
float height = 0.4f;
float alpha = 1.0f;
float z = 0.0001f;
float x = -0.20f;
float y = -0.25f;
buf.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR );
double uMin = sprite.getInterpolatedU( 16D - width * 16D ), uMax = sprite.getInterpolatedU( width * 16D );
double vMin = sprite.getMinV(), vMax = sprite.getInterpolatedV( height * 16D );
buf.pos( x, y, z ).tex( uMin, vMin ).color( r, g, b, alpha ).endVertex();
buf.pos( x, y + height, z ).tex( uMin, vMax ).color( r, g, b, alpha ).endVertex();
buf.pos( x + width, y + height, z ).tex( uMax, vMax ).color( r, g, b, alpha ).endVertex();
buf.pos( x + width, y, z ).tex( uMax, vMin ).color( r, g, b, alpha ).endVertex();
tess.draw();
GlStateManager.enableLighting();
GlStateManager.enableAlpha();
GlStateManager.disableBlend();
GlStateManager.color( 1F, 1F, 1F, 1F );
GlStateManager.popMatrix();
}
}
/**
* Render an item in 2D and the given text below it.
*
@@ -192,9 +147,9 @@ public class TesrRenderHelper
public static void renderFluid2dWithAmount( IAEFluidStack fluidStack, float scale, float spacing )
{
final FluidStack renderStack = fluidStack.getFluidStack();
final ItemStack renderStack = fluidStack.asItemStackRepresentation();
TesrRenderHelper.renderFluid2d( renderStack, scale );
TesrRenderHelper.renderItem2d( renderStack, scale );
final long stackSize = fluidStack.getStackSize() / 1000;
final String renderedStackSize = NUMBER_CONVERTER.toWideReadableForm( stackSize ) + "B";
@@ -245,10 +245,7 @@ public class PacketJEIRecipe extends AppEngPacket
if( out != null )
{
if (!cct.useRealItems())
{
out.setStackSize( recipe[x][y].getCount() );
}
out.setStackSize( recipe[x][y].getCount() );
currentItem = out.createItemStack();
}
}
@@ -19,7 +19,6 @@
package appeng.core.sync.packets;
import appeng.fluids.container.ContainerFluidInterface;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
@@ -91,9 +90,5 @@ public class PacketTargetFluidStack extends AppEngPacket
{
( (ContainerFluidTerminal) player.openContainer ).setTargetStack( this.stack );
}
else if( player.openContainer instanceof ContainerFluidInterface )
{
( (ContainerFluidInterface) player.openContainer ).setTargetStack( this.stack );
}
}
}
+3 -56
View File
@@ -59,7 +59,6 @@ public class CraftingJob implements Runnable, ICraftingJob
private final IItemList<IAEItemStack> missing = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
private final HashMap<String, TwoIntegers> opsAndMultiplier = new HashMap<>();
private final Object monitor = new Object();
private final Stopwatch watch = Stopwatch.createUnstarted();
private CraftingTreeNode tree;
private final IAEItemStack output;
private boolean simulate = false;
@@ -67,10 +66,7 @@ public class CraftingJob implements Runnable, ICraftingJob
private long bytes = 0;
private final IActionSource actionSrc;
private final ICraftingCallback callback;
private boolean running = false;
private boolean done = false;
private int time;
private int incTime;
private World wrapWorld( final World w )
{
@@ -137,7 +133,6 @@ public class CraftingJob implements Runnable, ICraftingJob
try
{
TickHandler.INSTANCE.registerCraftingSimulation( this.world, this );
this.handlePausing();
final Stopwatch timer = Stopwatch.createStarted();
@@ -219,41 +214,6 @@ public class CraftingJob implements Runnable, ICraftingJob
this.finish();
}
void handlePausing() throws InterruptedException
{
if( !this.actionSrc.player().isPresent() && this.incTime > 100 )
{
this.incTime = 0;
synchronized ( this.monitor )
{
if( this.watch.elapsed( TimeUnit.MICROSECONDS ) > this.time )
{
this.running = false;
this.watch.stop();
this.monitor.notify();
}
if( !this.running )
{
AELog.craftingDebug( "crafting job will now sleep" );
while ( !this.running )
{
this.monitor.wait();
}
AELog.craftingDebug( "crafting job now active" );
}
}
if( Thread.interrupted() )
{
throw new InterruptedException();
}
}
this.incTime++;
}
private void finish()
{
if( this.callback != null )
@@ -265,7 +225,6 @@ public class CraftingJob implements Runnable, ICraftingJob
synchronized( this.monitor )
{
this.running = false;
this.done = true;
this.monitor.notify();
}
@@ -311,25 +270,13 @@ public class CraftingJob implements Runnable, ICraftingJob
/**
* @return true if this needs more simulation
*/
public boolean simulateFor(final int milli)
public boolean simulateFor()
{
this.time = milli;
synchronized ( this.monitor )
{
if( this.done )
{
synchronized( this.monitor ) {
if ( this.done ) {
return false;
}
if( !this.actionSrc.player().isPresent() )
{
this.watch.reset();
this.watch.start();
this.monitor.notify();
}
this.running = true;
}
return true;
}
@@ -119,7 +119,7 @@ public class CraftingTreeNode
IAEItemStack request( final MECraftingInventory inv, long l, final IActionSource src ) throws CraftBranchFailure, InterruptedException
{
this.job.handlePausing();
final List<IAEItemStack> thingsUsed = new ArrayList<>();
this.what.setStackSize( l );
@@ -185,7 +185,7 @@ public class CraftingTreeProcess
void request( final MECraftingInventory inv, final long i, final IActionSource src ) throws CraftBranchFailure, InterruptedException
{
this.job.handlePausing();
if( this.fullSimulation )
{
final InventoryCrafting ic = new InventoryCrafting( new ContainerNull(), 3, 3 );
@@ -305,7 +305,7 @@ public class CraftingTreeProcess
void getPlan( final IItemList<IAEItemStack> plan )
{
for( IAEItemStack i : this.details.getOutputs() )
for( IAEItemStack i : this.details.getCondensedOutputs() )
{
i = i.copy();
i.setCountRequestable( i.getStackSize() * this.crafts );
@@ -21,9 +21,6 @@ package appeng.fluids.client.gui;
import java.io.IOException;
import appeng.api.util.IConfigManager;
import appeng.client.gui.widgets.GuiCustomSlot;
import appeng.util.IConfigManagerHost;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.entity.player.InventoryPlayer;
@@ -41,12 +38,11 @@ import appeng.fluids.helper.IFluidInterfaceHost;
import appeng.fluids.util.IAEFluidTank;
public class GuiFluidInterface extends GuiUpgradeable implements IConfigManagerHost
public class GuiFluidInterface extends GuiUpgradeable
{
public final static int ID_BUTTON_TANK = 222;
private final IFluidInterfaceHost host;
private final ContainerFluidInterface container;
private GuiTabButton priority;
public GuiFluidInterface( final InventoryPlayer ip, final IFluidInterfaceHost te )
@@ -54,8 +50,6 @@ public class GuiFluidInterface extends GuiUpgradeable implements IConfigManagerH
super( new ContainerFluidInterface( ip, te ) );
this.ySize = 231;
this.host = te;
( this.container = (ContainerFluidInterface) this.inventorySlots ).setGui( this );
}
@Override
@@ -68,7 +62,9 @@ public class GuiFluidInterface extends GuiUpgradeable implements IConfigManagerH
for( int i = 0; i < DualityFluidInterface.NUMBER_OF_TANKS; ++i )
{
this.guiSlots.add( new GuiFluidTank( fluidTank, i, DualityFluidInterface.NUMBER_OF_TANKS + i, 36 + 18 * i, 53, 16, 68 ) );
final GuiFluidTank guiTank = new GuiFluidTank( fluidTank, i, DualityFluidInterface.NUMBER_OF_TANKS + i, this.getGuiLeft() + 35 + 18 * i, this
.getGuiTop() + 53, 16, 68 );
this.buttonList.add( guiTank );
this.guiSlots.add( new GuiFluidSlot( configFluids, i, i, 35 + 18 * i, 35 ) );
}
@@ -108,33 +104,9 @@ public class GuiFluidInterface extends GuiUpgradeable implements IConfigManagerH
}
}
@Override
protected void mouseClicked( int xCoord, int yCoord, int btn ) throws IOException
{
for( GuiCustomSlot slot : this.guiSlots )
{
if( slot instanceof GuiFluidTank )
{
if( this.isPointInRegion( slot.xPos(), slot.yPos(), slot.getWidth(), slot.getHeight(), xCoord, yCoord ) && slot.canClick( this.mc.player ) )
{
this.container.setTargetStack( ( (GuiFluidTank) slot ).getFluidStack() );
slot.slotClicked( this.mc.player.inventory.getItemStack(), btn );
return;
}
}
}
super.mouseClicked( xCoord, yCoord, btn );
}
@Override
protected boolean drawUpgrades()
{
return false;
}
@Override
public void updateSetting( IConfigManager manager, Enum settingName, Enum newValue )
{
}
}
@@ -19,50 +19,42 @@
package appeng.fluids.client.gui.widgets;
import appeng.client.gui.widgets.GuiCustomSlot;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketInventoryAction;
import appeng.helpers.InventoryAction;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.util.AEColor;
import appeng.client.gui.widgets.ITooltip;
import appeng.fluids.util.IAEFluidTank;
@SideOnly( Side.CLIENT )
public class GuiFluidTank extends GuiCustomSlot implements ITooltip
public class GuiFluidTank extends GuiButton implements ITooltip
{
private final IAEFluidTank tank;
private final int slot;
private final int width;
private final int height;
public GuiFluidTank( IAEFluidTank tank, int slot, int id, int x, int y, int w, int h )
{
super( id, x, y );
super( id, x, y, w, h, "" );
this.tank = tank;
this.slot = slot;
this.width = w;
this.height = h;
}
@Override
public void drawContent( Minecraft mc, int mouseX, int mouseY, float partialTicks )
public void drawButton( final Minecraft mc, final int mouseX, final int mouseY, final float partialTicks )
{
final IAEFluidStack fs = this.getFluidStack();
if( fs != null )
if( this.visible )
{
GlStateManager.disableBlend();
GlStateManager.disableLighting();
//drawRect( this.x, this.y, this.x + this.width, this.y + this.height, AEColor.GRAY.blackVariant | 0xFF000000 );
drawRect( this.x, this.y, this.x + this.width, this.y + this.height, AEColor.GRAY.blackVariant | 0xFF000000 );
final IAEFluidStack fluid = this.tank.getFluidInSlot( this.slot );
if( fluid != null && fluid.getStackSize() > 0 )
@@ -77,16 +69,17 @@ public class GuiFluidTank extends GuiCustomSlot implements ITooltip
TextureAtlasSprite sprite = mc.getTextureMapBlocks().getAtlasSprite( fluid.getFluid().getStill().toString() );
final int scaledHeight = (int) ( this.height * ( (float) fluid.getStackSize() / this.tank.getTankProperties()[this.slot].getCapacity() ) );
int iconHeightRemainder = scaledHeight % this.getHeight();
int iconHeightRemainder = scaledHeight % 16;
if( iconHeightRemainder > 0 )
{
this.drawTexturedModalRect( this.xPos(), this.yPos() + this.getHeight() - iconHeightRemainder, sprite, this.getWidth(), iconHeightRemainder );
this.drawTexturedModalRect( this.x, this.y + this.height - iconHeightRemainder, sprite, 16, iconHeightRemainder );
}
for( int i = 0; i < scaledHeight / this.getHeight(); i++ )
for( int i = 0; i < scaledHeight / 16; i++ )
{
this.drawTexturedModalRect( this.xPos(), this.yPos() + this.getHeight() - iconHeightRemainder - ( i + 1 ) * 16, sprite, this.getWidth(), this.getHeight() );
this.drawTexturedModalRect( this.x, this.y + this.height - iconHeightRemainder - ( i + 1 ) * 16, sprite, 16, 16 );
}
}
}
}
@@ -107,25 +100,25 @@ public class GuiFluidTank extends GuiCustomSlot implements ITooltip
@Override
public int xPos()
{
return this.x - 1;
return this.x - 2;
}
@Override
public int yPos()
{
return this.y - 1;
return this.y - 2;
}
@Override
public int getWidth()
{
return this.width;
return this.width + 4;
}
@Override
public int getHeight()
{
return this.height + 1;
return this.height + 4;
}
@Override
@@ -134,24 +127,4 @@ public class GuiFluidTank extends GuiCustomSlot implements ITooltip
return true;
}
public IAEFluidStack getFluidStack()
{
return this.tank.getFluidInSlot( this.slot );
}
@Override
public void slotClicked( ItemStack clickStack, final int mouseButton )
{
if( getFluidStack() != null )
{
NetworkHandler.instance().sendToServer( new PacketInventoryAction( InventoryAction.FILL_ITEM, slot, 0 ) );
}
else
{
NetworkHandler.instance().sendToServer( new PacketInventoryAction( InventoryAction.EMPTY_ITEM, slot, 0 ) );
}
}
}
@@ -19,17 +19,9 @@
package appeng.fluids.container;
import javax.annotation.Nonnull;
import java.util.Collections;
import java.util.Map;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketTargetFluidStack;
import appeng.fluids.util.AEFluidStack;
import appeng.helpers.InventoryAction;
import appeng.util.IConfigManagerHost;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.IContainerListener;
@@ -41,19 +33,12 @@ import appeng.fluids.helper.FluidSyncHelper;
import appeng.fluids.helper.IFluidInterfaceHost;
import appeng.fluids.util.IAEFluidTank;
import appeng.util.Platform;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidUtil;
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
public class ContainerFluidInterface extends ContainerFluidConfigurable implements IConfigManagerHost
public class ContainerFluidInterface extends ContainerFluidConfigurable
{
private final DualityFluidInterface myDuality;
private final FluidSyncHelper tankSync;
private IConfigManagerHost gui;
// Holds the fluid the client wishes to extract, or null for insert
private IAEFluidStack clientRequestedTargetFluid = null;
public ContainerFluidInterface( final InventoryPlayer ip, final IFluidInterfaceHost te )
{
@@ -75,15 +60,6 @@ public class ContainerFluidInterface extends ContainerFluidConfigurable implemen
return this.myDuality.getConfig();
}
@Override
public void updateSetting( IConfigManager manager, Enum settingName, Enum newValue )
{
if( this.getGui() != null )
{
this.getGui().updateSetting( manager, settingName, newValue );
}
}
@Override
public void detectAndSendChanges()
{
@@ -121,126 +97,6 @@ public class ContainerFluidInterface extends ContainerFluidConfigurable implemen
this.tankSync.readPacket( fluids );
}
private IConfigManagerHost getGui()
{
return this.gui;
}
public void setGui( @Nonnull final IConfigManagerHost gui )
{
this.gui = gui;
}
public void doAction( EntityPlayerMP player, InventoryAction action, int slot, long id )
{
if( action != InventoryAction.FILL_ITEM && action != InventoryAction.EMPTY_ITEM )
{
super.doAction( player, action, slot, id );
return;
}
final ItemStack held = player.inventory.getItemStack();
ItemStack heldCopy = held.copy();
heldCopy.setCount( 1 );
IFluidHandlerItem fh = FluidUtil.getFluidHandler( heldCopy );
if( fh == null )
{
// only fluid handlers items
return;
}
if( action == InventoryAction.FILL_ITEM && this.clientRequestedTargetFluid != null )
{
final IAEFluidStack stack = this.clientRequestedTargetFluid.copy();
// Check how much we can store in the item
stack.setStackSize( Integer.MAX_VALUE );
int amountAllowed = fh.fill( stack.getFluidStack(), false );
int heldAmount = held.getCount();
for( int i = 0; i < heldAmount; i++ )
{
ItemStack copiedFluidContainer = held.copy();
copiedFluidContainer.setCount( 1 );
fh = FluidUtil.getFluidHandler( copiedFluidContainer );
FluidStack extractableFluid = this.myDuality.getTanks().drain( stack.setStackSize( amountAllowed ).getFluidStack(), false );
if( extractableFluid == null || extractableFluid.amount == 0 )
{
break;
}
int fillableAmount = fh.fill( extractableFluid, false );
if( fillableAmount > 0 )
{
FluidStack extractedFluid = this.myDuality.getTanks().drain( extractableFluid, true );
fh.fill( extractedFluid, true );
}
if( held.getCount() == 1 )
{
player.inventory.setItemStack( fh.getContainer() );
}
else
{
player.inventory.getItemStack().shrink( 1 );
if( !player.inventory.addItemStackToInventory( fh.getContainer() ) )
{
player.dropItem( fh.getContainer(), false );
}
}
}
}
else if( action == InventoryAction.EMPTY_ITEM )
{
int heldAmount = held.getCount();
for( int i = 0; i < heldAmount; i++ )
{
ItemStack copiedFluidContainer = held.copy();
copiedFluidContainer.setCount( 1 );
fh = FluidUtil.getFluidHandler( copiedFluidContainer );
FluidStack drainable = fh.drain( this.myDuality.getTanks().getTankProperties()[slot].getCapacity(), false );
if( drainable != null )
{
fh.drain( drainable, true );
this.myDuality.getTanks().fill( drainable, true );
}
if( held.getCount() == 1 )
{
player.inventory.setItemStack( fh.getContainer() );
}
else
{
player.inventory.getItemStack().shrink( 1 );
if( !player.inventory.addItemStackToInventory( fh.getContainer() ) )
{
player.dropItem( fh.getContainer(), false );
}
}
}
}
this.updateHeld( player );
}
public void setTargetStack( final IAEFluidStack stack )
{
if( Platform.isClient() )
{
if( stack == null && this.clientRequestedTargetFluid == null )
{
return;
}
if( stack != null && this.clientRequestedTargetFluid != null && stack.getFluidStack().isFluidEqual( this.clientRequestedTargetFluid.getFluidStack() ) )
{
return;
}
NetworkHandler.instance().sendToServer( new PacketTargetFluidStack( (AEFluidStack) stack ) );
}
this.clientRequestedTargetFluid = stack == null ? null : stack.copy();
}
@Override
protected boolean supportCapacity()
{
@@ -91,10 +91,12 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
private int isWorking = -1;
private int priority;
private final MEMonitorPassThrough<IAEItemStack> items = new MEMonitorPassThrough<>( new NullInventory<IAEItemStack>(), AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) );
private final MEMonitorPassThrough<IAEFluidStack> fluids = new MEMonitorPassThrough<>( new NullInventory<IAEFluidStack>(), AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) );
private boolean resetConfigCache;
private IMEMonitor<IAEFluidStack> configCachedHandler;
private final MEMonitorPassThrough<IAEItemStack> items = new MEMonitorPassThrough<>( new NullInventory<IAEItemStack>(), AEApi.instance()
.storage()
.getStorageChannel( IItemStorageChannel.class ) );
private final MEMonitorPassThrough<IAEFluidStack> fluids = new MEMonitorPassThrough<>( new NullInventory<IAEFluidStack>(), AEApi.instance()
.storage()
.getStorageChannel( IFluidStorageChannel.class ) );
public DualityFluidInterface( final AENetworkProxy networkProxy, final IFluidInterfaceHost ih )
{
@@ -144,12 +146,7 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
{
if( this.hasConfig() )
{
if( resetConfigCache )
{
resetConfigCache = false;
configCachedHandler = new InterfaceInventory( this );
}
return (IMEMonitor<T>) configCachedHandler;
return (IMEMonitor<T>) new InterfaceInventory( this );
}
return (IMEMonitor<T>) this.fluids;
@@ -453,12 +450,7 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
if( inventory == this.config )
{
boolean cfg = hasConfig();
this.readConfig();
if( cfg != hasConfig )
{
resetConfigCache = true;
}
}
else if( inventory == this.tanks )
{
@@ -563,6 +555,7 @@ public class DualityFluidInterface implements IGridTickable, IStorageMonitorable
InterfaceInventory( final DualityFluidInterface tileInterface )
{
super( tileInterface.tanks );
this.setActionSource( new MachineSource( tileInterface.iHost ) );
}
@Override
@@ -19,15 +19,15 @@
package appeng.fluids.parts;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Settings;
import appeng.api.config.StorageFilter;
import appeng.api.storage.data.IAEItemStack;
import appeng.me.GridAccessException;
import appeng.util.inv.ItemSlot;
import net.minecraft.item.ItemStack;
import appeng.parts.misc.PartStorageBus;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.IFluidTankProperties;
@@ -63,20 +63,17 @@ public class FluidHandlerAdapter implements IMEInventory<IAEFluidStack>, IBaseMo
private final IGridProxyable proxyable;
private final FluidHandlerAdapter.InventoryCache cache;
private StorageFilter mode;
private AccessRestriction access;
FluidHandlerAdapter( IFluidHandler fluidHandler, IGridProxyable proxy )
{
this.fluidHandler = fluidHandler;
this.proxyable = proxy;
if( this.proxyable instanceof PartFluidStorageBus )
if( this.proxyable instanceof PartStorageBus )
{
PartFluidStorageBus partFluidStorageBus = (PartFluidStorageBus) this.proxyable;
this.mode = ( (StorageFilter) partFluidStorageBus.getConfigManager().getSetting( Settings.STORAGE_FILTER ) );
this.access = ( (AccessRestriction) partFluidStorageBus.getConfigManager().getSetting( Settings.ACCESS ) );
PartStorageBus partStorageBus = (PartStorageBus) this.proxyable;
this.mode = ( (StorageFilter) partStorageBus.getConfigManager().getSetting( Settings.STORAGE_FILTER ) );
}
this.cache = new FluidHandlerAdapter.InventoryCache( this.fluidHandler, this.mode );
this.cache.update();
this.cache = new FluidHandlerAdapter.InventoryCache( this.fluidHandler, this.mode);
}
@Override
@@ -95,17 +92,9 @@ public class FluidHandlerAdapter implements IMEInventory<IAEFluidStack>, IBaseMo
if( type == Actionable.MODULATE )
{
IAEFluidStack added = input.copy().setStackSize( input.getStackSize() - remaining );
this.cache.currentlyCached.add( added );
this.postDifference( Collections.singletonList( added ) );
try
{
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
}
catch( GridAccessException ex )
{
// meh
}
this.cache
.currentlyCached
.add( input.copy().setStackSize( wasFillled ));
}
fluidStack.amount = remaining;
@@ -130,19 +119,10 @@ public class FluidHandlerAdapter implements IMEInventory<IAEFluidStack>, IBaseMo
IAEFluidStack gatheredAEFluidstack = AEFluidStack.fromFluidStack( gathered );
if( mode == Actionable.MODULATE )
{
IAEFluidStack cachedStack = this.cache.currentlyCached.findPrecise( request );
if( cachedStack != null )
IAEFluidStack e = this.cache.currentlyCached.findPrecise( gatheredAEFluidstack );
if (e != null)
{
cachedStack.decStackSize( gatheredAEFluidstack.getStackSize() );
this.postDifference( Collections.singletonList( gatheredAEFluidstack.copy().setStackSize( -gatheredAEFluidstack.getStackSize() ) ) );
}
try
{
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
}
catch( GridAccessException ex )
{
// meh
e.decStackSize( gathered.amount );
}
}
return gatheredAEFluidstack;
@@ -152,7 +132,7 @@ public class FluidHandlerAdapter implements IMEInventory<IAEFluidStack>, IBaseMo
public TickRateModulation onTick()
{
List<IAEFluidStack> changes = this.cache.update();
if( !changes.isEmpty() && access.hasPermission( AccessRestriction.READ ) )
if( !changes.isEmpty() )
{
this.postDifference( changes );
return TickRateModulation.URGENT;
@@ -217,6 +197,7 @@ public class FluidHandlerAdapter implements IMEInventory<IAEFluidStack>, IBaseMo
private final StorageFilter mode;
IItemList<IAEFluidStack> currentlyCached = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList();
public InventoryCache( IFluidHandler fluidHandler, StorageFilter mode )
{
this.mode = mode;
@@ -232,11 +213,18 @@ public class FluidHandlerAdapter implements IMEInventory<IAEFluidStack>, IBaseMo
for( IFluidTankProperties tankProperty : tankProperties )
{
if( this.mode == StorageFilter.EXTRACTABLE_ONLY && this.fluidHandler.drain( 1, false ) == null )
FluidStack newFS = tankProperty.getContents();
if( this.mode == StorageFilter.EXTRACTABLE_ONLY && newFS != null )
{
continue;
if( this.fluidHandler.drain( 1, false ) == null )
{
newFS = null;
}
}
if( newFS != null )
{
currentlyOnStorage.add( AEFluidStack.fromFluidStack( newFS ) );
}
currentlyOnStorage.add( AEFluidStack.fromFluidStack( tankProperty.getContents() ) );
}
for ( final IAEFluidStack is : currentlyCached )
@@ -204,7 +204,7 @@ public class PartFluidFormationPlane extends PartAbstractFormationPlane<IAEFluid
@Override
public List<IMEInventoryHandler> getCellArray( final IStorageChannel channel )
{
if( channel == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) )
if( this.getProxy().isActive() && channel == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) )
{
final List<IMEInventoryHandler> handler = new ArrayList<>( 1 );
handler.add( this.myHandler );
@@ -5,7 +5,6 @@ package appeng.fluids.parts;
import java.util.Random;
import appeng.api.networking.events.MENetworkChannelChanged;
import appeng.api.storage.data.IItemList;
import appeng.fluids.helper.IConfigurableFluidInventory;
import appeng.me.cache.NetworkMonitor;
import net.minecraft.entity.player.EntityPlayer;
@@ -114,7 +113,7 @@ public class PartFluidLevelEmitter extends PartUpgradeable implements IStackWatc
}
@Override
public void onStackChange( IItemList<?> o, IAEStack<?> fullStack, IAEStack<?> diffStack, IActionSource src, IStorageChannel<?> chan )
public void onStackChange( IAEStack<?> diffStack, IStorageChannel<?> chan )
{
if( chan == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) && diffStack.equals( this.config.getFluidInSlot( 0 ) ) )
{
@@ -26,7 +26,6 @@ import java.util.Objects;
import javax.annotation.Nonnull;
import appeng.fluids.helper.IConfigurableFluidInventory;
import appeng.util.ConfigManager;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
@@ -168,28 +167,11 @@ public class PartFluidStorageBus extends PartSharedStorageBus implements IMEMoni
final boolean fullReset = this.resetCacheLogic == 2;
this.resetCacheLogic = 0;
final MEInventoryHandler<IAEFluidStack> in = this.getInternalHandler();
final IMEInventory<IAEFluidStack> in = this.getInternalHandler();
IItemList<IAEFluidStack> before = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList();
boolean denyRead = false;
if( in != null )
{
if( accessChanged )
{
AccessRestriction currentAccess = (AccessRestriction) ( (ConfigManager) this.getConfigManager() ).getSetting( Settings.ACCESS );
AccessRestriction oldAccess = (AccessRestriction) ( (ConfigManager) this.getConfigManager() ).getOldSetting( Settings.ACCESS );
if( oldAccess.hasPermission( AccessRestriction.READ ) && !currentAccess.hasPermission( AccessRestriction.READ ) )
{
denyRead = true;
}
in.setBaseAccess( oldAccess );
before = in.getAvailableItems( before );
in.setBaseAccess( currentAccess );
accessChanged = false;
}
else
{
before = in.getAvailableItems( before );
}
before = in.getAvailableItems( before );
}
this.cached = false;
@@ -198,17 +180,15 @@ public class PartFluidStorageBus extends PartSharedStorageBus implements IMEMoni
this.handlerHash = 0;
}
final MEInventoryHandler<IAEFluidStack> out = this.getInternalHandler();
final IMEInventory<IAEFluidStack> out = this.getInternalHandler();
if( in != out || denyRead )
if( in != out )
{
IItemList<IAEFluidStack> after = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList();
if( out != null && !denyRead )
if( out != null )
{
after = out.getAvailableItems( after );
}
Platform.postListChanges( before, after, this, this.source );
}
}
@@ -227,7 +207,7 @@ public class PartFluidStorageBus extends PartSharedStorageBus implements IMEMoni
{
this.resetCacheLogic = 2;
}
else if( this.resetCacheLogic < 2 )
else
{
this.resetCacheLogic = 1;
}
@@ -284,14 +264,6 @@ public class PartFluidStorageBus extends PartSharedStorageBus implements IMEMoni
@Override
public void postChange( final IBaseMonitor<IAEFluidStack> monitor, final Iterable<IAEFluidStack> change, final IActionSource source )
{
if( this.source.machine().map( machine -> machine == this ).orElse( false ) && monitor != null )
{
AccessRestriction currentAccess = (AccessRestriction) ( (ConfigManager) this.getConfigManager() ).getSetting( Settings.ACCESS );
if( !currentAccess.hasPermission( AccessRestriction.READ ) )
{
return;
}
}
try
{
if( this.getProxy().isActive() )
@@ -326,10 +298,6 @@ public class PartFluidStorageBus extends PartSharedStorageBus implements IMEMoni
this.handlerHash = newHandlerHash;
this.handler = null;
if( this.monitor != null )
{
( (IBaseMonitor<IAEFluidStack>) monitor ).removeListener( this );
}
this.monitor = null;
if( target != null )
{
@@ -338,7 +306,6 @@ public class PartFluidStorageBus extends PartSharedStorageBus implements IMEMoni
{
this.monitor = (ITickingMonitor) inv;
this.monitor.setActionSource( new MachineSource( this ) );
this.monitor.setMode( (StorageFilter) this.getConfigManager().getSetting( Settings.STORAGE_FILTER ) );
}
if( inv != null )
@@ -23,6 +23,7 @@ import java.util.*;
import javax.annotation.Nullable;
import appeng.api.definitions.IItemDefinition;
import appeng.integration.modules.gregtech.GTCEInventoryAdaptor;
import appeng.util.*;
import appeng.util.inv.*;
@@ -34,6 +35,7 @@ import gregtech.api.metatileentity.MetaTileEntity;
import gregtech.api.metatileentity.MetaTileEntityHolder;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.init.Items;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.Item;
@@ -140,17 +142,15 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
private int isWorking = -1;
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 EnumMap<EnumFacing,List<ItemStack>> waitingToSendFacing = new EnumMap<>(EnumFacing.class);
private GTCEInventoryAdaptor GTad;
private boolean resetConfigCache = true;
private IMEMonitor<IAEItemStack> configCachedHandler;
public DualityInterface( final AENetworkProxy networkProxy, final IInterfaceHost ih )
{
this.gridProxy = networkProxy;
this.gridProxy.setFlags( GridFlags.REQUIRE_CHANNEL );
this.upgrades = new StackUpgradeInventory( this.gridProxy.getMachineRepresentation(), this, 4 );
this.upgrades = new StackUpgradeInventory( this.gridProxy.getMachineRepresentation(), this, 4);
this.cm.registerSetting( Settings.BLOCK, YesNo.NO );
this.cm.registerSetting( Settings.INTERFACE_TERMINAL, YesNo.YES );
@@ -178,14 +178,9 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
{
return;
}
if( inv == this.config && ( !removed.isEmpty() || !added.isEmpty() ) )
if( inv == this.config )
{
boolean cfg = hasConfig();
this.readConfig();
if( cfg != hasConfig )
{
resetConfigCache = true;
}
}
else if( inv == this.patterns && ( !removed.isEmpty() || !added.isEmpty() ) )
{
@@ -980,12 +975,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
{
if( this.hasConfig() )
{
if( resetConfigCache )
{
resetConfigCache = false;
configCachedHandler = new InterfaceInventory( this );
}
return (IMEMonitor<T>) configCachedHandler;
return (IMEMonitor<T>) new InterfaceInventory( this );
}
return (IMEMonitor<T>) this.items;
@@ -1593,6 +1583,7 @@ public class DualityInterface implements IGridTickable, IStorageMonitorable, IIn
public InterfaceInventory( final DualityInterface tileInterface )
{
super( new AdaptorItemHandler( tileInterface.storage ) );
this.setActionSource( new MachineSource( DualityInterface.this.iHost ) );
}
@Override
@@ -147,7 +147,7 @@ public class PatternHelper implements ICraftingPatternDetails, Comparable<Patter
}
}
}
final int outputLength = out.size();
final int outputLength = this.isCrafting ? CRAFTING_OUTPUT_LIMIT : PROCESSING_OUTPUT_LIMIT;
this.inputs = in.toArray(new IAEItemStack[ALL_INPUT_LIMIT]);
this.outputs = out.toArray(new IAEItemStack[outputLength]);
+12 -7
View File
@@ -187,15 +187,20 @@ public class TickHandler
if( ev.type == Type.WORLD && ev.phase == Phase.END )
{
final WorldTickEvent wte = (WorldTickEvent) ev;
synchronized ( this.craftingJobs )
synchronized( this.craftingJobs )
{
final Collection<CraftingJob> jobSet = this.craftingJobs.get( wte.world );
if (!jobSet.isEmpty()) {
final int jobSize = jobSet.size();
final int microSecondsPerTick = AEConfig.instance().getCraftingCalculationTimePerTick() * 1000;
final int simTime = Math.max(1, microSecondsPerTick / jobSize);
jobSet.removeIf( cj -> !cj.simulateFor( simTime ) );
if( !jobSet.isEmpty() )
{
final Iterator<CraftingJob> i = jobSet.iterator();
while( i.hasNext() )
{
final CraftingJob cj = i.next();
if( !cj.simulateFor() )
{
i.remove();
}
}
}
}
}
@@ -225,7 +225,7 @@ public class ItemEncodedPattern extends AEBaseItem implements ICraftingPatternIt
final ICraftingPatternDetails details = this.getPatternForItem( item, w );
out = details != null ? details.getOutputs()[0].createItemStack() : ItemStack.EMPTY;
out = details != null ? details.getCondensedOutputs()[0].createItemStack() : ItemStack.EMPTY;
SIMPLE_CACHE.put( item, out );
return out;
+12 -49
View File
@@ -30,6 +30,7 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
@@ -41,7 +42,10 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import it.unimi.dsi.fastutil.objects.*;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectRBTreeSet;
import it.unimi.dsi.fastutil.objects.ObjectSet;
import net.minecraft.world.World;
import appeng.api.AEApi;
@@ -270,14 +274,17 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
return;
}
final Object2ObjectMap<IAEItemStack, ImmutableList<ICraftingPatternDetails>> oldItems = new Object2ObjectOpenHashMap<>(this.craftableItems);
final Set<IAEItemStack> oldEmitableItems = new HashSet<>(this.emitableItems);
final Object2ObjectMap<IAEItemStack, ImmutableList<ICraftingPatternDetails>> oldItems = this.craftableItems;
// erase list.
this.craftingMethods.clear();
this.craftableItems.clear();
this.emitableItems.clear();
// update the stuff that was in the list...
this.storageGrid.postAlterationOfStoredItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), oldItems.keySet(),
new BaseActionSource() );
// re-create list..
for( final ICraftingProvider provider : this.craftingProviders )
{
@@ -289,7 +296,7 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
// new craftables!
for( final ICraftingPatternDetails details : this.craftingMethods.keySet() )
{
for( IAEItemStack out : details.getOutputs() )
for( IAEItemStack out : details.getCondensedOutputs() )
{
out = out.copy();
out.reset();
@@ -312,51 +319,7 @@ public class CraftingGridCache implements ICraftingGrid, ICraftingProviderHelper
this.craftableItems.put( e.getKey(), ImmutableList.copyOf( e.getValue() ) );
}
Object2ObjectMap<IAEItemStack, ImmutableList<ICraftingPatternDetails>> craftablesChanged = new Object2ObjectArrayMap<>();
ObjectSet<Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>>> i = oldItems.entrySet();
for ( Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>> ais : i) {
if (!this.craftableItems.containsKey( ais.getKey() )) {
IAEItemStack changedStack = ais.getKey().copy();
changedStack.reset();
changedStack.setCraftable( false );
craftablesChanged.put( changedStack, ais.getValue() );
}
}
ObjectSet<Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>>> j = this.craftableItems.entrySet();
for ( Entry<IAEItemStack, ImmutableList<ICraftingPatternDetails>> ais : j) {
if (!oldItems.containsKey( ais )){
IAEItemStack changedStack = ais.getKey().copy();
changedStack.reset();
changedStack.setCraftable( true );
craftablesChanged.put( changedStack, ais.getValue() );
}
}
for( final IAEItemStack st : oldEmitableItems )
{
if( !emitableItems.contains( st ) )
{
IAEItemStack changedStack = st.copy();
changedStack.reset();
changedStack.setCraftable( false );
craftablesChanged.put( changedStack, null );
}
}
for( final IAEItemStack st : this.emitableItems )
{
if( !oldEmitableItems.contains( st ) )
{
IAEItemStack changedStack = st.copy();
changedStack.reset();
changedStack.setCraftable( true );
craftablesChanged.put( changedStack, null );
}
}
this.storageGrid.postCraftablesChanges( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), craftablesChanged.keySet(),
this.storageGrid.postAlterationOfStoredItems( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ), this.craftableItems.keySet(),
new BaseActionSource() );
}
+13 -31
View File
@@ -231,7 +231,7 @@ public class EnergyGridCache implements IEnergyGrid
if( this.drainPerTick > 0.0001 )
{
final double drained = this.extractAEPower( this.getIdlePowerUsage(), Actionable.MODULATE, PowerMultiplier.CONFIG );
currentlyHasPower = drained >= this.drainPerTick - 0.001;
currentlyHasPower = drained >= this.drainPerTick - 0.001 && this.getStoredPower() > 0;
}
else
{
@@ -341,19 +341,12 @@ public class EnergyGridCache implements IEnergyGrid
final Iterator<IAEPowerStorage> it = this.providers.iterator();
ongoingExtractOperation = true;
boolean ls = false;
try
{
while ( extractedPower < amt && it.hasNext() )
{
final IAEPowerStorage node = it.next();
if( node == localStorage && mode == Actionable.MODULATE )
{
ls = true;
continue;
}
final double req = amt - extractedPower;
final double newPower = node.extractAEPower( req, mode, PowerMultiplier.ONE );
extractedPower += newPower;
@@ -365,25 +358,11 @@ public class EnergyGridCache implements IEnergyGrid
}
} finally
{
providers.removeIf( p -> providerToRemove.contains( p ) );
this.providerToRemove.clear();
ongoingExtractOperation = false;
}
if( ls && extractedPower < amt )
{
final double req = amt - extractedPower;
final double newPower = localStorage.extractAEPower( req, mode, PowerMultiplier.ONE );
extractedPower += newPower;
if( newPower < req )
{
providers.remove( localStorage );
}
}
providers.removeIf( p -> providerToRemove.contains( p ) );
this.providerToRemove.clear();
final double result = Math.min( extractedPower, amt );
if( mode == Actionable.MODULATE )
@@ -426,12 +405,11 @@ public class EnergyGridCache implements IEnergyGrid
}
} finally
{
requesters.removeIf( r -> requesterToRemove.contains( r ) );
this.requesterToRemove.clear();
ongoingInjectOperation = false;
}
requesters.removeIf( r -> requesterToRemove.contains( r ) );
this.requesterToRemove.clear();
final double overflow = Math.max( 0.0, amt );
if( mode == Actionable.MODULATE )
@@ -448,7 +426,7 @@ public class EnergyGridCache implements IEnergyGrid
double required = 0;
final Iterator<IAEPowerStorage> it = this.requesters.iterator();
while ( required < maxRequired && it.hasNext() )
while( required < maxRequired && it.hasNext() )
{
final IAEPowerStorage node = it.next();
if( node.getPowerFlow() != AccessRestriction.READ )
@@ -810,9 +788,13 @@ public class EnergyGridCache implements IEnergyGrid
if( this.stored < 0.01 )
{
EnergyGridCache.this.ticksSinceHasPowerChange = 0;
EnergyGridCache.this.publicPowerState( false, EnergyGridCache.this.myGrid );
refreshPower();
if (globalAvailablePower < MAX_BUFFER_STORAGE - 0.001)
{
EnergyGridCache.this.ticksSinceHasPowerChange = 0;
EnergyGridCache.this.publicPowerState( false, EnergyGridCache.this.myGrid );
}
}
}
}
}
}
+2 -12
View File
@@ -109,9 +109,6 @@ public class GridStorageCache implements IStorageGrid
this.watchers.remove( node );
}
}
this.storageMonitors.forEach( ( channel, monitor ) -> monitor.forceUpdate() );
}
@Override
@@ -140,9 +137,6 @@ public class GridStorageCache implements IStorageGrid
this.watchers.put( node, iw );
swh.updateWatcher( iw );
}
this.storageMonitors.forEach( ( channel, monitor ) -> monitor.forceUpdate() );
}
@Override
@@ -254,6 +248,8 @@ public class GridStorageCache implements IStorageGrid
}
}
this.storageMonitors.forEach( ( channel, monitor ) -> monitor.forceUpdate() );
tracker.applyChanges();
}
@@ -285,12 +281,6 @@ public class GridStorageCache implements IStorageGrid
this.storageMonitors.get( chan ).postChange( true, (Iterable) input, src );
}
@Override
public void postCraftablesChanges( IStorageChannel<?> chan, Iterable<? extends IAEStack<?>> input, IActionSource src )
{
this.storageMonitors.get( chan ).updateCraftables( (Iterable) input, src );
}
@Override
public void registerCellProvider( final ICellProvider provider )
{
+109 -68
View File
@@ -19,10 +19,24 @@
package appeng.me.cache;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Deque;
import java.util.Iterator;
import java.util.Map.Entry;
import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import appeng.api.AEApi;
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 com.google.common.collect.ImmutableList;
import com.google.common.collect.Queues;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.networking.events.MENetworkStorageEvent;
@@ -31,20 +45,12 @@ import appeng.api.storage.IMEInventoryHandler;
import appeng.api.storage.IMEMonitor;
import appeng.api.storage.IMEMonitorHandlerReceiver;
import appeng.api.storage.IStorageChannel;
import appeng.api.storage.channels.IFluidStorageChannel;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEStack;
import appeng.api.storage.data.IItemList;
import appeng.me.storage.ItemWatcher;
import com.google.common.collect.Queues;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import java.util.Collection;
import java.util.Deque;
import java.util.Iterator;
import java.util.Map.Entry;
public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
{
@@ -61,7 +67,7 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
private final Object2ObjectMap<IMEMonitorHandlerReceiver<T>, Object> listeners;
private boolean sendEvent = false;
private boolean forceUpdate = false;
private boolean hasChanged = false;
@Nonnegative
private int localDepthSemaphore = 0;
private long gridItemCount;
@@ -90,7 +96,21 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
@Override
public T extractItems( final T request, final Actionable mode, final IActionSource src )
{
return this.getHandler().extractItems( request, mode, src );
if( mode == Actionable.SIMULATE )
{
return this.getHandler().extractItems( request, mode, src );
}
this.localDepthSemaphore++;
final T leftover = this.getHandler().extractItems( request, mode, src );
this.localDepthSemaphore--;
if( this.localDepthSemaphore == 0 )
{
this.monitorDifference( request.copy(), leftover, true, src );
}
return leftover;
}
@Override
@@ -125,10 +145,6 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
public long getGridCurrentCount()
{
if( forceUpdate )
{
getStorageList();
}
if( myChannel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
{
return gridItemCount;
@@ -140,40 +156,28 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
return 0;
}
public void incGridCurrentCount(long count)
public long incGridCurrentCount(long count)
{
if( myChannel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
{
gridItemCount += count;
return gridItemCount += count;
}
else if( myChannel == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) )
{
gridFluidCount += count;
return gridFluidCount += count;
}
return 0;
}
@Nonnull
@Override
public IItemList<T> getStorageList()
{
if( forceUpdate )
if( hasChanged )
{
forceUpdate = false;
hasChanged = false;
this.cachedList.resetStatus();
this.getAvailableItems( this.cachedList );
long count = 0;
for (T stack : this.cachedList) {
count += stack.getStackSize();
}
if( myChannel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
{
gridItemCount = count;
}
else if( myChannel == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) )
{
gridFluidCount = count;
}
return this.getAvailableItems( this.cachedList );
}
return this.cachedList;
@@ -182,7 +186,21 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
@Override
public T injectItems( final T input, final Actionable mode, final IActionSource src )
{
return this.getHandler().injectItems( input, mode, src );
if( mode == Actionable.SIMULATE )
{
return this.getHandler().injectItems( input, mode, src );
}
this.localDepthSemaphore++;
final T leftover = this.getHandler().injectItems( input, mode, src );
this.localDepthSemaphore--;
if( this.localDepthSemaphore == 0 )
{
this.monitorDifference( input.copy(), leftover, false, src );
}
return leftover;
}
@Override
@@ -214,15 +232,37 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
return this.listeners.entrySet().iterator();
}
private T monitorDifference( final IAEStack<T> original, final T leftOvers, final boolean extraction, final IActionSource src )
{
final T diff = original.copy();
if( extraction )
{
diff.setStackSize( leftOvers == null ? 0 : -leftOvers.getStackSize() );
}
else if( leftOvers != null )
{
diff.decStackSize( leftOvers.getStackSize() );
}
if( diff.getStackSize() != 0 )
{
this.postChangesToListeners( ImmutableList.of( diff ), src );
}
return leftOvers;
}
private void notifyListenersOfChange( final Iterable<T> diff, final IActionSource src )
{
this.hasChanged = true;
final Iterator<Entry<IMEMonitorHandlerReceiver<T>, Object>> i = this.getListeners();
while( i.hasNext() )
{
final Entry<IMEMonitorHandlerReceiver<T>, Object> o = i.next();
final IMEMonitorHandlerReceiver<T> receiver = o.getKey();
if( receiver.isValid( o.getValue() ) )
if( receiver.isValid( o.getValue() ) && receiver.hasListeners() )
{
receiver.postChange( this, diff, src );
}
@@ -233,20 +273,9 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
}
}
protected void updateCraftables( Iterable<T> input, IActionSource src )
private void postChangesToListeners( final Iterable<T> changes, final IActionSource src )
{
for( final T changedItem : input )
{
if (changedItem.isCraftable()) {
this.cachedList.add( changedItem );
}
else
{
T i = this.cachedList.findPrecise( changedItem );
if (i != null)
i.setCraftable( false );
}
}
this.postChange( true, changes, src );
}
protected void postChange( final boolean add, final Iterable<T> changes, final IActionSource src )
@@ -256,42 +285,35 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
return;
}
this.localDepthSemaphore++;
GLOBAL_DEPTH.push( this );
this.localDepthSemaphore++;
this.sendEvent = true;
for( final T changed : changes )
for ( final T changedItem : changes )
{
T change = changed;
if( !add && change != null )
T difference = changedItem;
if( !add && changedItem != null )
{
change = changed.copy();
change.setStackSize( -change.getStackSize() );
difference = changedItem.copy();
difference.setStackSize( -changedItem.getStackSize() );
}
incGridCurrentCount( change.getStackSize() );
this.cachedList.add( change );
incGridCurrentCount( difference.getStackSize() );
this.cachedList.add( difference );
if( this.myGridCache.getInterestManager().containsKey( change ) )
if( this.myGridCache.getInterestManager().containsKey( changedItem ) )
{
final Collection<ItemWatcher> list = this.myGridCache.getInterestManager().get( change );
final Collection<ItemWatcher> list = this.myGridCache.getInterestManager().get( changedItem );
if( !list.isEmpty() )
{
IAEStack<T> fullStack = this.getStorageList().findPrecise( change );
if( fullStack == null )
{
fullStack = change.copy();
fullStack.setStackSize( 0 );
}
this.myGridCache.getInterestManager().enableTransactions();
for( final ItemWatcher iw : list )
{
iw.getHost().onStackChange( this.getStorageList(), fullStack, change, src, this.getChannel() );
iw.getHost().onStackChange( difference, this.getChannel() );
}
this.myGridCache.getInterestManager().disableTransactions();
@@ -312,7 +334,26 @@ public class NetworkMonitor<T extends IAEStack<T>> implements IMEMonitor<T>
void forceUpdate()
{
this.forceUpdate = true;
this.hasChanged = true;
//when the grid comes back online, reset the count to 0 so
//it reflects the correct amount after the changes are accounted for
if( myChannel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
{
gridItemCount = 0;
for( IAEItemStack iaeItemStack : (Iterable<IAEItemStack>) getStorageList() )
{
gridItemCount += iaeItemStack.getStackSize();
}
}
else if( myChannel == AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) )
{
gridFluidCount = 0;
for( IAEFluidStack iaeFluidStack : (Iterable<IAEFluidStack>) getStorageList() )
{
gridFluidCount += iaeFluidStack.getStackSize();
}
}
final Iterator<Entry<IMEMonitorHandlerReceiver<T>, Object>> i = this.getListeners();
while ( i.hasNext() )
@@ -19,10 +19,6 @@
package appeng.me.storage;
import appeng.me.GridAccessException;
import appeng.me.helpers.MachineSource;
import appeng.tile.storage.TileDrive;
import com.google.common.collect.ImmutableList;
import net.minecraft.item.ItemStack;
import appeng.api.config.Actionable;
@@ -40,7 +36,6 @@ public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T>
private final ItemStack is;
private final ICellHandler handler;
private final IChestOrDrive cord;
private IActionSource source;
public DriveWatcher( final ICellInventoryHandler<T> i, final ItemStack is, final ICellHandler han, final IChestOrDrive cod )
{
@@ -48,7 +43,6 @@ public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T>
this.is = is;
this.handler = han;
this.cord = cod;
this.source = new MachineSource( cod );
}
public int getStatus()
@@ -72,14 +66,6 @@ public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T>
this.cord.blinkCell( this.getSlot() );
this.oldStatus = newStatus;
}
try
{
( (TileDrive) this.cord ).getProxy().getStorage().postAlterationOfStoredItems( this.getChannel(), ImmutableList.of( input.copy().setStackSize( input.getStackSize() - ( a == null ? 0 : a.getStackSize() ) ) ), this.source );
}
catch( GridAccessException e )
{
e.printStackTrace();
}
}
return a;
@@ -99,15 +85,6 @@ public class DriveWatcher<T extends IAEStack<T>> extends MEInventoryHandler<T>
this.cord.blinkCell( this.getSlot() );
this.oldStatus = newStatus;
}
try
{
( (TileDrive) this.cord ).getProxy().getStorage().postAlterationOfStoredItems( this.getChannel(), ImmutableList.of( request.copy().setStackSize( -a.getStackSize() ) ), this.source );
}
catch( GridAccessException e )
{
e.printStackTrace();
}
}
return a;
@@ -19,11 +19,14 @@
package appeng.me.storage;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.concurrent.ConcurrentSkipListMap;
import appeng.fluids.util.AEFluidStack;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.IFluidTankProperties;
@@ -45,14 +48,16 @@ import appeng.api.storage.data.IItemList;
public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITickingMonitor
{
private final IFluidHandler handler;
private IItemList<IAEFluidStack> cache = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList();
private final IItemList<IAEFluidStack> list = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList();
private final HashMap<IMEMonitorHandlerReceiver<IAEFluidStack>, Object> listeners = new HashMap<>();
private final NavigableMap<Integer, CachedFluidStack> memory;
private IActionSource mySource;
private StorageFilter mode = StorageFilter.EXTRACTABLE_ONLY;
public MEMonitorIFluidHandler( final IFluidHandler handler )
{
this.handler = handler;
this.memory = new ConcurrentSkipListMap<>();
}
@Override
@@ -77,6 +82,11 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
return input.copy();
}
if( type == Actionable.MODULATE )
{
this.onTick();
}
if( filled == input.getStackSize() )
{
return null;
@@ -84,15 +94,6 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
final IAEFluidStack o = input.copy();
o.setStackSize( input.getStackSize() - filled );
if( type == Actionable.MODULATE )
{
IAEFluidStack added = o.copy();
this.cache.add( added );
this.postDifference( Collections.singletonList( added ) );
this.onTick();
}
return o;
}
@@ -106,18 +107,13 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
return null;
}
final IAEFluidStack o = request.copy();
o.setStackSize( removed.amount );
if( type == Actionable.MODULATE )
{
IAEFluidStack cachedStack = this.cache.findPrecise( request );
if( cachedStack != null )
{
cachedStack.decStackSize( o.getStackSize() );
this.postDifference( Collections.singletonList( o.copy().setStackSize( -o.getStackSize() ) ) );
}
this.onTick();
}
final IAEFluidStack o = request.copy();
o.setStackSize( removed.amount );
return o;
}
@@ -130,51 +126,111 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
@Override
public TickRateModulation onTick()
{
final List<IAEFluidStack> changes = new ArrayList<>();
this.list.resetStatus();
int high = 0;
boolean changed = false;
final List<IAEFluidStack> changes = new ArrayList<>();
final IFluidTankProperties[] tankProperties = this.handler.getTankProperties();
IItemList<IAEFluidStack> currentlyOnStorage = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createList();
for( IFluidTankProperties tankProperty : tankProperties )
final IFluidTankProperties[] props = this.handler.getTankProperties();
for( int slot = 0; slot < this.handler.getTankProperties().length; ++slot )
{
if( this.mode == StorageFilter.EXTRACTABLE_ONLY && this.handler.drain( 1, false ) == null )
final CachedFluidStack old = this.memory.get( slot );
high = Math.max( high, slot );
final FluidStack newIS = !props[slot].canDrain() && this.getMode() == StorageFilter.EXTRACTABLE_ONLY ? null : props[slot].getContents();
final FluidStack oldIS = old == null ? null : old.fluidStack;
if( isDifferent( newIS, oldIS ) )
{
continue;
final CachedFluidStack cis = new CachedFluidStack( newIS );
this.memory.put( slot, cis );
if( old != null && old.aeStack != null )
{
old.aeStack.setStackSize( -old.aeStack.getStackSize() );
changes.add( old.aeStack );
}
if( cis.aeStack != null )
{
changes.add( cis.aeStack );
this.list.add( cis.aeStack );
}
changed = true;
}
currentlyOnStorage.add( AEFluidStack.fromFluidStack( tankProperty.getContents() ) );
}
for( final IAEFluidStack is : cache )
{
is.setStackSize( -is.getStackSize() );
}
for( final IAEFluidStack is : currentlyOnStorage )
{
cache.add( is );
}
for( final IAEFluidStack is : cache )
{
if( is.getStackSize() != 0 )
else
{
changes.add( is );
final int newSize = newIS == null ? 0 : newIS.amount;
final int diff = newSize - ( oldIS == null ? 0 : oldIS.amount );
IAEFluidStack stack = null;
if( newIS != null )
{
stack = ( old == null || old.aeStack == null ? AEApi.instance()
.storage()
.getStorageChannel( IFluidStorageChannel.class )
.createStack( newIS ) : old.aeStack.copy() );
}
if( stack != null )
{
stack.setStackSize( newSize );
this.list.add( stack );
}
if( diff != 0 && stack != null )
{
final CachedFluidStack cis = new CachedFluidStack( newIS );
this.memory.put( slot, cis );
final IAEFluidStack a = stack.copy();
a.setStackSize( diff );
changes.add( a );
changed = true;
}
}
}
cache = currentlyOnStorage;
// detect dropped items; should fix non IISided Inventory Changes.
final NavigableMap<Integer, CachedFluidStack> end = this.memory.tailMap( high, false );
if( !end.isEmpty() )
{
for( final CachedFluidStack cis : end.values() )
{
if( cis != null && cis.aeStack != null )
{
final IAEFluidStack a = cis.aeStack.copy();
a.setStackSize( -a.getStackSize() );
changes.add( a );
changed = true;
}
}
end.clear();
}
if( !changes.isEmpty() )
{
this.postDifference( changes );
changed = true;
}
return changed ? TickRateModulation.URGENT : TickRateModulation.SLOWER;
}
private static boolean isDifferent( FluidStack a, FluidStack b )
{
if( a == b )
{
return false;
}
if( a == null || b == null )
{
return true;
}
return !a.getFluid().equals( b.getFluid() );
}
private void postDifference( final Iterable<IAEFluidStack> a )
{
if( a != null )
@@ -235,9 +291,9 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
@Override
public IItemList<IAEFluidStack> getAvailableItems( final IItemList out )
{
for( final IAEFluidStack fs : cache )
for( final CachedFluidStack is : this.memory.values() )
{
out.addStorage( fs );
out.addStorage( is.aeStack );
}
return out;
@@ -246,7 +302,7 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
@Override
public IItemList<IAEFluidStack> getStorageList()
{
return this.cache;
return this.list;
}
private StorageFilter getMode()
@@ -270,4 +326,24 @@ public class MEMonitorIFluidHandler implements IMEMonitor<IAEFluidStack>, ITicki
this.mySource = mySource;
}
private static class CachedFluidStack
{
private final FluidStack fluidStack;
private final IAEFluidStack aeStack;
CachedFluidStack( final FluidStack is )
{
if( is == null )
{
this.fluidStack = null;
this.aeStack = null;
}
else
{
this.fluidStack = is.copy();
this.aeStack = AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ).createStack( is );
}
}
}
}
@@ -19,8 +19,12 @@
package appeng.me.storage;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.concurrent.ConcurrentSkipListMap;
import net.minecraft.item.ItemStack;
@@ -46,15 +50,16 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
{
private final InventoryAdaptor adaptor;
private IItemList<IAEItemStack> cache = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
private final IItemList<IAEItemStack> list = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
private final HashMap<IMEMonitorHandlerReceiver<IAEItemStack>, Object> listeners = new HashMap<>();
private final NavigableMap<Integer, CachedItemStack> memory;
private IActionSource mySource;
private StorageFilter mode = StorageFilter.EXTRACTABLE_ONLY;
public MEMonitorIInventory( final InventoryAdaptor adaptor )
{
this.adaptor = adaptor;
this.memory = new ConcurrentSkipListMap<>();
}
@Override
@@ -83,6 +88,11 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
out = this.adaptor.addItems( input.createItemStack() );
}
if( type == Actionable.MODULATE )
{
this.onTick();
}
if( out.isEmpty() )
{
return null;
@@ -91,15 +101,6 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
// better then doing construction from scratch :3
final IAEItemStack o = input.copy();
o.setStackSize( out.getCount() );
if( type == Actionable.MODULATE )
{
IAEItemStack added = o.copy();
this.cache.add( added );
this.postDifference( Collections.singletonList( added ) );
this.onTick();
}
return o;
}
@@ -128,12 +129,6 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
if( type == Actionable.MODULATE )
{
IAEItemStack cachedStack = this.cache.findPrecise( request );
if( cachedStack != null )
{
cachedStack.decStackSize( o.getStackSize() );
this.postDifference( Collections.singletonList( o.copy().setStackSize( -o.getStackSize() ) ) );
}
this.onTick();
}
@@ -149,52 +144,110 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
@Override
public TickRateModulation onTick()
{
boolean changed = false;
final List<IAEItemStack> changes = new ArrayList<>();
IItemList<IAEItemStack> currentlyOnStorage = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
for( final ItemSlot is : adaptor )
this.list.resetStatus();
int high = 0;
boolean changed = false;
for( final ItemSlot is : this.adaptor )
{
if( this.mode == StorageFilter.EXTRACTABLE_ONLY && !is.isExtractable() )
final CachedItemStack old = this.memory.get( is.getSlot() );
high = Math.max( high, is.getSlot() );
final ItemStack newIS = !is.isExtractable() && this.getMode() == StorageFilter.EXTRACTABLE_ONLY ? ItemStack.EMPTY : is.getItemStack();
final ItemStack oldIS = old == null ? ItemStack.EMPTY : old.itemStack;
if( this.isDifferent( newIS, oldIS ) )
{
continue;
final CachedItemStack cis = new CachedItemStack( is.getItemStack() );
this.memory.put( is.getSlot(), cis );
if( old != null && old.aeStack != null )
{
old.aeStack.setStackSize( -old.aeStack.getStackSize() );
changes.add( old.aeStack );
}
if( cis.aeStack != null )
{
changes.add( cis.aeStack );
this.list.add( cis.aeStack );
}
changed = true;
}
currentlyOnStorage.add( is.getAEItemStack() );
}
for( final IAEItemStack is : cache )
{
is.setStackSize( -is.getStackSize() );
}
for( final IAEItemStack is : currentlyOnStorage )
{
cache.add( is );
}
for( final IAEItemStack is : cache )
{
if( is.getStackSize() != 0 )
else
{
changes.add( is );
final int newSize = ( newIS.isEmpty() ? 0 : newIS.getCount() );
final int diff = newSize - ( oldIS.isEmpty() ? 0 : oldIS.getCount() );
final IAEItemStack stack = ( old == null || old.aeStack == null ? AEApi.instance()
.storage()
.getStorageChannel( IItemStorageChannel.class )
.createStack( newIS ) : old.aeStack.copy() );
if( stack != null )
{
stack.setStackSize( newSize );
this.list.add( stack );
}
if( diff != 0 && stack != null )
{
final CachedItemStack cis = new CachedItemStack( is.getItemStack() );
this.memory.put( is.getSlot(), cis );
final IAEItemStack a = stack.copy();
a.setStackSize( diff );
changes.add( a );
changed = true;
}
}
}
cache = currentlyOnStorage;
// detect dropped items; should fix non IISided Inventory Changes.
final NavigableMap<Integer, CachedItemStack> end = this.memory.tailMap( high, false );
if( !end.isEmpty() )
{
for( final CachedItemStack cis : end.values() )
{
if( cis != null && cis.aeStack != null )
{
final IAEItemStack a = cis.aeStack.copy();
a.setStackSize( -a.getStackSize() );
changes.add( a );
changed = true;
}
}
end.clear();
}
if( !changes.isEmpty() )
{
this.postDifference( changes );
changed = true;
}
return changed ? TickRateModulation.URGENT : TickRateModulation.SLOWER;
}
private boolean isDifferent( final ItemStack a, final ItemStack b )
{
if( a == b && b.isEmpty() )
{
return false;
}
if( ( a.isEmpty() && !b.isEmpty() ) || ( !a.isEmpty() && b.isEmpty() ) )
{
return true;
}
return !Platform.itemComparisons().isSameItem( a, b );
}
private void postDifference( final Iterable<IAEItemStack> a )
{
// AELog.info( a.getItemStack().getUnlocalizedName() + " @ " + a.getStackSize() );
if( a != null )
{
final Iterator<Entry<IMEMonitorHandlerReceiver<IAEItemStack>, Object>> i = this.listeners.entrySet().iterator();
@@ -253,9 +306,9 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
@Override
public IItemList<IAEItemStack> getAvailableItems( final IItemList out )
{
for( IAEItemStack is : cache )
for( final CachedItemStack is : this.memory.values() )
{
out.addStorage( is );
out.addStorage( is.aeStack );
}
return out;
@@ -264,7 +317,7 @@ public class MEMonitorIInventory implements IMEMonitor<IAEItemStack>, ITickingMo
@Override
public IItemList<IAEItemStack> getStorageList()
{
return this.cache;
return this.list;
}
private StorageFilter getMode()
@@ -72,7 +72,7 @@ public class MEMonitorPassThrough<T extends IAEStack<T>> extends MEPassThrough<T
final IItemList<T> after = this.getInternal() == null ? this.getWrappedChannel().createList() : this.getInternal()
.getAvailableItems( new ItemListIgnoreCrafting( this.getWrappedChannel().createList() ) );
if( this.monitor != null && this.listeners.size() > 0 )
if( this.monitor != null )
{
this.monitor.addListener( this, this.monitor );
}
@@ -124,6 +124,12 @@ public class MEMonitorPassThrough<T extends IAEStack<T>> extends MEPassThrough<T
return verificationToken == this.monitor;
}
@Override
public boolean hasListeners()
{
return this.listeners.size() > 0;
}
@Override
public void postChange( final IBaseMonitor<T> monitor, final Iterable<T> change, final IActionSource source )
{
@@ -41,7 +41,7 @@ public class MEPassThrough<T extends IAEStack<T>> implements IMEInventoryHandler
this.setInternal( i );
}
public IMEInventory<T> getInternal()
protected IMEInventory<T> getInternal()
{
return this.internal;
}
@@ -180,10 +180,7 @@ public class PartExportBus extends PartSharedItemBus implements ICraftingRequest
}
else
{
if( inv.getStorageList().findPrecise( ais ) != null )
{
this.pushItemIntoTarget( destination, energy, inv, ais );
}
this.pushItemIntoTarget( destination, energy, inv, ais );
}
if( this.itemToSend == before && this.isCraftingEnabled() )
@@ -206,7 +206,7 @@ public class PartFormationPlane extends PartAbstractFormationPlane<IAEItemStack>
@Override
public List<IMEInventoryHandler> getCellArray( final IStorageChannel channel )
{
if( channel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
if( this.getProxy().isActive() && channel == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
{
final List<IMEInventoryHandler> handler = new ArrayList<>( 1 );
handler.add( this.myHandler );
@@ -283,12 +283,12 @@ public class PartImportBus extends PartSharedItemBus implements IInventoryDestin
final ItemStack simResult;
if( this.getInstalledUpgrades( Upgrades.FUZZY ) > 0 )
{
simResult = myAdaptor.simulateSimilarRemove( toSend, itemStackToImport, fzMode, null );
simResult = myAdaptor.simulateSimilarRemove( toSend, itemStackToImport, fzMode, this );
itemAmountNotStorable = inv.injectItems( AEItemStack.fromItemStack( simResult ), Actionable.SIMULATE, this.source );
}
else
{
simResult = myAdaptor.simulateRemove( toSend, itemStackToImport, null );
simResult = myAdaptor.simulateRemove( toSend, itemStackToImport, this );
itemAmountNotStorable = inv.injectItems( AEItemStack.fromItemStack( simResult ), Actionable.SIMULATE, this.source );
}
@@ -19,44 +19,20 @@
package appeng.parts.automation;
import appeng.api.AEApi;
import appeng.api.config.*;
import appeng.api.networking.crafting.*;
import appeng.api.networking.energy.IEnergyGrid;
import appeng.api.networking.energy.IEnergyWatcher;
import appeng.api.networking.energy.IEnergyWatcherHost;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkCraftingPatternChange;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.networking.security.IActionSource;
import appeng.api.networking.storage.IBaseMonitor;
import appeng.api.networking.storage.IStackWatcher;
import appeng.api.networking.storage.IStackWatcherHost;
import appeng.api.parts.IPartCollisionHelper;
import appeng.api.parts.IPartModel;
import appeng.api.storage.IMEMonitor;
import appeng.api.storage.IMEMonitorHandlerReceiver;
import appeng.api.storage.IStorageChannel;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IAEStack;
import appeng.api.storage.data.IItemList;
import appeng.api.util.AECableType;
import appeng.api.util.AEPartLocation;
import appeng.api.util.IConfigManager;
import appeng.core.AppEng;
import appeng.core.sync.GuiBridge;
import appeng.helpers.Reflected;
import appeng.items.parts.PartModels;
import appeng.me.GridAccessException;
import java.util.Collections;
import java.util.Optional;
import java.util.Random;
import appeng.api.networking.events.*;
import appeng.me.Grid;
import appeng.me.GridNode;
import appeng.me.cache.NetworkMonitor;
import appeng.parts.PartModel;
import appeng.tile.inventory.AppEngInternalAEInventory;
import appeng.util.Platform;
import appeng.util.inv.InvOperation;
import appeng.util.item.AEItemStack;
import appeng.util.item.OreHelper;
import appeng.util.item.OreReference;
import it.unimi.dsi.fastutil.objects.Object2LongMap;
import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.ItemStack;
@@ -70,8 +46,46 @@ import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.items.IItemHandler;
import java.util.Optional;
import java.util.Random;
import appeng.api.AEApi;
import appeng.api.config.FuzzyMode;
import appeng.api.config.LevelType;
import appeng.api.config.RedstoneMode;
import appeng.api.config.Settings;
import appeng.api.config.Upgrades;
import appeng.api.config.YesNo;
import appeng.api.networking.crafting.ICraftingGrid;
import appeng.api.networking.crafting.ICraftingPatternDetails;
import appeng.api.networking.crafting.ICraftingProvider;
import appeng.api.networking.crafting.ICraftingProviderHelper;
import appeng.api.networking.crafting.ICraftingWatcher;
import appeng.api.networking.crafting.ICraftingWatcherHost;
import appeng.api.networking.energy.IEnergyGrid;
import appeng.api.networking.energy.IEnergyWatcher;
import appeng.api.networking.energy.IEnergyWatcherHost;
import appeng.api.networking.security.IActionSource;
import appeng.api.networking.storage.IBaseMonitor;
import appeng.api.networking.storage.IStackWatcher;
import appeng.api.networking.storage.IStackWatcherHost;
import appeng.api.parts.IPartCollisionHelper;
import appeng.api.parts.IPartModel;
import appeng.api.storage.IMEMonitor;
import appeng.api.storage.IMEMonitorHandlerReceiver;
import appeng.api.storage.IStorageChannel;
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.IConfigManager;
import appeng.core.AppEng;
import appeng.core.sync.GuiBridge;
import appeng.helpers.Reflected;
import appeng.items.parts.PartModels;
import appeng.me.GridAccessException;
import appeng.parts.PartModel;
import appeng.tile.inventory.AppEngInternalAEInventory;
import appeng.util.Platform;
import appeng.util.inv.InvOperation;
public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherHost, IStackWatcherHost, ICraftingWatcherHost, IMEMonitorHandlerReceiver<IAEItemStack>, ICraftingProvider
@@ -363,7 +377,7 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
}
@Override
public void onStackChange( IItemList<?> o, IAEStack<?> fullStack, IAEStack<?> diffStack, IActionSource src, IStorageChannel<?> chan )
public void onStackChange( final IAEStack diffStack, final IStorageChannel chan )
{
if( chan == AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) )
{
@@ -507,7 +521,6 @@ public class PartLevelEmitter extends PartUpgradeable implements IEnergyWatcherH
public void upgradesChanged()
{
this.configureWatchers();
this.updateState();
}
@Override
@@ -21,7 +21,6 @@ package appeng.parts.misc;
import javax.annotation.Nullable;
import appeng.api.AEApi;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.config.Settings;
import appeng.api.config.StorageFilter;
@@ -34,7 +33,6 @@ 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.inv.ItemHandlerIterator;
@@ -60,7 +58,6 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
private final IGridProxyable proxyable;
private final InventoryCache cache;
private StorageFilter mode;
private AccessRestriction access;
private ItemStack stackCache = null;
@@ -72,10 +69,8 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
{
PartStorageBus partStorageBus = (PartStorageBus) this.proxyable;
this.mode = ( (StorageFilter) partStorageBus.getConfigManager().getSetting( Settings.STORAGE_FILTER ) );
this.access = ( (AccessRestriction) partStorageBus.getConfigManager().getSetting( Settings.ACCESS ) );
}
this.cache = new InventoryCache( this.itemHandler, this.mode );
this.cache.update();
}
@Override
@@ -102,7 +97,7 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
ItemStack remaining = orgInput;
for( int i = 0; i < slotCount && !remaining.isEmpty(); i++ )
for ( int i = 0; i < slotCount && !remaining.isEmpty(); i++ )
{
remaining = this.itemHandler.insertItem( i, remaining, type == Actionable.SIMULATE );
}
@@ -122,17 +117,9 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
if( type == Actionable.MODULATE )
{
IAEItemStack added = iox.copy().setStackSize( iox.getStackSize() - remaining.getCount() );
this.cache.currentlyCached.add( added );
this.postDifference( Collections.singletonList( added ) );
try
{
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
}
catch( GridAccessException ex )
{
// meh
}
this.cache
.currentlyCached
.add( AEItemStack.fromItemStack( orgInput ).setStackSize( orgInput.getCount() - remaining.getCount() ) );
}
return AEItemStack.fromItemStack( remaining );
@@ -206,19 +193,10 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
IAEItemStack gatheredAEItemStack = AEItemStack.fromItemStack( gathered );
if( mode == Actionable.MODULATE )
{
IAEItemStack cachedStack = this.cache.currentlyCached.findPrecise( request );
if( cachedStack != null )
IAEItemStack e = this.cache.currentlyCached.findPrecise( gatheredAEItemStack );
if (e != null)
{
cachedStack.decStackSize( gatheredAEItemStack.getStackSize() );
this.postDifference( Collections.singletonList( gatheredAEItemStack.copy().setStackSize( -gatheredAEItemStack.getStackSize() ) ) );
}
try
{
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
}
catch( GridAccessException ex )
{
// meh
e.decStackSize( gathered.getCount() );
}
}
@@ -232,7 +210,7 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
public TickRateModulation onTick()
{
List<IAEItemStack> changes = this.cache.update();
if( !changes.isEmpty() && access.hasPermission( AccessRestriction.READ ) )
if( !changes.isEmpty() )
{
this.postDifference( changes );
return TickRateModulation.URGENT;
@@ -297,6 +275,7 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
private final StorageFilter mode;
IItemList<IAEItemStack> currentlyCached = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
public InventoryCache( IItemHandler itemHandler, StorageFilter mode )
{
this.mode = mode;
@@ -320,13 +299,13 @@ class ItemHandlerAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<IAE
IItemList<IAEItemStack> currentlyOnStorage = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
for( final ItemSlot is : this )
for ( final ItemSlot is : this )
{
if( this.mode == StorageFilter.EXTRACTABLE_ONLY && !is.isExtractable() )
final ItemStack newIS = !is.isExtractable() && this.getMode() == StorageFilter.EXTRACTABLE_ONLY ? ItemStack.EMPTY : is.getItemStack();
if( !newIS.isEmpty() )
{
continue;
currentlyOnStorage.add( is.getAEItemStack() );
}
currentlyOnStorage.add( is.getAEItemStack() );
}
for ( final IAEItemStack is : currentlyCached )
@@ -2,9 +2,7 @@ package appeng.parts.misc;
import javax.annotation.Nullable;
import appeng.api.AEApi;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.config.Settings;
import appeng.api.networking.security.IActionSource;
import appeng.api.networking.storage.IBaseMonitor;
import appeng.api.networking.ticking.TickRateModulation;
@@ -15,7 +13,6 @@ 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.item.AEItemStack;
@@ -40,7 +37,6 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
private final IItemRepository itemRepository;
private final IGridProxyable proxyable;
private final InventoryCache cache;
private AccessRestriction access;
private ItemStack stackCache;
@@ -49,12 +45,6 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
this.itemRepository = itemRepository;
this.proxyable = proxy;
this.cache = new InventoryCache( this.itemRepository );
if( this.proxyable instanceof PartStorageBus )
{
PartStorageBus partStorageBus = (PartStorageBus) this.proxyable;
this.access = ( (AccessRestriction) partStorageBus.getConfigManager().getSetting( Settings.ACCESS ) );
}
this.cache.update();
}
@Override
@@ -79,7 +69,7 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
ItemStack remaining = this.itemRepository.insertItem( orgInput, type == Actionable.SIMULATE );
// Store the stack in the cache for next time.
if( !remaining.isEmpty() && remaining != orgInput )
if (!remaining.isEmpty() && remaining != orgInput)
{
stackCache = remaining;
}
@@ -93,17 +83,9 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
if( type == Actionable.MODULATE )
{
IAEItemStack added = iox.copy().setStackSize( iox.getStackSize() - remaining.getCount() );
this.cache.currentlyCached.add( added );
this.postDifference( Collections.singletonList( added ) );
try
{
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
}
catch( GridAccessException ex )
{
// meh
}
this.cache
.currentlyCached
.add( AEItemStack.fromItemStack( orgInput ).setStackSize( orgInput.getCount() - remaining.getCount() ) );
}
return AEItemStack.fromItemStack( remaining );
@@ -123,8 +105,7 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
{
// Something broke. It should never return more than we requested...
// We're going to silently eat the remainder
AELog.warn( "Mod that provided item handler %s is broken. Returned %s items while only requesting %d.",
this.itemRepository.getClass().getName(), extracted.toString(), remainingSize );
AELog.warn( "Mod that provided item handler %s is broken. Returned %s items while only requesting %d.", this.itemRepository.getClass().getName(), extracted.toString(), remainingSize );
extracted.setCount( remainingSize );
}
@@ -133,19 +114,10 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
IAEItemStack extractedAEItemStack = AEItemStack.fromItemStack( extracted );
if( mode == Actionable.MODULATE )
{
IAEItemStack cachedStack = this.cache.currentlyCached.findPrecise( request );
if (cachedStack != null)
IAEItemStack e = this.cache.currentlyCached.findPrecise( extractedAEItemStack );
if (e != null)
{
cachedStack.decStackSize( extractedAEItemStack.getStackSize() );
this.postDifference( Collections.singletonList( extractedAEItemStack.copy().setStackSize( -extractedAEItemStack.getStackSize() ) ) );
}
try
{
this.proxyable.getProxy().getTick().alertDevice( this.proxyable.getProxy().getNode() );
}
catch( GridAccessException ex )
{
// meh
e.decStackSize( extracted.getCount() );
}
}
return extractedAEItemStack;
@@ -198,15 +170,17 @@ class ItemRepositoryAdapter implements IMEInventory<IAEItemStack>, IBaseMonitor<
@Override
public TickRateModulation onTick()
{
List<IAEItemStack> changes = this.cache.update();
if( !changes.isEmpty() && access.hasPermission( AccessRestriction.READ ) )
{
this.postDifference( changes );
return TickRateModulation.URGENT;
}
else
{
return TickRateModulation.SLOWER;
List<IAEItemStack> changes = this.cache.update();
if( !changes.isEmpty() )
{
this.postDifference( changes );
return TickRateModulation.URGENT;
}
else
{
return TickRateModulation.SLOWER;
}
}
}
@@ -22,14 +22,8 @@ package appeng.parts.misc;
import java.util.Collections;
import java.util.List;
import appeng.api.config.AccessRestriction;
import appeng.fluids.parts.PartFluidInterface;
import appeng.fluids.tile.TileFluidInterface;
import appeng.tile.misc.TileInterface;
import appeng.tile.networking.TileCableBus;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
@@ -61,7 +55,6 @@ public abstract class PartSharedStorageBus extends PartUpgradeable implements IG
{
private boolean wasActive = false;
private int priority = 0;
protected boolean accessChanged;
public PartSharedStorageBus( ItemStack is )
{
@@ -153,10 +146,6 @@ public abstract class PartSharedStorageBus extends PartUpgradeable implements IG
@Override
public void updateSetting( final IConfigManager manager, final Enum settingName, final Enum newValue )
{
if( settingName instanceof AccessRestriction )
{
this.accessChanged = true;
}
this.resetCache( true );
this.getHost().markForSave();
}
@@ -166,27 +155,7 @@ public abstract class PartSharedStorageBus extends PartUpgradeable implements IG
{
if( pos.offset( this.getSide().getFacing() ).equals( neighbor ) )
{
final TileEntity te = w.getTileEntity( neighbor );
// In case the TE was destroyed, we have to do a full reset immediately.
if( te instanceof TileCableBus )
{
if( ( (TileCableBus) te ).getPart( this.getSide().getOpposite() ) instanceof PartFluidInterface )
{
this.resetCache( true );
this.resetCache();
}
}
if( te == null || te instanceof TileFluidInterface )
{
this.resetCache( true );
this.resetCache();
}
else
{
this.resetCache( false );
}
this.resetCache( false );
}
}
@@ -23,12 +23,6 @@ import java.util.Collections;
import java.util.List;
import java.util.Objects;
import appeng.fluids.parts.FluidHandlerAdapter;
import appeng.me.storage.MEPassThrough;
import appeng.parts.AEBasePart;
import appeng.tile.misc.TileInterface;
import appeng.tile.networking.TileCableBus;
import appeng.util.ConfigManager;
import com.jaquadro.minecraft.storagedrawers.api.capabilities.IItemRepository;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
@@ -127,7 +121,6 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
private int handlerHash = 0;
private boolean wasActive = false;
private byte resetCacheLogic = 0;
private boolean accessChanged;
@Reflected
public PartStorageBus( final ItemStack is )
@@ -179,10 +172,6 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
@Override
public void updateSetting( final IConfigManager manager, final Enum settingName, final Enum newValue )
{
if( settingName instanceof AccessRestriction )
{
this.accessChanged = true;
}
this.resetCache( true );
this.getHost().markForSave();
}
@@ -245,7 +234,7 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
{
this.resetCacheLogic = 2;
}
else if( this.resetCacheLogic < 2 )
else
{
this.resetCacheLogic = 1;
}
@@ -269,14 +258,6 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
@Override
public void postChange( final IBaseMonitor<IAEItemStack> monitor, final Iterable<IAEItemStack> change, final IActionSource source )
{
if( this.mySrc.machine().map( machine -> machine == this ).orElse( false ) && monitor != null )
{
AccessRestriction currentAccess = (AccessRestriction) ( (ConfigManager) this.getConfigManager() ).getSetting( Settings.ACCESS );
if( !currentAccess.hasPermission( AccessRestriction.READ ) )
{
return;
}
}
try
{
if( this.getProxy().isActive() )
@@ -309,19 +290,10 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
{
if( pos.offset( this.getSide().getFacing() ).equals( neighbor ) )
{
final TileEntity te = w.getTileEntity( neighbor );
// In case the TE was destroyed, we have to do a full reset immediately.
if( te instanceof TileCableBus )
{
if( ( (TileCableBus) te ).getPart( this.getSide().getOpposite() ) instanceof PartInterface )
{
this.resetCache( true );
this.resetCache();
}
}
if( te == null || te instanceof TileInterface )
if( te == null )
{
this.resetCache( true );
this.resetCache();
@@ -376,28 +348,11 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
final boolean fullReset = this.resetCacheLogic == 2;
this.resetCacheLogic = 0;
final MEInventoryHandler<IAEItemStack> in = this.getInternalHandler();
final IMEInventory<IAEItemStack> in = this.getInternalHandler();
IItemList<IAEItemStack> before = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
boolean denyRead = false;
if( in != null )
{
if( accessChanged )
{
AccessRestriction currentAccess = (AccessRestriction) ( (ConfigManager) this.getConfigManager() ).getSetting( Settings.ACCESS );
AccessRestriction oldAccess = (AccessRestriction) ( (ConfigManager) this.getConfigManager() ).getOldSetting( Settings.ACCESS );
if( oldAccess.hasPermission( AccessRestriction.READ ) && !currentAccess.hasPermission( AccessRestriction.READ ) )
{
denyRead = true;
}
in.setBaseAccess( oldAccess );
before = in.getAvailableItems( before );
in.setBaseAccess( currentAccess );
accessChanged = false;
}
else
{
before = in.getAvailableItems( before );
}
before = in.getAvailableItems( before );
}
this.cached = false;
@@ -406,19 +361,16 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
this.handlerHash = 0;
}
final MEInventoryHandler<IAEItemStack> out = this.getInternalHandler();
final IMEInventory<IAEItemStack> out = this.getInternalHandler();
if( in != out || denyRead )
if( in != out )
{
IItemList<IAEItemStack> after = AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ).createList();
if( out != null && !denyRead )
if( out != null )
{
after = out.getAvailableItems( after );
}
Platform.postListChanges( before, after, this, this.mySrc );
}
}
@@ -479,6 +431,16 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
return Objects.hash( target, target.getCapability( Capabilities.STORAGE_MONITORABLE_ACCESSOR, targetSide ) );
}
if (ITEM_REPOSITORY_CAPABILITY != null && target.hasCapability( ITEM_REPOSITORY_CAPABILITY, targetSide ))
{
final IItemRepository handlerRepo = target.getCapability( ITEM_REPOSITORY_CAPABILITY, targetSide );
if( handlerRepo != null )
{
return Objects.hash( target, handlerRepo, handlerRepo.getAllItems().size() );
}
}
final IItemHandler itemHandler = target.getCapability( CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, targetSide );
if( itemHandler != null )
@@ -510,15 +472,17 @@ public class PartStorageBus extends PartUpgradeable implements IGridTickable, IC
this.handlerHash = newHandlerHash;
this.handler = null;
if( this.monitor != null )
{
( (IBaseMonitor<IAEItemStack>) monitor ).removeListener( this );
}
this.monitor = null;
if( target != null )
{
IMEInventory<IAEItemStack> inv = this.getInventoryWrapper( target );
if( inv instanceof MEMonitorIInventory )
{
final MEMonitorIInventory h = (MEMonitorIInventory) inv;
h.setMode( (StorageFilter) this.getConfigManager().getSetting( Settings.STORAGE_FILTER ) );
}
if( inv instanceof ITickingMonitor )
{
this.monitor = (ITickingMonitor) inv;
@@ -350,25 +350,9 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
if( needsNewFrequency )
{
newFreq = this.getProxy().getP2P().newFrequency();
final ItemStack newType = this.getHost().getPart( this.getSide() ).getItemStack( PartItemStack.WRENCH );
this.getHost().removePart( this.getSide(), false );
final AEPartLocation dir = this.getHost().addPart( newType, this.getSide(), player, hand );
final IPart newBus = this.getHost().getPart( dir );
if( newBus instanceof PartP2PTunnel )
{
final PartP2PTunnel newTunnel = (PartP2PTunnel) newBus;
newTunnel.setOutput( false );
newTunnel.onTunnelNetworkChange();
newTunnel.getProxy().getP2P().updateFreq( newTunnel, newFreq );
}
}
else
{
this.getProxy().getP2P().updateFreq( this, newFreq );
}
this.getProxy().getP2P().updateFreq( this, newFreq );
}
catch( final GridAccessException e )
{
@@ -381,17 +365,10 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
final String type = p2pItem.getUnlocalizedName();
p2pItem.writeToNBT( data );
if( needsNewFrequency )
{
data.setShort( "freq", newFreq );
}
else
{
data.setShort( "freq", this.getFrequency() );
}
data.setShort( "freq", this.getFrequency() );
final AEColor[] colors = Platform.p2p().toColors( this.getFrequency() );
final int[] colorCode = new int[]{
final int[] colorCode = new int[] {
colors[0].ordinal(), colors[0].ordinal(), colors[1].ordinal(), colors[1].ordinal(),
colors[2].ordinal(), colors[2].ordinal(), colors[3].ordinal(), colors[3].ordinal(),
};
@@ -24,10 +24,8 @@ import java.io.IOException;
import appeng.api.networking.events.MENetworkChannelsChanged;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.networking.security.IActionSource;
import appeng.api.storage.channels.IFluidStorageChannel;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IItemList;
import appeng.fluids.util.AEFluidStack;
import io.netty.buffer.ByteBuf;
@@ -82,7 +80,6 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements
private IAEItemStack configuredItem;
private IAEFluidStack configuredFluid;
private long configuredAmount;
private String lastHumanReadableText;
private boolean isLocked;
private IStackWatcher myWatcher;
@@ -209,21 +206,14 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements
fluidInTank = fluidHandlerItem.drain( Integer.MAX_VALUE, false );
}
if( fluidInTank == null )
if (fluidInTank == null)
{
this.configuredFluid = null;
if( !eq.isEmpty() )
{
this.configuredItem = AEItemStack.fromItemStack( eq ).setStackSize( 0 );
}
else
{
this.configuredItem = null;
}
this.configuredItem = AEItemStack.fromItemStack( eq );
}
else if( fluidInTank.amount > 0 )
{
this.configuredFluid = AEFluidStack.fromFluidStack( fluidInTank ).setStackSize( 0 );
this.configuredFluid = AEFluidStack.fromFluidStack( fluidInTank );
this.configuredItem = null;
}
@@ -307,31 +297,30 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements
private <T extends IAEStack<T>> void updateReportingValue ( final IMEMonitor<T> monitor )
{
if( this.configuredItem != null)
{
final IAEItemStack result = (IAEItemStack) monitor.getStorageList().findPrecise( (T) this.configuredItem );
if( result == null )
{
this.configuredAmount = 0;
this.configuredItem.setStackSize( 0 );
}
else
{
this.configuredAmount = result.getStackSize();
this.configuredItem.setStackSize( result.getStackSize() );
}
this.configuredItem.setStackSize( this.configuredAmount );
}
else if( this.configuredFluid != null)
{
final IAEFluidStack result = (IAEFluidStack) monitor.getStorageList().findPrecise( (T) this.configuredFluid );
if( result == null )
{
this.configuredAmount = 0;
this.configuredFluid.setStackSize( 0 );
}
else
{
this.configuredAmount = result.getStackSize();
this.configuredFluid.setStackSize( result.getStackSize() );
}
this.configuredFluid.setStackSize( this.configuredAmount );
}
}
@@ -399,35 +388,108 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements
@MENetworkEventSubscribe
public void powerStatusChange( final MENetworkPowerStatusChange ev )
{
if( this.getProxy().isPowered() )
if( !this.getProxy().isPowered() )
{
this.configureWatchers();
if( this.myWatcher != null )
{
if( this.configuredItem != null )
{
this.configuredItem.setStackSize( 0 );
}
if( this.configuredFluid != null )
{
this.configuredFluid.setStackSize( 0 );
}
}
}
else
{
try
{
if( this.configuredItem != null )
{
this.updateReportingValue( this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) );
}
if( this.configuredFluid != null )
{
this.updateReportingValue( this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) ) );
}
}
catch( final GridAccessException e )
{
// ;P
}
}
}
@MENetworkEventSubscribe
public void channelChanged( final MENetworkChannelsChanged c )
{
if( this.getProxy().isPowered() )
if( !this.getProxy().isPowered() )
{
this.configureWatchers();
if( this.myWatcher != null )
{
if( this.configuredItem != null )
{
this.configuredItem.setStackSize( 0 );
}
if( this.configuredFluid != null )
{
this.configuredFluid.setStackSize( 0 );
}
}
}
else
{
try
{
if( this.configuredItem != null )
{
this.updateReportingValue( this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IItemStorageChannel.class ) ) );
}
if( this.configuredFluid != null )
{
this.updateReportingValue( this.getProxy().getStorage().getInventory( AEApi.instance().storage().getStorageChannel( IFluidStorageChannel.class ) ) );
}
}
catch( final GridAccessException e )
{
// ;P
}
}
}
@Override
public void onStackChange( IItemList<?> o, IAEStack<?> fullStack, IAEStack<?> diffStack, IActionSource src, IStorageChannel<?> chan )
public void onStackChange( final IAEStack diffStack, final IStorageChannel chan )
{
this.configuredAmount = this.configuredAmount + diffStack.getStackSize();
if( this.configuredItem != null )
{
this.configuredItem.setStackSize( this.configuredAmount );
long diff = this.configuredItem.getStackSize() + diffStack.getStackSize();
this.configuredItem.setStackSize( diff >= 0 ? this.configuredItem.getStackSize() + diffStack.getStackSize() : 0 );
final long stackSize = this.configuredItem.getStackSize();
final String humanReadableText = NUMBER_CONVERTER.toWideReadableForm( stackSize );
if( !humanReadableText.equals( this.lastHumanReadableText ) )
{
this.lastHumanReadableText = humanReadableText;
this.getHost().markForUpdate();
}
}
else if( this.configuredFluid != null )
{
this.configuredFluid.setStackSize( this.configuredAmount );
long diff = this.configuredFluid.getStackSize() + diffStack.getStackSize();
this.configuredFluid.setStackSize( diff >= 0 ? this.configuredFluid.getStackSize() + diffStack.getStackSize() : 0 );
final long stackSize = this.configuredFluid.getStackSize() / 1000;
final String humanReadableText = NUMBER_CONVERTER.toWideReadableForm( stackSize ) + "B";
if( !humanReadableText.equals( this.lastHumanReadableText ) )
{
this.lastHumanReadableText = humanReadableText;
this.getHost().markForUpdate();
}
}
this.getHost().markForUpdate();
}
@Override
@@ -137,10 +137,14 @@ public class PartConversionMonitor extends AbstractPartMonitor
{
this.insertItem( player, hand, false );
}
}
//If its a fluid container, grab its fluidstack. if its empty pass its itemstack;
if (eq.isEmpty()){
return super.onPartActivate( player, hand, pos );
}
if( fluidInTank != null && fluidInTank.amount > 0 )
{
if( getDisplayed() instanceof IAEItemStack || getDisplayed() == null )
@@ -151,16 +155,23 @@ public class PartConversionMonitor extends AbstractPartMonitor
{
this.drainFluidContainer( player, hand );
}
else
{
else {
return super.onPartActivate( player, hand, pos );
}
}
else if( this.getDisplayed() != null && this.getDisplayed().equals( player.getHeldItem( hand ) ) )
else
{
this.insertItem( player, hand, false );
if( getDisplayed() instanceof IAEFluidStack || getDisplayed() == null )
{
return super.onPartActivate( player, hand, pos );
}
if( ( (IAEItemStack) this.getDisplayed() ).equals( eq ) )
{
this.insertItem( player, hand, false );
}
}
return super.onPartActivate( player, hand, pos );
return true;
}
@Override
@@ -181,6 +192,7 @@ public class PartConversionMonitor extends AbstractPartMonitor
return false;
}
ItemStack eq = player.getHeldItem( hand );
if( this.getDisplayed() != null && this.getDisplayed() instanceof IAEItemStack )
{
this.extractItem( player, ( (IAEItemStack) this.getDisplayed() ).getDefinition().getMaxStackSize() );
@@ -270,7 +282,7 @@ public class PartConversionMonitor extends AbstractPartMonitor
{
if (!(this.getDisplayed() instanceof IAEItemStack))
return;
final IAEItemStack input = (IAEItemStack) this.getDisplayed().copy();
final IAEItemStack input = (IAEItemStack) this.getDisplayed();
if( input != null )
{
try
@@ -494,14 +494,12 @@ public class TileChest extends AENetworkPowerTile implements IMEChest, ITerminal
try
{
this.getProxy().getGrid().postEvent( new MENetworkCellArrayUpdate() );
if( this.getProxy().isActive() )
{
final IStorageGrid gs = this.getProxy().getStorage();
Platform.postChanges( gs, removed, added, this.mySrc );
}
final IStorageGrid gs = this.getProxy().getStorage();
Platform.postChanges( gs, removed, added, this.mySrc );
}
catch( final GridAccessException ignored )
{
}
// update the neighbors
@@ -556,10 +554,14 @@ public class TileChest extends AENetworkPowerTile implements IMEChest, ITerminal
@Override
public List<IMEInventoryHandler> getCellArray( final IStorageChannel channel )
{
this.updateHandler();
if( this.cellHandler != null && this.cellHandler.getChannel() == channel )
if( this.getProxy().isActive() )
{
return Collections.singletonList( this.cellHandler );
this.updateHandler();
if( this.cellHandler != null && this.cellHandler.getChannel() == channel )
{
return Collections.singletonList( this.cellHandler );
}
}
return Collections.emptyList();
}
@@ -690,16 +692,21 @@ public class TileChest extends AENetworkPowerTile implements IMEChest, ITerminal
@Override
public void postChange( final IBaseMonitor<T> monitor, final Iterable<T> change, final IActionSource source )
{
try
if( source == TileChest.this.mySrc || source.machine().map( machine -> machine == TileChest.this ).orElse( false ) )
{
if( TileChest.this.getProxy().isActive() )
try
{
TileChest.this.getProxy().getStorage().postAlterationOfStoredItems( this.chan, change, TileChest.this.mySrc );
if( TileChest.this.getProxy().isActive() )
{
TileChest.this.getProxy().getStorage().postAlterationOfStoredItems( this.chan, change, TileChest.this.mySrc );
}
}
catch( final GridAccessException e )
{
// :(
}
} catch ( final GridAccessException e )
{
// :(
}
TileChest.this.blinkCell( 0 );
}
@@ -264,11 +264,9 @@ public class TileDrive extends AENetworkInvTile implements IChestOrDrive, IPrior
try
{
this.getProxy().getGrid().postEvent( new MENetworkCellArrayUpdate() );
if( this.getProxy().isActive() )
{
final IStorageGrid gs = this.getProxy().getStorage();
Platform.postChanges( gs, removed, added, this.mySrc );
}
final IStorageGrid gs = this.getProxy().getStorage();
Platform.postChanges( gs, removed, added, this.mySrc );
}
catch( final GridAccessException ignored )
{
@@ -336,8 +334,13 @@ public class TileDrive extends AENetworkInvTile implements IChestOrDrive, IPrior
@Override
public List<IMEInventoryHandler> getCellArray( final IStorageChannel channel )
{
this.updateState();
return this.inventoryHandlers.get( channel );
if( this.getProxy().isActive() )
{
this.updateState();
return this.inventoryHandlers.get( channel );
}
return Collections.emptyList();
}
@Override
@@ -418,12 +418,10 @@ public class TileIOPort extends AENetworkInvTile implements IUpgradeableHost, IC
if( possible > 0 )
{
IAEStack injectable = s.copy();
possible = Math.min( possible, itemsToMove );
injectable.setStackSize( possible );
s.setStackSize( possible );
final IAEStack extracted = src.extractItems( injectable, Actionable.MODULATE, this.mySrc );
final IAEStack extracted = src.extractItems( s, Actionable.MODULATE, this.mySrc );
if( extracted != null )
{
possible = extracted.getStackSize();
@@ -502,9 +500,8 @@ public class TileIOPort extends AENetworkInvTile implements IUpgradeableHost, IC
final IAEStack test = myList.getFirstItem();
if( test != null )
{
IAEStack testCopy = test.copy();
testCopy.setStackSize( 1 );
return src.injectItems( testCopy, Actionable.SIMULATE, this.mySrc ) != null;
test.setStackSize( 1 );
return src.injectItems( test, Actionable.SIMULATE, this.mySrc ) != null;
}
return false;
}
@@ -36,7 +36,6 @@ public final class ConfigManager implements IConfigManager
{
private final Map<Settings, Enum<?>> settings = new EnumMap<>( Settings.class );
private final IConfigManagerHost target;
private Map<Settings, Enum<?>> oldSettings = new EnumMap<>( Settings.class );
public ConfigManager( final IConfigManagerHost tile )
{
@@ -73,15 +72,10 @@ public final class ConfigManager implements IConfigManager
{
final Enum<?> oldValue = this.getSetting( settingName );
this.settings.put( settingName, newValue );
this.oldSettings.put( settingName, oldValue );
this.target.updateSetting( this, settingName, newValue );
return oldValue;
}
public Enum<?> getOldSetting(final Settings settingName){
return this.oldSettings.get( settingName );
}
/**
* save all settings using config manager.
*