package net.CyanWool.world;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;
import net.CyanWool.api.io.ChunkIOService;
import net.CyanWool.api.world.Chunk;
import net.CyanWool.api.world.ChunkCoords;
import net.CyanWool.api.world.ChunkManager;
import net.CyanWool.api.world.World;
public class CyanChunkManager implements ChunkManager {
private World world;
private ConcurrentMap<ChunkCoords, Chunk> chunks;
private ChunkIOService service;
public CyanChunkManager(World world, ChunkIOService service) {
this.world = world;
this.service = service;
this.chunks = new ConcurrentHashMap<ChunkCoords, Chunk>();
}
@Override
public Chunk getChunk(int x, int z) {
ChunkCoords coords = new ChunkCoords(x, z);
if (chunks.containsKey(coords)) {
return chunks.get(coords);
} else {
loadChunk(x, z);
return chunks.get(coords);
}
}
@Override
public boolean isChunkLoaded(int x, int z) {
ChunkCoords coords = new ChunkCoords(x, z);
return chunks.containsKey(coords) && chunks.get(coords).isLoaded();
}
@Override
public boolean isChunkInUse(int x, int z) {
ChunkCoords coords = new ChunkCoords(x, z);
Chunk chunk = chunks.get(coords);
return chunk != null && !chunk.getPlayers().isEmpty();
}
@Override
public boolean loadChunk(int x, int z) {
Chunk chunk = service.readChunk(x, z);
ChunkCoords coords = new ChunkCoords(x, z);
chunks.put(coords, chunk);
boolean generate = chunk.isNeedGenerate();
if (!generate) {
return true;
}
generateChunk(chunk);
return true;
}
@Override
public void unloadChunk(Chunk chunk) {
ChunkCoords coords = new ChunkCoords(chunk.getX(), chunk.getZ());
chunks.remove(coords);
service.saveChunk(chunk);
}
@Override
public void generateChunk(Chunk chunk) {
world.getGenerator().generate(chunk.getX(), chunk.getZ());
}
@Override
public List<Chunk> getLoadedChunks() {
List<Chunk> result = new CopyOnWriteArrayList<Chunk>();
for (Chunk chunk : chunks.values()) {
if (chunk.isLoaded()) {
result.add(chunk);
}
}
return result;
}
@Override
public Chunk getChunkFromChunkCoords(int x, int z) {
return getChunk(x, z);
}
@Override
public Chunk getChunkFromBlockCoords(int x, int z) {
return getChunk(x >> 4, z >> 4);
}
@Override
public void saveChunks() {
for (Chunk chunk : getLoadedChunks()) {
unloadChunk(chunk);
}
}
@Override
public void onTick() {
// Auto unload chunks
for (Chunk chunk : getLoadedChunks()) {
if (!chunk.isLocked() && chunk.getUsedPlayers() == 0) {
unloadChunk(chunk);
}
}
}
}