diff --git a/configuration.txt b/configuration.txt index 71e6ef2f..311a33ca 100755 --- a/configuration.txt +++ b/configuration.txt @@ -3,10 +3,6 @@ # How often a tile gets rendered (in seconds). renderinterval: 1 -# When enabled Dynmap will preload chunks before rendering a tile. This will avoid Dynmap rendering unloaded (=partially blue) tiles. -# This WILL impact memory and diskio. -loadChunks: false - # The path where the tile-files are placed. tilepath: web/tiles diff --git a/src/main/java/org/dynmap/DynmapPlayerListener.java b/src/main/java/org/dynmap/DynmapPlayerListener.java index d91c1524..7c98da1b 100644 --- a/src/main/java/org/dynmap/DynmapPlayerListener.java +++ b/src/main/java/org/dynmap/DynmapPlayerListener.java @@ -54,9 +54,6 @@ public class DynmapPlayerListener extends PlayerListener { } else if (split[1].equals("fullrender")) { Player player = event.getPlayer(); mgr.renderFullWorld(player.getLocation()); - } else if (split[1].equals("fullrenderasync")) { - Player player = event.getPlayer(); - mgr.renderFullWorldAsync(player.getLocation()); } } } diff --git a/src/main/java/org/dynmap/MapManager.java b/src/main/java/org/dynmap/MapManager.java index 227284fa..244a5e5c 100644 --- a/src/main/java/org/dynmap/MapManager.java +++ b/src/main/java/org/dynmap/MapManager.java @@ -78,27 +78,16 @@ public class MapManager extends Thread { maps = loadMapTypes(configuration); } - void renderFullWorldAsync(Location l) { - fullmapTiles.clear(); - fullmapTilesRendered.clear(); - debugger.debug("Full render starting..."); - for (MapType map : maps) { - for (MapTile tile : map.getTiles(l)) { - fullmapTiles.add(tile); - invalidateTile(tile); - } - } - debugger.debug("Full render finished."); - } - void renderFullWorld(Location l) { debugger.debug("Full render starting..."); for (MapType map : maps) { HashSet found = new HashSet(); + HashSet rendered = new HashSet(); LinkedList renderQueue = new LinkedList(); + LinkedList loadedChunks = new LinkedList(); for (MapTile tile : map.getTiles(l)) { - if (!(found.contains(tile) || map.isRendered(tile))) { + if (!found.contains(tile)) { found.add(tile); renderQueue.add(tile); } @@ -106,13 +95,29 @@ public class MapManager extends Thread { while (!renderQueue.isEmpty()) { MapTile tile = renderQueue.pollFirst(); - loadRequiredChunks(tile); + DynmapChunk[] requiredChunks = tile.getMap().getRequiredChunks(tile); + + // Unload old chunks. + while (loadedChunks.size() >= Math.max(0, 200 - requiredChunks.length)) { + DynmapChunk c = loadedChunks.pollFirst(); + world.unloadChunk(c.x, c.y, false, true); + } + + // Load the required chunks. + for (DynmapChunk chunk : requiredChunks) { + boolean wasLoaded = world.isChunkLoaded(chunk.x, chunk.y); + world.loadChunk(chunk.x, chunk.y, false); + if (!wasLoaded) + loadedChunks.add(chunk); + } + debugger.debug("renderQueue: " + renderQueue.size() + "/" + found.size()); if (map.render(tile)) { found.remove(tile); + rendered.add(tile); updateQueue.pushUpdate(new Client.Tile(tile.getName())); for (MapTile adjTile : map.getAdjecentTiles(tile)) { - if (!(found.contains(adjTile) || map.isRendered(adjTile))) { + if (!(found.contains(adjTile) || rendered.contains(adjTile))) { found.add(adjTile); renderQueue.add(adjTile); } @@ -121,62 +126,14 @@ public class MapManager extends Thread { found.remove(tile); System.gc(); } - } - debugger.debug("Full render finished."); - } - public HashSet fullmapTiles = new HashSet(); - public boolean fullmapRenderStarting = false; - public HashSet fullmapTilesRendered = new HashSet(); - - void handleFullMapRender(MapTile tile) { - if (!fullmapTiles.contains(tile)) { - debugger.debug("Non fullmap-render tile: " + tile); - return; - } - fullmapTilesRendered.add(tile); - MapType map = tile.getMap(); - MapTile[] adjecenttiles = map.getAdjecentTiles(tile); - for (int i = 0; i < adjecenttiles.length; i++) { - MapTile adjecentTile = adjecenttiles[i]; - if (!fullmapTiles.contains(adjecentTile)) { - fullmapTiles.add(adjecentTile); - staleQueue.pushStaleTile(adjecentTile); + // Unload remaining chunks to clean-up. + while (!loadedChunks.isEmpty()) { + DynmapChunk c = loadedChunks.pollFirst(); + world.unloadChunk(c.x, c.y, false, true); } } - debugger.debug("Queue size: " + staleQueue.size() + "+" + fullmapTilesRendered.size() + "/" + fullmapTiles.size()); - } - - private boolean hasEnoughMemory() { - return Runtime.getRuntime().freeMemory() >= 100 * 1024 * 1024; - } - - private void waitForMemory() { - if (!hasEnoughMemory()) { - debugger.debug("Waiting for memory..."); - // Wait until there is at least 50mb of free memory. - do { - System.gc(); - try { - Thread.sleep(500); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } while (!hasEnoughMemory()); - debugger.debug(Runtime.getRuntime().freeMemory() / (1024 * 1024) + "MB of memory free, will continue..."); - } - } - - private void loadRequiredChunks(MapTile tile) { - if (!loadChunks) - return; - waitForMemory(); - - // Actually load the chunks. - for (DynmapChunk chunk : tile.getMap().getRequiredChunks(tile)) { - if (!world.isChunkLoaded(chunk.x, chunk.y)) - world.loadChunk(chunk.x, chunk.y); - } + debugger.debug("Full render finished."); } private MapType[] loadMapTypes(ConfigurationNode configuration) { @@ -240,15 +197,10 @@ public class MapManager extends Thread { while (running) { MapTile t = staleQueue.popStaleTile(); if (t != null) { - loadRequiredChunks(t); - debugger.debug("Rendering tile " + t + "..."); boolean isNonEmptyTile = t.getMap().render(t); updateQueue.pushUpdate(new Client.Tile(t.getName())); - if (isNonEmptyTile) - handleFullMapRender(t); - try { Thread.sleep(renderWait); } catch (InterruptedException e) {