mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2024-11-17 15:24:52 +00:00
Various improvements to peripheral invalidation
- Abstract peripheral ID and type checking into separate class - Update peripherals directly rather than marking as invalid then fetching from the network. - Update peripherals when adjacent tiles change This does result in a slightly more ugly interface, but reduces the amount of work needed to perform partial updates of peripherals, such as those done by neighbouring tile updates.
This commit is contained in:
parent
04f162ef25
commit
6cf32f1f74
@ -1,11 +1,8 @@
|
|||||||
package dan200.computercraft.api.network.wired;
|
package dan200.computercraft.api.network.wired;
|
||||||
|
|
||||||
import dan200.computercraft.api.ComputerCraftAPI;
|
import dan200.computercraft.api.ComputerCraftAPI;
|
||||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An object which may be part of a wired network.
|
* An object which may be part of a wired network.
|
||||||
@ -19,21 +16,6 @@ import java.util.Map;
|
|||||||
*/
|
*/
|
||||||
public interface IWiredElement extends IWiredSender
|
public interface IWiredElement extends IWiredSender
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Fetch the peripherals this network element provides.
|
|
||||||
*
|
|
||||||
* This is only called when initially attaching to a network and after a call to {@link IWiredNode#invalidate()}}, so
|
|
||||||
* one does not <em>need</em> to cache the return value.
|
|
||||||
*
|
|
||||||
* @return The peripherals this node provides.
|
|
||||||
* @see IWiredNode#invalidate()
|
|
||||||
*/
|
|
||||||
@Nonnull
|
|
||||||
default Map<String, IPeripheral> getPeripherals()
|
|
||||||
{
|
|
||||||
return Collections.emptyMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when objects on the network change. This may occur when network nodes are added or removed, or when
|
* Called when objects on the network change. This may occur when network nodes are added or removed, or when
|
||||||
* peripherals change.
|
* peripherals change.
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
package dan200.computercraft.api.network.wired;
|
package dan200.computercraft.api.network.wired;
|
||||||
|
|
||||||
|
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A wired network is composed of one of more {@link IWiredNode}s, a set of connections between them, and a series
|
* A wired network is composed of one of more {@link IWiredNode}s, a set of connections between them, and a series
|
||||||
@ -51,7 +54,8 @@ public interface IWiredNetwork
|
|||||||
/**
|
/**
|
||||||
* Sever all connections this node has, removing it from this network.
|
* Sever all connections this node has, removing it from this network.
|
||||||
*
|
*
|
||||||
* This should only be used on the server thread.
|
* This should only be used on the server thread. You should only call this on nodes
|
||||||
|
* that your network element owns.
|
||||||
*
|
*
|
||||||
* @param node The node to remove
|
* @param node The node to remove
|
||||||
* @return Whether this node was removed from the network. One cannot remove a node from a network where it is the
|
* @return Whether this node was removed from the network. One cannot remove a node from a network where it is the
|
||||||
@ -62,13 +66,15 @@ public interface IWiredNetwork
|
|||||||
boolean remove( @Nonnull IWiredNode node );
|
boolean remove( @Nonnull IWiredNode node );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark this node's peripherals as having changed.
|
* Update the peripherals a node provides.
|
||||||
*
|
*
|
||||||
* This should only be used on the server thread.
|
* This should only be used on the server thread. You should only call this on nodes
|
||||||
|
* that your network element owns.
|
||||||
*
|
*
|
||||||
* @param node The node to mark as invalid.
|
* @param node The node to attach peripherals for.
|
||||||
|
* @param peripherals The new peripherals for this node.
|
||||||
* @throws IllegalArgumentException If the node is not in the network.
|
* @throws IllegalArgumentException If the node is not in the network.
|
||||||
* @see IWiredElement#getPeripherals()
|
* @see IWiredNode#updatePeripherals(Map)
|
||||||
*/
|
*/
|
||||||
void invalidate( @Nonnull IWiredNode node );
|
void updatePeripherals( @Nonnull IWiredNode node, @Nonnull Map<String, IPeripheral> peripherals );
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
package dan200.computercraft.api.network.wired;
|
package dan200.computercraft.api.network.wired;
|
||||||
|
|
||||||
import dan200.computercraft.api.network.IPacketNetwork;
|
import dan200.computercraft.api.network.IPacketNetwork;
|
||||||
|
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wired nodes act as a layer between {@link IWiredElement}s and {@link IWiredNetwork}s.
|
* Wired nodes act as a layer between {@link IWiredElement}s and {@link IWiredNetwork}s.
|
||||||
@ -72,7 +74,8 @@ public interface IWiredNode extends IPacketNetwork
|
|||||||
/**
|
/**
|
||||||
* Sever all connections this node has, removing it from this network.
|
* Sever all connections this node has, removing it from this network.
|
||||||
*
|
*
|
||||||
* This should only be used on the server thread.
|
* This should only be used on the server thread. You should only call this on nodes
|
||||||
|
* that your network element owns.
|
||||||
*
|
*
|
||||||
* @return Whether this node was removed from the network. One cannot remove a node from a network where it is the
|
* @return Whether this node was removed from the network. One cannot remove a node from a network where it is the
|
||||||
* only element.
|
* only element.
|
||||||
@ -87,12 +90,14 @@ public interface IWiredNode extends IPacketNetwork
|
|||||||
/**
|
/**
|
||||||
* Mark this node's peripherals as having changed.
|
* Mark this node's peripherals as having changed.
|
||||||
*
|
*
|
||||||
* This should only be used on the server thread.
|
* This should only be used on the server thread. You should only call this on nodes
|
||||||
|
* that your network element owns.
|
||||||
*
|
*
|
||||||
* @see IWiredElement#getPeripherals()
|
* @param peripherals The new peripherals for this node.
|
||||||
|
* @see IWiredNetwork#updatePeripherals(IWiredNode, Map)
|
||||||
*/
|
*/
|
||||||
default void invalidate()
|
default void updatePeripherals( @Nonnull Map<String, IPeripheral> peripherals )
|
||||||
{
|
{
|
||||||
getNetwork().invalidate( this );
|
getNetwork().updatePeripherals( this, peripherals );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,10 +16,7 @@ import dan200.computercraft.shared.peripheral.PeripheralType;
|
|||||||
import dan200.computercraft.shared.peripheral.common.BlockCable;
|
import dan200.computercraft.shared.peripheral.common.BlockCable;
|
||||||
import dan200.computercraft.shared.peripheral.common.BlockCableModemVariant;
|
import dan200.computercraft.shared.peripheral.common.BlockCableModemVariant;
|
||||||
import dan200.computercraft.shared.peripheral.common.PeripheralItemFactory;
|
import dan200.computercraft.shared.peripheral.common.PeripheralItemFactory;
|
||||||
import dan200.computercraft.shared.util.IDAssigner;
|
|
||||||
import dan200.computercraft.shared.util.PeripheralUtil;
|
|
||||||
import dan200.computercraft.shared.wired.CapabilityWiredElement;
|
import dan200.computercraft.shared.wired.CapabilityWiredElement;
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
@ -35,7 +32,6 @@ import net.minecraftforge.common.capabilities.Capability;
|
|||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.io.File;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -79,16 +75,6 @@ public class TileCable extends TileModemBase
|
|||||||
return new Vec3d( pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5 );
|
return new Vec3d( pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public Map<String, IPeripheral> getPeripherals()
|
|
||||||
{
|
|
||||||
IPeripheral peripheral = m_entity.getConnectedPeripheral();
|
|
||||||
return peripheral != null
|
|
||||||
? Collections.singletonMap( m_entity.getConnectedPeripheralName(), peripheral )
|
|
||||||
: Collections.emptyMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void attachPeripheral( String name, IPeripheral peripheral )
|
protected void attachPeripheral( String name, IPeripheral peripheral )
|
||||||
{
|
{
|
||||||
@ -105,9 +91,9 @@ public class TileCable extends TileModemBase
|
|||||||
// Members
|
// Members
|
||||||
|
|
||||||
private boolean m_peripheralAccessAllowed;
|
private boolean m_peripheralAccessAllowed;
|
||||||
private int m_attachedPeripheralID;
|
private WiredModemLocalPeripheral m_peripheral = new WiredModemLocalPeripheral();
|
||||||
|
|
||||||
private boolean m_destroyed;
|
private boolean m_destroyed = false;
|
||||||
|
|
||||||
private boolean m_hasDirection = false;
|
private boolean m_hasDirection = false;
|
||||||
private boolean m_connectionsFormed = false;
|
private boolean m_connectionsFormed = false;
|
||||||
@ -115,14 +101,6 @@ public class TileCable extends TileModemBase
|
|||||||
private WiredModemElement m_cable;
|
private WiredModemElement m_cable;
|
||||||
private IWiredNode m_node;
|
private IWiredNode m_node;
|
||||||
|
|
||||||
public TileCable()
|
|
||||||
{
|
|
||||||
m_peripheralAccessAllowed = false;
|
|
||||||
m_attachedPeripheralID = -1;
|
|
||||||
|
|
||||||
m_destroyed = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ModemPeripheral createPeripheral()
|
protected ModemPeripheral createPeripheral()
|
||||||
{
|
{
|
||||||
@ -133,7 +111,7 @@ public class TileCable extends TileModemBase
|
|||||||
@Override
|
@Override
|
||||||
protected boolean canSeePeripheral( @Nonnull String peripheralName )
|
protected boolean canSeePeripheral( @Nonnull String peripheralName )
|
||||||
{
|
{
|
||||||
return !peripheralName.equals( getConnectedPeripheralName() );
|
return !peripheralName.equals( m_peripheral.getConnectedName() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@ -294,10 +272,29 @@ public class TileCable extends TileModemBase
|
|||||||
modemChanged();
|
modemChanged();
|
||||||
connectionsChanged();
|
connectionsChanged();
|
||||||
|
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( !world.isRemote && m_peripheralAccessAllowed )
|
||||||
|
{
|
||||||
|
if( m_peripheral.attach( world, getPos(), dir ) ) updateConnectedPeripherals();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNeighbourTileEntityChange( @Nonnull BlockPos neighbour )
|
||||||
|
{
|
||||||
|
super.onNeighbourTileEntityChange( neighbour );
|
||||||
|
if( !world.isRemote && m_peripheralAccessAllowed )
|
||||||
|
{
|
||||||
|
EnumFacing facing = getDirection();
|
||||||
|
if( getPos().offset( facing ).equals( neighbour ) )
|
||||||
|
{
|
||||||
|
if( m_peripheral.attach( world, getPos(), facing ) ) updateConnectedPeripherals();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public AxisAlignedBB getModemBounds()
|
public AxisAlignedBB getModemBounds()
|
||||||
@ -400,9 +397,9 @@ public class TileCable extends TileModemBase
|
|||||||
if( !getWorld().isRemote )
|
if( !getWorld().isRemote )
|
||||||
{
|
{
|
||||||
// On server, we interacted if a peripheral was found
|
// On server, we interacted if a peripheral was found
|
||||||
String oldPeriphName = getConnectedPeripheralName();
|
String oldPeriphName = m_peripheral.getConnectedName();
|
||||||
togglePeripheralAccess();
|
togglePeripheralAccess();
|
||||||
String periphName = getConnectedPeripheralName();
|
String periphName = m_peripheral.getConnectedName();
|
||||||
|
|
||||||
if( !Objects.equal( periphName, oldPeriphName ) )
|
if( !Objects.equal( periphName, oldPeriphName ) )
|
||||||
{
|
{
|
||||||
@ -437,7 +434,7 @@ public class TileCable extends TileModemBase
|
|||||||
// Read properties
|
// Read properties
|
||||||
super.readFromNBT( nbttagcompound );
|
super.readFromNBT( nbttagcompound );
|
||||||
m_peripheralAccessAllowed = nbttagcompound.getBoolean( "peripheralAccess" );
|
m_peripheralAccessAllowed = nbttagcompound.getBoolean( "peripheralAccess" );
|
||||||
m_attachedPeripheralID = nbttagcompound.getInteger( "peripheralID" );
|
m_peripheral.readNBT( nbttagcompound, "" );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@ -447,7 +444,7 @@ public class TileCable extends TileModemBase
|
|||||||
// Write properties
|
// Write properties
|
||||||
nbttagcompound = super.writeToNBT( nbttagcompound );
|
nbttagcompound = super.writeToNBT( nbttagcompound );
|
||||||
nbttagcompound.setBoolean( "peripheralAccess", m_peripheralAccessAllowed );
|
nbttagcompound.setBoolean( "peripheralAccess", m_peripheralAccessAllowed );
|
||||||
nbttagcompound.setInteger( "peripheralID", m_attachedPeripheralID );
|
m_peripheral.writeNBT( nbttagcompound, "" );
|
||||||
return nbttagcompound;
|
return nbttagcompound;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -476,8 +473,13 @@ public class TileCable extends TileModemBase
|
|||||||
if( !m_connectionsFormed )
|
if( !m_connectionsFormed )
|
||||||
{
|
{
|
||||||
m_connectionsFormed = true;
|
m_connectionsFormed = true;
|
||||||
|
|
||||||
connectionsChanged();
|
connectionsChanged();
|
||||||
if( m_peripheralAccessAllowed ) m_node.invalidate();
|
if( m_peripheralAccessAllowed )
|
||||||
|
{
|
||||||
|
m_peripheral.attach( world, pos, m_dir );
|
||||||
|
updateConnectedPeripherals();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -515,15 +517,11 @@ public class TileCable extends TileModemBase
|
|||||||
if( getWorld().isRemote ) return;
|
if( getWorld().isRemote ) return;
|
||||||
|
|
||||||
PeripheralType type = getPeripheralType();
|
PeripheralType type = getPeripheralType();
|
||||||
if( type == PeripheralType.Cable )
|
|
||||||
{
|
|
||||||
m_attachedPeripheralID = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( type != PeripheralType.WiredModemWithCable && m_peripheralAccessAllowed )
|
if( type != PeripheralType.WiredModemWithCable && m_peripheralAccessAllowed )
|
||||||
{
|
{
|
||||||
m_peripheralAccessAllowed = false;
|
m_peripheralAccessAllowed = false;
|
||||||
m_node.invalidate();
|
m_peripheral.detach();
|
||||||
|
m_node.updatePeripherals( Collections.emptyMap() );
|
||||||
markDirty();
|
markDirty();
|
||||||
updateAnim();
|
updateAnim();
|
||||||
}
|
}
|
||||||
@ -534,61 +532,34 @@ public class TileCable extends TileModemBase
|
|||||||
{
|
{
|
||||||
if( !m_peripheralAccessAllowed )
|
if( !m_peripheralAccessAllowed )
|
||||||
{
|
{
|
||||||
|
m_peripheral.attach( world, getPos(), getDirection() );
|
||||||
|
if( !m_peripheral.hasPeripheral() ) return;
|
||||||
|
|
||||||
m_peripheralAccessAllowed = true;
|
m_peripheralAccessAllowed = true;
|
||||||
if( getConnectedPeripheral() == null )
|
m_node.updatePeripherals( m_peripheral.toMap() );
|
||||||
{
|
|
||||||
m_peripheralAccessAllowed = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
m_peripheral.detach();
|
||||||
|
|
||||||
m_peripheralAccessAllowed = false;
|
m_peripheralAccessAllowed = false;
|
||||||
|
m_node.updatePeripherals( Collections.emptyMap() );
|
||||||
}
|
}
|
||||||
|
|
||||||
updateAnim();
|
updateAnim();
|
||||||
m_node.invalidate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getConnectedPeripheralName()
|
private void updateConnectedPeripherals()
|
||||||
{
|
{
|
||||||
IPeripheral periph = getConnectedPeripheral();
|
Map<String, IPeripheral> peripherals = m_peripheral.toMap();
|
||||||
if( periph != null )
|
if( peripherals.isEmpty() )
|
||||||
{
|
{
|
||||||
String type = periph.getType();
|
// If there are no peripherals then disable access and update the display state.
|
||||||
if( m_attachedPeripheralID < 0 )
|
m_peripheralAccessAllowed = false;
|
||||||
{
|
updateAnim();
|
||||||
m_attachedPeripheralID = IDAssigner.getNextIDFromFile( new File(
|
|
||||||
ComputerCraft.getWorldDir( getWorld() ),
|
|
||||||
"computer/lastid_" + type + ".txt"
|
|
||||||
) );
|
|
||||||
}
|
|
||||||
return type + "_" + m_attachedPeripheralID;
|
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private IPeripheral getConnectedPeripheral()
|
m_node.updatePeripherals( peripherals );
|
||||||
{
|
|
||||||
if( m_peripheralAccessAllowed )
|
|
||||||
{
|
|
||||||
if( getPeripheralType() == PeripheralType.WiredModemWithCable )
|
|
||||||
{
|
|
||||||
EnumFacing facing = getDirection();
|
|
||||||
BlockPos neighbour = getPos().offset( facing );
|
|
||||||
IPeripheral peripheral = getPeripheral( getWorld(), neighbour, facing.getOpposite() );
|
|
||||||
return peripheral == null || peripheral instanceof WiredModemPeripheral ? null : peripheral;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IPeripheral getPeripheral( World world, BlockPos pos, EnumFacing facing )
|
|
||||||
{
|
|
||||||
Block block = world.getBlockState( pos ).getBlock();
|
|
||||||
if( block == ComputerCraft.Blocks.wiredModemFull || block == ComputerCraft.Blocks.cable ) return null;
|
|
||||||
|
|
||||||
return PeripheralUtil.getPeripheral( world, pos, facing );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -13,7 +13,6 @@ import dan200.computercraft.api.network.wired.IWiredNode;
|
|||||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||||
import dan200.computercraft.shared.peripheral.common.BlockCable;
|
import dan200.computercraft.shared.peripheral.common.BlockCable;
|
||||||
import dan200.computercraft.shared.peripheral.common.TilePeripheralBase;
|
import dan200.computercraft.shared.peripheral.common.TilePeripheralBase;
|
||||||
import dan200.computercraft.shared.util.IDAssigner;
|
|
||||||
import dan200.computercraft.shared.wired.CapabilityWiredElement;
|
import dan200.computercraft.shared.wired.CapabilityWiredElement;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
@ -24,11 +23,9 @@ import net.minecraft.util.math.Vec3d;
|
|||||||
import net.minecraft.util.text.TextComponentTranslation;
|
import net.minecraft.util.text.TextComponentTranslation;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraftforge.common.capabilities.Capability;
|
import net.minecraftforge.common.capabilities.Capability;
|
||||||
import net.minecraftforge.common.util.Constants;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.io.File;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class TileWiredModemFull extends TilePeripheralBase
|
public class TileWiredModemFull extends TilePeripheralBase
|
||||||
@ -76,20 +73,12 @@ public class TileWiredModemFull extends TilePeripheralBase
|
|||||||
BlockPos pos = m_entity.getPos();
|
BlockPos pos = m_entity.getPos();
|
||||||
return new Vec3d( pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5 );
|
return new Vec3d( pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public Map<String, IPeripheral> getPeripherals()
|
|
||||||
{
|
|
||||||
return m_entity.getPeripherals();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private WiredModemPeripheral[] m_modems = new WiredModemPeripheral[6];
|
private WiredModemPeripheral[] m_modems = new WiredModemPeripheral[6];
|
||||||
|
|
||||||
private boolean m_peripheralAccessAllowed = false;
|
private boolean m_peripheralAccessAllowed = false;
|
||||||
private int[] m_attachedPeripheralIDs = new int[6];
|
private WiredModemLocalPeripheral[] m_peripherals = new WiredModemLocalPeripheral[6];
|
||||||
private String[] m_attachedPeripheralTypes = new String[6];
|
|
||||||
|
|
||||||
private boolean m_destroyed = false;
|
private boolean m_destroyed = false;
|
||||||
private boolean m_connectionsFormed = false;
|
private boolean m_connectionsFormed = false;
|
||||||
@ -99,7 +88,7 @@ public class TileWiredModemFull extends TilePeripheralBase
|
|||||||
|
|
||||||
public TileWiredModemFull()
|
public TileWiredModemFull()
|
||||||
{
|
{
|
||||||
Arrays.fill( m_attachedPeripheralIDs, -1 );
|
for( int i = 0; i < m_peripherals.length; i++ ) m_peripherals[i] = new WiredModemLocalPeripheral();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void remove()
|
private void remove()
|
||||||
@ -152,18 +141,29 @@ public class TileWiredModemFull extends TilePeripheralBase
|
|||||||
{
|
{
|
||||||
if( !world.isRemote && m_peripheralAccessAllowed )
|
if( !world.isRemote && m_peripheralAccessAllowed )
|
||||||
{
|
{
|
||||||
Map<String, IPeripheral> updated = getPeripherals();
|
boolean hasChanged = false;
|
||||||
|
for( EnumFacing facing : EnumFacing.VALUES )
|
||||||
if( updated.isEmpty() )
|
|
||||||
{
|
{
|
||||||
// If there are no peripherals then disable access and update the display state.
|
hasChanged |= m_peripherals[facing.ordinal()].attach( world, getPos(), facing );
|
||||||
m_peripheralAccessAllowed = false;
|
|
||||||
updateAnim();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always invalidate the node: it's more accurate than checking if the peripherals
|
if( hasChanged ) updateConnectedPeripherals();
|
||||||
// have changed
|
}
|
||||||
m_node.invalidate();
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNeighbourTileEntityChange( @Nonnull BlockPos neighbour )
|
||||||
|
{
|
||||||
|
if( !world.isRemote && m_peripheralAccessAllowed )
|
||||||
|
{
|
||||||
|
for( EnumFacing facing : EnumFacing.VALUES )
|
||||||
|
{
|
||||||
|
if( getPos().offset( facing ).equals( neighbour ) )
|
||||||
|
{
|
||||||
|
WiredModemLocalPeripheral peripheral = m_peripherals[facing.ordinal()];
|
||||||
|
if( peripheral.attach( world, getPos(), facing ) ) updateConnectedPeripherals();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,9 +180,9 @@ public class TileWiredModemFull extends TilePeripheralBase
|
|||||||
if( !getWorld().isRemote )
|
if( !getWorld().isRemote )
|
||||||
{
|
{
|
||||||
// On server, we interacted if a peripheral was found
|
// On server, we interacted if a peripheral was found
|
||||||
Set<String> oldPeriphName = getPeripherals().keySet();
|
Set<String> oldPeriphName = getConnectedPeripheralNames();
|
||||||
togglePeripheralAccess();
|
togglePeripheralAccess();
|
||||||
Set<String> periphName = getPeripherals().keySet();
|
Set<String> periphName = getConnectedPeripheralNames();
|
||||||
|
|
||||||
if( !Objects.equal( periphName, oldPeriphName ) )
|
if( !Objects.equal( periphName, oldPeriphName ) )
|
||||||
{
|
{
|
||||||
@ -220,17 +220,7 @@ public class TileWiredModemFull extends TilePeripheralBase
|
|||||||
{
|
{
|
||||||
super.readFromNBT( tag );
|
super.readFromNBT( tag );
|
||||||
m_peripheralAccessAllowed = tag.getBoolean( "peripheralAccess" );
|
m_peripheralAccessAllowed = tag.getBoolean( "peripheralAccess" );
|
||||||
for( int i = 0; i < m_attachedPeripheralIDs.length; i++ )
|
for( int i = 0; i < m_peripherals.length; i++ ) m_peripherals[i].readNBT( tag, "_" + i );
|
||||||
{
|
|
||||||
if( tag.hasKey( "peripheralID_" + i, Constants.NBT.TAG_ANY_NUMERIC ) )
|
|
||||||
{
|
|
||||||
m_attachedPeripheralIDs[i] = tag.getInteger( "peripheralID_" + i );
|
|
||||||
}
|
|
||||||
if( tag.hasKey( "peripheralType_" + i, Constants.NBT.TAG_STRING ) )
|
|
||||||
{
|
|
||||||
m_attachedPeripheralTypes[i] = tag.getString( "peripheralType_" + i );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@ -239,17 +229,7 @@ public class TileWiredModemFull extends TilePeripheralBase
|
|||||||
{
|
{
|
||||||
tag = super.writeToNBT( tag );
|
tag = super.writeToNBT( tag );
|
||||||
tag.setBoolean( "peripheralAccess", m_peripheralAccessAllowed );
|
tag.setBoolean( "peripheralAccess", m_peripheralAccessAllowed );
|
||||||
for( int i = 0; i < m_attachedPeripheralIDs.length; i++ )
|
for( int i = 0; i < m_peripherals.length; i++ ) m_peripherals[i].writeNBT( tag, "_" + i );
|
||||||
{
|
|
||||||
if( m_attachedPeripheralIDs[i] >= 0 )
|
|
||||||
{
|
|
||||||
tag.setInteger( "peripheralID_" + i, m_attachedPeripheralIDs[i] );
|
|
||||||
}
|
|
||||||
if( m_attachedPeripheralTypes[i] != null )
|
|
||||||
{
|
|
||||||
tag.setString( "peripheralType_" + i, m_attachedPeripheralTypes[i] );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,8 +274,16 @@ public class TileWiredModemFull extends TilePeripheralBase
|
|||||||
if( !m_connectionsFormed )
|
if( !m_connectionsFormed )
|
||||||
{
|
{
|
||||||
m_connectionsFormed = true;
|
m_connectionsFormed = true;
|
||||||
|
|
||||||
connectionsChanged();
|
connectionsChanged();
|
||||||
if( m_peripheralAccessAllowed ) m_node.invalidate();
|
if( m_peripheralAccessAllowed )
|
||||||
|
{
|
||||||
|
for( EnumFacing facing : EnumFacing.VALUES )
|
||||||
|
{
|
||||||
|
m_peripherals[facing.ordinal()].attach( world, getPos(), facing );
|
||||||
|
}
|
||||||
|
updateConnectedPeripherals();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,60 +314,63 @@ public class TileWiredModemFull extends TilePeripheralBase
|
|||||||
{
|
{
|
||||||
if( !m_peripheralAccessAllowed )
|
if( !m_peripheralAccessAllowed )
|
||||||
{
|
{
|
||||||
m_peripheralAccessAllowed = true;
|
boolean hasAny = false;
|
||||||
if( getPeripherals().isEmpty() )
|
for( EnumFacing facing : EnumFacing.VALUES )
|
||||||
{
|
{
|
||||||
m_peripheralAccessAllowed = false;
|
WiredModemLocalPeripheral peripheral = m_peripherals[facing.ordinal()];
|
||||||
return;
|
peripheral.attach( world, getPos(), facing );
|
||||||
|
hasAny |= peripheral.hasPeripheral();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( !hasAny ) return;
|
||||||
|
|
||||||
|
m_peripheralAccessAllowed = true;
|
||||||
|
m_node.updatePeripherals( getConnectedPeripherals() );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_peripheralAccessAllowed = false;
|
m_peripheralAccessAllowed = false;
|
||||||
|
|
||||||
|
for( WiredModemLocalPeripheral peripheral : m_peripherals ) peripheral.detach();
|
||||||
|
m_node.updatePeripherals( Collections.emptyMap() );
|
||||||
}
|
}
|
||||||
|
|
||||||
updateAnim();
|
updateAnim();
|
||||||
m_node.invalidate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
private Set<String> getConnectedPeripheralNames()
|
||||||
private Map<String, IPeripheral> getPeripherals()
|
{
|
||||||
|
if( !m_peripheralAccessAllowed ) return Collections.emptySet();
|
||||||
|
|
||||||
|
Set<String> peripherals = new HashSet<>( 6 );
|
||||||
|
for( WiredModemLocalPeripheral m_peripheral : m_peripherals )
|
||||||
|
{
|
||||||
|
String name = m_peripheral.getConnectedName();
|
||||||
|
if( name != null ) peripherals.add( name );
|
||||||
|
}
|
||||||
|
return peripherals;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, IPeripheral> getConnectedPeripherals()
|
||||||
{
|
{
|
||||||
if( !m_peripheralAccessAllowed ) return Collections.emptyMap();
|
if( !m_peripheralAccessAllowed ) return Collections.emptyMap();
|
||||||
|
|
||||||
Map<String, IPeripheral> peripherals = new HashMap<>( 6 );
|
Map<String, IPeripheral> peripherals = new HashMap<>( 6 );
|
||||||
for( EnumFacing facing : EnumFacing.VALUES )
|
for( WiredModemLocalPeripheral m_peripheral : m_peripherals ) m_peripheral.extendMap( peripherals );
|
||||||
{
|
|
||||||
BlockPos neighbour = getPos().offset( facing );
|
|
||||||
IPeripheral peripheral = TileCable.getPeripheral( getWorld(), neighbour, facing.getOpposite() );
|
|
||||||
if( peripheral != null && !(peripheral instanceof WiredModemPeripheral) )
|
|
||||||
{
|
|
||||||
String type = peripheral.getType();
|
|
||||||
int id = m_attachedPeripheralIDs[facing.ordinal()];
|
|
||||||
String oldType = m_attachedPeripheralTypes[facing.ordinal()];
|
|
||||||
if( id < 0 || !type.equals( oldType ) )
|
|
||||||
{
|
|
||||||
m_attachedPeripheralTypes[facing.ordinal()] = type;
|
|
||||||
id = m_attachedPeripheralIDs[facing.ordinal()] = IDAssigner.getNextIDFromFile( new File(
|
|
||||||
ComputerCraft.getWorldDir( getWorld() ),
|
|
||||||
"computer/lastid_" + type + ".txt"
|
|
||||||
) );
|
|
||||||
}
|
|
||||||
|
|
||||||
peripherals.put( type + "_" + id, peripheral );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return peripherals;
|
return peripherals;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getCachedPeripheralName( EnumFacing facing )
|
private void updateConnectedPeripherals()
|
||||||
{
|
{
|
||||||
if( !m_peripheralAccessAllowed ) return null;
|
Map<String, IPeripheral> peripherals = getConnectedPeripherals();
|
||||||
|
if( peripherals.isEmpty() )
|
||||||
|
{
|
||||||
|
// If there are no peripherals then disable access and update the display state.
|
||||||
|
m_peripheralAccessAllowed = false;
|
||||||
|
updateAnim();
|
||||||
|
}
|
||||||
|
|
||||||
int id = m_attachedPeripheralIDs[facing.ordinal()];
|
m_node.updatePeripherals( peripherals );
|
||||||
String type = m_attachedPeripheralTypes[facing.ordinal()];
|
|
||||||
return id < 0 || type == null ? null : type + "_" + id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// IWiredElementTile
|
// IWiredElementTile
|
||||||
@ -415,7 +406,7 @@ public class TileWiredModemFull extends TilePeripheralBase
|
|||||||
@Override
|
@Override
|
||||||
protected boolean canSeePeripheral( @Nonnull String peripheralName )
|
protected boolean canSeePeripheral( @Nonnull String peripheralName )
|
||||||
{
|
{
|
||||||
return !peripheralName.equals( getCachedPeripheralName( side ) );
|
return !peripheralName.equals( m_peripherals[side.ordinal()].getConnectedName() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
|
@ -0,0 +1,139 @@
|
|||||||
|
package dan200.computercraft.shared.peripheral.modem;
|
||||||
|
|
||||||
|
import dan200.computercraft.ComputerCraft;
|
||||||
|
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||||
|
import dan200.computercraft.shared.util.IDAssigner;
|
||||||
|
import dan200.computercraft.shared.util.PeripheralUtil;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
|
import net.minecraft.util.EnumFacing;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.common.util.Constants;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a local peripheral exposed on the wired network
|
||||||
|
*
|
||||||
|
* This is responsible for getting the peripheral in world, tracking id and type and determining whether
|
||||||
|
* it has changed.
|
||||||
|
*/
|
||||||
|
public final class WiredModemLocalPeripheral
|
||||||
|
{
|
||||||
|
private int id;
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
private IPeripheral peripheral;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attach a new peripheral from the world
|
||||||
|
*
|
||||||
|
* @param world The world to search in
|
||||||
|
* @param origin The position to search from
|
||||||
|
* @param direction The direction so search in
|
||||||
|
* @return Whether the peripheral changed.
|
||||||
|
*/
|
||||||
|
public boolean attach( @Nonnull World world, @Nonnull BlockPos origin, @Nonnull EnumFacing direction )
|
||||||
|
{
|
||||||
|
IPeripheral oldPeripheral = this.peripheral;
|
||||||
|
IPeripheral peripheral = this.peripheral = getPeripheralFrom( world, origin, direction );
|
||||||
|
|
||||||
|
if( peripheral == null )
|
||||||
|
{
|
||||||
|
return oldPeripheral != null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
String type = peripheral.getType();
|
||||||
|
int id = this.id;
|
||||||
|
|
||||||
|
if( id > 0 && this.type == null )
|
||||||
|
{
|
||||||
|
// If we had an ID but no type, then just set the type.
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
else if( id < 0 || !type.equals( this.type ) )
|
||||||
|
{
|
||||||
|
this.type = type;
|
||||||
|
this.id = IDAssigner.getNextIDFromFile( new File(
|
||||||
|
ComputerCraft.getWorldDir( world ),
|
||||||
|
"computer/lastid_" + type + ".txt"
|
||||||
|
) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return oldPeripheral == null || !oldPeripheral.equals( peripheral );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detach the current peripheral
|
||||||
|
*
|
||||||
|
* @return Whether the peripheral changed
|
||||||
|
*/
|
||||||
|
public boolean detach()
|
||||||
|
{
|
||||||
|
if( peripheral == null ) return false;
|
||||||
|
peripheral = null;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public String getConnectedName()
|
||||||
|
{
|
||||||
|
return peripheral != null ? type + "_" + id : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public IPeripheral getPeripheral()
|
||||||
|
{
|
||||||
|
return peripheral;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasPeripheral()
|
||||||
|
{
|
||||||
|
return peripheral != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void extendMap( @Nonnull Map<String, IPeripheral> peripherals )
|
||||||
|
{
|
||||||
|
if( peripheral != null ) peripherals.put( type + "_" + id, peripheral );
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, IPeripheral> toMap()
|
||||||
|
{
|
||||||
|
return peripheral == null
|
||||||
|
? Collections.emptyMap()
|
||||||
|
: Collections.singletonMap( type + "_" + id, peripheral );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeNBT( @Nonnull NBTTagCompound tag, @Nonnull String suffix )
|
||||||
|
{
|
||||||
|
if( id >= 0 ) tag.setInteger( "peripheralID" + suffix, id );
|
||||||
|
if( type != null ) tag.setString( "peripheralType" + suffix, type );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readNBT( @Nonnull NBTTagCompound tag, @Nonnull String suffix )
|
||||||
|
{
|
||||||
|
id = tag.hasKey( "peripheralID" + suffix, Constants.NBT.TAG_ANY_NUMERIC )
|
||||||
|
? tag.getInteger( "peripheralID" + suffix ) : -1;
|
||||||
|
|
||||||
|
type = tag.hasKey( "peripheralType" + suffix, Constants.NBT.TAG_STRING )
|
||||||
|
? tag.getString( "peripheralType" + suffix ) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IPeripheral getPeripheralFrom( World world, BlockPos pos, EnumFacing direction )
|
||||||
|
{
|
||||||
|
BlockPos offset = pos.offset( direction );
|
||||||
|
|
||||||
|
Block block = world.getBlockState( offset ).getBlock();
|
||||||
|
if( block == ComputerCraft.Blocks.wiredModemFull || block == ComputerCraft.Blocks.cable ) return null;
|
||||||
|
|
||||||
|
IPeripheral peripheral = PeripheralUtil.getPeripheral( world, offset, direction.getOpposite() );
|
||||||
|
return peripheral instanceof WiredModemPeripheral ? null : peripheral;
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,7 @@
|
|||||||
package dan200.computercraft.shared.wired;
|
package dan200.computercraft.shared.wired;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
import dan200.computercraft.api.network.Packet;
|
import dan200.computercraft.api.network.Packet;
|
||||||
import dan200.computercraft.api.network.wired.IWiredNetwork;
|
import dan200.computercraft.api.network.wired.IWiredNetwork;
|
||||||
import dan200.computercraft.api.network.wired.IWiredNode;
|
import dan200.computercraft.api.network.wired.IWiredNode;
|
||||||
@ -283,9 +285,10 @@ public final class WiredNetwork implements IWiredNetwork
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invalidate( @Nonnull IWiredNode node )
|
public void updatePeripherals( @Nonnull IWiredNode node, @Nonnull Map<String, IPeripheral> newPeripherals )
|
||||||
{
|
{
|
||||||
WiredNode wired = checkNode( node );
|
WiredNode wired = checkNode( node );
|
||||||
|
Preconditions.checkNotNull( peripherals, "peripherals cannot be null" );
|
||||||
|
|
||||||
lock.writeLock().lock();
|
lock.writeLock().lock();
|
||||||
try
|
try
|
||||||
@ -293,11 +296,10 @@ public final class WiredNetwork implements IWiredNetwork
|
|||||||
if( wired.network != this ) throw new IllegalStateException( "Node is not on this network" );
|
if( wired.network != this ) throw new IllegalStateException( "Node is not on this network" );
|
||||||
|
|
||||||
Map<String, IPeripheral> oldPeripherals = wired.peripherals;
|
Map<String, IPeripheral> oldPeripherals = wired.peripherals;
|
||||||
Map<String, IPeripheral> newPeripherals = wired.element.getPeripherals();
|
|
||||||
WiredNetworkChange change = WiredNetworkChange.changeOf( oldPeripherals, newPeripherals );
|
WiredNetworkChange change = WiredNetworkChange.changeOf( oldPeripherals, newPeripherals );
|
||||||
if( change.isEmpty() ) return;
|
if( change.isEmpty() ) return;
|
||||||
|
|
||||||
wired.peripherals = newPeripherals;
|
wired.peripherals = ImmutableMap.copyOf( newPeripherals );
|
||||||
|
|
||||||
// Detach the old peripherals then remove them.
|
// Detach the old peripherals then remove them.
|
||||||
peripherals.keySet().removeAll( change.peripheralsRemoved().keySet() );
|
peripherals.keySet().removeAll( change.peripheralsRemoved().keySet() );
|
||||||
|
@ -23,7 +23,6 @@ import org.junit.Test;
|
|||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
@ -379,17 +378,10 @@ public class NetworkTest
|
|||||||
remotePeripherals.putAll( change.peripheralsAdded() );
|
remotePeripherals.putAll( change.peripheralsAdded() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public Map<String, IPeripheral> getPeripherals()
|
|
||||||
{
|
|
||||||
return Collections.unmodifiableMap( localPeripherals );
|
|
||||||
}
|
|
||||||
|
|
||||||
public NetworkElement addPeripheral( String name )
|
public NetworkElement addPeripheral( String name )
|
||||||
{
|
{
|
||||||
localPeripherals.put( name, new NetworkPeripheral() );
|
localPeripherals.put( name, new NetworkPeripheral() );
|
||||||
getNode().invalidate();
|
getNode().updatePeripherals( localPeripherals );
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user