minor formatting/comment updates
This commit is contained in:
@@ -61,7 +61,7 @@ public abstract class AbstractDataSourceLoader
|
||||
loaderRegistry.put(clazz, this);
|
||||
}
|
||||
|
||||
// Can return null as meaning the requirement is not met
|
||||
/** Can return null as meaning the requirement is not met */
|
||||
public abstract ILodDataSource loadData(DataMetaFile dataFile, InputStream data, IDhLevel level) throws IOException;
|
||||
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ public abstract class AbstractRenderSourceLoader
|
||||
this.detailOffset = detailOffset;
|
||||
}
|
||||
|
||||
// Can return null as meaning the file is out of date or something
|
||||
/** Can return null if the file is out of date or something */
|
||||
public abstract ILodRenderSource loadRender(RenderMetaFile renderFile, InputStream data, IDhLevel level) throws IOException;
|
||||
public abstract ILodRenderSource createRender(ILodDataSource dataSource, IDhClientLevel level);
|
||||
|
||||
|
||||
@@ -5,7 +5,10 @@ import com.seibel.lod.core.datatype.full.accessor.SingleFullArrayView;
|
||||
public interface IIncompleteDataSource extends ILodDataSource
|
||||
{
|
||||
void sampleFrom(ILodDataSource source);
|
||||
|
||||
ILodDataSource trySelfPromote();
|
||||
// Return null if doesn't exist
|
||||
|
||||
/** @return null if the data doesn't exist */
|
||||
SingleFullArrayView tryGet(int x, int z);
|
||||
|
||||
}
|
||||
|
||||
@@ -45,4 +45,5 @@ public interface ILodRenderSource
|
||||
|
||||
/** Overrides any data that has not been written directly using write(). Skips empty source dataPoints. */
|
||||
void updateFromRenderSource(ILodRenderSource source);
|
||||
|
||||
}
|
||||
|
||||
@@ -25,13 +25,13 @@ public class PlaceHolderRenderSource implements ILodRenderSource
|
||||
public byte getDataDetail() { return 0; }
|
||||
|
||||
@Override
|
||||
public void enableRender(IDhClientLevel level, LodQuadTree quadTree){ /* TODO */ }
|
||||
public void enableRender(IDhClientLevel level, LodQuadTree quadTree) { /* TODO */ }
|
||||
|
||||
@Override
|
||||
public void disableRender(){ /* TODO */ }
|
||||
public void disableRender() { /* TODO */ }
|
||||
|
||||
@Override
|
||||
public void dispose(){ /* TODO */ }
|
||||
public void dispose() { /* TODO */ }
|
||||
|
||||
@Override
|
||||
public boolean trySwapRenderBuffer(LodQuadTree quadTree, AtomicReference<RenderBuffer> referenceSlots) { return false; }
|
||||
@@ -59,5 +59,4 @@ public class PlaceHolderRenderSource implements ILodRenderSource
|
||||
@Override
|
||||
public void updateFromRenderSource(ILodRenderSource source) { /* TODO */ }
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -13,16 +13,19 @@ import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
||||
//FIXME: To-Be-Used class
|
||||
public class ChunkToLodBuilder {
|
||||
public static final ConfigBasedLogger LOGGER = new ConfigBasedLogger(LogManager.getLogger(),
|
||||
() -> Config.Client.Advanced.Debugging.DebugSwitch.logLodBuilderEvent.get());
|
||||
public class ChunkToLodBuilder
|
||||
{
|
||||
public static final ConfigBasedLogger LOGGER = new ConfigBasedLogger(LogManager.getLogger(), () -> Config.Client.Advanced.Debugging.DebugSwitch.logLodBuilderEvent.get());
|
||||
public static final long MAX_TICK_TIME_NS = 1000000000L / 20L;
|
||||
public static final int THREAD_COUNT = 1;
|
||||
|
||||
static class Task {
|
||||
|
||||
private static class Task
|
||||
{
|
||||
final DhChunkPos chunkPos;
|
||||
final CompletableFuture<ChunkSizedData> future;
|
||||
Task(DhChunkPos chunkPos, CompletableFuture<ChunkSizedData> future) {
|
||||
|
||||
Task(DhChunkPos chunkPos, CompletableFuture<ChunkSizedData> future)
|
||||
{
|
||||
this.chunkPos = chunkPos;
|
||||
this.future = future;
|
||||
}
|
||||
@@ -31,65 +34,91 @@ public class ChunkToLodBuilder {
|
||||
private final ConcurrentLinkedDeque<Task> taskToBuild = new ConcurrentLinkedDeque<>();
|
||||
private final ExecutorService executor = LodUtil.makeThreadPool(THREAD_COUNT, ChunkToLodBuilder.class);
|
||||
private final AtomicInteger runningCount = new AtomicInteger(0);
|
||||
|
||||
public CompletableFuture<ChunkSizedData> tryGenerateData(IChunkWrapper chunk) {
|
||||
if (chunk == null) throw new NullPointerException("ChunkWrapper cannot be null!");
|
||||
|
||||
|
||||
|
||||
public CompletableFuture<ChunkSizedData> tryGenerateData(IChunkWrapper chunk)
|
||||
{
|
||||
if (chunk == null)
|
||||
throw new NullPointerException("ChunkWrapper cannot be null!");
|
||||
|
||||
IChunkWrapper oldChunk = latestChunkToBuild.put(chunk.getChunkPos(), chunk); // an Exchange operation
|
||||
// If there's old chunk, that means we just replaced an unprocessed old request on generating data on this pos.
|
||||
// if so, we can just return null to signal this, as the old request's future will instead be the proper one
|
||||
// that will return the latest generated data.
|
||||
if (oldChunk != null) return null;
|
||||
if (oldChunk != null)
|
||||
return null;
|
||||
|
||||
// Otherwise, it means we're the first to do so. Lets submit our task to this entry.
|
||||
CompletableFuture<ChunkSizedData> future = new CompletableFuture<>();
|
||||
taskToBuild.addLast(new Task(chunk.getChunkPos(), future));
|
||||
return future;
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
|
||||
public void tick()
|
||||
{
|
||||
if (runningCount.get() >= THREAD_COUNT) return;
|
||||
if (taskToBuild.isEmpty()) return;
|
||||
for (int i = 0; i<THREAD_COUNT; i++) {
|
||||
for (int i = 0; i<THREAD_COUNT; i++)
|
||||
{
|
||||
runningCount.incrementAndGet();
|
||||
CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
CompletableFuture.runAsync(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
_tick();
|
||||
} finally {
|
||||
}
|
||||
finally
|
||||
{
|
||||
runningCount.decrementAndGet();
|
||||
}
|
||||
}, executor);
|
||||
}
|
||||
}
|
||||
|
||||
private void _tick() {
|
||||
|
||||
private void _tick()
|
||||
{
|
||||
long time = System.nanoTime();
|
||||
int count = 0;
|
||||
boolean allDone = false;
|
||||
while (true) {
|
||||
if (System.nanoTime() - time > MAX_TICK_TIME_NS && !taskToBuild.isEmpty()) break;
|
||||
while (true)
|
||||
{
|
||||
if (System.nanoTime() - time > MAX_TICK_TIME_NS && !taskToBuild.isEmpty())
|
||||
break;
|
||||
|
||||
Task task = taskToBuild.pollFirst();
|
||||
if (task == null) {
|
||||
if (task == null)
|
||||
{
|
||||
allDone = true;
|
||||
break;
|
||||
}
|
||||
|
||||
count++;
|
||||
IChunkWrapper latestChunk = latestChunkToBuild.remove(task.chunkPos); // Basically an Exchange operation
|
||||
if (latestChunk == null) {
|
||||
if (latestChunk == null)
|
||||
{
|
||||
LOGGER.error("Somehow Task at {} has latestChunk as null! Skipping task!", task.chunkPos);
|
||||
task.future.complete(null);
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
if (LodDataBuilder.canGenerateLodFromChunk(latestChunk)) {
|
||||
|
||||
try
|
||||
{
|
||||
if (LodDataBuilder.canGenerateLodFromChunk(latestChunk))
|
||||
{
|
||||
ChunkSizedData data = LodDataBuilder.createChunkData(latestChunk);
|
||||
if (data != null) {
|
||||
if (data != null)
|
||||
{
|
||||
task.future.complete(data);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LOGGER.error("Error while processing Task at {}!", task.chunkPos, ex);
|
||||
}
|
||||
|
||||
// Failed to build due to chunk not meeting requirement.
|
||||
IChunkWrapper casChunk = latestChunkToBuild.putIfAbsent(task.chunkPos, latestChunk); // CAS operation with expected=null
|
||||
if (casChunk == null || latestChunk.isStillValid()) // That means CAS have been successful
|
||||
@@ -98,11 +127,16 @@ public class ChunkToLodBuilder {
|
||||
task.future.complete(null);
|
||||
count--;
|
||||
}
|
||||
|
||||
long time2 = System.nanoTime();
|
||||
if (!allDone) {
|
||||
if (!allDone)
|
||||
{
|
||||
//LOGGER.info("Completed {} tasks in {} in this tick", count, Duration.ofNanos(time2 - time));
|
||||
} else if (count > 0) {
|
||||
}
|
||||
else if (count > 0)
|
||||
{
|
||||
//LOGGER.info("Completed all {} tasks in {}", count, Duration.ofNanos(time2 - time));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+12
-7
@@ -11,21 +11,26 @@ import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
//TODO: Merge this with FullToColumnTransformer
|
||||
public class DataRenderTransformer {
|
||||
public class DataRenderTransformer
|
||||
{
|
||||
public static final ExecutorService TRANSFORMER_THREADS
|
||||
= LodUtil.makeThreadPool(4, "Data/Render Transformer");
|
||||
|
||||
public static CompletableFuture<ILodRenderSource> transformDataSource(ILodDataSource data, IDhClientLevel level) {
|
||||
|
||||
public static CompletableFuture<ILodRenderSource> transformDataSource(ILodDataSource data, IDhClientLevel level)
|
||||
{
|
||||
return CompletableFuture.supplyAsync(() -> transform(data, level), TRANSFORMER_THREADS);
|
||||
}
|
||||
|
||||
public static CompletableFuture<ILodRenderSource> asyncTransformDataSource(CompletableFuture<ILodDataSource> data, IDhClientLevel level) {
|
||||
|
||||
public static CompletableFuture<ILodRenderSource> asyncTransformDataSource(CompletableFuture<ILodDataSource> data, IDhClientLevel level)
|
||||
{
|
||||
return data.thenApplyAsync((d) -> transform(d, level), TRANSFORMER_THREADS);
|
||||
}
|
||||
|
||||
private static ILodRenderSource transform(ILodDataSource dataSource, IDhClientLevel level) {
|
||||
|
||||
private static ILodRenderSource transform(ILodDataSource dataSource, IDhClientLevel level)
|
||||
{
|
||||
if (dataSource == null) return null;
|
||||
return ColumnRenderLoader.loaderRegistry.get(ColumnRenderSource.class)
|
||||
.stream().findFirst().get().createRender(dataSource, level);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ public class FullToColumnTransformer {
|
||||
* Creates a LodNode for a chunk in the given world.
|
||||
* @throws IllegalArgumentException thrown if either the chunk or world is null.
|
||||
*/
|
||||
|
||||
public static ColumnRenderSource transformFullDataToColumnData(IDhClientLevel level, FullDataSource data) {
|
||||
final DhSectionPos pos = data.getSectionPos();
|
||||
final byte dataDetail = data.getDataDetail();
|
||||
|
||||
Reference in New Issue
Block a user