Keeps getting hotter.

- Belts now use the new system.
 - Remove ILightListener.java.
 - Listeners can choose to remove themselves.
 - Rename some static GridAlignedBB methods.
This commit is contained in:
JozsefA 2021-03-23 02:12:09 -07:00
parent 20189a86fc
commit 5eae3a53fc
15 changed files with 106 additions and 60 deletions

View file

@ -1094,7 +1094,7 @@ public abstract class Contraption {
GridAlignedBB betterBounds = GridAlignedBB.ofRadius(radius);
GridAlignedBB contraptionBounds = GridAlignedBB.fromAABB(bounds);
GridAlignedBB contraptionBounds = GridAlignedBB.from(bounds);
if (axis == Direction.Axis.X) {
betterBounds.maxX = contraptionBounds.maxX;
betterBounds.minX = contraptionBounds.minX;

View file

@ -40,13 +40,15 @@ public abstract class ContraptionLighter<C extends Contraption> implements Light
public abstract GridAlignedBB getContraptionBounds();
@Override
public void onLightUpdate(ILightReader world, LightType type, GridAlignedBB changed) {
public boolean onLightUpdate(ILightReader world, LightType type, GridAlignedBB changed) {
lightVolume.notifyLightUpdate(world, type, changed);
return false;
}
@Override
public void onLightPacket(ILightReader world, int chunkX, int chunkZ) {
public boolean onLightPacket(ILightReader world, int chunkX, int chunkZ) {
lightVolume.notifyLightPacket(world, chunkX, chunkZ);
return false;
}
protected void startListening() {

View file

@ -32,7 +32,7 @@ public class NonStationaryLighter<C extends Contraption> extends ContraptionLigh
@Override
public GridAlignedBB getContraptionBounds() {
GridAlignedBB bb = GridAlignedBB.fromAABB(contraption.bounds);
GridAlignedBB bb = GridAlignedBB.from(contraption.bounds);
bb.translate(contraption.entity.getPosition());

View file

@ -12,7 +12,7 @@ public class AnchoredLighter extends ContraptionLighter<Contraption> {
@Override
public GridAlignedBB getContraptionBounds() {
GridAlignedBB bb = GridAlignedBB.fromAABB(contraption.bounds);
GridAlignedBB bb = GridAlignedBB.from(contraption.bounds);
bb.translate(contraption.anchor);
return bb;
}

View file

@ -12,7 +12,7 @@ public class PistonLighter extends ContraptionLighter<PistonContraption> {
@Override
public GridAlignedBB getContraptionBounds() {
GridAlignedBB bounds = GridAlignedBB.fromAABB(contraption.bounds);
GridAlignedBB bounds = GridAlignedBB.from(contraption.bounds);
bounds.translate(contraption.anchor);
int length = contraption.extensionLength;

View file

@ -15,7 +15,7 @@ public class PulleyLighter extends ContraptionLighter<PulleyContraption> {
@Override
public GridAlignedBB getContraptionBounds() {
GridAlignedBB bounds = GridAlignedBB.fromAABB(contraption.bounds);
GridAlignedBB bounds = GridAlignedBB.from(contraption.bounds);
World world = contraption.entity.world;

View file

@ -294,10 +294,10 @@ public class BeltRenderer extends SafeTileEntityRenderer<BeltTileEntity> {
}
protected int getPackedLight(BeltTileEntity controller, float beltPos) {
BeltTileEntity belt = BeltHelper.getBeltForOffset(controller, beltPos);
int segment = (int) Math.floor(beltPos) * 2;
if (belt == null) return 0;
if (controller.light == null || segment >= controller.light.length) return 0;
return (belt.skyLight << 20) | (belt.blockLight << 4);
return (controller.light[segment + 1] << 20) | (controller.light[segment] << 4);
}
}

View file

@ -23,7 +23,9 @@ import com.simibubi.create.content.contraptions.relays.belt.transport.ItemHandle
import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack;
import com.simibubi.create.content.logistics.block.belts.tunnel.BrassTunnelTileEntity;
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
import com.simibubi.create.foundation.render.backend.light.ILightListener;
import com.simibubi.create.foundation.render.backend.light.GridAlignedBB;
import com.simibubi.create.foundation.render.backend.light.LightUpdateListener;
import com.simibubi.create.foundation.render.backend.light.LightUpdater;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour;
@ -46,6 +48,7 @@ import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.Vec3i;
import net.minecraft.world.ILightReader;
import net.minecraft.world.LightType;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.model.data.IModelData;
@ -57,7 +60,7 @@ import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
public class BeltTileEntity extends KineticTileEntity implements ILightListener {
public class BeltTileEntity extends KineticTileEntity implements LightUpdateListener {
public Map<Entity, TransportedEntityInfo> passengers;
public Optional<DyeColor> color;
@ -73,8 +76,7 @@ public class BeltTileEntity extends KineticTileEntity implements ILightListener
public CompoundNBT trackerUpdateTag;
// client
public byte blockLight = -1;
public byte skyLight = -1;
public byte[] light;
public static enum CasingType {
NONE, ANDESITE, BRASS;
@ -109,8 +111,9 @@ public class BeltTileEntity extends KineticTileEntity implements ILightListener
initializeItemHandler();
if (blockLight == -1)
updateLight();
if (light == null && isController())
LightUpdater.getInstance().startListening(getBeltVolume(), this);
initializeLight();
// Move Items
if (!isController())
@ -513,23 +516,68 @@ public class BeltTileEntity extends KineticTileEntity implements ILightListener
return 0;
}
@Override
public void onChunkLightUpdate() {
updateLight();
}
@Override
public boolean shouldRenderAsTE() {
return isController();
}
private void updateLight() {
if (world != null) {
skyLight = (byte) world.getLightLevel(LightType.SKY, pos);
blockLight = (byte) world.getLightLevel(LightType.BLOCK, pos);
} else {
skyLight = -1;
blockLight = -1;
@Override
public boolean onLightUpdate(ILightReader world, LightType type, GridAlignedBB changed) {
if (this.removed) {
return true;
}
GridAlignedBB beltVolume = getBeltVolume();
if (beltVolume.intersects(changed)) {
GridAlignedBB section = changed.intersect(beltVolume);
if (type == LightType.BLOCK)
section.forEachContained(this::updateBlockLight);
if (type == LightType.SKY)
section.forEachContained(this::updateSkyLight);
}
return false;
}
private GridAlignedBB getBeltVolume() {
BlockPos endPos = controller.offset(getBeltFacing(), beltLength - 1);
return GridAlignedBB.from(pos, endPos);
}
private void updateBlockLight(int x, int y, int z) {
int segment = posToSegment(x, y, z) * 2;
light[segment] = (byte) world.getLightLevel(LightType.BLOCK, new BlockPos(x, y, z));
}
private void updateSkyLight(int x, int y, int z) {
int segment = posToSegment(x, y, z) * 2;
light[segment + 1] = (byte) world.getLightLevel(LightType.SKY, new BlockPos(x, y, z));
}
private int posToSegment(int x, int y, int z) {
int dX = Math.abs(controller.getX() - x);
int dY = Math.abs(controller.getY() - y);
int dZ = Math.abs(controller.getZ() - z);
return dY + dX + dZ;
}
private void initializeLight() {
light = new byte[beltLength * 2];
Direction facing = getBeltFacing();
BlockPos.Mutable pos = new BlockPos.Mutable(controller);
for (int i = 0; i < beltLength; i++) {
int segment = 2 * i;
light[segment] = (byte) world.getLightLevel(LightType.BLOCK, pos);
light[segment + 1] = (byte) world.getLightLevel(LightType.SKY, pos);
pos.move(facing);
}
}
}

View file

@ -10,7 +10,6 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher;
import com.simibubi.create.foundation.render.backend.light.ILightListener;
import com.simibubi.create.foundation.render.backend.light.LightUpdater;
import net.minecraft.client.multiplayer.ClientChunkProvider;
@ -49,9 +48,6 @@ public abstract class LightUpdateMixin extends AbstractChunkProvider {
.map(Map.Entry::getValue)
.forEach(tile -> {
CreateClient.kineticRenderer.get(world).onLightUpdate(tile);
if (tile instanceof ILightListener)
((ILightListener) tile).onChunkLightUpdate();
});
}

View file

@ -3,7 +3,6 @@ package com.simibubi.create.foundation.mixin;
import com.simibubi.create.CreateClient;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher;
import com.simibubi.create.foundation.render.backend.RenderWork;
import com.simibubi.create.foundation.render.backend.light.ILightListener;
import com.simibubi.create.foundation.render.backend.light.LightUpdater;
import net.minecraft.client.Minecraft;
@ -39,9 +38,6 @@ public class NetworkLightUpdateMixin {
.values()
.forEach(tile -> {
CreateClient.kineticRenderer.get(world).onLightUpdate(tile);
if (tile instanceof ILightListener)
((ILightListener) tile).onChunkLightUpdate();
});
}

View file

@ -6,6 +6,7 @@ import com.simibubi.create.foundation.render.backend.RenderUtil;
import net.minecraft.util.Direction;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.SectionPos;
import net.minecraft.util.math.Vec3i;
@ -34,7 +35,7 @@ public class GridAlignedBB {
return new GridAlignedBB(bb.minX, bb.minY, bb.minZ, bb.maxX, bb.maxY, bb.maxZ);
}
public static GridAlignedBB fromAABB(AxisAlignedBB aabb) {
public static GridAlignedBB from(AxisAlignedBB aabb) {
int minX = (int) Math.floor(aabb.minX);
int minY = (int) Math.floor(aabb.minY);
int minZ = (int) Math.floor(aabb.minZ);
@ -44,7 +45,7 @@ public class GridAlignedBB {
return new GridAlignedBB(minX, minY, minZ, maxX, maxY, maxZ);
}
public static GridAlignedBB fromSection(SectionPos pos) {
public static GridAlignedBB from(SectionPos pos) {
return new GridAlignedBB(pos.getWorldStartX(),
pos.getWorldStartY(),
pos.getWorldStartZ(),
@ -53,7 +54,16 @@ public class GridAlignedBB {
pos.getWorldEndZ() + 1);
}
public static GridAlignedBB fromChunk(int sectionX, int sectionZ) {
public static GridAlignedBB from(BlockPos start, BlockPos end) {
return new GridAlignedBB(start.getX(),
start.getY(),
start.getZ(),
end.getX() + 1,
end.getY() + 1,
end.getZ() + 1);
}
public static GridAlignedBB from(int sectionX, int sectionZ) {
int startX = sectionX << 4;
int startZ = sectionZ << 4;
return new GridAlignedBB(startX,

View file

@ -1,5 +0,0 @@
package com.simibubi.create.foundation.render.backend.light;
public interface ILightListener {
void onChunkLightUpdate();
}

View file

@ -11,16 +11,22 @@ public interface LightUpdateListener {
/**
* Called when a light updates in a chunk the implementor cares about.
*
* @return true if this object is no longer valid and should not receive any more updates.
*/
void onLightUpdate(ILightReader world, LightType type, GridAlignedBB changed);
boolean onLightUpdate(ILightReader world, LightType type, GridAlignedBB changed);
/**
* Called when the server sends light data to the client.
*
* @return true if this object is no longer valid and should not receive any more updates.
*/
default void onLightPacket(ILightReader world, int chunkX, int chunkZ) {
GridAlignedBB changedVolume = GridAlignedBB.fromChunk(chunkX, chunkZ);
default boolean onLightPacket(ILightReader world, int chunkX, int chunkZ) {
GridAlignedBB changedVolume = GridAlignedBB.from(chunkX, chunkZ);
onLightUpdate(world, LightType.BLOCK, changedVolume);
onLightUpdate(world, LightType.SKY, changedVolume);
if (onLightUpdate(world, LightType.BLOCK, changedVolume))
return true;
return onLightUpdate(world, LightType.SKY, changedVolume);
}
}

View file

@ -114,12 +114,9 @@ public class LightUpdater {
if (set == null || set.isEmpty()) return;
GridAlignedBB chunkBox = GridAlignedBB.fromSection(SectionPos.from(sectionPos));
for (LightUpdateListener listener : set) {
listener.onLightUpdate(world, type, chunkBox.copy());
}
GridAlignedBB chunkBox = GridAlignedBB.from(SectionPos.from(sectionPos));
set.removeIf(listener -> listener.onLightUpdate(world, type, chunkBox.copy()));
}
/**
@ -136,10 +133,7 @@ public class LightUpdater {
if (set == null || set.isEmpty()) return;
for (LightUpdateListener listener : set) {
listener.onLightPacket(world, chunkX, chunkZ);
}
set.removeIf(listener -> listener.onLightPacket(world, chunkX, chunkZ));
}
private LongRBTreeSet clearChunks(LightUpdateListener listener) {

View file

@ -14,7 +14,6 @@ import com.simibubi.create.foundation.render.backend.RenderWork;
import com.simibubi.create.foundation.render.backend.gl.GlTexture;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.SectionPos;
import net.minecraft.world.ILightReader;
import net.minecraft.world.LightType;
@ -138,7 +137,7 @@ public class LightVolume {
public void notifyLightPacket(ILightReader world, int chunkX, int chunkZ) {
if (removed) return;
GridAlignedBB changedVolume = GridAlignedBB.fromChunk(chunkX, chunkZ);
GridAlignedBB changedVolume = GridAlignedBB.from(chunkX, chunkZ);
if (!changedVolume.intersects(sampleVolume))
return;
changedVolume.intersectAssign(sampleVolume); // compute the region contained by us that has dirty lighting data.