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
This commit is contained in:
OLEGSHA 2021-08-05 16:42:21 +03:00
parent fbc803d6e2
commit 0f60d45ffa
Signed by: OLEGSHA
GPG Key ID: E57A4B08D64AFF7A
30 changed files with 613 additions and 373 deletions

View File

@ -17,19 +17,16 @@
*/ */
package ru.windcorp.progressia.common.world.context; 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.block.BlockData;
import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.entity.EntityData;
import ru.windcorp.progressia.common.world.generic.context.BlockGenericContextWO; import ru.windcorp.progressia.common.world.generic.context.BlockGenericContextWO;
import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.common.world.tile.TileData;
public interface BlockDataContext public interface BlockDataContext
extends BlockGenericContextWO<BlockData, TileData, TileDataStack, TileDataReference, ChunkData, EntityData>, extends BlockGenericContextWO<BlockData, TileData, EntityData>,
WorldDataContext, WorldDataContext,
BlockDataContextRO { BlockDataContextRO {
// currently empty // currently empty
} }

View File

@ -17,16 +17,13 @@
*/ */
package ru.windcorp.progressia.common.world.context; 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.block.BlockData;
import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.entity.EntityData;
import ru.windcorp.progressia.common.world.generic.context.BlockGenericContextRO; import ru.windcorp.progressia.common.world.generic.context.BlockGenericContextRO;
import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.common.world.tile.TileData;
public interface BlockDataContextRO public interface BlockDataContextRO
extends BlockGenericContextRO<BlockData, TileData, TileDataStackRO, TileDataReferenceRO, ChunkDataRO, EntityData>, extends BlockGenericContextRO<BlockData, TileData, EntityData>,
WorldDataContextRO { WorldDataContextRO {
// currently empty // currently empty

View File

@ -17,19 +17,16 @@
*/ */
package ru.windcorp.progressia.common.world.context; 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.block.BlockData;
import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.entity.EntityData;
import ru.windcorp.progressia.common.world.generic.context.BlockFaceGenericContextWO; import ru.windcorp.progressia.common.world.generic.context.BlockFaceGenericContextWO;
import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.common.world.tile.TileData;
public interface BlockFaceDataContext public interface BlockFaceDataContext
extends BlockFaceGenericContextWO<BlockData, TileData, TileDataStack, TileDataReference, ChunkData, EntityData>, extends BlockFaceGenericContextWO<BlockData, TileData, EntityData>,
BlockDataContext, BlockDataContext,
BlockFaceDataContextRO { BlockFaceDataContextRO {
// currently empty // currently empty
} }

View File

@ -17,16 +17,13 @@
*/ */
package ru.windcorp.progressia.common.world.context; 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.block.BlockData;
import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.entity.EntityData;
import ru.windcorp.progressia.common.world.generic.context.BlockFaceGenericContextRO; import ru.windcorp.progressia.common.world.generic.context.BlockFaceGenericContextRO;
import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.common.world.tile.TileData;
public interface BlockFaceDataContextRO public interface BlockFaceDataContextRO
extends BlockFaceGenericContextRO<BlockData, TileData, TileDataStackRO, TileDataReferenceRO, ChunkDataRO, EntityData>, extends BlockFaceGenericContextRO<BlockData, TileData, EntityData>,
BlockDataContext { BlockDataContext {
// currently empty // currently empty

View File

@ -17,22 +17,16 @@
*/ */
package ru.windcorp.progressia.common.world.context; 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.block.BlockData;
import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.entity.EntityData;
import ru.windcorp.progressia.common.world.generic.context.TileGenericContextWO; import ru.windcorp.progressia.common.world.generic.context.TileGenericContextWO;
import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.common.world.tile.TileData;
public interface TileDataContext public interface TileDataContext
extends TileGenericContextWO<BlockData, TileData, TileDataStack, TileDataReference, ChunkData, EntityData>, extends TileGenericContextWO<BlockData, TileData, EntityData>,
BlockFaceDataContext, BlockFaceDataContext,
TileDataContextRO { TileDataContextRO {
@Override // currently empty
default int getTag() {
return getTileReference().getTag();
}
} }

View File

@ -17,16 +17,13 @@
*/ */
package ru.windcorp.progressia.common.world.context; 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.block.BlockData;
import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.entity.EntityData;
import ru.windcorp.progressia.common.world.generic.context.TileGenericContextRO; import ru.windcorp.progressia.common.world.generic.context.TileGenericContextRO;
import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.common.world.tile.TileData;
public interface TileDataContextRO public interface TileDataContextRO
extends TileGenericContextRO<BlockData, TileData, TileDataStackRO, TileDataReferenceRO, ChunkDataRO, EntityData>, extends TileGenericContextRO<BlockData, TileData, EntityData>,
BlockFaceDataContextRO { BlockFaceDataContextRO {
// currently empty // currently empty

View File

@ -17,20 +17,23 @@
*/ */
package ru.windcorp.progressia.common.world.context; 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.block.BlockData;
import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.entity.EntityData;
import ru.windcorp.progressia.common.world.generic.context.WorldGenericContextWO; import ru.windcorp.progressia.common.world.generic.context.WorldGenericContextWO;
import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.common.world.tile.TileData;
public interface WorldDataContext public interface WorldDataContext
extends WorldGenericContextWO<BlockData, TileData, TileDataStack, TileDataReference, ChunkData, EntityData>, extends WorldGenericContextWO<BlockData, TileData, EntityData>,
WorldDataContextRO, WorldDataContextRO {
WorldData {
/**
// currently empty * 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);
} }

View File

@ -18,19 +18,30 @@
package ru.windcorp.progressia.common.world.context; package ru.windcorp.progressia.common.world.context;
import ru.windcorp.progressia.common.world.ChunkDataRO; import ru.windcorp.progressia.common.world.GravityModel;
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.block.BlockData; import ru.windcorp.progressia.common.world.block.BlockData;
import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.entity.EntityData;
import ru.windcorp.progressia.common.world.generic.context.WorldGenericContextRO; import ru.windcorp.progressia.common.world.generic.context.WorldGenericContextRO;
import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.common.world.tile.TileData;
public interface WorldDataContextRO public interface WorldDataContextRO extends WorldGenericContextRO<BlockData, TileData, EntityData> {
extends WorldGenericContextRO<BlockData, TileData, TileDataStackRO, TileDataReferenceRO, ChunkDataRO, EntityData>,
WorldDataRO {
// currently empty /**
* Returns in-world time since creation. World time is zero before and
* during first tick.
* <p>
* 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();
} }

View File

@ -144,7 +144,7 @@ public interface WorldGenericRO<
return getChunk(chunkPos) != null; return getChunk(chunkPos) != null;
} }
default boolean isBlockLoaded(Vec3i blockInWorld) { default boolean isLocationLoaded(Vec3i blockInWorld) {
return getChunkByBlock(blockInWorld) != null; return getChunkByBlock(blockInWorld) != null;
} }

View File

@ -29,37 +29,15 @@ import ru.windcorp.progressia.common.world.generic.*;
public interface BlockFaceGenericContextRO< public interface BlockFaceGenericContextRO<
B extends BlockGeneric, B extends BlockGeneric,
T extends TileGeneric, T extends TileGeneric,
TS extends TileGenericStackRO <B, T, TS, TR, C>,
TR extends TileGenericReferenceRO <B, T, TS, TR, C>,
C extends ChunkGenericRO <B, T, TS, TR, C>,
E extends EntityGeneric E extends EntityGeneric
> extends WorldContexts.BlockFace, BlockGenericContextRO<B, T, TS, TR, C, E> { > extends WorldContexts.BlockFace, BlockGenericContextRO<B, T, E> {
//@formatter:on //@formatter:on
/** /**
* Gets the tile stack at the relevant position. * Determines whether the specified position has a tile. Block location and
* * block face are 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() {
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.
* *
* @param layer the layer of the tile
* @return {@code true} iff the tile exists * @return {@code true} iff the tile exists
*/ */
default boolean hasTile(int layer) { default boolean hasTile(int layer) {
@ -67,14 +45,60 @@ public interface BlockFaceGenericContextRO<
} }
/** /**
* Gets the tile at the specified position; block location and face are * Determines whether the specified position has a tile with the given tag.
* implied by the context. * Block location and block face are implied by the context.
* *
* @return the specified tile or {@code null} if the location is not loaded * @param tag the tag of the tile
* or the tile does not exist * @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:
* <ul>
* <li>the location is not loaded,
* <li>there is no tile stack on the relevant face, or
* <li>{@code layer} is not less than the amount of tiles in the tile stack.
* </ul>
*
* @return the tile or {@code null} if the position does not contain a tile
*/ */
default T getTile(int layer) { default T getTile(int layer) {
return getTile(getLocation(), getFace(), 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:
* <ul>
* <li>the location is not loaded,
* <li>there is no tile stack on the relevant face, or
* <li>there is no tile with the specified tag in the tile stack.
* </ul>
*
* @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.
* <p>
* 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());
}
} }

View File

@ -31,11 +31,8 @@ import ru.windcorp.progressia.common.world.generic.*;
public interface BlockFaceGenericContextWO< public interface BlockFaceGenericContextWO<
B extends BlockGeneric, B extends BlockGeneric,
T extends TileGeneric, T extends TileGeneric,
TS extends TileGenericStackWO <B, T, TS, TR, C>,
TR extends TileGenericReferenceWO <B, T, TS, TR, C>,
C extends ChunkGenericWO <B, T, TS, TR, C>,
E extends EntityGeneric E extends EntityGeneric
> extends WorldContexts.BlockFace, BlockGenericContextWO<B, T, TS, TR, C, E> { > extends WorldContexts.BlockFace, BlockGenericContextWO<B, T, E> {
//@formatter:on //@formatter:on
/** /**

View File

@ -29,11 +29,8 @@ import ru.windcorp.progressia.common.world.rels.BlockFace;
public interface BlockGenericContextRO< public interface BlockGenericContextRO<
B extends BlockGeneric, B extends BlockGeneric,
T extends TileGeneric, T extends TileGeneric,
TS extends TileGenericStackRO <B, T, TS, TR, C>,
TR extends TileGenericReferenceRO <B, T, TS, TR, C>,
C extends ChunkGenericRO <B, T, TS, TR, C>,
E extends EntityGeneric E extends EntityGeneric
> extends WorldContexts.Block, WorldGenericContextRO<B, T, TS, TR, C, E> { > extends WorldContexts.Block, WorldGenericContextRO<B, T, E> {
//@formatter:on //@formatter:on
/** /**
@ -43,11 +40,16 @@ public interface BlockGenericContextRO<
* @return {@code true} iff the location is loaded * @return {@code true} iff the location is loaded
*/ */
default boolean isLoaded() { 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:
* <ul>
* <li>the location that the block would occupy is not loaded, or
* <li>the corresponding chunk's terrain has not yet generated.
* </ul>
* *
* @return the block or {@code null} if the location is not loaded * @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 * Determines whether the specified position has a tile. Block location is
* 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
* implied by the context. * 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 * @return {@code true} iff the tile exists
*/ */
default boolean hasTile(BlockFace face, int layer) { 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 * Determines whether the specified position has a tile with the given tag.
* context. * Block location is implied by context.
* *
* @return the specified tile or {@code null} if the location is not loaded * @param face the face of the block that the tile occupies
* or the tile does not exist * @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:
* <ul>
* <li>the location is not loaded,
* <li>there is no tile stack on the specified face, or
* <li>{@code layer} is not less than the amount of tiles in the tile stack.
* </ul>
*
* @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) { default T getTile(BlockFace face, int layer) {
return getTile(getLocation(), face, 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:
* <ul>
* <li>the location is not loaded,
* <li>there is no tile stack on the specified face, or
* <li>there is no tile with the specified tag in the tile stack.
* </ul>
*
* @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
* <p>
* 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);
}
} }

View File

@ -31,11 +31,8 @@ import ru.windcorp.progressia.common.world.rels.BlockFace;
public interface BlockGenericContextWO< public interface BlockGenericContextWO<
B extends BlockGeneric, B extends BlockGeneric,
T extends TileGeneric, T extends TileGeneric,
TS extends TileGenericStackWO <B, T, TS, TR, C>,
TR extends TileGenericReferenceWO <B, T, TS, TR, C>,
C extends ChunkGenericWO <B, T, TS, TR, C>,
E extends EntityGeneric E extends EntityGeneric
> extends WorldContexts.Block, WorldGenericContextWO<B, T, TS, TR, C, E> { > extends WorldContexts.Block, WorldGenericContextWO<B, T, E> {
//@formatter:on //@formatter:on
/** /**

View File

@ -29,15 +29,12 @@ import ru.windcorp.progressia.common.world.generic.*;
public interface TileGenericContextRO< public interface TileGenericContextRO<
B extends BlockGeneric, B extends BlockGeneric,
T extends TileGeneric, T extends TileGeneric,
TS extends TileGenericStackRO <B, T, TS, TR, C>,
TR extends TileGenericReferenceRO <B, T, TS, TR, C>,
C extends ChunkGenericRO <B, T, TS, TR, C>,
E extends EntityGeneric E extends EntityGeneric
> extends WorldContexts.Tile, BlockFaceGenericContextRO<B, T, TS, TR, C, E> { > extends WorldContexts.Tile, BlockFaceGenericContextRO<B, T, E> {
//@formatter:on //@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 * @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:
* <ul>
* <li>the location is not loaded,
* <li>there is no tile stack on the relevant face, or
* <li>{@code layer} is not less than the amount of tiles in the tile stack.
* </ul>
* *
* @return the specified tile or {@code null} if the location is not loaded * @return the tile or {@code null} if the position does not contain a tile
* or the tile does not exist
*/ */
default T getTile() { default T getTile() {
return getTile(getLocation(), getFace(), getLayer()); 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());
}
} }

View File

@ -31,11 +31,8 @@ import ru.windcorp.progressia.common.world.generic.*;
public interface TileGenericContextWO< public interface TileGenericContextWO<
B extends BlockGeneric, B extends BlockGeneric,
T extends TileGeneric, T extends TileGeneric,
TS extends TileGenericStackWO <B, T, TS, TR, C>,
TR extends TileGenericReferenceWO <B, T, TS, TR, C>,
C extends ChunkGenericWO <B, T, TS, TR, C>,
E extends EntityGeneric E extends EntityGeneric
> extends WorldContexts.Tile, BlockFaceGenericContextWO<B, T, TS, TR, C, E> { > extends WorldContexts.Tile, BlockFaceGenericContextWO<B, T, E> {
//@formatter:on //@formatter:on
/** /**

View File

@ -17,23 +17,175 @@
*/ */
package ru.windcorp.progressia.common.world.generic.context; 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.context.Context;
import ru.windcorp.progressia.common.world.generic.*; import ru.windcorp.progressia.common.world.generic.*;
import ru.windcorp.progressia.common.world.rels.BlockFace;
/** /**
* A {@link Context} with a world instance. * A {@link Context} with a world instance.
* <p>
* This interfaces defines the entirety of world query methods supported by the
* default contexts.
*/ */
// @formatter:off // @formatter:off
public interface WorldGenericContextRO< public interface WorldGenericContextRO<
B extends BlockGeneric, B extends BlockGeneric,
T extends TileGeneric, T extends TileGeneric,
TS extends TileGenericStackRO <B, T, TS, TR, C>,
TR extends TileGenericReferenceRO <B, T, TS, TR, C>,
C extends ChunkGenericRO <B, T, TS, TR, C>,
E extends EntityGeneric E extends EntityGeneric
> extends WorldContexts.World, WorldGenericRO<B, T, TS, TR, C, E> { > extends WorldContexts.World {
// @formatter:on // @formatter:on
// currently empty /**
* Retrieves the block at the specified location. This method may return
* {@code null} in one of two cases:
* <ul>
* <li>the location that the block would occupy is not loaded, or
* <li>the corresponding chunk's terrain has not yet generated.
* </ul>
*
* @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:
* <ul>
* <li>the location is not loaded,
* <li>there is no tile stack on the specified face, or
* <li>{@code layer} is not less than the amount of tiles in the tile stack.
* </ul>
*
* @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:
* <ul>
* <li>the location is not loaded,
* <li>there is no tile stack on the specified face, or
* <li>there is no tile with the specified tag in the tile stack.
* </ul>
*
* @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.
* <p>
* 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<E> 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<? super E> action) {
getEntities().forEach(action);
}
/**
* Iterates all entities in cuboid safely
*/
default void forEachEntityIn(Vec3i min, Vec3i max, Consumer<? super E> 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<? super E> 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<? super E> action) {
forEachEntity(e -> {
if (id.equals(e.getId())) {
action.accept(e);
}
});
}
} }

View File

@ -28,16 +28,16 @@ import ru.windcorp.progressia.common.world.rels.BlockFace;
* A writable {@link Context} with a world instance. This context provides * A writable {@link Context} with a world instance. This context provides
* methods for affecting the world. The application of requested changes may or * methods for affecting the world. The application of requested changes may or
* may not be immediate, see {@link #isImmediate()}. * may not be immediate, see {@link #isImmediate()}.
* <p>
* This interfaces defines the entirety of world modification methods supported
* by the default contexts.
*/ */
// @formatter:off // @formatter:off
public interface WorldGenericContextWO< public interface WorldGenericContextWO<
B extends BlockGeneric, B extends BlockGeneric,
T extends TileGeneric, T extends TileGeneric,
TS extends TileGenericStackWO <B, T, TS, TR, C>,
TR extends TileGenericReferenceWO <B, T, TS, TR, C>,
C extends ChunkGenericWO <B, T, TS, TR, C>,
E extends EntityGeneric E extends EntityGeneric
> extends WorldContexts.World, WorldGenericWO<B, T, TS, TR, C, E> { > extends WorldContexts.World {
// @formatter:on // @formatter:on
/** /**
@ -116,7 +116,6 @@ public interface WorldGenericContextWO<
* @param entity the entity to add * @param entity the entity to add
* @see #isImmediate() * @see #isImmediate()
*/ */
@Override
void addEntity(E entity); void addEntity(E entity);
/** /**
@ -128,7 +127,6 @@ public interface WorldGenericContextWO<
* @see #isImmediate() * @see #isImmediate()
* @see #removeEntity(EntityGeneric) * @see #removeEntity(EntityGeneric)
*/ */
@Override
void removeEntity(long entityId); void removeEntity(long entityId);
/** /**
@ -139,7 +137,6 @@ public interface WorldGenericContextWO<
* @see #isImmediate() * @see #isImmediate()
* @see #removeEntity(long) * @see #removeEntity(long)
*/ */
@Override
default void removeEntity(E entity) { default void removeEntity(E entity) {
removeEntity(entity.getEntityId()); removeEntity(entity.getEntityId());
} }
@ -151,7 +148,6 @@ public interface WorldGenericContextWO<
* @param entity the entity to change * @param entity the entity to change
* @param change the change to apply * @param change the change to apply
*/ */
@Override
<SE extends StatefulObject & EntityGeneric> void changeEntity(SE entity, StateChange<SE> change); <SE extends StatefulObject & EntityGeneric> void changeEntity(SE entity, StateChange<SE> change);
} }

View File

@ -73,7 +73,7 @@ public class TickAndUpdateUtil {
} }
public static void tickTiles(DefaultWorldLogic world, Vec3i blockInWorld, BlockFace face) { public static void tickTiles(DefaultWorldLogic world, Vec3i blockInWorld, BlockFace face) {
if (!world.isBlockLoaded(blockInWorld)) { if (!world.isLocationLoaded(blockInWorld)) {
return; return;
} }
@ -123,7 +123,7 @@ public class TickAndUpdateUtil {
} }
public static void updateTiles(DefaultWorldLogic world, Vec3i blockInWorld, BlockFace face) { public static void updateTiles(DefaultWorldLogic world, Vec3i blockInWorld, BlockFace face) {
if (!world.isBlockLoaded(blockInWorld)) { if (!world.isLocationLoaded(blockInWorld)) {
return; return;
} }

View File

@ -18,8 +18,6 @@
package ru.windcorp.progressia.server.world.context; package ru.windcorp.progressia.server.world.context;
import ru.windcorp.progressia.common.world.context.BlockDataContext; 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 { public interface ServerBlockContext extends BlockDataContext, ServerWorldContext, ServerBlockContextRO {
@ -28,11 +26,6 @@ public interface ServerBlockContext extends BlockDataContext, ServerWorldContext
@Override @Override
ServerBlockContext data(); ServerBlockContext data();
@Override
default TileLogicStack getTilesOrNull(BlockFace face) {
return (TileLogicStack) ServerBlockContextRO.Logic.super.getTilesOrNull(face);
}
} }
@Override @Override

View File

@ -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.context.BlockDataContextRO;
import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.entity.EntityData;
import ru.windcorp.progressia.common.world.generic.context.BlockGenericContextRO; 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.block.BlockLogic;
import ru.windcorp.progressia.server.world.tile.TileLogic; import ru.windcorp.progressia.server.world.tile.TileLogic;
public interface ServerBlockContextRO extends ServerWorldContextRO, BlockDataContextRO { public interface ServerBlockContextRO extends ServerWorldContextRO, BlockDataContextRO {
public interface Logic extends ServerWorldContextRO.Logic, public interface Logic
BlockGenericContextRO<BlockLogic, TileLogic, TileLogicStackRO, TileLogicReferenceRO, ChunkLogicRO, EntityData> { extends ServerWorldContextRO.Logic, BlockGenericContextRO<BlockLogic, TileLogic, EntityData> {
@Override @Override
ServerBlockContextRO data(); ServerBlockContextRO data();

View File

@ -18,7 +18,6 @@
package ru.windcorp.progressia.server.world.context; package ru.windcorp.progressia.server.world.context;
import ru.windcorp.progressia.common.world.context.BlockFaceDataContext; import ru.windcorp.progressia.common.world.context.BlockFaceDataContext;
import ru.windcorp.progressia.server.world.TileLogicStack;
public interface ServerBlockFaceContext extends BlockFaceDataContext, ServerBlockContext, ServerBlockFaceContextRO { public interface ServerBlockFaceContext extends BlockFaceDataContext, ServerBlockContext, ServerBlockFaceContextRO {
@ -27,11 +26,6 @@ public interface ServerBlockFaceContext extends BlockFaceDataContext, ServerBloc
@Override @Override
ServerBlockFaceContext data(); ServerBlockFaceContext data();
@Override
default TileLogicStack getTilesOrNull() {
return (TileLogicStack) ServerBlockFaceContextRO.Logic.super.getTilesOrNull();
}
} }
@Override @Override

View File

@ -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.context.BlockFaceDataContextRO;
import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.entity.EntityData;
import ru.windcorp.progressia.common.world.generic.context.BlockFaceGenericContextRO; 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.block.BlockLogic;
import ru.windcorp.progressia.server.world.tile.TileLogic; import ru.windcorp.progressia.server.world.tile.TileLogic;
public interface ServerBlockFaceContextRO extends ServerBlockContextRO, BlockFaceDataContextRO { public interface ServerBlockFaceContextRO extends ServerBlockContextRO, BlockFaceDataContextRO {
public interface Logic extends ServerBlockContextRO.Logic, public interface Logic
BlockFaceGenericContextRO<BlockLogic, TileLogic, TileLogicStackRO, TileLogicReferenceRO, ChunkLogicRO, EntityData> { extends ServerBlockContextRO.Logic, BlockFaceGenericContextRO<BlockLogic, TileLogic, EntityData> {
@Override @Override
ServerBlockFaceContextRO data(); ServerBlockFaceContextRO data();

View File

@ -51,9 +51,7 @@ public interface ServerContext extends Context {
* *
* @return the length of the last server tick * @return the length of the last server tick
*/ */
default double getTickLength() { double getTickLength();
return getServer().getTickLength();
}
/** /**
* Adjusts the provided value according to tick length assuming the value * Adjusts the provided value according to tick length assuming the value

View File

@ -18,7 +18,6 @@
package ru.windcorp.progressia.server.world.context; package ru.windcorp.progressia.server.world.context;
import ru.windcorp.progressia.common.world.context.TileDataContext; import ru.windcorp.progressia.common.world.context.TileDataContext;
import ru.windcorp.progressia.server.world.TileLogicReference;
public interface ServerTileContext extends TileDataContext, ServerBlockFaceContext, ServerTileContextRO { public interface ServerTileContext extends TileDataContext, ServerBlockFaceContext, ServerTileContextRO {
@ -27,11 +26,6 @@ public interface ServerTileContext extends TileDataContext, ServerBlockFaceConte
@Override @Override
ServerTileContext data(); ServerTileContext data();
@Override
default TileLogicReference getTileReference() {
return (TileLogicReference) ServerTileContextRO.Logic.super.getTileReference();
}
} }
@Override @Override

View File

@ -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.context.TileDataContextRO;
import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.entity.EntityData;
import ru.windcorp.progressia.common.world.generic.context.TileGenericContextRO; 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.block.BlockLogic;
import ru.windcorp.progressia.server.world.tile.TileLogic; import ru.windcorp.progressia.server.world.tile.TileLogic;
public interface ServerTileContextRO extends ServerBlockFaceContextRO, TileDataContextRO { public interface ServerTileContextRO extends ServerBlockFaceContextRO, TileDataContextRO {
public interface Logic extends ServerBlockFaceContextRO.Logic, public interface Logic
TileGenericContextRO<BlockLogic, TileLogic, TileLogicStackRO, TileLogicReferenceRO, ChunkLogicRO, EntityData> { extends ServerBlockFaceContextRO.Logic, TileGenericContextRO<BlockLogic, TileLogic, EntityData> {
@Override @Override
ServerTileContextRO data(); ServerTileContextRO data();

View File

@ -17,22 +17,14 @@
*/ */
package ru.windcorp.progressia.server.world.context; 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.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 ServerWorldContext extends WorldDataContext, ServerWorldContextRO {
public interface Logic extends ServerWorldContextRO.Logic, public interface Logic extends ServerWorldContextRO.Logic {
WorldLogic {
@Override @Override
ServerWorldContext data(); ServerWorldContext data();
@Override
TileLogicStack getTiles(Vec3i blockInWorld, BlockFace face);
} }

View File

@ -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.context.WorldDataContextRO;
import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.entity.EntityData;
import ru.windcorp.progressia.common.world.generic.context.WorldGenericContextRO; 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.block.BlockLogic;
import ru.windcorp.progressia.server.world.tile.TileLogic; import ru.windcorp.progressia.server.world.tile.TileLogic;
public interface ServerWorldContextRO extends WorldDataContextRO, ServerContext { public interface ServerWorldContextRO extends WorldDataContextRO, ServerContext {
public interface Logic public interface Logic extends WorldGenericContextRO<BlockLogic, TileLogic, EntityData>, ServerContext {
extends
WorldGenericContextRO<BlockLogic, TileLogic, TileLogicStackRO, TileLogicReferenceRO, ChunkLogicRO, EntityData>,
WorldLogicRO,
ServerContext {
/** /**
* Acquires the data view of this context. Use this method to * Acquires the data view of this context. Use this method to

View File

@ -37,9 +37,14 @@ import ru.windcorp.progressia.server.world.context.ServerWorldContextRO;
* when a {@link WorldLogic} (or a {@link WorldLogicRO}) instance requires a * when a {@link WorldLogic} (or a {@link WorldLogicRO}) instance requires a
* context wrapper. * context wrapper.
* <p> * <p>
* 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. * {@link #empty()} static method to acquire a usable instance.
* <p> * <p>
* {@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.
* <p>
* This class defines the outward-facing safe interface of the actual * This class defines the outward-facing safe interface of the actual
* implementation located in {@link ReusableServerContextImpl}. The reasoning * implementation located in {@link ReusableServerContextImpl}. The reasoning
* for creating a subclass is to allow a single instance to implement both * for creating a subclass is to allow a single instance to implement both

View File

@ -23,7 +23,6 @@ import java.util.Random;
import glm.vec._3.i.Vec3i; import glm.vec._3.i.Vec3i;
import ru.windcorp.progressia.common.state.StateChange; import ru.windcorp.progressia.common.state.StateChange;
import ru.windcorp.progressia.common.state.StatefulObject; 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.GravityModel;
import ru.windcorp.progressia.common.world.TileDataStack; import ru.windcorp.progressia.common.world.TileDataStack;
import ru.windcorp.progressia.common.world.WorldData; 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.rels.RelFace;
import ru.windcorp.progressia.common.world.tile.TileData; import ru.windcorp.progressia.common.world.tile.TileData;
import ru.windcorp.progressia.server.Server; 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.TileLogicStack;
import ru.windcorp.progressia.server.world.WorldLogic; 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.context.ServerTileContext;
import ru.windcorp.progressia.server.world.tile.TileLogic;
class ReusableServerContextImpl extends ReusableServerContext class ReusableServerContextImpl extends ReusableServerContext
implements ReusableServerContextBuilders.Empty, ReusableServerContextBuilders.WithWorld, implements ReusableServerContextBuilders.Empty, ReusableServerContextBuilders.WithWorld,
@ -61,7 +61,13 @@ class ReusableServerContextImpl extends ReusableServerContext
* The relevant {@link WorldLogic} instance. If this is {@code null}, the * The relevant {@link WorldLogic} instance. If this is {@code null}, the
* role is {@link Role#NONE}. * 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 * 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 * The index of the relevant tile. This value is {@code -1} unless the role
* is {@link Role#TILE}. * 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. * 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. * ends. This is always 0 when the object is a builder.
*/ */
protected int subcontextDepth = 0; protected int subcontextDepth = 0;
/** /**
* The Logic view returned by {@link #logic()}. * The Logic view returned by {@link #logic()}.
*/ */
@ -117,7 +128,7 @@ class ReusableServerContextImpl extends ReusableServerContext
return Role.WORLD; return Role.WORLD;
if (blockFace == null) if (blockFace == null)
return Role.LOCATION; return Role.LOCATION;
if (index == -1) if (layer == -1)
return Role.TILE_STACK; return Role.TILE_STACK;
return Role.TILE; return Role.TILE;
} }
@ -179,7 +190,7 @@ class ReusableServerContextImpl extends ReusableServerContext
location.y, location.y,
location.z, location.z,
blockFace, blockFace,
index layer
); );
break; break;
case TILE_STACK: case TILE_STACK:
@ -216,10 +227,11 @@ class ReusableServerContextImpl extends ReusableServerContext
} }
server = null; server = null;
world = null; worldLogic = null;
worldData = null;
location = null; location = null;
blockFace = null; blockFace = null;
index = -1; layer = -1;
isBuilder = true; isBuilder = true;
@ -246,7 +258,8 @@ class ReusableServerContextImpl extends ReusableServerContext
public WithWorld in(Server server, WorldLogic world) { public WithWorld in(Server server, WorldLogic world) {
requireBuilderRole(Role.NONE); requireBuilderRole(Role.NONE);
this.server = server; this.server = server;
this.world = world; this.worldLogic = world;
this.worldData = world.getData();
return this; return this;
} }
@ -272,11 +285,11 @@ class ReusableServerContextImpl extends ReusableServerContext
this.blockFace = side; this.blockFace = side;
return this; return this;
} }
@Override @Override
public WithTileStack on(BlockFace side) { public WithTileStack on(BlockFace side) {
requireBuilderRole(Role.LOCATION); requireBuilderRole(Role.LOCATION);
this.blockFace = side.relativize(world.getData().getUp(location)); this.blockFace = side.relativize(worldLogic.getData().getUp(location));
return this; return this;
} }
@ -287,91 +300,10 @@ class ReusableServerContextImpl extends ReusableServerContext
@Override @Override
public ReusableServerContext index(int index) { public ReusableServerContext index(int index) {
requireBuilderRole(Role.TILE_STACK); requireBuilderRole(Role.TILE_STACK);
this.index = index; this.layer = index;
return build(); return build();
} }
/*
* ServerWorldContext.Logic STUFF
*/
private class Logic implements ServerTileContext.Logic {
@Override
public boolean isReal() {
return ReusableServerContextImpl.this.isReal();
}
@Override
public Collection<? extends ChunkLogic> getChunks() {
return world.getChunks();
}
@Override
public Collection<EntityData> 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 * LOCATION GETTERS
*/ */
@ -381,139 +313,326 @@ class ReusableServerContextImpl extends ReusableServerContext
assert requireContextRole(Role.WORLD); assert requireContextRole(Role.WORLD);
return server; return server;
} }
@Override @Override
public Vec3i getLocation() { public Vec3i getLocation() {
assert requireContextRole(Role.LOCATION); assert requireContextRole(Role.LOCATION);
return location; return location;
} }
@Override @Override
public RelFace getFace() { public RelFace getFace() {
assert requireContextRole(Role.TILE_STACK); assert requireContextRole(Role.TILE_STACK);
return blockFace; return blockFace;
} }
@Override @Override
public int getLayer() { public int getLayer() {
assert requireContextRole(Role.TILE); assert requireContextRole(Role.TILE);
return index; return layer;
} }
/* /*
* RO CONTEXT INTERFACE * RO CONTEXT INTERFACE
*/ */
@Override @Override
public boolean isReal() { public boolean isReal() {
assert requireContextRole(Role.WORLD); assert requireContextRole(Role.WORLD);
return true; return true;
} }
@Override @Override
public Random getRandom() { public Random getRandom() {
assert requireContextRole(Role.WORLD); assert requireContextRole(Role.WORLD);
return server.getAdHocRandom(); return random;
} }
@Override @Override
public ChunkData getChunk(Vec3i pos) { public double getTickLength() {
assert requireContextRole(Role.WORLD); assert requireContextRole(Role.WORLD);
return world.getData().getChunk(pos); return server.getTickLength();
} }
@Override @Override
public Collection<? extends ChunkData> getChunks() { public BlockData getBlock(Vec3i location) {
assert requireContextRole(Role.WORLD); 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 @Override
public Collection<EntityData> getEntities() { public Collection<EntityData> getEntities() {
assert requireContextRole(Role.WORLD); assert requireContextRole(Role.WORLD);
return world.getEntities(); return worldData.getEntities();
} }
@Override @Override
public EntityData getEntity(long entityId) { public EntityData getEntity(long entityId) {
assert requireContextRole(Role.WORLD); assert requireContextRole(Role.WORLD);
return world.getEntity(entityId); return worldData.getEntity(entityId);
} }
@Override @Override
public GravityModel getGravityModel() { public GravityModel getGravityModel() {
assert requireContextRole(Role.WORLD); assert requireContextRole(Role.WORLD);
return world.getData().getGravityModel(); return worldData.getGravityModel();
} }
@Override @Override
public float getTime() { public float getTime() {
assert requireContextRole(Role.WORLD); assert requireContextRole(Role.WORLD);
return world.getData().getTime(); return worldData.getTime();
} }
/*
* RO CONTEXT OPTIMIZATIONS
*/
/* /*
* RW CONTEXT INTERFACE * RW CONTEXT INTERFACE
*/ */
@Override @Override
public boolean isImmediate() { public boolean isImmediate() {
assert requireContextRole(Role.WORLD); assert requireContextRole(Role.WORLD);
return true; return true;
} }
@Override @Override
public void setBlock(Vec3i blockInWorld, BlockData block, boolean notify) { public void setBlock(Vec3i blockInWorld, BlockData block) {
assert requireContextRole(Role.WORLD); assert requireContextRole(Role.WORLD);
world.getData().setBlock(blockInWorld, block, notify); worldData.setBlock(blockInWorld, block, true);
} }
@Override @Override
public void addTile(Vec3i location, BlockFace face, TileData tile) { public void addTile(Vec3i location, BlockFace face, TileData tile) {
assert requireContextRole(Role.WORLD); assert requireContextRole(Role.WORLD);
world.getData().getTiles(location, face).addFarthest(tile); worldData.getTiles(location, face).addFarthest(tile);
} }
@Override @Override
public void removeTile(Vec3i location, BlockFace face, int tag) { public void removeTile(Vec3i location, BlockFace face, int tag) {
assert requireContextRole(Role.WORLD); assert requireContextRole(Role.WORLD);
TileDataStack stack = world.getData().getTilesOrNull(location, face); TileDataStack stack = worldData.getTilesOrNull(location, face);
if (stack == null) return; if (stack == null)
int index = stack.getIndexByTag(tag); return;
if (index == -1) return; int layer = stack.getIndexByTag(tag);
stack.remove(index); if (layer == -1)
return;
stack.remove(layer);
} }
@Override @Override
public void addEntity(EntityData entity) { public void addEntity(EntityData entity) {
assert requireContextRole(Role.WORLD); assert requireContextRole(Role.WORLD);
world.getData().addEntity(entity); worldData.addEntity(entity);
} }
@Override @Override
public void removeEntity(long entityId) { public void removeEntity(long entityId) {
assert requireContextRole(Role.WORLD); assert requireContextRole(Role.WORLD);
world.getData().removeEntity(entityId); worldData.removeEntity(entityId);
} }
@Override @Override
public <SE extends StatefulObject & EntityGeneric> void changeEntity(SE entity, StateChange<SE> change) { public <SE extends StatefulObject & EntityGeneric> void changeEntity(SE entity, StateChange<SE> change) {
assert requireContextRole(Role.WORLD); assert requireContextRole(Role.WORLD);
world.getData().changeEntity(entity, change); worldData.changeEntity(entity, change);
} }
@Override @Override
public void advanceTime(float change) { public void advanceTime(float change) {
assert requireContextRole(Role.WORLD); 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<EntityData> 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;
}
} }

View File

@ -177,7 +177,7 @@ public class SurfaceWorld
public boolean isBlockLoadedSfc(Vec3i surfaceBlockInWorld) { public boolean isBlockLoadedSfc(Vec3i surfaceBlockInWorld) {
Vec3i blockInWorld = Vectors.grab3i(); Vec3i blockInWorld = Vectors.grab3i();
resolve(surfaceBlockInWorld, blockInWorld); resolve(surfaceBlockInWorld, blockInWorld);
boolean result = parent.isBlockLoaded(blockInWorld); boolean result = parent.isLocationLoaded(blockInWorld);
Vectors.release(blockInWorld); Vectors.release(blockInWorld);
return result; return result;
} }