1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-01-26 08:56:54 +00:00

Convert wired elements to capabilities

See #18
This commit is contained in:
SquidDev 2018-03-24 11:57:36 +00:00
parent 36878e75b7
commit 043d5f00ca
11 changed files with 123 additions and 144 deletions

View File

@ -16,7 +16,6 @@ import dan200.computercraft.api.media.IMediaProvider;
import dan200.computercraft.api.network.IPacketNetwork;
import dan200.computercraft.api.network.wired.IWiredElement;
import dan200.computercraft.api.network.wired.IWiredNode;
import dan200.computercraft.api.network.wired.IWiredProvider;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.api.peripheral.IPeripheralProvider;
import dan200.computercraft.api.permissions.ITurtlePermissionProvider;
@ -61,6 +60,7 @@ import dan200.computercraft.shared.turtle.blocks.BlockTurtle;
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
import dan200.computercraft.shared.turtle.upgrades.*;
import dan200.computercraft.shared.util.*;
import dan200.computercraft.shared.wired.CapabilityWiredElement;
import dan200.computercraft.shared.wired.WiredNode;
import io.netty.buffer.Unpooled;
import net.minecraft.entity.Entity;
@ -69,6 +69,7 @@ import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketBuffer;
import net.minecraft.server.MinecraftServer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.NonNullList;
@ -266,7 +267,6 @@ public class ComputerCraft
private static List<ITurtlePermissionProvider> permissionProviders = new ArrayList<>();
private static final Map<String, IPocketUpgrade> pocketUpgrades = new HashMap<>();
private static final Set<ILuaAPIFactory> apiFactories = new LinkedHashSet<>();
private static final Set<IWiredProvider> wiredProviders = new LinkedHashSet<>();
// Implementation
@Mod.Instance( value = ComputerCraft.MOD_ID )
@ -733,11 +733,6 @@ public class ComputerCraft
}
}
public static void registerWiredProvider( IWiredProvider provider )
{
if( provider != null ) wiredProviders.add( provider );
}
public static IWiredNode createWiredNodeForElement( IWiredElement element )
{
return new WiredNode( element );
@ -766,20 +761,10 @@ public class ComputerCraft
public static IWiredElement getWiredElementAt( IBlockAccess world, BlockPos pos, EnumFacing side )
{
// Try the handlers in order:
for( IWiredProvider provider : wiredProviders )
{
try
{
IWiredElement element = provider.getElement( world, pos, side );
if( element != null ) return element;
}
catch( Exception e )
{
ComputerCraft.log.error( "Wired element provider " + provider + " errored.", e );
}
}
return null;
TileEntity tile = world.getTileEntity( pos );
return tile != null && tile.hasCapability( CapabilityWiredElement.CAPABILITY, side )
? tile.getCapability( CapabilityWiredElement.CAPABILITY, side )
: null;
}
public static int getDefaultBundledRedstoneOutput( World world, BlockPos pos, EnumFacing side )

View File

@ -14,7 +14,6 @@ import dan200.computercraft.api.media.IMediaProvider;
import dan200.computercraft.api.network.IPacketNetwork;
import dan200.computercraft.api.network.wired.IWiredElement;
import dan200.computercraft.api.network.wired.IWiredNode;
import dan200.computercraft.api.network.wired.IWiredProvider;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.api.peripheral.IPeripheralProvider;
@ -332,26 +331,6 @@ public final class ComputerCraftAPI
}
}
/**
* Registers a peripheral handler to convert blocks into {@link IPeripheral} implementations.
*
* @param handler The peripheral provider to register.
* @see dan200.computercraft.api.peripheral.IPeripheral
* @see dan200.computercraft.api.peripheral.IPeripheralProvider
*/
public static void registerWiredProvider( @Nonnull IWiredProvider handler )
{
findCC();
if ( computerCraft_registerWiredProvider != null)
{
try {
computerCraft_registerWiredProvider.invoke( null, handler );
} catch (Exception e){
// It failed
}
}
}
/**
* Construct a new wired node for a given wired element
*
@ -453,9 +432,6 @@ public final class ComputerCraftAPI
computerCraft_registerAPIFactory = findCCMethod( "registerAPIFactory", new Class<?>[] {
ILuaAPIFactory.class
} );
computerCraft_registerWiredProvider = findCCMethod( "registerWiredProvider", new Class<?>[] {
IWiredProvider.class
} );
computerCraft_createWiredNodeForElement = findCCMethod( "createWiredNodeForElement", new Class<?>[] {
IWiredElement.class
} );
@ -499,7 +475,6 @@ public final class ComputerCraftAPI
private static Method computerCraft_registerPocketUpgrade = null;
private static Method computerCraft_getWirelessNetwork = null;
private static Method computerCraft_registerAPIFactory = null;
private static Method computerCraft_registerWiredProvider = null;
private static Method computerCraft_createWiredNodeForElement = null;
private static Method computerCraft_getWiredElementAt = null;
}

View File

@ -14,12 +14,8 @@ import java.util.Map;
* as a proxy for all network objects. Whilst the node may change networks, an element's node should remain constant
* for its lifespan.
*
* Elements are generally tied to a block or tile entity in world. One should either register an {@link IWiredProvider}
* or implement {@link IWiredElementTile} on your tile entity.
*
* @see IWiredProvider
* @see ComputerCraftAPI#registerWiredProvider(IWiredProvider)
* @see IWiredElementTile
* Elements are generally tied to a block or tile entity in world. In such as case, one should provide the
* {@link IWiredElement} capability for the appropriate sides.
*/
public interface IWiredElement extends IWiredSender
{

View File

@ -1,22 +0,0 @@
package dan200.computercraft.api.network.wired;
import net.minecraft.util.EnumFacing;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* A {@link net.minecraft.tileentity.TileEntity} which provides a {@link IWiredElement}. This acts
* as a simpler alternative to a full-blown {@link IWiredProvider}.
*/
public interface IWiredElementTile
{
/**
* Get the wired element of this tile for a given side.
*
* @param side The side to get the network element from.
* @return A network element, or {@code null} if there is no element here.
*/
@Nullable
IWiredElement getWiredElement( @Nonnull EnumFacing side );
}

View File

@ -1,29 +0,0 @@
package dan200.computercraft.api.network.wired;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* Fetch or create an {@link IWiredElement} for a block at a given position.
*
* @see dan200.computercraft.api.ComputerCraftAPI#registerWiredProvider(IWiredProvider)
* @see IWiredElementTile
*/
@FunctionalInterface
public interface IWiredProvider
{
/**
* Extract a wired network element from a block location.
*
* @param world The world the block is in.
* @param pos The position the block is at.
* @param side The side to get the network element from.
* @return A network element, or {@code null} if there is not an element here you'd like to handle.
*/
@Nullable
IWiredElement getElement( @Nonnull IBlockAccess world, @Nonnull BlockPos pos, @Nonnull EnumFacing side );
}

View File

@ -18,7 +18,7 @@ import dan200.computercraft.shared.peripheral.common.BlockCableModemVariant;
import dan200.computercraft.shared.peripheral.common.PeripheralItemFactory;
import dan200.computercraft.shared.util.IDAssigner;
import dan200.computercraft.shared.util.PeripheralUtil;
import dan200.computercraft.api.network.wired.IWiredElementTile;
import dan200.computercraft.shared.wired.CapabilityWiredElement;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
@ -31,6 +31,7 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.Capability;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@ -39,7 +40,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
public class TileCable extends TileModemBase implements IWiredElementTile
public class TileCable extends TileModemBase
{
public static final double MIN = 0.375;
public static final double MAX = 1 - MIN;
@ -488,9 +489,10 @@ public class TileCable extends TileModemBase implements IWiredElementTile
BlockPos current = getPos();
for( EnumFacing facing : EnumFacing.VALUES )
{
if( !world.isBlockLoaded( pos ) ) continue;
IWiredElement element = ComputerCraft.getWiredElementAt( world, current.offset( facing ), facing.getOpposite() );
BlockPos offset = current.offset( facing );
if( !world.isBlockLoaded( offset ) ) continue;
IWiredElement element = ComputerCraft.getWiredElementAt( world, offset, facing.getOpposite() );
if( element == null ) continue;
if( BlockCable.canConnectIn( state, facing ) )
@ -597,13 +599,25 @@ public class TileCable extends TileModemBase implements IWiredElementTile
return true;
}
// IWiredElement tile
// IWiredElement capability
@Override
public boolean hasCapability( @Nonnull Capability<?> capability, @Nullable EnumFacing facing )
{
if( capability == CapabilityWiredElement.CAPABILITY ) return BlockCable.canConnectIn( getBlockState(), facing );
return super.hasCapability( capability, facing );
}
@Nullable
@Override
public IWiredElement getWiredElement( @Nonnull EnumFacing side )
public <T> T getCapability( @Nonnull Capability<T> capability, @Nullable EnumFacing facing )
{
return BlockCable.canConnectIn( getBlockState(), side ) ? m_cable : null;
if( capability == CapabilityWiredElement.CAPABILITY )
{
return BlockCable.canConnectIn( getBlockState(), facing ) ? CapabilityWiredElement.CAPABILITY.cast( m_cable ) : null;
}
return super.getCapability( capability, facing );
}
// IPeripheralTile

View File

@ -9,12 +9,12 @@ package dan200.computercraft.shared.peripheral.modem;
import com.google.common.base.Objects;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.network.wired.IWiredElement;
import dan200.computercraft.api.network.wired.IWiredElementTile;
import dan200.computercraft.api.network.wired.IWiredNode;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.shared.peripheral.common.BlockCable;
import dan200.computercraft.shared.peripheral.common.TilePeripheralBase;
import dan200.computercraft.shared.util.IDAssigner;
import dan200.computercraft.shared.wired.CapabilityWiredElement;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumFacing;
@ -23,13 +23,15 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.Constants;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.File;
import java.util.*;
public class TileWiredModemFull extends TilePeripheralBase implements IWiredElementTile
public class TileWiredModemFull extends TilePeripheralBase
{
private static class FullElement extends WiredModemElement
{
@ -310,9 +312,10 @@ public class TileWiredModemFull extends TilePeripheralBase implements IWiredElem
BlockPos current = getPos();
for( EnumFacing facing : EnumFacing.VALUES )
{
if( !world.isBlockLoaded( pos ) ) continue;
BlockPos offset = current.offset( facing );
if( !world.isBlockLoaded( offset ) ) continue;
IWiredElement element = ComputerCraft.getWiredElementAt( world, current.offset( facing ), facing.getOpposite() );
IWiredElement element = ComputerCraft.getWiredElementAt( world, offset, facing.getOpposite() );
if( element == null ) continue;
// If we can connect to it then do so
@ -385,11 +388,22 @@ public class TileWiredModemFull extends TilePeripheralBase implements IWiredElem
// IWiredElementTile
@Nonnull
@Override
public IWiredElement getWiredElement( @Nonnull EnumFacing side )
public boolean hasCapability( @Nonnull Capability<?> capability, @Nullable EnumFacing facing )
{
return m_element;
return capability == CapabilityWiredElement.CAPABILITY || super.hasCapability( capability, facing );
}
@Nullable
@Override
public <T> T getCapability( @Nonnull Capability<T> capability, @Nullable EnumFacing facing )
{
if( capability == CapabilityWiredElement.CAPABILITY )
{
return CapabilityWiredElement.CAPABILITY.cast( m_element );
}
return super.getCapability( capability, facing );
}
// IPeripheralTile

View File

@ -1,7 +1,7 @@
package dan200.computercraft.shared.peripheral.modem;
import dan200.computercraft.api.network.wired.IWiredNetworkChange;
import dan200.computercraft.api.network.wired.IWiredElement;
import dan200.computercraft.api.network.wired.IWiredNetworkChange;
import dan200.computercraft.api.network.wired.IWiredNode;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.shared.wired.WiredNode;

View File

@ -49,7 +49,7 @@ import dan200.computercraft.shared.pocket.recipes.PocketComputerUpgradeRecipe;
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
import dan200.computercraft.shared.turtle.inventory.ContainerTurtle;
import dan200.computercraft.shared.util.*;
import dan200.computercraft.shared.wired.DefaultWiredProvider;
import dan200.computercraft.shared.wired.CapabilityWiredElement;
import net.minecraft.block.Block;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
@ -485,7 +485,7 @@ public abstract class ComputerCraftProxyCommon implements IComputerCraftProxy
ComputerCraftAPI.registerMediaProvider( new DefaultMediaProvider() );
// Register network providers
ComputerCraftAPI.registerWiredProvider( new DefaultWiredProvider() );
CapabilityWiredElement.register();
}
private void registerForgeHandlers()

View File

@ -0,0 +1,69 @@
package dan200.computercraft.shared.wired;
import dan200.computercraft.api.network.wired.IWiredElement;
import dan200.computercraft.api.network.wired.IWiredNode;
import net.minecraft.nbt.NBTBase;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityInject;
import net.minecraftforge.common.capabilities.CapabilityManager;
import javax.annotation.Nonnull;
public class CapabilityWiredElement
{
@CapabilityInject( IWiredElement.class )
public static Capability<IWiredElement> CAPABILITY = null;
public static void register()
{
CapabilityManager.INSTANCE.register( IWiredElement.class, new NullStorage(), NullElement::new );
}
private static class NullElement implements IWiredElement
{
@Nonnull
@Override
public IWiredNode getNode()
{
throw new IllegalStateException( "Should not use the default element implementation" );
}
@Nonnull
@Override
public World getWorld()
{
throw new IllegalStateException( "Should not use the default element implementation" );
}
@Nonnull
@Override
public Vec3d getPosition()
{
throw new IllegalStateException( "Should not use the default element implementation" );
}
@Nonnull
@Override
public String getSenderID()
{
throw new IllegalStateException( "Should not use the default element implementation" );
}
}
private static class NullStorage implements Capability.IStorage<IWiredElement>
{
@Override
public NBTBase writeNBT( Capability<IWiredElement> capability, IWiredElement instance, EnumFacing side )
{
return null;
}
@Override
public void readNBT( Capability<IWiredElement> capability, IWiredElement instance, EnumFacing side, NBTBase base )
{
}
}
}

View File

@ -1,23 +0,0 @@
package dan200.computercraft.shared.wired;
import dan200.computercraft.api.network.wired.IWiredElement;
import dan200.computercraft.api.network.wired.IWiredElementTile;
import dan200.computercraft.api.network.wired.IWiredProvider;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class DefaultWiredProvider implements IWiredProvider
{
@Nullable
@Override
public IWiredElement getElement( @Nonnull IBlockAccess world, @Nonnull BlockPos pos, @Nonnull EnumFacing side )
{
TileEntity te = world.getTileEntity( pos );
return te instanceof IWiredElementTile ? ((IWiredElementTile) te).getWiredElement( side ) : null;
}
}