From e392ecd08d108a712a0707d51fcf46c0f3c53f63 Mon Sep 17 00:00:00 2001 From: thatsIch Date: Fri, 1 May 2015 09:49:00 +0200 Subject: [PATCH] Fixes #1368: Vibration Chamber notifies neighbors on inventory change and state change --- .../block/misc/BlockVibrationChamber.java | 2 +- src/main/java/appeng/helpers/Reflected.java | 2 +- src/main/java/appeng/tile/AEBaseInvTile.java | 4 +- src/main/java/appeng/tile/AEBaseTile.java | 109 +++++++++++------- .../tile/events/AETileEventHandler.java | 8 +- .../appeng/tile/events/TileEventType.java | 7 +- .../tile/misc/TileVibrationChamber.java | 68 ++++++----- .../appeng/tile/networking/TileCableBus.java | 7 -- 8 files changed, 123 insertions(+), 84 deletions(-) diff --git a/src/main/java/appeng/block/misc/BlockVibrationChamber.java b/src/main/java/appeng/block/misc/BlockVibrationChamber.java index 574aaaf7a..3f076dea3 100644 --- a/src/main/java/appeng/block/misc/BlockVibrationChamber.java +++ b/src/main/java/appeng/block/misc/BlockVibrationChamber.java @@ -39,7 +39,7 @@ import appeng.tile.misc.TileVibrationChamber; import appeng.util.Platform; -public class BlockVibrationChamber extends AEBaseBlock +public final class BlockVibrationChamber extends AEBaseBlock { public BlockVibrationChamber() diff --git a/src/main/java/appeng/helpers/Reflected.java b/src/main/java/appeng/helpers/Reflected.java index 4938d5eba..6e0c84da8 100644 --- a/src/main/java/appeng/helpers/Reflected.java +++ b/src/main/java/appeng/helpers/Reflected.java @@ -11,7 +11,7 @@ import java.lang.annotation.Target; * Marker interface to help identify invocation of reflection */ @Retention( RetentionPolicy.SOURCE ) -@Target( { ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.TYPE } ) +@Target( { ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.TYPE, ElementType.METHOD } ) public @interface Reflected { diff --git a/src/main/java/appeng/tile/AEBaseInvTile.java b/src/main/java/appeng/tile/AEBaseInvTile.java index 9ceef2816..529d98661 100644 --- a/src/main/java/appeng/tile/AEBaseInvTile.java +++ b/src/main/java/appeng/tile/AEBaseInvTile.java @@ -19,6 +19,8 @@ package appeng.tile; +import javax.annotation.Nullable; + import net.minecraft.block.Block; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; @@ -93,7 +95,7 @@ public abstract class AEBaseInvTile extends AEBaseTile implements ISidedInventor } @Override - public void setInventorySlotContents( int i, ItemStack itemstack ) + public void setInventorySlotContents( int i, @Nullable ItemStack itemstack ) { this.getInternalInventory().setInventorySlotContents( i, itemstack ); } diff --git a/src/main/java/appeng/tile/AEBaseTile.java b/src/main/java/appeng/tile/AEBaseTile.java index 5e67c8b5a..71f817fd4 100644 --- a/src/main/java/appeng/tile/AEBaseTile.java +++ b/src/main/java/appeng/tile/AEBaseTile.java @@ -26,6 +26,9 @@ import java.util.EnumMap; import java.util.HashMap; import java.util.LinkedList; import java.util.List; +import java.util.Map; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; @@ -61,14 +64,15 @@ public class AEBaseTile extends TileEntity implements IOrientable, ICommonTile, { public static final ThreadLocal> DROP_NO_ITEMS = new ThreadLocal>(); - private static final HashMap>> HANDLERS = new HashMap>>(); - private static final HashMap ITEM_STACKS = new HashMap(); - public int renderFragment = 0; + private static final Map, Map>> HANDLERS = new HashMap, Map>>(); + private static final Map, ItemStackSrc> ITEM_STACKS = new HashMap, ItemStackSrc>(); + private int renderFragment = 0; + @Nullable public String customName; private ForgeDirection forward = ForgeDirection.UNKNOWN; private ForgeDirection up = ForgeDirection.UNKNOWN; - public static void registerTileItem( Class c, ItemStackSrc wat ) + public static void registerTileItem( Class c, ItemStackSrc wat ) { ITEM_STACKS.put( c, wat ); } @@ -84,11 +88,13 @@ public class AEBaseTile extends TileEntity implements IOrientable, ICommonTile, return !this.worldObj.blockExists( this.xCoord, this.yCoord, this.zCoord ); } + @Nonnull public TileEntity getTile() { return this; } + @Nullable protected ItemStack getItemFromTile( Object obj ) { ItemStackSrc src = ITEM_STACKS.get( obj.getClass() ); @@ -99,11 +105,6 @@ public class AEBaseTile extends TileEntity implements IOrientable, ICommonTile, return src.stack( 1 ); } - public final void Tick() - { - - } - /** * for dormant chunk cache. */ @@ -176,7 +177,7 @@ public class AEBaseTile extends TileEntity implements IOrientable, ICommonTile, { for( AETileEventHandler h : this.getHandlerListFor( TileEventType.TICK ) ) { - h.Tick( this ); + h.tick( this ); } } @@ -211,10 +212,11 @@ public class AEBaseTile extends TileEntity implements IOrientable, ICommonTile, return this.hasHandlerFor( TileEventType.TICK ); } - protected boolean hasHandlerFor( TileEventType type ) + private boolean hasHandlerFor( TileEventType type ) { List list = this.getHandlerListFor( type ); - return list != null && !list.isEmpty(); + + return !list.isEmpty(); } @Override @@ -331,45 +333,72 @@ public class AEBaseTile extends TileEntity implements IOrientable, ICommonTile, return true; } - protected List getHandlerListFor( TileEventType type ) + @Nonnull + private List getHandlerListFor( TileEventType type ) { - Class clz = this.getClass(); - EnumMap> handlerSet = HANDLERS.get( clz ); + final Map> eventToHandlers = this.getEventToHandlers(); + final List handlers = this.getHandlers( eventToHandlers, type ); - if( handlerSet == null ) - { - HANDLERS.put( clz, handlerSet = new EnumMap>( TileEventType.class ) ); - - for( Method m : clz.getMethods() ) - { - TileEvent te = m.getAnnotation( TileEvent.class ); - if( te != null ) - { - this.addHandler( handlerSet, te.value(), m ); - } - } - } - - List list = handlerSet.get( type ); - - if( list == null ) - { - handlerSet.put( type, list = new LinkedList() ); - } - - return list; + return handlers; } - private void addHandler( EnumMap> handlerSet, TileEventType value, Method m ) + @Nonnull + private Map> getEventToHandlers() + { + final Class clazz = this.getClass(); + final Map> storedHandlers = HANDLERS.get( clazz ); + + if ( storedHandlers == null ) + { + final Map> newStoredHandlers = new EnumMap>( TileEventType.class ); + + HANDLERS.put( clazz, newStoredHandlers ); + + for( Method method : clazz.getMethods() ) + { + TileEvent event = method.getAnnotation( TileEvent.class ); + if( event != null ) + { + this.addHandler( newStoredHandlers, event.value(), method ); + } + } + + return newStoredHandlers; + } + else + { + return storedHandlers; + } + } + + @Nonnull + private List getHandlers( Map> eventToHandlers, TileEventType event ) { + final List oldHandlers = eventToHandlers.get( event ); + + if( oldHandlers == null ) + { + final List newHandlers = new LinkedList(); + eventToHandlers.put( event, newHandlers ); + + return newHandlers; + } + else + { + return oldHandlers; + } + } + + private void addHandler( Map> handlerSet, TileEventType value, Method m ) { List list = handlerSet.get( value ); if( list == null ) { - handlerSet.put( value, list = new ArrayList() ); + list = new ArrayList(); + handlerSet.put( value, list ); } - list.add( new AETileEventHandler( m, value ) ); + list.add( new AETileEventHandler( m ) ); } @Override diff --git a/src/main/java/appeng/tile/events/AETileEventHandler.java b/src/main/java/appeng/tile/events/AETileEventHandler.java index d33b25519..3bd648e30 100644 --- a/src/main/java/appeng/tile/events/AETileEventHandler.java +++ b/src/main/java/appeng/tile/events/AETileEventHandler.java @@ -32,18 +32,18 @@ import cpw.mods.fml.relauncher.SideOnly; import appeng.tile.AEBaseTile; -public class AETileEventHandler +public final class AETileEventHandler { private final Method method; - public AETileEventHandler( Method m, TileEventType which ) + public AETileEventHandler( Method method ) { - this.method = m; + this.method = method; } // TICK - public void Tick( AEBaseTile tile ) + public void tick( AEBaseTile tile ) { try { diff --git a/src/main/java/appeng/tile/events/TileEventType.java b/src/main/java/appeng/tile/events/TileEventType.java index 3b242863a..26cadd3db 100644 --- a/src/main/java/appeng/tile/events/TileEventType.java +++ b/src/main/java/appeng/tile/events/TileEventType.java @@ -25,5 +25,10 @@ public enum TileEventType WORLD_NBT_READ, WORLD_NBT_WRITE, - NETWORK_READ, NETWORK_WRITE + /** + * Methods annotated with this need to return a boolean + */ + NETWORK_READ, + + NETWORK_WRITE } diff --git a/src/main/java/appeng/tile/misc/TileVibrationChamber.java b/src/main/java/appeng/tile/misc/TileVibrationChamber.java index 60230e6d0..dbfd51d7c 100644 --- a/src/main/java/appeng/tile/misc/TileVibrationChamber.java +++ b/src/main/java/appeng/tile/misc/TileVibrationChamber.java @@ -36,21 +36,25 @@ import appeng.api.networking.ticking.TickingRequest; import appeng.api.util.AECableType; import appeng.api.util.DimensionalCoord; import appeng.core.settings.TickRates; +import appeng.helpers.Reflected; import appeng.me.GridAccessException; import appeng.tile.TileEvent; import appeng.tile.events.TileEventType; import appeng.tile.grid.AENetworkInvTile; import appeng.tile.inventory.AppEngInternalInventory; import appeng.tile.inventory.InvOperation; +import appeng.util.Platform; public class TileVibrationChamber extends AENetworkInvTile implements IGridTickable { - - final double powerPerTick = 5; - - final int[] sides = new int[] { 0 }; - final AppEngInternalInventory inv = new AppEngInternalInventory( this, 1 ); + private static final int FUEL_SLOT_INDEX = 0; + private static final double POWER_PER_TICK = 5; + private static final int[] ACCESSIBLE_SLOTS = new int[] { FUEL_SLOT_INDEX }; + private static final int MAX_BURN_SPEED = 200; + private static final double DILATION_SCALING = 100.0; + private static final int MIN_BURN_SPEED = 20; + private final IInventory inv = new AppEngInternalInventory( this, 1 ); public int burnSpeed = 100; public double burnTime = 0; @@ -71,16 +75,20 @@ public class TileVibrationChamber extends AENetworkInvTile implements IGridTicka return AECableType.COVERED; } + @Reflected @TileEvent( TileEventType.NETWORK_READ ) - public boolean readFromStream_TileVibrationChamber( ByteBuf data ) + public boolean hasUpdate( ByteBuf data ) { - boolean wasOn = this.isOn; + final boolean wasOn = this.isOn; + this.isOn = data.readBoolean(); + return wasOn != this.isOn; // TESR doesn't need updates! } + @Reflected @TileEvent( TileEventType.NETWORK_WRITE ) - public void writeToStream_TileVibrationChamber( ByteBuf data ) + public void writeToNetwork( ByteBuf data ) { data.writeBoolean( this.burnTime > 0 ); } @@ -107,12 +115,6 @@ public class TileVibrationChamber extends AENetworkInvTile implements IGridTicka return this.inv; } - @Override - public int getInventoryStackLimit() - { - return 64; - } - @Override public boolean isItemValidForSlot( int i, ItemStack itemstack ) { @@ -147,12 +149,12 @@ public class TileVibrationChamber extends AENetworkInvTile implements IGridTicka @Override public int[] getAccessibleSlotsBySide( ForgeDirection side ) { - return this.sides; + return ACCESSIBLE_SLOTS; } private boolean canEatFuel() { - ItemStack is = this.getStackInSlot( 0 ); + ItemStack is = this.getStackInSlot( FUEL_SLOT_INDEX ); if( is != null ) { int newBurnTime = TileEntityFurnace.getItemBurnTime( is ); @@ -182,7 +184,7 @@ public class TileVibrationChamber extends AENetworkInvTile implements IGridTicka } @Override - public TickRateModulation tickingRequest( IGridNode node, int TicksSinceLastCall ) + public TickRateModulation tickingRequest( IGridNode node, int ticksSinceLastCall ) { if( this.burnTime <= 0 ) { @@ -197,10 +199,10 @@ public class TileVibrationChamber extends AENetworkInvTile implements IGridTicka return TickRateModulation.SLEEP; } - this.burnSpeed = Math.max( 20, Math.min( this.burnSpeed, 200 ) ); - double dilation = this.burnSpeed / 100.0; + this.burnSpeed = Math.max( MIN_BURN_SPEED, Math.min( this.burnSpeed, MAX_BURN_SPEED ) ); + double dilation = this.burnSpeed / DILATION_SCALING; - double timePassed = TicksSinceLastCall * dilation; + double timePassed = ticksSinceLastCall * dilation; this.burnTime -= timePassed; if( this.burnTime < 0 ) { @@ -211,7 +213,7 @@ public class TileVibrationChamber extends AENetworkInvTile implements IGridTicka try { IEnergyGrid grid = this.gridProxy.getEnergy(); - double newPower = timePassed * this.powerPerTick; + double newPower = timePassed * POWER_PER_TICK; double overFlow = grid.injectPower( newPower, Actionable.SIMULATE ); // burn the over flow. @@ -219,30 +221,30 @@ public class TileVibrationChamber extends AENetworkInvTile implements IGridTicka if( overFlow > 0 ) { - this.burnSpeed -= TicksSinceLastCall; + this.burnSpeed -= ticksSinceLastCall; } else { - this.burnSpeed += TicksSinceLastCall; + this.burnSpeed += ticksSinceLastCall; } - this.burnSpeed = Math.max( 20, Math.min( this.burnSpeed, 200 ) ); + this.burnSpeed = Math.max( MIN_BURN_SPEED, Math.min( this.burnSpeed, MAX_BURN_SPEED ) ); return overFlow > 0 ? TickRateModulation.SLOWER : TickRateModulation.FASTER; } catch( GridAccessException e ) { - this.burnSpeed -= TicksSinceLastCall; - this.burnSpeed = Math.max( 20, Math.min( this.burnSpeed, 200 ) ); + this.burnSpeed -= ticksSinceLastCall; + this.burnSpeed = Math.max( MIN_BURN_SPEED, Math.min( this.burnSpeed, MAX_BURN_SPEED ) ); return TickRateModulation.SLOWER; } } private void eatFuel() { - ItemStack is = this.getStackInSlot( 0 ); + final ItemStack is = this.getStackInSlot( FUEL_SLOT_INDEX ); if( is != null ) { - int newBurnTime = TileEntityFurnace.getItemBurnTime( is ); + final int newBurnTime = TileEntityFurnace.getItemBurnTime( is ); if( newBurnTime > 0 && is.stackSize > 0 ) { this.burnTime += newBurnTime; @@ -252,7 +254,7 @@ public class TileVibrationChamber extends AENetworkInvTile implements IGridTicka { ItemStack container = null; - if( is.getItem().hasContainerItem( is ) ) + if( is.getItem() != null && is.getItem().hasContainerItem( is ) ) { container = is.getItem().getContainerItem( is ); } @@ -263,6 +265,8 @@ public class TileVibrationChamber extends AENetworkInvTile implements IGridTicka { this.setInventorySlotContents( 0, is ); } + + this.markDirty(); } } @@ -278,10 +282,16 @@ public class TileVibrationChamber extends AENetworkInvTile implements IGridTicka } } + // state change if( ( !this.isOn && this.burnTime > 0 ) || ( this.isOn && this.burnTime <= 0 ) ) { this.isOn = this.burnTime > 0; this.markForUpdate(); + + if ( this.hasWorldObj() ) + { + Platform.notifyBlocksOfNeighbors( this.worldObj, this.xCoord, this.yCoord, this.zCoord ); + } } } } diff --git a/src/main/java/appeng/tile/networking/TileCableBus.java b/src/main/java/appeng/tile/networking/TileCableBus.java index 2de8272c5..9ee329b69 100644 --- a/src/main/java/appeng/tile/networking/TileCableBus.java +++ b/src/main/java/appeng/tile/networking/TileCableBus.java @@ -30,7 +30,6 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntity; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.Vec3; import net.minecraft.world.World; @@ -162,12 +161,6 @@ public class TileCableBus extends AEBaseTile implements AEMultiTile, ICustomColl return this.cb.getCableConnectionType( side ); } - @Override - public TileEntity getTile() - { - return this; - } - @Override public void onChunkUnload() {