ChunkLightingManager class

Пакет: com.hypixel.hytale.server.core.universe.world.lighting

Файл: com/hypixel/hytale/server/core/universe/world/lighting/ChunkLightingManager.java

implements: Runnable

Поля (17)

МодификаторыТипИмя
break
break
int var1
var1
int var1
int var10
var10
int var2
var2
StringBuilder var2
Vector3i var3
var3
Vector3i var3
WorldChunk var3
int var3
int var4
BlockSection var5

Методы (27)

МодификаторыВозвратСигнатура
public void addToQueuevoid addToQueue(Vector3i var1)
for for(int var4 = 0; var4 < 10; var4++)
for for(int var4 = 0; var4 < 10; var4++)
for for(int var5 = 0; var5 < 10; var5++)
public LightCalculation getLightCalculationLightCalculation getLightCalculation()
public int getQueueSizeint getQueueSize()
if if(var3 != null)
if if(var10 != var1)
if if(var1 > 5000)
if if(BlockChunk.SEND_LOCAL_LIGHTING_DATA || BlockChunk.SEND_GLOBAL_LIGHTING_DATA)
public void initvoid init(WorldChunk var1)
public boolean interruptboolean interrupt()
public boolean invalidateLightAtBlockboolean invalidateLightAtBlock(@Nonnull ChunkStore var1, int var2, int var3, int var4, BlockType var5, int var6, int var7)
public boolean invalidateLightInChunkboolean invalidateLightInChunk(@Nonnull ChunkStore var1, int var2, int var3)
public boolean invalidateLightInChunkSectionboolean invalidateLightInChunkSection(@Nonnull ChunkStore var1, int var2, int var3, int var4)
public void invalidateLoadedChunksvoid invalidateLoadedChunks()
public boolean isQueuedboolean isQueued(int var1, int var2)
public boolean isQueuedboolean isQueued(Vector3i var1)
private void processvoid process(Vector3i var1)
public void setLightCalculationvoid setLightCalculation(LightCalculation var1)
public void startvoid start()
public void stopvoid stop()
synchronized synchronized(this.queue)
synchronized synchronized(this.queue)
synchronized synchronized(this.queue)
synchronized synchronized(this.queue)
synchronized synchronized(this.queue)

Исходный код

Показать/скрыть
class="kw">package com.hypixel.hytale.server.core.universe.world.lighting;

class="kw">import com.hypixel.hytale.logger.HytaleLogger;
class="kw">import com.hypixel.hytale.math.util.ChunkUtil;
class="kw">import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
class="kw">import com.hypixel.hytale.server.core.universe.world.World;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.BlockChunk;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.WorldChunk;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.section.BlockSection;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectArrayFIFOQueue;
class="kw">import java.util.Set;
class="kw">import java.util.concurrent.ConcurrentHashMap;
class="kw">import java.util.concurrent.Semaphore;
class="kw">import java.util.logging.Level;
class="kw">import javax.annotation.Nonnull;
class="kw">import org.joml.Vector3i;

class="kw">public class ChunkLightingManager class="kw">implements Runnable {
   @Nonnull
   class="kw">private class="kw">final HytaleLogger logger;
   @Nonnull
   class="kw">private class="kw">final Thread thread;
   @Nonnull
   class="kw">private class="kw">final World world;
   class="kw">private class="kw">final Semaphore semaphore = new Semaphore(1);
   class="kw">private class="kw">final Set<Vector3i> set = ConcurrentHashMap.newKeySet();
   class="kw">private class="kw">final ObjectArrayFIFOQueue<Vector3i> queue = new ObjectArrayFIFOQueue();
   class="kw">private LightCalculation lightCalculation;

   class="kw">public ChunkLightingManager(@Nonnull World var1) {
      this.logger = HytaleLogger.get("World|" + var1.getName() + "|L");
      this.thread = new Thread(this, "ChunkLighting - " + var1.getName());
      this.thread.setDaemon(true);
      this.world = var1;
      this.lightCalculation = new FloodLightCalculation(this);
   }

   @Nonnull
   class="kw">protected HytaleLogger getLogger() {
      class="kw">return this.logger;
   }

   @Nonnull
   class="kw">public World getWorld() {
      class="kw">return this.world;
   }

   class="kw">public void setLightCalculation(LightCalculation var1) {
      this.lightCalculation = var1;
   }

   class="kw">public LightCalculation getLightCalculation() {
      class="kw">return this.lightCalculation;
   }

   class="kw">public void start() {
      this.thread.start();
   }

