From 0f60d45ffa547fe9e196f216ccc60b912158164e Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Thu, 5 Aug 2021 16:42:21 +0300 Subject: [PATCH] Contexts no longer expose to World, Chunks, TileStacks or TileReferences The intention is to bottleneck all read queries and write requests through context objects without the need to create practically useless Chunk, TileStack and TileRef wrappers. - WorldGenericContext{RO,WO} no longer extend WorldGeneric{RO,WO} - Added tag access for tiles to contexts - Documented almost all context methods - Renamed isBlockLoaded() to isLocationLoaded() - I found some inner peace --- .../world/context/BlockDataContext.java | 7 +- .../world/context/BlockDataContextRO.java | 5 +- .../world/context/BlockFaceDataContext.java | 7 +- .../world/context/BlockFaceDataContextRO.java | 5 +- .../common/world/context/TileDataContext.java | 10 +- .../world/context/TileDataContextRO.java | 5 +- .../world/context/WorldDataContext.java | 21 +- .../world/context/WorldDataContextRO.java | 27 +- .../common/world/generic/WorldGenericRO.java | 2 +- .../context/BlockFaceGenericContextRO.java | 84 ++-- .../context/BlockFaceGenericContextWO.java | 5 +- .../context/BlockGenericContextRO.java | 97 +++-- .../context/BlockGenericContextWO.java | 5 +- .../generic/context/TileGenericContextRO.java | 47 +-- .../generic/context/TileGenericContextWO.java | 5 +- .../context/WorldGenericContextRO.java | 166 +++++++- .../context/WorldGenericContextWO.java | 12 +- .../server/world/TickAndUpdateUtil.java | 4 +- .../world/context/ServerBlockContext.java | 7 - .../world/context/ServerBlockContextRO.java | 7 +- .../world/context/ServerBlockFaceContext.java | 6 - .../context/ServerBlockFaceContextRO.java | 7 +- .../server/world/context/ServerContext.java | 4 +- .../world/context/ServerTileContext.java | 6 - .../world/context/ServerTileContextRO.java | 7 +- .../world/context/ServerWorldContext.java | 10 +- .../world/context/ServerWorldContextRO.java | 10 +- .../context/impl/ReusableServerContext.java | 7 +- .../impl/ReusableServerContextImpl.java | 399 ++++++++++++------ .../test/gen/surface/SurfaceWorld.java | 2 +- 30 files changed, 613 insertions(+), 373 deletions(-) diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContext.java b/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContext.java index 4ebb85a..3462048 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContext.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContext.java @@ -17,19 +17,16 @@ */ package ru.windcorp.progressia.common.world.context; -import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.TileDataReference; -import ru.windcorp.progressia.common.world.TileDataStack; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.context.BlockGenericContextWO; import ru.windcorp.progressia.common.world.tile.TileData; public interface BlockDataContext - extends BlockGenericContextWO, + extends BlockGenericContextWO, WorldDataContext, BlockDataContextRO { - + // currently empty } diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContextRO.java index f910fa1..70ad8f4 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/BlockDataContextRO.java @@ -17,16 +17,13 @@ */ package ru.windcorp.progressia.common.world.context; -import ru.windcorp.progressia.common.world.ChunkDataRO; -import ru.windcorp.progressia.common.world.TileDataReferenceRO; -import ru.windcorp.progressia.common.world.TileDataStackRO; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.context.BlockGenericContextRO; import ru.windcorp.progressia.common.world.tile.TileData; public interface BlockDataContextRO - extends BlockGenericContextRO, + extends BlockGenericContextRO, WorldDataContextRO { // currently empty diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/BlockFaceDataContext.java b/src/main/java/ru/windcorp/progressia/common/world/context/BlockFaceDataContext.java index 45ce045..b12c36c 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/BlockFaceDataContext.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/BlockFaceDataContext.java @@ -17,19 +17,16 @@ */ package ru.windcorp.progressia.common.world.context; -import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.TileDataReference; -import ru.windcorp.progressia.common.world.TileDataStack; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.context.BlockFaceGenericContextWO; import ru.windcorp.progressia.common.world.tile.TileData; public interface BlockFaceDataContext - extends BlockFaceGenericContextWO, + extends BlockFaceGenericContextWO, BlockDataContext, BlockFaceDataContextRO { - + // currently empty } diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/BlockFaceDataContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/context/BlockFaceDataContextRO.java index ddf7089..a20355a 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/BlockFaceDataContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/BlockFaceDataContextRO.java @@ -17,16 +17,13 @@ */ package ru.windcorp.progressia.common.world.context; -import ru.windcorp.progressia.common.world.ChunkDataRO; -import ru.windcorp.progressia.common.world.TileDataReferenceRO; -import ru.windcorp.progressia.common.world.TileDataStackRO; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.context.BlockFaceGenericContextRO; import ru.windcorp.progressia.common.world.tile.TileData; public interface BlockFaceDataContextRO - extends BlockFaceGenericContextRO, + extends BlockFaceGenericContextRO, BlockDataContext { // currently empty diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContext.java b/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContext.java index 79e8d51..3f4a0d6 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContext.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContext.java @@ -17,22 +17,16 @@ */ package ru.windcorp.progressia.common.world.context; -import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.TileDataReference; -import ru.windcorp.progressia.common.world.TileDataStack; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.context.TileGenericContextWO; import ru.windcorp.progressia.common.world.tile.TileData; public interface TileDataContext - extends TileGenericContextWO, + extends TileGenericContextWO, BlockFaceDataContext, TileDataContextRO { - @Override - default int getTag() { - return getTileReference().getTag(); - } + // currently empty } diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContextRO.java index b7f2b4d..e143e03 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/TileDataContextRO.java @@ -17,16 +17,13 @@ */ package ru.windcorp.progressia.common.world.context; -import ru.windcorp.progressia.common.world.ChunkDataRO; -import ru.windcorp.progressia.common.world.TileDataReferenceRO; -import ru.windcorp.progressia.common.world.TileDataStackRO; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.context.TileGenericContextRO; import ru.windcorp.progressia.common.world.tile.TileData; public interface TileDataContextRO - extends TileGenericContextRO, + extends TileGenericContextRO, BlockFaceDataContextRO { // currently empty diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/WorldDataContext.java b/src/main/java/ru/windcorp/progressia/common/world/context/WorldDataContext.java index 31dbef1..68965b5 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/WorldDataContext.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/WorldDataContext.java @@ -17,20 +17,23 @@ */ package ru.windcorp.progressia.common.world.context; -import ru.windcorp.progressia.common.world.ChunkData; -import ru.windcorp.progressia.common.world.TileDataReference; -import ru.windcorp.progressia.common.world.TileDataStack; -import ru.windcorp.progressia.common.world.WorldData; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.context.WorldGenericContextWO; import ru.windcorp.progressia.common.world.tile.TileData; public interface WorldDataContext - extends WorldGenericContextWO, - WorldDataContextRO, - WorldData { - - // currently empty + extends WorldGenericContextWO, + WorldDataContextRO { + + /** + * Increases in-game time of this world by {@code change}. Total time is + * decreased when {@code change} is negative. + * + * @param change the amount of time to add to current world time. May be + * negative. + * @see #getTime() + */ + void advanceTime(float change); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/context/WorldDataContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/context/WorldDataContextRO.java index c474ea4..8201738 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/context/WorldDataContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/context/WorldDataContextRO.java @@ -18,19 +18,30 @@ package ru.windcorp.progressia.common.world.context; -import ru.windcorp.progressia.common.world.ChunkDataRO; -import ru.windcorp.progressia.common.world.TileDataReferenceRO; -import ru.windcorp.progressia.common.world.TileDataStackRO; -import ru.windcorp.progressia.common.world.WorldDataRO; +import ru.windcorp.progressia.common.world.GravityModel; import ru.windcorp.progressia.common.world.block.BlockData; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.context.WorldGenericContextRO; import ru.windcorp.progressia.common.world.tile.TileData; -public interface WorldDataContextRO - extends WorldGenericContextRO, - WorldDataRO { +public interface WorldDataContextRO extends WorldGenericContextRO { - // currently empty + /** + * Returns in-world time since creation. World time is zero before and + * during first tick. + *

+ * Game logic should assume that this value mostly increases uniformly. + * However, it is not guaranteed that in-world time always increments. + * + * @return time, in in-game seconds, since the world was created + */ + float getTime(); + + /** + * Gets the {@link GravityModel} used by this world. + * + * @return the gravity model + */ + GravityModel getGravityModel(); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/WorldGenericRO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/WorldGenericRO.java index 75ad1c3..eac2a0c 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/WorldGenericRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/WorldGenericRO.java @@ -144,7 +144,7 @@ public interface WorldGenericRO< return getChunk(chunkPos) != null; } - default boolean isBlockLoaded(Vec3i blockInWorld) { + default boolean isLocationLoaded(Vec3i blockInWorld) { return getChunkByBlock(blockInWorld) != null; } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockFaceGenericContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockFaceGenericContextRO.java index 212cc9b..0ca350a 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockFaceGenericContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockFaceGenericContextRO.java @@ -29,37 +29,15 @@ import ru.windcorp.progressia.common.world.generic.*; public interface BlockFaceGenericContextRO< B extends BlockGeneric, T extends TileGeneric, - TS extends TileGenericStackRO , - TR extends TileGenericReferenceRO , - C extends ChunkGenericRO , E extends EntityGeneric -> extends WorldContexts.BlockFace, BlockGenericContextRO { +> extends WorldContexts.BlockFace, BlockGenericContextRO { //@formatter:on /** - * Gets the tile stack at the relevant position. - * - * @return the specified tile stack or {@code null} if the location is not - * loaded or the tile stack does not exist - */ - default TS getTilesOrNull() { - return getTilesOrNull(getLocation(), getFace()); - } - - /** - * Determines whether the location relevant to this context has a tile - * stack. - * - * @return {@code true} iff the tile stack exists - */ - default boolean hasTiles() { - return hasTiles(getLocation(), getFace()); - } - - /** - * Determines whether the specified position has a tile; block location and - * face are implied by the context. + * Determines whether the specified position has a tile. Block location and + * block face are implied by the context. * + * @param layer the layer of the tile * @return {@code true} iff the tile exists */ default boolean hasTile(int layer) { @@ -67,14 +45,60 @@ public interface BlockFaceGenericContextRO< } /** - * Gets the tile at the specified position; block location and face are - * implied by the context. + * Determines whether the specified position has a tile with the given tag. + * Block location and block face are implied by the context. * - * @return the specified tile or {@code null} if the location is not loaded - * or the tile does not exist + * @param tag the tag of the tile + * @return {@code true} iff the tile exists + */ + default boolean isTagValid(int tag) { + return isTagValid(getLocation(), getFace(), tag); + } + + /** + * Retrieves the tile at the specified position. Block location and block + * face are implied by the context. This method may return {@code null} in + * one of three cases: + *

    + *
  • the location is not loaded, + *
  • there is no tile stack on the relevant face, or + *
  • {@code layer} is not less than the amount of tiles in the tile stack. + *
+ * + * @return the tile or {@code null} if the position does not contain a tile */ default T getTile(int layer) { return getTile(getLocation(), getFace(), layer); } + /** + * Retrieves the tile at the specified position and the tile's tag. Block + * location and block face are implied by the context. This + * method may return {@code null} in one of three cases: + *
    + *
  • the location is not loaded, + *
  • there is no tile stack on the relevant face, or + *
  • there is no tile with the specified tag in the tile stack. + *
+ * + * @param tag the tag of the tile + * @return the tile or {@code null} if the position does not contain a tile + */ + default T getTileByTag(int tag) { + return getTileByTag(getLocation(), getFace(), tag); + } + + /** + * Counts the amount of tiles in the specified tile stack. Block location + * and block face are implied by the context. + *

+ * This method returns {@code 0} in case the location is not loaded. + * + * @return the count of tiles in the tile stack or {@code -1} if the tile + * stack could not exist + */ + default int getTileCount() { + return getTileCount(getLocation(), getFace()); + } + } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockFaceGenericContextWO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockFaceGenericContextWO.java index bcaa226..dd6c5ad 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockFaceGenericContextWO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockFaceGenericContextWO.java @@ -31,11 +31,8 @@ import ru.windcorp.progressia.common.world.generic.*; public interface BlockFaceGenericContextWO< B extends BlockGeneric, T extends TileGeneric, - TS extends TileGenericStackWO , - TR extends TileGenericReferenceWO , - C extends ChunkGenericWO , E extends EntityGeneric -> extends WorldContexts.BlockFace, BlockGenericContextWO { +> extends WorldContexts.BlockFace, BlockGenericContextWO { //@formatter:on /** diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextRO.java index 91ac3d3..239a02e 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextRO.java @@ -29,11 +29,8 @@ import ru.windcorp.progressia.common.world.rels.BlockFace; public interface BlockGenericContextRO< B extends BlockGeneric, T extends TileGeneric, - TS extends TileGenericStackRO , - TR extends TileGenericReferenceRO , - C extends ChunkGenericRO , E extends EntityGeneric -> extends WorldContexts.Block, WorldGenericContextRO { +> extends WorldContexts.Block, WorldGenericContextRO { //@formatter:on /** @@ -43,11 +40,16 @@ public interface BlockGenericContextRO< * @return {@code true} iff the location is loaded */ default boolean isLoaded() { - return isBlockLoaded(getLocation()); + return isLocationLoaded(getLocation()); } /** - * Gets the block relevant in this context. + * Retrieves the block at the relevant location. This method may return + * {@code null} in one of two cases: + *

    + *
  • the location that the block would occupy is not loaded, or + *
  • the corresponding chunk's terrain has not yet generated. + *
* * @return the block or {@code null} if the location is not loaded */ @@ -56,30 +58,11 @@ public interface BlockGenericContextRO< } /** - * Gets the tile stack at the specified position; block location is implied - * by the context. - * - * @return the specified tile stack or {@code null} if the location is not - * loaded or the tile stack does not exist - */ - default TS getTilesOrNull(BlockFace face) { - return getTilesOrNull(getLocation(), face); - } - - /** - * Determines whether the location relevant to this context has a tile stack - * at the specified side. - * - * @return {@code true} iff the tile stack exists - */ - default boolean hasTiles(BlockFace face) { - return hasTiles(getLocation(), face); - } - - /** - * Determines whether the specified position has a tile; block location is + * Determines whether the specified position has a tile. Block location is * implied by the context. * + * @param face the face of the block that the tile occupies + * @param layer the layer of the tile * @return {@code true} iff the tile exists */ default boolean hasTile(BlockFace face, int layer) { @@ -87,14 +70,64 @@ public interface BlockGenericContextRO< } /** - * Gets the tile at the specified position; block location is implied by the - * context. + * Determines whether the specified position has a tile with the given tag. + * Block location is implied by context. * - * @return the specified tile or {@code null} if the location is not loaded - * or the tile does not exist + * @param face the face of the block that the tile occupies + * @param tag the tag of the tile + * @return {@code true} iff the tile exists + */ + default boolean isTagValid(BlockFace face, int tag) { + return isTagValid(getLocation(), face, tag); + } + + /** + * Retrieves the tile at the specified position. Block location is implied + * by context. This method may return {@code null} in one of three cases: + *
    + *
  • the location is not loaded, + *
  • there is no tile stack on the specified face, or + *
  • {@code layer} is not less than the amount of tiles in the tile stack. + *
+ * + * @param face the face of the block that the tile occupies + * @param layer the layer of the tile stack that the tile occupies + * @return the tile or {@code null} if the position does not contain a tile */ default T getTile(BlockFace face, int layer) { return getTile(getLocation(), face, layer); } + /** + * Retrieves the tile at the specified position and the tile's tag. Block + * location is implied by the context. This + * method may return {@code null} in one of three cases: + *
    + *
  • the location is not loaded, + *
  • there is no tile stack on the specified face, or + *
  • there is no tile with the specified tag in the tile stack. + *
+ * + * @param face the face of the block that the tile occupies + * @param tag the tag of the tile + * @return the tile or {@code null} if the position does not contain a tile + */ + default T getTileByTag(BlockFace face, int tag) { + return getTileByTag(getLocation(), face, tag); + } + + /** + * Counts the amount of tiles in the specified tile stack. Block location is + * implied by the context + *

+ * This method returns {@code 0} in case the location is not loaded. + * + * @param face the face of the block that the tile stack occupies + * @return the count of tiles in the tile stack or {@code -1} if the tile + * stack could not exist + */ + default int getTileCount(BlockFace face) { + return getTileCount(face); + } + } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextWO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextWO.java index f7a0eea..ffdb969 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextWO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/BlockGenericContextWO.java @@ -31,11 +31,8 @@ import ru.windcorp.progressia.common.world.rels.BlockFace; public interface BlockGenericContextWO< B extends BlockGeneric, T extends TileGeneric, - TS extends TileGenericStackWO , - TR extends TileGenericReferenceWO , - C extends ChunkGenericWO , E extends EntityGeneric -> extends WorldContexts.Block, WorldGenericContextWO { +> extends WorldContexts.Block, WorldGenericContextWO { //@formatter:on /** diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextRO.java index 0bc04d0..daf7fb8 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextRO.java @@ -29,15 +29,12 @@ import ru.windcorp.progressia.common.world.generic.*; public interface TileGenericContextRO< B extends BlockGeneric, T extends TileGeneric, - TS extends TileGenericStackRO , - TR extends TileGenericReferenceRO , - C extends ChunkGenericRO , E extends EntityGeneric -> extends WorldContexts.Tile, BlockFaceGenericContextRO { +> extends WorldContexts.Tile, BlockFaceGenericContextRO { //@formatter:on /** - * Determines whether the location relevant to this context has a tile. + * Determines whether the relevant position has a tile. * * @return {@code true} iff the tile exists */ @@ -46,42 +43,18 @@ public interface TileGenericContextRO< } /** - * Gets the tile at the relevant position. + * Retrieves the tile at the relevant position. This method may return + * {@code null} in one of three cases: + *

    + *
  • the location is not loaded, + *
  • there is no tile stack on the relevant face, or + *
  • {@code layer} is not less than the amount of tiles in the tile stack. + *
* - * @return the specified tile or {@code null} if the location is not loaded - * or the tile does not exist + * @return the tile or {@code null} if the position does not contain a tile */ default T getTile() { return getTile(getLocation(), getFace(), getLayer()); } - @Override - default int getTag() { - TS tileStack = getTilesOrNull(); - if (tileStack == null) { - return -1; - } - - return tileStack.getTagByIndex(getLayer()); - } - - /** - * Gets the {@link TileGenericReferenceRO TileReference} to the relevant - * tile. - * - * @return the reference to the tile relevant to this context or - * {@code null} if the location is not loaded or the tile does not - * exist - * - * @see TileGenericStackRO#getReference(int) - */ - default TR getTileReference() { - TS tileStack = getTilesOrNull(); - if (tileStack == null) { - return null; - } - - return tileStack.getReference(getLayer()); - } - } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextWO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextWO.java index 01a27d1..4c2b4dd 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextWO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/TileGenericContextWO.java @@ -31,11 +31,8 @@ import ru.windcorp.progressia.common.world.generic.*; public interface TileGenericContextWO< B extends BlockGeneric, T extends TileGeneric, - TS extends TileGenericStackWO , - TR extends TileGenericReferenceWO , - C extends ChunkGenericWO , E extends EntityGeneric -> extends WorldContexts.Tile, BlockFaceGenericContextWO { +> extends WorldContexts.Tile, BlockFaceGenericContextWO { //@formatter:on /** diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextRO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextRO.java index 588c98f..d604d62 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextRO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextRO.java @@ -17,23 +17,175 @@ */ package ru.windcorp.progressia.common.world.generic.context; +import java.util.Collection; +import java.util.function.Consumer; + +import glm.vec._3.Vec3; +import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.context.Context; import ru.windcorp.progressia.common.world.generic.*; +import ru.windcorp.progressia.common.world.rels.BlockFace; /** * A {@link Context} with a world instance. + *

+ * This interfaces defines the entirety of world query methods supported by the + * default contexts. */ // @formatter:off public interface WorldGenericContextRO< B extends BlockGeneric, T extends TileGeneric, - TS extends TileGenericStackRO , - TR extends TileGenericReferenceRO , - C extends ChunkGenericRO , E extends EntityGeneric -> extends WorldContexts.World, WorldGenericRO { +> extends WorldContexts.World { // @formatter:on - - // currently empty - + + /** + * Retrieves the block at the specified location. This method may return + * {@code null} in one of two cases: + *

    + *
  • the location that the block would occupy is not loaded, or + *
  • the corresponding chunk's terrain has not yet generated. + *
+ * + * @param location the location to query + * @return the block or {@code null} if the location is not loaded + */ + B getBlock(Vec3i location); + + /** + * Determines whether the specified location is loaded. + * + * @param location the location to query + * @return {@code true} iff the location is loaded + */ + boolean isLocationLoaded(Vec3i location); + + /** + * Retrieves the tile at the specified position. This method may return + * {@code null} in one of three cases: + *
    + *
  • the location is not loaded, + *
  • there is no tile stack on the specified face, or + *
  • {@code layer} is not less than the amount of tiles in the tile stack. + *
+ * + * @param location location of the host block + * @param face the face of the block that the tile occupies + * @param layer the layer of the tile stack that the tile occupies + * @return the tile or {@code null} if the position does not contain a tile + */ + T getTile(Vec3i location, BlockFace face, int layer); + + /** + * Retrieves the tile at the specified position and the tile's tag. This + * method may return {@code null} in one of three cases: + *
    + *
  • the location is not loaded, + *
  • there is no tile stack on the specified face, or + *
  • there is no tile with the specified tag in the tile stack. + *
+ * + * @param location location of the host block + * @param face the face of the block that the tile occupies + * @param tag the tag of the tile + * @return the tile or {@code null} if the position does not contain a tile + */ + T getTileByTag(Vec3i location, BlockFace face, int tag); + + /** + * Determines whether the specified position has a tile. + * + * @param location location of the host block + * @param face the face of the block that the tile occupies + * @param layer the layer of the tile + * @return {@code true} iff the tile exists + */ + boolean hasTile(Vec3i location, BlockFace face, int layer); + + /** + * Determines whether the specified position has a tile with the given tag. + * + * @param location location of the host block + * @param face the face of the block that the tile occupies + * @param tag the tag of the tile + * @return {@code true} iff the tile exists + */ + boolean isTagValid(Vec3i location, BlockFace face, int tag); + + /** + * Counts the amount of tiles in the specified tile stack. + *

+ * This method returns {@code 0} in case the location is not loaded. + * + * @param location location of the host block + * @param face the face of the block that the tile stack occupies + * @return the count of tiles in the tile stack or {@code -1} if the tile + * stack could not exist + */ + int getTileCount(Vec3i location, BlockFace face); + + /** + * Retrieves a listing of all entities. {@link #forEachEntity(Consumer)} + * should be used to iterate the collection. The collection is not + * modifiable. + * + * @return all loaded entities + */ + Collection getEntities(); + + /** + * Retrieves the entity with the specified entity ID. + * + * @param entityId the entity ID to look up + * @return the entity found or {@code null} + */ + E getEntity(long entityId); + + /* + * Convenience methods + */ + + /** + * Iterates all entities safely + */ + default void forEachEntity(Consumer action) { + getEntities().forEach(action); + } + + /** + * Iterates all entities in cuboid safely + */ + default void forEachEntityIn(Vec3i min, Vec3i max, Consumer action) { + forEachEntity(e -> { + Vec3 pos = e.getPosition(); + if (pos.x < min.x || pos.y < min.y || pos.z < min.z || pos.x > max.x || pos.y > max.y || pos.z > max.z) { + action.accept(e); + } + }); + } + + /** + * Iterates all entities in cuboid safely + */ + default void forEachEntityIn(Vec3 min, Vec3 max, Consumer action) { + forEachEntity(e -> { + Vec3 pos = e.getPosition(); + if (pos.x < min.x || pos.y < min.y || pos.z < min.z || pos.x > max.x || pos.y > max.y || pos.z > max.z) { + action.accept(e); + } + }); + } + + /** + * Iterates all entities with ID safely + */ + default void forEachEntityWithId(String id, Consumer action) { + forEachEntity(e -> { + if (id.equals(e.getId())) { + action.accept(e); + } + }); + } + } diff --git a/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextWO.java b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextWO.java index 27bbb1a..ad1291e 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextWO.java +++ b/src/main/java/ru/windcorp/progressia/common/world/generic/context/WorldGenericContextWO.java @@ -28,16 +28,16 @@ import ru.windcorp.progressia.common.world.rels.BlockFace; * A writable {@link Context} with a world instance. This context provides * methods for affecting the world. The application of requested changes may or * may not be immediate, see {@link #isImmediate()}. + *

+ * This interfaces defines the entirety of world modification methods supported + * by the default contexts. */ // @formatter:off public interface WorldGenericContextWO< B extends BlockGeneric, T extends TileGeneric, - TS extends TileGenericStackWO , - TR extends TileGenericReferenceWO , - C extends ChunkGenericWO , E extends EntityGeneric -> extends WorldContexts.World, WorldGenericWO { +> extends WorldContexts.World { // @formatter:on /** @@ -116,7 +116,6 @@ public interface WorldGenericContextWO< * @param entity the entity to add * @see #isImmediate() */ - @Override void addEntity(E entity); /** @@ -128,7 +127,6 @@ public interface WorldGenericContextWO< * @see #isImmediate() * @see #removeEntity(EntityGeneric) */ - @Override void removeEntity(long entityId); /** @@ -139,7 +137,6 @@ public interface WorldGenericContextWO< * @see #isImmediate() * @see #removeEntity(long) */ - @Override default void removeEntity(E entity) { removeEntity(entity.getEntityId()); } @@ -151,7 +148,6 @@ public interface WorldGenericContextWO< * @param entity the entity to change * @param change the change to apply */ - @Override void changeEntity(SE entity, StateChange change); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java b/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java index fd3e0ec..112d722 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java +++ b/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java @@ -73,7 +73,7 @@ public class TickAndUpdateUtil { } public static void tickTiles(DefaultWorldLogic world, Vec3i blockInWorld, BlockFace face) { - if (!world.isBlockLoaded(blockInWorld)) { + if (!world.isLocationLoaded(blockInWorld)) { return; } @@ -123,7 +123,7 @@ public class TickAndUpdateUtil { } public static void updateTiles(DefaultWorldLogic world, Vec3i blockInWorld, BlockFace face) { - if (!world.isBlockLoaded(blockInWorld)) { + if (!world.isLocationLoaded(blockInWorld)) { return; } diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContext.java index a1fbbf5..4130b50 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContext.java @@ -18,8 +18,6 @@ package ru.windcorp.progressia.server.world.context; import ru.windcorp.progressia.common.world.context.BlockDataContext; -import ru.windcorp.progressia.common.world.rels.BlockFace; -import ru.windcorp.progressia.server.world.TileLogicStack; public interface ServerBlockContext extends BlockDataContext, ServerWorldContext, ServerBlockContextRO { @@ -28,11 +26,6 @@ public interface ServerBlockContext extends BlockDataContext, ServerWorldContext @Override ServerBlockContext data(); - @Override - default TileLogicStack getTilesOrNull(BlockFace face) { - return (TileLogicStack) ServerBlockContextRO.Logic.super.getTilesOrNull(face); - } - } @Override diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContextRO.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContextRO.java index 1ffb30d..ca2e09f 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContextRO.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockContextRO.java @@ -20,16 +20,13 @@ package ru.windcorp.progressia.server.world.context; import ru.windcorp.progressia.common.world.context.BlockDataContextRO; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.context.BlockGenericContextRO; -import ru.windcorp.progressia.server.world.ChunkLogicRO; -import ru.windcorp.progressia.server.world.TileLogicReferenceRO; -import ru.windcorp.progressia.server.world.TileLogicStackRO; import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.tile.TileLogic; public interface ServerBlockContextRO extends ServerWorldContextRO, BlockDataContextRO { - public interface Logic extends ServerWorldContextRO.Logic, - BlockGenericContextRO { + public interface Logic + extends ServerWorldContextRO.Logic, BlockGenericContextRO { @Override ServerBlockContextRO data(); diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockFaceContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockFaceContext.java index 335e15f..499408d 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockFaceContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockFaceContext.java @@ -18,7 +18,6 @@ package ru.windcorp.progressia.server.world.context; import ru.windcorp.progressia.common.world.context.BlockFaceDataContext; -import ru.windcorp.progressia.server.world.TileLogicStack; public interface ServerBlockFaceContext extends BlockFaceDataContext, ServerBlockContext, ServerBlockFaceContextRO { @@ -27,11 +26,6 @@ public interface ServerBlockFaceContext extends BlockFaceDataContext, ServerBloc @Override ServerBlockFaceContext data(); - @Override - default TileLogicStack getTilesOrNull() { - return (TileLogicStack) ServerBlockFaceContextRO.Logic.super.getTilesOrNull(); - } - } @Override diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockFaceContextRO.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockFaceContextRO.java index 7fca1db..b1a3f05 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockFaceContextRO.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerBlockFaceContextRO.java @@ -20,16 +20,13 @@ package ru.windcorp.progressia.server.world.context; import ru.windcorp.progressia.common.world.context.BlockFaceDataContextRO; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.context.BlockFaceGenericContextRO; -import ru.windcorp.progressia.server.world.ChunkLogicRO; -import ru.windcorp.progressia.server.world.TileLogicReferenceRO; -import ru.windcorp.progressia.server.world.TileLogicStackRO; import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.tile.TileLogic; public interface ServerBlockFaceContextRO extends ServerBlockContextRO, BlockFaceDataContextRO { - public interface Logic extends ServerBlockContextRO.Logic, - BlockFaceGenericContextRO { + public interface Logic + extends ServerBlockContextRO.Logic, BlockFaceGenericContextRO { @Override ServerBlockFaceContextRO data(); diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerContext.java index bb218ab..052718f 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerContext.java @@ -51,9 +51,7 @@ public interface ServerContext extends Context { * * @return the length of the last server tick */ - default double getTickLength() { - return getServer().getTickLength(); - } + double getTickLength(); /** * Adjusts the provided value according to tick length assuming the value diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContext.java index 5d5a3c0..7682287 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContext.java @@ -18,7 +18,6 @@ package ru.windcorp.progressia.server.world.context; import ru.windcorp.progressia.common.world.context.TileDataContext; -import ru.windcorp.progressia.server.world.TileLogicReference; public interface ServerTileContext extends TileDataContext, ServerBlockFaceContext, ServerTileContextRO { @@ -27,11 +26,6 @@ public interface ServerTileContext extends TileDataContext, ServerBlockFaceConte @Override ServerTileContext data(); - @Override - default TileLogicReference getTileReference() { - return (TileLogicReference) ServerTileContextRO.Logic.super.getTileReference(); - } - } @Override diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContextRO.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContextRO.java index 73b8d2c..b5a42df 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContextRO.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerTileContextRO.java @@ -20,16 +20,13 @@ package ru.windcorp.progressia.server.world.context; import ru.windcorp.progressia.common.world.context.TileDataContextRO; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.context.TileGenericContextRO; -import ru.windcorp.progressia.server.world.ChunkLogicRO; -import ru.windcorp.progressia.server.world.TileLogicReferenceRO; -import ru.windcorp.progressia.server.world.TileLogicStackRO; import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.tile.TileLogic; public interface ServerTileContextRO extends ServerBlockFaceContextRO, TileDataContextRO { - public interface Logic extends ServerBlockFaceContextRO.Logic, - TileGenericContextRO { + public interface Logic + extends ServerBlockFaceContextRO.Logic, TileGenericContextRO { @Override ServerTileContextRO data(); diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContext.java index ee04242..b8504c4 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContext.java @@ -17,22 +17,14 @@ */ package ru.windcorp.progressia.server.world.context; -import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.context.WorldDataContext; -import ru.windcorp.progressia.common.world.rels.BlockFace; -import ru.windcorp.progressia.server.world.TileLogicStack; -import ru.windcorp.progressia.server.world.WorldLogic; public interface ServerWorldContext extends WorldDataContext, ServerWorldContextRO { - public interface Logic extends ServerWorldContextRO.Logic, - WorldLogic { + public interface Logic extends ServerWorldContextRO.Logic { @Override ServerWorldContext data(); - - @Override - TileLogicStack getTiles(Vec3i blockInWorld, BlockFace face); } diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContextRO.java b/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContextRO.java index 43eeedc..0202024 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContextRO.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/ServerWorldContextRO.java @@ -3,20 +3,12 @@ package ru.windcorp.progressia.server.world.context; import ru.windcorp.progressia.common.world.context.WorldDataContextRO; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.generic.context.WorldGenericContextRO; -import ru.windcorp.progressia.server.world.ChunkLogicRO; -import ru.windcorp.progressia.server.world.TileLogicReferenceRO; -import ru.windcorp.progressia.server.world.TileLogicStackRO; -import ru.windcorp.progressia.server.world.WorldLogicRO; import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.tile.TileLogic; public interface ServerWorldContextRO extends WorldDataContextRO, ServerContext { - public interface Logic - extends - WorldGenericContextRO, - WorldLogicRO, - ServerContext { + public interface Logic extends WorldGenericContextRO, ServerContext { /** * Acquires the data view of this context. Use this method to diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContext.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContext.java index fdffd22..6131776 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContext.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContext.java @@ -37,9 +37,14 @@ import ru.windcorp.progressia.server.world.context.ServerWorldContextRO; * when a {@link WorldLogic} (or a {@link WorldLogicRO}) instance requires a * context wrapper. *

- * Use other unutilized instances of {@link ReusableServerContext} or + * Use other unutilized instances of {@code ReusableServerContext} or * {@link #empty()} static method to acquire a usable instance. *

+ * {@code ReusableServerContext} asserts that is it {@linkplain #isReal() real} + * and {@linkplain #isImmediate() immediate}. It creates and provides an + * independent randomness source. The tick length is consulted with the server. + * Use wrappers to alter these properties. + *

* This class defines the outward-facing safe interface of the actual * implementation located in {@link ReusableServerContextImpl}. The reasoning * for creating a subclass is to allow a single instance to implement both diff --git a/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContextImpl.java b/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContextImpl.java index 2336937..7e4545d 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContextImpl.java +++ b/src/main/java/ru/windcorp/progressia/server/world/context/impl/ReusableServerContextImpl.java @@ -23,7 +23,6 @@ import java.util.Random; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.state.StateChange; import ru.windcorp.progressia.common.state.StatefulObject; -import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.GravityModel; import ru.windcorp.progressia.common.world.TileDataStack; import ru.windcorp.progressia.common.world.WorldData; @@ -34,10 +33,11 @@ import ru.windcorp.progressia.common.world.rels.BlockFace; import ru.windcorp.progressia.common.world.rels.RelFace; import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.server.Server; -import ru.windcorp.progressia.server.world.ChunkLogic; import ru.windcorp.progressia.server.world.TileLogicStack; import ru.windcorp.progressia.server.world.WorldLogic; +import ru.windcorp.progressia.server.world.block.BlockLogic; import ru.windcorp.progressia.server.world.context.ServerTileContext; +import ru.windcorp.progressia.server.world.tile.TileLogic; class ReusableServerContextImpl extends ReusableServerContext implements ReusableServerContextBuilders.Empty, ReusableServerContextBuilders.WithWorld, @@ -61,7 +61,13 @@ class ReusableServerContextImpl extends ReusableServerContext * The relevant {@link WorldLogic} instance. If this is {@code null}, the * role is {@link Role#NONE}. */ - protected WorldLogic world; + protected WorldLogic worldLogic; + + /** + * The {@link WorldData} accessible through {@link #worldLogic}. This field + * is kept always in sync with {@link #worldLogic}. + */ + protected WorldData worldData; /** * The relevant location. If this is {@code null}, the role is @@ -85,7 +91,12 @@ class ReusableServerContextImpl extends ReusableServerContext * The index of the relevant tile. This value is {@code -1} unless the role * is {@link Role#TILE}. */ - protected int index; + protected int layer; + + /** + * The {@link Random} instance exposed with {@link #getRandom()}. + */ + protected final Random random = new Random(); /** * Determines whether this object currently acts as a builder or a context. @@ -98,7 +109,7 @@ class ReusableServerContextImpl extends ReusableServerContext * ends. This is always 0 when the object is a builder. */ protected int subcontextDepth = 0; - + /** * The Logic view returned by {@link #logic()}. */ @@ -117,7 +128,7 @@ class ReusableServerContextImpl extends ReusableServerContext return Role.WORLD; if (blockFace == null) return Role.LOCATION; - if (index == -1) + if (layer == -1) return Role.TILE_STACK; return Role.TILE; } @@ -179,7 +190,7 @@ class ReusableServerContextImpl extends ReusableServerContext location.y, location.z, blockFace, - index + layer ); break; case TILE_STACK: @@ -216,10 +227,11 @@ class ReusableServerContextImpl extends ReusableServerContext } server = null; - world = null; + worldLogic = null; + worldData = null; location = null; blockFace = null; - index = -1; + layer = -1; isBuilder = true; @@ -246,7 +258,8 @@ class ReusableServerContextImpl extends ReusableServerContext public WithWorld in(Server server, WorldLogic world) { requireBuilderRole(Role.NONE); this.server = server; - this.world = world; + this.worldLogic = world; + this.worldData = world.getData(); return this; } @@ -272,11 +285,11 @@ class ReusableServerContextImpl extends ReusableServerContext this.blockFace = side; return this; } - + @Override public WithTileStack on(BlockFace side) { requireBuilderRole(Role.LOCATION); - this.blockFace = side.relativize(world.getData().getUp(location)); + this.blockFace = side.relativize(worldLogic.getData().getUp(location)); return this; } @@ -287,91 +300,10 @@ class ReusableServerContextImpl extends ReusableServerContext @Override public ReusableServerContext index(int index) { requireBuilderRole(Role.TILE_STACK); - this.index = index; + this.layer = index; return build(); } - /* - * ServerWorldContext.Logic STUFF - */ - - private class Logic implements ServerTileContext.Logic { - @Override - public boolean isReal() { - return ReusableServerContextImpl.this.isReal(); - } - - @Override - public Collection getChunks() { - return world.getChunks(); - } - - @Override - public Collection getEntities() { - return ReusableServerContextImpl.this.getEntities(); - } - - @Override - public EntityData getEntity(long entityId) { - return ReusableServerContextImpl.this.getEntity(entityId); - } - - @Override - public Server getServer() { - return ReusableServerContextImpl.this.getServer(); - } - - @Override - public Random getRandom() { - return ReusableServerContextImpl.this.getRandom(); - } - - @Override - public Vec3i getLocation() { - return ReusableServerContextImpl.this.getLocation(); - } - - @Override - public RelFace getFace() { - return ReusableServerContextImpl.this.getFace(); - } - - @Override - public int getLayer() { - return ReusableServerContextImpl.this.getLayer(); - } - - @Override - public TileLogicStack getTiles(Vec3i blockInWorld, BlockFace face) { - return world.getTiles(blockInWorld, face); - } - - @Override - public ChunkLogic getChunk(Vec3i pos) { - return world.getChunk(pos); - } - - @Override - public WorldData getData() { - return world.getData(); - } - - @Override - public ServerTileContext data() { - return ReusableServerContextImpl.this; - } - - @Override - public String toString() { - return ReusableServerContextImpl.this + ".Logic"; - } - } - - @Override - public Logic logic() { - return logic; - } - /* * LOCATION GETTERS */ @@ -381,139 +313,326 @@ class ReusableServerContextImpl extends ReusableServerContext assert requireContextRole(Role.WORLD); return server; } - + @Override public Vec3i getLocation() { assert requireContextRole(Role.LOCATION); return location; } - + @Override public RelFace getFace() { assert requireContextRole(Role.TILE_STACK); return blockFace; } - + @Override public int getLayer() { assert requireContextRole(Role.TILE); - return index; + return layer; } /* * RO CONTEXT INTERFACE */ - + @Override public boolean isReal() { assert requireContextRole(Role.WORLD); return true; } - + @Override public Random getRandom() { assert requireContextRole(Role.WORLD); - return server.getAdHocRandom(); + return random; } - + @Override - public ChunkData getChunk(Vec3i pos) { + public double getTickLength() { assert requireContextRole(Role.WORLD); - return world.getData().getChunk(pos); + return server.getTickLength(); } - + @Override - public Collection getChunks() { + public BlockData getBlock(Vec3i location) { assert requireContextRole(Role.WORLD); - return world.getData().getChunks(); + return worldData.getBlock(location); } - + + @Override + public boolean isLocationLoaded(Vec3i location) { + assert requireContextRole(Role.WORLD); + return worldData.isLocationLoaded(location); + } + + @Override + public TileData getTile(Vec3i location, BlockFace face, int layer) { + assert requireContextRole(Role.WORLD); + return worldData.getTile(location, face, layer); + } + + @Override + public boolean hasTile(Vec3i location, BlockFace face, int layer) { + assert requireContextRole(Role.WORLD); + return worldData.hasTile(location, face, layer); + } + + @Override + public TileData getTileByTag(Vec3i location, BlockFace face, int tag) { + assert requireContextRole(Role.WORLD); + TileDataStack stack = worldData.getTilesOrNull(location, face); + if (stack == null) + return null; + int layer = stack.getIndexByTag(tag); + if (layer == -1) + return null; + return stack.get(layer); + } + + @Override + public boolean isTagValid(Vec3i location, BlockFace face, int tag) { + assert requireContextRole(Role.WORLD); + TileDataStack stack = worldData.getTilesOrNull(location, face); + if (stack == null) + return false; + return stack.getIndexByTag(tag) != -1; + } + + @Override + public int getTag() { + assert requireContextRole(Role.TILE); + TileDataStack stack = worldData.getTilesOrNull(location, blockFace); + if (stack == null) + return -1; + return stack.getTagByIndex(layer); + } + + @Override + public int getTileCount(Vec3i location, BlockFace face) { + assert requireContextRole(Role.TILE_STACK); + TileDataStack stack = worldData.getTilesOrNull(location, blockFace); + if (stack == null) + return 0; + return stack.size(); + } + @Override public Collection getEntities() { assert requireContextRole(Role.WORLD); - return world.getEntities(); + return worldData.getEntities(); } - + @Override public EntityData getEntity(long entityId) { assert requireContextRole(Role.WORLD); - return world.getEntity(entityId); + return worldData.getEntity(entityId); } - + @Override public GravityModel getGravityModel() { assert requireContextRole(Role.WORLD); - return world.getData().getGravityModel(); + return worldData.getGravityModel(); } - + @Override public float getTime() { assert requireContextRole(Role.WORLD); - return world.getData().getTime(); + return worldData.getTime(); } - /* - * RO CONTEXT OPTIMIZATIONS - */ - /* * RW CONTEXT INTERFACE */ - + @Override public boolean isImmediate() { assert requireContextRole(Role.WORLD); return true; } - + @Override - public void setBlock(Vec3i blockInWorld, BlockData block, boolean notify) { + public void setBlock(Vec3i blockInWorld, BlockData block) { assert requireContextRole(Role.WORLD); - world.getData().setBlock(blockInWorld, block, notify); + worldData.setBlock(blockInWorld, block, true); } - + @Override public void addTile(Vec3i location, BlockFace face, TileData tile) { assert requireContextRole(Role.WORLD); - world.getData().getTiles(location, face).addFarthest(tile); + worldData.getTiles(location, face).addFarthest(tile); } - + @Override public void removeTile(Vec3i location, BlockFace face, int tag) { assert requireContextRole(Role.WORLD); - TileDataStack stack = world.getData().getTilesOrNull(location, face); - if (stack == null) return; - int index = stack.getIndexByTag(tag); - if (index == -1) return; - stack.remove(index); + TileDataStack stack = worldData.getTilesOrNull(location, face); + if (stack == null) + return; + int layer = stack.getIndexByTag(tag); + if (layer == -1) + return; + stack.remove(layer); } - + @Override public void addEntity(EntityData entity) { assert requireContextRole(Role.WORLD); - world.getData().addEntity(entity); + worldData.addEntity(entity); } - + @Override public void removeEntity(long entityId) { assert requireContextRole(Role.WORLD); - world.getData().removeEntity(entityId); + worldData.removeEntity(entityId); } - + @Override public void changeEntity(SE entity, StateChange change) { assert requireContextRole(Role.WORLD); - world.getData().changeEntity(entity, change); + worldData.changeEntity(entity, change); } - + @Override public void advanceTime(float change) { assert requireContextRole(Role.WORLD); - world.getData().advanceTime(change); + worldData.advanceTime(change); } /* - * RW CONTEXT OPTIMIZATIONS + * ServerWorldContext.Logic STUFF */ + private class Logic implements ServerTileContext.Logic { + + /* + * LOCATION GETTERS + */ + + @Override + public Server getServer() { + return server; + } + + @Override + public Vec3i getLocation() { + return location; + } + + @Override + public RelFace getFace() { + return blockFace; + } + + @Override + public int getLayer() { + return layer; + } + + /* + * RO CONTEXT INTERFACE + */ + + @Override + public boolean isReal() { + return true; + } + + @Override + public Random getRandom() { + return random; + } + + @Override + public double getTickLength() { + return server.getTickLength(); + } + + @Override + public BlockLogic getBlock(Vec3i location) { + assert requireContextRole(Role.WORLD); + return worldLogic.getBlock(location); + } + + @Override + public boolean isLocationLoaded(Vec3i location) { + return worldData.isLocationLoaded(location); + } + + @Override + public boolean hasTile(Vec3i location, BlockFace face, int layer) { + return worldData.hasTile(location, face, layer); + } + + @Override + public boolean isTagValid(Vec3i location, BlockFace face, int tag) { + return ReusableServerContextImpl.this.isTagValid(location, face, tag); + } + + @Override + public TileLogic getTile(Vec3i location, BlockFace face, int layer) { + assert requireContextRole(Role.WORLD); + return worldLogic.getTile(location, face, layer); + } + + @Override + public TileLogic getTileByTag(Vec3i location, BlockFace face, int tag) { + assert requireContextRole(Role.WORLD); + TileLogicStack stack = worldLogic.getTilesOrNull(location, face); + if (stack == null) { + return null; + } + int layer = stack.getIndexByTag(tag); + if (layer == -1) { + return null; + } + return stack.get(layer); + } + + @Override + public int getTileCount(Vec3i location, BlockFace face) { + assert requireContextRole(Role.WORLD); + TileLogicStack stack = worldLogic.getTilesOrNull(location, face); + if (stack == null) { + return 0; + } + return stack.size(); + } + + @Override + public int getTag() { + return ReusableServerContextImpl.this.getTag(); + } + + @Override + public Collection getEntities() { + return worldLogic.getEntities(); + } + + @Override + public EntityData getEntity(long entityId) { + return worldLogic.getEntity(entityId); + } + + /* + * MISC + */ + + @Override + public ReusableServerContext data() { + return ReusableServerContextImpl.this; + } + + @Override + public String toString() { + return ReusableServerContextImpl.this + ".Logic"; + } + } + + @Override + public Logic logic() { + assert requireContextRole(Role.WORLD); + return logic; + } + } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceWorld.java b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceWorld.java index 7d3ec10..43a218e 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceWorld.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/surface/SurfaceWorld.java @@ -177,7 +177,7 @@ public class SurfaceWorld public boolean isBlockLoadedSfc(Vec3i surfaceBlockInWorld) { Vec3i blockInWorld = Vectors.grab3i(); resolve(surfaceBlockInWorld, blockInWorld); - boolean result = parent.isBlockLoaded(blockInWorld); + boolean result = parent.isLocationLoaded(blockInWorld); Vectors.release(blockInWorld); return result; }