1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-11-08 01:12:59 +00:00
Files
CC-Tweaked/remappedSrc/dan200/computercraft/shared/wired/WiredNode.java
2021-07-11 01:33:21 +00:00

169 lines
4.6 KiB
Java

/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.shared.wired;
import dan200.computercraft.api.network.IPacketReceiver;
import dan200.computercraft.api.network.Packet;
import dan200.computercraft.api.network.wired.IWiredElement;
import dan200.computercraft.api.network.wired.IWiredNetwork;
import dan200.computercraft.api.network.wired.IWiredNode;
import dan200.computercraft.api.network.wired.IWiredSender;
import dan200.computercraft.api.peripheral.IPeripheral;
import javax.annotation.Nonnull;
import java.util.*;
import java.util.concurrent.locks.Lock;
public final class WiredNode implements IWiredNode
{
final IWiredElement element;
final HashSet<WiredNode> neighbours = new HashSet<>();
Map<String, IPeripheral> peripherals = Collections.emptyMap();
volatile WiredNetwork network;
private Set<IPacketReceiver> receivers;
public WiredNode( IWiredElement element )
{
this.element = element;
network = new WiredNetwork( this );
}
@Override
public synchronized void addReceiver( @Nonnull IPacketReceiver receiver )
{
if( receivers == null )
{
receivers = new HashSet<>();
}
receivers.add( receiver );
}
@Override
public synchronized void removeReceiver( @Nonnull IPacketReceiver receiver )
{
if( receivers != null )
{
receivers.remove( receiver );
}
}
@Override
public boolean isWireless()
{
return false;
}
@Override
public void transmitSameDimension( @Nonnull Packet packet, double range )
{
Objects.requireNonNull( packet, "packet cannot be null" );
if( !(packet.getSender() instanceof IWiredSender) || ((IWiredSender) packet.getSender()).getNode() != this )
{
throw new IllegalArgumentException( "Sender is not in the network" );
}
acquireReadLock();
try
{
WiredNetwork.transmitPacket( this, packet, range, false );
}
finally
{
network.lock.readLock()
.unlock();
}
}
@Override
public void transmitInterdimensional( @Nonnull Packet packet )
{
Objects.requireNonNull( packet, "packet cannot be null" );
if( !(packet.getSender() instanceof IWiredSender) || ((IWiredSender) packet.getSender()).getNode() != this )
{
throw new IllegalArgumentException( "Sender is not in the network" );
}
acquireReadLock();
try
{
WiredNetwork.transmitPacket( this, packet, 0, true );
}
finally
{
network.lock.readLock()
.unlock();
}
}
private void acquireReadLock()
{
WiredNetwork currentNetwork = network;
while( true )
{
Lock lock = currentNetwork.lock.readLock();
lock.lock();
if( currentNetwork == network )
{
return;
}
lock.unlock();
}
}
synchronized void tryTransmit( Packet packet, double packetDistance, boolean packetInterdimensional, double range, boolean interdimensional )
{
if( receivers == null )
{
return;
}
for( IPacketReceiver receiver : receivers )
{
if( !packetInterdimensional )
{
double receiveRange = Math.max( range, receiver.getRange() ); // Ensure range is symmetrical
if( interdimensional || receiver.isInterdimensional() || packetDistance < receiveRange )
{
receiver.receiveSameDimension( packet,
packetDistance + element.getPosition()
.distanceTo( receiver.getPosition() ) );
}
}
else
{
if( interdimensional || receiver.isInterdimensional() )
{
receiver.receiveDifferentDimension( packet );
}
}
}
}
@Nonnull
@Override
public IWiredElement getElement()
{
return element;
}
@Nonnull
@Override
public IWiredNetwork getNetwork()
{
return network;
}
@Override
public String toString()
{
return "WiredNode{@" + element.getPosition() + " (" + element.getClass()
.getSimpleName() + ")}";
}
}