1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-11-16 21:27:10 +00:00

Allow generic peripherals to specify a custom source

- Add a new GenericPeripheral interface. We don't strictly speaking
   need this - could put this on GenericSource - but the separation
   seems cleaner.

 - GenericPeripheral.getType() returns a new PeripheralType class, which
   can either be untyped() or specify a type name. This is a little
   over-engineered (could just be a nullable string), but I'm planning
   to allow multiple types in the future, so want some level of
   future-proofing.

 - Thread this PeripheralType through the method gathering code and
   expose it to the GenericPeripheralProvider, which then chooses an
   appropriate name.

   This is a little ugly (we're leaking information about peripherals
   everywhere), but I think is fine for now. It's all private internals
   after all!

Closes #830
This commit is contained in:
Jonathan Coates
2021-11-22 18:05:13 +00:00
parent 070479d901
commit f33f57ea35
7 changed files with 191 additions and 37 deletions

View File

@@ -25,11 +25,11 @@ class GenericPeripheral implements IDynamicPeripheral
private final TileEntity tile;
private final List<SaturatedMethod> methods;
GenericPeripheral( TileEntity tile, List<SaturatedMethod> methods )
GenericPeripheral( TileEntity tile, String name, List<SaturatedMethod> methods )
{
ResourceLocation type = tile.getType().getRegistryName();
this.tile = tile;
this.type = type == null ? "unknown" : type.toString();
this.type = name != null ? name : (type != null ? type.toString() : "unknown");
this.methods = methods;
}

View File

@@ -6,6 +6,7 @@
package dan200.computercraft.shared.peripheral.generic;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.api.peripheral.PeripheralType;
import dan200.computercraft.core.asm.NamedMethod;
import dan200.computercraft.core.asm.PeripheralMethod;
import net.minecraft.tileentity.TileEntity;
@@ -38,10 +39,10 @@ public class GenericPeripheralProvider
TileEntity tile = world.getBlockEntity( pos );
if( tile == null ) return null;
ArrayList<SaturatedMethod> saturated = new ArrayList<>( 0 );
GenericPeripheralBuilder saturated = new GenericPeripheralBuilder();
List<NamedMethod<PeripheralMethod>> tileMethods = PeripheralMethod.GENERATOR.getMethods( tile.getClass() );
if( !tileMethods.isEmpty() ) addSaturated( saturated, tile, tileMethods );
if( !tileMethods.isEmpty() ) saturated.addMethods( tile, tileMethods );
for( Capability<?> capability : capabilities )
{
@@ -50,20 +51,44 @@ public class GenericPeripheralProvider
List<NamedMethod<PeripheralMethod>> capabilityMethods = PeripheralMethod.GENERATOR.getMethods( contents.getClass() );
if( capabilityMethods.isEmpty() ) return;
addSaturated( saturated, contents, capabilityMethods );
saturated.addMethods( contents, capabilityMethods );
wrapper.addListener( cast( invalidate ) );
} );
}
return saturated.isEmpty() ? null : new GenericPeripheral( tile, saturated );
return saturated.toPeripheral( tile );
}
private static void addSaturated( ArrayList<SaturatedMethod> saturated, Object target, List<NamedMethod<PeripheralMethod>> methods )
private static class GenericPeripheralBuilder
{
saturated.ensureCapacity( saturated.size() + methods.size() );
for( NamedMethod<PeripheralMethod> method : methods )
String name;
final ArrayList<SaturatedMethod> methods = new ArrayList<>( 0 );
IPeripheral toPeripheral( TileEntity tile )
{
saturated.add( new SaturatedMethod( target, method ) );
if( methods.isEmpty() ) return null;
methods.trimToSize();
return new GenericPeripheral( tile, name, methods );
}
void addMethods( Object target, List<NamedMethod<PeripheralMethod>> methods )
{
ArrayList<SaturatedMethod> saturatedMethods = this.methods;
saturatedMethods.ensureCapacity( saturatedMethods.size() + methods.size() );
for( NamedMethod<PeripheralMethod> method : methods )
{
saturatedMethods.add( new SaturatedMethod( target, method ) );
// If we have a peripheral type, use it. Always pick the smallest one, so it's consistent (assuming mods
// don't change).
PeripheralType type = method.getGenericType();
if( type != null && type.getPrimaryType() != null )
{
String name = type.getPrimaryType();
if( this.name == null || this.name.compareTo( name ) > 0 ) this.name = name;
}
}
}
}