From 62cf921cc68b776f588370edc6d2d06b476575c0 Mon Sep 17 00:00:00 2001 From: SquidDev Date: Sat, 17 Nov 2018 11:52:12 +0000 Subject: [PATCH] Allow modems to handle being attached to multiple computers - Introduce a ModemState, which shares the open channels across all modem instances of a wired modem. - Keep a set of computers for all modem peripherals. - Keep a map of computers -> (string, peripheral) for wired modem peripherals. We shouldn't need this one, as you cannot attach one modem to another, but it's good to be consistent. One major change here is that modems will continue to be "on", even if no computers are attached. This would substantially increase implementation complexity, so I think this is an acceptable compromise for now. Should fix #74 --- .../peripheral/modem/ModemPeripheral.java | 196 +++++------------- .../shared/peripheral/modem/ModemState.java | 77 +++++++ .../peripheral/modem/TileAdvancedModem.java | 2 +- .../shared/peripheral/modem/TileCable.java | 14 +- .../peripheral/modem/TileModemBase.java | 29 +-- .../peripheral/modem/TileWiredModemFull.java | 25 +-- .../peripheral/modem/TileWirelessModem.java | 2 +- .../modem/WiredModemPeripheral.java | 148 ++++++------- .../modem/WirelessModemPeripheral.java | 3 +- .../pocket/peripherals/PocketModem.java | 4 +- .../peripherals/PocketModemPeripheral.java | 3 +- .../shared/turtle/upgrades/TurtleModem.java | 13 +- 12 files changed, 224 insertions(+), 292 deletions(-) create mode 100644 src/main/java/dan200/computercraft/shared/peripheral/modem/ModemState.java 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 554c20942..cd42792ba 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/modem/ModemPeripheral.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/modem/ModemPeripheral.java @@ -14,53 +14,43 @@ import dan200.computercraft.api.network.IPacketSender; import dan200.computercraft.api.network.Packet; import dan200.computercraft.api.peripheral.IComputerAccess; import dan200.computercraft.api.peripheral.IPeripheral; -import gnu.trove.set.TIntSet; -import gnu.trove.set.hash.TIntHashSet; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; import javax.annotation.Nonnull; +import java.util.HashSet; +import java.util.Set; import static dan200.computercraft.core.apis.ArgumentHelper.getInt; -public abstract class ModemPeripheral - implements IPeripheral, IPacketSender, IPacketReceiver +public abstract class ModemPeripheral implements IPeripheral, IPacketSender, IPacketReceiver { private IPacketNetwork m_network; - private IComputerAccess m_computer; - private final TIntSet m_channels; + private Set m_computers = new HashSet<>( 1 ); + private final ModemState m_state; - private boolean m_open; - private boolean m_changed; - - public ModemPeripheral() + protected ModemPeripheral( ModemState state ) { - m_network = null; - m_computer = null; - m_channels = new TIntHashSet(); - m_open = false; - m_changed = true; + this.m_state = state; + } + + public ModemState getModemState() + { + return m_state; } private synchronized void setNetwork( IPacketNetwork network ) { - if( m_network != network ) - { - // Leave old network - if( m_network != null ) - { - m_network.removeReceiver( this ); - } + if( m_network == network ) return; - // Set new network - m_network = network; + // Leave old network + if( m_network != null ) m_network.removeReceiver( this ); - // Join new network - if( m_network != null ) - { - m_network.addReceiver( this ); - } - } + // Set new network + m_network = network; + + // Join new network + if( m_network != null ) m_network.addReceiver( this ); } protected void switchNetwork() @@ -71,36 +61,19 @@ public abstract class ModemPeripheral public synchronized void destroy() { setNetwork( null ); - m_channels.clear(); - m_open = false; - } - - public boolean pollChanged() - { - if( m_changed ) - { - m_changed = false; - return true; - } - return false; - } - - public boolean isActive() - { - return m_computer != null && m_open; } @Override public void receiveSameDimension( @Nonnull Packet packet, double distance ) { - if( packet.getSender() == this ) return; + if( packet.getSender() == this || !m_state.isOpen( packet.getChannel() ) ) return; - synchronized (m_channels) + synchronized( this ) { - if( m_computer != null && m_channels.contains( packet.getChannel() ) ) + for( IComputerAccess computer : m_computers ) { - m_computer.queueEvent( "modem_message", new Object[] { - m_computer.getAttachmentName(), packet.getChannel(), packet.getReplyChannel(), packet.getPayload(), distance + computer.queueEvent( "modem_message", new Object[]{ + computer.getAttachmentName(), packet.getChannel(), packet.getReplyChannel(), packet.getPayload(), distance } ); } } @@ -109,21 +82,21 @@ public abstract class ModemPeripheral @Override public void receiveDifferentDimension( @Nonnull Packet packet ) { - if( packet.getSender() == this ) return; + if( packet.getSender() == this || !m_state.isOpen( packet.getChannel() ) ) return; - synchronized (m_channels) + synchronized( this ) { - if( m_computer != null && m_channels.contains( packet.getChannel() ) ) + for( IComputerAccess computer : m_computers ) { - m_computer.queueEvent( "modem_message", new Object[] { - m_computer.getAttachmentName(), packet.getChannel(), packet.getReplyChannel(), packet.getPayload() + computer.queueEvent( "modem_message", new Object[]{ + computer.getAttachmentName(), packet.getChannel(), packet.getReplyChannel(), packet.getPayload() } ); } } } protected abstract IPacketNetwork getNetwork(); - + // IPeripheral implementation @Nonnull @@ -132,12 +105,12 @@ public abstract class ModemPeripheral { return "modem"; } - + @Nonnull @Override public String[] getMethodNames() { - return new String[] { + return new String[]{ "open", "isOpen", "close", @@ -146,7 +119,7 @@ public abstract class ModemPeripheral "isWireless", }; } - + private static int parseChannel( Object[] arguments, int index ) throws LuaException { int channel = getInt( arguments, index ); @@ -156,7 +129,7 @@ public abstract class ModemPeripheral } return channel; } - + @Override public Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaContext context, int method, @Nonnull Object[] arguments ) throws LuaException, InterruptedException { @@ -166,68 +139,26 @@ public abstract class ModemPeripheral { // open int channel = parseChannel( arguments, 0 ); - synchronized( this ) - { - if( !m_channels.contains( channel ) ) - { - if( m_channels.size() >= 128 ) - { - throw new LuaException( "Too many open channels" ); - } - - m_channels.add( channel ); - if( !m_open ) - { - m_open = true; - m_changed = true; - } - } - } + m_state.open( channel ); return null; } case 1: { // isOpen int channel = parseChannel( arguments, 0 ); - synchronized( this ) - { - boolean open = m_channels.contains( channel ); - return new Object[] { open }; - } + return new Object[]{ m_state.isOpen( channel ) }; } case 2: { // close int channel = parseChannel( arguments, 0 ); - synchronized( this ) - { - if( m_channels.remove( channel ) ) - { - if( m_channels.size() == 0 ) - { - m_open = false; - m_changed = true; - } - } - } + m_state.close( channel ); return null; } case 3: { // closeAll - synchronized( this ) - { - if( m_channels.size() > 0 ) - { - m_channels.clear(); - - if( m_open ) - { - m_open = false; - m_changed = true; - } - } - } + m_state.closeAll(); return null; } case 4: @@ -235,12 +166,12 @@ public abstract class ModemPeripheral // transmit int channel = parseChannel( arguments, 0 ); int replyChannel = parseChannel( arguments, 1 ); - Object payload = (arguments.length >= 3) ? arguments[2] : null; + Object payload = arguments.length > 2 ? arguments[2] : null; synchronized( this ) { World world = getWorld(); Vec3d position = getPosition(); - if( world != null && position != null && m_network != null) + if( world != null && position != null && m_network != null ) { Packet packet = new Packet( channel, replyChannel, payload, this ); if( isInterdimensional() ) @@ -258,14 +189,8 @@ public abstract class ModemPeripheral case 5: { // isWireless - synchronized( this ) - { - if( m_network != null ) - { - return new Object[] { m_network.isWireless() }; - } - } - return new Object[] { false }; + IPacketNetwork network = m_network; + return new Object[]{ network != null && network.isWireless() }; } default: { @@ -273,50 +198,33 @@ public abstract class ModemPeripheral } } } - + @Override public synchronized void attach( @Nonnull IComputerAccess computer ) { - m_computer = computer; + m_computers.add( computer ); setNetwork( getNetwork() ); - m_open = !m_channels.isEmpty(); } - + @Override public synchronized void detach( @Nonnull IComputerAccess computer ) { - if( m_network != null ) - { - m_network.removeReceiver( this ); - m_channels.clear(); - m_network = null; - } - - m_computer = null; - - if( m_open ) - { - m_open = false; - m_changed = true; - } - } - - public IComputerAccess getComputer() - { - return m_computer; + m_computers.remove( computer ); + if( m_computers.isEmpty() ) setNetwork( null ); } @Nonnull @Override - public String getSenderID() + public synchronized String getSenderID() { - if( m_computer == null ) + if( m_computers.size() != 1 ) { return "unknown"; } else { - return m_computer.getID() + "_" + m_computer.getAttachmentName(); + IComputerAccess computer = m_computers.iterator().next(); + return computer.getID() + "_" + computer.getAttachmentName(); } } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/modem/ModemState.java b/src/main/java/dan200/computercraft/shared/peripheral/modem/ModemState.java new file mode 100644 index 000000000..e283b52c1 --- /dev/null +++ b/src/main/java/dan200/computercraft/shared/peripheral/modem/ModemState.java @@ -0,0 +1,77 @@ +/* + * This file is part of ComputerCraft - http://www.computercraft.info + * Copyright Daniel Ratcliffe, 2011-2018. Do not distribute without permission. + * Send enquiries to dratcliffe@gmail.com + */ + +package dan200.computercraft.shared.peripheral.modem; + +import dan200.computercraft.api.lua.LuaException; +import it.unimi.dsi.fastutil.ints.IntOpenHashSet; +import it.unimi.dsi.fastutil.ints.IntSet; + +import java.util.concurrent.atomic.AtomicBoolean; + +public class ModemState +{ + private boolean open = false; + private AtomicBoolean changed = new AtomicBoolean( true ); + + private final IntSet channels = new IntOpenHashSet(); + + private void setOpen( boolean open ) + { + if( this.open == open ) return; + this.open = open; + this.changed.set( true ); + } + + public boolean pollChanged() + { + return changed.getAndSet( false ); + } + + public boolean isOpen() + { + return open; + } + + public boolean isOpen( int channel ) + { + synchronized( channels ) + { + return channels.contains( channel ); + } + } + + public void open( int channel ) throws LuaException + { + synchronized( channels ) + { + if( !channels.contains( channel ) ) + { + if( channels.size() >= 128 ) throw new LuaException( "Too many open channels" ); + channels.add( channel ); + setOpen( true ); + } + } + } + + public void close( int channel ) + { + synchronized( channels ) + { + channels.remove( channel ); + if( channels.isEmpty() ) setOpen( false ); + } + } + + public void closeAll() + { + synchronized( channels ) + { + channels.clear(); + setOpen( false ); + } + } +} diff --git a/src/main/java/dan200/computercraft/shared/peripheral/modem/TileAdvancedModem.java b/src/main/java/dan200/computercraft/shared/peripheral/modem/TileAdvancedModem.java index c5378c2a4..73e65b80a 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/modem/TileAdvancedModem.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/modem/TileAdvancedModem.java @@ -25,7 +25,7 @@ public class TileAdvancedModem extends TileModemBase public Peripheral( TileModemBase entity ) { - super( true ); + super( new ModemState(), true ); m_entity = entity; } 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 5bbcabb80..ef62d394c 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/modem/TileCable.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/modem/TileCable.java @@ -97,7 +97,7 @@ public class TileCable extends TileModemBase private boolean m_hasDirection = false; private boolean m_connectionsFormed = false; - + private WiredModemElement m_cable; private IWiredNode m_node; @@ -106,7 +106,7 @@ public class TileCable extends TileModemBase { m_cable = new CableElement( this ); m_node = m_cable.getNode(); - return new WiredModemPeripheral( m_cable ) + return new WiredModemPeripheral( new ModemState(), m_cable ) { @Nonnull @Override @@ -453,14 +453,8 @@ public class TileCable extends TileModemBase protected void updateAnim() { int anim = 0; - if( m_modem.isActive() ) - { - anim += 1; - } - if( m_peripheralAccessAllowed ) - { - anim += 2; - } + if( m_modem.getModemState().isOpen() ) anim |= 1; + if( m_peripheralAccessAllowed ) anim |= 2; setAnim( anim ); } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/modem/TileModemBase.java b/src/main/java/dan200/computercraft/shared/peripheral/modem/TileModemBase.java index a964dd38f..e8af5ef41 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/modem/TileModemBase.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/modem/TileModemBase.java @@ -56,10 +56,7 @@ public abstract class TileModemBase extends TilePeripheralBase public void onNeighbourChange() { EnumFacing dir = getDirection(); - if( !getWorld().isSideSolid( - getPos().offset( dir ), - dir.getOpposite() - ) ) + if( !getWorld().isSideSolid( getPos().offset( dir ), dir.getOpposite() ) ) { // Drop everything and remove block ((BlockGeneric)getBlockType()).dropAllItems( getWorld(), getPos(), false ); @@ -79,22 +76,15 @@ public abstract class TileModemBase extends TilePeripheralBase public void update() { super.update(); - if( !getWorld().isRemote && m_modem.pollChanged() ) + if( !getWorld().isRemote && m_modem.getModemState().pollChanged() ) { updateAnim(); } } - + protected void updateAnim() { - if( m_modem.isActive() ) - { - setAnim(1); - } - else - { - setAnim(0); - } + setAnim( m_modem.getModemState().isOpen() ? 1 : 0 ); } @Override @@ -109,15 +99,6 @@ public abstract class TileModemBase extends TilePeripheralBase @Override public IPeripheral getPeripheral( EnumFacing side ) { - if( side == getDirection() ) - { - return m_modem; - } - return null; - } - - protected boolean isAttached() - { - return (m_modem != null) && (m_modem.getComputer() != null); + return side == getDirection() ? m_modem : null; } } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/modem/TileWiredModemFull.java b/src/main/java/dan200/computercraft/shared/peripheral/modem/TileWiredModemFull.java index 60b88afe2..a80d1d900 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/modem/TileWiredModemFull.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/modem/TileWiredModemFull.java @@ -83,6 +83,7 @@ public class TileWiredModemFull extends TilePeripheralBase private boolean m_destroyed = false; private boolean m_connectionsFormed = false; + private final ModemState m_modemState = new ModemState(); private final WiredModemElement m_element = new FullElement( this ); private final IWiredNode m_node = m_element.getNode(); @@ -236,19 +237,8 @@ public class TileWiredModemFull extends TilePeripheralBase protected void updateAnim() { int anim = 0; - for( WiredModemPeripheral modem : m_modems ) - { - if( modem != null && modem.isActive() ) - { - anim += 1; - break; - } - } - - if( m_peripheralAccessAllowed ) - { - anim += 2; - } + if( m_modemState.isOpen() ) anim |= 1; + if( m_peripheralAccessAllowed ) anim |= 2; setAnim( anim ); } @@ -264,12 +254,7 @@ public class TileWiredModemFull extends TilePeripheralBase { if( !getWorld().isRemote ) { - boolean changed = false; - for( WiredModemPeripheral peripheral : m_modems ) - { - if( peripheral != null && peripheral.pollChanged() ) changed = true; - } - if( changed ) updateAnim(); + if( m_modemState.pollChanged() ) updateAnim(); if( !m_connectionsFormed ) { @@ -402,7 +387,7 @@ public class TileWiredModemFull extends TilePeripheralBase if( peripheral == null ) { WiredModemLocalPeripheral localPeripheral = m_peripherals[side.ordinal()]; - peripheral = m_modems[side.ordinal()] = new WiredModemPeripheral( m_element ) + peripheral = m_modems[side.ordinal()] = new WiredModemPeripheral( m_modemState, m_element ) { @Nonnull @Override diff --git a/src/main/java/dan200/computercraft/shared/peripheral/modem/TileWirelessModem.java b/src/main/java/dan200/computercraft/shared/peripheral/modem/TileWirelessModem.java index c28152ad9..27b512f10 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/modem/TileWirelessModem.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/modem/TileWirelessModem.java @@ -29,7 +29,7 @@ public class TileWirelessModem extends TileModemBase public Peripheral( TileModemBase entity ) { - super( false ); + super( new ModemState(), false ); m_entity = entity; } diff --git a/src/main/java/dan200/computercraft/shared/peripheral/modem/WiredModemPeripheral.java b/src/main/java/dan200/computercraft/shared/peripheral/modem/WiredModemPeripheral.java index 47536d1c3..612853967 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/modem/WiredModemPeripheral.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/modem/WiredModemPeripheral.java @@ -18,6 +18,8 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import static dan200.computercraft.core.apis.ArgumentHelper.getString; @@ -25,10 +27,11 @@ public abstract class WiredModemPeripheral extends ModemPeripheral implements IW { private final WiredModemElement modem; - private final Map peripheralWrappers = new HashMap<>(); + private final Map> peripheralWrappers = new HashMap<>( 1 ); - public WiredModemPeripheral( WiredModemElement modem ) + public WiredModemPeripheral( ModemState state, WiredModemElement modem ) { + super( state ); this.modem = modem; } @@ -88,56 +91,54 @@ public abstract class WiredModemPeripheral extends ModemPeripheral implements IW case 0: { // getNamesRemote - synchronized( peripheralWrappers ) + Map wrappers = getWrappers( computer ); + Map table = new HashMap<>(); + if( wrappers != null ) { int idx = 1; - Map table = new HashMap<>(); - for( String name : peripheralWrappers.keySet() ) - { - table.put( idx++, name ); - } - return new Object[]{ table }; + for( String name : wrappers.keySet() ) table.put( idx++, name ); } + return new Object[]{ table }; } case 1: { // isPresentRemote - String type = getTypeRemote( getString( arguments, 0 ) ); - return new Object[]{ type != null }; + String name = getString( arguments, 0 ); + return new Object[]{ getWrapper( computer, name ) != null }; } case 2: { // getTypeRemote - String type = getTypeRemote( getString( arguments, 0 ) ); - if( type != null ) - { - return new Object[]{ type }; - } - return null; + String name = getString( arguments, 0 ); + RemotePeripheralWrapper wrapper = getWrapper( computer, name ); + return wrapper != null ? new Object[]{ wrapper.getType() } : null; } case 3: { // getMethodsRemote - String[] methodNames = getMethodNamesRemote( getString( arguments, 0 ) ); - if( methodNames != null ) + String name = getString( arguments, 0 ); + RemotePeripheralWrapper wrapper = getWrapper( computer, name ); + if( wrapper == null ) return null; + + String[] methodNames = wrapper.getMethodNames(); + Map table = new HashMap<>(); + for( int i = 0; i < methodNames.length; ++i ) { - Map table = new HashMap<>(); - for( int i = 0; i < methodNames.length; ++i ) - { - table.put( i + 1, methodNames[i] ); - } - return new Object[]{ table }; + table.put( i + 1, methodNames[i] ); } - return null; + return new Object[]{ table }; } case 4: { // callRemote String remoteName = getString( arguments, 0 ); String methodName = getString( arguments, 1 ); + RemotePeripheralWrapper wrapper = getWrapper( computer, remoteName ); + if( wrapper == null ) throw new LuaException( "No peripheral: " + remoteName ); + Object[] methodArgs = new Object[arguments.length - 2]; System.arraycopy( arguments, 2, methodArgs, 0, arguments.length - 2 ); - return callMethodRemote( remoteName, context, methodName, methodArgs ); + return wrapper.callMethod( context, methodName, methodArgs ); } case 5: { @@ -157,29 +158,37 @@ public abstract class WiredModemPeripheral extends ModemPeripheral implements IW public void attach( @Nonnull IComputerAccess computer ) { super.attach( computer ); + + ConcurrentMap wrappers; + synchronized( peripheralWrappers ) + { + wrappers = peripheralWrappers.get( computer ); + if( wrappers == null ) peripheralWrappers.put( computer, wrappers = new ConcurrentHashMap<>() ); + } + synchronized( modem.getRemotePeripherals() ) { - synchronized( peripheralWrappers ) + for( Map.Entry entry : modem.getRemotePeripherals().entrySet() ) { - for( Map.Entry entry : modem.getRemotePeripherals().entrySet() ) - { - attachPeripheralImpl( entry.getKey(), entry.getValue() ); - } + attachPeripheralImpl( computer, wrappers, entry.getKey(), entry.getValue() ); } } } @Override - public synchronized void detach( @Nonnull IComputerAccess computer ) + public void detach( @Nonnull IComputerAccess computer ) { + Map wrappers; synchronized( peripheralWrappers ) { - for( RemotePeripheralWrapper wrapper : peripheralWrappers.values() ) - { - wrapper.detach(); - } - peripheralWrappers.clear(); + wrappers = peripheralWrappers.remove( computer ); } + if( wrappers != null ) + { + for( RemotePeripheralWrapper wrapper : wrappers.values() ) wrapper.detach(); + wrappers.clear(); + } + super.detach( computer ); } @@ -204,11 +213,12 @@ public abstract class WiredModemPeripheral extends ModemPeripheral implements IW public void attachPeripheral( String name, IPeripheral peripheral ) { - if( getComputer() == null ) return; - synchronized( peripheralWrappers ) { - attachPeripheralImpl( name, peripheral ); + for( Map.Entry> entry : peripheralWrappers.entrySet() ) + { + attachPeripheralImpl( entry.getKey(), entry.getValue(), name, peripheral ); + } } } @@ -216,63 +226,35 @@ public abstract class WiredModemPeripheral extends ModemPeripheral implements IW { synchronized( peripheralWrappers ) { - RemotePeripheralWrapper wrapper = peripheralWrappers.get( name ); - if( wrapper != null ) - { - peripheralWrappers.remove( name ); - wrapper.detach(); + for(ConcurrentMap wrappers : peripheralWrappers.values()) { + RemotePeripheralWrapper wrapper = wrappers.remove( name ); + if( wrapper != null ) wrapper.detach(); } + } } - private void attachPeripheralImpl( String periphName, IPeripheral peripheral ) + private void attachPeripheralImpl( IComputerAccess computer, ConcurrentMap peripherals, String periphName, IPeripheral peripheral ) { - if( !peripheralWrappers.containsKey( periphName ) && !periphName.equals( getLocalPeripheral().getConnectedName() ) ) + if( !peripherals.containsKey( periphName ) && !periphName.equals( getLocalPeripheral().getConnectedName() ) ) { - RemotePeripheralWrapper wrapper = new RemotePeripheralWrapper( modem, peripheral, getComputer(), periphName ); - peripheralWrappers.put( periphName, wrapper ); + RemotePeripheralWrapper wrapper = new RemotePeripheralWrapper( modem, peripheral, computer, periphName ); + peripherals.put( periphName, wrapper ); wrapper.attach(); } } - - private String getTypeRemote( String remoteName ) - { + + private ConcurrentMap getWrappers( IComputerAccess computer ) { synchronized( peripheralWrappers ) { - RemotePeripheralWrapper wrapper = peripheralWrappers.get( remoteName ); - if( wrapper != null ) - { - return wrapper.getType(); - } + return peripheralWrappers.get( computer ); } - return null; } - private String[] getMethodNamesRemote( String remoteName ) + private RemotePeripheralWrapper getWrapper( IComputerAccess computer, String remoteName ) { - synchronized( peripheralWrappers ) - { - RemotePeripheralWrapper wrapper = peripheralWrappers.get( remoteName ); - if( wrapper != null ) - { - return wrapper.getMethodNames(); - } - } - return null; - } - - private Object[] callMethodRemote( String remoteName, ILuaContext context, String method, Object[] arguments ) throws LuaException, InterruptedException - { - RemotePeripheralWrapper wrapper; - synchronized( peripheralWrappers ) - { - wrapper = peripheralWrappers.get( remoteName ); - } - if( wrapper != null ) - { - return wrapper.callMethod( context, method, arguments ); - } - throw new LuaException( "No peripheral: " + remoteName ); + ConcurrentMap wrappers = getWrappers( computer ); + return wrappers == null ? null : wrappers.get( remoteName ); } private static class RemotePeripheralWrapper implements IComputerAccess, IComputerOwned diff --git a/src/main/java/dan200/computercraft/shared/peripheral/modem/WirelessModemPeripheral.java b/src/main/java/dan200/computercraft/shared/peripheral/modem/WirelessModemPeripheral.java index 71d574515..e64041de8 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/modem/WirelessModemPeripheral.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/modem/WirelessModemPeripheral.java @@ -15,8 +15,9 @@ public abstract class WirelessModemPeripheral extends ModemPeripheral { private boolean m_advanced; - public WirelessModemPeripheral( boolean advanced ) + public WirelessModemPeripheral( ModemState state, boolean advanced ) { + super( state ); m_advanced = advanced; } diff --git a/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModem.java b/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModem.java index 74d10fce0..7b351caa1 100644 --- a/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModem.java +++ b/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModem.java @@ -5,6 +5,7 @@ import dan200.computercraft.api.pocket.IPocketAccess; import dan200.computercraft.api.pocket.IPocketUpgrade; import dan200.computercraft.shared.peripheral.PeripheralType; import dan200.computercraft.shared.peripheral.common.PeripheralItemFactory; +import dan200.computercraft.shared.peripheral.modem.ModemState; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.item.ItemStack; @@ -75,7 +76,8 @@ public class PocketModem implements IPocketUpgrade modem.setLocation( entity.getEntityWorld(), entity.posX, entity.posY, entity.posZ ); } - access.setLight( modem.isActive() ? 0xBA0000 : -1 ); + ModemState state = modem.getModemState(); + if( state.pollChanged() ) access.setLight( state.isOpen() ? 0xBA0000 : -1 ); } } } diff --git a/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModemPeripheral.java b/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModemPeripheral.java index 5ec82623d..22763466a 100644 --- a/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModemPeripheral.java +++ b/src/main/java/dan200/computercraft/shared/pocket/peripherals/PocketModemPeripheral.java @@ -6,6 +6,7 @@ package dan200.computercraft.shared.pocket.peripherals; import dan200.computercraft.api.peripheral.IPeripheral; +import dan200.computercraft.shared.peripheral.modem.ModemState; import dan200.computercraft.shared.peripheral.modem.WirelessModemPeripheral; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; @@ -19,7 +20,7 @@ public class PocketModemPeripheral extends WirelessModemPeripheral public PocketModemPeripheral( boolean advanced ) { - super( advanced ); + super( new ModemState(), advanced ); m_world = null; m_position = new Vec3d( 0.0, 0.0, 0.0 ); } diff --git a/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleModem.java b/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleModem.java index 22a4e431f..5105f3791 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleModem.java +++ b/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleModem.java @@ -10,6 +10,7 @@ import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.turtle.*; import dan200.computercraft.shared.peripheral.PeripheralType; import dan200.computercraft.shared.peripheral.common.PeripheralItemFactory; +import dan200.computercraft.shared.peripheral.modem.ModemState; import dan200.computercraft.shared.peripheral.modem.WirelessModemPeripheral; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.block.model.IBakedModel; @@ -17,9 +18,9 @@ import net.minecraft.client.renderer.block.model.ModelManager; import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.math.BlockPos; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; @@ -37,7 +38,7 @@ public class TurtleModem implements ITurtleUpgrade public Peripheral( ITurtleAccess turtle, boolean advanced ) { - super( advanced ); + super( new ModemState(), advanced ); m_turtle = turtle; } @@ -221,12 +222,12 @@ public class TurtleModem implements ITurtleUpgrade if( !turtle.getWorld().isRemote ) { IPeripheral peripheral = turtle.getPeripheral( side ); - if( peripheral != null && peripheral instanceof Peripheral ) + if( peripheral instanceof Peripheral ) { - Peripheral modemPeripheral = (Peripheral)peripheral; - if( modemPeripheral.pollChanged() ) + ModemState state = ((Peripheral) peripheral).getModemState(); + if( state.pollChanged() ) { - turtle.getUpgradeNBTData( side ).setBoolean( "active", modemPeripheral.isActive() ); + turtle.getUpgradeNBTData( side ).setBoolean( "active", state.isOpen() ); turtle.updateUpgradeNBTData( side ); } }