Package mapwriter

Source Code of mapwriter.ChunkManager

package mapwriter;

import java.util.Map;

import mapwriter.region.MwChunk;
import mapwriter.tasks.SaveChunkTask;
import mapwriter.tasks.UpdateSurfaceChunksTask;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;

public class ChunkManager {
  public Mw mw;
  private boolean closed = false;
  private CircularHashMap<Chunk, Integer> chunkMap = new CircularHashMap<Chunk, Integer>();
 
  private static final int VISIBLE_FLAG = 0x01;
  private static final int VIEWED_FLAG = 0x02;
 
  public ChunkManager(Mw mw) {
    this.mw = mw;
  }
 
  public synchronized void close() {
    this.closed = true;
    this.saveChunks();
    this.chunkMap.clear();
  }
 
  // create MwChunk from Minecraft chunk.
  // only MwChunk's should be used in the background thread.
  // TODO: make this a full copy of chunk data to prevent possible race conditions
  public static MwChunk copyToMwChunk(Chunk chunk) {
   
    byte[][] msbArray = new byte[16][];
    byte[][] lsbArray = new byte[16][];
    byte[][] metaArray = new byte[16][];
    byte[][] lightingArray = new byte[16][];
   
    ExtendedBlockStorage[] storageArrays = chunk.getBlockStorageArray();
    if (storageArrays != null) {
      for (ExtendedBlockStorage storage : storageArrays) {
        if (storage != null) {
          int y = (storage.getYLocation() >> 4) & 0xf;
          lsbArray[y] = storage.getBlockLSBArray();
          msbArray[y] = (storage.getBlockMSBArray() != null) ? storage.getBlockMSBArray().data : null;
          metaArray[y] = (storage.getMetadataArray() != null) ? storage.getMetadataArray().data : null;
          lightingArray[y] = (storage.getBlocklightArray() != null) ? storage.getBlocklightArray().data : null;
        }
      }
    }
   
    return new MwChunk(chunk.xPosition, chunk.zPosition, chunk.worldObj.provider.dimensionId,
        msbArray, lsbArray, metaArray, lightingArray, chunk.getBiomeArray());
  }
 
  public synchronized void addChunk(Chunk chunk) {
    if (!this.closed && (chunk != null)) {
      this.chunkMap.put(chunk, 0);
    }
  }
 
  public synchronized void removeChunk(Chunk chunk) {
    if (!this.closed && (chunk != null)) {
            if(!this.chunkMap.containsKey(chunk)) return; //FIXME: Is this failsafe enough for unloading?
      int flags = this.chunkMap.get(chunk);
      if ((flags & VIEWED_FLAG) != 0) {
        this.addSaveChunkTask(chunk);
      }
      this.chunkMap.remove(chunk);
    }
  }
 
  public synchronized void saveChunks() {
    for (Map.Entry<Chunk, Integer> entry : this.chunkMap.entrySet()) {
      int flags = entry.getValue();
      if ((flags & VIEWED_FLAG) != 0) {
        this.addSaveChunkTask(entry.getKey());
      }
    }
  }
 
  public void updateUndergroundChunks() {
    int chunkArrayX = (this.mw.playerXInt >> 4) - 1;
    int chunkArrayZ = (this.mw.playerZInt >> 4) - 1;
    MwChunk[] chunkArray = new MwChunk[9];
    for (int z = 0; z < 3; z++) {
      for (int x = 0; x < 3; x++) {
        Chunk chunk = this.mw.mc.theWorld.getChunkFromChunkCoords(
          chunkArrayX + x,
          chunkArrayZ + z
        );
        if (!chunk.isEmpty()) {
          chunkArray[(z * 3) + x] = copyToMwChunk(chunk);
        }
      }
    }
  }
 
  public void updateSurfaceChunks() {
    int chunksToUpdate = Math.min(this.chunkMap.size(), this.mw.chunksPerTick);
    MwChunk[] chunkArray = new MwChunk[chunksToUpdate];
    for (int i = 0; i < chunksToUpdate; i++) {
      Map.Entry<Chunk, Integer> entry = this.chunkMap.getNextEntry();
      if (entry != null) {
        // if this chunk is within a certain distance to the player then
        // add it to the viewed set
        Chunk chunk = entry.getKey();
        int flags = entry.getValue();
        if (MwUtil.distToChunkSq(this.mw.playerXInt, this.mw.playerZInt, chunk) <= this.mw.maxChunkSaveDistSq) {
          flags |= (VISIBLE_FLAG | VIEWED_FLAG);
        } else {
          flags &= ~VISIBLE_FLAG;
        }
        entry.setValue(flags);
       
        if ((flags & VISIBLE_FLAG) != 0) {
          chunkArray[i] = copyToMwChunk(chunk);
        } else {
          chunkArray[i] = null;
        }
      }
    }
   
    this.mw.executor.addTask(new UpdateSurfaceChunksTask(this.mw, chunkArray));
  }
 
  public void onTick() {
    if (!this.closed) {
      if ((this.mw.tickCounter & 0xf) == 0) {
        this.updateUndergroundChunks();
      } else {
        this.updateSurfaceChunks();
      }
    }
  }
 
  public void forceChunks(MwChunk[] chunkArray){
    this.mw.executor.addTask(new UpdateSurfaceChunksTask(this.mw, chunkArray));
  }
 
  private void addSaveChunkTask(Chunk chunk) {
    if ((this.mw.multiplayer && this.mw.regionFileOutputEnabledMP) ||
      (!this.mw.multiplayer && this.mw.regionFileOutputEnabledSP)) {
      if (!chunk.isEmpty()) {
        this.mw.executor.addTask(new SaveChunkTask(copyToMwChunk(chunk), this.mw.regionManager));
      }
    }
  }
}
TOP

Related Classes of mapwriter.ChunkManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.