From f7a5678814cae3ed7dba8c4e3609ba36d9a75cf3 Mon Sep 17 00:00:00 2001 From: NuclearW Date: Sat, 7 Jul 2012 14:42:35 -0400 Subject: [PATCH] Change ChunkletManager to a notify/demand system Allowing NullChunkletManager to bypass the ChunkletUnloader as it is not needed. --- .../nossr50/listeners/WorldListener.java | 2 +- .../nossr50/runnables/ChunkletUnloader.java | 7 ++- .../util/blockmeta/ChunkletManager.java | 32 +++++++++- .../util/blockmeta/HashChunkletManager.java | 63 +++++++++++++------ .../util/blockmeta/NullChunkletManager.java | 15 +++++ 5 files changed, 97 insertions(+), 22 deletions(-) diff --git a/src/main/java/com/gmail/nossr50/listeners/WorldListener.java b/src/main/java/com/gmail/nossr50/listeners/WorldListener.java index d15df92f9..46f501054 100644 --- a/src/main/java/com/gmail/nossr50/listeners/WorldListener.java +++ b/src/main/java/com/gmail/nossr50/listeners/WorldListener.java @@ -33,6 +33,6 @@ public class WorldListener implements Listener { @EventHandler public void onChunkUnload(ChunkUnloadEvent event) { - ChunkletUnloader.addToList(event.getChunk()); + mcMMO.placeStore.chunkUnloaded(event.getChunk().getX(), event.getChunk().getZ(), event.getWorld()); } } diff --git a/src/main/java/com/gmail/nossr50/runnables/ChunkletUnloader.java b/src/main/java/com/gmail/nossr50/runnables/ChunkletUnloader.java index be311660e..de7e33d8f 100644 --- a/src/main/java/com/gmail/nossr50/runnables/ChunkletUnloader.java +++ b/src/main/java/com/gmail/nossr50/runnables/ChunkletUnloader.java @@ -6,6 +6,7 @@ import java.util.Map; import java.util.Map.Entry; import org.bukkit.Chunk; +import org.bukkit.World; import com.gmail.nossr50.mcMMO; @@ -26,6 +27,10 @@ public class ChunkletUnloader implements Runnable { unloadedChunks.put(chunk, 0); } + public static void addToList(int cx, int cz, World world) { + addToList(world.getChunkAt(cx, cz)); + } + @Override public void run() { for (Iterator> it = unloadedChunks.entrySet().iterator() ; it.hasNext() ; ) { @@ -37,7 +42,7 @@ public class ChunkletUnloader implements Runnable { //Chunklets are unloaded only if their chunk has been unloaded for minimumInactiveTime if (inactiveTime >= minimumInactiveTime) { - mcMMO.placeStore.chunkUnloaded(chunk.getX(), chunk.getZ(), chunk.getWorld()); + mcMMO.placeStore.unloadChunk(chunk.getX(), chunk.getZ(), chunk.getWorld()); it.remove(); continue; } diff --git a/src/main/java/com/gmail/nossr50/util/blockmeta/ChunkletManager.java b/src/main/java/com/gmail/nossr50/util/blockmeta/ChunkletManager.java index 245ef4889..7a1d2b7cf 100644 --- a/src/main/java/com/gmail/nossr50/util/blockmeta/ChunkletManager.java +++ b/src/main/java/com/gmail/nossr50/util/blockmeta/ChunkletManager.java @@ -15,7 +15,35 @@ public interface ChunkletManager { public void loadChunklet(int cx, int cy, int cz, World world); /** - * Informs the ChunkletManager a chunk is loaded, it should load appropriate data + * Unload a specific chunklet + * + * @param cx Chunklet X coordinate that needs to be unloaded + * @param cy Chunklet Y coordinate that needs to be unloaded + * @param cz Chunklet Z coordinate that needs to be unloaded + * @param world World that the chunklet needs to be unloaded from + */ + public void unloadChunklet(int cx, int cy, int cz, World world); + + /** + * Load a given Chunk's Chunklet data + * + * @param cx Chunk X coordinate that is to be loaded + * @param cz Chunk Z coordinate that is to be loaded + * @param world World that the Chunk is in + */ + public void loadChunk(int cx, int cz, World world); + + /** + * Unload a given Chunk's Chunklet data + * + * @param cx Chunk X coordinate that is to be unloaded + * @param cz Chunk Z coordinate that is to be unloaded + * @param world World that the Chunk is in + */ + public void unloadChunk(int cx, int cz, World world); + + /** + * Informs the ChunkletManager a chunk is loaded * * @param cx Chunk X coordinate that is loaded * @param cz Chunk Z coordinate that is loaded @@ -24,7 +52,7 @@ public interface ChunkletManager { public void chunkLoaded(int cx, int cz, World world); /** - * Informs the ChunkletManager a chunk is unloaded, it should unload and save appropriate data + * Informs the ChunkletManager a chunk is unloaded * * @param cx Chunk X coordinate that is unloaded * @param cz Chunk Z coordinate that is unloaded diff --git a/src/main/java/com/gmail/nossr50/util/blockmeta/HashChunkletManager.java b/src/main/java/com/gmail/nossr50/util/blockmeta/HashChunkletManager.java index 1aee93fcd..2223073f0 100644 --- a/src/main/java/com/gmail/nossr50/util/blockmeta/HashChunkletManager.java +++ b/src/main/java/com/gmail/nossr50/util/blockmeta/HashChunkletManager.java @@ -16,6 +16,7 @@ import org.bukkit.World; import org.bukkit.block.Block; import com.gmail.nossr50.mcMMO; +import com.gmail.nossr50.runnables.ChunkletUnloader; public class HashChunkletManager implements ChunkletManager { private HashMap store = new HashMap(); @@ -37,28 +38,44 @@ public class HashChunkletManager implements ChunkletManager { } @Override - public void chunkLoaded(int cx, int cz, World world) { - //File dataDir = new File(world.getWorldFolder(), "mcmmo_data"); - //File cxDir = new File(dataDir, "" + cx); - //if(!cxDir.exists()) return; - //File czDir = new File(cxDir, "" + cz); - //if(!czDir.exists()) return; + public void unloadChunklet(int cx, int cy, int cz, World world) { + File dataDir = new File(world.getWorldFolder(), "mcmmo_data"); + if(store.containsKey(world.getName() + "," + cx + "," + cz + "," + cy)) { + File cxDir = new File(dataDir, "" + cx); + if(!cxDir.exists()) cxDir.mkdir(); + File czDir = new File(cxDir, "" + cz); + if(!czDir.exists()) czDir.mkdir(); + File yFile = new File(czDir, "" + cy); - //for(int y = 0; y < 4; y++) { - // File yFile = new File(czDir, "" + y); - // if(!yFile.exists()) { - // continue; - // } else { - // ChunkletStore in = deserializeChunkletStore(yFile); - // if(in != null) { - // store.put(world.getName() + "," + cx + "," + cz + "," + y, in); - // } - // } - //} + ChunkletStore out = store.get(world.getName() + "," + cx + "," + cz + "," + cy); + serializeChunkletStore(out, yFile); + store.remove(world.getName() + "," + cx + "," + cz + "," + cy); + } } @Override - public void chunkUnloaded(int cx, int cz, World world) { + public void loadChunk(int cx, int cz, World world) { + File dataDir = new File(world.getWorldFolder(), "mcmmo_data"); + File cxDir = new File(dataDir, "" + cx); + if(!cxDir.exists()) return; + File czDir = new File(cxDir, "" + cz); + if(!czDir.exists()) return; + + for(int y = 0; y < 4; y++) { + File yFile = new File(czDir, "" + y); + if(!yFile.exists()) { + continue; + } else { + ChunkletStore in = deserializeChunkletStore(yFile); + if(in != null) { + store.put(world.getName() + "," + cx + "," + cz + "," + y, in); + } + } + } + } + + @Override + public void unloadChunk(int cx, int cz, World world) { File dataDir = new File(world.getWorldFolder(), "mcmmo_data"); for(int y = 0; y < 4; y++) { @@ -76,6 +93,16 @@ public class HashChunkletManager implements ChunkletManager { } } + @Override + public void chunkLoaded(int cx, int cz, World world) { + //loadChunk(cx, cz, world); + } + + @Override + public void chunkUnloaded(int cx, int cz, World world) { + ChunkletUnloader.addToList(cx, cx, world); + } + @Override public void saveWorld(World world) { String worldName = world.getName(); diff --git a/src/main/java/com/gmail/nossr50/util/blockmeta/NullChunkletManager.java b/src/main/java/com/gmail/nossr50/util/blockmeta/NullChunkletManager.java index 2f1013faf..b2f137bd3 100644 --- a/src/main/java/com/gmail/nossr50/util/blockmeta/NullChunkletManager.java +++ b/src/main/java/com/gmail/nossr50/util/blockmeta/NullChunkletManager.java @@ -14,6 +14,21 @@ public class NullChunkletManager implements ChunkletManager { return; } + @Override + public void unloadChunklet(int cx, int cy, int cz, World world) { + return; + } + + @Override + public void loadChunk(int cx, int cz, World world) { + return; + } + + @Override + public void unloadChunk(int cx, int cz, World world) { + return; + } + @Override public void chunkLoaded(int cx, int cz, World world) { return;