Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pipe fixes #1713

Merged
merged 8 commits into from
Sep 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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