mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-27 06:20:02 +00:00
Merge W2F-hydroplanner
This commit is contained in:
commit
8899c9e3f9
6 files changed
+356
-3
No files matched your search
@@ -28,6 +28,8 @@ import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ForkJoinWorkerThread;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public final class HydrologyPlanner {
|
||||
static final int ROUTING_CONTEXT_CACHE_SIZE = 64;
|
||||
@@ -64,6 +66,8 @@ public final class HydrologyPlanner {
|
||||
final HydrologySegmentBuilder segments;
|
||||
final HydrologyFeatureSitePlanner featureSites;
|
||||
final HydrologyRegionalPlanner regional;
|
||||
private volatile Predicate<HydrologyTileKey> earlyOwnerScope;
|
||||
private volatile Function<HydrologyTileKey, HydrologyTile> plannedTiles;
|
||||
|
||||
public HydrologyPlanner(long worldSeed, HydrologyPlannerSettings settings, HydrologyTerrainSampler sampler) {
|
||||
this(
|
||||
@@ -244,6 +248,23 @@ public final class HydrologyPlanner {
|
||||
return List.copyOf(unique);
|
||||
}
|
||||
|
||||
/**
|
||||
* Limits the lower-rank neighbour drafts an owner starts before its admission demands them to the
|
||||
* tiles the scope accepts; null starts all of them. A neighbour that no admission demands and
|
||||
* nothing plans is a draft computed for nothing, and so are the early neighbours it starts itself.
|
||||
*/
|
||||
void limitEarlyOwners(Predicate<HydrologyTileKey> scope) {
|
||||
earlyOwnerScope = scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Where the plans of tiles already planned are found. An owner draft that left the owner cache is
|
||||
* restored from its tile's plan when a neighbour demands it again, instead of being drafted twice.
|
||||
*/
|
||||
void usePlannedTiles(Function<HydrologyTileKey, HydrologyTile> source) {
|
||||
plannedTiles = source;
|
||||
}
|
||||
|
||||
void clearOwnerDrafts() {
|
||||
resolvedOwners.invalidateAll();
|
||||
regional.clear();
|
||||
@@ -289,6 +310,9 @@ public final class HydrologyPlanner {
|
||||
return local;
|
||||
}
|
||||
CrossTileResolvedOwner cached = resolvedOwners.getIfPresent(key);
|
||||
if (cached == null) {
|
||||
cached = plannedOwner(key);
|
||||
}
|
||||
if (cached != null) {
|
||||
context.remember(key, cached);
|
||||
return cached;
|
||||
@@ -335,6 +359,17 @@ public final class HydrologyPlanner {
|
||||
}
|
||||
}
|
||||
|
||||
private CrossTileResolvedOwner plannedOwner(HydrologyTileKey key) {
|
||||
Function<HydrologyTileKey, HydrologyTile> source = plannedTiles;
|
||||
HydrologyTile tile = source == null ? null : source.apply(key);
|
||||
if (tile == null || tile.resolvedOwner() == null) {
|
||||
return null;
|
||||
}
|
||||
reuseResolvedTile(tile);
|
||||
CrossTileResolvedOwner restored = resolvedOwners.getIfPresent(key);
|
||||
return restored == null ? tile.resolvedOwner() : restored;
|
||||
}
|
||||
|
||||
List<CrossTileResolvedOwner> resolveLowerRankOwners(
|
||||
List<HydrologyTileKey> candidateKeys,
|
||||
CrossTileResolutionContext context,
|
||||
@@ -751,6 +786,7 @@ public final class HydrologyPlanner {
|
||||
return;
|
||||
}
|
||||
int radius = settings.crossTileColorPeriod() - 1;
|
||||
Predicate<HydrologyTileKey> scope = earlyOwnerScope;
|
||||
ArrayList<HydrologyTileKey> candidates = new ArrayList<>();
|
||||
for (long tileZ = (long) ownerKey.tileZ() - radius; tileZ <= (long) ownerKey.tileZ() + radius; tileZ++) {
|
||||
for (long tileX = (long) ownerKey.tileX() - radius; tileX <= (long) ownerKey.tileX() + radius; tileX++) {
|
||||
@@ -759,7 +795,8 @@ public final class HydrologyPlanner {
|
||||
continue;
|
||||
}
|
||||
HydrologyTileKey key = new HydrologyTileKey((int) tileX, (int) tileZ);
|
||||
if (crossTile.ownerColorRank(key) >= ownerRank || preparedOwners.containsKey(key)
|
||||
if (crossTile.ownerColorRank(key) >= ownerRank || scope != null && !scope.test(key)
|
||||
|| preparedOwners.containsKey(key)
|
||||
|| resolvedOwners.getIfPresent(key) != null || resolvingOwners.containsKey(key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -161,6 +161,17 @@ public final class HydrologyTileCache implements AutoCloseable {
|
||||
this.closed = new AtomicBoolean();
|
||||
this.localChunks = ThreadLocal.withInitial(LocalChunks::new);
|
||||
this.neighbourPrefetchEnabled = true;
|
||||
planner.usePlannedTiles(this::plannedTile);
|
||||
}
|
||||
|
||||
/** A tile already planned, resident or in the prepared-plan store, loaded without planning it. */
|
||||
private HydrologyTile plannedTile(HydrologyTileKey key) {
|
||||
HydrologyTile resident = tiles.getIfPresent(key);
|
||||
if (resident != null) {
|
||||
return resident;
|
||||
}
|
||||
PreparedHydrologyTileStore store = persistentStore;
|
||||
return store == null ? null : store.load(key).orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -690,7 +701,7 @@ public final class HydrologyTileCache implements AutoCloseable {
|
||||
tileCoordinate(Math.addExact(area.maximumBlockZ(), publicationRadius), tileSize));
|
||||
List<HydrologyTileKey> keys = nearestFirst(required, tileCoordinate(area.centerBlockX(), tileSize),
|
||||
tileCoordinate(area.centerBlockZ(), tileSize), MAXIMUM_PREGENERATION_TILES);
|
||||
PregenerationScope scope = new PregenerationScope(bounds);
|
||||
PregenerationScope scope = new PregenerationScope(bounds, required);
|
||||
try {
|
||||
enqueuePrefetchArea(keys, scope);
|
||||
return scope;
|
||||
@@ -1082,6 +1093,7 @@ public final class HydrologyTileCache implements AutoCloseable {
|
||||
scope.previousNeighbourPrefetch = pregenerationScope == null
|
||||
? neighbourPrefetchEnabled : pregenerationScope.previousNeighbourPrefetch;
|
||||
pregenerationScope = scope;
|
||||
planner.limitEarlyOwners(scope.required::contains);
|
||||
prefetchQueue.removeIf(key -> {
|
||||
if (!area.contains(key)) {
|
||||
queuedPrefetches.remove(key);
|
||||
@@ -1619,12 +1631,19 @@ public final class HydrologyTileCache implements AutoCloseable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Speculative planning during a pregeneration: tiles inside {@code bounds} may be planned ahead of
|
||||
* generation, and owner drafts start their lower-rank neighbours early only inside {@code required},
|
||||
* the tiles the area composes from.
|
||||
*/
|
||||
public final class PregenerationScope implements AutoCloseable {
|
||||
private final TileBounds bounds;
|
||||
private final TileBounds required;
|
||||
private boolean previousNeighbourPrefetch;
|
||||
|
||||
private PregenerationScope(TileBounds bounds) {
|
||||
private PregenerationScope(TileBounds bounds, TileBounds required) {
|
||||
this.bounds = bounds;
|
||||
this.required = required;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1634,6 +1653,7 @@ public final class HydrologyTileCache implements AutoCloseable {
|
||||
return;
|
||||
}
|
||||
pregenerationScope = null;
|
||||
planner.limitEarlyOwners(null);
|
||||
neighbourPrefetchEnabled = previousNeighbourPrefetch;
|
||||
prefetchQueue.clear();
|
||||
queuedPrefetches.clear();
|
||||
|
||||
Reference in new issue
Block a user