From 0016857b032d5d4f6551ef92e1ea4a2976b954ff Mon Sep 17 00:00:00 2001 From: AlgorithmX2 Date: Tue, 21 Jan 2014 22:52:33 -0600 Subject: [PATCH] ME P2P tunnels --- helpers/TickHandler.java | 21 +++++ me/cache/P2PCache.java | 59 ++++++++++--- me/cache/helpers/Connections.java | 45 ++++++++++ parts/p2p/PartP2PTunnelME.java | 137 +++++++++++++++++++++++++++++- 4 files changed, 250 insertions(+), 12 deletions(-) create mode 100644 me/cache/helpers/Connections.java diff --git a/helpers/TickHandler.java b/helpers/TickHandler.java index 61fe9446b..e0b2f1970 100644 --- a/helpers/TickHandler.java +++ b/helpers/TickHandler.java @@ -3,6 +3,7 @@ package appeng.helpers; import java.util.EnumSet; import java.util.LinkedList; import java.util.Queue; +import java.util.concurrent.Callable; import net.minecraftforge.event.ForgeSubscribe; import net.minecraftforge.event.world.WorldEvent; @@ -33,6 +34,8 @@ public class TickHandler implements ITickHandler final public static TickHandler instance = new TickHandler(); + final private Queue callQueue = new LinkedList(); + final private HandlerRep server = new HandlerRep(); final private HandlerRep client = new HandlerRep(); @@ -43,6 +46,11 @@ public class TickHandler implements ITickHandler return client; } + public void addCallable(Callable c) + { + callQueue.add( c ); + } + public void addInit(AEBaseTile tile) { getRepo().tiles.add( tile ); @@ -107,6 +115,19 @@ public class TickHandler implements ITickHandler { g.update(); } + + Callable c = null; + while ((c = callQueue.poll()) != null) + { + try + { + c.call(); + } + catch (Exception e) + { + e.printStackTrace(); + } + } } @Override diff --git a/me/cache/P2PCache.java b/me/cache/P2PCache.java index d562226a8..8a025176a 100644 --- a/me/cache/P2PCache.java +++ b/me/cache/P2PCache.java @@ -2,14 +2,19 @@ package appeng.me.cache; import java.util.HashMap; +import appeng.api.networking.GridFlags; import appeng.api.networking.IGrid; import appeng.api.networking.IGridCache; import appeng.api.networking.IGridHost; import appeng.api.networking.IGridNode; import appeng.api.networking.IGridStorage; -import appeng.core.AELog; +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.me.cache.helpers.TunnelCollection; import appeng.parts.p2p.PartP2PTunnel; +import appeng.parts.p2p.PartP2PTunnelME; import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.Multimap; @@ -27,6 +32,34 @@ public class P2PCache implements IGridCache myGrid = g; } + @MENetworkEventSubscribe + public void bootComplete(MENetworkBootingStatusChange bootstat) + { + ITickManager tm = myGrid.getCache( ITickManager.class ); + for (PartP2PTunnel me : inputs.values()) + { + if ( me instanceof PartP2PTunnelME ) + tm.wakeDevice( me.getGridNode() ); + } + } + + @MENetworkEventSubscribe + public void bootComplete(MENetworkPowerStatusChange power) + { + ITickManager tm = myGrid.getCache( ITickManager.class ); + for (PartP2PTunnel me : inputs.values()) + { + if ( me instanceof PartP2PTunnelME ) + tm.wakeDevice( me.getGridNode() ); + } + } + + @Override + public void onUpdateTick(IGrid grid) + { + + } + public void updateFreq(PartP2PTunnel t, long NewFreq) { outputs.remove( t.freq, t ); @@ -39,7 +72,7 @@ public class P2PCache implements IGridCache else inputs.put( t.freq, t ); - AELog.info( "update-" + (t.output ? "output: " : "input: ") + t.freq ); + // AELog.info( "update-" + (t.output ? "output: " : "input: ") + t.freq ); updateTunnel( t.freq, t.output ); updateTunnel( t.freq, !t.output ); } @@ -49,8 +82,14 @@ public class P2PCache implements IGridCache { if ( machine instanceof PartP2PTunnel ) { + if ( machine instanceof PartP2PTunnelME ) + { + if ( !node.hasFlag( GridFlags.REQURE_CHANNEL ) ) + return; + } + PartP2PTunnel t = (PartP2PTunnel) machine; - AELog.info( "add-" + (t.output ? "output: " : "input: ") + t.freq ); + // AELog.info( "add-" + (t.output ? "output: " : "input: ") + t.freq ); if ( t.output ) outputs.put( t.freq, t ); @@ -66,8 +105,14 @@ public class P2PCache implements IGridCache { if ( machine instanceof PartP2PTunnel ) { + if ( machine instanceof PartP2PTunnelME ) + { + if ( !node.hasFlag( GridFlags.REQURE_CHANNEL ) ) + return; + } + PartP2PTunnel t = (PartP2PTunnel) machine; - AELog.info( "rmv-" + (t.output ? "output: " : "input: ") + t.freq ); + // AELog.info( "rmv-" + (t.output ? "output: " : "input: ") + t.freq ); if ( t.output ) outputs.remove( t.freq, t ); @@ -106,12 +151,6 @@ public class P2PCache implements IGridCache return inputs.get( freq ); } - @Override - public void onUpdateTick(IGrid grid) - { - - } - @Override public void onSplit(IGridStorage storageB) { diff --git a/me/cache/helpers/Connections.java b/me/cache/helpers/Connections.java new file mode 100644 index 000000000..a632e9c07 --- /dev/null +++ b/me/cache/helpers/Connections.java @@ -0,0 +1,45 @@ +package appeng.me.cache.helpers; + +import java.util.HashMap; +import java.util.concurrent.Callable; + +import appeng.api.networking.IGridNode; +import appeng.core.AELog; +import appeng.parts.p2p.PartP2PTunnelME; + +public class Connections implements Callable +{ + + final private PartP2PTunnelME me; + final public HashMap connections = new HashMap(); + + public boolean create = false; + public boolean destroy = false; + + public Connections(PartP2PTunnelME o) { + me = o; + } + + @Override + public Object call() throws Exception + { + me.updateConnections( this ); + + return null; + } + + public void markDestroy() + { + create = false; + destroy = true; + AELog.info( "markDestroy" ); + } + + public void markCreate() + { + create = true; + destroy = false; + AELog.info( "markCreate" ); + } + +}; diff --git a/parts/p2p/PartP2PTunnelME.java b/parts/p2p/PartP2PTunnelME.java index ed7f4bc25..afaf6f386 100644 --- a/parts/p2p/PartP2PTunnelME.java +++ b/parts/p2p/PartP2PTunnelME.java @@ -1,25 +1,38 @@ package appeng.parts.p2p; import java.util.EnumSet; +import java.util.Iterator; +import java.util.LinkedList; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraftforge.common.ForgeDirection; +import appeng.api.AEApi; import appeng.api.networking.GridFlags; import appeng.api.networking.IGridNode; +import appeng.api.networking.ticking.IGridTickable; +import appeng.api.networking.ticking.TickRateModulation; +import appeng.api.networking.ticking.TickingRequest; import appeng.api.parts.IPartHost; import appeng.api.util.AECableType; +import appeng.core.AELog; +import appeng.helpers.TickHandler; +import appeng.me.GridAccessException; +import appeng.me.cache.helpers.Connections; +import appeng.me.cache.helpers.TunnelConnection; import appeng.me.helpers.AENetworkProxy; -public class PartP2PTunnelME extends PartP2PTunnel +public class PartP2PTunnelME extends PartP2PTunnel implements IGridTickable { AENetworkProxy outerProxy = new AENetworkProxy( this, "outer", true ); + public Connections connection = new Connections( this ); public PartP2PTunnelME(ItemStack is) { super( is ); - proxy.setFlags( GridFlags.TIER_2_CAPACITY, GridFlags.REQURE_CHANNEL, GridFlags.DENSE_CHANNEL, GridFlags.CANNOT_CARRY_DENSE ); + proxy.setFlags( GridFlags.REQURE_CHANNEL, GridFlags.DENSE_CHANNEL ); + outerProxy.setFlags( GridFlags.TIER_2_CAPACITY, GridFlags.CANNOT_CARRY_DENSE ); } @Override @@ -69,4 +82,124 @@ public class PartP2PTunnelME extends PartP2PTunnel return AECableType.DENSE; } + @Override + public void onChange() + { + super.onChange(); + if ( !output ) + { + try + { + proxy.getTick().wakeDevice( proxy.getNode() ); + } + catch (GridAccessException e) + { + // :P + } + } + } + + @Override + public TickingRequest getTickingRequest(IGridNode node) + { + return new TickingRequest( 5, 20, output, false ); + } + + @Override + public TickRateModulation tickingRequest(IGridNode node, int TicksSinceLastCall) + { + // just move on... + try + { + if ( !proxy.getPath().isNetworkBooting() ) + { + if ( !proxy.getEnergy().isNetworkPowered() ) + { + connection.markDestroy(); + TickHandler.instance.addCallable( connection ); + } + else + { + if ( proxy.isActive() ) + { + connection.markCreate(); + TickHandler.instance.addCallable( connection ); + } + else + { + connection.markDestroy(); + TickHandler.instance.addCallable( connection ); + } + } + + return TickRateModulation.SLEEP; + } + } + catch (GridAccessException e) + { + // meh? + } + + return TickRateModulation.IDLE; + } + + public void updateConnections(Connections connections) + { + if ( connections.destroy ) + { + for (TunnelConnection cw : connection.connections.values()) + cw.c.destroy(); + + connection.connections.clear(); + } + else if ( connections.create ) + { + + Iterator i = connection.connections.values().iterator(); + while (i.hasNext()) + { + TunnelConnection cw = i.next(); + AELog.info( "Old!" ); + try + { + if ( cw.tunnel.proxy.getGrid() != proxy.getGrid() ) + { + cw.c.destroy(); + i.remove(); + } + else if ( !cw.tunnel.proxy.isActive() ) + { + cw.c.destroy(); + i.remove(); + } + } + catch (GridAccessException e) + { + e.printStackTrace(); + } + } + + LinkedList newSides = new LinkedList(); + try + { + for (PartP2PTunnelME me : getOutputs()) + { + if ( me.proxy.isActive() && connections.connections.get( me.getGridNode() ) == null ) + { + newSides.add( me ); + } + } + + for (PartP2PTunnelME me : newSides) + { + connections.connections.put( me.getGridNode(), + new TunnelConnection( me, AEApi.instance().createGridConnection( outerProxy.getNode(), me.outerProxy.getNode() ) ) ); + } + } + catch (GridAccessException e) + { + e.printStackTrace(); + } + } + } }