Check for empty dimensions outside of chunk unloading loop, culling worlds without needing chunk unloads to trigger it. (#4704)
This commit is contained in:
parent
b8e411674b
commit
4c1167c96d
3 changed files with 53 additions and 24 deletions
|
@ -72,7 +72,7 @@
|
||||||
Iterator<Long> iterator = this.field_73248_b.iterator();
|
Iterator<Long> iterator = this.field_73248_b.iterator();
|
||||||
|
|
||||||
for (int i = 0; i < 100 && iterator.hasNext(); iterator.remove())
|
for (int i = 0; i < 100 && iterator.hasNext(); iterator.remove())
|
||||||
@@ -234,10 +267,15 @@
|
@@ -234,6 +267,7 @@
|
||||||
if (chunk != null && chunk.field_189550_d)
|
if (chunk != null && chunk.field_189550_d)
|
||||||
{
|
{
|
||||||
chunk.func_76623_d();
|
chunk.func_76623_d();
|
||||||
|
@ -80,11 +80,12 @@
|
||||||
this.func_73242_b(chunk);
|
this.func_73242_b(chunk);
|
||||||
this.func_73243_a(chunk);
|
this.func_73243_a(chunk);
|
||||||
this.field_73244_f.remove(olong);
|
this.field_73244_f.remove(olong);
|
||||||
++i;
|
@@ -242,6 +276,8 @@
|
||||||
+ if (field_73244_f.size() == 0 && net.minecraftforge.common.ForgeChunkManager.getPersistentChunksFor(this.field_73251_h).size() == 0 && !this.field_73251_h.field_73011_w.func_186058_p().shouldLoadSpawn()){
|
|
||||||
+ net.minecraftforge.common.DimensionManager.unloadWorld(this.field_73251_h.field_73011_w.getDimension());
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ if (this.field_73244_f.isEmpty()) net.minecraftforge.common.DimensionManager.unloadWorld(this.field_73251_h.field_73011_w.getDimension());
|
||||||
|
+
|
||||||
|
this.field_73247_e.func_75817_a();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,9 @@ import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||||
import it.unimi.dsi.fastutil.ints.IntListIterator;
|
import it.unimi.dsi.fastutil.ints.IntListIterator;
|
||||||
import org.apache.logging.log4j.Level;
|
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntSets;
|
||||||
|
|
||||||
import com.google.common.collect.HashMultiset;
|
import com.google.common.collect.HashMultiset;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
@ -50,7 +52,6 @@ import net.minecraft.world.WorldServer;
|
||||||
import net.minecraft.world.WorldServerMulti;
|
import net.minecraft.world.WorldServerMulti;
|
||||||
import net.minecraft.world.storage.ISaveHandler;
|
import net.minecraft.world.storage.ISaveHandler;
|
||||||
import net.minecraftforge.event.world.WorldEvent;
|
import net.minecraftforge.event.world.WorldEvent;
|
||||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
|
||||||
import net.minecraftforge.fml.common.FMLLog;
|
import net.minecraftforge.fml.common.FMLLog;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
@ -68,13 +69,15 @@ public class DimensionManager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Hashtable<Integer, WorldServer> worlds = new Hashtable<Integer, WorldServer>();
|
|
||||||
private static boolean hasInit = false;
|
private static boolean hasInit = false;
|
||||||
private static Hashtable<Integer, Dimension> dimensions = new Hashtable<Integer, Dimension>();
|
|
||||||
private static IntArrayList unloadQueue = new IntArrayList();
|
private static final Hashtable<Integer, WorldServer> worlds = new Hashtable<>();
|
||||||
private static BitSet dimensionMap = new BitSet(Long.SIZE << 4);
|
private static final Hashtable<Integer, Dimension> dimensions = new Hashtable<>();
|
||||||
private static ConcurrentMap<World, World> weakWorldMap = new MapMaker().weakKeys().weakValues().<World,World>makeMap();
|
private static final IntSet keepLoaded = IntSets.synchronize(new IntOpenHashSet());
|
||||||
private static Multiset<Integer> leakedWorlds = HashMultiset.create();
|
private static final IntArrayList unloadQueue = new IntArrayList();
|
||||||
|
private static final BitSet dimensionMap = new BitSet(Long.SIZE << 4);
|
||||||
|
private static final ConcurrentMap<World, World> weakWorldMap = new MapMaker().weakKeys().weakValues().makeMap();
|
||||||
|
private static final Multiset<Integer> leakedWorlds = HashMultiset.create();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of dimensions associated with this DimensionType.
|
* Returns a list of dimensions associated with this DimensionType.
|
||||||
|
@ -299,13 +302,35 @@ public class DimensionManager
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Queues a dimension to unload.
|
* Sets if a dimension should stay loaded.
|
||||||
* If the dimension is already queued, it will reset the delay to unload
|
* @param dim the dimension ID
|
||||||
|
* @param keep whether or not the dimension should be kept loaded
|
||||||
|
* @return true iff the dimension's status changed
|
||||||
|
*/
|
||||||
|
public static boolean keepDimensionLoaded(int dim, boolean keep)
|
||||||
|
{
|
||||||
|
return keep ? keepLoaded.add(dim) : keepLoaded.remove(dim);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean canUnloadWorld(WorldServer world)
|
||||||
|
{
|
||||||
|
return ForgeChunkManager.getPersistentChunksFor(world).isEmpty()
|
||||||
|
&& world.playerEntities.isEmpty()
|
||||||
|
&& !world.provider.getDimensionType().shouldLoadSpawn()
|
||||||
|
&& !keepLoaded.contains(world.provider.getDimension());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queues a dimension to unload, if it can be unloaded.
|
||||||
|
* If the dimension is already queued, it will reset the delay to unload.
|
||||||
* @param id The id of the dimension
|
* @param id The id of the dimension
|
||||||
*/
|
*/
|
||||||
public static void unloadWorld(int id)
|
public static void unloadWorld(int id)
|
||||||
{
|
{
|
||||||
if(!unloadQueue.contains(id))
|
WorldServer world = worlds.get(id);
|
||||||
|
if (world == null || !canUnloadWorld(world)) return;
|
||||||
|
|
||||||
|
if (!unloadQueue.contains(id))
|
||||||
{
|
{
|
||||||
FMLLog.log.debug("Queueing dimension {} to unload", id);
|
FMLLog.log.debug("Queueing dimension {} to unload", id);
|
||||||
unloadQueue.add(id);
|
unloadQueue.add(id);
|
||||||
|
@ -337,7 +362,8 @@ public class DimensionManager
|
||||||
WorldServer w = worlds.get(id);
|
WorldServer w = worlds.get(id);
|
||||||
queueIterator.remove();
|
queueIterator.remove();
|
||||||
dimension.ticksWaited = 0;
|
dimension.ticksWaited = 0;
|
||||||
if (w == null || !ForgeChunkManager.getPersistentChunksFor(w).isEmpty() || !w.playerEntities.isEmpty() || dimension.type.shouldLoadSpawn()) //Don't unload the world if the status changed
|
// Don't unload the world if the status changed
|
||||||
|
if (w == null || !canUnloadWorld(w))
|
||||||
{
|
{
|
||||||
FMLLog.log.debug("Aborting unload for dimension {} as status changed", id);
|
FMLLog.log.debug("Aborting unload for dimension {} as status changed", id);
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -41,7 +41,7 @@ public class ChunkGenWorker implements IWorker
|
||||||
private final int notificationFrequency;
|
private final int notificationFrequency;
|
||||||
private int lastNotification = 0;
|
private int lastNotification = 0;
|
||||||
private int genned = 0;
|
private int genned = 0;
|
||||||
private Boolean loadSpawn;
|
private Boolean keepingLoaded;
|
||||||
|
|
||||||
public ChunkGenWorker(ICommandSender listener, BlockPos start, int total, int dim, int interval)
|
public ChunkGenWorker(ICommandSender listener, BlockPos start, int total, int dim, int interval)
|
||||||
{
|
{
|
||||||
|
@ -116,10 +116,9 @@ public class ChunkGenWorker implements IWorker
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// While we work we don't want to cause world load spam so pause unloading the world.
|
// While we work we don't want to cause world load spam so pause unloading the world.
|
||||||
if (loadSpawn == null)
|
if (keepingLoaded == null)
|
||||||
{
|
{
|
||||||
loadSpawn = world.provider.getDimensionType().shouldLoadSpawn();
|
keepingLoaded = DimensionManager.keepDimensionLoaded(dim, true);
|
||||||
world.provider.getDimensionType().setLoadSpawn(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (++lastNotification >= notificationFrequency)
|
if (++lastNotification >= notificationFrequency)
|
||||||
|
@ -159,7 +158,10 @@ public class ChunkGenWorker implements IWorker
|
||||||
if (queue.size() == 0)
|
if (queue.size() == 0)
|
||||||
{
|
{
|
||||||
listener.sendMessage(TextComponentHelper.createComponentTranslation(listener, "commands.forge.gen.complete", genned, total, dim));
|
listener.sendMessage(TextComponentHelper.createComponentTranslation(listener, "commands.forge.gen.complete", genned, total, dim));
|
||||||
DimensionManager.getProviderType(dim).setLoadSpawn(loadSpawn);
|
if (keepingLoaded != null && keepingLoaded)
|
||||||
|
{
|
||||||
|
DimensionManager.keepDimensionLoaded(dim, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue