mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-01-12 02:10:30 +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.StringTextComponent;
|
||||||
import net.minecraft.util.text.TranslationTextComponent;
|
import net.minecraft.util.text.TranslationTextComponent;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.common.util.LazyOptional;
|
||||||
|
import net.minecraftforge.common.util.NonNullConsumer;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@ -56,6 +58,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
|||||||
private boolean m_on = false;
|
private boolean m_on = false;
|
||||||
boolean m_startOn = false;
|
boolean m_startOn = false;
|
||||||
private boolean m_fresh = false;
|
private boolean m_fresh = false;
|
||||||
|
private final NonNullConsumer<LazyOptional<IPeripheral>>[] invalidate;
|
||||||
|
|
||||||
private final ComputerFamily family;
|
private final ComputerFamily family;
|
||||||
|
|
||||||
@ -63,6 +66,14 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
|||||||
{
|
{
|
||||||
super( type );
|
super( type );
|
||||||
this.family = family;
|
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()
|
protected void unload()
|
||||||
@ -225,7 +236,7 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
|||||||
computer.setBundledRedstoneInput( localDir, BundledRedstone.getOutput( getWorld(), offset, offsetSide ) );
|
computer.setBundledRedstoneInput( localDir, BundledRedstone.getOutput( getWorld(), offset, offsetSide ) );
|
||||||
if( !isPeripheralBlockedOnSide( localDir ) )
|
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 );
|
computer.setPeripheral( localDir, peripheral );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,11 +15,13 @@ import net.minecraft.util.math.BlockPos;
|
|||||||
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.LazyOptional;
|
import net.minecraftforge.common.util.LazyOptional;
|
||||||
|
import net.minecraftforge.common.util.NonNullConsumer;
|
||||||
import net.minecraftforge.energy.CapabilityEnergy;
|
import net.minecraftforge.energy.CapabilityEnergy;
|
||||||
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
|
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
|
||||||
import net.minecraftforge.items.CapabilityItemHandler;
|
import net.minecraftforge.items.CapabilityItemHandler;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -31,14 +33,13 @@ public class GenericPeripheralProvider
|
|||||||
CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY,
|
CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY,
|
||||||
};
|
};
|
||||||
|
|
||||||
@Nonnull
|
@Nullable
|
||||||
public static LazyOptional<IPeripheral> getPeripheral( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side )
|
public static IPeripheral getPeripheral( @Nonnull World world, @Nonnull BlockPos pos, @Nonnull Direction side, NonNullConsumer<LazyOptional<IPeripheral>> invalidate )
|
||||||
{
|
{
|
||||||
TileEntity tile = world.getTileEntity( pos );
|
TileEntity tile = world.getTileEntity( pos );
|
||||||
if( tile == null ) return LazyOptional.empty();
|
if( tile == null ) return null;
|
||||||
|
|
||||||
ArrayList<SaturatedMethod> saturated = new ArrayList<>( 0 );
|
ArrayList<SaturatedMethod> saturated = new ArrayList<>( 0 );
|
||||||
LazyOptional<IPeripheral> peripheral = LazyOptional.of( () -> new GenericPeripheral( tile, saturated ) );
|
|
||||||
|
|
||||||
List<NamedMethod<PeripheralMethod>> tileMethods = PeripheralMethod.GENERATOR.getMethods( tile.getClass() );
|
List<NamedMethod<PeripheralMethod>> tileMethods = PeripheralMethod.GENERATOR.getMethods( tile.getClass() );
|
||||||
if( !tileMethods.isEmpty() ) addSaturated( saturated, tile, tileMethods );
|
if( !tileMethods.isEmpty() ) addSaturated( saturated, tile, tileMethods );
|
||||||
@ -51,11 +52,11 @@ public class GenericPeripheralProvider
|
|||||||
if( capabilityMethods.isEmpty() ) return;
|
if( capabilityMethods.isEmpty() ) return;
|
||||||
|
|
||||||
addSaturated( saturated, contents, capabilityMethods );
|
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 )
|
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 ) );
|
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