/* * Minecraft Forge * Copyright (c) 2016. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package net.minecraftforge.common.chunkio; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.storage.AnvilChunkLoader; import net.minecraft.world.gen.ChunkProviderServer; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.math.ChunkPos; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.world.ChunkDataEvent; import java.io.IOException; import java.util.concurrent.ConcurrentLinkedQueue; class ChunkIOProvider implements Runnable { private final QueuedChunk chunkInfo; private final AnvilChunkLoader loader; private final ChunkProviderServer provider; private Chunk chunk; private NBTTagCompound nbt; private final ConcurrentLinkedQueue<Runnable> callbacks = new ConcurrentLinkedQueue<Runnable>(); private boolean ran = false; ChunkIOProvider(QueuedChunk chunk, AnvilChunkLoader loader, ChunkProviderServer provider) { this.chunkInfo = chunk; this.loader = loader; this.provider = provider; } public void addCallback(Runnable callback) { this.callbacks.add(callback); } public void removeCallback(Runnable callback) { this.callbacks.remove(callback); } @Override public void run() // async stuff { synchronized(this) { Object[] data = null; try { data = this.loader.loadChunk__Async(chunkInfo.world, chunkInfo.x, chunkInfo.z); } catch (IOException e) { e.printStackTrace(); } if (data != null) { this.nbt = (NBTTagCompound)data[1]; this.chunk = (Chunk)data[0]; } this.ran = true; this.notifyAll(); } } // sync stuff public void syncCallback() { if (chunk == null) { this.runCallbacks(); return; } // Load Entities this.loader.loadEntities(this.chunkInfo.world, this.nbt.getCompoundTag("Level"), this.chunk); MinecraftForge.EVENT_BUS.post(new ChunkDataEvent.Load(this.chunk, this.nbt)); // Don't call ChunkDataEvent.Load async this.chunk.setLastSaveTime(provider.world.getTotalWorldTime()); this.provider.chunkGenerator.recreateStructures(this.chunk, this.chunkInfo.x, this.chunkInfo.z); provider.id2ChunkMap.put(ChunkPos.asLong(this.chunkInfo.x, this.chunkInfo.z), this.chunk); this.chunk.onChunkLoad(); this.chunk.populateChunk(provider, provider.chunkGenerator); this.runCallbacks(); } public Chunk getChunk() { return this.chunk; } public boolean runFinished() { return this.ran; } public boolean hasCallback() { return this.callbacks.size() > 0; } public void runCallbacks() { for (Runnable r : this.callbacks) { r.run(); } this.callbacks.clear(); } }