Add MapUpdateTask and tentatively fix for RenderSorting

This commit is contained in:
Blue (Lukas Rieger) 2021-05-16 11:13:21 +02:00
parent f4926fe72d
commit 53378ba059
No known key found for this signature in database
GPG Key ID: 904C4995F9E1F800
6 changed files with 125 additions and 100 deletions

View File

@ -24,7 +24,6 @@
*/
package de.bluecolored.bluemap.common.plugin;
import com.flowpowered.math.vector.Vector2i;
import de.bluecolored.bluemap.common.BlueMapService;
import de.bluecolored.bluemap.common.InterruptableReentrantLock;
import de.bluecolored.bluemap.common.MissingResourcesException;
@ -32,7 +31,9 @@
import de.bluecolored.bluemap.common.live.LiveAPIRequestHandler;
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerInterface;
import de.bluecolored.bluemap.common.plugin.skins.PlayerSkinUpdater;
import de.bluecolored.bluemap.common.rendermanager.*;
import de.bluecolored.bluemap.common.rendermanager.MapUpdateTask;
import de.bluecolored.bluemap.common.rendermanager.RenderManager;
import de.bluecolored.bluemap.common.web.FileRequestHandler;
import de.bluecolored.bluemap.core.BlueMap;
import de.bluecolored.bluemap.core.MinecraftVersion;
import de.bluecolored.bluemap.core.config.CoreConfig;
@ -43,7 +44,6 @@
import de.bluecolored.bluemap.core.metrics.Metrics;
import de.bluecolored.bluemap.core.resourcepack.ParseResourceException;
import de.bluecolored.bluemap.core.util.FileUtils;
import de.bluecolored.bluemap.common.web.FileRequestHandler;
import de.bluecolored.bluemap.core.webserver.HttpRequestHandler;
import de.bluecolored.bluemap.core.webserver.WebServer;
import de.bluecolored.bluemap.core.world.World;
@ -168,15 +168,7 @@ public void load() throws IOException, ParseResourceException {
//update all maps
for (BmMap map : maps.values()) {
Collection<Vector2i> regions = map.getWorld().listRegions();
List<WorldRegionRenderTask> mapTasks = new ArrayList<>(regions.size());
for (Vector2i region : regions)
mapTasks.add(new WorldRegionRenderTask(map, region));
mapTasks.sort(WorldRegionRenderTask::compare);
CombinedRenderTask<WorldRegionRenderTask> mapUpdateTask = new CombinedRenderTask<>("Update map '" + map.getId() + "'", mapTasks);
renderManager.scheduleRenderTask(mapUpdateTask);
renderManager.scheduleRenderTask(new MapUpdateTask(map));
}
//start render-manager

View File

@ -24,16 +24,12 @@
*/
package de.bluecolored.bluemap.common.plugin.commands;
import com.flowpowered.math.vector.Vector2i;
import de.bluecolored.bluemap.common.plugin.Plugin;
import de.bluecolored.bluemap.common.plugin.text.Text;
import de.bluecolored.bluemap.common.plugin.text.TextColor;
import de.bluecolored.bluemap.common.rendermanager.CombinedRenderTask;
import de.bluecolored.bluemap.common.rendermanager.RenderManager;
import de.bluecolored.bluemap.common.rendermanager.RenderTask;
import de.bluecolored.bluemap.common.rendermanager.WorldRegionRenderTask;
import de.bluecolored.bluemap.core.map.BmMap;
import de.bluecolored.bluemap.core.world.Grid;
import de.bluecolored.bluemap.core.world.World;
import org.apache.commons.lang3.time.DurationFormatUtils;
@ -135,41 +131,6 @@ public Text mapHelperHover() {
return Text.of("map").setHoverText(Text.of(TextColor.WHITE, "Available maps: \n", TextColor.GRAY, joiner.toString()));
}
public List<Vector2i> getRegions(World world) {
return getRegions(world, null, -1);
}
public List<Vector2i> getRegions(World world, Vector2i center, int radius) {
if (center == null || radius < 0) return new ArrayList<>(world.listRegions());
List<Vector2i> regions = new ArrayList<>();
Grid regionGrid = world.getRegionGrid();
Vector2i halfCell = regionGrid.getGridSize().div(2);
int increasedRadiusSquared = (int) Math.pow(radius + Math.ceil(halfCell.length()), 2);
for (Vector2i region : world.listRegions()) {
Vector2i min = regionGrid.getCellMin(region);
Vector2i regionCenter = min.add(halfCell);
if (regionCenter.distanceSquared(center) <= increasedRadiusSquared)
regions.add(region);
}
return regions;
}
public RenderTask createMapUpdateTask(BmMap map) {
return createMapUpdateTask(map, getRegions(map.getWorld()));
}
public RenderTask createMapUpdateTask(BmMap map, Collection<Vector2i> regions) {
List<WorldRegionRenderTask> tasks = new ArrayList<>(regions.size());
regions.forEach(region -> tasks.add(new WorldRegionRenderTask(map, region)));
tasks.sort(WorldRegionRenderTask::compare);
return new CombinedRenderTask<>("Update map '" + map.getId() + "'", tasks);
}
public synchronized Optional<RenderTask> getTaskForRef(String ref) {
return Optional.ofNullable(taskRefMap.get(ref)).map(WeakReference::get);
}

View File

@ -50,6 +50,7 @@
import de.bluecolored.bluemap.common.plugin.text.TextColor;
import de.bluecolored.bluemap.common.plugin.text.TextFormat;
import de.bluecolored.bluemap.common.rendermanager.MapPurgeTask;
import de.bluecolored.bluemap.common.rendermanager.MapUpdateTask;
import de.bluecolored.bluemap.common.rendermanager.RenderTask;
import de.bluecolored.bluemap.core.BlueMap;
import de.bluecolored.bluemap.core.MinecraftVersion;
@ -619,7 +620,6 @@ public int updateCommand(CommandContext<S> context, boolean force) {
new Thread(() -> {
try {
List<BmMap> maps = new ArrayList<>();
World world = worldToRender;
if (worldToRender != null) {
plugin.getServerInterface().persistWorldChanges(worldToRender.getUUID());
for (BmMap map : plugin.getMapTypes()) {
@ -628,21 +628,18 @@ public int updateCommand(CommandContext<S> context, boolean force) {
} else {
plugin.getServerInterface().persistWorldChanges(mapToRender.getWorld().getUUID());
maps.add(mapToRender);
world = mapToRender.getWorld();
}
List<Vector2i> regions = helper.getRegions(world, center, radius);
if (force) {
for (BmMap map : maps) {
MapRenderState state = map.getRenderState();
regions.forEach(region -> state.setRenderTime(region, -1));
}
}
for (BmMap map : maps) {
plugin.getRenderManager().scheduleRenderTask(helper.createMapUpdateTask(map, regions));
source.sendMessage(Text.of(TextColor.GREEN, "Created new Update-Task for map '" + map.getId() + "' ", TextColor.GRAY, "(" + regions.size() + " regions, ~" + regions.size() * 1024L + " chunks)"));
MapUpdateTask updateTask = new MapUpdateTask(map, center, radius);
plugin.getRenderManager().scheduleRenderTask(updateTask);
if (force) {
MapRenderState state = map.getRenderState();
updateTask.getRegions().forEach(region -> state.setRenderTime(region, -1));
}
source.sendMessage(Text.of(TextColor.GREEN, "Created new Update-Task for map '" + map.getId() + "' ", TextColor.GRAY, "(" + updateTask.getRegions().size() + " regions, ~" + updateTask.getRegions().size() * 1024L + " chunks)"));
}
source.sendMessage(Text.of(TextColor.GREEN, "Use ", TextColor.GRAY, "/bluemap", TextColor.GREEN, " to see the progress."));
@ -710,7 +707,7 @@ public int purgeCommand(CommandContext<S> context) {
// if map is loaded, reset it and start updating it after the purge
if (optMap.isPresent()) {
RenderTask updateTask = helper.createMapUpdateTask(optMap.get());
RenderTask updateTask = new MapUpdateTask(optMap.get());
plugin.getRenderManager().scheduleRenderTask(updateTask);
source.sendMessage(Text.of(TextColor.GREEN, "Created new Update-Task for map '" + mapId + "'"));
source.sendMessage(Text.of(TextColor.GRAY, "If you don't want to render this map again, you need to remove it from your configuration first!"));

View File

@ -0,0 +1,83 @@
package de.bluecolored.bluemap.common.rendermanager;
import com.flowpowered.math.vector.Vector2i;
import de.bluecolored.bluemap.core.map.BmMap;
import de.bluecolored.bluemap.core.world.Grid;
import de.bluecolored.bluemap.core.world.World;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class MapUpdateTask extends CombinedRenderTask<WorldRegionRenderTask> {
private final BmMap map;
private final Collection<Vector2i> regions;
public MapUpdateTask(BmMap map) {
this(map, getRegions(map.getWorld()));
}
public MapUpdateTask(BmMap map, boolean force) {
this(map, getRegions(map.getWorld()), force);
}
public MapUpdateTask(BmMap map, Vector2i center, int radius) {
this(map, getRegions(map.getWorld(), center, radius));
}
public MapUpdateTask(BmMap map, Vector2i center, int radius, boolean force) {
this(map, getRegions(map.getWorld(), center, radius), force);
}
public MapUpdateTask(BmMap map, Collection<Vector2i> regions) {
this(map, regions, false);
}
public MapUpdateTask(BmMap map, Collection<Vector2i> regions, boolean force) {
super("Update map '" + map.getId() + "'", createTasks(map, regions, force));
this.map = map;
this.regions = Collections.unmodifiableCollection(new ArrayList<>(regions));
}
public BmMap getMap() {
return map;
}
public Collection<Vector2i> getRegions() {
return regions;
}
private static Collection<WorldRegionRenderTask> createTasks(BmMap map, Collection<Vector2i> regions, boolean force) {
List<WorldRegionRenderTask> tasks = new ArrayList<>(regions.size());
regions.forEach(region -> tasks.add(new WorldRegionRenderTask(map, region, force)));
tasks.sort(WorldRegionRenderTask::compare);
return tasks;
}
private static List<Vector2i> getRegions(World world) {
return getRegions(world, null, -1);
}
private static List<Vector2i> getRegions(World world, Vector2i center, int radius) {
if (center == null || radius < 0) return new ArrayList<>(world.listRegions());
List<Vector2i> regions = new ArrayList<>();
Grid regionGrid = world.getRegionGrid();
Vector2i halfCell = regionGrid.getGridSize().div(2);
int increasedRadiusSquared = (int) Math.pow(radius + Math.ceil(halfCell.length()), 2);
for (Vector2i region : world.listRegions()) {
Vector2i min = regionGrid.getCellMin(region);
Vector2i regionCenter = min.add(halfCell);
if (regionCenter.distanceSquared(center) <= increasedRadiusSquared)
regions.add(region);
}
return regions;
}
}

View File

@ -25,7 +25,6 @@
package de.bluecolored.bluemap.common.rendermanager;
import com.flowpowered.math.vector.Vector2i;
import de.bluecolored.bluemap.core.logger.Logger;
import de.bluecolored.bluemap.core.map.BmMap;
import de.bluecolored.bluemap.core.world.Grid;
import de.bluecolored.bluemap.core.world.Region;
@ -165,11 +164,7 @@ public boolean isForce() {
@Override
public String getDescription() {
if (force) {
return "Render region " + getWorldRegion() + " for map '" + map.getId() + "'";
} else {
return "Update region " + getWorldRegion() + " for map '" + map.getId() + "'";
}
return "Update region " + getWorldRegion() + " for map '" + map.getId() + "'";
}
@Override
@ -177,7 +172,7 @@ public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
WorldRegionRenderTask that = (WorldRegionRenderTask) o;
return force == that.force && map.equals(that.map) && worldRegion.equals(that.worldRegion);
return force == that.force && map.getId().equals(that.map.getId()) && worldRegion.equals(that.worldRegion);
}
@Override
@ -195,24 +190,27 @@ private static int tileComparator(Vector2i v1, Vector2i v2) {
public static int compare(WorldRegionRenderTask task1, WorldRegionRenderTask task2) {
if (task1.equals(task2)) return 0;
int comp = task1.getMap().getId().compareTo(task2.getMap().getId());
int comp = task1.map.getId().compareTo(task2.map.getId());
if (comp != 0) return comp;
//sort based on the worlds spawn-point
World world = task1.getMap().getWorld();
Vector2i spawnPoint = world.getSpawnPoint().toVector2(true);
Grid regionGrid = world.getRegionGrid();
Vector2i spawnRegion = regionGrid.getCell(spawnPoint);
if (task1.map == task2.map) { //should always be true
//sort based on the worlds spawn-point
World world = task1.map.getWorld();
Vector2i spawnPoint = world.getSpawnPoint().toVector2(true);
Grid regionGrid = world.getRegionGrid();
Vector2i task1Rel = task1.getWorldRegion().sub(spawnRegion);
Vector2i task2Rel = task2.getWorldRegion().sub(spawnRegion);
Vector2i spawnRegion = regionGrid.getCell(spawnPoint);
comp = tileComparator(task1Rel, task2Rel);
Vector2i task1Rel = task1.worldRegion.sub(spawnRegion);
Vector2i task2Rel = task2.worldRegion.sub(spawnRegion);
comp = tileComparator(task1Rel, task2Rel);
} else {
comp = tileComparator(task1.worldRegion, task2.worldRegion);
}
if (comp != 0) return comp;
if (task1.isForce() == task2.isForce()) return 0;
if (task1.isForce()) return -1;
return 1;
return -Boolean.compare(task1.force, task2.force);
}
}

View File

@ -24,14 +24,12 @@
*/
package de.bluecolored.bluemap.cli;
import com.flowpowered.math.vector.Vector2i;
import de.bluecolored.bluemap.common.BlueMapService;
import de.bluecolored.bluemap.common.MissingResourcesException;
import de.bluecolored.bluemap.common.plugin.RegionFileWatchService;
import de.bluecolored.bluemap.common.rendermanager.CombinedRenderTask;
import de.bluecolored.bluemap.common.rendermanager.MapUpdateTask;
import de.bluecolored.bluemap.common.rendermanager.RenderManager;
import de.bluecolored.bluemap.common.rendermanager.RenderTask;
import de.bluecolored.bluemap.common.rendermanager.WorldRegionRenderTask;
import de.bluecolored.bluemap.common.web.FileRequestHandler;
import de.bluecolored.bluemap.core.BlueMap;
import de.bluecolored.bluemap.core.MinecraftVersion;
@ -86,20 +84,16 @@ public void renderMaps(BlueMapService blueMap, boolean watch, boolean forceRende
}
//update all maps
List<WorldRegionRenderTask> tasks = new ArrayList<>();
for (BmMap map : maps.values())
for (Vector2i region : map.getWorld().listRegions())
tasks.add(new WorldRegionRenderTask(map, region, forceRender));
tasks.sort(WorldRegionRenderTask::compare);
RenderTask mainTask = new CombinedRenderTask<>("CLI Render", tasks);
int totalRegions = 0;
for (BmMap map : maps.values()) {
MapUpdateTask updateTask = new MapUpdateTask(map, forceRender);
renderManager.scheduleRenderTask(updateTask);
totalRegions += updateTask.getRegions().size();
}
renderManager.scheduleRenderTask(mainTask);
int totalRegions = tasks.size();
Logger.global.logInfo("Start " + (forceRender ? "rendering " : "updating ") + maps.size() + " maps (" + totalRegions + " regions, ~" + totalRegions * 1024L + " chunks)...");
Logger.global.logInfo("Start updating " + maps.size() + " maps (" + totalRegions + " regions, ~" + totalRegions * 1024L + " chunks)...");
// start rendering
long startTime = System.currentTimeMillis();
renderManager.start(blueMap.getCoreConfig().getRenderThreadCount());
Timer timer = new Timer("BlueMap-CLI-Timer", true);
@ -117,7 +111,7 @@ public void run() {
String etrDurationString = DurationFormatUtils.formatDuration(etaMs, "HH:mm:ss");
eta = " (ETA: " + etrDurationString + ")";
}
Logger.global.logInfo("Rendering: " + (Math.round(progress * 100000) / 1000.0) + "%" + eta);
Logger.global.logInfo(task.getDescription() + ": " + (Math.round(progress * 100000) / 1000.0) + "%" + eta);
}
};
timer.scheduleAtFixedRate(updateInfoTask, TimeUnit.SECONDS.toMillis(10), TimeUnit.SECONDS.toMillis(10));
@ -160,7 +154,7 @@ public void run() {
// wait until done, then shutdown if not watching
renderManager.awaitIdle();
Logger.global.logInfo("Your maps are now up-to-date!");
Logger.global.logInfo("Your maps are now all up-to-date!");
if (watch) {
updateInfoTask.cancel();