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
|
@ -72,7 +72,7 @@
|
|||
Iterator<Long> iterator = this.field_73248_b.iterator();
|
||||
|
||||
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)
|
||||
{
|
||||
chunk.func_76623_d();
|
||||
|
@ -80,11 +80,12 @@
|
|||
this.func_73242_b(chunk);
|
||||
this.func_73243_a(chunk);
|
||||
this.field_73244_f.remove(olong);
|
||||
++i;
|
||||
+ 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;
|
||||
+ }
|
||||
}
|
||||
@@ -242,6 +276,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ 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.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.Lists;
|
||||
|
@ -50,7 +52,6 @@ import net.minecraft.world.WorldServer;
|
|||
import net.minecraft.world.WorldServerMulti;
|
||||
import net.minecraft.world.storage.ISaveHandler;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
import net.minecraftforge.fml.common.FMLLog;
|
||||
|
||||
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 Hashtable<Integer, Dimension> dimensions = new Hashtable<Integer, Dimension>();
|
||||
private static IntArrayList unloadQueue = new IntArrayList();
|
||||
private static BitSet dimensionMap = new BitSet(Long.SIZE << 4);
|
||||
private static ConcurrentMap<World, World> weakWorldMap = new MapMaker().weakKeys().weakValues().<World,World>makeMap();
|
||||
private static Multiset<Integer> leakedWorlds = HashMultiset.create();
|
||||
|
||||
private static final Hashtable<Integer, WorldServer> worlds = new Hashtable<>();
|
||||
private static final Hashtable<Integer, Dimension> dimensions = new Hashtable<>();
|
||||
private static final IntSet keepLoaded = IntSets.synchronize(new IntOpenHashSet());
|
||||
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.
|
||||
|
@ -299,13 +302,35 @@ public class DimensionManager
|
|||
}
|
||||
|
||||
/**
|
||||
* Queues a dimension to unload.
|
||||
* If the dimension is already queued, it will reset the delay to unload
|
||||
* Sets if a dimension should stay loaded.
|
||||
* @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
|
||||
*/
|
||||
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);
|
||||
unloadQueue.add(id);
|
||||
|
@ -337,7 +362,8 @@ public class DimensionManager
|
|||
WorldServer w = worlds.get(id);
|
||||
queueIterator.remove();
|
||||
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);
|
||||
continue;
|
||||
|
|
|
@ -41,7 +41,7 @@ public class ChunkGenWorker implements IWorker
|
|||
private final int notificationFrequency;
|
||||
private int lastNotification = 0;
|
||||
private int genned = 0;
|
||||
private Boolean loadSpawn;
|
||||
private Boolean keepingLoaded;
|
||||
|
||||
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.
|
||||
if (loadSpawn == null)
|
||||
if (keepingLoaded == null)
|
||||
{
|
||||
loadSpawn = world.provider.getDimensionType().shouldLoadSpawn();
|
||||
world.provider.getDimensionType().setLoadSpawn(true);
|
||||
keepingLoaded = DimensionManager.keepDimensionLoaded(dim, true);
|
||||
}
|
||||
|
||||
if (++lastNotification >= notificationFrequency)
|
||||
|
@ -159,7 +158,10 @@ public class ChunkGenWorker implements IWorker
|
|||
if (queue.size() == 0)
|
||||
{
|
||||
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 New Issue