Skip to content

Commit

Permalink
Merge PR #3923 by @pollend - JOML conversion work
Browse files Browse the repository at this point in the history
  • Loading branch information
Cervator committed May 2, 2020
2 parents 94544c3 + df2813d commit 6cdc19e
Show file tree
Hide file tree
Showing 2 changed files with 187 additions and 35 deletions.
139 changes: 123 additions & 16 deletions engine/src/main/java/org/terasology/world/BlockEntityRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package org.terasology.world;

import org.joml.Vector3fc;
import org.joml.Vector3ic;
import org.terasology.entitySystem.Component;
import org.terasology.entitySystem.entity.EntityRef;
import org.terasology.math.geom.Vector3f;
Expand Down Expand Up @@ -43,58 +45,163 @@ public interface BlockEntityRegistry {
* This method returns the block entity at the given location, but will not produce a temporary entity if
* one isn't currently in memory.
*
* @param blockPosition
* @param blockPosition absolute position of the block
* @return The block entity for the location if it exists, or the null entity
*/
* @deprecated This is scheduled for removal in an upcoming version
* method will be replaced with JOML implementation {@link #getExistingBlockEntityAt(Vector3ic)}.
**/
@Deprecated
EntityRef getExistingBlockEntityAt(Vector3i blockPosition);


/**
* This method returns the block entity at the given location, but will not produce a temporary entity if
* one isn't currently in memory.
*
* @param blockPosition absolute position of the block
* @return The block entity for the location if it exists, or the null entity
*/
EntityRef getExistingBlockEntityAt(Vector3ic blockPosition);


/**
* This method is the same as setBlock, except if the old and new block types are part of the same family the
* entity will be force updated (usually they are not in this situation).
*
* @param position
* @param type
* @param position absolute position of the block in world space
* @param type type of block
* @return The previous block type, or null if the change failed due to the chunk not being available
* @deprecated This is scheduled for removal in an upcoming version
* method will be replaced with JOML implementation {@link #setBlockForceUpdateEntity(Vector3ic, Block)}.
*/
@Deprecated
Block setBlockForceUpdateEntity(Vector3i position, Block type);

/**
* This method is the same as setBlock, except the specified components are not altered during the update
* This method is the same as setBlock, except if the old and new block types are part of the same family the
* entity will be force updated (usually they are not in this situation).
*
* @param position
* @param type
* @param components
* @param position absolute position of the block in world space
* @param type type of block
* @return The previous block type, or null if the change failed due to the chunk not being available
*/
Block setBlockForceUpdateEntity(Vector3ic position, Block type);


/**
* This method is the same as setBlock, except the specified components are not altered during the update
*
* @param position absolute position of the block in world space
* @param type type of block
* @param components components that are assigned to the block
* @return The previous block type, or null if the change failed due to the chunk not being available
* @deprecated This is scheduled for removal in an upcoming version
* method will be replaced with JOML implementation {@link #setBlockRetainComponent(Vector3ic, Block, Class[])}.
**/
@Deprecated
Block setBlockRetainComponent(Vector3i position, Block type, Class<? extends Component>... components);

/**
* @param position
* @return The block entity for the location, creating it if it doesn't exist
* This method is the same as setBlock, except the specified components are not altered during the update
*
* @param position absolute position of the block in world space
* @param type type of block
* @param components components that are assigned to the block
* @return The previous block type, or null if the change failed due to the chunk not being available
*/
Block setBlockRetainComponent(Vector3ic position, Block type, Class<? extends Component>... components);


/**
* retrieves an EntityRef for a given block.
*
* @param position absolute position of the block in world space
* @return The block entity for the location, creating it if it doesn't exist
* @deprecated This is scheduled for removal in an upcoming version
* method will be replaced with JOML implementation {@link #getBlockEntityAt(Vector3fc)}.
**/
@Deprecated
EntityRef getBlockEntityAt(Vector3f position);

/**
* @param blockPosition
* retrieves an {@link EntityRef} for a given block.
* @param position absolute position of the block in world space rounded {@link org.joml.RoundingMode#HALF_UP}
* @return The block entity for the location, creating it if it doesn't exist
**/
EntityRef getBlockEntityAt(Vector3fc position);

/**
* retrieves an EntityRef for a given block.
*
* @param blockPosition absolute position of the block in world place
* @return The block entity for the location, creating it if it doesn't exist
* @deprecated This is scheduled for removal in an upcoming version
* method will be replaced with JOML implementation {@link #getBlockEntityAt(Vector3ic)}.
*/
@Deprecated
EntityRef getBlockEntityAt(Vector3i blockPosition);

/**
* @param blockPosition
* retrieves an EntityRef for a given block.
*
* @param blockPosition absolute position of the block in world place
* @return The block entity for the location, creating it if it doesn't exist
*/
EntityRef getBlockEntityAt(Vector3ic blockPosition);

/**
* retrieves an entity associated with the given block else return a {@link EntityRef#NULL}
* @param blockPosition position of the block in world position.
* @return The block controller entity for this location, or block entity if it exists.
* @deprecated This is scheduled for removal in an upcoming version
* method will be replaced with JOML implementation {@link #getExistingEntityAt(Vector3ic)}.
*/
@Deprecated
EntityRef getExistingEntityAt(Vector3i blockPosition);

/**
* @param blockPosition
* @return The block controller entity for this location, or block entity.
* retrieves an entity associated with the given block else return a {@link EntityRef#NULL}
* @param blockPosition position of the block in world position.
* @return The block controller entity for this location, or block entity if it exists.\
*/
EntityRef getExistingEntityAt(Vector3ic blockPosition);

/**
* retrieves an entity associated with the given block else create a new entity
* @param blockPosition absolute position of the block.
* @return The block {@link EntityRef} for this location.
* @deprecated This is scheduled for removal in an upcoming version
* method will be replaced with JOML implementation {@link #getEntityAt(Vector3ic)}.
*/
@Deprecated
EntityRef getEntityAt(Vector3i blockPosition);

/**
* @param blockPos
* @return Whether the entity at this position is permanent
* retrieves an entity associated with the given block else create a new entity
* @param blockPosition absolute position of the block in.
* @return The block {@link EntityRef} for this location.
*/
EntityRef getEntityAt(Vector3ic blockPosition);

/**
* tell if the entity assigned to a given block is permanent. non-permanent
* block entities are cleaned up at the end of the update.
*
* @param blockPos absolute position of the block.
* @return Whether the entity at this position is permanent
* @deprecated This is scheduled for removal in an upcoming version
* method will be replaced with JOML implementation {@link #hasPermanentBlockEntity(Vector3ic)}.
**/
@Deprecated
boolean hasPermanentBlockEntity(Vector3i blockPos);

/**
* tell if the entity assigned to a given block is permanent. non-permanent
* block entities are cleaned up at the end of the update.
*
* @param blockPos absolute position of the block.
* @return Whether the entity at this position is permanent
*
**/
boolean hasPermanentBlockEntity(Vector3ic blockPos);
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.joml.Vector3fc;
import org.joml.Vector3ic;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -68,7 +69,7 @@
public class EntityAwareWorldProvider extends AbstractWorldProviderDecorator implements BlockEntityRegistry, UpdateSubscriberSystem, EntityChangeSubscriber {
private static final Logger logger = LoggerFactory.getLogger(EntityAwareWorldProvider.class);
private static final Set<Class<? extends Component>> COMMON_BLOCK_COMPONENTS =
ImmutableSet.of(NetworkComponent.class, BlockComponent.class, LocationComponent.class);
ImmutableSet.of(NetworkComponent.class, BlockComponent.class, LocationComponent.class);
private static final float BLOCK_REGEN_SECONDS = 4.0f;

private EngineEntityManager entityManager;
Expand Down Expand Up @@ -116,14 +117,14 @@ public void shutdown() {

@Override
public Block setBlock(Vector3i pos, Block type) {
return this.setBlock(JomlUtil.from(pos),type);
return this.setBlock(JomlUtil.from(pos), type);
}

@Override
public Block setBlock(Vector3ic pos, Block type) {
if (GameThread.isCurrentThread()) {
EntityRef blockEntity = getBlockEntityAt(JomlUtil.from(pos));
Block oldType = super.setBlock(JomlUtil.from(pos), type);
Block oldType = super.setBlock(pos, type);
if (oldType != null) {
updateBlockEntity(blockEntity, JomlUtil.from(pos), oldType, type, false, Collections.<Class<? extends Component>>emptySet());
}
Expand All @@ -132,6 +133,7 @@ public Block setBlock(Vector3ic pos, Block type) {
return null;
}


//SetBlocks, not SetBlock, is currently triggered by the engine whenever a player places a block.
//This allows for several useful features, such as quickly synchronizing placement across networks.
//However, this means that even if only one block is placed, this is the method being called.
Expand All @@ -146,8 +148,8 @@ public Map<Vector3i, Block> setBlocks(Map<Vector3i, Block> blocks) {

// check for components to be retained when updating the block entity
Set<Class<? extends Component>> retainComponents = Optional.ofNullable(blockEntity.getComponent(RetainComponentsComponent.class))
.map(retainComponentsComponent -> retainComponentsComponent.components)
.orElse(Collections.emptySet());
.map(retainComponentsComponent -> retainComponentsComponent.components)
.orElse(Collections.emptySet());


updateBlockEntity(blockEntity, vec, oldBlocks.get(vec), blocks.get(vec), false, retainComponents);
Expand All @@ -161,11 +163,17 @@ public Map<Vector3i, Block> setBlocks(Map<Vector3i, Block> blocks) {
@Override
@SafeVarargs
public final Block setBlockRetainComponent(Vector3i pos, Block type, Class<? extends Component>... components) {
return setBlockRetainComponent(JomlUtil.from(pos), type, components);
}

@Override
@SafeVarargs
public final Block setBlockRetainComponent(Vector3ic position, Block type, Class<? extends Component>... components) {
if (GameThread.isCurrentThread()) {
EntityRef blockEntity = getBlockEntityAt(pos);
Block oldType = super.setBlock(pos, type);
EntityRef blockEntity = getBlockEntityAt(position);
Block oldType = super.setBlock(position, type);
if (oldType != null) {
updateBlockEntity(blockEntity, pos, oldType, type, false, Sets.newHashSet(components));
updateBlockEntity(blockEntity, JomlUtil.from(position), oldType, type, false, Sets.newHashSet(components));
}
return oldType;
}
Expand Down Expand Up @@ -205,8 +213,13 @@ public EntityRef setPermanentBlockEntity(Vector3i blockPosition, EntityRef block

@Override
public EntityRef getExistingBlockEntityAt(Vector3i blockPosition) {
return getExistingBlockEntityAt(JomlUtil.from(blockPosition));
}

@Override
public EntityRef getExistingBlockEntityAt(Vector3ic blockPosition) {
if (GameThread.isCurrentThread()) {
EntityRef result = blockEntityLookup.get(blockPosition);
EntityRef result = blockEntityLookup.get(JomlUtil.from(blockPosition));
return (result == null) ? EntityRef.NULL : result;
}
logger.error("Attempted to get block entity off-thread");
Expand All @@ -215,11 +228,16 @@ public EntityRef getExistingBlockEntityAt(Vector3i blockPosition) {

@Override
public Block setBlockForceUpdateEntity(Vector3i pos, Block type) {
return setBlockForceUpdateEntity(JomlUtil.from(pos), type);
}

@Override
public Block setBlockForceUpdateEntity(Vector3ic position, Block type) {
if (GameThread.isCurrentThread()) {
EntityRef blockEntity = getBlockEntityAt(pos);
Block oldType = super.setBlock(pos, type);
EntityRef blockEntity = getBlockEntityAt(position);
Block oldType = super.setBlock(position, type);
if (oldType != null) {
updateBlockEntity(blockEntity, pos, oldType, type, true, Collections.<Class<? extends Component>>emptySet());
updateBlockEntity(blockEntity, JomlUtil.from(position), oldType, type, true, Collections.<Class<? extends Component>>emptySet());
}
return oldType;
}
Expand All @@ -232,20 +250,32 @@ public EntityRef getBlockEntityAt(Vector3f position) {
return getBlockEntityAt(pos);
}

@Override
public EntityRef getBlockEntityAt(Vector3fc position) {
org.joml.Vector3i pos = new org.joml.Vector3i(position, org.joml.RoundingMode.HALF_UP);
return getBlockEntityAt(pos);
}

@Override
public EntityRef getBlockEntityAt(Vector3i blockPosition) {
return getBlockEntityAt(JomlUtil.from(blockPosition));
}

@Override
public EntityRef getBlockEntityAt(Vector3ic blockPosition) {
if (GameThread.isCurrentThread()) {
EntityRef blockEntity = getExistingBlockEntityAt(blockPosition);
if ((!blockEntity.exists() || !blockEntity.hasComponent(NetworkComponent.class)) && isBlockRelevant(blockPosition.x, blockPosition.y, blockPosition.z)) {
Block block = getBlock(blockPosition.x, blockPosition.y, blockPosition.z);
blockEntity = createBlockEntity(blockPosition, block);
if ((!blockEntity.exists() || !blockEntity.hasComponent(NetworkComponent.class)) && isBlockRelevant(blockPosition.x(), blockPosition.y(), blockPosition.z())) {
Block block = getBlock(blockPosition.x(), blockPosition.y(), blockPosition.z());
blockEntity = createBlockEntity(JomlUtil.from(blockPosition), block);
}
return blockEntity;
}
logger.error("Attempted to get block entity off-thread");
return EntityRef.NULL;
}


private boolean isTemporaryBlock(ComponentContainer entity, Block block) {
return isTemporaryBlock(entity, block, null);
}
Expand Down Expand Up @@ -305,8 +335,8 @@ private void updateBlockEntityComponents(EntityRef blockEntity, Block oldType, B

for (Component component : blockEntity.iterateComponents()) {
if (!COMMON_BLOCK_COMPONENTS.contains(component.getClass())
&& !entityManager.getComponentLibrary().getMetadata(component.getClass()).isRetainUnalteredOnBlockChange()
&& !newEntityBuilder.hasComponent(component.getClass()) && !retainComponents.contains(component.getClass())) {
&& !entityManager.getComponentLibrary().getMetadata(component.getClass()).isRetainUnalteredOnBlockChange()
&& !newEntityBuilder.hasComponent(component.getClass()) && !retainComponents.contains(component.getClass())) {
blockEntity.removeComponent(component.getClass());
}
}
Expand Down Expand Up @@ -370,8 +400,13 @@ private EntityRef createBlockEntity(Vector3i blockPosition, Block block) {

@Override
public EntityRef getExistingEntityAt(Vector3i blockPosition) {
return getExistingEntityAt(JomlUtil.from(blockPosition));
}

@Override
public EntityRef getExistingEntityAt(Vector3ic blockPosition) {
if (GameThread.isCurrentThread()) {
EntityRef result = blockRegionLookup.get(blockPosition);
EntityRef result = blockRegionLookup.get(JomlUtil.from(blockPosition));
if (result == null) {
return getExistingBlockEntityAt(blockPosition);
}
Expand All @@ -383,6 +418,11 @@ public EntityRef getExistingEntityAt(Vector3i blockPosition) {

@Override
public EntityRef getEntityAt(Vector3i blockPosition) {
return getEntityAt(JomlUtil.from(blockPosition));
}

@Override
public EntityRef getEntityAt(Vector3ic blockPosition) {
if (GameThread.isCurrentThread()) {
EntityRef entity = getExistingEntityAt(blockPosition);
if (!entity.exists()) {
Expand All @@ -396,8 +436,13 @@ public EntityRef getEntityAt(Vector3i blockPosition) {

@Override
public boolean hasPermanentBlockEntity(Vector3i blockPos) {
return hasPermanentBlockEntity(JomlUtil.from(blockPos));
}

@Override
public boolean hasPermanentBlockEntity(Vector3ic blockPos) {
if (GameThread.isCurrentThread()) {
EntityRef blockEntity = blockEntityLookup.get(blockPos);
EntityRef blockEntity = blockEntityLookup.get(JomlUtil.from(blockPos));
return blockEntity != null && !temporaryBlockEntities.contains(blockEntity);
}
logger.error("Attempted check whether a block entity is permanent, off thread");
Expand Down

0 comments on commit 6cdc19e

Please sign in to comment.