diff --git a/src/main/java/appeng/me/cache/P2PCache.java b/src/main/java/appeng/me/cache/P2PCache.java index a491a8bee..f25bbb080 100644 --- a/src/main/java/appeng/me/cache/P2PCache.java +++ b/src/main/java/appeng/me/cache/P2PCache.java @@ -20,6 +20,7 @@ package appeng.me.cache; import java.util.HashMap; +import java.util.Random; import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.Multimap; @@ -34,6 +35,7 @@ import appeng.api.networking.events.MENetworkBootingStatusChange; import appeng.api.networking.events.MENetworkEventSubscribe; import appeng.api.networking.events.MENetworkPowerStatusChange; import appeng.api.networking.ticking.ITickManager; +import appeng.core.AELog; import appeng.me.cache.helpers.TunnelCollection; import appeng.parts.p2p.PartP2PTunnel; import appeng.parts.p2p.PartP2PTunnelME; @@ -41,15 +43,17 @@ import appeng.parts.p2p.PartP2PTunnelME; public class P2PCache implements IGridCache { + private static final TunnelCollection NULL_COLLECTION = new TunnelCollection( null, null ); private final IGrid myGrid; - private final HashMap inputs = new HashMap<>(); - private final Multimap outputs = LinkedHashMultimap.create(); - private final TunnelCollection NullColl = new TunnelCollection<>( null, null ); + private final HashMap inputs = new HashMap<>(); + private final Multimap outputs = LinkedHashMultimap.create(); + private final Random frequencyGenerator; public P2PCache( final IGrid g ) { this.myGrid = g; + this.frequencyGenerator = new Random( g.hashCode() ); } @MENetworkEventSubscribe @@ -98,8 +102,7 @@ public class P2PCache implements IGridCache } final PartP2PTunnel t = (PartP2PTunnel) machine; - // AELog.info( "rmv-" + (t.output ? "output: " : "input: ") + t.freq - // ); + // AELog.info( "rmv-" + (t.output ? "output: " : "input: ") + t.freq ); if( t.isOutput() ) { @@ -128,8 +131,7 @@ public class P2PCache implements IGridCache } final PartP2PTunnel t = (PartP2PTunnel) machine; - // AELog.info( "add-" + (t.output ? "output: " : "input: ") + t.freq - // ); + // AELog.info( "add-" + (t.output ? "output: " : "input: ") + t.freq ); if( t.isOutput() ) { @@ -162,7 +164,7 @@ public class P2PCache implements IGridCache } - private void updateTunnel( final long freq, final boolean updateOutputs, final boolean configChange ) + private void updateTunnel( final short freq, final boolean updateOutputs, final boolean configChange ) { for( final PartP2PTunnel p : this.outputs.get( freq ) ) { @@ -184,7 +186,7 @@ public class P2PCache implements IGridCache } } - public void updateFreq( final PartP2PTunnel t, final long newFrequency ) + public void updateFreq( final PartP2PTunnel t, final short newFrequency ) { if( this.outputs.containsValue( t ) ) { @@ -207,30 +209,51 @@ public class P2PCache implements IGridCache this.inputs.put( t.getFrequency(), t ); } - // AELog.info( "update-" + (t.output ? "output: " : "input: ") + t.freq - // ); + // AELog.info( "update-" + (t.output ? "output: " : "input: ") + t.freq ); this.updateTunnel( t.getFrequency(), t.isOutput(), true ); this.updateTunnel( t.getFrequency(), !t.isOutput(), true ); } - public TunnelCollection getOutputs( final long freq, final Class c ) + public short newFrequency() + { + short newFrequency; + int cycles = 0; + + do + { + newFrequency = (short) this.frequencyGenerator.nextInt( 1 << 16 ); + cycles++; + } + while( newFrequency == 0 || this.inputs.containsKey( newFrequency ) ); + + if( cycles > 25 ) + { + AELog.debug( "Generating a new P2P frequency '%1$d' took %2$d cycles", newFrequency, cycles ); + } + + return newFrequency; + } + + public TunnelCollection getOutputs( final short freq, final Class c ) { final PartP2PTunnel in = this.inputs.get( freq ); + if( in == null ) { - return this.NullColl; + return NULL_COLLECTION; } final TunnelCollection out = this.inputs.get( freq ).getCollection( this.outputs.get( freq ), c ); + if( out == null ) { - return this.NullColl; + return NULL_COLLECTION; } return out; } - public PartP2PTunnel getInput( final long freq ) + public PartP2PTunnel getInput( final short freq ) { return this.inputs.get( freq ); } diff --git a/src/main/java/appeng/parts/p2p/PartP2PTunnel.java b/src/main/java/appeng/parts/p2p/PartP2PTunnel.java index 3c99ab6d8..28bcf6d7b 100644 --- a/src/main/java/appeng/parts/p2p/PartP2PTunnel.java +++ b/src/main/java/appeng/parts/p2p/PartP2PTunnel.java @@ -55,7 +55,7 @@ public abstract class PartP2PTunnel extends PartBasicSt { private final TunnelCollection type = new TunnelCollection( null, this.getClass() ); private boolean output; - private long freq; + private short freq; public PartP2PTunnel( final ItemStack is ) { @@ -134,7 +134,7 @@ public abstract class PartP2PTunnel extends PartBasicSt { super.readFromNBT( data ); this.setOutput( data.getBoolean( "output" ) ); - this.setFrequency( data.getLong( "freq" ) ); + this.setFrequency( data.getShort( "freq" ) ); } @Override @@ -142,7 +142,7 @@ public abstract class PartP2PTunnel extends PartBasicSt { super.writeToNBT( data ); data.setBoolean( "output", this.isOutput() ); - data.setLong( "freq", this.getFrequency() ); + data.setShort( "freq", this.getFrequency() ); } @Override @@ -172,7 +172,7 @@ public abstract class PartP2PTunnel extends PartBasicSt final NBTTagCompound data = mc.getData( is ); final ItemStack newType = new ItemStack( data ); - final long freq = data.getLong( "freq" ); + final short freq = data.getShort( "freq" ); if( !newType.isEmpty() ) { @@ -267,7 +267,7 @@ public abstract class PartP2PTunnel extends PartBasicSt if( !newType.isEmpty() && !Platform.itemComparisons().isEqualItem( newType, this.getItemStack() ) ) { final boolean oldOutput = this.isOutput(); - final long myFreq = this.getFrequency(); + final short myFreq = this.getFrequency(); this.getHost().removePart( this.getSide(), false ); final AEPartLocation dir = this.getHost().addPart( newType, this.getSide(), player, hand ); @@ -307,17 +307,17 @@ public abstract class PartP2PTunnel extends PartBasicSt final IMemoryCard mc = (IMemoryCard) is.getItem(); final NBTTagCompound data = new NBTTagCompound(); - long newFreq = this.getFrequency(); + short newFreq = this.getFrequency(); final boolean wasOutput = this.isOutput(); this.setOutput( false ); - if( wasOutput || this.getFrequency() == 0 ) - { - newFreq = System.currentTimeMillis(); - } - try { + if( wasOutput || this.getFrequency() == 0 ) + { + newFreq = this.getProxy().getP2P().newFrequency(); + } + this.getProxy().getP2P().updateFreq( this, newFreq ); } catch( final GridAccessException e ) @@ -331,7 +331,7 @@ public abstract class PartP2PTunnel extends PartBasicSt final String type = p2pItem.getUnlocalizedName(); p2pItem.writeToNBT( data ); - data.setLong( "freq", this.getFrequency() ); + data.setShort( "freq", this.getFrequency() ); mc.setMemoryCardContents( is, type + ".name", data ); mc.notifyUser( player, MemoryCardMessages.SETTINGS_SAVED ); @@ -363,12 +363,12 @@ public abstract class PartP2PTunnel extends PartBasicSt } } - public long getFrequency() + public short getFrequency() { return this.freq; } - public void setFrequency( final long freq ) + public void setFrequency( final short freq ) { this.freq = freq; } diff --git a/src/main/java/appeng/spatial/StorageHelper.java b/src/main/java/appeng/spatial/StorageHelper.java index b573aedf4..4ca35d2cf 100644 --- a/src/main/java/appeng/spatial/StorageHelper.java +++ b/src/main/java/appeng/spatial/StorageHelper.java @@ -139,6 +139,8 @@ public class StorageHelper passanger.startRiding( entity, true ); } } + + entity.world.updateEntity( entity ); return entity; } diff --git a/src/main/java/appeng/util/Platform.java b/src/main/java/appeng/util/Platform.java index 40f2f9b35..54bbaba20 100644 --- a/src/main/java/appeng/util/Platform.java +++ b/src/main/java/appeng/util/Platform.java @@ -129,6 +129,7 @@ import appeng.me.GridAccessException; import appeng.me.GridNode; import appeng.me.helpers.AENetworkProxy; import appeng.util.helpers.ItemComparisonHelper; +import appeng.util.helpers.P2PHelper; import appeng.util.item.AEItemStack; import appeng.util.item.AESharedNBT; import appeng.util.prioritylist.IPartitionList; @@ -157,12 +158,18 @@ public class Platform // private static Method getEntry; private static final ItemComparisonHelper ITEM_COMPARISON_HELPER = new ItemComparisonHelper(); + private static final P2PHelper P2P_HELPER = new P2PHelper(); public static ItemComparisonHelper itemComparisons() { return ITEM_COMPARISON_HELPER; } + public static P2PHelper p2p() + { + return P2P_HELPER; + } + public static Random getRandom() { return RANDOM_GENERATOR; diff --git a/src/main/java/appeng/util/helpers/P2PHelper.java b/src/main/java/appeng/util/helpers/P2PHelper.java new file mode 100644 index 000000000..57ce23dae --- /dev/null +++ b/src/main/java/appeng/util/helpers/P2PHelper.java @@ -0,0 +1,60 @@ +/* + * This file is part of Applied Energistics 2. + * Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved. + * + * Applied Energistics 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Applied Energistics 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Applied Energistics 2. If not, see . + */ + +package appeng.util.helpers; + + +import com.google.common.base.Preconditions; + +import appeng.api.util.AEColor; + + +public class P2PHelper +{ + + public AEColor[] toColors( short frequency ) + { + final AEColor[] colors = new AEColor[4]; + + for( int i = 0; i < 4; i++ ) + { + int nibble = ( frequency >> 4 * ( 3 - i ) ) & 0xF; + + colors[i] = AEColor.values()[nibble]; + } + + return colors; + } + + public short fromColors( AEColor[] colors ) + { + Preconditions.checkArgument( colors.length == 4 ); + + int t = 0; + + for( int i = 0; i < 4; i++ ) + { + int code = colors[3 - i].ordinal() << 4 * i; + + t |= code; + } + + return (short) ( t & 0xFFFF ); + } + +} diff --git a/src/test/java/appeng/util/helpers/P2PHelperTest.java b/src/test/java/appeng/util/helpers/P2PHelperTest.java new file mode 100644 index 000000000..c96a459cd --- /dev/null +++ b/src/test/java/appeng/util/helpers/P2PHelperTest.java @@ -0,0 +1,69 @@ +/* + * This file is part of Applied Energistics 2. + * Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved. + * + * Applied Energistics 2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Applied Energistics 2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Applied Energistics 2. If not, see . + */ + +package appeng.util.helpers; + + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import appeng.api.util.AEColor; + + +public class P2PHelperTest +{ + + private P2PHelper unitUnderTest = new P2PHelper(); + + private static short WHITE_FREQUENCY = 0; + private static AEColor[] WHITE_COLORS = new AEColor[] { AEColor.WHITE, AEColor.WHITE, AEColor.WHITE, AEColor.WHITE }; + + private static short BLACK_FREQUENCY = (short) 0xFFFF; + private static AEColor[] BLACK_COLORS = new AEColor[] { AEColor.BLACK, AEColor.BLACK, AEColor.BLACK, AEColor.BLACK }; + + private static short MULTI_FREQUENCY = (short) 0xE8D1; + private static AEColor[] MULTI_COLORS = new AEColor[] { AEColor.RED, AEColor.LIGHT_GRAY, AEColor.GREEN, AEColor.ORANGE }; + + @Test + public void testToColors() + { + assertArrayEquals( WHITE_COLORS, unitUnderTest.toColors( WHITE_FREQUENCY ) ); + assertArrayEquals( BLACK_COLORS, unitUnderTest.toColors( BLACK_FREQUENCY ) ); + assertArrayEquals( MULTI_COLORS, unitUnderTest.toColors( MULTI_FREQUENCY ) ); + } + + @Test + public void testFromColors() + { + assertEquals( WHITE_FREQUENCY, unitUnderTest.fromColors( WHITE_COLORS ) ); + assertEquals( BLACK_FREQUENCY, unitUnderTest.fromColors( BLACK_COLORS ) ); + assertEquals( MULTI_FREQUENCY, unitUnderTest.fromColors( MULTI_COLORS ) ); + } + + @Test + public void testToAndFromColors() + { + for( short i = Short.MIN_VALUE; i < Short.MAX_VALUE; i++ ) + { + assertEquals( i, unitUnderTest.fromColors( unitUnderTest.toColors( i ) ) ); + } + } + +}