mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-01-11 18:00:29 +00:00
Don't use capabilities for generic peripherals
Maybe the capability system was a mistake in retrospect, as we don't store the peripheral outside, so there's no way to reuse it. That will probably come in a later change. As a smaller fix, we pass the invalidate listener directly. The lifetime of this is the same as the computer, so we don't create a new one each time. There's still the potential to leak memory if people break/replace a computer (as listeners aren't removed), but that's an unavoidable flaw with capabilities. Fixes #593
This commit is contained in:
parent
d83a68f3ff
commit
737b3cb576
@ -67,7 +67,7 @@ public final class Peripherals
|
||||
}
|
||||
}
|
||||
|
||||
return CapabilityUtil.unwrap( GenericPeripheralProvider.getPeripheral( world, pos, side ), invalidate );
|
||||
return GenericPeripheralProvider.getPeripheral( world, pos, side, invalidate );
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -39,6 +39,8 @@ import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
import net.minecraft.util.text.TranslationTextComponent;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.common.util.NonNullConsumer;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
@ -56,6 +58,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
||||
private boolean m_on = false;
|
||||
boolean m_startOn = false;
|
||||
private boolean m_fresh = false;
|
||||
private final NonNullConsumer<LazyOptional<IPeripheral>>[] invalidate;
|
||||
|
||||
private final ComputerFamily family;
|
||||
|
||||
@ -63,6 +66,14 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
||||
{
|
||||
super( type );
|
||||
this.family = family;
|
||||
|
||||
// We cache these so we can guarantee we only ever register one listener for adjacent capabilities.
|
||||
@SuppressWarnings( { "unchecked", "rawtypes" } )
|
||||
NonNullConsumer<LazyOptional<IPeripheral>>[] invalidate = this.invalidate = new NonNullConsumer[6];
|
||||
for( Direction direction : Direction.values() )
|
||||
{
|
||||
invalidate[direction.ordinal()] = o -> updateInput( direction );
|
||||
}
|
||||
}
|
||||
|
||||
protected void unload()
|
||||
@ -225,7 +236,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
||||
computer.setBundledRedstoneInput( localDir, BundledRedstone.getOutput( getWorld(), offset, offsetSide ) );
|
||||
if( !isPeripheralBlockedOnSide( localDir ) )
|
||||
{
|
||||
IPeripheral peripheral = Peripherals.getPeripheral( getWorld(), offset, offsetSide, o -> updateInput( dir ) );
|
||||
IPeripheral peripheral = Peripherals.getPeripheral( getWorld(), offset, offsetSide, invalidate[dir.ordinal()] );
|
||||
computer.setPeripheral( localDir, peripheral );
|
||||
}
|
||||
}
|
||||
|
@ -15,11 +15,13 @@ import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.common.util.NonNullConsumer;
|
||||
import net.minecraftforge.energy.CapabilityEnergy;
|
||||
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ -31,14 +33,13 @@ public class GenericPeripheralProvider
|
||||
CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY,
|
||||
};
|
||||
|
||||
@Nonnull
|
||||
public static LazyOptional<IPeripheral> getPeripheral( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side )
|
||||
@Nullable
|
||||
public static IPeripheral getPeripheral( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side, NonNullConsumer<LazyOptional<IPeripheral>> invalidate )
|
||||
{
|
||||
TileEntity tile = world.getTileEntity( pos );
|
||||
if( tile == null ) return LazyOptional.empty();
|
||||
if( tile == null ) return null;
|
||||
|
||||
ArrayList<SaturatedMethod> saturated = new ArrayList<>( 0 );
|
||||
LazyOptional<IPeripheral> peripheral = LazyOptional.of( () -> new GenericPeripheral( tile, saturated ) );
|
||||
|
||||
List<NamedMethod<PeripheralMethod>> tileMethods = PeripheralMethod.GENERATOR.getMethods( tile.getClass() );
|
||||
if( !tileMethods.isEmpty() ) addSaturated( saturated, tile, tileMethods );
|
||||
@ -51,11 +52,11 @@ public class GenericPeripheralProvider
|
||||
if( capabilityMethods.isEmpty() ) return;
|
||||
|
||||
addSaturated( saturated, contents, capabilityMethods );
|
||||
wrapper.addListener( x -> peripheral.invalidate() );
|
||||
wrapper.addListener( cast( invalidate ) );
|
||||
} );
|
||||
}
|
||||
|
||||
return saturated.isEmpty() ? LazyOptional.empty() : peripheral;
|
||||
return saturated.isEmpty() ? null : new GenericPeripheral( tile, saturated );
|
||||
}
|
||||
|
||||
private static void addSaturated( ArrayList<SaturatedMethod> saturated, Object target, List<NamedMethod<PeripheralMethod>> methods )
|
||||
@ -66,4 +67,10 @@ public class GenericPeripheralProvider
|
||||
saturated.add( new SaturatedMethod( target, method ) );
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings( { "unchecked", "rawtypes" } )
|
||||
private static <T> NonNullConsumer<T> cast( NonNullConsumer<?> consumer )
|
||||
{
|
||||
return (NonNullConsumer) consumer;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user