From 4107e7aab80e17899206c91c60215729bd62da60 Mon Sep 17 00:00:00 2001 From: Hilligans Date: Fri, 27 Oct 2023 22:09:13 -0600 Subject: [PATCH] World system work --- pom.xml | 11 +++ .../dev/hilligans/ourcraft/Block/Block.java | 18 +++- .../dev/hilligans/ourcraft/ClientMain.java | 1 + .../Engine/EngineImplementationException.java | 9 ++ .../ourcraft/ModHandler/ModLoader.java | 1 + .../Packet/NewSystem/Client/SSendChunk.java | 22 +++++ .../Client/SSendWorldSystemFormat.java | 24 ++++++ .../hilligans/ourcraft/Network/Protocols.java | 7 ++ .../Server/Concurrent/ITickableTask.java | 3 +- .../ourcraft/Server/Concurrent/Lock.java | 12 ++- .../Server/Concurrent/TickingBase.java | 5 +- .../hilligans/ourcraft/Server/IServer.java | 1 - .../ourcraft/Server/Tasks/ChunkTask.java | 28 ------ .../dev/hilligans/ourcraft/World/Chunk.java | 12 +++ .../hilligans/ourcraft/World/ClientWorld.java | 34 -------- .../Modifications/IWorldModification.java | 37 ++++++++ .../SetBlock/SetSingleModification.java | 80 +++++++++++++++++ .../World/NewWorldSystem/ClassicChunk.java | 16 ++++ .../World/NewWorldSystem/CubicChunk.java | 76 +++++++++++++--- .../GlobalPaletteAtomicSubChunk.java | 45 +++++----- .../NewWorldSystem/GlobalPaletteImpl.java | 5 ++ .../World/NewWorldSystem/IAtomicChunk.java | 4 + .../ourcraft/World/NewWorldSystem/IChunk.java | 23 +++++ .../World/NewWorldSystem/IServerWorld.java | 6 ++ .../NewWorldSystem/IServerWorldBase.java | 28 ++++++ .../World/NewWorldSystem/ISubChunk.java | 6 ++ .../NewWorldSystem/PalettedSubChunk.java | 70 +++++++++++++-- .../NewWorldSystem/ServerCubicWorld.java | 14 ++- .../NewWorldSystem/SimpleServerWorld.java | 12 ++- .../NewWorldSystem/SimpleSubChunkImpl.java | 5 ++ .../SingleBlockFinalSubChunk.java | 74 ++++++++++++++++ .../ourcraft/World/Tasks/ChunkTickTask.java | 86 +++++++++++++++++++ .../dev/hilligans/ourcraft/World/World.java | 21 ----- 33 files changed, 660 insertions(+), 136 deletions(-) create mode 100644 src/main/java/dev/hilligans/ourcraft/Engine/EngineImplementationException.java create mode 100644 src/main/java/dev/hilligans/ourcraft/Network/Packet/NewSystem/Client/SSendChunk.java create mode 100644 src/main/java/dev/hilligans/ourcraft/Network/Packet/NewSystem/Client/SSendWorldSystemFormat.java delete mode 100644 src/main/java/dev/hilligans/ourcraft/Server/Tasks/ChunkTask.java create mode 100644 src/main/java/dev/hilligans/ourcraft/World/Modifications/IWorldModification.java create mode 100644 src/main/java/dev/hilligans/ourcraft/World/Modifications/SetBlock/SetSingleModification.java create mode 100644 src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/IServerWorldBase.java create mode 100644 src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/SingleBlockFinalSubChunk.java create mode 100644 src/main/java/dev/hilligans/ourcraft/World/Tasks/ChunkTickTask.java diff --git a/pom.xml b/pom.xml index 0ee28eb1..194503a0 100644 --- a/pom.xml +++ b/pom.xml @@ -158,6 +158,17 @@ annotations 23.0.0 + + + + org.lwjgl + lwjgl-assimp + + + org.lwjgl + lwjgl-assimp + ${lwjgl.natives} + diff --git a/src/main/java/dev/hilligans/ourcraft/Block/Block.java b/src/main/java/dev/hilligans/ourcraft/Block/Block.java index a1013298..cce391b5 100644 --- a/src/main/java/dev/hilligans/ourcraft/Block/Block.java +++ b/src/main/java/dev/hilligans/ourcraft/Block/Block.java @@ -3,7 +3,8 @@ import dev.hilligans.ourcraft.Block.BlockState.BlockStateBuilder; import dev.hilligans.ourcraft.Block.BlockState.IBlockState; import dev.hilligans.ourcraft.Client.Rendering.Graphics.IPrimitiveBuilder; -import dev.hilligans.ourcraft.World.NewWorldSystem.IMethodResult; +import dev.hilligans.ourcraft.Server.Concurrent.Lock; +import dev.hilligans.ourcraft.World.NewWorldSystem.*; import dev.hilligans.ourcraft.Client.MatrixStack; import dev.hilligans.ourcraft.Client.Rendering.NewRenderer.PrimitiveBuilder; import dev.hilligans.ourcraft.Client.Rendering.NewRenderer.TextAtlas; @@ -26,7 +27,6 @@ import dev.hilligans.ourcraft.Util.Side; import dev.hilligans.ourcraft.World.DataProvider; import dev.hilligans.ourcraft.World.DataProviders.ShortBlockState; -import dev.hilligans.ourcraft.World.NewWorldSystem.IWorld; import dev.hilligans.ourcraft.World.World; import dev.hilligans.ourcraft.Block.BlockState.IBlockStateTable; import org.joml.Vector3d; @@ -233,6 +233,20 @@ public IBlockState randomTick(IMethodResult result, IBlockState state, IWorld wo return null; } + public void randomTick(Lock lock, IMethodResult methodResult, IBlockState state, IChunk chunk, IWorld world, BlockPos pos, Random random) { + IBlockState newState = randomTick(methodResult, state, world, pos, random); + if(newState != null) { + if(chunk instanceof IAtomicChunk atomicChunk) { + atomicChunk.setBlockStateAtomic(lock, pos.x, pos.y, pos.z, newState); + } else { + if(!lock.hasLock(chunk.getChunkPos())) { + lock.acquire(chunk.getChunkPos()); + } + chunk.setBlockState(pos.x, pos.y, pos.z, newState); + } + } + } + //TODO add break source public void onBreak(IMethodResult result, IBlockState state, IWorld world) {} diff --git a/src/main/java/dev/hilligans/ourcraft/ClientMain.java b/src/main/java/dev/hilligans/ourcraft/ClientMain.java index 2f67c20b..0b886784 100644 --- a/src/main/java/dev/hilligans/ourcraft/ClientMain.java +++ b/src/main/java/dev/hilligans/ourcraft/ClientMain.java @@ -12,6 +12,7 @@ import java.io.IOException; import java.lang.invoke.VarHandle; import java.lang.reflect.Field; +import java.util.*; import java.util.concurrent.locks.LockSupport; import static java.lang.StringTemplate.STR; diff --git a/src/main/java/dev/hilligans/ourcraft/Engine/EngineImplementationException.java b/src/main/java/dev/hilligans/ourcraft/Engine/EngineImplementationException.java new file mode 100644 index 00000000..c99b1724 --- /dev/null +++ b/src/main/java/dev/hilligans/ourcraft/Engine/EngineImplementationException.java @@ -0,0 +1,9 @@ +package dev.hilligans.ourcraft.Engine; + +public class EngineImplementationException extends RuntimeException { + + public EngineImplementationException(String message) { + super(message); + } + +} diff --git a/src/main/java/dev/hilligans/ourcraft/ModHandler/ModLoader.java b/src/main/java/dev/hilligans/ourcraft/ModHandler/ModLoader.java index 5d42df78..3819dfba 100644 --- a/src/main/java/dev/hilligans/ourcraft/ModHandler/ModLoader.java +++ b/src/main/java/dev/hilligans/ourcraft/ModHandler/ModLoader.java @@ -37,6 +37,7 @@ public ModContent requestMod(String modID) { } public void loadDefaultMods() { + //System.out.println("Java " + System.getProperty("java.version")); loadAllMods(new File("mods/")); if(true) { loadClasses(new File("target/classes/"), ""); diff --git a/src/main/java/dev/hilligans/ourcraft/Network/Packet/NewSystem/Client/SSendChunk.java b/src/main/java/dev/hilligans/ourcraft/Network/Packet/NewSystem/Client/SSendChunk.java new file mode 100644 index 00000000..444f717a --- /dev/null +++ b/src/main/java/dev/hilligans/ourcraft/Network/Packet/NewSystem/Client/SSendChunk.java @@ -0,0 +1,22 @@ +package dev.hilligans.ourcraft.Network.Packet.NewSystem.Client; + +import dev.hilligans.ourcraft.Network.PacketBase; +import dev.hilligans.ourcraft.Network.PacketData; + +public class SSendChunk extends PacketBase { + + + @Override + public void encode(PacketData packetData) { + + } + + @Override + public void decode(PacketData packetData) { + } + + @Override + public void handle() { + + } +} diff --git a/src/main/java/dev/hilligans/ourcraft/Network/Packet/NewSystem/Client/SSendWorldSystemFormat.java b/src/main/java/dev/hilligans/ourcraft/Network/Packet/NewSystem/Client/SSendWorldSystemFormat.java new file mode 100644 index 00000000..6ba19af1 --- /dev/null +++ b/src/main/java/dev/hilligans/ourcraft/Network/Packet/NewSystem/Client/SSendWorldSystemFormat.java @@ -0,0 +1,24 @@ +package dev.hilligans.ourcraft.Network.Packet.NewSystem.Client; + +import dev.hilligans.ourcraft.Network.PacketBase; +import dev.hilligans.ourcraft.Network.PacketData; + +public class SSendWorldSystemFormat extends PacketBase { + + + + @Override + public void encode(PacketData packetData) { + + } + + @Override + public void decode(PacketData packetData) { + + } + + @Override + public void handle() { + + } +} diff --git a/src/main/java/dev/hilligans/ourcraft/Network/Protocols.java b/src/main/java/dev/hilligans/ourcraft/Network/Protocols.java index a5bf9ae4..794b62b3 100644 --- a/src/main/java/dev/hilligans/ourcraft/Network/Protocols.java +++ b/src/main/java/dev/hilligans/ourcraft/Network/Protocols.java @@ -3,6 +3,8 @@ import dev.hilligans.ourcraft.ModHandler.Content.ModContent; import dev.hilligans.ourcraft.Network.Packet.AuthServerPackets.*; import dev.hilligans.ourcraft.Network.Packet.Client.*; +import dev.hilligans.ourcraft.Network.Packet.NewSystem.Client.SSendChunk; +import dev.hilligans.ourcraft.Network.Packet.NewSystem.Client.SSendWorldSystemFormat; import dev.hilligans.ourcraft.Network.Packet.Server.*; public class Protocols { @@ -46,6 +48,11 @@ public static void register(ModContent modContent) { modContent.registerPacket("Auth", CGetToken::new); modContent.registerPacket("Auth", CTokenValid::new); modContent.registerPacket("Auth", CLogin::new); + + modContent.registerPacket("World", SSendWorldSystemFormat::new); + modContent.registerPacket("World", SSendChunk::new); + + } } diff --git a/src/main/java/dev/hilligans/ourcraft/Server/Concurrent/ITickableTask.java b/src/main/java/dev/hilligans/ourcraft/Server/Concurrent/ITickableTask.java index 7e7d1757..de0a74e4 100644 --- a/src/main/java/dev/hilligans/ourcraft/Server/Concurrent/ITickableTask.java +++ b/src/main/java/dev/hilligans/ourcraft/Server/Concurrent/ITickableTask.java @@ -1,12 +1,13 @@ package dev.hilligans.ourcraft.Server.Concurrent; +import dev.hilligans.ourcraft.World.NewWorldSystem.IWorld; import dev.hilligans.ourcraft.World.World; public interface ITickableTask extends Runnable { void stop(); - void start(World world, ChunkLocker chunkLocker); + void start(IWorld world, ChunkLocker chunkLocker); void setParker(ParkerUnparker parkerUnparker); diff --git a/src/main/java/dev/hilligans/ourcraft/Server/Concurrent/Lock.java b/src/main/java/dev/hilligans/ourcraft/Server/Concurrent/Lock.java index 702c7ae6..6e4cf5d8 100644 --- a/src/main/java/dev/hilligans/ourcraft/Server/Concurrent/Lock.java +++ b/src/main/java/dev/hilligans/ourcraft/Server/Concurrent/Lock.java @@ -8,7 +8,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.LockSupport; -public class Lock { +public class Lock implements AutoCloseable { public boolean hasAllLocks = false; @@ -59,17 +59,18 @@ public boolean hasAllLocks() { public void acquire(long... positions) {} - public void acquire(ChunkPos chunkPos) { + public Lock acquire(ChunkPos chunkPos) { for(ChunkPos chunkPos1 : chunkPositions) { if(chunkPos1.equals(chunkPos)) { acquire(); - return; + return this; } } ChunkPos[] chunkPosList = new ChunkPos[chunkPositions.length + 1]; System.arraycopy(chunkPositions,0, chunkPosList, 0, chunkPositions.length); chunkPosList[chunkPositions.length] = chunkPos; this.chunkPositions = chunkPosList; + return this; } public void acquire() { @@ -79,4 +80,9 @@ public void acquire() { public void release() { chunkLocker.release(this); } + + @Override + public void close() { + release(); + } } diff --git a/src/main/java/dev/hilligans/ourcraft/Server/Concurrent/TickingBase.java b/src/main/java/dev/hilligans/ourcraft/Server/Concurrent/TickingBase.java index 09747709..cea9e9f3 100644 --- a/src/main/java/dev/hilligans/ourcraft/Server/Concurrent/TickingBase.java +++ b/src/main/java/dev/hilligans/ourcraft/Server/Concurrent/TickingBase.java @@ -1,5 +1,6 @@ package dev.hilligans.ourcraft.Server.Concurrent; +import dev.hilligans.ourcraft.World.NewWorldSystem.IWorld; import dev.hilligans.ourcraft.World.World; public abstract class TickingBase implements ITickableTask { @@ -8,7 +9,7 @@ public abstract class TickingBase implements ITickableTask { public ParkerUnparker parkerUnparker; public Thread owner; - public World world; + public IWorld world; public ChunkLocker chunkLocker; @@ -18,7 +19,7 @@ public void stop() { } @Override - public void start(World world, ChunkLocker chunkLocker) { + public void start(IWorld world, ChunkLocker chunkLocker) { this.world = world; this.chunkLocker = chunkLocker; owner = Thread.startVirtualThread(this); diff --git a/src/main/java/dev/hilligans/ourcraft/Server/IServer.java b/src/main/java/dev/hilligans/ourcraft/Server/IServer.java index 3ad31169..44eede67 100644 --- a/src/main/java/dev/hilligans/ourcraft/Server/IServer.java +++ b/src/main/java/dev/hilligans/ourcraft/Server/IServer.java @@ -45,7 +45,6 @@ public void run() { } } } - } diff --git a/src/main/java/dev/hilligans/ourcraft/Server/Tasks/ChunkTask.java b/src/main/java/dev/hilligans/ourcraft/Server/Tasks/ChunkTask.java deleted file mode 100644 index 33ac0058..00000000 --- a/src/main/java/dev/hilligans/ourcraft/Server/Tasks/ChunkTask.java +++ /dev/null @@ -1,28 +0,0 @@ -package dev.hilligans.ourcraft.Server.Tasks; - -import dev.hilligans.ourcraft.Data.Other.ChunkPos; -import dev.hilligans.ourcraft.Server.Concurrent.ITickableTask; -import dev.hilligans.ourcraft.Server.Concurrent.Lock; -import dev.hilligans.ourcraft.Server.Concurrent.TickingBase; -import dev.hilligans.ourcraft.World.NewWorldSystem.IChunk; - -public class ChunkTask extends TickingBase { - - public IChunk chunk; - - public ChunkTask(IChunk chunk) { - this.chunk = chunk; - } - - - - @Override - public void tick() { - //we make the lock with all the chunk positions we want - Lock lock = new Lock(chunkLocker, new ChunkPos(chunk.getX(), chunk.getY(), chunk.getZ())); - //we can then acquire it when we need it - lock.acquire(); - //and release it when we no longer need it - lock.release(); - } -} diff --git a/src/main/java/dev/hilligans/ourcraft/World/Chunk.java b/src/main/java/dev/hilligans/ourcraft/World/Chunk.java index 6c6ac661..daab950b 100644 --- a/src/main/java/dev/hilligans/ourcraft/World/Chunk.java +++ b/src/main/java/dev/hilligans/ourcraft/World/Chunk.java @@ -28,6 +28,8 @@ import java.util.ArrayList; import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.UnaryOperator; import static org.lwjgl.opengl.GL11.*; import static org.lwjgl.opengl.GL15.glGetBufferSubData; @@ -235,11 +237,21 @@ public boolean isEmpty() { return false; } + @Override + public int getSubChunkCount() { + return 0; + } + @Override public void forEach(Consumer consumer) { } + @Override + public void replace(UnaryOperator replacer) { + + } + @Override public void setDirty(boolean value) { diff --git a/src/main/java/dev/hilligans/ourcraft/World/ClientWorld.java b/src/main/java/dev/hilligans/ourcraft/World/ClientWorld.java index 0a172104..fbab5836 100644 --- a/src/main/java/dev/hilligans/ourcraft/World/ClientWorld.java +++ b/src/main/java/dev/hilligans/ourcraft/World/ClientWorld.java @@ -66,38 +66,10 @@ public void tick() { } } else { - /*if(Settings.asyncChunkBuilding) { - while(!queuedChunks.isEmpty()) { - SubChunk subChunk = queuedChunks.poll(); - ClientUtil.chunkBuilder.submit(() -> { - PrimitiveBuilder primitiveBuilder = subChunk.getMeshBuilder(); - asyncChunkQueue.add(new Tuple<>(primitiveBuilder,subChunk)); - }); - } - - while(!asyncChunkQueue.isEmpty()) { - Tuple type = asyncChunkQueue.poll(); - type.getTypeB().verticesCount = type.getTypeA().indices.size(); - type.getTypeB().id = VAOManager.createVAO(type.getTypeA()); - } - } else { - buildChunks(12); - } - purgeTime++; - - */ } } - - public void setChunk(Chunk chunk) { - super.setChunk(chunk); - miniMap.update(chunk.x,chunk.z); - } - - - int purgeTime = 0; public void purgeChunks(int distance) { @@ -134,12 +106,6 @@ public void reloadChunks() { }); } - - public void requestChunk(int x, int z) { - client.sendPacket(new CRequestChunkPacket(x, z)); - set.add((long)x | (long) z << 32); - } - public void playSound(SoundBuffer soundBuffer, Vector3d pos) { if(Settings.sounds) { ClientMain.getClient().soundEngine.addSound(soundBuffer,pos); diff --git a/src/main/java/dev/hilligans/ourcraft/World/Modifications/IWorldModification.java b/src/main/java/dev/hilligans/ourcraft/World/Modifications/IWorldModification.java new file mode 100644 index 00000000..91d0e34a --- /dev/null +++ b/src/main/java/dev/hilligans/ourcraft/World/Modifications/IWorldModification.java @@ -0,0 +1,37 @@ +package dev.hilligans.ourcraft.World.Modifications; + +import dev.hilligans.ourcraft.Data.Other.BlockPos; +import dev.hilligans.ourcraft.Server.Concurrent.Lock; +import dev.hilligans.ourcraft.World.NewWorldSystem.IChunk; + +public interface IWorldModification { + + void apply(Lock lock, IChunk chunk); + + BlockPos getMin(); + BlockPos getMax(); + + default long getMinX() { + return getMin().x; + } + default long getMinY() { + return getMin().y; + } + default long getMinZ() { + return getMin().z; + } + default long getMaxX() { + return getMax().x; + } + default long getMaxY() { + return getMax().y; + } + default long getMaxZ() { + return getMax().z; + } + + default public boolean isWholeInside(IChunk chunk) { + return (getMinX() <= chunk.getBlockX() && getMinY() <= chunk.getBlockY() && getMinZ() <= chunk.getBlockZ()) && + (getMaxX() >= chunk.getBlockMaxX() && getMaxY() >= chunk.getBlockMaxY() && getMaxZ() >= chunk.getBlockMaxZ()); + } +} diff --git a/src/main/java/dev/hilligans/ourcraft/World/Modifications/SetBlock/SetSingleModification.java b/src/main/java/dev/hilligans/ourcraft/World/Modifications/SetBlock/SetSingleModification.java new file mode 100644 index 00000000..fb958dce --- /dev/null +++ b/src/main/java/dev/hilligans/ourcraft/World/Modifications/SetBlock/SetSingleModification.java @@ -0,0 +1,80 @@ +package dev.hilligans.ourcraft.World.Modifications.SetBlock; + +import dev.hilligans.ourcraft.Block.BlockState.IBlockState; +import dev.hilligans.ourcraft.Data.Other.BlockPos; +import dev.hilligans.ourcraft.Server.Concurrent.Lock; +import dev.hilligans.ourcraft.World.Modifications.IWorldModification; +import dev.hilligans.ourcraft.World.NewWorldSystem.IAtomicChunk; +import dev.hilligans.ourcraft.World.NewWorldSystem.IChunk; +import dev.hilligans.ourcraft.World.NewWorldSystem.SingleBlockFinalSubChunk; + +public class SetSingleModification implements IWorldModification { + + public final BlockPos min; + public final BlockPos max; + public final IBlockState blockState; + + public SetSingleModification(BlockPos min, BlockPos max, IBlockState blockState) { + this.min = min; + this.max = max; + this.blockState = blockState; + } + + @Override + public void apply(Lock lock, IChunk chunk) { + SingleBlockFinalSubChunk singleBlockFinalSubChunk = new SingleBlockFinalSubChunk(blockState); + if(lock.hasLock(chunk.getChunkPos())) { + if(isWholeInside(chunk)) { + chunk.replace(a -> singleBlockFinalSubChunk); + } else { + grabAndSet(lock, chunk); + + } + return; + } + if(chunk instanceof IAtomicChunk atomicChunk) { + if(isWholeInside(chunk)) { + atomicChunk.replaceAtomic(a -> singleBlockFinalSubChunk); + } else { + grabAndSet(lock, chunk); + } + return; + } + try(Lock l = lock.acquire(chunk.getChunkPos())) { + if(isWholeInside(chunk)) { + chunk.replace(a -> singleBlockFinalSubChunk); + } else { + grabAndSet(lock, chunk); + + } + } + } + + private void grabAndSet(Lock lock, IChunk chunk) { + lock.acquire(chunk.getChunkPos()); + long endX = Math.min(getMaxX(), chunk.getBlockMaxX()) + 1; + long endY = Math.min(getMaxY(), chunk.getBlockMaxY()) + 1; + long endZ = Math.min(getMaxZ(), chunk.getBlockMaxZ()) + 1; + set(chunk, Math.max(getMinX(), chunk.getBlockX()), Math.max(getMinY(), chunk.getBlockY()), Math.max(getMinZ(), chunk.getBlockZ()), endX, endY, endZ); + } + + private void set(IChunk c, long startX, long startY, long startZ, long endX, long endY, long endZ) { + for(long x = startX; x < endX; x++) { + for(long y = startY; y < endY; y++) { + for(long z = startZ; z < endZ; z++) { + c.setBlockState(x, y, z, blockState); + } + } + } + } + + @Override + public BlockPos getMin() { + return min; + } + + @Override + public BlockPos getMax() { + return max; + } +} diff --git a/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/ClassicChunk.java b/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/ClassicChunk.java index d7d1a70c..96eb1736 100644 --- a/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/ClassicChunk.java +++ b/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/ClassicChunk.java @@ -4,6 +4,8 @@ import dev.hilligans.ourcraft.Block.Blocks; import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.UnaryOperator; public class ClassicChunk implements IChunk { @@ -95,6 +97,11 @@ public boolean isEmpty() { return false; } + @Override + public int getSubChunkCount() { + return 0; + } + @Override public void forEach(Consumer consumer) { for(ISubChunk subChunk : chunks) { @@ -102,6 +109,15 @@ public void forEach(Consumer consumer) { } } + @Override + public void replace(UnaryOperator replacer) { + if(chunks != null) { + for(int x = 0; x < chunks.length; x++) { + chunks[x] = replacer.apply(chunks[x]); + } + } + } + @Override public void setDirty(boolean value) { dirty = value; diff --git a/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/CubicChunk.java b/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/CubicChunk.java index f08bf777..b4f8fe2e 100644 --- a/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/CubicChunk.java +++ b/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/CubicChunk.java @@ -5,10 +5,17 @@ import dev.hilligans.ourcraft.Data.Other.ChunkPos; import dev.hilligans.ourcraft.Server.Concurrent.Lock; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.VarHandle; +import java.util.ArrayList; import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.UnaryOperator; public class CubicChunk implements IAtomicChunk { + static final VarHandle ARRAY_HANDLE = MethodHandles.arrayElementVarHandle(ISubChunk[].class); + public int size; public int x; public int y; @@ -79,9 +86,15 @@ public void setBlockState(long x, long y, long z, IBlockState blockState) { int index = getIndex(x & 31, y & 31, z & 31); ISubChunk subChunk = subChunks[index]; if(subChunk == null) { - subChunk = new GlobalPaletteImpl(16,16); + subChunk = new GlobalPaletteAtomicSubChunk(); subChunks[index] = subChunk; } + ISubChunk repl = subChunk.canInsertOrGetNext(blockState); + if(repl != null) { + repl.setBlockState((int) (x & 15), (int) (y & 15), (int) (z & 15), blockState); + subChunks[index] = repl; + return; + } subChunk.setBlockState((int) (x & 15), (int) (y & 15), (int) (z & 15), blockState); } @@ -89,16 +102,28 @@ public void setBlockState(long x, long y, long z, IBlockState blockState) { public void setBlockStateAtomic(Lock lock, long x, long y, long z, IBlockState blockState) { if(!lock.hasLock(new ChunkPos(this.x, this.y, this.z))) { int index = getIndex(x & 31, y & 31, z & 31); - synchronized (this) { - ISubChunk subChunk = subChunks[index]; + ISubChunk subChunk; + do { + subChunk = (ISubChunk) ARRAY_HANDLE.getVolatile(subChunks, index); if(subChunk instanceof IAtomicSubChunk atomicSubChunk) { - atomicSubChunk.setBlockStateAtomic((int) (x & 15), (int) (y & 15), (int) (z & 15), blockState); + ISubChunk newChunk = subChunk.canInsertOrGetNext(blockState); + if(newChunk != null) { + newChunk.setBlockState((int) (x & 15), (int) (y & 15), (int) (z & 15), blockState); + if(ARRAY_HANDLE.weakCompareAndSet(subChunks, index, subChunk, newChunk)) { + return; + } + } else { + atomicSubChunk.setBlockStateAtomic((int) (x & 15), (int) (y & 15), (int) (z & 15), blockState); + } + } else { + lock.acquire(new ChunkPos(this.x, this.y, this.z)); + setBlockState(x, y, z, blockState); return; } - } - lock.acquire(new ChunkPos(this.x, this.y, this.z)); + } while(ARRAY_HANDLE.getVolatile(subChunks, index) != subChunk); + } else { + setBlockState(x, y, z, blockState); } - setBlockState(x, y, z, blockState); } @Override @@ -115,8 +140,23 @@ public boolean swapBlockStateAtomic(Lock lock, long x, long y, long z, IBlockSta } if(getBlockState1(x, y, z) == expected) { setBlockState(x, y, z, to); + return true; + } + return false; + } + + @Override + public void replaceAtomic(UnaryOperator replacer) { + if(subChunks != null) { + for(int x = 0; x < subChunks.length; x++) { + ISubChunk subChunk; + ISubChunk newSubChunk; + do { + subChunk = (ISubChunk) ARRAY_HANDLE.getVolatile(subChunks, x); + newSubChunk = replacer.apply(subChunk); + } while (ARRAY_HANDLE.weakCompareAndSet(subChunks, x, subChunk, newSubChunk)); + } } - return true; } @Override @@ -136,6 +176,11 @@ public boolean isEmpty() { return subChunks == null; } + @Override + public int getSubChunkCount() { + return subChunks.length; + } + @Override public void forEach(Consumer consumer) { if(subChunks != null) { @@ -145,15 +190,22 @@ public void forEach(Consumer consumer) { } } + @Override + public void replace(UnaryOperator replacer) { + if(subChunks != null) { + for(int x = 0; x < subChunks.length; x++) { + subChunks[x] = replacer.apply(subChunks[x]); + } + } + } + @Override public void setDirty(boolean value) { - int D = 1; + short D = 1; if(value) { - // System.out.println(flags); flags |= D; - // System.out.println(flags); } else { - flags &=~D; + flags &= (short) ~D; } } diff --git a/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/GlobalPaletteAtomicSubChunk.java b/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/GlobalPaletteAtomicSubChunk.java index 1b5b02bd..080d73d8 100644 --- a/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/GlobalPaletteAtomicSubChunk.java +++ b/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/GlobalPaletteAtomicSubChunk.java @@ -1,6 +1,7 @@ package dev.hilligans.ourcraft.World.NewWorldSystem; import dev.hilligans.ourcraft.Block.BlockState.IBlockState; +import dev.hilligans.ourcraft.Ourcraft; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; @@ -8,9 +9,9 @@ public class GlobalPaletteAtomicSubChunk implements IAtomicSubChunk { - static final VarHandle ARRAY_HANDLE = MethodHandles.arrayElementVarHandle(int[].class); + static final VarHandle ARRAY_HANDLE = MethodHandles.arrayElementVarHandle(short[].class); public ArrayList blockStates; - public int[] blocks = new int[16 * 16 * 16 / 4]; + public short[] blocks = new short[16 * 16 * 16]; public GlobalPaletteAtomicSubChunk(ArrayList blockStates) { this.blockStates = blockStates; @@ -19,6 +20,9 @@ public GlobalPaletteAtomicSubChunk(ArrayList blockStates) { } } + public GlobalPaletteAtomicSubChunk() { + this(Ourcraft.GAME_INSTANCE.BLOCK_STATES); + } @Override public int getWidth() { @@ -32,57 +36,54 @@ public int getHeight() { @Override public IBlockState getBlockState(int x, int y, int z) { - return blockStates.get((blocks[getIndex(x, y, z)] >> 16 * (z & 0b11)) & 0xFFFF); + return blockStates.get((blocks[getIndex(x, y, z)])); } @Override public IBlockState setBlockState(int x, int y, int z, IBlockState blockState) { - int shift = 16 * (z & 0b11); - int id = blockState.getBlockStateID() << shift; - int and = 0xFFFF << shift; - int index = getIndex(x, y, z); - int v = blocks[index]; - blocks[index] = v & and | id; - return blockStates.get((v >> shift) & 0xFFFF); + int id = blockState.getBlockStateID(); + blocks[getIndex(x, y, z)] = (short) id; + return blockStates.get(id); } @Override public IBlockState setBlockStateAtomic(int x, int y, int z, IBlockState blockState) { - int shift = 16 * (z & 0b11); - int id = blockState.getBlockStateID() << shift; - int and = 0xFFFF << shift; + int id = blockState.getBlockStateID(); int index = getIndex(x, y, z); int v; do { v = (int) ARRAY_HANDLE.getVolatile(blocks, index); - } while (!ARRAY_HANDLE.weakCompareAndSet(blocks, index, v, v & and | id)); + } while (!ARRAY_HANDLE.weakCompareAndSet(blocks, index, v, id)); - return blockStates.get((v >> shift) & 0xFFFF); + return blockStates.get(v); } @Override public boolean swapBlockStateAtomic(int x, int y, int z, IBlockState expected, IBlockState to) { - int shift = 16 * (z & 0b11); - int newID = to.getBlockStateID() << shift; - int oldID = expected.getBlockStateID() << shift; - int and = 0xFFFF << shift; + int newID = to.getBlockStateID(); + int oldID = expected.getBlockStateID(); int index = getIndex(x, y, z); int v; do { v = (int) ARRAY_HANDLE.getVolatile(blocks, index); - if((v & and) != oldID) { + if(v != oldID) { return false; } - } while (!ARRAY_HANDLE.weakCompareAndSet(blocks, index, v, v & and | newID)); + } while (!ARRAY_HANDLE.weakCompareAndSet(blocks, index, v, newID)); return true; } public static int getIndex(int x, int y, int z) { - return ((x * 16) + y) * 4 + (z >> 2); + return ((x * 16) + y) * 16 + z; } @Override public boolean isEmpty() { return false; } + + @Override + public ISubChunk canInsertOrGetNext(IBlockState blockState) { + return null; + } } diff --git a/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/GlobalPaletteImpl.java b/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/GlobalPaletteImpl.java index be5c379e..4a15d418 100644 --- a/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/GlobalPaletteImpl.java +++ b/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/GlobalPaletteImpl.java @@ -62,4 +62,9 @@ public IBlockState setBlockState(int x, int y, int z, IBlockState blockState) { public boolean isEmpty() { return blockStates == null; } + + @Override + public ISubChunk canInsertOrGetNext(IBlockState blockState) { + return null; + } } diff --git a/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/IAtomicChunk.java b/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/IAtomicChunk.java index 7f4a5a0c..350593e8 100644 --- a/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/IAtomicChunk.java +++ b/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/IAtomicChunk.java @@ -3,6 +3,9 @@ import dev.hilligans.ourcraft.Block.BlockState.IBlockState; import dev.hilligans.ourcraft.Server.Concurrent.Lock; +import java.util.function.Function; +import java.util.function.UnaryOperator; + public interface IAtomicChunk extends IChunk { @@ -25,4 +28,5 @@ public interface IAtomicChunk extends IChunk { */ boolean swapBlockStateAtomic(Lock lock, long x, long y, long z, IBlockState expected, IBlockState to); + void replaceAtomic(UnaryOperator replacer); } diff --git a/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/IChunk.java b/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/IChunk.java index fb71d919..87fb3d43 100644 --- a/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/IChunk.java +++ b/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/IChunk.java @@ -2,11 +2,14 @@ import dev.hilligans.ourcraft.Block.BlockState.IBlockState; import dev.hilligans.ourcraft.Data.Other.BlockPos; +import dev.hilligans.ourcraft.Data.Other.ChunkPos; import dev.hilligans.ourcraft.Data.Other.IBoundingBox; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.UnaryOperator; public interface IChunk extends IBoundingBox { @@ -29,6 +32,18 @@ default long getBlockZ() { return getZ() * getWidth(); } + default long getBlockMaxX() { + return getBlockX() + getWidth() - 1; + } + + default long getBlockMaxY() { + return getBlockY() + getHeight() - 1; + } + + default long getBlockMaxZ() { + return getBlockZ() + getWidth() - 1; + } + default int getYOffset() { return 0; } @@ -49,6 +64,10 @@ default BlockPos getChunkBlockPos(BlockPos dest) { return dest.set((int)getChunkXBlockPos(),(int)getChunkYBlockPos(),(int)getChunkZBlockPos()); } + default ChunkPos getChunkPos() { + return new ChunkPos(getX(), getY(), getZ()); + } + IBlockState getBlockState1(long x, long y, long z); default IBlockState getBlockState1(BlockPos pos) { @@ -68,8 +87,12 @@ default IBlockState getBlockState1(BlockPos pos) { * This method can run on the chunk itself acting like a single subchunk. */ + int getSubChunkCount(); + void forEach(Consumer consumer); + void replace(UnaryOperator replacer); + void setDirty(boolean value); boolean isDirty(); diff --git a/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/IServerWorld.java b/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/IServerWorld.java index 33ef4dfb..1106057d 100644 --- a/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/IServerWorld.java +++ b/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/IServerWorld.java @@ -6,6 +6,9 @@ import dev.hilligans.ourcraft.Network.Packet.Server.SSendChunkPacket; import dev.hilligans.ourcraft.Server.MultiPlayerServer; +import java.util.concurrent.Future; +import java.util.function.Consumer; + public interface IServerWorld extends IWorld { BlockPos getWorldSpawn(BoundingBox boundingBox); @@ -14,6 +17,9 @@ public interface IServerWorld extends IWorld { MultiPlayerServer getServer(); + void queuePostTickEvent(Future> runnableFuture); + + void processPostTickEvents(Future> runnableFuture); default void sendChunksToPlayer(int playerX, int playerY, int playerZ, ServerPlayerData serverPlayerData) { int chunkWidth = getChunkContainer().getChunkWidth(); diff --git a/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/IServerWorldBase.java b/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/IServerWorldBase.java new file mode 100644 index 00000000..92f4f42f --- /dev/null +++ b/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/IServerWorldBase.java @@ -0,0 +1,28 @@ +package dev.hilligans.ourcraft.World.NewWorldSystem; + +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.Future; +import java.util.function.Consumer; + +public interface IServerWorldBase extends IServerWorld { + + @Override + default void queuePostTickEvent(Future> future) { + getPostTickQueue().add(future); + } + + @Override + default void processPostTickEvents(Future> runnableFuture) { + ConcurrentLinkedQueue>> futures = getPostTickQueue(); + while (!futures.isEmpty()) { + try { + futures.remove().get().accept(this); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + + ConcurrentLinkedQueue>> getPostTickQueue(); + +} diff --git a/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/ISubChunk.java b/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/ISubChunk.java index 6cd7e02f..c3acea41 100644 --- a/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/ISubChunk.java +++ b/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/ISubChunk.java @@ -15,5 +15,11 @@ public interface ISubChunk { boolean isEmpty(); + /** + * @param blockState the block to insert + * @return null if can be inserted or a new subchunk if must be replaced + */ + ISubChunk canInsertOrGetNext(IBlockState blockState); + default void free(@Nullable IWorld world) {} } diff --git a/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/PalettedSubChunk.java b/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/PalettedSubChunk.java index e09a0aef..33859e64 100644 --- a/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/PalettedSubChunk.java +++ b/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/PalettedSubChunk.java @@ -2,12 +2,26 @@ import dev.hilligans.ourcraft.Block.BlockState.IBlockState; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; -public class PalettedSubChunk implements ISubChunk { +public class PalettedSubChunk implements IAtomicSubChunk { - public IChunk chunk; + public AtomicInteger handleCount = new AtomicInteger(); + public volatile boolean blocking; + public int paletteWidth = 4; + public int[] blocks; + public short[] palette; + + public PalettedSubChunk() { + palette = new short[1 << paletteWidth]; + } + + public PalettedSubChunk(SingleBlockFinalSubChunk from) { + palette = new short[1 << paletteWidth]; + palette[0] = (short) from.blockState.getBlockStateID(); + } @Override public int getWidth() { @@ -34,17 +48,57 @@ public boolean isEmpty() { return false; } - public static int minContainerSize = 4; + @Override + public ISubChunk canInsertOrGetNext(IBlockState blockState) { + //TODO implement + return null; + } + + @Override + public IBlockState setBlockStateAtomic(int x, int y, int z, IBlockState blockState) { + return null; + } + + @Override + public boolean swapBlockStateAtomic(int x, int y, int z, IBlockState expected, IBlockState to) { + return false; + } + + public boolean grow() { + if(paletteWidth >= 8) { + return false; + } + blocking = true; + //spin until everything is done setting + while (handleCount.get() != 0) {} + paletteWidth++; + if(paletteWidth == 7) { + paletteWidth = 8; + } + int count = Math.ceilDiv(16 * 16 * 16, paletteWidth); + int[] newVals = new int[count]; + + int and = 1; + for(int x = 0; x < paletteWidth; x++) { + and = and << 1 | 1; + } - public static class Lock { + int c = 0; + int i; + int b; + while (c != 16 * 16 * 16) { + //newVals - public AtomicInteger lockCount = new AtomicInteger(); - public boolean locked = false; - public Lock() { - //lockCount.get() + c++; } + blocking = false; + return true; + } + + public static int getIndex(int x, int y, int z, int width) { + return 0; } } diff --git a/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/ServerCubicWorld.java b/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/ServerCubicWorld.java index 1b0d06d4..53c8966d 100644 --- a/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/ServerCubicWorld.java +++ b/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/ServerCubicWorld.java @@ -10,13 +10,20 @@ import dev.hilligans.planets.world.PlanetFeaturePlacerHelper; import org.joml.Random; -public class ServerCubicWorld extends CubicWorld implements IServerWorld { +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.Future; +import java.util.function.Consumer; + +public class ServerCubicWorld extends CubicWorld implements IServerWorldBase { public MultiPlayerServer multiPlayerServer; public IWorldHeightBuilder worldHeightBuilder; public IWorldGenerator worldGenerator; public final int widthBits = 5; + public ConcurrentLinkedQueue>> postTickFutures = new ConcurrentLinkedQueue<>(); + + public ServerCubicWorld(int id, String worldName, int radius, IWorldHeightBuilder worldHeightBuilder) { super(id, worldName, radius); this.worldHeightBuilder = worldHeightBuilder; @@ -873,4 +880,9 @@ public void generateWorld() { public IWorldGenerator getWorldGenerator() { return worldGenerator; } + + @Override + public ConcurrentLinkedQueue>> getPostTickQueue() { + return postTickFutures; + } } diff --git a/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/SimpleServerWorld.java b/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/SimpleServerWorld.java index 148db2ab..9d7cad09 100644 --- a/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/SimpleServerWorld.java +++ b/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/SimpleServerWorld.java @@ -8,12 +8,17 @@ import dev.hilligans.ourcraft.Server.MultiPlayerServer; import java.util.Random; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.Future; +import java.util.function.Consumer; -public class SimpleServerWorld extends SimpleWorld implements IServerWorld, IMethodResult, IFeaturePlacerHelper { +public class SimpleServerWorld extends SimpleWorld implements IServerWorldBase, IMethodResult, IFeaturePlacerHelper { public MultiPlayerServer server; public BlockPos featurePlacerPosition = new BlockPos(0, 0, 0); + public ConcurrentLinkedQueue>> postTickFutures = new ConcurrentLinkedQueue<>(); + public SimpleServerWorld(int id, String name) { super(id, name); } @@ -42,6 +47,11 @@ public IChunk getGeneratedChunk(int xx, int zz) { return chunk; } + @Override + public ConcurrentLinkedQueue>> getPostTickQueue() { + return postTickFutures; + } + @Override public IChunk getChunk(long blockX, long blockY, long blockZ) { IChunk chunk = super.getChunk(blockX, blockY, blockZ); diff --git a/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/SimpleSubChunkImpl.java b/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/SimpleSubChunkImpl.java index b2c1cc1b..fc0f9ba3 100644 --- a/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/SimpleSubChunkImpl.java +++ b/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/SimpleSubChunkImpl.java @@ -60,4 +60,9 @@ public IBlockState setBlockState(int x, int y, int z, IBlockState blockState) { public boolean isEmpty() { return blockStates == null; } + + @Override + public ISubChunk canInsertOrGetNext(IBlockState blockState) { + return null; + } } diff --git a/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/SingleBlockFinalSubChunk.java b/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/SingleBlockFinalSubChunk.java new file mode 100644 index 00000000..09e80a64 --- /dev/null +++ b/src/main/java/dev/hilligans/ourcraft/World/NewWorldSystem/SingleBlockFinalSubChunk.java @@ -0,0 +1,74 @@ +package dev.hilligans.ourcraft.World.NewWorldSystem; + +import dev.hilligans.ourcraft.Block.BlockState.IBlockState; +import dev.hilligans.ourcraft.Engine.EngineImplementationException; + +public class SingleBlockFinalSubChunk implements IAtomicSubChunk { + + public final IBlockState blockState; + final short width; + final short height; + public static final boolean CHECKED = false; + + public SingleBlockFinalSubChunk(IBlockState blockState) { + this(blockState, 16, 16); + } + + public SingleBlockFinalSubChunk(IBlockState blockState, int width, int height) { + this.blockState = blockState; + this.width = (short) width; + this.height = (short) height; + } + + @Override + public int getWidth() { + return width; + } + + @Override + public int getHeight() { + return height; + } + + @Override + public IBlockState getBlockState(int x, int y, int z) { + return blockState; + } + + @Override + public IBlockState setBlockState(int x, int y, int z, IBlockState blockState) { + if(CHECKED && blockState != this.blockState) { + throw new EngineImplementationException("canInsertOrGetNext will always return a new subchunk when states dont match so a blockstate set should never be attempted here"); + } + return this.blockState; + } + + @Override + public boolean isEmpty() { + return blockState.getBlock().blockProperties.airBlock; + } + + @Override + public ISubChunk canInsertOrGetNext(IBlockState blockState) { + if(blockState == this.blockState) { + return null; + } + return new PalettedSubChunk(this); + } + + @Override + public IBlockState setBlockStateAtomic(int x, int y, int z, IBlockState blockState) { + if(CHECKED && blockState != this.blockState) { + throw new EngineImplementationException("canInsertOrGetNext will always return a new subchunk when states dont match so a blockstate set should never be attempted here"); + } + return this.blockState; + } + + @Override + public boolean swapBlockStateAtomic(int x, int y, int z, IBlockState expected, IBlockState to) { + if(CHECKED && to != this.blockState) { + throw new EngineImplementationException("canInsertOrGetNext will always return a new subchunk when states dont match so a blockstate set should never be attempted here"); + } + return expected == to && to == this.blockState; + } +} diff --git a/src/main/java/dev/hilligans/ourcraft/World/Tasks/ChunkTickTask.java b/src/main/java/dev/hilligans/ourcraft/World/Tasks/ChunkTickTask.java new file mode 100644 index 00000000..14ed0383 --- /dev/null +++ b/src/main/java/dev/hilligans/ourcraft/World/Tasks/ChunkTickTask.java @@ -0,0 +1,86 @@ +package dev.hilligans.ourcraft.World.Tasks; + +import dev.hilligans.ourcraft.Block.Block; +import dev.hilligans.ourcraft.Block.BlockState.IBlockState; +import dev.hilligans.ourcraft.Data.Other.BlockPos; +import dev.hilligans.ourcraft.Data.Other.ChunkPos; +import dev.hilligans.ourcraft.Server.Concurrent.*; +import dev.hilligans.ourcraft.World.NewWorldSystem.IChunk; +import dev.hilligans.ourcraft.World.NewWorldSystem.IMethodResult; +import dev.hilligans.ourcraft.World.NewWorldSystem.ISubChunk; +import dev.hilligans.ourcraft.World.NewWorldSystem.IWorld; +import dev.hilligans.ourcraft.World.World; + +import java.util.Random; +import java.util.function.Consumer; + +public class ChunkTickTask extends TickingBase implements IMethodResult { + + public IChunk chunk; + public Random random; + public int randomTickCount = 3; + + public ChunkTickTask(IChunk chunk) { + this.chunk = chunk; + this.random = new Random(); + } + + @Override + public void tick() { + + ChunkTickTask instance = this; + //we make the lock with all the chunk positions we want + Lock lock = new Lock(chunkLocker, new ChunkPos(chunk.getX(), chunk.getY(), chunk.getZ())); + chunk.forEach(new Consumer() { + @Override + public void accept(ISubChunk iSubChunk) { + for(int i = 0; i < randomTickCount; i++) { + int width = iSubChunk.getWidth(); + int height = iSubChunk.getHeight(); + int pos = random.nextInt(width * width * height); + int z = pos % width; + pos /= width; + int y = pos % height; + int x = pos / width; + IBlockState blockState = iSubChunk.getBlockState(x, y, z); + blockState.getBlock().randomTick(lock, instance, blockState, chunk, world, new BlockPos(x, y, z), random); + } + } + }); + + //we can then acquire it when we need it + //lock.acquire(); + //and release it when we no longer need it + // lock.release(); + } + + @Override + public void queueUpdate(int x, int y, int z) { + + } + + @Override + public void queueUpdate(BlockPos pos) { + + } + + @Override + public void queueSixUpdates(int x, int y, int z) { + + } + + @Override + public void queueSixUpdates(BlockPos pos) { + + } + + @Override + public void scheduleTick(int x, int y, int z, Block block, int delay) { + + } + + @Override + public void scheduleTick(BlockPos pos, Block block, int delay) { + + } +} \ No newline at end of file diff --git a/src/main/java/dev/hilligans/ourcraft/World/World.java b/src/main/java/dev/hilligans/ourcraft/World/World.java index eca2c5a2..ed72d0e6 100644 --- a/src/main/java/dev/hilligans/ourcraft/World/World.java +++ b/src/main/java/dev/hilligans/ourcraft/World/World.java @@ -67,25 +67,10 @@ public Chunk getChunk(int x, int z) { return chunkContainer.getChunk(x,z); } - public void scheduleTick(BlockPos pos, int time) { - if(isServer()) { - - } - } - public void removeChunk(int x, int z) { chunkContainer.removeChunk(x,z); } - public Chunk getOrGenerateChunk(int x, int z) { - Chunk chunk = getChunk(x,z); - if(chunk == null) { - generateChunk(x,z); - } - chunk = getChunk(x,z); - return chunk; - } - public void generateChunk(int x, int z) { if(getChunk(x,z) == null) { Chunk chunk = new Chunk(x,z,this); @@ -192,14 +177,8 @@ public void tick() { } - ConcurrentLinkedQueue requestedChunks = new ConcurrentLinkedQueue<>(); public HashSet set = new HashSet<>(); - public void setChunk(Chunk chunk) { - set.remove((long) chunk.x | (long) chunk.z << 32); - putChunk(chunk.x, chunk.z, chunk); - } - public void setChunk(Chunk chunk, int x, int z) { chunk.setWorld(this); chunk.x = x;