From 610981b7b8e305695ec9ec739abfc9038cfa8d98 Mon Sep 17 00:00:00 2001 From: Forwolk Date: Sat, 4 Aug 2018 13:19:08 +0300 Subject: [PATCH] World <-- Region <-- Chunk Weak references --- core/src/main/java/mc/core/world/Chunk.java | 7 +++-- core/src/main/java/mc/core/world/Region.java | 2 ++ .../main/java/mc/world/flat/SimpleChunk.java | 12 ++++++++ .../generated_world/chunk/ChunkImpl.java | 28 +++++++++++++++---- .../generated_world/chunk/ChunkProxy.java | 14 ++++++++++ .../generated_world/region/RegionImpl.java | 20 +++++++++---- 6 files changed, 71 insertions(+), 12 deletions(-) diff --git a/core/src/main/java/mc/core/world/Chunk.java b/core/src/main/java/mc/core/world/Chunk.java index 0b712b0..6b63845 100644 --- a/core/src/main/java/mc/core/world/Chunk.java +++ b/core/src/main/java/mc/core/world/Chunk.java @@ -45,6 +45,9 @@ public interface Chunk extends Serializable{ int getY(); int getZ(); - void setBlock (int x, int y, int z, Block block); - Block getBlock (int x, int y, int z); + void setBlock(int x, int y, int z, Block block); + Block getBlock(int x, int y, int z); + + Region getRegion(); + World getWorld(); } diff --git a/core/src/main/java/mc/core/world/Region.java b/core/src/main/java/mc/core/world/Region.java index dec2730..e2f1371 100644 --- a/core/src/main/java/mc/core/world/Region.java +++ b/core/src/main/java/mc/core/world/Region.java @@ -30,5 +30,7 @@ public interface Region extends Serializable{ Biome getBiomeAt (int x, int z); void setBiome (int x, int z, Biome biome); + World getWorld(); + void save(Serializer chunkSerializer, IRegionReaderWriter regionReaderWritter) throws IOException; } diff --git a/flat_world/src/main/java/mc/world/flat/SimpleChunk.java b/flat_world/src/main/java/mc/world/flat/SimpleChunk.java index 03ad6ad..ee5eaab 100644 --- a/flat_world/src/main/java/mc/world/flat/SimpleChunk.java +++ b/flat_world/src/main/java/mc/world/flat/SimpleChunk.java @@ -9,6 +9,8 @@ import mc.core.block.BlockFactory; import mc.core.block.BlockType; import mc.core.world.Biome; import mc.core.world.Chunk; +import mc.core.world.Region; +import mc.core.world.World; public class SimpleChunk implements Chunk { @Override @@ -104,4 +106,14 @@ public class SimpleChunk implements Chunk { else if (y == 3) return blockFactory.create(BlockType.GRASS, 0); else return Block.airBlock(x, y, z); } + + @Override + public Region getRegion() { + throw new UnsupportedOperationException(); + } + + @Override + public World getWorld() { + throw new UnsupportedOperationException(); + } } diff --git a/generated_world/src/main/java/mc/world/generated_world/chunk/ChunkImpl.java b/generated_world/src/main/java/mc/world/generated_world/chunk/ChunkImpl.java index f9abc9a..fad881c 100644 --- a/generated_world/src/main/java/mc/world/generated_world/chunk/ChunkImpl.java +++ b/generated_world/src/main/java/mc/world/generated_world/chunk/ChunkImpl.java @@ -1,16 +1,17 @@ package mc.world.generated_world.chunk; import lombok.Getter; -import lombok.RequiredArgsConstructor; import mc.core.block.Block; import mc.core.block.BlockType; import mc.core.world.Biome; import mc.core.world.Chunk; import mc.core.world.Region; +import mc.core.world.World; + +import java.lang.ref.WeakReference; import static mc.world.generated_world.WorldConstants.WORLD_CHUNK_SIZE; -@RequiredArgsConstructor public class ChunkImpl implements Chunk{ @Getter private final int x; @@ -19,7 +20,14 @@ public class ChunkImpl implements Chunk{ @Getter private final int z; private final Block[][][] blocks = new Block[WORLD_CHUNK_SIZE][WORLD_CHUNK_SIZE][WORLD_CHUNK_SIZE]; - private final transient Region region; + private final transient WeakReference region; + + public ChunkImpl(int x, int y, int z, Region region) { + this.x = x; + this.y = y; + this.z = z; + this.region = new WeakReference<>(region); + } @Override public int getBlockType(int x, int y, int z) { @@ -73,12 +81,12 @@ public class ChunkImpl implements Chunk{ @Override public Biome getBiome(int x, int z) { - return region.getBiomeAt(x + this.x * WORLD_CHUNK_SIZE,z + this.z * WORLD_CHUNK_SIZE); + return getRegion().getBiomeAt(x + this.x * WORLD_CHUNK_SIZE,z + this.z * WORLD_CHUNK_SIZE); } @Override public void setBiome(int x, int z, Biome biome) { - region.setBiome(x + this.x * WORLD_CHUNK_SIZE,z + this.z * WORLD_CHUNK_SIZE, biome); + getRegion().setBiome(x + this.x * WORLD_CHUNK_SIZE,z + this.z * WORLD_CHUNK_SIZE, biome); } @Override @@ -98,4 +106,14 @@ public class ChunkImpl implements Chunk{ } return blocks[x][y][z]; } + + @Override + public Region getRegion() { + return region.get(); + } + + @Override + public World getWorld() { + return getRegion().getWorld(); + } } diff --git a/generated_world/src/main/java/mc/world/generated_world/chunk/ChunkProxy.java b/generated_world/src/main/java/mc/world/generated_world/chunk/ChunkProxy.java index 4490001..fb03d6d 100644 --- a/generated_world/src/main/java/mc/world/generated_world/chunk/ChunkProxy.java +++ b/generated_world/src/main/java/mc/world/generated_world/chunk/ChunkProxy.java @@ -3,6 +3,8 @@ package mc.world.generated_world.chunk; import mc.core.block.Block; import mc.core.world.Biome; import mc.core.world.Chunk; +import mc.core.world.Region; +import mc.core.world.World; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -129,4 +131,16 @@ public class ChunkProxy implements Chunk { use(); return chunk.getBlock(x, y, z); } + + @Override + public Region getRegion() { + use(); + return chunk.getRegion(); + } + + @Override + public World getWorld() { + use(); + return chunk.getWorld(); + } } diff --git a/generated_world/src/main/java/mc/world/generated_world/region/RegionImpl.java b/generated_world/src/main/java/mc/world/generated_world/region/RegionImpl.java index 812512f..643644d 100644 --- a/generated_world/src/main/java/mc/world/generated_world/region/RegionImpl.java +++ b/generated_world/src/main/java/mc/world/generated_world/region/RegionImpl.java @@ -14,12 +14,12 @@ import org.springframework.beans.factory.annotation.Autowired; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import java.lang.ref.WeakReference; import java.text.MessageFormat; import static mc.world.generated_world.WorldConstants.*; @Slf4j -@RequiredArgsConstructor public class RegionImpl implements Region{ @Getter private final int x; @@ -27,18 +27,23 @@ public class RegionImpl implements Region{ private final int z; private final ChunkProxy[][][] chunks = new ChunkProxy[WORLD_REGION_SIZE/WORLD_CHUNK_SIZE][WORLD_REGION_SIZE/WORLD_CHUNK_SIZE][WORLD_REGION_SIZE/WORLD_CHUNK_SIZE]; private final Biome[][] biomes = new Biome[WORLD_REGION_SIZE][WORLD_REGION_SIZE]; - @Getter - private final transient World world; + private final transient WeakReference world; @Autowired private ChunkLoader chunkLoader; + public RegionImpl (int x, int z, World world) { + this.x = x; + this.z = z; + this.world = new WeakReference<>(world); + } + @Override public Chunk getChunkAt(int x, int y, int z) { if (x < 0 || y < 0 || z < 0 || x >= 16 || y >= 16 || z >= 16) { throw new RuntimeException(MessageFormat.format("Invalid chunk coordinates [{0} {1} {2}]", x, y, z)); } if (chunkLoader == null) { - chunkLoader = new InMemoryCacheChunkLoader(world); + chunkLoader = new InMemoryCacheChunkLoader(getWorld()); } Chunk chunk = chunks[x][y][z]; if (chunk == null) { @@ -72,10 +77,15 @@ public class RegionImpl implements Region{ biomes[x][z] = biome; } + @Override + public World getWorld() { + return world.get(); + } + @Override public void save(Serializer chunkSerializer, IRegionReaderWriter regionReaderWriter) throws IOException { String worldPath = System.getProperty("worlds.folder", "worlds"); - File worldFile = new File(worldPath, world.getWorldId().toString()); + File worldFile = new File(worldPath, getWorld().getWorldId().toString()); File regionFile = new File(worldFile, MessageFormat.format(REGION_FILE_NAME_TEMPLATE, this.getX(), this.getZ())); if (!regionFile.exists()) { regionFile.mkdirs();