2014-11-14 12:02:52 +01:00
/ *
* This file is part of Applied Energistics 2 .
* Copyright ( c ) 2013 - 2014 , 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 < http : //www.gnu.org/licenses/lgpl>.
* /
2014-09-24 02:26:27 +02:00
package appeng.me ;
2014-11-30 04:58:08 +01:00
2014-09-24 02:26:27 +02:00
import java.util.Arrays ;
import java.util.EnumSet ;
import appeng.api.exceptions.FailedConnection ;
import appeng.api.networking.GridFlags ;
import appeng.api.networking.IGridConnection ;
import appeng.api.networking.IGridNode ;
import appeng.api.networking.events.MENetworkChannelsChanged ;
import appeng.api.networking.pathing.IPathingGrid ;
2015-06-16 02:44:59 +02:00
import appeng.api.util.AEPartLocation ;
2015-02-28 17:20:33 +01:00
import appeng.api.util.DimensionalCoord ;
2014-09-24 02:26:27 +02:00
import appeng.api.util.IReadOnlyCollection ;
import appeng.core.AEConfig ;
import appeng.core.AELog ;
import appeng.core.features.AEFeature ;
import appeng.me.pathfinding.IPathItem ;
import appeng.util.Platform ;
import appeng.util.ReadOnlyCollection ;
2015-02-28 17:20:33 +01:00
2014-09-24 02:26:27 +02:00
public class GridConnection implements IGridConnection , IPathItem
{
2015-01-01 22:13:10 +01:00
private static final MENetworkChannelsChanged EVENT = new MENetworkChannelsChanged ( ) ;
2015-04-03 08:54:31 +02:00
public int channelData = 0 ;
Object visitorIterationNumber = null ;
2014-09-24 02:26:27 +02:00
private GridNode sideA ;
2015-06-16 02:44:59 +02:00
private AEPartLocation fromAtoB ;
2014-09-24 02:26:27 +02:00
private GridNode sideB ;
2015-09-30 14:24:40 +02:00
public GridConnection ( final IGridNode aNode , final IGridNode bNode , final AEPartLocation fromAtoB ) throws FailedConnection
2015-02-28 17:20:33 +01:00
{
2014-09-24 02:26:27 +02:00
2015-09-30 14:24:40 +02:00
final GridNode a = ( GridNode ) aNode ;
final GridNode b = ( GridNode ) bNode ;
2014-09-24 02:26:27 +02:00
2015-04-03 08:54:31 +02:00
if ( Platform . securityCheck ( a , b ) )
2014-09-24 02:26:27 +02:00
{
2015-04-03 08:54:31 +02:00
if ( AEConfig . instance . isFeatureEnabled ( AEFeature . LogSecurityAudits ) )
2014-09-24 02:26:27 +02:00
{
2015-02-28 17:20:33 +01:00
final DimensionalCoord aCoordinates = a . getGridBlock ( ) . getLocation ( ) ;
final DimensionalCoord bCoordinates = b . getGridBlock ( ) . getLocation ( ) ;
2015-03-05 14:52:00 +01:00
AELog . info ( " Security audit 1 failed at [%s] belonging to player [id=%d] " , aCoordinates . toString ( ) , a . playerID ) ;
AELog . info ( " Security audit 2 failed at [%s] belonging to player [id=%d] " , bCoordinates . toString ( ) , b . playerID ) ;
2014-09-24 02:26:27 +02:00
}
throw new FailedConnection ( ) ;
}
2015-04-03 08:54:31 +02:00
if ( a = = null | | b = = null )
2015-04-29 02:30:53 +02:00
{
2014-09-24 02:26:27 +02:00
throw new GridException ( " Connection Forged Between null entities. " ) ;
2015-04-29 02:30:53 +02:00
}
2014-09-24 02:26:27 +02:00
2015-04-03 08:54:31 +02:00
if ( a . hasConnection ( b ) | | b . hasConnection ( a ) )
2015-03-22 01:59:15 +01:00
{
2015-11-30 12:55:47 +01:00
final String aMachineClass = a . getGridBlock ( ) . getMachine ( ) . getClass ( ) . getSimpleName ( ) ;
final String bMachineClass = b . getGridBlock ( ) . getMachine ( ) . getClass ( ) . getSimpleName ( ) ;
final String aCoordinates = a . getGridBlock ( ) . getLocation ( ) . toString ( ) ;
final String bCoordinates = b . getGridBlock ( ) . getLocation ( ) . toString ( ) ;
2014-09-24 02:26:27 +02:00
2015-11-30 12:55:47 +01:00
throw new GridException ( String . format ( " Connection between node [machine=%s, %s] and [machine=%s, %s] on [%s] already exists. " , aMachineClass , aCoordinates , bMachineClass , bCoordinates , fromAtoB ) ) ;
2015-03-22 01:59:15 +01:00
}
2015-11-30 12:55:47 +01:00
2014-12-29 15:13:47 +01:00
this . sideA = a ;
2014-09-24 02:26:27 +02:00
this . fromAtoB = fromAtoB ;
2014-12-29 15:13:47 +01:00
this . sideB = b ;
2014-09-24 02:26:27 +02:00
2015-04-03 08:54:31 +02:00
if ( b . getMyGrid ( ) = = null )
2014-09-24 02:26:27 +02:00
{
b . setGrid ( a . getInternalGrid ( ) ) ;
}
else
{
2015-04-03 08:54:31 +02:00
if ( a . getMyGrid ( ) = = null )
2014-09-24 02:26:27 +02:00
{
2015-09-30 14:24:40 +02:00
final GridPropagator gp = new GridPropagator ( b . getInternalGrid ( ) ) ;
2014-09-24 02:26:27 +02:00
a . beginVisit ( gp ) ;
}
2015-04-03 08:54:31 +02:00
else if ( b . getMyGrid ( ) = = null )
2014-09-24 02:26:27 +02:00
{
2015-09-30 14:24:40 +02:00
final GridPropagator gp = new GridPropagator ( a . getInternalGrid ( ) ) ;
2014-09-24 02:26:27 +02:00
b . beginVisit ( gp ) ;
}
2015-04-03 08:54:31 +02:00
else if ( this . isNetworkABetter ( a , b ) )
2014-09-24 02:26:27 +02:00
{
2015-09-30 14:24:40 +02:00
final GridPropagator gp = new GridPropagator ( a . getInternalGrid ( ) ) ;
2014-09-24 02:26:27 +02:00
b . beginVisit ( gp ) ;
}
else
{
2015-09-30 14:24:40 +02:00
final GridPropagator gp = new GridPropagator ( b . getInternalGrid ( ) ) ;
2014-09-24 02:26:27 +02:00
a . beginVisit ( gp ) ;
}
}
// a connection was destroyed RE-PATH!!
2015-09-30 14:24:40 +02:00
final IPathingGrid p = this . sideA . getInternalGrid ( ) . getCache ( IPathingGrid . class ) ;
2014-09-24 02:26:27 +02:00
p . repath ( ) ;
2014-12-29 15:13:47 +01:00
this . sideA . addConnection ( this ) ;
this . sideB . addConnection ( this ) ;
2014-09-24 02:26:27 +02:00
}
2015-09-30 14:24:40 +02:00
private boolean isNetworkABetter ( final GridNode a , final GridNode b )
2014-09-24 02:26:27 +02:00
{
2014-11-30 04:58:08 +01:00
return a . getMyGrid ( ) . getPriority ( ) > b . getMyGrid ( ) . getPriority ( ) | | a . getMyGrid ( ) . size ( ) > b . getMyGrid ( ) . size ( ) ;
2014-09-24 02:26:27 +02:00
}
2015-04-03 08:54:31 +02:00
@Override
2015-09-30 14:24:40 +02:00
public IGridNode getOtherSide ( final IGridNode gridNode )
2015-04-03 08:54:31 +02:00
{
if ( gridNode = = this . sideA )
2015-04-29 02:30:53 +02:00
{
2015-04-03 08:54:31 +02:00
return this . sideB ;
2015-04-29 02:30:53 +02:00
}
2015-04-03 08:54:31 +02:00
if ( gridNode = = this . sideB )
2015-04-29 02:30:53 +02:00
{
2015-04-03 08:54:31 +02:00
return this . sideA ;
2015-04-29 02:30:53 +02:00
}
2015-04-03 08:54:31 +02:00
throw new GridException ( " Invalid Side of Connection " ) ;
}
@Override
2015-09-30 14:24:40 +02:00
public AEPartLocation getDirection ( final IGridNode side )
2015-04-03 08:54:31 +02:00
{
2015-06-16 02:44:59 +02:00
if ( this . fromAtoB = = AEPartLocation . INTERNAL )
2015-04-29 02:30:53 +02:00
{
2015-04-03 08:54:31 +02:00
return this . fromAtoB ;
2015-04-29 02:30:53 +02:00
}
2015-04-03 08:54:31 +02:00
if ( this . sideA = = side )
2015-04-29 02:30:53 +02:00
{
2015-04-03 08:54:31 +02:00
return this . fromAtoB ;
2015-04-29 02:30:53 +02:00
}
2015-04-03 08:54:31 +02:00
else
2015-04-29 02:30:53 +02:00
{
2015-04-03 08:54:31 +02:00
return this . fromAtoB . getOpposite ( ) ;
2015-04-29 02:30:53 +02:00
}
2015-04-03 08:54:31 +02:00
}
2014-09-24 02:26:27 +02:00
@Override
public void destroy ( )
{
// a connection was destroyed RE-PATH!!
2015-09-30 14:24:40 +02:00
final IPathingGrid p = this . sideA . getInternalGrid ( ) . getCache ( IPathingGrid . class ) ;
2014-09-24 02:26:27 +02:00
p . repath ( ) ;
2014-12-29 15:13:47 +01:00
this . sideA . removeConnection ( this ) ;
this . sideB . removeConnection ( this ) ;
2014-09-24 02:26:27 +02:00
2014-12-29 15:13:47 +01:00
this . sideA . validateGrid ( ) ;
this . sideB . validateGrid ( ) ;
2014-09-24 02:26:27 +02:00
}
@Override
public IGridNode a ( )
{
2014-12-29 15:13:47 +01:00
return this . sideA ;
2014-09-24 02:26:27 +02:00
}
@Override
public IGridNode b ( )
{
2014-12-29 15:13:47 +01:00
return this . sideB ;
2014-09-24 02:26:27 +02:00
}
@Override
2015-04-03 08:54:31 +02:00
public boolean hasDirection ( )
2014-09-24 02:26:27 +02:00
{
2015-06-16 02:44:59 +02:00
return this . fromAtoB ! = AEPartLocation . INTERNAL ;
2014-09-24 02:26:27 +02:00
}
@Override
2015-04-03 08:54:31 +02:00
public int getUsedChannels ( )
2014-09-24 02:26:27 +02:00
{
2015-04-03 08:54:31 +02:00
return ( this . channelData > > 8 ) & 0xff ;
2014-09-24 02:26:27 +02:00
}
@Override
2015-04-03 08:54:31 +02:00
public IPathItem getControllerRoute ( )
2014-09-24 02:26:27 +02:00
{
2015-04-03 08:54:31 +02:00
if ( this . sideA . getFlags ( ) . contains ( GridFlags . CANNOT_CARRY ) )
2015-04-29 02:30:53 +02:00
{
2015-04-03 08:54:31 +02:00
return null ;
2015-04-29 02:30:53 +02:00
}
2015-04-03 08:54:31 +02:00
return this . sideA ;
2014-09-24 02:26:27 +02:00
}
@Override
2015-09-30 14:24:40 +02:00
public void setControllerRoute ( final IPathItem fast , final boolean zeroOut )
2014-09-24 02:26:27 +02:00
{
2015-04-03 08:54:31 +02:00
if ( zeroOut )
2015-04-29 02:30:53 +02:00
{
2015-04-03 08:54:31 +02:00
this . channelData & = ~ 0xff ;
2015-04-29 02:30:53 +02:00
}
2015-04-03 08:54:31 +02:00
if ( this . sideB = = fast )
{
2015-09-30 14:24:40 +02:00
final GridNode tmp = this . sideA ;
2015-04-03 08:54:31 +02:00
this . sideA = this . sideB ;
this . sideB = tmp ;
this . fromAtoB = this . fromAtoB . getOpposite ( ) ;
}
2014-09-24 02:26:27 +02:00
}
@Override
public boolean canSupportMoreChannels ( )
{
2014-12-29 15:13:47 +01:00
return this . getLastUsedChannels ( ) < 32 ; // max, PERIOD.
2014-09-24 02:26:27 +02:00
}
@Override
2015-04-03 08:54:31 +02:00
public IReadOnlyCollection < IPathItem > getPossibleOptions ( )
2014-09-24 02:26:27 +02:00
{
2015-04-03 08:54:31 +02:00
return new ReadOnlyCollection < IPathItem > ( Arrays . asList ( ( IPathItem ) this . a ( ) , ( IPathItem ) this . b ( ) ) ) ;
2014-09-24 02:26:27 +02:00
}
@Override
2015-09-30 14:24:40 +02:00
public void incrementChannelCount ( final int usedChannels )
2014-09-24 02:26:27 +02:00
{
2015-04-03 08:54:31 +02:00
this . channelData + = usedChannels ;
2014-09-24 02:26:27 +02:00
}
@Override
2015-04-03 08:54:31 +02:00
public EnumSet < GridFlags > getFlags ( )
2014-09-24 02:26:27 +02:00
{
2015-04-03 08:54:31 +02:00
return EnumSet . noneOf ( GridFlags . class ) ;
2014-09-24 02:26:27 +02:00
}
@Override
public void finalizeChannels ( )
{
2015-04-03 08:54:31 +02:00
if ( this . getUsedChannels ( ) ! = this . getLastUsedChannels ( ) )
2014-09-24 02:26:27 +02:00
{
2015-03-26 10:41:45 +01:00
this . channelData & = 0xff ;
2014-12-29 15:13:47 +01:00
this . channelData | = this . channelData < < 8 ;
2014-09-24 02:26:27 +02:00
2015-04-03 08:54:31 +02:00
if ( this . sideA . getInternalGrid ( ) ! = null )
2015-04-29 02:30:53 +02:00
{
2015-01-01 22:13:10 +01:00
this . sideA . getInternalGrid ( ) . postEventTo ( this . sideA , EVENT ) ;
2015-04-29 02:30:53 +02:00
}
2014-09-24 02:26:27 +02:00
2015-04-03 08:54:31 +02:00
if ( this . sideB . getInternalGrid ( ) ! = null )
2015-04-29 02:30:53 +02:00
{
2015-01-01 22:13:10 +01:00
this . sideB . getInternalGrid ( ) . postEventTo ( this . sideB , EVENT ) ;
2015-04-29 02:30:53 +02:00
}
2014-09-24 02:26:27 +02:00
}
}
2015-04-03 08:54:31 +02:00
public int getLastUsedChannels ( )
2014-09-24 02:26:27 +02:00
{
2015-04-03 08:54:31 +02:00
return this . channelData & 0xff ;
2014-09-24 02:26:27 +02:00
}
}