From 6b060a1ff67c27f7f59085703f50d0b6a9e36682 Mon Sep 17 00:00:00 2001 From: dfsek Date: Tue, 4 Jan 2022 09:37:06 -0700 Subject: [PATCH] buffered world builder api --- .../dfsek/terra/api/world/BufferedWorld.java | 78 ++++++++++++++++++- .../dfsek/terra/api/world/WritableWorld.java | 7 +- .../terra/api/world/util/Interceptors.java | 17 ++++ .../terra/api/world/util/ReadInterceptor.java | 9 +++ .../api/world/util/WriteInterceptor.java | 13 ++++ 5 files changed, 120 insertions(+), 4 deletions(-) create mode 100644 common/api/src/main/java/com/dfsek/terra/api/world/util/Interceptors.java create mode 100644 common/api/src/main/java/com/dfsek/terra/api/world/util/ReadInterceptor.java create mode 100644 common/api/src/main/java/com/dfsek/terra/api/world/util/WriteInterceptor.java diff --git a/common/api/src/main/java/com/dfsek/terra/api/world/BufferedWorld.java b/common/api/src/main/java/com/dfsek/terra/api/world/BufferedWorld.java index ce235e624..a2d782fd1 100644 --- a/common/api/src/main/java/com/dfsek/terra/api/world/BufferedWorld.java +++ b/common/api/src/main/java/com/dfsek/terra/api/world/BufferedWorld.java @@ -1,12 +1,18 @@ package com.dfsek.terra.api.world; +import java.util.Objects; + import com.dfsek.terra.api.block.entity.BlockEntity; import com.dfsek.terra.api.block.state.BlockState; import com.dfsek.terra.api.config.ConfigPack; import com.dfsek.terra.api.entity.Entity; import com.dfsek.terra.api.entity.EntityType; +import com.dfsek.terra.api.util.vector.Vector3Int; import com.dfsek.terra.api.world.biome.generation.BiomeProvider; import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator; +import com.dfsek.terra.api.world.util.Interceptors; +import com.dfsek.terra.api.world.util.ReadInterceptor; +import com.dfsek.terra.api.world.util.WriteInterceptor; /** @@ -17,12 +23,18 @@ public class BufferedWorld implements WritableWorld { private final WritableWorld delegate; private final int offsetX, offsetY, offsetZ; - protected BufferedWorld(WritableWorld delegate, int offsetX, int offsetY, int offsetZ) { + private final ReadInterceptor readInterceptor; + private final WriteInterceptor writeInterceptor; + + protected BufferedWorld(WritableWorld delegate, int offsetX, int offsetY, int offsetZ, + ReadInterceptor readInterceptor, WriteInterceptor writeInterceptor) { this.delegate = delegate; this.offsetX = offsetX; this.offsetY = offsetY; this.offsetZ = offsetZ; + this.readInterceptor = readInterceptor; + this.writeInterceptor = writeInterceptor; } @Override @@ -32,7 +44,7 @@ public class BufferedWorld implements WritableWorld { @Override public BlockState getBlockState(int x, int y, int z) { - return delegate.getBlockState(x + offsetX, y + offsetY, z + offsetZ); + return readInterceptor.read(x, y, z, delegate); } @Override @@ -72,7 +84,7 @@ public class BufferedWorld implements WritableWorld { @Override public void setBlockState(int x, int y, int z, BlockState data, boolean physics) { - delegate.setBlockState(x + offsetX, y + offsetY, z + offsetZ, data, physics); + writeInterceptor.write(x, y, z, data, delegate, physics); } @Override @@ -82,9 +94,69 @@ public class BufferedWorld implements WritableWorld { /** * Get the world this {@link BufferedWorld} delegates to. + * * @return Delegate world. */ public WritableWorld getDelegate() { return delegate; } + + public static final class Builder { + private final WritableWorld delegate; + private ReadInterceptor readInterceptor; + private WriteInterceptor writeInterceptor; + + private int x = 0; + private int y = 0; + private int z = 0; + + private Builder(WritableWorld delegate) { + this.delegate = delegate; + } + + public Builder read(ReadInterceptor interceptor) { + this.readInterceptor = interceptor; + return this; + } + + public Builder write(WriteInterceptor interceptor) { + this.writeInterceptor = interceptor; + return this; + } + + public Builder offsetX(int x) { + this.x = x; + return this; + } + + public Builder offsetY(int y) { + this.y = y; + return this; + } + + public Builder offsetZ(int z) { + this.z = z; + return this; + } + + public Builder offset(Vector3Int vector) { + this.x = vector.getX(); + this.y = vector.getY(); + this.z = vector.getZ(); + return this; + } + + public BufferedWorld build() { + return new BufferedWorld(delegate, + x, + y, + z, + Objects.requireNonNullElse(readInterceptor, Interceptors.readThrough()), + Objects.requireNonNullElse(writeInterceptor, Interceptors.writeThrough())); + } + } + + protected static Builder builder(WritableWorld world) { + return new Builder(world); + } } diff --git a/common/api/src/main/java/com/dfsek/terra/api/world/WritableWorld.java b/common/api/src/main/java/com/dfsek/terra/api/world/WritableWorld.java index 6059148e2..228846bb5 100644 --- a/common/api/src/main/java/com/dfsek/terra/api/world/WritableWorld.java +++ b/common/api/src/main/java/com/dfsek/terra/api/world/WritableWorld.java @@ -6,6 +6,7 @@ import com.dfsek.terra.api.entity.EntityType; import com.dfsek.terra.api.util.vector.Vector3; import com.dfsek.terra.api.util.vector.Vector3Int; import com.dfsek.terra.api.world.chunk.generation.util.Column; +import com.dfsek.terra.api.world.util.Interceptors; public interface WritableWorld extends ReadableWorld { @@ -55,7 +56,11 @@ public interface WritableWorld extends ReadableWorld { Entity spawnEntity(double x, double y, double z, EntityType entityType); default BufferedWorld buffer(int offsetX, int offsetY, int offsetZ) { - return new BufferedWorld(this, offsetX, offsetY, offsetZ); + return BufferedWorld.builder(this).offsetX(offsetX).offsetY(offsetY).offsetZ(offsetZ).build(); + } + + default BufferedWorld.Builder buffer() { + return BufferedWorld.builder(this); } default Column column(int x, int z) { diff --git a/common/api/src/main/java/com/dfsek/terra/api/world/util/Interceptors.java b/common/api/src/main/java/com/dfsek/terra/api/world/util/Interceptors.java new file mode 100644 index 000000000..6ef2514d4 --- /dev/null +++ b/common/api/src/main/java/com/dfsek/terra/api/world/util/Interceptors.java @@ -0,0 +1,17 @@ +package com.dfsek.terra.api.world.util; + +public final class Interceptors { + private static final ReadInterceptor READ_THROUGH = ((x, y, z, world) -> world.getBlockState(x, y, z)); + private static final WriteInterceptor WRITE_THROUGH = ((x, y, z, block, world, physics) -> world.setBlockState(x, y, z, block, physics)); + private Interceptors() { + + } + + public static ReadInterceptor readThrough() { + return READ_THROUGH; + } + + public static WriteInterceptor writeThrough() { + return WRITE_THROUGH; + } +} diff --git a/common/api/src/main/java/com/dfsek/terra/api/world/util/ReadInterceptor.java b/common/api/src/main/java/com/dfsek/terra/api/world/util/ReadInterceptor.java new file mode 100644 index 000000000..583cb9d8b --- /dev/null +++ b/common/api/src/main/java/com/dfsek/terra/api/world/util/ReadInterceptor.java @@ -0,0 +1,9 @@ +package com.dfsek.terra.api.world.util; + +import com.dfsek.terra.api.block.state.BlockState; +import com.dfsek.terra.api.world.ReadableWorld; + + +public interface ReadInterceptor { + BlockState read(int x, int y, int z, ReadableWorld world); +} diff --git a/common/api/src/main/java/com/dfsek/terra/api/world/util/WriteInterceptor.java b/common/api/src/main/java/com/dfsek/terra/api/world/util/WriteInterceptor.java new file mode 100644 index 000000000..27f4bcbe1 --- /dev/null +++ b/common/api/src/main/java/com/dfsek/terra/api/world/util/WriteInterceptor.java @@ -0,0 +1,13 @@ +package com.dfsek.terra.api.world.util; + +import com.dfsek.terra.api.block.state.BlockState; +import com.dfsek.terra.api.world.WritableWorld; + + +public interface WriteInterceptor { + default void write(int x, int y, int z, BlockState block, WritableWorld world) { + write(x, y, z, block, world, false); + } + + void write(int x, int y, int z, BlockState block, WritableWorld world, boolean physics); +}