Switch to non-recursive fill algorithm - handle huge regions better

This commit is contained in:
Mike Primm 2011-12-10 23:34:46 -06:00
parent eb0a3ef83f
commit c8805ab564
3 changed files with 24 additions and 11 deletions

View File

@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.dynmap</groupId> <groupId>org.dynmap</groupId>
<artifactId>Dynmap-Factions</artifactId> <artifactId>Dynmap-Factions</artifactId>
<version>0.10</version> <version>0.11</version>
<build> <build>
<resources> <resources>

View File

@ -1,5 +1,6 @@
package org.dynmap.factions; package org.dynmap.factions;
import java.util.ArrayDeque;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
@ -181,14 +182,26 @@ public class DynmapFactionsPlugin extends JavaPlugin {
*/ */
private int floodFillTarget(TileFlags src, TileFlags dest, int x, int y) { private int floodFillTarget(TileFlags src, TileFlags dest, int x, int y) {
int cnt = 0; int cnt = 0;
ArrayDeque<int[]> stack = new ArrayDeque<int[]>();
stack.push(new int[] { x, y });
while(stack.isEmpty() == false) {
int[] nxt = stack.pop();
x = nxt[0];
y = nxt[1];
if(src.getFlag(x, y)) { /* Set in src */ if(src.getFlag(x, y)) { /* Set in src */
src.setFlag(x, y, false); /* Clear source */ src.setFlag(x, y, false); /* Clear source */
dest.setFlag(x, y, true); /* Set in destination */ dest.setFlag(x, y, true); /* Set in destination */
cnt++; cnt++;
cnt += floodFillTarget(src, dest, x+1, y); /* Fill adjacent blocks */ if(src.getFlag(x+1, y))
cnt += floodFillTarget(src, dest, x-1, y); stack.push(new int[] { x+1, y });
cnt += floodFillTarget(src, dest, x, y+1); if(src.getFlag(x-1, y))
cnt += floodFillTarget(src, dest, x, y-1); stack.push(new int[] { x-1, y });
if(src.getFlag(x, y+1))
stack.push(new int[] { x, y+1 });
if(src.getFlag(x, y-1))
stack.push(new int[] { x, y-1 });
}
} }
return cnt; return cnt;
} }

View File

@ -12,7 +12,7 @@ import java.util.HashMap;
*/ */
public class TileFlags { public class TileFlags {
private HashMap<Long, long[]> chunkmap = new HashMap<Long, long[]>(); private HashMap<Long, long[]> chunkmap = new HashMap<Long, long[]>();
private long last_key = Long.MIN_VALUE; private long last_key = Long.MAX_VALUE;
private long[] last_row; private long[] last_row;
public TileFlags() { public TileFlags() {
@ -62,6 +62,6 @@ public class TileFlags {
public void clear() { public void clear() {
chunkmap.clear(); chunkmap.clear();
last_row = null; last_row = null;
last_key = Long.MIN_VALUE; last_key = Long.MAX_VALUE;
} }
} }