   @Override
   class="kw">public void run() {
      try {
         int var1 = 0;
         int var2 = 0;

         while (!this.thread.isInterrupted()) {
            this.semaphore.drainPermits();
            Vector3i var3;
            class="kw">synchronized (this.queue) {
               var3 = this.queue.isEmpty() ? null : (Vector3i)this.queue.dequeue();
            }

            if (var3 != null) {
               this.process(var3);
            }

            Thread.yield();
            int var10;
            class="kw">synchronized (this.queue) {
               var10 = this.queue.size();
            }

            if (var10 != var1) {
               var2 = 0;
               var1 = var10;
            } else if (var2 <= var10) {
               var2++;
            } else {
               this.semaphore.acquire();
            }
         }
      } catch (InterruptedException var9) {
         Thread.currentThread().interrupt();
      }
   }

   class="kw">private void process(Vector3i var1) {
      try {
         class="kw">switch (this.lightCalculation.calculateLight(var1)) {
            case NOT_LOADED:
            case WAITING_FOR_NEIGHBOUR:
            case DONE:
               this.set.remove(var1);
               break;
            case INVALIDATED:
               class="kw">synchronized (this.queue) {
                  this.queue.enqueue(var1);
               }
         }
      } catch (Exception var5) {
         ((HytaleLogger.Api)this.logger.at(Level.WARNING).withCause(var5)).log("Failed to calculate lighting for: %s", var1);
         this.set.remove(var1);
      }
   }

   class="kw">public boolean interrupt() {
      if (this.thread.isAlive()) {
         this.thread.interrupt();
         class="kw">return true;
      } else {
         class="kw">return false;
      }
   }

   class="kw">public void stop() {
      try {
         int var1 = 0;

         while (this.thread.isAlive()) {
            this.thread.interrupt();
            this.thread.join(this.world.getTickStepNanos() / 1000000);
            var1 += this.world.getTickStepNanos() / 1000000;
            if (var1 > 5000) {
               StringBuilder var2 = new StringBuilder();

               for (StackTraceElement var6 : this.thread.getStackTrace()) {
                  var2.append("\tat ").append(var6).append('\n');
               }

               HytaleLogger.getLogger().at(Level.SEVERE).log("Abandoning ChunkLighting Thread %s (stuck for >5s):\n%s", this.thread, var2.toString());
               break;
            }
         }
      } catch (InterruptedException var7) {
         Thread.currentThread().interrupt();
      }
   }

   class="kw">public void init(WorldChunk var1) {
      this.lightCalculation.init(var1);
   }

   class="kw">public void addToQueue(Vector3i var1) {
      if (this.set.add(var1)) {
         class="kw">synchronized (this.queue) {
            this.queue.enqueue(var1);
         }

         this.semaphore.release(1);
      }
   }

   class="kw">public boolean isQueued(int var1, int var2) {
      Vector3i var3 = new Vector3i(var1, 0, var2);

      for (int var4 = 0; var4 < 10; var4++) {
         var3.y = var4;
         if (this.isQueued(var3)) {
            class="kw">return true;
         }
      }

      class="kw">return false;
   }

   class="kw">public boolean isQueued(Vector3i var1) {
      class="kw">return this.set.contains(var1);
   }

   class="kw">public int getQueueSize() {
      class="kw">synchronized (this.queue) {
         class="kw">return this.queue.size();
      }
   }

   class="kw">public boolean invalidateLightAtBlock(@Nonnull ChunkStore var1, int var2, int var3, int var4, BlockType var5, int var6, int var7) {
      class="kw">return this.lightCalculation.invalidateLightAtBlock(var1, var2, var3, var4, var5, var6, var7);
   }

   class="kw">public boolean invalidateLightInChunk(@Nonnull ChunkStore var1, int var2, int var3) {
      class="kw">return this.lightCalculation.invalidateLightInChunkSections(var1, var2, var3, 0, 10);
   }

   class="kw">public boolean invalidateLightInChunkSection(@Nonnull ChunkStore var1, int var2, int var3, int var4) {
      class="kw">return this.lightCalculation.invalidateLightInChunkSections(var1, var2, var3, var4, var4 + 1);
   }

   class="kw">public void invalidateLoadedChunks() {
      this.world.getChunkStore().getStore().forEachEntityParallel(WorldChunk.getComponentType(), (var0, var1, var2) -> {
         WorldChunk var3 = var1.getComponent(var0, WorldChunk.getComponentType());

         for (int var4 = 0; var4 < 10; var4++) {
            BlockSection var5 = var3.getBlockChunk().getSectionAtIndex(var4);
            var5.invalidateLocalLight();
            if (BlockChunk.SEND_LOCAL_LIGHTING_DATA || BlockChunk.SEND_GLOBAL_LIGHTING_DATA) {
               var3.getBlockChunk().invalidateChunkSection(var4);
            }
         }
      });
      this.world.getChunkStore().getChunkIndexes().forEach(var1 -> {
         int var3 = ChunkUtil.xOfChunkIndex(var1);
         int var4 = ChunkUtil.zOfChunkIndex(var1);

         for (int var5 = 0; var5 < 10; var5++) {
            this.addToQueue(new Vector3i(var3, var5, var4));
         }
      });
   }
}