Rewrite to remove unneeded pathfind call

This commit is contained in:
Timo van Veen 2023-10-24 19:12:15 +02:00
parent 26c9af50a7
commit 67ebc8a2c6
6 changed files with 70 additions and 48 deletions

View file

@ -640,7 +640,7 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
if (lookAhead != null) {
if (spaceDown) {
carriage.train.manualTick = true;
nav.startNavigation(lookAhead, -1, false);
nav.startNavigation(nav.findPathTo(lookAhead, -1));
carriage.train.manualTick = false;
navDistanceTotal = nav.distanceToDestination;
return true;

View file

@ -15,6 +15,9 @@ import java.util.UUID;
import javax.annotation.Nullable;
import com.mojang.logging.LogUtils;
import com.simibubi.create.content.trains.graph.DiscoveredPath;
import org.apache.commons.lang3.mutable.MutableDouble;
import org.apache.commons.lang3.mutable.MutableObject;
@ -380,15 +383,11 @@ public class Navigation {
train.reservedSignalBlocks.clear();
}
public double startNavigation(GlobalStation destination, double maxCost, boolean simulate) {
DiscoveredPath pathTo = findPathTo(destination, maxCost);
public double startNavigation(DiscoveredPath pathTo) {
boolean noneFound = pathTo == null;
double distance = noneFound ? -1 : Math.abs(pathTo.distance);
double cost = noneFound ? -1 : pathTo.cost;
if (simulate)
return cost;
distanceToDestination = distance;
if (noneFound) {
@ -407,10 +406,10 @@ public class Navigation {
train.reservedSignalBlocks.clear();
train.navigation.waitingForSignal = null;
if (this.destination == null && !simulate)
if (this.destination == null)
distanceStartedAt = distance;
if (this.destination == destination)
if (this.destination == pathTo.destination)
return 0;
if (!train.runtime.paused) {
@ -435,16 +434,16 @@ public class Navigation {
train.status.foundConductor();
}
this.destination = destination;
this.destination = pathTo.destination;
return cost;
}
@Nullable
private DiscoveredPath findPathTo(GlobalStation destination, double maxCost) {
public DiscoveredPath findPathTo(GlobalStation destination, double maxCost) {
TrackGraph graph = train.graph;
if (graph == null)
return null;
LogUtils.getLogger().info("finding path");
Couple<DiscoveredPath> results = Couple.create(null, null);
for (boolean forward : Iterate.trueAndFalse) {
@ -486,7 +485,7 @@ public class Navigation {
double position = edge.getLength() - destination.getLocationOn(edge);
double distanceToDestination = distance - position;
results.set(forward, new DiscoveredPath((forward ? 1 : -1) * distanceToDestination, cost, currentPath));
results.set(forward, new DiscoveredPath((forward ? 1 : -1) * distanceToDestination, cost, currentPath, destination));
return true;
});
}
@ -508,18 +507,6 @@ public class Navigation {
return frontBetter ? front : back;
}
public class DiscoveredPath {
List<Couple<TrackNode>> path;
double distance;
double cost;
public DiscoveredPath(double distance, double cost, List<Couple<TrackNode>> path) {
this.distance = distance;
this.cost = cost;
this.path = path;
}
}
public GlobalStation findNearestApproachable(boolean forward) {
TrackGraph graph = train.graph;
if (graph == null)
@ -776,9 +763,9 @@ public class Navigation {
c -> currentPath.add(Couple
.deserializeEach(c.getList("Nodes", Tag.TAG_COMPOUND), c2 -> TrackNodeLocation.read(c2, dimensions))
.map(graph::locateNode)));
removeBrokenPathEntries();
waitingForSignal = tag.contains("BlockingSignal")
? Pair.of(tag.getUUID("BlockingSignal"), tag.getBoolean("BlockingSignalSide"))
: null;
@ -793,7 +780,7 @@ public class Navigation {
* Trains might load or save with null entries in their path, this method avoids
* that anomaly from causing NPEs. The underlying issue has not been found.
*/
boolean nullEntriesPresent = false;
for (Iterator<Couple<TrackNode>> iterator = currentPath.iterator(); iterator.hasNext();) {

View file

@ -17,6 +17,8 @@ import java.util.function.Consumer;
import javax.annotation.Nullable;
import com.simibubi.create.content.trains.graph.DiscoveredPath;
import org.apache.commons.lang3.mutable.MutableBoolean;
import org.apache.commons.lang3.mutable.MutableObject;
@ -541,12 +543,12 @@ public class Train {
GlobalStation destination = navigation.destination;
if (!navigatingManually && fullRefresh) {
GlobalStation preferredDestination = runtime.startCurrentInstruction();
if (preferredDestination != null)
destination = preferredDestination;
DiscoveredPath preferredPath = runtime.startCurrentInstruction();
if (preferredPath != null)
destination = preferredPath.destination;
}
navigation.startNavigation(destination, navigatingManually ? -1 : Double.MAX_VALUE, false);
navigation.startNavigation(navigation.findPathTo(destination, navigatingManually ? -1 : Double.MAX_VALUE));
}
private void tickDerailedSlowdown() {

View file

@ -0,0 +1,22 @@
package com.simibubi.create.content.trains.graph;
import com.simibubi.create.content.trains.station.GlobalStation;
import com.simibubi.create.foundation.utility.Couple;
import org.openjdk.nashorn.internal.objects.Global;
import java.util.List;
public class DiscoveredPath {
public List<Couple<TrackNode>> path;
public GlobalStation destination;
public double distance;
public double cost;
public DiscoveredPath(double distance, double cost, List<Couple<TrackNode>> path, GlobalStation destination) {
this.distance = distance;
this.cost = cost;
this.path = path;
this.destination = destination;
}
}

View file

@ -8,7 +8,9 @@ import java.util.Objects;
import com.simibubi.create.AllItems;
import com.simibubi.create.content.trains.display.GlobalTrainDisplayData.TrainDeparturePrediction;
import com.simibubi.create.content.trains.entity.Carriage;
import com.simibubi.create.content.trains.entity.Navigation;
import com.simibubi.create.content.trains.entity.Train;
import com.simibubi.create.content.trains.graph.DiscoveredPath;
import com.simibubi.create.content.trains.graph.EdgePointType;
import com.simibubi.create.content.trains.schedule.condition.ScheduleWaitCondition;
import com.simibubi.create.content.trains.schedule.condition.ScheduledDelay;
@ -122,17 +124,17 @@ public class ScheduleRuntime {
return;
}
GlobalStation nextStation = startCurrentInstruction();
if (nextStation == null)
DiscoveredPath nextPath = startCurrentInstruction();
if (nextPath == null)
return;
train.status.successfulNavigation();
if (nextStation == train.getCurrentStation()) {
if (nextPath.destination == train.getCurrentStation()) {
state = State.IN_TRANSIT;
destinationReached();
return;
}
if (train.navigation.startNavigation(nextStation, Double.MAX_VALUE, false) != TBD) {
if (train.navigation.startNavigation(nextPath) != TBD) {
state = State.IN_TRANSIT;
ticksInTransit = 0;
}
@ -167,13 +169,13 @@ public class ScheduleRuntime {
carriage.storage.tickIdleCargoTracker();
}
public GlobalStation startCurrentInstruction() {
public DiscoveredPath startCurrentInstruction() {
ScheduleEntry entry = schedule.entries.get(currentEntry);
ScheduleInstruction instruction = entry.instruction;
if (instruction instanceof DestinationInstruction destination) {
String regex = destination.getFilterForRegex();
GlobalStation best = null;
DiscoveredPath best = null;
double bestCost = Double.MAX_VALUE;
boolean anyMatch = false;
@ -188,12 +190,19 @@ public class ScheduleRuntime {
continue;
anyMatch = true;
boolean matchesCurrent = train.currentStation != null && train.currentStation.equals(globalStation.id);
double cost = matchesCurrent ? 0 : train.navigation.startNavigation(globalStation, bestCost, true);
double cost;
DiscoveredPath path = train.navigation.findPathTo(globalStation, bestCost);
if (matchesCurrent) {
cost = 0;
} else {
cost = path == null ? -1 : path.cost;
}
if (cost < 0)
continue;
if (cost > bestCost)
continue;
best = globalStation;
best = path;
bestCost = cost;
}
@ -332,9 +341,9 @@ public class ScheduleRuntime {
return accumulatedTime;
if (predictionTicks.size() <= currentEntry)
return accumulatedTime;
int departureTime = estimateStayDuration(index);
if (accumulatedTime < 0) {
predictions.add(createPrediction(index, filter.getFilter(), currentTitle, accumulatedTime));
return Math.min(accumulatedTime, departureTime);
@ -348,12 +357,12 @@ public class ScheduleRuntime {
predictions.add(createPrediction(index, filter.getFilter(), currentTitle, accumulatedTime));
if (accumulatedTime != TBD)
if (accumulatedTime != TBD)
accumulatedTime += departureTime;
if (departureTime == INVALID)
accumulatedTime = INVALID;
return accumulatedTime;
}
@ -381,7 +390,7 @@ public class ScheduleRuntime {
private TrainDeparturePrediction createPrediction(int index, String destination, String currentTitle, int time) {
if (time == INVALID)
return null;
int size = schedule.entries.size();
if (index >= size) {
if (!schedule.cyclic)

View file

@ -13,6 +13,8 @@ import java.util.function.Consumer;
import javax.annotation.Nullable;
import com.simibubi.create.content.trains.graph.DiscoveredPath;
import org.jetbrains.annotations.NotNull;
import com.simibubi.create.AllBlocks;
@ -286,7 +288,7 @@ public class StationBlockEntity extends SmartBlockEntity implements ITransformab
BlockPos up = new BlockPos(track.getUpNormal(level, pos, state));
BlockPos down = new BlockPos(track.getUpNormal(level, pos, state).scale(-1));
int bogeyOffset = pos.distManhattan(edgePoint.getGlobalPosition()) - 1;
if (!isValidBogeyOffset(bogeyOffset)) {
for (boolean upsideDown : Iterate.falseAndTrue) {
for (int i = -1; i <= 1; i++) {
@ -374,8 +376,8 @@ public class StationBlockEntity extends SmartBlockEntity implements ITransformab
if (train.navigation.destination != station)
continue;
GlobalStation preferredDestination = train.runtime.startCurrentInstruction();
train.navigation.startNavigation(preferredDestination != null ? preferredDestination : station, Double.MAX_VALUE, false);
DiscoveredPath preferredPath = train.runtime.startCurrentInstruction();
train.navigation.startNavigation(preferredPath != null ? preferredPath : train.navigation.findPathTo(station, Double.MAX_VALUE));
}
}