Skip to content

Commit

Permalink
Pipe fixes (#1713)
Browse files Browse the repository at this point in the history
  • Loading branch information
brachy84 authored and serenibyss committed Nov 23, 2023
1 parent ebe06ec commit 14a906b
Show file tree
Hide file tree
Showing 12 changed files with 172 additions and 189 deletions.
66 changes: 0 additions & 66 deletions src/main/java/gregtech/api/pipenet/PipeGatherer.java

This file was deleted.

53 changes: 30 additions & 23 deletions src/main/java/gregtech/api/pipenet/PipeNetWalker.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@
* <p><b>Do not walk a walker more than once</b>
* <p>For example implementations look at {@link ItemNetWalker}
*/
public abstract class PipeNetWalker {
public abstract class PipeNetWalker<T extends IPipeTile<?, ?>> {

private PipeNetWalker root;
private PipeNetWalker<T> root;
private final World world;
private final Set<Long> walked = new HashSet<>();
private final List<EnumFacing> pipes = new ArrayList<>();
private List<PipeNetWalker> walkers;
private List<PipeNetWalker<T>> walkers;
private final BlockPos.MutableBlockPos currentPos;
private int walkedBlocks;
private boolean invalid;
Expand All @@ -48,15 +48,15 @@ protected PipeNetWalker(World world, BlockPos sourcePipe, int walkedBlocks) {
* @param walkedBlocks distance from source in blocks
* @return new sub walker
*/
protected abstract PipeNetWalker createSubWalker(World world, EnumFacing facingToNextPos, BlockPos nextPos, int walkedBlocks);
protected abstract PipeNetWalker<T> createSubWalker(World world, EnumFacing facingToNextPos, BlockPos nextPos, int walkedBlocks);

/**
* You can increase walking stats here. for example
*
* @param pipeTile current checking pipe
* @param pos current pipe pos
*/
protected abstract void checkPipe(IPipeTile<?, ?> pipeTile, BlockPos pos);
protected abstract void checkPipe(T pipeTile, BlockPos pos);

/**
* Checks the neighbour of the current pos
Expand All @@ -65,7 +65,7 @@ protected PipeNetWalker(World world, BlockPos sourcePipe, int walkedBlocks) {
* @param faceToNeighbour face to neighbour
* @param neighbourTile neighbour tile
*/
protected abstract void checkNeighbour(IPipeTile<?, ?> pipeTile, BlockPos pipePos, EnumFacing faceToNeighbour, @Nullable TileEntity neighbourTile);
protected abstract void checkNeighbour(T pipeTile, BlockPos pipePos, EnumFacing faceToNeighbour, @Nullable TileEntity neighbourTile);

/**
* If the pipe is valid to perform a walk on
Expand All @@ -76,7 +76,11 @@ protected PipeNetWalker(World world, BlockPos sourcePipe, int walkedBlocks) {
* @param faceToNeighbour face to pipeTile
* @return if the pipe is valid
*/
protected abstract boolean isValidPipe(IPipeTile<?, ?> currentPipe, IPipeTile<?, ?> neighbourPipe, BlockPos pipePos, EnumFacing faceToNeighbour);
protected boolean isValidPipe(T currentPipe, T neighbourPipe, BlockPos pipePos, EnumFacing faceToNeighbour) {
return true;
}

protected abstract Class<T> getBasePipeClass();

/**
* The directions that this net can traverse from this pipe
Expand All @@ -92,7 +96,7 @@ protected EnumFacing[] getSurroundingPipeSides() {
*
* @param subWalker the finished sub walker
*/
protected void onRemoveSubWalker(PipeNetWalker subWalker) {
protected void onRemoveSubWalker(PipeNetWalker<T> subWalker) {
}

public void traversePipeNet() {
Expand Down Expand Up @@ -120,7 +124,10 @@ public void traversePipeNet(int maxWalks) {

private boolean walk() {
if (walkers == null) {
checkPos();
if (!checkPos()) {
this.root.failed = true;
return true;
}

if (pipes.size() == 0)
return true;
Expand All @@ -132,14 +139,14 @@ private boolean walk() {

walkers = new ArrayList<>();
for (EnumFacing side : pipes) {
PipeNetWalker walker = Objects.requireNonNull(createSubWalker(world, side, currentPos.offset(side), walkedBlocks + 1), "Walker can't be null");
PipeNetWalker<T> walker = Objects.requireNonNull(createSubWalker(world, side, currentPos.offset(side), walkedBlocks + 1), "Walker can't be null");
walker.root = root;
walkers.add(walker);
}
}
Iterator<PipeNetWalker> iterator = walkers.iterator();
Iterator<PipeNetWalker<T>> iterator = walkers.iterator();
while (iterator.hasNext()) {
PipeNetWalker walker = iterator.next();
PipeNetWalker<T> walker = iterator.next();
if (walker.walk()) {
onRemoveSubWalker(walker);
iterator.remove();
Expand All @@ -149,19 +156,17 @@ private boolean walk() {
return !isRunning() || walkers.size() == 0;
}

private void checkPos() {
private boolean checkPos() {
pipes.clear();
TileEntity thisPipe = world.getTileEntity(currentPos);
IPipeTile<?, ?> pipeTile = (IPipeTile<?, ?>) thisPipe;
if (pipeTile == null) {
if (walkedBlocks == 1) {
// if it is the first block, it wasn't already checked
GTLog.logger.error("First PipeTile is null during walk at {}", currentPos);
this.failed = true;
return;
} else
throw new IllegalStateException("PipeTile was not null last walk, but now is");
if (!(thisPipe instanceof IPipeTile<?, ?>)) {
GTLog.logger.fatal("PipeWalker expected a pipe, but found {} at {}", thisPipe, currentPos);
return false;
}
if (!getBasePipeClass().isAssignableFrom(thisPipe.getClass())) {
return false;
}
T pipeTile = (T) thisPipe;
checkPipe(pipeTile, currentPos);
root.walked.add(pipeTile.getPipePos().toLong());

Expand All @@ -174,7 +179,8 @@ private void checkPos() {

pos.setPos(currentPos).move(accessSide);
TileEntity tile = world.getTileEntity(pos);
if (tile instanceof IPipeTile<?, ?> otherPipe) {
if (tile != null && getBasePipeClass().isAssignableFrom(tile.getClass())) {
T otherPipe = (T) tile;
if (!otherPipe.isConnected(accessSide.getOpposite()) || otherPipe.isFaceBlocked(accessSide.getOpposite()) || isWalked(otherPipe))
continue;
if (isValidPipe(pipeTile, otherPipe, currentPos, accessSide)) {
Expand All @@ -185,6 +191,7 @@ private void checkPos() {
checkNeighbour(pipeTile, currentPos, accessSide, tile);
}
pos.release();
return true;
}

protected boolean isWalked(IPipeTile<?, ?> pipe) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import gregtech.api.capability.GregtechCapabilities;
import gregtech.api.capability.IEnergyContainer;
import gregtech.api.pipenet.PipeNetWalker;
import gregtech.api.pipenet.tile.IPipeTile;
import gregtech.common.pipelike.cable.tile.TileEntityCable;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
Expand All @@ -15,9 +14,12 @@
import java.util.ArrayList;
import java.util.List;

public class EnergyNetWalker extends PipeNetWalker {
public class EnergyNetWalker extends PipeNetWalker<TileEntityCable> {

public static List<RoutePath> createNetData(World world, BlockPos sourcePipe) {
if (!(world.getTileEntity(sourcePipe) instanceof TileEntityCable)) {
return null;
}
EnergyNetWalker walker = new EnergyNetWalker(world, sourcePipe, 1, new ArrayList<>());
walker.traversePipeNet();
return walker.isFailed() ? null : walker.routes;
Expand All @@ -33,21 +35,21 @@ protected EnergyNetWalker(World world, BlockPos sourcePipe, int walkedBlocks, Li
}

@Override
protected PipeNetWalker createSubWalker(World world, EnumFacing facingToNextPos, BlockPos nextPos, int walkedBlocks) {
protected PipeNetWalker<TileEntityCable> createSubWalker(World world, EnumFacing facingToNextPos, BlockPos nextPos, int walkedBlocks) {
EnergyNetWalker walker = new EnergyNetWalker(world, nextPos, walkedBlocks, routes);
walker.loss = loss;
walker.pipes = pipes;
return walker;
}

@Override
protected void checkPipe(IPipeTile<?, ?> pipeTile, BlockPos pos) {
pipes = ArrayUtils.add(pipes, (TileEntityCable) pipeTile);
loss += ((TileEntityCable) pipeTile).getNodeData().getLossPerBlock();
protected void checkPipe(TileEntityCable pipeTile, BlockPos pos) {
pipes = ArrayUtils.add(pipes, pipeTile);
loss += pipeTile.getNodeData().getLossPerBlock();
}

@Override
protected void checkNeighbour(IPipeTile<?, ?> pipeTile, BlockPos pipePos, EnumFacing faceToNeighbour, @Nullable TileEntity neighbourTile) {
protected void checkNeighbour(TileEntityCable pipeTile, BlockPos pipePos, EnumFacing faceToNeighbour, @Nullable TileEntity neighbourTile) {
if (neighbourTile != null) {
IEnergyContainer container = neighbourTile.getCapability(GregtechCapabilities.CAPABILITY_ENERGY_CONTAINER, faceToNeighbour.getOpposite());
if (container != null) {
Expand All @@ -57,7 +59,7 @@ protected void checkNeighbour(IPipeTile<?, ?> pipeTile, BlockPos pipePos, EnumFa
}

@Override
protected boolean isValidPipe(IPipeTile<?, ?> currentPipe, IPipeTile<?, ?> neighbourPipe, BlockPos pipePos, EnumFacing faceToNeighbour) {
return neighbourPipe instanceof TileEntityCable;
protected Class<TileEntityCable> getBasePipeClass() {
return TileEntityCable.class;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@ public class AveragingPerTickCounter {
private boolean dirty = true;
private double lastAverage = 0;

public AveragingPerTickCounter() {
this(0, 20);
}

/**
* Averages a value over a certain amount of ticks
*
* @param defaultValue self explanatory
* @param defaultValue self-explanatory
* @param length amount of ticks to average (20 for 1 second)
*/
public AveragingPerTickCounter(long defaultValue, int length) {
Expand All @@ -26,10 +30,11 @@ public AveragingPerTickCounter(long defaultValue, int length) {
}

private void checkValueState(World world) {
if (world == null) return;
long currentWorldTime = world.getTotalWorldTime();
if (currentWorldTime != lastUpdatedWorldTime) {
long dif = currentWorldTime - lastUpdatedWorldTime;
if (dif >= values.length) {
if (dif >= values.length || dif < 0) {
Arrays.fill(values, defaultValue);
currentIndex = 0;
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
package gregtech.api.util;
package gregtech.common.pipelike.cable.tile;

import net.minecraft.world.World;

public class PerTickLongCounter {

private final long defaultValue;

private long lastUpdatedWorldTime;

private long lastValue;
private long currentValue;

public PerTickLongCounter() {
this(0);
}

public PerTickLongCounter(long defaultValue) {
this.defaultValue = defaultValue;
this.currentValue = defaultValue;
this.lastValue = defaultValue;
}

private void checkValueState(World world) {
if (world == null) return;
long currentWorldTime = world.getTotalWorldTime();
if (currentWorldTime != lastUpdatedWorldTime) {
if (currentWorldTime == lastUpdatedWorldTime + 1) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import gregtech.api.pipenet.block.BlockPipe;
import gregtech.api.pipenet.block.material.TileEntityMaterialPipeBase;
import gregtech.api.unification.material.properties.WireProperties;
import gregtech.api.util.PerTickLongCounter;
import gregtech.api.util.TaskScheduler;
import gregtech.api.util.TextFormattingUtil;
import gregtech.client.particle.GTOverheatParticle;
Expand Down Expand Up @@ -44,11 +43,11 @@ public class TileEntityCable extends TileEntityMaterialPipeBase<Insulation, Wire
private static final int meltTemp = 3000;

private final EnumMap<EnumFacing, EnergyNetHandler> handlers = new EnumMap<>(EnumFacing.class);
private final PerTickLongCounter maxVoltageCounter = new PerTickLongCounter(0);
private final AveragingPerTickCounter averageVoltageCounter = new AveragingPerTickCounter(0, 20);
private final AveragingPerTickCounter averageAmperageCounter = new AveragingPerTickCounter(0, 20);
private final PerTickLongCounter maxVoltageCounter = new PerTickLongCounter();
private final AveragingPerTickCounter averageVoltageCounter = new AveragingPerTickCounter();
private final AveragingPerTickCounter averageAmperageCounter = new AveragingPerTickCounter();
private EnergyNetHandler defaultHandler;
// the EnergyNetHandler can only be created on the server so we have a empty placeholder for the client
// the EnergyNetHandler can only be created on the server, so we have an empty placeholder for the client
private final IEnergyContainer clientCapability = IEnergyContainer.DEFAULT;
private WeakReference<EnergyNet> currentEnergyNet = new WeakReference<>(null);
@SideOnly(Side.CLIENT)
Expand All @@ -57,6 +56,10 @@ public class TileEntityCable extends TileEntityMaterialPipeBase<Insulation, Wire
private int temperature = getDefaultTemp();
private boolean isTicking = false;

public long getWorldTime() {
return hasWorld() ? getWorld().getTotalWorldTime() : 0L;
}

@Override
public Class<Insulation> getPipeTypeClass() {
return Insulation.class;
Expand Down Expand Up @@ -100,13 +103,13 @@ public void onLoad() {
* @return if the cable should be destroyed
*/
public boolean incrementAmperage(long amps, long voltage) {
if (voltage > maxVoltageCounter.get(world)) {
maxVoltageCounter.set(world, voltage);
if (voltage > maxVoltageCounter.get(getWorld())) {
maxVoltageCounter.set(getWorld(), voltage);
}
averageVoltageCounter.increment(world, voltage);
averageAmperageCounter.increment(world, amps);
averageVoltageCounter.increment(getWorld(), voltage);
averageAmperageCounter.increment(getWorld(), amps);

int dif = (int) (averageAmperageCounter.getLast(world) - getMaxAmperage());
int dif = (int) (averageAmperageCounter.getLast(getWorld()) - getMaxAmperage());
if (dif > 0) {
applyHeat(dif * 40);
return true;
Expand Down
Loading

0 comments on commit 14a906b

Please sign in to comment.