Fix beacons disappearing and not updating correctly
This commit is contained in:
-177
@@ -1,177 +0,0 @@
|
||||
package com.seibel.distanthorizons.core.file.beacon;
|
||||
|
||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||
import com.seibel.distanthorizons.core.pos.DhSectionPos;
|
||||
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos;
|
||||
import com.seibel.distanthorizons.core.render.renderer.generic.BeaconRenderHandler;
|
||||
import com.seibel.distanthorizons.core.render.renderer.generic.GenericObjectRenderer;
|
||||
import com.seibel.distanthorizons.core.sql.dto.BeaconBeamDTO;
|
||||
import com.seibel.distanthorizons.core.sql.repo.BeaconBeamRepo;
|
||||
import com.seibel.distanthorizons.core.util.KeyedLockContainer;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
public class BeaconBeamDataHandler
|
||||
{
|
||||
private final BeaconBeamRepo beaconBeamRepo;
|
||||
|
||||
@Nullable
|
||||
private BeaconRenderHandler beaconRenderHandler;
|
||||
|
||||
private final KeyedLockContainer<Long> updateLockContainer = new KeyedLockContainer<>();
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
|
||||
public BeaconBeamDataHandler(@NotNull BeaconBeamRepo beaconBeamRepo, @Nullable GenericObjectRenderer renderer)
|
||||
{
|
||||
this.beaconBeamRepo = beaconBeamRepo;
|
||||
|
||||
if (renderer != null)
|
||||
{
|
||||
this.beaconRenderHandler = new BeaconRenderHandler(renderer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==========//
|
||||
// updating //
|
||||
//==========//
|
||||
|
||||
public void setBeaconBeamsForChunk(DhChunkPos chunkPos, List<BeaconBeamDTO> activeBeamList)
|
||||
{
|
||||
long sectionPos = DhSectionPos.encode(LodUtil.CHUNK_DETAIL_LEVEL, chunkPos.getX(), chunkPos.getZ());
|
||||
this.setBeaconBeamsForPos(sectionPos, activeBeamList);
|
||||
}
|
||||
|
||||
public void setBeaconBeamsForPos(long sectionPos, List<BeaconBeamDTO> activeBeamList)
|
||||
{
|
||||
// locked to prevent two threads from updating the same section at the same time
|
||||
ReentrantLock lock = this.updateLockContainer.getLockForPos(sectionPos);
|
||||
try
|
||||
{
|
||||
lock.lock();
|
||||
|
||||
HashSet<DhBlockPos> allPosSet = new HashSet<>();
|
||||
|
||||
// sort new beams
|
||||
HashMap<DhBlockPos, BeaconBeamDTO> activeBeamByPos = new HashMap<>(activeBeamList.size());
|
||||
for (BeaconBeamDTO beam : activeBeamList)
|
||||
{
|
||||
activeBeamByPos.put(beam.blockPos, beam);
|
||||
allPosSet.add(beam.blockPos);
|
||||
}
|
||||
|
||||
// get existing beams
|
||||
List<BeaconBeamDTO> existingBeamList = this.beaconBeamRepo.getAllBeamsForPos(sectionPos);
|
||||
HashMap<DhBlockPos, BeaconBeamDTO> existingBeamByPos = new HashMap<>(existingBeamList.size());
|
||||
for (BeaconBeamDTO beam : existingBeamList)
|
||||
{
|
||||
existingBeamByPos.put(beam.blockPos, beam);
|
||||
allPosSet.add(beam.blockPos);
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (DhBlockPos beaconPos : allPosSet)
|
||||
{
|
||||
if (!DhSectionPos.contains(sectionPos, beaconPos))
|
||||
{
|
||||
// don't update beacons outside the updated chunk
|
||||
continue;
|
||||
}
|
||||
|
||||
BeaconBeamDTO existingBeam = existingBeamByPos.get(beaconPos);
|
||||
BeaconBeamDTO activeBeam = activeBeamByPos.get(beaconPos);
|
||||
|
||||
|
||||
if (activeBeam != null)
|
||||
{
|
||||
if (existingBeam == null)
|
||||
{
|
||||
// new beam found, add to DB
|
||||
this.beaconBeamRepo.save(activeBeam);
|
||||
if (this.beaconRenderHandler != null)
|
||||
{
|
||||
this.beaconRenderHandler.startRenderingBeacon(activeBeam);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// beam still exists in chunk
|
||||
if (!existingBeam.color.equals(activeBeam.color))
|
||||
{
|
||||
// beam colors were changed
|
||||
this.beaconBeamRepo.save(activeBeam);
|
||||
if (this.beaconRenderHandler != null)
|
||||
{
|
||||
this.beaconRenderHandler.updateBeaconColor(activeBeam);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (existingBeam != null)
|
||||
{
|
||||
// beam no longer exists at position, remove from DB
|
||||
this.beaconBeamRepo.deleteWithKey(beaconPos);
|
||||
if (this.beaconRenderHandler != null)
|
||||
{
|
||||
this.beaconRenderHandler.stopRenderingBeaconAtPos(beaconPos);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//===================//
|
||||
// loading/unloading //
|
||||
//===================//
|
||||
|
||||
public void loadBeaconBeamsInPos(long pos)
|
||||
{
|
||||
if (this.beaconRenderHandler == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// get all beams in pos
|
||||
List<BeaconBeamDTO> existingBeamList = this.beaconBeamRepo.getAllBeamsForPos(pos);
|
||||
for (BeaconBeamDTO newBeam : existingBeamList)
|
||||
{
|
||||
this.beaconRenderHandler.startRenderingBeacon(newBeam);
|
||||
}
|
||||
}
|
||||
|
||||
public void unloadBeaconBeamsInPos(long pos)
|
||||
{
|
||||
if (this.beaconRenderHandler == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// get all beams in pos
|
||||
List<BeaconBeamDTO> existingBeamList = this.beaconBeamRepo.getAllBeamsForPos(pos);
|
||||
for (BeaconBeamDTO beam : existingBeamList)
|
||||
{
|
||||
this.beaconRenderHandler.stopRenderingBeaconAtPos(beam.blockPos);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,12 +21,12 @@ package com.seibel.distanthorizons.core.level;
|
||||
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiChunkModifiedEvent;
|
||||
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2;
|
||||
import com.seibel.distanthorizons.core.file.beacon.BeaconBeamDataHandler;
|
||||
import com.seibel.distanthorizons.core.file.fullDatafile.DelayedFullDataSourceSaveCache;
|
||||
import com.seibel.distanthorizons.core.generation.DhLightingEngine;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||
import com.seibel.distanthorizons.core.pos.DhSectionPos;
|
||||
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos;
|
||||
import com.seibel.distanthorizons.core.render.renderer.generic.CloudRenderHandler;
|
||||
import com.seibel.distanthorizons.core.render.renderer.generic.GenericObjectRenderer;
|
||||
import com.seibel.distanthorizons.core.sql.dto.BeaconBeamDTO;
|
||||
@@ -34,6 +34,7 @@ import com.seibel.distanthorizons.core.sql.dto.ChunkHashDTO;
|
||||
import com.seibel.distanthorizons.core.sql.repo.AbstractDhRepo;
|
||||
import com.seibel.distanthorizons.core.sql.repo.BeaconBeamRepo;
|
||||
import com.seibel.distanthorizons.core.sql.repo.ChunkHashRepo;
|
||||
import com.seibel.distanthorizons.core.util.KeyedLockContainer;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
|
||||
@@ -43,10 +44,12 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.io.File;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
public abstract class AbstractDhLevel implements IDhLevel
|
||||
{
|
||||
@@ -59,6 +62,8 @@ public abstract class AbstractDhLevel implements IDhLevel
|
||||
@Nullable
|
||||
public BeaconBeamRepo beaconBeamRepo;
|
||||
|
||||
protected final KeyedLockContainer<Long> beaconUpdateLockContainer = new KeyedLockContainer<>();
|
||||
|
||||
protected final DelayedFullDataSourceSaveCache delayedFullDataSourceSaveCache = new DelayedFullDataSourceSaveCache(this::onDataSourceSaveAsync, 3_000);
|
||||
/** contains the {@link DhChunkPos} for each {@link DhSectionPos} that are queued to save */
|
||||
protected final ConcurrentHashMap<Long, HashSet<DhChunkPos>> updatedChunkPosSetBySectionPos = new ConcurrentHashMap<>();
|
||||
@@ -67,7 +72,6 @@ public abstract class AbstractDhLevel implements IDhLevel
|
||||
/** Will be null if clouds shouldn't be rendered for this level. */
|
||||
@Nullable
|
||||
protected CloudRenderHandler cloudRenderHandler;
|
||||
protected BeaconBeamDataHandler beaconBeamDataHandler;
|
||||
|
||||
|
||||
|
||||
@@ -126,13 +130,6 @@ public abstract class AbstractDhLevel implements IDhLevel
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// shouldn't happen, but just in case
|
||||
if (this.beaconBeamRepo != null)
|
||||
{
|
||||
this.beaconBeamDataHandler = new BeaconBeamDataHandler(this.beaconBeamRepo, genericRenderer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -228,31 +225,139 @@ public abstract class AbstractDhLevel implements IDhLevel
|
||||
//=================//
|
||||
|
||||
@Override
|
||||
public void updateBeaconBeamsForChunk(IChunkWrapper chunkToUpdate, ArrayList<IChunkWrapper> nearbyChunkList)
|
||||
public void updateBeaconBeamsForSectionPos(long sectionPos, List<BeaconBeamDTO> activeBeamList)
|
||||
{
|
||||
if (this.beaconBeamDataHandler != null)
|
||||
int minBlockX = DhSectionPos.getMinCornerBlockX(sectionPos);
|
||||
int minBlockZ = DhSectionPos.getMinCornerBlockZ(sectionPos);
|
||||
// TODO special logic had to be done for DhChunkPos.getMaxBlock,
|
||||
// does that need to be done here?
|
||||
// The DhChunkPos issue caused beacons to appear/disappear incorrectly on negative chunk borders
|
||||
int maxBlockX = minBlockX + DhSectionPos.getBlockWidth(sectionPos);
|
||||
int maxBlockZ = minBlockZ + DhSectionPos.getBlockWidth(sectionPos);
|
||||
|
||||
this.updateBeaconBeamsBetweenBlockPos(
|
||||
sectionPos,
|
||||
minBlockX, minBlockZ,
|
||||
maxBlockX, maxBlockZ,
|
||||
activeBeamList
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBeaconBeamsForChunkPos(DhChunkPos chunkPos, List<BeaconBeamDTO> activeBeamList)
|
||||
{
|
||||
long sectionPos = DhSectionPos.encodeContaining(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, chunkPos);
|
||||
|
||||
int minBlockX = chunkPos.getMinBlockX();
|
||||
int minBlockZ = chunkPos.getMinBlockZ();
|
||||
int maxBlockX = chunkPos.getMaxBlockX();
|
||||
int maxBlockZ = chunkPos.getMaxBlockZ();
|
||||
|
||||
//LOGGER.info("beacons ["+activeBeamList.size()+"] at ["+chunkPos+"] x["+minBlockX+"]-["+maxBlockX+"] z["+minBlockZ+"]-["+maxBlockZ+"].");
|
||||
|
||||
this.updateBeaconBeamsBetweenBlockPos(
|
||||
sectionPos,
|
||||
minBlockX, maxBlockX,
|
||||
minBlockZ, maxBlockZ,
|
||||
activeBeamList
|
||||
);
|
||||
}
|
||||
|
||||
private void updateBeaconBeamsBetweenBlockPos(
|
||||
long sectionPosForLock,
|
||||
int minBlockX, int maxBlockX,
|
||||
int minBlockZ, int maxBlockZ,
|
||||
List<BeaconBeamDTO> activeBeamList
|
||||
) // TODO min/max block pos instead
|
||||
{
|
||||
if (this.beaconBeamRepo == null)
|
||||
{
|
||||
List<BeaconBeamDTO> activeBeamList = chunkToUpdate.getAllActiveBeacons(nearbyChunkList);
|
||||
this.beaconBeamDataHandler.setBeaconBeamsForChunk(chunkToUpdate.getChunkPos(), activeBeamList);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// locked to prevent two threads from updating the same section at the same time
|
||||
ReentrantLock lock = this.beaconUpdateLockContainer.getLockForPos(sectionPosForLock);
|
||||
try
|
||||
{
|
||||
lock.lock();
|
||||
|
||||
HashSet<DhBlockPos> allPosSet = new HashSet<>();
|
||||
|
||||
// sort new beams
|
||||
HashMap<DhBlockPos, BeaconBeamDTO> activeBeamByPos = new HashMap<>(activeBeamList.size());
|
||||
for (BeaconBeamDTO beam : activeBeamList)
|
||||
{
|
||||
activeBeamByPos.put(beam.blockPos, beam);
|
||||
allPosSet.add(beam.blockPos);
|
||||
}
|
||||
|
||||
// get existing beams
|
||||
List<BeaconBeamDTO> existingBeamList = this.beaconBeamRepo.getAllBeamsInBlockPosRange(
|
||||
minBlockX, maxBlockX,
|
||||
minBlockZ, maxBlockZ);
|
||||
HashMap<DhBlockPos, BeaconBeamDTO> existingBeamByPos = new HashMap<>(existingBeamList.size());
|
||||
for (BeaconBeamDTO beam : existingBeamList)
|
||||
{
|
||||
existingBeamByPos.put(beam.blockPos, beam);
|
||||
allPosSet.add(beam.blockPos);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
for (DhBlockPos beaconPos : allPosSet)
|
||||
{
|
||||
if (minBlockX <= beaconPos.getX() && beaconPos.getX() <= maxBlockX
|
||||
&& minBlockZ <= beaconPos.getZ() && beaconPos.getZ() <= maxBlockZ)
|
||||
{
|
||||
//// don't modify beacons outside the updated range
|
||||
//continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
BeaconBeamDTO existingBeam = existingBeamByPos.get(beaconPos);
|
||||
BeaconBeamDTO activeBeam = activeBeamByPos.get(beaconPos);
|
||||
if (activeBeam != null)
|
||||
{
|
||||
//LOGGER.info("add beacon ["+activeBeam.blockPos+"] x["+minBlockX+"]-["+maxBlockX+"] z["+minBlockZ+"]-["+maxBlockZ+"].");
|
||||
|
||||
if (existingBeam == null)
|
||||
{
|
||||
// new beam found, add to DB
|
||||
this.beaconBeamRepo.save(activeBeam);
|
||||
}
|
||||
else
|
||||
{
|
||||
// beam still exists in chunk
|
||||
if (!existingBeam.color.equals(activeBeam.color))
|
||||
{
|
||||
// beam colors were changed
|
||||
this.beaconBeamRepo.save(activeBeam);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (existingBeam != null)
|
||||
{
|
||||
// beam no longer exists at position, remove from DB
|
||||
this.beaconBeamRepo.deleteWithKey(beaconPos);
|
||||
//LOGGER.info("remove beacon ["+beaconPos+"] x["+minBlockX+"]-["+maxBlockX+"] z["+minBlockZ+"]-["+maxBlockZ+"].");
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadBeaconBeamsInPos(long pos)
|
||||
{
|
||||
if (this.beaconBeamDataHandler != null)
|
||||
{
|
||||
this.beaconBeamDataHandler.loadBeaconBeamsInPos(pos);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void unloadBeaconBeamsInPos(long pos)
|
||||
{
|
||||
if (this.beaconBeamDataHandler != null)
|
||||
{
|
||||
this.beaconBeamDataHandler.unloadBeaconBeamsInPos(pos);
|
||||
}
|
||||
}
|
||||
@Nullable
|
||||
public BeaconBeamRepo getBeaconBeamRepo() { return this.beaconBeamRepo; }
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ import com.seibel.distanthorizons.core.config.AppliedConfigState;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.file.beacon.BeaconBeamDataHandler;
|
||||
import com.seibel.distanthorizons.core.file.fullDatafile.FullDataSourceProviderV2;
|
||||
import com.seibel.distanthorizons.core.file.fullDatafile.RemoteFullDataSourceProvider;
|
||||
import com.seibel.distanthorizons.core.file.structure.ISaveStructure;
|
||||
@@ -144,7 +143,7 @@ public class DhClientLevel extends AbstractDhLevel implements IDhClientLevel
|
||||
return;
|
||||
}
|
||||
|
||||
this.beaconBeamDataHandler.setBeaconBeamsForPos(dataSourceDto.pos, message.payload.beaconBeams);
|
||||
this.updateBeaconBeamsForSectionPos(dataSourceDto.pos, message.payload.beaconBeams);
|
||||
this.updateDataSourcesAsync(dataSourceDto.createDataSource(this.levelWrapper));
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -283,7 +282,6 @@ public class DhClientLevel extends AbstractDhLevel implements IDhClientLevel
|
||||
ClientLevelModule.ClientRenderState renderState = this.clientside.ClientRenderStateRef.get();
|
||||
return (renderState != null) ? renderState.renderBufferHandler : null;
|
||||
}
|
||||
public BeaconBeamDataHandler getBeaconBeamDataHandler() { return this.beaconBeamDataHandler; }
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@ import com.seibel.distanthorizons.core.file.structure.ISaveStructure;
|
||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||
import com.seibel.distanthorizons.core.render.RenderBufferHandler;
|
||||
import com.seibel.distanthorizons.core.render.renderer.generic.GenericObjectRenderer;
|
||||
import com.seibel.distanthorizons.core.sql.dto.BeaconBeamDTO;
|
||||
import com.seibel.distanthorizons.core.sql.repo.BeaconBeamRepo;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -50,9 +52,16 @@ public interface IDhLevel extends AutoCloseable, GeneratedFullDataSourceProvider
|
||||
int getChunkHash(DhChunkPos pos);
|
||||
void updateChunkAsync(IChunkWrapper chunk, int newChunkHash);
|
||||
|
||||
void loadBeaconBeamsInPos(long pos);
|
||||
void updateBeaconBeamsForChunk(IChunkWrapper chunkToUpdate, ArrayList<IChunkWrapper> nearbyChunkList);
|
||||
void unloadBeaconBeamsInPos(long pos);
|
||||
default void updateBeaconBeamsForChunk(IChunkWrapper chunkToUpdate, ArrayList<IChunkWrapper> nearbyChunkList)
|
||||
{
|
||||
List<BeaconBeamDTO> activeBeamList = chunkToUpdate.getAllActiveBeacons(nearbyChunkList);
|
||||
this.updateBeaconBeamsForChunkPos(chunkToUpdate.getChunkPos(), activeBeamList);
|
||||
}
|
||||
void updateBeaconBeamsForChunkPos(DhChunkPos chunkPos, List<BeaconBeamDTO> activeBeamList);
|
||||
void updateBeaconBeamsForSectionPos(long sectionPos, List<BeaconBeamDTO> activeBeamList);
|
||||
|
||||
@Nullable
|
||||
BeaconBeamRepo getBeaconBeamRepo();
|
||||
|
||||
FullDataSourceProviderV2 getFullDataProvider();
|
||||
|
||||
|
||||
+1
-1
@@ -239,7 +239,7 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende
|
||||
{
|
||||
try
|
||||
{
|
||||
this.level.getBeaconBeamDataHandler().setBeaconBeamsForPos(dataSourceDto.pos, response.payload.beaconBeams);
|
||||
this.level.updateBeaconBeamsForSectionPos(dataSourceDto.pos, response.payload.beaconBeams);
|
||||
try (FullDataSourceV2 fullDataSource = dataSourceDto.createDataSource(this.level.getLevelWrapper()))
|
||||
{
|
||||
entry.dataSourceConsumer.accept(fullDataSource);
|
||||
|
||||
@@ -83,6 +83,19 @@ public class DhChunkPos
|
||||
public int getMinBlockX() { return this.x << 4; }
|
||||
public int getMinBlockZ() { return this.z << 4; }
|
||||
|
||||
public int getMaxBlockX()
|
||||
{
|
||||
int minBlockPos = this.getMinBlockX() + LodUtil.CHUNK_WIDTH;
|
||||
minBlockPos += (minBlockPos < 0) ? -1 : 0;
|
||||
return minBlockPos;
|
||||
}
|
||||
public int getMaxBlockZ()
|
||||
{
|
||||
int minBlockPos = this.getMinBlockZ() + LodUtil.CHUNK_WIDTH;
|
||||
minBlockPos += (minBlockPos < 0) ? -1 : 0;
|
||||
return minBlockPos;
|
||||
}
|
||||
|
||||
public DhBlockPos2D getMinBlockPos() { return new DhBlockPos2D(this.x << 4, this.z << 4); }
|
||||
|
||||
public boolean contains(DhBlockPos pos)
|
||||
@@ -92,8 +105,8 @@ public class DhChunkPos
|
||||
int maxBlockX = minBlockX + LodUtil.CHUNK_WIDTH;
|
||||
int maxBlockZ = minBlockZ + LodUtil.CHUNK_WIDTH;
|
||||
|
||||
return minBlockX <= pos.getX() && pos.getX() < maxBlockX
|
||||
&& minBlockZ <= pos.getZ() && pos.getZ() < maxBlockZ;
|
||||
return minBlockX >= pos.getX() && pos.getX() < maxBlockX
|
||||
&& minBlockZ >= pos.getZ() && pos.getZ() < maxBlockZ;
|
||||
}
|
||||
|
||||
public double distance(DhChunkPos other)
|
||||
|
||||
@@ -34,6 +34,8 @@ import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D;
|
||||
import com.seibel.distanthorizons.core.pos.DhSectionPos;
|
||||
import com.seibel.distanthorizons.core.render.renderer.DebugRenderer;
|
||||
import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable;
|
||||
import com.seibel.distanthorizons.core.render.renderer.generic.BeaconRenderHandler;
|
||||
import com.seibel.distanthorizons.core.render.renderer.generic.GenericObjectRenderer;
|
||||
import com.seibel.distanthorizons.core.util.KeyedLockContainer;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.util.ThreadUtil;
|
||||
@@ -43,6 +45,7 @@ import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
|
||||
import com.seibel.distanthorizons.coreapi.util.MathUtil;
|
||||
import it.unimi.dsi.fastutil.longs.LongIterator;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.annotation.WillNotClose;
|
||||
import java.awt.*;
|
||||
@@ -138,6 +141,9 @@ public class LodQuadTree extends QuadTree<LodRenderSection> implements IDebugRen
|
||||
})
|
||||
.<Long, ColumnRenderSource>build();
|
||||
|
||||
@Nullable
|
||||
public final BeaconRenderHandler beaconRenderHandler;
|
||||
|
||||
|
||||
/** the smallest numerical detail level number that can be rendered */
|
||||
private byte maxRenderDetailLevel;
|
||||
@@ -167,6 +173,10 @@ public class LodQuadTree extends QuadTree<LodRenderSection> implements IDebugRen
|
||||
this.level = level;
|
||||
this.fullDataSourceProvider = fullDataSourceProvider;
|
||||
this.blockRenderDistanceDiameter = viewDiameterInBlocks;
|
||||
|
||||
GenericObjectRenderer genericObjectRenderer = this.level.getGenericRenderer();
|
||||
this.beaconRenderHandler = (genericObjectRenderer != null) ? new BeaconRenderHandler(genericObjectRenderer) : null;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -340,9 +350,11 @@ public class LodQuadTree extends QuadTree<LodRenderSection> implements IDebugRen
|
||||
}
|
||||
else
|
||||
{
|
||||
// onRenderingDisabled() needs to be fired before the children are enabled so beacons render correctly
|
||||
// children are all loaded, unload this and parents
|
||||
|
||||
if (renderSection.getRenderingEnabled())
|
||||
{
|
||||
// needs to be fired before the children are enabled so beacons render correctly
|
||||
renderSection.onRenderingDisabled();
|
||||
|
||||
|
||||
@@ -463,7 +475,7 @@ public class LodQuadTree extends QuadTree<LodRenderSection> implements IDebugRen
|
||||
}
|
||||
});
|
||||
|
||||
// onRenderingEnabled() needs to be fired after the children are disabled so beacons render correctly
|
||||
// needs to be fired after the children are disabled so beacons render correctly
|
||||
renderSection.onRenderingEnabled();
|
||||
|
||||
}
|
||||
|
||||
@@ -38,6 +38,9 @@ import com.seibel.distanthorizons.core.render.glObject.GLProxy;
|
||||
import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.ColumnRenderBuffer;
|
||||
import com.seibel.distanthorizons.core.render.renderer.DebugRenderer;
|
||||
import com.seibel.distanthorizons.core.render.renderer.generic.BeaconRenderHandler;
|
||||
import com.seibel.distanthorizons.core.sql.dto.BeaconBeamDTO;
|
||||
import com.seibel.distanthorizons.core.sql.repo.BeaconBeamRepo;
|
||||
import com.seibel.distanthorizons.core.util.KeyedLockContainer;
|
||||
import com.seibel.distanthorizons.core.util.threading.PriorityTaskPicker;
|
||||
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
|
||||
@@ -49,6 +52,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import javax.annotation.WillNotClose;
|
||||
import java.awt.*;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
@@ -83,6 +87,15 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable
|
||||
private final KeyedLockContainer<Long> renderLoadLockContainer;
|
||||
private final Cache<Long, ColumnRenderSource> cachedRenderSourceByPos;
|
||||
|
||||
/**
|
||||
* contains the list of beacons currently being rendered in this section
|
||||
* if this list is modified the {@link LodRenderSection#beaconRenderHandler} should be updated to match.
|
||||
*/
|
||||
private final List<BeaconBeamDTO> activeBeaconList = new ArrayList<>();
|
||||
@Nullable
|
||||
public final BeaconRenderHandler beaconRenderHandler;
|
||||
@Nullable
|
||||
public final BeaconBeamRepo beaconBeamRepo;
|
||||
|
||||
|
||||
private boolean renderingEnabled = false;
|
||||
@@ -139,6 +152,9 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable
|
||||
this.level = level;
|
||||
this.fullDataSourceProvider = fullDataSourceProvider;
|
||||
|
||||
this.beaconRenderHandler = this.quadTree.beaconRenderHandler;
|
||||
this.beaconBeamRepo = this.level.getBeaconBeamRepo();
|
||||
|
||||
DebugRenderer.register(this, Config.Client.Advanced.Debugging.DebugWireframe.showRenderSectionStatus);
|
||||
}
|
||||
|
||||
@@ -193,6 +209,7 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable
|
||||
|
||||
this.getAndBuildRenderDataRunnable = () ->
|
||||
{
|
||||
this.getAndRefreshRenderingBeacons();
|
||||
this.getAndUploadRenderDataToGpu();
|
||||
|
||||
// the future is passed in separate to prevent any possible race condition null pointers
|
||||
@@ -350,25 +367,24 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable
|
||||
public void setRenderingEnabled(boolean enabled) { this.renderingEnabled = enabled;}
|
||||
|
||||
/** @see LodRenderSection#setRenderingEnabled */
|
||||
public void onRenderingEnabled() { this.level.loadBeaconBeamsInPos(this.pos); }
|
||||
public void onRenderingEnabled() { this.startRenderingBeacons(); }
|
||||
/** @see LodRenderSection#setRenderingEnabled */
|
||||
public void onRenderingDisabled()
|
||||
{
|
||||
this.level.unloadBeaconBeamsInPos(this.pos);
|
||||
this.stopRenderingBeacons();
|
||||
|
||||
if (Config.Client.Advanced.Debugging.DebugWireframe.showRenderSectionStatus.get())
|
||||
{
|
||||
// show that this position has just been disabled
|
||||
DebugRenderer.makeParticle(
|
||||
new DebugRenderer.BoxParticle(
|
||||
new DebugRenderer.Box(this.pos, 128f, 156f, 0.09f, Color.CYAN.darker()),
|
||||
0.2, 32f
|
||||
)
|
||||
new DebugRenderer.BoxParticle(
|
||||
new DebugRenderer.Box(this.pos, 128f, 156f, 0.09f, Color.CYAN.darker()),
|
||||
0.2, 32f
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean gpuUploadInProgress() { return this.getAndBuildRenderDataFuture != null; }
|
||||
|
||||
|
||||
@@ -465,6 +481,85 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable
|
||||
|
||||
|
||||
|
||||
//=================//
|
||||
// beacon handling //
|
||||
//=================//
|
||||
|
||||
/** gets the active beacon list and stops/starts beacon rendering as necessary */
|
||||
private void getAndRefreshRenderingBeacons()
|
||||
{
|
||||
// do nothing if beacon rendering or repos are unavailable
|
||||
if (this.beaconBeamRepo == null
|
||||
|| this.beaconRenderHandler == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Synchronized to prevent two threads for starting/stopping rendering at once
|
||||
// Shouldn't be necessary, but just in case.
|
||||
synchronized (this.activeBeaconList)
|
||||
{
|
||||
List<BeaconBeamDTO> activeBeacons = this.beaconBeamRepo.getAllBeamsForPos(this.pos);
|
||||
|
||||
|
||||
// stop rendering current beacons
|
||||
for (BeaconBeamDTO beam : this.activeBeaconList)
|
||||
{
|
||||
this.beaconRenderHandler.stopRenderingBeaconAtPos(beam.blockPos);
|
||||
}
|
||||
|
||||
// swap old and new active beacon list
|
||||
this.activeBeaconList.clear();
|
||||
this.activeBeaconList.addAll(activeBeacons);
|
||||
|
||||
// start rendering new beacon list
|
||||
for (BeaconBeamDTO beam : this.activeBeaconList)
|
||||
{
|
||||
this.beaconRenderHandler.startRenderingBeacon(beam);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void stopRenderingBeacons()
|
||||
{
|
||||
// do nothing if beacon rendering is unavailable
|
||||
if (this.beaconRenderHandler == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
synchronized (this.activeBeaconList)
|
||||
{
|
||||
for (BeaconBeamDTO beam : this.activeBeaconList)
|
||||
{
|
||||
this.beaconRenderHandler.stopRenderingBeaconAtPos(beam.blockPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void startRenderingBeacons()
|
||||
{
|
||||
// do nothing if beacon rendering is unavailable
|
||||
if (this.beaconRenderHandler == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
synchronized (this.activeBeaconList)
|
||||
{
|
||||
for (BeaconBeamDTO beam : this.activeBeaconList)
|
||||
{
|
||||
this.beaconRenderHandler.startRenderingBeacon(beam);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//==============//
|
||||
// base methods //
|
||||
//==============//
|
||||
@@ -514,7 +609,7 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable
|
||||
}
|
||||
|
||||
|
||||
this.level.unloadBeaconBeamsInPos(this.pos);
|
||||
this.stopRenderingBeacons();
|
||||
|
||||
if (this.renderBuffer != null)
|
||||
{
|
||||
@@ -551,6 +646,7 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable
|
||||
// while this should generally be a fast operation
|
||||
// this is run on a separate thread to prevent lag on the render thread
|
||||
executor.execute(() -> this.fullDataSourceProvider.removeRetrievalRequestIf((genPos) -> DhSectionPos.contains(this.pos, genPos)));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -174,8 +174,8 @@ public class BeaconBeamRepo extends AbstractDhRepo<DhBlockPos, BeaconBeamDTO>
|
||||
int maxBlockZ = minBlockZ + LodUtil.CHUNK_WIDTH;
|
||||
|
||||
return this.getAllBeamsInBlockPosRange(
|
||||
minBlockX, minBlockZ,
|
||||
maxBlockX, maxBlockZ
|
||||
minBlockX, maxBlockX,
|
||||
minBlockZ, maxBlockZ
|
||||
);
|
||||
}
|
||||
|
||||
@@ -187,8 +187,8 @@ public class BeaconBeamRepo extends AbstractDhRepo<DhBlockPos, BeaconBeamDTO>
|
||||
int maxBlockZ = minBlockZ + DhSectionPos.getBlockWidth(pos);
|
||||
|
||||
return this.getAllBeamsInBlockPosRange(
|
||||
minBlockX, minBlockZ,
|
||||
maxBlockX, maxBlockZ
|
||||
minBlockX, maxBlockX,
|
||||
minBlockZ, maxBlockZ
|
||||
);
|
||||
}
|
||||
|
||||
@@ -199,8 +199,8 @@ public class BeaconBeamRepo extends AbstractDhRepo<DhBlockPos, BeaconBeamDTO>
|
||||
"? <= BlockPosX AND BlockPosX <= ? AND " +
|
||||
"? <= BlockPosZ AND BlockPosZ <= ?";
|
||||
public List<BeaconBeamDTO> getAllBeamsInBlockPosRange(
|
||||
int minBlockX, int minBlockZ,
|
||||
int maxBlockX, int maxBlockZ
|
||||
int minBlockX, int maxBlockX,
|
||||
int minBlockZ, int maxBlockZ
|
||||
)
|
||||
{
|
||||
ArrayList<BeaconBeamDTO> beamList = new ArrayList<>();
|
||||
@@ -214,8 +214,8 @@ public class BeaconBeamRepo extends AbstractDhRepo<DhBlockPos, BeaconBeamDTO>
|
||||
|
||||
int i = 1;
|
||||
statement.setInt(i++, minBlockX);
|
||||
statement.setInt(i++, minBlockZ);
|
||||
statement.setInt(i++, maxBlockX);
|
||||
statement.setInt(i++, minBlockZ);
|
||||
statement.setInt(i++, maxBlockZ);
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user