mirror of
https://github.com/webbukkit/dynmap.git
synced 2024-11-24 19:25:15 +01:00
Shift most of touch processing off server main thread
This commit is contained in:
parent
02091acd45
commit
530eb0ae9e
@ -4,12 +4,12 @@ package org.dynmap;
|
|||||||
* Generic block location
|
* Generic block location
|
||||||
*/
|
*/
|
||||||
public class DynmapLocation {
|
public class DynmapLocation {
|
||||||
public int x, y, z;
|
public double x, y, z;
|
||||||
public String world;
|
public String world;
|
||||||
|
|
||||||
public DynmapLocation() {}
|
public DynmapLocation() {}
|
||||||
|
|
||||||
public DynmapLocation(String w, int x, int y, int z) {
|
public DynmapLocation(String w, double x, double y, double z) {
|
||||||
world = w;
|
world = w;
|
||||||
this.x = x; this.y = y; this.z = z;
|
this.x = x; this.y = y; this.z = z;
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,6 @@ import org.bukkit.block.Block;
|
|||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.CustomEventListener;
|
import org.bukkit.event.CustomEventListener;
|
||||||
@ -111,7 +110,6 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
|||||||
|
|
||||||
/* Flag to let code know that we're doing reload - make sure we don't double-register event handlers */
|
/* Flag to let code know that we're doing reload - make sure we don't double-register event handlers */
|
||||||
public boolean is_reload = false;
|
public boolean is_reload = false;
|
||||||
private boolean generate_only = false;
|
|
||||||
private static boolean ignore_chunk_loads = false; /* Flag keep us from processing our own chunk loads */
|
private static boolean ignore_chunk_loads = false; /* Flag keep us from processing our own chunk loads */
|
||||||
|
|
||||||
private HashMap<Event.Type, List<Listener>> event_handlers = new HashMap<Event.Type, List<Listener>>();
|
private HashMap<Event.Type, List<Listener>> event_handlers = new HashMap<Event.Type, List<Listener>>();
|
||||||
@ -130,7 +128,6 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Add/Replace branches in configuration tree with contribution from a separate file */
|
/* Add/Replace branches in configuration tree with contribution from a separate file */
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private void mergeConfigurationBranch(ConfigurationNode cfgnode, String branch, boolean replace_existing, boolean islist) {
|
private void mergeConfigurationBranch(ConfigurationNode cfgnode, String branch, boolean replace_existing, boolean islist) {
|
||||||
Object srcbranch = cfgnode.getObject(branch);
|
Object srcbranch = cfgnode.getObject(branch);
|
||||||
if(srcbranch == null)
|
if(srcbranch == null)
|
||||||
@ -521,10 +518,11 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
|||||||
public void onBlockPlace(BlockPlaceEvent event) {
|
public void onBlockPlace(BlockPlaceEvent event) {
|
||||||
if(event.isCancelled())
|
if(event.isCancelled())
|
||||||
return;
|
return;
|
||||||
DynmapLocation dloc = toLoc(event.getBlock().getLocation());
|
Location loc = event.getBlock().getLocation();
|
||||||
mapManager.sscache.invalidateSnapshot(dloc);
|
String wn = loc.getWorld().getName();
|
||||||
|
mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||||
if(onplace) {
|
if(onplace) {
|
||||||
mapManager.touch(dloc, "blockplace");
|
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockplace");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -532,10 +530,11 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
|||||||
public void onBlockBreak(BlockBreakEvent event) {
|
public void onBlockBreak(BlockBreakEvent event) {
|
||||||
if(event.isCancelled())
|
if(event.isCancelled())
|
||||||
return;
|
return;
|
||||||
DynmapLocation dloc = toLoc(event.getBlock().getLocation());
|
Location loc = event.getBlock().getLocation();
|
||||||
mapManager.sscache.invalidateSnapshot(dloc);
|
String wn = loc.getWorld().getName();
|
||||||
|
mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||||
if(onbreak) {
|
if(onbreak) {
|
||||||
mapManager.touch(dloc, "blockbreak");
|
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockbreak");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -543,10 +542,11 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
|||||||
public void onLeavesDecay(LeavesDecayEvent event) {
|
public void onLeavesDecay(LeavesDecayEvent event) {
|
||||||
if(event.isCancelled())
|
if(event.isCancelled())
|
||||||
return;
|
return;
|
||||||
DynmapLocation dloc = toLoc(event.getBlock().getLocation());
|
Location loc = event.getBlock().getLocation();
|
||||||
mapManager.sscache.invalidateSnapshot(dloc);
|
String wn = loc.getWorld().getName();
|
||||||
|
mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||||
if(onleaves) {
|
if(onleaves) {
|
||||||
mapManager.touch(dloc, "leavesdecay");
|
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "leavesdecay");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -554,10 +554,11 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
|||||||
public void onBlockBurn(BlockBurnEvent event) {
|
public void onBlockBurn(BlockBurnEvent event) {
|
||||||
if(event.isCancelled())
|
if(event.isCancelled())
|
||||||
return;
|
return;
|
||||||
DynmapLocation dloc = toLoc(event.getBlock().getLocation());
|
Location loc = event.getBlock().getLocation();
|
||||||
mapManager.sscache.invalidateSnapshot(dloc);
|
String wn = loc.getWorld().getName();
|
||||||
|
mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||||
if(onburn) {
|
if(onburn) {
|
||||||
mapManager.touch(dloc, "blockburn");
|
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockburn");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -565,10 +566,11 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
|||||||
public void onBlockForm(BlockFormEvent event) {
|
public void onBlockForm(BlockFormEvent event) {
|
||||||
if(event.isCancelled())
|
if(event.isCancelled())
|
||||||
return;
|
return;
|
||||||
DynmapLocation dloc = toLoc(event.getBlock().getLocation());
|
Location loc = event.getBlock().getLocation();
|
||||||
mapManager.sscache.invalidateSnapshot(dloc);
|
String wn = loc.getWorld().getName();
|
||||||
|
mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||||
if(onblockform) {
|
if(onblockform) {
|
||||||
mapManager.touch(dloc, "blockform");
|
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockform");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -576,10 +578,11 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
|||||||
public void onBlockFade(BlockFadeEvent event) {
|
public void onBlockFade(BlockFadeEvent event) {
|
||||||
if(event.isCancelled())
|
if(event.isCancelled())
|
||||||
return;
|
return;
|
||||||
DynmapLocation dloc = toLoc(event.getBlock().getLocation());
|
Location loc = event.getBlock().getLocation();
|
||||||
mapManager.sscache.invalidateSnapshot(dloc);
|
String wn = loc.getWorld().getName();
|
||||||
|
mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||||
if(onblockfade) {
|
if(onblockfade) {
|
||||||
mapManager.touch(dloc, "blockfade");
|
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockfade");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -587,10 +590,11 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
|||||||
public void onBlockSpread(BlockSpreadEvent event) {
|
public void onBlockSpread(BlockSpreadEvent event) {
|
||||||
if(event.isCancelled())
|
if(event.isCancelled())
|
||||||
return;
|
return;
|
||||||
DynmapLocation dloc = toLoc(event.getBlock().getLocation());
|
Location loc = event.getBlock().getLocation();
|
||||||
mapManager.sscache.invalidateSnapshot(dloc);
|
String wn = loc.getWorld().getName();
|
||||||
|
mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||||
if(onblockspread) {
|
if(onblockspread) {
|
||||||
mapManager.touch(dloc, "blockspread");
|
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockspread");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -598,24 +602,27 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
|||||||
public void onBlockFromTo(BlockFromToEvent event) {
|
public void onBlockFromTo(BlockFromToEvent event) {
|
||||||
if(event.isCancelled())
|
if(event.isCancelled())
|
||||||
return;
|
return;
|
||||||
DynmapLocation dloc = toLoc(event.getToBlock().getLocation());
|
Location loc = event.getToBlock().getLocation();
|
||||||
mapManager.sscache.invalidateSnapshot(dloc);
|
String wn = loc.getWorld().getName();
|
||||||
|
mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||||
if(onblockfromto)
|
if(onblockfromto)
|
||||||
mapManager.touch(dloc, "blockfromto");
|
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockfromto");
|
||||||
dloc = toLoc(event.getBlock().getLocation());
|
loc = event.getBlock().getLocation();
|
||||||
mapManager.sscache.invalidateSnapshot(dloc);
|
wn = loc.getWorld().getName();
|
||||||
|
mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||||
if(onblockfromto)
|
if(onblockfromto)
|
||||||
mapManager.touch(dloc, "blockfromto");
|
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockfromto");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBlockPhysics(BlockPhysicsEvent event) {
|
public void onBlockPhysics(BlockPhysicsEvent event) {
|
||||||
if(event.isCancelled())
|
if(event.isCancelled())
|
||||||
return;
|
return;
|
||||||
DynmapLocation dloc = toLoc(event.getBlock().getLocation());
|
Location loc = event.getBlock().getLocation();
|
||||||
mapManager.sscache.invalidateSnapshot(dloc);
|
String wn = loc.getWorld().getName();
|
||||||
|
mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||||
if(onblockphysics) {
|
if(onblockphysics) {
|
||||||
mapManager.touch(dloc, "blockphysics");
|
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockphysics");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -631,17 +638,18 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
|||||||
} catch (ClassCastException ccx) {
|
} catch (ClassCastException ccx) {
|
||||||
dir = BlockFace.NORTH;
|
dir = BlockFace.NORTH;
|
||||||
}
|
}
|
||||||
DynmapLocation dloc = toLoc(loc);
|
String wn = loc.getWorld().getName();
|
||||||
mapManager.sscache.invalidateSnapshot(dloc);
|
int x = loc.getBlockX(), y = loc.getBlockY(), z = loc.getBlockZ();
|
||||||
|
mapManager.sscache.invalidateSnapshot(wn, x, y, z);
|
||||||
if(onpiston)
|
if(onpiston)
|
||||||
mapManager.touch(dloc, "pistonretract");
|
mapManager.touch(wn, x, y, z, "pistonretract");
|
||||||
for(int i = 0; i < 2; i++) {
|
for(int i = 0; i < 2; i++) {
|
||||||
dloc.x += dir.getModX();
|
x += dir.getModX();
|
||||||
dloc.y += dir.getModY();
|
y += dir.getModY();
|
||||||
dloc.z += dir.getModZ();
|
z += dir.getModZ();
|
||||||
mapManager.sscache.invalidateSnapshot(dloc);
|
mapManager.sscache.invalidateSnapshot(wn, x, y, z);
|
||||||
if(onpiston)
|
if(onpiston)
|
||||||
mapManager.touch(dloc, "pistonretract");
|
mapManager.touch(wn, x, y, z, "pistonretract");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
@ -650,24 +658,24 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
|||||||
return;
|
return;
|
||||||
Block b = event.getBlock();
|
Block b = event.getBlock();
|
||||||
Location loc = b.getLocation();
|
Location loc = b.getLocation();
|
||||||
DynmapLocation dloc = toLoc(loc);
|
|
||||||
mapManager.sscache.invalidateSnapshot(dloc);
|
|
||||||
BlockFace dir;
|
BlockFace dir;
|
||||||
try { /* Workaround Bukkit bug = http://leaky.bukkit.org/issues/1227 */
|
try { /* Workaround Bukkit bug = http://leaky.bukkit.org/issues/1227 */
|
||||||
dir = event.getDirection();
|
dir = event.getDirection();
|
||||||
} catch (ClassCastException ccx) {
|
} catch (ClassCastException ccx) {
|
||||||
dir = BlockFace.NORTH;
|
dir = BlockFace.NORTH;
|
||||||
}
|
}
|
||||||
mapManager.sscache.invalidateSnapshot(dloc);
|
String wn = loc.getWorld().getName();
|
||||||
|
int x = loc.getBlockX(), y = loc.getBlockY(), z = loc.getBlockZ();
|
||||||
|
mapManager.sscache.invalidateSnapshot(wn, x, y, z);
|
||||||
if(onpiston)
|
if(onpiston)
|
||||||
mapManager.touch(dloc, "pistonretract");
|
mapManager.touch(wn, x, y, z, "pistonretract");
|
||||||
for(int i = 0; i < 1+event.getLength(); i++) {
|
for(int i = 0; i < 1+event.getLength(); i++) {
|
||||||
dloc.x += dir.getModX();
|
x += dir.getModX();
|
||||||
dloc.y += dir.getModY();
|
y += dir.getModY();
|
||||||
dloc.z += dir.getModZ();
|
z += dir.getModZ();
|
||||||
mapManager.sscache.invalidateSnapshot(dloc);
|
mapManager.sscache.invalidateSnapshot(wn, x, y, z);
|
||||||
if(onpiston)
|
if(onpiston)
|
||||||
mapManager.touch(dloc, "pistonretract");
|
mapManager.touch(wn, x, y, z, "pistonretract");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -707,22 +715,16 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
|||||||
registerEvent(Event.Type.BLOCK_PISTON_RETRACT, blockTrigger);
|
registerEvent(Event.Type.BLOCK_PISTON_RETRACT, blockTrigger);
|
||||||
/* Register player event trigger handlers */
|
/* Register player event trigger handlers */
|
||||||
PlayerListener playerTrigger = new PlayerListener() {
|
PlayerListener playerTrigger = new PlayerListener() {
|
||||||
private DynmapLocation dloc = new DynmapLocation();
|
|
||||||
private DynmapLocation toLoc(Location loc) {
|
|
||||||
dloc.x = loc.getBlockX(); dloc.y = loc.getBlockY();
|
|
||||||
dloc.z = loc.getBlockZ(); dloc.world = loc.getWorld().getName();
|
|
||||||
return dloc;
|
|
||||||
}
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||||
toLoc(event.getPlayer().getLocation());
|
Location loc = event.getPlayer().getLocation();
|
||||||
mapManager.touch(dloc, "playerjoin");
|
mapManager.touch(loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "playerjoin");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlayerMove(PlayerMoveEvent event) {
|
public void onPlayerMove(PlayerMoveEvent event) {
|
||||||
toLoc(event.getPlayer().getLocation());
|
Location loc = event.getPlayer().getLocation();
|
||||||
mapManager.touch(dloc, "playermove");
|
mapManager.touch(loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "playermove");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -769,7 +771,6 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
|||||||
|
|
||||||
/* Register world event triggers */
|
/* Register world event triggers */
|
||||||
WorldListener worldTrigger = new WorldListener() {
|
WorldListener worldTrigger = new WorldListener() {
|
||||||
private DynmapLocation dloc = new DynmapLocation();
|
|
||||||
@Override
|
@Override
|
||||||
public void onChunkLoad(ChunkLoadEvent event) {
|
public void onChunkLoad(ChunkLoadEvent event) {
|
||||||
if(ignore_chunk_loads)
|
if(ignore_chunk_loads)
|
||||||
@ -921,10 +922,11 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
|||||||
|
|
||||||
if (c.equals("render") && checkPlayerPermission(sender,"render")) {
|
if (c.equals("render") && checkPlayerPermission(sender,"render")) {
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
int invalidates = mapManager.touch(toLoc(player.getLocation()), "render");
|
Location loc = player.getLocation();
|
||||||
sender.sendMessage("Queued " + invalidates + " tiles" + (invalidates == 0
|
|
||||||
? " (world is not loaded?)"
|
mapManager.touch(loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "render");
|
||||||
: "..."));
|
|
||||||
|
sender.sendMessage("Tile render queued.");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sender.sendMessage("Command can only be issued by player.");
|
sender.sendMessage("Command can only be issued by player.");
|
||||||
@ -1026,7 +1028,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
|||||||
w = mapManager.getWorld(wname);
|
w = mapManager.getWorld(wname);
|
||||||
if(w != null) {
|
if(w != null) {
|
||||||
DynmapLocation spawn = w.getSpawnLocation();
|
DynmapLocation spawn = w.getSpawnLocation();
|
||||||
DynmapLocation loc = new DynmapLocation(wname, w.configuration.getInteger("center/x", spawn.x), w.configuration.getInteger("center/y", spawn.y), w.configuration.getInteger("center/z", spawn.z));
|
DynmapLocation loc = new DynmapLocation(wname, w.configuration.getDouble("center/x", spawn.x), w.configuration.getDouble("center/y", spawn.y), w.configuration.getDouble("center/z", spawn.z));
|
||||||
mapManager.renderFullWorld(loc,sender, map, false);
|
mapManager.renderFullWorld(loc,sender, map, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1701,12 +1703,12 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
|||||||
*
|
*
|
||||||
* @param l0 - first location (required)
|
* @param l0 - first location (required)
|
||||||
* @param l1 - second location (if null, only single point invalidated (l0))
|
* @param l1 - second location (if null, only single point invalidated (l0))
|
||||||
* @return number of tiles queued to be rerendered
|
* @return zero or higher if request queued, -1 if error
|
||||||
*/
|
*/
|
||||||
public int triggerRenderOfVolume(Location l0, Location l1) {
|
public int triggerRenderOfVolume(Location l0, Location l1) {
|
||||||
if(mapManager != null) {
|
if(mapManager != null) {
|
||||||
if(l1 == null)
|
if(l1 == null)
|
||||||
return mapManager.touch(l0.getWorld().getName(), l0.getBlockX(), l0.getBlockY(), l0.getBlockZ(), "api");
|
mapManager.touch(l0.getWorld().getName(), l0.getBlockX(), l0.getBlockY(), l0.getBlockZ(), "api");
|
||||||
else {
|
else {
|
||||||
int minx = Math.min(l0.getBlockX(), l1.getBlockX());
|
int minx = Math.min(l0.getBlockX(), l1.getBlockX());
|
||||||
int maxx = Math.max(l0.getBlockX(), l1.getBlockX());
|
int maxx = Math.max(l0.getBlockX(), l1.getBlockX());
|
||||||
@ -1715,7 +1717,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
|||||||
int minz = Math.min(l0.getBlockZ(), l1.getBlockZ());
|
int minz = Math.min(l0.getBlockZ(), l1.getBlockZ());
|
||||||
int maxz = Math.max(l0.getBlockZ(), l1.getBlockZ());
|
int maxz = Math.max(l0.getBlockZ(), l1.getBlockZ());
|
||||||
|
|
||||||
return mapManager.touchVolume(l0.getWorld().getName(), minx, miny, minz, maxx, maxy, maxz, "api");
|
mapManager.touchVolume(l0.getWorld().getName(), minx, miny, minz, maxx, maxy, maxz, "api");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -1886,8 +1888,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
|||||||
@Override
|
@Override
|
||||||
public int triggerRenderOfBlock(String wid, int x, int y, int z) {
|
public int triggerRenderOfBlock(String wid, int x, int y, int z) {
|
||||||
if(mapManager != null)
|
if(mapManager != null)
|
||||||
return mapManager.touch(wid, x, y, z, "api");
|
mapManager.touch(wid, x, y, z, "api");
|
||||||
else
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1895,9 +1896,9 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
|||||||
public int triggerRenderOfVolume(String wid, int minx, int miny, int minz, int maxx, int maxy, int maxz) {
|
public int triggerRenderOfVolume(String wid, int minx, int miny, int minz, int maxx, int maxy, int maxz) {
|
||||||
if(mapManager != null) {
|
if(mapManager != null) {
|
||||||
if((minx == maxx) && (miny == maxy) && (minz == maxz))
|
if((minx == maxx) && (miny == maxy) && (minz == maxz))
|
||||||
return mapManager.touch(wid, minx, miny, minz, "api");
|
mapManager.touch(wid, minx, miny, minz, "api");
|
||||||
else
|
else
|
||||||
return mapManager.touchVolume(wid, minx, miny, minz, maxx, maxy, maxz, "api");
|
mapManager.touchVolume(wid, minx, miny, minz, maxx, maxy, maxz, "api");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -86,6 +86,32 @@ public class MapManager {
|
|||||||
private DynmapScheduledThreadPoolExecutor render_pool;
|
private DynmapScheduledThreadPoolExecutor render_pool;
|
||||||
private static final int POOL_SIZE = 3;
|
private static final int POOL_SIZE = 3;
|
||||||
|
|
||||||
|
/* Touch event queues */
|
||||||
|
private static class TouchEvent implements Comparable<TouchEvent> {
|
||||||
|
int x, y, z;
|
||||||
|
String world;
|
||||||
|
String reason;
|
||||||
|
@Override
|
||||||
|
public int compareTo(TouchEvent te) {
|
||||||
|
if(x < te.x) return -1;
|
||||||
|
if(x > te.x) return 1;
|
||||||
|
if(y < te.y) return -1;
|
||||||
|
if(y > te.y) return 1;
|
||||||
|
if(z < te.z) return -1;
|
||||||
|
if(z > te.z) return 1;
|
||||||
|
return world.compareTo(te.world);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static class TouchVolumeEvent {
|
||||||
|
int xmin, ymin, zmin;
|
||||||
|
int xmax, ymax, zmax;
|
||||||
|
String world;
|
||||||
|
String reason;
|
||||||
|
}
|
||||||
|
private TreeSet<TouchEvent> touch_events = new TreeSet<TouchEvent>();
|
||||||
|
private LinkedList<TouchVolumeEvent> touch_volume_events = new LinkedList<TouchVolumeEvent>();
|
||||||
|
private Object touch_lock = new Object();
|
||||||
|
|
||||||
private HashMap<String, MapStats> mapstats = new HashMap<String, MapStats>();
|
private HashMap<String, MapStats> mapstats = new HashMap<String, MapStats>();
|
||||||
|
|
||||||
private static class MapStats {
|
private static class MapStats {
|
||||||
@ -94,9 +120,10 @@ public class MapManager {
|
|||||||
int updatedcnt;
|
int updatedcnt;
|
||||||
int transparentcnt;
|
int transparentcnt;
|
||||||
}
|
}
|
||||||
|
/* synchronized using 'lock' */
|
||||||
private HashMap<String, TriggerStats> trigstats = new HashMap<String, TriggerStats>();
|
private HashMap<String, TriggerStats> trigstats = new HashMap<String, TriggerStats>();
|
||||||
|
|
||||||
|
|
||||||
private static class TriggerStats {
|
private static class TriggerStats {
|
||||||
long callsmade;
|
long callsmade;
|
||||||
long callswithtiles;
|
long callswithtiles;
|
||||||
@ -235,10 +262,10 @@ public class MapManager {
|
|||||||
rendertype = RENDERTYPE_FULLRENDER;
|
rendertype = RENDERTYPE_FULLRENDER;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cxmin = (l.x - radius)>>4;
|
cxmin = ((int)l.x - radius)>>4;
|
||||||
czmin = (l.z - radius)>>4;
|
czmin = ((int)l.z - radius)>>4;
|
||||||
cxmax = (l.x + radius+15)>>4;
|
cxmax = ((int)l.x + radius + 15)>>4;
|
||||||
czmax = (l.z + radius+15)>>4;
|
czmax = ((int)l.z + radius + 15)>>4;
|
||||||
rendertype = RENDERTYPE_RADIUSRENDER;
|
rendertype = RENDERTYPE_RADIUSRENDER;
|
||||||
}
|
}
|
||||||
this.mapname = mapname;
|
this.mapname = mapname;
|
||||||
@ -453,7 +480,7 @@ public class MapManager {
|
|||||||
renderedmaps.addAll(map.getMapsSharingRender(world));
|
renderedmaps.addAll(map.getMapsSharingRender(world));
|
||||||
|
|
||||||
/* Now, prime the render queue */
|
/* Now, prime the render queue */
|
||||||
for (MapTile mt : map.getTiles(world, loc.x, loc.y, loc.z)) {
|
for (MapTile mt : map.getTiles(world, (int)loc.x, (int)loc.y, (int)loc.z)) {
|
||||||
if (!found.getFlag(mt.tileOrdinalX(), mt.tileOrdinalY())) {
|
if (!found.getFlag(mt.tileOrdinalX(), mt.tileOrdinalY())) {
|
||||||
found.setFlag(mt.tileOrdinalX(), mt.tileOrdinalY(), true);
|
found.setFlag(mt.tileOrdinalX(), mt.tileOrdinalY(), true);
|
||||||
renderQueue.add(mt);
|
renderQueue.add(mt);
|
||||||
@ -462,7 +489,7 @@ public class MapManager {
|
|||||||
if(!updaterender) { /* Only add other seed points for fullrender */
|
if(!updaterender) { /* Only add other seed points for fullrender */
|
||||||
/* Add spawn location too (helps with some worlds where 0,64,0 may not be generated */
|
/* Add spawn location too (helps with some worlds where 0,64,0 may not be generated */
|
||||||
DynmapLocation sloc = world.getSpawnLocation();
|
DynmapLocation sloc = world.getSpawnLocation();
|
||||||
for (MapTile mt : map.getTiles(world, sloc.x, sloc.y, sloc.z)) {
|
for (MapTile mt : map.getTiles(world, (int)sloc.x, (int)sloc.y, (int)sloc.z)) {
|
||||||
if (!found.getFlag(mt.tileOrdinalX(), mt.tileOrdinalY())) {
|
if (!found.getFlag(mt.tileOrdinalX(), mt.tileOrdinalY())) {
|
||||||
found.setFlag(mt.tileOrdinalX(), mt.tileOrdinalY(), true);
|
found.setFlag(mt.tileOrdinalX(), mt.tileOrdinalY(), true);
|
||||||
renderQueue.add(mt);
|
renderQueue.add(mt);
|
||||||
@ -470,7 +497,7 @@ public class MapManager {
|
|||||||
}
|
}
|
||||||
if(world.seedloc != null) {
|
if(world.seedloc != null) {
|
||||||
for(DynmapLocation seed : world.seedloc) {
|
for(DynmapLocation seed : world.seedloc) {
|
||||||
for (MapTile mt : map.getTiles(world, seed.x, seed.y, seed.z)) {
|
for (MapTile mt : map.getTiles(world, (int)seed.x, (int)seed.y, (int)seed.z)) {
|
||||||
if (!found.getFlag(mt.tileOrdinalX(),mt.tileOrdinalY())) {
|
if (!found.getFlag(mt.tileOrdinalX(),mt.tileOrdinalY())) {
|
||||||
found.setFlag(mt.tileOrdinalX(),mt.tileOrdinalY(), true);
|
found.setFlag(mt.tileOrdinalX(),mt.tileOrdinalY(), true);
|
||||||
renderQueue.add(mt);
|
renderQueue.add(mt);
|
||||||
@ -688,6 +715,13 @@ public class MapManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class DoTouchProcessing implements Runnable {
|
||||||
|
public void run() {
|
||||||
|
processTouchEvents();
|
||||||
|
scheduleDelayedJob(this, 1000); /* Once per second */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public MapManager(DynmapPlugin plugin, ConfigurationNode configuration) {
|
public MapManager(DynmapPlugin plugin, ConfigurationNode configuration) {
|
||||||
plug_in = plugin;
|
plug_in = plugin;
|
||||||
mapman = this;
|
mapman = this;
|
||||||
@ -1010,63 +1044,32 @@ public class MapManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int touch(DynmapLocation l, String reason) {
|
public void touch(String wname, int x, int y, int z, String reason) {
|
||||||
return touch(l.world, l.x, l.y, l.z, reason);
|
TouchEvent evt = new TouchEvent();
|
||||||
|
evt.world = wname;
|
||||||
|
evt.x = x;
|
||||||
|
evt.y = y;
|
||||||
|
evt.z = z;
|
||||||
|
evt.reason = reason;
|
||||||
|
synchronized(touch_lock) {
|
||||||
|
touch_events.add(evt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int touch(String wname, int x, int y, int z, String reason) {
|
public void touchVolume(String wname, int minx, int miny, int minz, int maxx, int maxy, int maxz, String reason) {
|
||||||
DynmapWorld world = getWorld(wname);
|
TouchVolumeEvent evt = new TouchVolumeEvent();
|
||||||
if (world == null)
|
evt.world = wname;
|
||||||
return 0;
|
evt.xmin = minx;
|
||||||
int invalidates = 0;
|
evt.xmax = maxx;
|
||||||
for (int i = 0; i < world.maps.size(); i++) {
|
evt.ymin = miny;
|
||||||
MapTile[] tiles = world.maps.get(i).getTiles(world, x, y, z);
|
evt.ymax = maxy;
|
||||||
for (int j = 0; j < tiles.length; j++) {
|
evt.zmin = minz;
|
||||||
if(invalidateTile(tiles[j]))
|
evt.zmax = maxz;
|
||||||
invalidates++;
|
evt.reason = reason;
|
||||||
|
synchronized(touch_lock) {
|
||||||
|
touch_volume_events.add(evt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(reason != null) {
|
|
||||||
TriggerStats ts = trigstats.get(reason);
|
|
||||||
if(ts == null) {
|
|
||||||
ts = new TriggerStats();
|
|
||||||
trigstats.put(reason, ts);
|
|
||||||
}
|
|
||||||
ts.callsmade++;
|
|
||||||
if(invalidates > 0) {
|
|
||||||
ts.callswithtiles++;
|
|
||||||
ts.tilesqueued += invalidates;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return invalidates;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int touchVolume(String wname, int minx, int miny, int minz, int maxx, int maxy, int maxz, String reason) {
|
|
||||||
DynmapWorld world = getWorld(wname);
|
|
||||||
if (world == null)
|
|
||||||
return 0;
|
|
||||||
int invalidates = 0;
|
|
||||||
for (int i = 0; i < world.maps.size(); i++) {
|
|
||||||
MapTile[] tiles = world.maps.get(i).getTiles(world, minx, miny, minz, maxx, maxy, maxz);
|
|
||||||
for (int j = 0; j < tiles.length; j++) {
|
|
||||||
if(invalidateTile(tiles[j]))
|
|
||||||
invalidates++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(reason != null) {
|
|
||||||
TriggerStats ts = trigstats.get(reason);
|
|
||||||
if(ts == null) {
|
|
||||||
ts = new TriggerStats();
|
|
||||||
trigstats.put(reason, ts);
|
|
||||||
}
|
|
||||||
ts.callsmade++;
|
|
||||||
if(invalidates > 0) {
|
|
||||||
ts.callswithtiles++;
|
|
||||||
ts.tilesqueued += invalidates;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return invalidates;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean invalidateTile(MapTile tile) {
|
public boolean invalidateTile(MapTile tile) {
|
||||||
return tileQueue.push(tile);
|
return tileQueue.push(tile);
|
||||||
@ -1089,6 +1092,7 @@ public class MapManager {
|
|||||||
tileQueue.start();
|
tileQueue.start();
|
||||||
scheduleDelayedJob(new DoZoomOutProcessing(), 60000);
|
scheduleDelayedJob(new DoZoomOutProcessing(), 60000);
|
||||||
scheduleDelayedJob(new CheckWorldTimes(), 5000);
|
scheduleDelayedJob(new CheckWorldTimes(), 5000);
|
||||||
|
scheduleDelayedJob(new DoTouchProcessing(), 1000);
|
||||||
/* Resume pending jobs */
|
/* Resume pending jobs */
|
||||||
for(FullWorldRenderState job : active_renders.values()) {
|
for(FullWorldRenderState job : active_renders.values()) {
|
||||||
scheduleDelayedJob(job, 5000);
|
scheduleDelayedJob(job, 5000);
|
||||||
@ -1401,4 +1405,95 @@ public class MapManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process touch events
|
||||||
|
*/
|
||||||
|
private void processTouchEvents() {
|
||||||
|
TreeSet<TouchEvent> te = null;
|
||||||
|
LinkedList<TouchVolumeEvent> tve = null;
|
||||||
|
synchronized(touch_lock) {
|
||||||
|
if(touch_events.isEmpty() == false) {
|
||||||
|
te = touch_events;
|
||||||
|
touch_events = new TreeSet<TouchEvent>();
|
||||||
|
}
|
||||||
|
if(touch_volume_events.isEmpty() == false) {
|
||||||
|
tve = touch_volume_events;
|
||||||
|
touch_volume_events = new LinkedList<TouchVolumeEvent>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DynmapWorld world = null;
|
||||||
|
String wname = "";
|
||||||
|
|
||||||
|
/* If any touch events, process them */
|
||||||
|
if(te != null) {
|
||||||
|
for(TouchEvent evt : te) {
|
||||||
|
int invalidates = 0;
|
||||||
|
/* If different world, look it up */
|
||||||
|
if(evt.world.equals(wname) == false) {
|
||||||
|
wname = evt.world;
|
||||||
|
world = getWorld(wname);
|
||||||
|
}
|
||||||
|
if(world == null) continue;
|
||||||
|
for (int i = 0; i < world.maps.size(); i++) {
|
||||||
|
MapTile[] tiles = world.maps.get(i).getTiles(world, evt.x, evt.y, evt.z);
|
||||||
|
for (int j = 0; j < tiles.length; j++) {
|
||||||
|
if(invalidateTile(tiles[j]))
|
||||||
|
invalidates++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(evt.reason != null) {
|
||||||
|
synchronized(lock) {
|
||||||
|
TriggerStats ts = trigstats.get(evt.reason);
|
||||||
|
if(ts == null) {
|
||||||
|
ts = new TriggerStats();
|
||||||
|
trigstats.put(evt.reason, ts);
|
||||||
|
}
|
||||||
|
ts.callsmade++;
|
||||||
|
if(invalidates > 0) {
|
||||||
|
ts.callswithtiles++;
|
||||||
|
ts.tilesqueued += invalidates;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
te.clear(); /* Clean up set */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If any volume touches */
|
||||||
|
if(tve != null) {
|
||||||
|
for(TouchVolumeEvent evt : tve) {
|
||||||
|
/* If different world, look it up */
|
||||||
|
if(evt.world.equals(wname) == false) {
|
||||||
|
wname = evt.world;
|
||||||
|
world = getWorld(wname);
|
||||||
|
}
|
||||||
|
if(world == null) continue;
|
||||||
|
int invalidates = 0;
|
||||||
|
for (int i = 0; i < world.maps.size(); i++) {
|
||||||
|
MapTile[] tiles = world.maps.get(i).getTiles(world, evt.xmin, evt.ymin, evt.zmin, evt.xmax, evt.ymax, evt.zmax);
|
||||||
|
for (int j = 0; j < tiles.length; j++) {
|
||||||
|
if(invalidateTile(tiles[j]))
|
||||||
|
invalidates++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(evt.reason != null) {
|
||||||
|
synchronized(lock) {
|
||||||
|
TriggerStats ts = trigstats.get(evt.reason);
|
||||||
|
if(ts == null) {
|
||||||
|
ts = new TriggerStats();
|
||||||
|
trigstats.put(evt.reason, ts);
|
||||||
|
}
|
||||||
|
ts.callsmade++;
|
||||||
|
if(invalidates > 0) {
|
||||||
|
ts.callswithtiles++;
|
||||||
|
ts.tilesqueued += invalidates;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Clean up */
|
||||||
|
tve.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ import java.util.LinkedHashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.bukkit.ChunkSnapshot;
|
import org.bukkit.ChunkSnapshot;
|
||||||
import org.dynmap.DynmapLocation;
|
|
||||||
|
|
||||||
public class SnapshotCache {
|
public class SnapshotCache {
|
||||||
private CacheHashMap snapcache;
|
private CacheHashMap snapcache;
|
||||||
@ -49,24 +48,9 @@ public class SnapshotCache {
|
|||||||
snapcache = new CacheHashMap(max_size);
|
snapcache = new CacheHashMap(max_size);
|
||||||
refqueue = new ReferenceQueue<ChunkSnapshot>();
|
refqueue = new ReferenceQueue<ChunkSnapshot>();
|
||||||
}
|
}
|
||||||
private String getKey(DynmapLocation loc) {
|
|
||||||
return loc.world + ":" + (loc.x>>4) + ":" + (loc.z>>4);
|
|
||||||
}
|
|
||||||
private String getKey(String w, int cx, int cz) {
|
private String getKey(String w, int cx, int cz) {
|
||||||
return w + ":" + cx + ":" + cz;
|
return w + ":" + cx + ":" + cz;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Invalidate cached snapshot, if in cache
|
|
||||||
*/
|
|
||||||
public void invalidateSnapshot(DynmapLocation loc) {
|
|
||||||
String key = getKey(loc);
|
|
||||||
CacheRec rec = snapcache.remove(key);
|
|
||||||
if(rec != null) {
|
|
||||||
snapcache.reverselookup.remove(rec.ref);
|
|
||||||
rec.ref.clear();
|
|
||||||
}
|
|
||||||
processRefQueue();
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* Invalidate cached snapshot, if in cache
|
* Invalidate cached snapshot, if in cache
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user