mirror of
https://github.com/webbukkit/dynmap.git
synced 2024-11-28 05:05:16 +01:00
Made use of newly introduced unloadChunk in BukkitAPI + removal of unstable features.
This commit is contained in:
parent
b31bb14452
commit
89c8d564a4
@ -3,10 +3,6 @@
|
|||||||
# How often a tile gets rendered (in seconds).
|
# How often a tile gets rendered (in seconds).
|
||||||
renderinterval: 1
|
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.
|
# The path where the tile-files are placed.
|
||||||
tilepath: web/tiles
|
tilepath: web/tiles
|
||||||
|
|
||||||
|
@ -54,9 +54,6 @@ public class DynmapPlayerListener extends PlayerListener {
|
|||||||
} else if (split[1].equals("fullrender")) {
|
} else if (split[1].equals("fullrender")) {
|
||||||
Player player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
mgr.renderFullWorld(player.getLocation());
|
mgr.renderFullWorld(player.getLocation());
|
||||||
} else if (split[1].equals("fullrenderasync")) {
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
mgr.renderFullWorldAsync(player.getLocation());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,27 +78,16 @@ public class MapManager extends Thread {
|
|||||||
maps = loadMapTypes(configuration);
|
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) {
|
void renderFullWorld(Location l) {
|
||||||
debugger.debug("Full render starting...");
|
debugger.debug("Full render starting...");
|
||||||
for (MapType map : maps) {
|
for (MapType map : maps) {
|
||||||
HashSet<MapTile> found = new HashSet<MapTile>();
|
HashSet<MapTile> found = new HashSet<MapTile>();
|
||||||
|
HashSet<MapTile> rendered = new HashSet<MapTile>();
|
||||||
LinkedList<MapTile> renderQueue = new LinkedList<MapTile>();
|
LinkedList<MapTile> renderQueue = new LinkedList<MapTile>();
|
||||||
|
LinkedList<DynmapChunk> loadedChunks = new LinkedList<DynmapChunk>();
|
||||||
|
|
||||||
for (MapTile tile : map.getTiles(l)) {
|
for (MapTile tile : map.getTiles(l)) {
|
||||||
if (!(found.contains(tile) || map.isRendered(tile))) {
|
if (!found.contains(tile)) {
|
||||||
found.add(tile);
|
found.add(tile);
|
||||||
renderQueue.add(tile);
|
renderQueue.add(tile);
|
||||||
}
|
}
|
||||||
@ -106,13 +95,29 @@ public class MapManager extends Thread {
|
|||||||
while (!renderQueue.isEmpty()) {
|
while (!renderQueue.isEmpty()) {
|
||||||
MapTile tile = renderQueue.pollFirst();
|
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());
|
debugger.debug("renderQueue: " + renderQueue.size() + "/" + found.size());
|
||||||
if (map.render(tile)) {
|
if (map.render(tile)) {
|
||||||
found.remove(tile);
|
found.remove(tile);
|
||||||
|
rendered.add(tile);
|
||||||
updateQueue.pushUpdate(new Client.Tile(tile.getName()));
|
updateQueue.pushUpdate(new Client.Tile(tile.getName()));
|
||||||
for (MapTile adjTile : map.getAdjecentTiles(tile)) {
|
for (MapTile adjTile : map.getAdjecentTiles(tile)) {
|
||||||
if (!(found.contains(adjTile) || map.isRendered(adjTile))) {
|
if (!(found.contains(adjTile) || rendered.contains(adjTile))) {
|
||||||
found.add(adjTile);
|
found.add(adjTile);
|
||||||
renderQueue.add(adjTile);
|
renderQueue.add(adjTile);
|
||||||
}
|
}
|
||||||
@ -121,64 +126,16 @@ public class MapManager extends Thread {
|
|||||||
found.remove(tile);
|
found.remove(tile);
|
||||||
System.gc();
|
System.gc();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unload remaining chunks to clean-up.
|
||||||
|
while (!loadedChunks.isEmpty()) {
|
||||||
|
DynmapChunk c = loadedChunks.pollFirst();
|
||||||
|
world.unloadChunk(c.x, c.y, false, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
debugger.debug("Full render finished.");
|
debugger.debug("Full render finished.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public HashSet<MapTile> fullmapTiles = new HashSet<MapTile>();
|
|
||||||
public boolean fullmapRenderStarting = false;
|
|
||||||
public HashSet<MapTile> fullmapTilesRendered = new HashSet<MapTile>();
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private MapType[] loadMapTypes(ConfigurationNode configuration) {
|
private MapType[] loadMapTypes(ConfigurationNode configuration) {
|
||||||
List<?> configuredMaps = (List<?>) configuration.getProperty("maps");
|
List<?> configuredMaps = (List<?>) configuration.getProperty("maps");
|
||||||
ArrayList<MapType> mapTypes = new ArrayList<MapType>();
|
ArrayList<MapType> mapTypes = new ArrayList<MapType>();
|
||||||
@ -240,15 +197,10 @@ public class MapManager extends Thread {
|
|||||||
while (running) {
|
while (running) {
|
||||||
MapTile t = staleQueue.popStaleTile();
|
MapTile t = staleQueue.popStaleTile();
|
||||||
if (t != null) {
|
if (t != null) {
|
||||||
loadRequiredChunks(t);
|
|
||||||
|
|
||||||
debugger.debug("Rendering tile " + t + "...");
|
debugger.debug("Rendering tile " + t + "...");
|
||||||
boolean isNonEmptyTile = t.getMap().render(t);
|
boolean isNonEmptyTile = t.getMap().render(t);
|
||||||
updateQueue.pushUpdate(new Client.Tile(t.getName()));
|
updateQueue.pushUpdate(new Client.Tile(t.getName()));
|
||||||
|
|
||||||
if (isNonEmptyTile)
|
|
||||||
handleFullMapRender(t);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Thread.sleep(renderWait);
|
Thread.sleep(renderWait);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
|
Loading…
Reference in New Issue
Block a user