Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package friedrichlp.tsc.asm.mixins.world;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.concurrent.Callable;
- import java.util.zip.Deflater;
- import java.util.zip.GZIPOutputStream;
- import org.spongepowered.asm.mixin.Mixin;
- import org.spongepowered.asm.mixin.Overwrite;
- import friedrichlp.tsc.TSC;
- import net.minecraft.nbt.NBTTagCompound;
- import net.minecraft.util.math.ChunkPos;
- import net.minecraft.world.World;
- import net.minecraft.world.chunk.Chunk;
- import net.minecraft.world.chunk.storage.AnvilChunkLoader;
- import net.minecraft.world.gen.ChunkProviderServer;
- import net.minecraftforge.common.MinecraftForge;
- import net.minecraftforge.common.chunkio.ChunkIOExecutor;
- import net.minecraftforge.event.world.ChunkDataEvent;
- @Mixin(ChunkIOExecutor.class)
- public class MixinChunkIOExecutor {
- private static List<Entry> chunksToLoad = new ArrayList<Entry>();
- private static long ticks;
- @Overwrite
- public static void queueChunkLoad(World world, AnvilChunkLoader loader, ChunkProviderServer provider, int x, int z, Runnable runnable) {
- Entry e = new Entry(world, loader, provider, x, z);
- e.callbacks.add(runnable);
- chunksToLoad.add(e);
- }
- @Overwrite
- public static void dropQueuedChunkLoad(World world, int x, int z, Runnable runnable) {
- Entry entry = null;
- for (Entry e : chunksToLoad) {
- if (e.x == x && e.z == z) {
- e.callbacks.remove(runnable);
- if (e.callbacks.isEmpty()) {
- entry = e;
- }
- break;
- }
- }
- if (entry != null) {
- chunksToLoad.remove(entry);
- }
- }
- @Overwrite
- public static void tick () {
- if (ticks % 5 == 0) {
- try {
- TSC.WORKER_THREADS_EXECUTOR.invokeAll(chunksToLoad);
- } catch (InterruptedException ex) {
- ex.printStackTrace();
- }
- List<Entry> toRemove = new ArrayList<Entry>();
- chunksToLoad.forEach(e -> {
- if (e.run) {
- e.finish();
- toRemove.add(e);
- }
- });
- chunksToLoad.removeAll(toRemove);
- }
- ticks++;
- }
- private static class Entry implements Callable<Void> {
- private World w;
- private AnvilChunkLoader loader;
- private ChunkProviderServer provider;
- private int x;
- private int z;
- private List<Runnable> callbacks = new ArrayList<Runnable>();
- private boolean run;
- private Chunk c;
- private NBTTagCompound nbt;
- private Entry (World w, AnvilChunkLoader loader, ChunkProviderServer provider, int x, int z) {
- this.w = w;
- this.loader = loader;
- this.provider = provider;
- this.x = x;
- this.z = z;
- }
- private void runCallbacks () {
- this.callbacks.forEach(Runnable::run);
- }
- private void finish () {
- if (this.c == null) {
- this.runCallbacks();
- return;
- }
- // Load Entities
- this.loader.loadEntities(this.w, this.nbt.getCompoundTag("Level"), this.c);
- MinecraftForge.EVENT_BUS.post(new ChunkDataEvent.Load(this.c, this.nbt)); // Don't call ChunkDataEvent.Load async
- this.c.setLastSaveTime(provider.world.getTotalWorldTime());
- this.provider.chunkGenerator.recreateStructures(this.c, this.x, this.z);
- provider.id2ChunkMap.put(ChunkPos.asLong(this.x, this.z), this.c);
- this.c.onLoad();
- this.c.populate(provider, provider.chunkGenerator);
- this.runCallbacks();
- }
- @Override
- public Void call() throws Exception {
- try {
- Object[] data = null;
- try {
- data = this.loader.loadChunk__Async(this.w, this.x, this.z);
- } catch (IOException e) {
- throw new RuntimeException(e); // Allow exception to bubble up to afterExecute
- }
- if (data != null) {
- this.nbt = (NBTTagCompound)data[1];
- this.c = (Chunk)data[0];
- }
- } finally {
- this.run = true;
- }
- return null;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment