This commit is contained in:
Sen 2025-07-12 16:48:23 +02:00
parent c126bdd8b0
commit 318a8885ba
Signed by: sen
GPG key ID: 3AC50A6F47D1B722
53 changed files with 990 additions and 5887 deletions

View file

@ -23,10 +23,6 @@ import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Queue;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.function.Function;
import javax.imageio.ImageIO;
@ -120,10 +116,6 @@ import common.entity.npc.EntityNPC;
import common.entity.npc.EntityWaterNPC;
import common.entity.npc.PlayerCharacter;
import common.entity.types.EntityLiving;
import common.future.Futures;
import common.future.ListenableFuture;
import common.future.ListenableFutureTask;
import common.future.ThreadFactoryBuilder;
import common.init.BlockRegistry;
import common.init.Blocks;
import common.init.EntityRegistry;
@ -171,7 +163,6 @@ import common.util.CharValidator;
import common.util.ExtMath;
import common.util.Facing;
import common.util.HitPosition;
import common.util.LazyLoader;
import common.util.Util;
import common.util.Var;
import common.util.HitPosition.ObjectType;
@ -281,15 +272,11 @@ public class Client implements IThreadListener {
public static final int LOG_BUFFER = 32768;
public static final int MIN_WIDTH = 800;
public static final int MIN_HEIGHT = 450;
private static final LazyLoader<NioEventLoopGroup> CLIENT_NIO_EVENTLOOP = new LazyLoader<NioEventLoopGroup>() {
protected NioEventLoopGroup load() {
return new NioEventLoopGroup(0, new ThreadFactoryBuilder().setNameFormat("Netty Client IO #%d").setDaemon(true).build());
}
};
private final Queue<FutureTask<?>> tasks = new ArrayDeque<FutureTask<?>>();
private final Thread thread = Thread.currentThread();
private final NioEventLoopGroup eventGroup = new NioEventLoopGroup(0, Util.getThreadFactory("Netty Client IO"));
private final Queue<Runnable> tasks = new ArrayDeque<Runnable>();
private final Map<Integer, Long> bars = Maps.newTreeMap();
private final Thread clThread = Thread.currentThread();
private final Map<String, CVar> cvars = Maps.newTreeMap();
private final Map<String, Field> synced = Maps.newTreeMap();
private final Map<Keysym, DebugFunction> debug = Maps.newTreeMap();
@ -537,7 +524,7 @@ public class Client implements IThreadListener {
private NetConnection connect(InetAddress address, int port) {
final NetConnection connection = new NetConnection();
new Bootstrap().group(CLIENT_NIO_EVENTLOOP.getValue()).handler(new ChannelInitializer<Channel>() {
new Bootstrap().group(this.eventGroup).handler(new ChannelInitializer<Channel>() {
protected void initChannel(Channel channel) throws Exception {
try {
channel.config().setOption(ChannelOption.TCP_NODELAY, true);
@ -708,17 +695,13 @@ public class Client implements IThreadListener {
{
while (!this.tasks.isEmpty())
{
FutureTask<?> task = this.tasks.poll();
Runnable task = this.tasks.poll();
try {
task.run();
task.get();
}
catch(ExecutionException e1) {
if(!(e1.getCause() instanceof ThreadQuickExitException))
Log.SYSTEM.error(e1, "Fehler beim Ausführen von Render-Task " + task);
}
catch(InterruptedException e2) {
Log.SYSTEM.error(e2, "Fehler beim Ausführen von Render-Task " + task);
catch(Throwable e) {
if(!(e instanceof ThreadQuickExitException))
Log.SYSTEM.error(e, "Fehler beim Ausführen von Render-Task " + task);
}
}
}
@ -1605,40 +1588,25 @@ public class Client implements IThreadListener {
this.viewEntity = viewingEntity;
}
private <V> ListenableFuture<V> addScheduledTask(Callable<V> callableToSchedule)
{
if (!this.isMainThread())
{
ListenableFutureTask<V> listenablefuturetask = ListenableFutureTask.<V>create(callableToSchedule);
synchronized (this.tasks)
{
this.tasks.add(listenablefuturetask);
return listenablefuturetask;
}
}
else
{
try
{
return Futures.<V>immediateFuture(callableToSchedule.call());
}
catch (Exception exception)
{
Log.SYSTEM.error(exception, "Fehler beim sofortigen Ausführen von Render-Task " + callableToSchedule);
return Futures.immediateFailedFuture(exception);
}
}
}
public ListenableFuture<Object> schedule(Runnable runnableToSchedule)
{
return this.<Object>addScheduledTask(Executors.callable(runnableToSchedule));
}
public void schedule(Runnable task) {
if(!this.isMainThread()) {
synchronized(this.tasks) {
this.tasks.add(task);
}
}
else {
try {
task.run();
}
catch(Throwable e) {
Log.SYSTEM.error(e, "Fehler beim sofortigen Ausführen von Render-Task " + task);
}
}
}
public boolean isMainThread()
{
return Thread.currentThread() == this.clThread;
return Thread.currentThread() == this.thread;
}
public BlockRenderer getBlockRendererDispatcher()

View file

@ -27,7 +27,7 @@ public class GuiInfo extends Gui {
"Albert Pham - WorldEdit (Snippets)",
"Joonas Vali - NameGenerator",
"LWJGL 2.9.4-nightly-20150209 - Project, Vector*, Matrix*",
"Guava 17.0 - collect, future, Predicates",
"Guava 17.0 - collect, Predicates",
"Netty 4.0.23-Final - net.*",
"JOrbis 20101023 (JCraft) - jogg, jorbis, CodecJOrbis"
};

View file

@ -0,0 +1,595 @@
package client.renderer.chunk;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.AbstractExecutorService;
import java.util.concurrent.Callable;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import common.collect.ImmutableList;
import common.collect.Sets;
import common.log.Log;
public abstract class ChunkBuilder {
public static interface ListenableFuture<V> extends Future<V> {
void addListener(Runnable listener, Executor executor);
}
public static class ImmediateFuture implements ListenableFuture<Object> {
public void addListener(Runnable listener, Executor executor) {
try {
executor.execute(listener);
}
catch(RuntimeException e) {
Log.SYSTEM.error(e, "Fehler beim Ausführen von " + listener + " mit " + executor);
}
}
public boolean cancel(boolean mayInterruptIfRunning) {
return false;
}
public Object get() {
return null;
}
public Object get(long timeout, TimeUnit unit) throws ExecutionException {
return null;
}
public boolean isCancelled() {
return false;
}
public boolean isDone() {
return true;
}
}
private static class SameThreadExecutorService extends AbstractExecutorService implements ExecutorService {
private final Lock lock = new ReentrantLock();
private final Condition termination = lock.newCondition();
private int runningTasks = 0;
private boolean shutdown = false;
public void execute(Runnable command) {
startTask();
try {
command.run();
}
finally {
endTask();
}
}
public boolean isShutdown() {
lock.lock();
try {
return shutdown;
}
finally {
lock.unlock();
}
}
public void shutdown() {
lock.lock();
try {
shutdown = true;
}
finally {
lock.unlock();
}
}
public List<Runnable> shutdownNow() {
shutdown();
return Collections.emptyList();
}
public boolean isTerminated() {
lock.lock();
try {
return shutdown && runningTasks == 0;
}
finally {
lock.unlock();
}
}
public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
long nanos = unit.toNanos(timeout);
lock.lock();
try {
for(;;) {
if(isTerminated()) {
return true;
}
else if(nanos <= 0) {
return false;
}
else {
nanos = termination.awaitNanos(nanos);
}
}
}
finally {
lock.unlock();
}
}
private void startTask() {
lock.lock();
try {
if(isShutdown()) {
throw new RejectedExecutionException("Executor already shutdown");
}
runningTasks++;
}
finally {
lock.unlock();
}
}
private void endTask() {
lock.lock();
try {
runningTasks--;
if(isTerminated()) {
termination.signalAll();
}
}
finally {
lock.unlock();
}
}
protected final <T> ListenableFutureTask<T> newTaskFor(Runnable runnable, T value) {
return ListenableFutureTask.create(runnable, value);
}
protected final <T> ListenableFutureTask<T> newTaskFor(Callable<T> callable) {
return ListenableFutureTask.create(callable);
}
public ListenableFuture<?> submit(Runnable task) {
return (ListenableFuture<?>)super.submit(task);
}
public <T> ListenableFuture<T> submit(Runnable task, T result) {
return (ListenableFuture<T>)super.submit(task, result);
}
public <T> ListenableFuture<T> submit(Callable<T> task) {
return (ListenableFuture<T>)super.submit(task);
}
}
private static final class ExecutionList {
private RunnableExecutorPair runnables;
private boolean executed;
public void add(Runnable runnable, Executor executor) {
synchronized(this) {
if(!executed) {
runnables = new RunnableExecutorPair(runnable, executor, runnables);
return;
}
}
executeListener(runnable, executor);
}
public void execute() {
RunnableExecutorPair list;
synchronized(this) {
if(executed) {
return;
}
executed = true;
list = runnables;
runnables = null;
}
RunnableExecutorPair reversedList = null;
while(list != null) {
RunnableExecutorPair tmp = list;
list = list.next;
tmp.next = reversedList;
reversedList = tmp;
}
while(reversedList != null) {
executeListener(reversedList.runnable, reversedList.executor);
reversedList = reversedList.next;
}
}
private static void executeListener(Runnable runnable, Executor executor) {
try {
executor.execute(runnable);
}
catch(RuntimeException e) {
Log.SYSTEM.error(e, "Fehler beim Ausführen von " + runnable + " mit " + executor);
}
}
private static final class RunnableExecutorPair {
final Runnable runnable;
final Executor executor;
RunnableExecutorPair next;
RunnableExecutorPair(Runnable runnable, Executor executor, RunnableExecutorPair next) {
this.runnable = runnable;
this.executor = executor;
this.next = next;
}
}
}
public static class ListenableFutureTask<V> extends FutureTask<V> implements ListenableFuture<V> {
private final ExecutionList executionList = new ExecutionList();
public static <V> ListenableFutureTask<V> create(Callable<V> callable) {
return new ListenableFutureTask<V>(callable);
}
public static <V> ListenableFutureTask<V> create(Runnable runnable, V result) {
return new ListenableFutureTask<V>(runnable, result);
}
ListenableFutureTask(Callable<V> callable) {
super(callable);
}
ListenableFutureTask(Runnable runnable, V result) {
super(runnable, result);
}
public void addListener(Runnable listener, Executor exec) {
executionList.add(listener, exec);
}
protected void done() {
executionList.execute();
}
}
public static void addCallback(List<ListenableFuture<Object>> futures, final ChunkCompileTaskGenerator generator, final CompiledChunk compiled, final ChunkRenderWorker worker) {
final CombinedFuture future = new CombinedFuture(ImmutableList.copyOf(futures));
generator.addFinishRunnable(new Runnable()
{
public void run()
{
future.cancel(false);
}
});
Runnable listener = new Runnable() {
public void run() {
try {
boolean interrupted = false;
try {
while(true) {
try {
future.get();
break;
}
catch(InterruptedException e) {
interrupted = true;
}
}
}
finally {
if(interrupted) {
Thread.currentThread().interrupt();
}
}
}
catch(ExecutionException e) {
if (!(e.getCause() instanceof CancellationException) && !(e.getCause() instanceof InterruptedException))
Log.RENDER.error(e.getCause(), "Fehler beim Rendern des Chunks");
worker.freeRenderBuilder(generator);
return;
}
catch(RuntimeException e) {
if (!(e instanceof CancellationException))
Log.RENDER.error(e, "Fehler beim Rendern des Chunks");
worker.freeRenderBuilder(generator);
return;
}
catch(Error e) {
Log.RENDER.error(e, "Fehler beim Rendern des Chunks");
worker.freeRenderBuilder(generator);
return;
}
worker.setRenderBuilderChunk(generator, compiled);
}
};
future.addListener(listener, new SameThreadExecutorService());
}
private static <V> V getUninterruptibly(Future<V> future) throws ExecutionException {
boolean interrupted = false;
try {
while(true) {
try {
return future.get();
}
catch(InterruptedException e) {
interrupted = true;
}
}
}
finally {
if(interrupted) {
Thread.currentThread().interrupt();
}
}
}
public static class CombinedFuture {
private final Sync sync = new Sync();
private final ExecutionList executionList = new ExecutionList();
ImmutableList<? extends ListenableFuture<Object>> futures;
final AtomicInteger remaining;
final Object seenExceptionsLock = new Object();
boolean active = true;
Set<Throwable> seenExceptions;
CombinedFuture(ImmutableList<ListenableFuture<Object>> futures) {
this.futures = futures;
this.remaining = new AtomicInteger(futures.size());
init();
}
protected void init() {
addListener(new Runnable() {
@Override
public void run() {
if(CombinedFuture.this.isCancelled()) {
for(ListenableFuture<?> future : CombinedFuture.this.futures) {
future.cancel(CombinedFuture.this.wasInterrupted());
}
}
CombinedFuture.this.futures = null;
CombinedFuture.this.active = false;
}
}, new SameThreadExecutorService());
if(futures.isEmpty()) {
set();
return;
}
int i = 0;
for(final ListenableFuture<Object> listenable : futures) {
final int index = i++;
listenable.addListener(new Runnable() {
@Override
public void run() {
setOneValue(index, listenable);
}
}, new SameThreadExecutorService());
}
}
private void setExceptionAndMaybeLog(Throwable throwable) {
boolean visibleFromOutputFuture = false;
boolean firstTimeSeeingThisException = true;
if(true) {
visibleFromOutputFuture = this.setException(throwable);
synchronized(seenExceptionsLock) {
if(seenExceptions == null) {
seenExceptions = Sets.newHashSet();
}
firstTimeSeeingThisException = seenExceptions.add(throwable);
}
}
if(throwable instanceof Error || (true && !visibleFromOutputFuture && firstTimeSeeingThisException)) {
Log.SYSTEM.error(throwable, "Aufgabe fehlgeschlagen");
}
}
private void setOneValue(int index, Future<Object> future) {
boolean wasActive = active;
if(isDone() || !wasActive)
checkState(true, "Future was done before all dependencies completed");
try {
checkState(future.isDone(), "Tried to set value from future which is not done");
Object returnValue = getUninterruptibly(future);
}
catch(CancellationException e) {
if(true) {
cancel(false);
}
}
catch(ExecutionException e) {
setExceptionAndMaybeLog(e.getCause());
}
catch(Throwable t) {
setExceptionAndMaybeLog(t);
}
finally {
int newRemaining = remaining.decrementAndGet();
checkState(newRemaining >= 0, "Less than 0 remaining futures");
if(newRemaining == 0) {
if(wasActive) {
set();
}
else {
checkState(isDone(), "Future is not done");
}
}
}
}
public void get() throws InterruptedException, ExecutionException {
sync.get();
}
public boolean isDone() {
return sync.isDone();
}
public boolean isCancelled() {
return sync.isCancelled();
}
public boolean cancel(boolean mayInterruptIfRunning) {
if(!sync.cancel(mayInterruptIfRunning)) {
return false;
}
executionList.execute();
return true;
}
protected final boolean wasInterrupted() {
return sync.wasInterrupted();
}
public void addListener(Runnable listener, Executor exec) {
executionList.add(listener, exec);
}
protected boolean set() {
boolean result = sync.set();
if(result) {
executionList.execute();
}
return result;
}
protected boolean setException(Throwable throwable) {
boolean result = sync.setException(throwable);
if(result) {
executionList.execute();
}
return result;
}
static final class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = 0L;
static final int RUNNING = 0;
static final int COMPLETING = 1;
static final int COMPLETED = 2;
static final int CANCELLED = 4;
static final int INTERRUPTED = 8;
private Throwable exception;
protected int tryAcquireShared(int ignored) {
if(isDone()) {
return 1;
}
return -1;
}
protected boolean tryReleaseShared(int finalState) {
setState(finalState);
return true;
}
void get(long nanos) throws TimeoutException, CancellationException, ExecutionException, InterruptedException {
if(!tryAcquireSharedNanos(-1, nanos)) {
throw new TimeoutException("Timeout waiting for task.");
}
getValue();
}
void get() throws CancellationException, ExecutionException, InterruptedException {
acquireSharedInterruptibly(-1);
getValue();
}
private void getValue() throws CancellationException, ExecutionException {
int state = getState();
switch(state) {
case COMPLETED:
if(exception != null) {
throw new ExecutionException(exception);
}
else {
return;
}
case CANCELLED:
case INTERRUPTED:
throw cancellationExceptionWithCause("Task was cancelled.", exception);
default:
throw new IllegalStateException("Error, synchronizer in invalid state: " + state);
}
}
boolean isDone() {
return (getState() & (COMPLETED | CANCELLED | INTERRUPTED)) != 0;
}
boolean isCancelled() {
return (getState() & (CANCELLED | INTERRUPTED)) != 0;
}
boolean wasInterrupted() {
return getState() == INTERRUPTED;
}
boolean set() {
return complete(null, COMPLETED);
}
boolean setException(Throwable t) {
return complete(t, COMPLETED);
}
boolean cancel(boolean interrupt) {
return complete(null, interrupt ? INTERRUPTED : CANCELLED);
}
private boolean complete(Throwable t, int finalState) {
boolean doCompletion = compareAndSetState(RUNNING, COMPLETING);
if(doCompletion) {
this.exception = ((finalState & (CANCELLED | INTERRUPTED)) != 0) ? new CancellationException("Future.cancel() was called.") : t;
releaseShared(finalState);
}
else if(getState() == COMPLETING) {
acquireShared(-1);
}
return doCompletion;
}
}
static final CancellationException cancellationExceptionWithCause(String message, Throwable cause) {
CancellationException exception = new CancellationException(message);
exception.initCause(cause);
return exception;
}
}
private static void checkState(boolean expression, String errorMessage) {
if(!expression) {
throw new IllegalStateException(errorMessage);
}
}
}

View file

@ -5,22 +5,18 @@ import java.util.List;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadFactory;
import client.Client;
import client.renderer.RegionRenderCacheBuilder;
import client.renderer.RenderBuffer;
import client.renderer.VertexBuffer;
import client.renderer.chunk.ChunkBuilder.ImmediateFuture;
import client.renderer.chunk.ChunkBuilder.ListenableFuture;
import client.renderer.chunk.ChunkBuilder.ListenableFutureTask;
import common.collect.Lists;
import common.future.Futures;
import common.future.ListenableFuture;
import common.future.ListenableFutureTask;
import common.future.ThreadFactoryBuilder;
import common.model.BlockLayer;
public class ChunkRenderDispatcher
{
private static final ThreadFactory threadFactory = (new ThreadFactoryBuilder()).setNameFormat("Chunk Batcher %d").setDaemon(true).build();
private final List<ChunkRenderWorker> listThreadedWorkers = Lists.<ChunkRenderWorker>newArrayList();
private final BlockingQueue<ChunkCompileTaskGenerator> queueChunkUpdates = new ArrayBlockingQueue<ChunkCompileTaskGenerator>(100);
private final BlockingQueue<RegionRenderCacheBuilder> queueFreeRenderBuilders = new ArrayBlockingQueue<RegionRenderCacheBuilder>(5);
@ -34,7 +30,8 @@ public class ChunkRenderDispatcher
for (int i = 0; i < 2; ++i)
{
ChunkRenderWorker chunkrenderworker = new ChunkRenderWorker(this);
Thread thread = threadFactory.newThread(chunkrenderworker);
Thread thread = new Thread(chunkrenderworker, "Chunk Batcher #" + (i + 1));
thread.setDaemon(true);
thread.start();
this.listThreadedWorkers.add(chunkrenderworker);
}
@ -225,15 +222,15 @@ public class ChunkRenderDispatcher
return flag;
}
public ListenableFuture<Object> uploadChunk(final BlockLayer player, final RenderBuffer p_178503_2_, final RenderChunk chunkRenderer, final CompiledChunk compiledChunkIn)
public ListenableFuture<Object> uploadChunk(final BlockLayer layer, final RenderBuffer buf, final RenderChunk renderer, final CompiledChunk compiled)
{
if (Client.CLIENT.isMainThread())
{
p_178503_2_.reset();
chunkRenderer.getVertexBufferByLayer(player.ordinal()).bufferData(p_178503_2_.getByteBuffer());
buf.reset();
renderer.getVertexBufferByLayer(layer.ordinal()).bufferData(buf.getByteBuffer());
p_178503_2_.setTranslation(0.0D, 0.0D, 0.0D);
return Futures.<Object>immediateFuture((Object)null);
buf.setTranslation(0.0D, 0.0D, 0.0D);
return new ImmediateFuture();
}
else
{
@ -241,7 +238,7 @@ public class ChunkRenderDispatcher
{
public void run()
{
ChunkRenderDispatcher.this.uploadChunk(player, p_178503_2_, chunkRenderer, compiledChunkIn);
ChunkRenderDispatcher.this.uploadChunk(layer, buf, renderer, compiled);
}
}, (Object)null);

View file

@ -1,16 +1,11 @@
package client.renderer.chunk;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CancellationException;
import client.Client;
import client.renderer.RegionRenderCacheBuilder;
import client.renderer.chunk.ChunkBuilder.ListenableFuture;
import common.collect.Lists;
import common.entity.Entity;
import common.future.FutureCallback;
import common.future.Futures;
import common.future.ListenableFuture;
import common.log.Log;
import common.model.BlockLayer;
@ -120,72 +115,25 @@ public class ChunkRenderWorker implements Runnable
generator.getLock().unlock();
}
final CompiledChunk lvt_7_1_ = generator.getCompiledChunk();
ArrayList lvt_8_1_ = Lists.newArrayList();
final CompiledChunk compiled = generator.getCompiledChunk();
List<ListenableFuture<Object>> list = Lists.newArrayList();
if (chunkcompiletaskgenerator$type == ChunkCompileTaskGenerator.Type.REBUILD_CHUNK)
{
for (BlockLayer enumworldblocklayer : BlockLayer.values())
{
if (lvt_7_1_.isLayerStarted(enumworldblocklayer))
if (compiled.isLayerStarted(enumworldblocklayer))
{
lvt_8_1_.add(this.chunkRenderDispatcher.uploadChunk(enumworldblocklayer, generator.getRegionRenderCacheBuilder().getWorldRendererByLayer(enumworldblocklayer), generator.getRenderChunk(), lvt_7_1_));
list.add(this.chunkRenderDispatcher.uploadChunk(enumworldblocklayer, generator.getRegionRenderCacheBuilder().getWorldRendererByLayer(enumworldblocklayer), generator.getRenderChunk(), compiled));
}
}
}
else if (chunkcompiletaskgenerator$type == ChunkCompileTaskGenerator.Type.RESORT_TRANSPARENCY)
{
lvt_8_1_.add(this.chunkRenderDispatcher.uploadChunk(BlockLayer.TRANSLUCENT, generator.getRegionRenderCacheBuilder().getWorldRendererByLayer(BlockLayer.TRANSLUCENT), generator.getRenderChunk(), lvt_7_1_));
list.add(this.chunkRenderDispatcher.uploadChunk(BlockLayer.TRANSLUCENT, generator.getRegionRenderCacheBuilder().getWorldRendererByLayer(BlockLayer.TRANSLUCENT), generator.getRenderChunk(), compiled));
}
final ListenableFuture<List<Object>> listenablefuture = Futures.allAsList(lvt_8_1_);
generator.addFinishRunnable(new Runnable()
{
public void run()
{
listenablefuture.cancel(false);
}
});
Futures.addCallback(listenablefuture, new FutureCallback<List<Object>>()
{
public void onSuccess(List<Object> p_onSuccess_1_)
{
ChunkRenderWorker.this.freeRenderBuilder(generator);
generator.getLock().lock();
label21:
{
try
{
if (generator.getStatus() == ChunkCompileTaskGenerator.Status.UPLOADING)
{
generator.setStatus(ChunkCompileTaskGenerator.Status.DONE);
break label21;
}
if (!generator.isFinished())
{
Log.RENDER.warn("Chunk-Rendering-Aufgabe war " + generator.getStatus() + " wenn UPLOADING erwartet war; breche Aufgabe ab");
}
}
finally
{
generator.getLock().unlock();
}
return;
}
generator.getRenderChunk().setCompiledChunk(lvt_7_1_);
}
public void onFailure(Throwable p_onFailure_1_)
{
ChunkRenderWorker.this.freeRenderBuilder(generator);
if (!(p_onFailure_1_ instanceof CancellationException) && !(p_onFailure_1_ instanceof InterruptedException))
{
Log.RENDER.error(p_onFailure_1_, "Fehler beim Rendern des Chunks");
}
}
});
ChunkBuilder.addCallback(list, generator, compiled, this);
}
}
@ -194,11 +142,40 @@ public class ChunkRenderWorker implements Runnable
return this.regionRenderCacheBuilder != null ? this.regionRenderCacheBuilder : this.chunkRenderDispatcher.allocateRenderBuilder();
}
private void freeRenderBuilder(ChunkCompileTaskGenerator taskGenerator)
public void freeRenderBuilder(ChunkCompileTaskGenerator taskGenerator)
{
if (this.regionRenderCacheBuilder == null)
{
this.chunkRenderDispatcher.freeRenderBuilder(taskGenerator.getRegionRenderCacheBuilder());
}
}
public void setRenderBuilderChunk(ChunkCompileTaskGenerator generator, CompiledChunk compiled)
{
ChunkRenderWorker.this.freeRenderBuilder(generator);
generator.getLock().lock();
label21:
{
try
{
if (generator.getStatus() == ChunkCompileTaskGenerator.Status.UPLOADING)
{
generator.setStatus(ChunkCompileTaskGenerator.Status.DONE);
break label21;
}
if (!generator.isFinished())
{
Log.RENDER.warn("Chunk-Rendering-Aufgabe war " + generator.getStatus() + " wenn UPLOADING erwartet war; breche Aufgabe ab");
}
}
finally
{
generator.getLock().unlock();
}
return;
}
generator.getRenderChunk().setCompiledChunk(compiled);
}
}