From d76ce22db76bf0730e88d3945882ecf22d65a22f Mon Sep 17 00:00:00 2001 From: SquidDev Date: Thu, 18 May 2017 23:50:14 +0100 Subject: [PATCH] Split transmit into two separate methods This removes the interdimensional and range options from the packet and ensures they are provides them from the transmit* methods instead. --- .../api/network/IPacketNetwork.java | 16 +++++-- .../api/network/IPacketReceiver.java | 11 +++-- .../computercraft/api/network/Packet.java | 40 ++---------------- .../peripheral/modem/ModemPeripheral.java | 10 ++++- .../shared/peripheral/modem/TileCable.java | 42 +++++++++++++++---- .../peripheral/modem/WirelessNetwork.java | 22 +++++++--- 6 files changed, 81 insertions(+), 60 deletions(-) diff --git a/src/main/java/dan200/computercraft/api/network/IPacketNetwork.java b/src/main/java/dan200/computercraft/api/network/IPacketNetwork.java index 2354e7441..4b07e0ee7 100644 --- a/src/main/java/dan200/computercraft/api/network/IPacketNetwork.java +++ b/src/main/java/dan200/computercraft/api/network/IPacketNetwork.java @@ -38,11 +38,21 @@ public interface IPacketNetwork /** * Submit a packet for transmitting across the network. This will route the packet through the network, sending it - * to all reachable receivers. + * to all receivers within range (or any interdimensional ones). * * @param packet The packet to send. - * @see IPacketReceiver#receiveDifferentDimension(Packet) + * @see #transmitInterdimensional(Packet) * @see IPacketReceiver#receiveSameDimension(Packet, double) */ - void transmit( @Nonnull Packet packet ); + void transmitSameDimension( @Nonnull Packet packet, double range ); + + /** + * Submit a packet for transmitting across the network. This will route the packet through the network, sending it + * to all receivers across all dimensions. + * + * @param packet The packet to send. + * @see #transmitSameDimension(Packet, double) + * @see IPacketReceiver#receiveDifferentDimension(Packet) + */ + void transmitInterdimensional( @Nonnull Packet packet ); } diff --git a/src/main/java/dan200/computercraft/api/network/IPacketReceiver.java b/src/main/java/dan200/computercraft/api/network/IPacketReceiver.java index 2e5c87820..58a0b7e2f 100644 --- a/src/main/java/dan200/computercraft/api/network/IPacketReceiver.java +++ b/src/main/java/dan200/computercraft/api/network/IPacketReceiver.java @@ -41,7 +41,7 @@ public interface IPacketReceiver * @return The maximum distance this device can send and receive messages. * @see #isInterdimensional() * @see #receiveSameDimension(Packet packet, double) - * @see Packet#getRange() + * @see IPacketNetwork#transmitInterdimensional(Packet) */ double getRange(); @@ -53,7 +53,7 @@ public interface IPacketReceiver * @return Whether this receiver receives packets from other dimensions. * @see #getRange() * @see #receiveDifferentDimension(Packet) - * @see Packet#isInterdimensional() + * @see IPacketNetwork#transmitInterdimensional(Packet) */ boolean isInterdimensional(); @@ -64,7 +64,9 @@ public interface IPacketReceiver * if so, queue the appropriate modem event. * @param distance The distance this packet has travelled from the source. * @see Packet - * @see IPacketNetwork#transmit(Packet) + * @see #getRange() + * @see IPacketNetwork#transmitSameDimension(Packet, double) + * @see IPacketNetwork#transmitInterdimensional(Packet) */ void receiveSameDimension( @Nonnull Packet packet, double distance ); @@ -74,7 +76,8 @@ public interface IPacketReceiver * @param packet The packet to receive. Generally you should check that you are listening on the given channel and, * if so, queue the appropriate modem event. * @see Packet - * @see IPacketNetwork#transmit(Packet) + * @see IPacketNetwork#transmitInterdimensional(Packet) + * @see IPacketNetwork#transmitSameDimension(Packet, double) * @see #isInterdimensional() */ void receiveDifferentDimension( @Nonnull Packet packet ); diff --git a/src/main/java/dan200/computercraft/api/network/Packet.java b/src/main/java/dan200/computercraft/api/network/Packet.java index c83d90e7b..070ce5a01 100644 --- a/src/main/java/dan200/computercraft/api/network/Packet.java +++ b/src/main/java/dan200/computercraft/api/network/Packet.java @@ -14,7 +14,8 @@ import javax.annotation.Nullable; * Represents a packet which may be sent across a {@link IPacketNetwork}. * * @see IPacketSender - * @see IPacketNetwork#transmit(Packet) + * @see IPacketNetwork#transmitSameDimension(Packet, double) + * @see IPacketNetwork#transmitInterdimensional(Packet) * @see IPacketReceiver#receiveDifferentDimension(Packet) * @see IPacketReceiver#receiveSameDimension(Packet, double) */ @@ -24,8 +25,6 @@ public class Packet private final int m_replyChannel; private final Object m_payload; - private final double m_range; - private final boolean m_interdimensional; private final IPacketSender m_sender; /** @@ -38,15 +37,13 @@ public class Packet * event or returning from a peripheral call. * @param sender The object which sent this packet. */ - public Packet( int channel, int replyChannel, @Nullable Object payload, double range, boolean interdimensional, @Nonnull IPacketSender sender ) + public Packet( int channel, int replyChannel, @Nullable Object payload, @Nonnull IPacketSender sender ) { Preconditions.checkNotNull( sender, "sender cannot be null" ); m_channel = channel; m_replyChannel = replyChannel; m_payload = payload; - m_range = range; - m_interdimensional = interdimensional; m_sender = sender; } @@ -83,32 +80,6 @@ public class Packet return m_payload; } - /** - * Get the minimum distance this packet will travel. - * - * Packets may still travel further if there is a more sensitive receiver available. - * - * @return The distance this packet will travel. - * @see IPacketReceiver#getRange() - */ - public double getRange() - { - return m_range; - } - - /** - * Whether this packet will travel across dimensions. - * - * Packets may still be received if there is a more sensitive receiver available. - * - * @return If this packet will travel across dimensions. - * @see IPacketReceiver#isInterdimensional() - */ - public boolean isInterdimensional() - { - return m_interdimensional; - } - /** * The object which sent this message. * @@ -130,8 +101,6 @@ public class Packet if( m_channel != packet.m_channel ) return false; if( m_replyChannel != packet.m_replyChannel ) return false; - if( Double.compare( packet.m_range, m_range ) != 0 ) return false; - if( m_interdimensional != packet.m_interdimensional ) return false; if( m_payload != null ? !m_payload.equals( packet.m_payload ) : packet.m_payload != null ) return false; return m_sender.equals( packet.m_sender ); } @@ -143,9 +112,6 @@ public class Packet result = m_channel; result = 31 * result + m_replyChannel; result = 31 * result + (m_payload != null ? m_payload.hashCode() : 0); - long temp = Double.doubleToLongBits( m_range ); - result = 31 * result + (int) (temp ^ (temp >>> 32)); - result = 31 * result + (m_interdimensional ? 1 : 0); result = 31 * result + m_sender.hashCode(); return result; } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/modem/ModemPeripheral.java b/src/main/java/dan200/computercraft/shared/peripheral/modem/ModemPeripheral.java index d327a6ca3..c5daff739 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/modem/ModemPeripheral.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/modem/ModemPeripheral.java @@ -244,7 +244,15 @@ public abstract class ModemPeripheral Vec3d position = getPosition(); if( world != null && position != null && m_network != null) { - m_network.transmit( new Packet( channel, replyChannel, payload, getRange(), isInterdimensional(), this ) ); + Packet packet = new Packet( channel, replyChannel, payload, this ); + if( isInterdimensional() ) + { + m_network.transmitInterdimensional( packet ); + } + else + { + m_network.transmitSameDimension( packet, getRange() ); + } } } return null; diff --git a/src/main/java/dan200/computercraft/shared/peripheral/modem/TileCable.java b/src/main/java/dan200/computercraft/shared/peripheral/modem/TileCable.java index 269db26a2..fc8502378 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/modem/TileCable.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/modem/TileCable.java @@ -239,7 +239,7 @@ public class TileCable extends TileModemBase // Members private final Set m_receivers; - private final Queue m_transmitQueue; + private final Queue m_transmitQueue; private boolean m_peripheralAccessAllowed; private int m_attachedPeripheralID; @@ -254,7 +254,7 @@ public class TileCable extends TileModemBase public TileCable() { m_receivers = new HashSet(); - m_transmitQueue = new LinkedList(); + m_transmitQueue = new LinkedList(); m_peripheralAccessAllowed = false; m_attachedPeripheralID = -1; @@ -569,7 +569,7 @@ public class TileCable extends TileModemBase { while( m_transmitQueue.peek() != null ) { - Packet p = m_transmitQueue.remove(); + PacketWrapper p = m_transmitQueue.remove(); if( p != null ) { dispatchPacket( p ); @@ -598,16 +598,25 @@ public class TileCable extends TileModemBase m_receivers.remove( receiver ); } } - + @Override - public void transmit( @Nonnull Packet packet ) + public void transmitSameDimension( @Nonnull Packet packet, double range ) { synchronized( m_transmitQueue ) { - m_transmitQueue.offer( packet ); + m_transmitQueue.offer( new PacketWrapper( packet, range ) ); } } - + + @Override + public void transmitInterdimensional( @Nonnull Packet packet ) + { + synchronized( m_transmitQueue ) + { + m_transmitQueue.offer( new PacketWrapper( packet, Double.MAX_VALUE ) ); + } + } + @Override public boolean isWireless() { @@ -714,13 +723,28 @@ public class TileCable extends TileModemBase // private stuff // Packet sending + + private static class PacketWrapper + { + final Packet m_packet; + final double m_range; + + private PacketWrapper( Packet m_packet, double m_range ) + { + this.m_packet = m_packet; + this.m_range = m_range; + } + } - private void dispatchPacket( final Packet packet ) + private void dispatchPacket( final PacketWrapper packet ) { searchNetwork( new ICableVisitor() { public void visit( TileCable modem, int distance ) { - modem.receivePacket( packet, distance ); + if( distance <= packet.m_range) + { + modem.receivePacket( packet.m_packet, distance ); + } } } ); } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/modem/WirelessNetwork.java b/src/main/java/dan200/computercraft/shared/peripheral/modem/WirelessNetwork.java index 60fe6c98a..6c859007c 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/modem/WirelessNetwork.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/modem/WirelessNetwork.java @@ -56,30 +56,40 @@ public class WirelessNetwork implements IPacketNetwork } @Override - public synchronized void transmit( @Nonnull Packet packet ) + public synchronized void transmitSameDimension( @Nonnull Packet packet, double range ) + { + Preconditions.checkNotNull( packet, "packet cannot be null" ); + for( IPacketReceiver device : m_receivers ) + { + tryTransmit( device, packet, range, false ); + } + } + + @Override + public synchronized void transmitInterdimensional( @Nonnull Packet packet ) { Preconditions.checkNotNull( packet, "packet cannot be null" ); for (IPacketReceiver device : m_receivers) { - tryTransmit( device, packet ); + tryTransmit( device, packet, 0, true ); } } - private void tryTransmit( IPacketReceiver receiver, Packet packet ) + private void tryTransmit( IPacketReceiver receiver, Packet packet, double range, boolean interdimensional ) { IPacketSender sender = packet.getSender(); if( receiver.getWorld() == sender.getWorld() ) { - double receiveRange = Math.max( packet.getRange(), receiver.getRange() ); // Ensure range is symmetrical + double receiveRange = Math.max( range, receiver.getRange() ); // Ensure range is symmetrical double distanceSq = receiver.getPosition().squareDistanceTo( sender.getPosition() ); - if( packet.isInterdimensional() || receiver.isInterdimensional() || distanceSq <= (receiveRange * receiveRange) ) + if( interdimensional || receiver.isInterdimensional() || distanceSq <= (receiveRange * receiveRange) ) { receiver.receiveSameDimension( packet, Math.sqrt( distanceSq ) ); } } else { - if( packet.isInterdimensional() || receiver.isInterdimensional() ) + if( interdimensional || receiver.isInterdimensional() ) { receiver.receiveDifferentDimension( packet ); }