Some changes to the ForgeChunkManager.
Null modData is allowed now. The entity id is actually properly persisted in the ticket now. There is a new "orderedLoadingCallback" that allows you to provide a preferred ticket loading order in case of "excess tickets". Also, tickets that are not in the returned list are now unregistered. There is a way to resort the chunks in the forced chunklist on a ticket now. Log the dormant cache configuration
This commit is contained in:
parent
021bbad2b5
commit
595d3e9e79
1 changed files with 84 additions and 16 deletions
|
@ -90,13 +90,42 @@ public class ForgeChunkManager
|
|||
{
|
||||
/**
|
||||
* Called back when tickets are loaded from the world to allow the
|
||||
* mod to re-register the chunks associated with those tickets
|
||||
* mod to re-register the chunks associated with those tickets. The list supplied
|
||||
* here is truncated to length prior to use. Tickets unwanted by the
|
||||
* mod must be disposed of manually.
|
||||
*
|
||||
* @param tickets
|
||||
* @param world
|
||||
*/
|
||||
public void ticketsLoaded(List<Ticket> tickets, World world);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a special LoadingCallback that can be implemented as well as the
|
||||
* LoadingCallback to provide access to additional behaviour.
|
||||
* Specifically, this callback will fire prior to Forge dropping excess
|
||||
* tickets. Tickets in the returned list are presumed ordered and excess will
|
||||
* be truncated from the returned list.
|
||||
* This allows the mod to control not only if they actually <em>want</em> a ticket but
|
||||
* also their preferred ticket ordering.
|
||||
*
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public interface OrderedLoadingCallback extends LoadingCallback
|
||||
{
|
||||
/**
|
||||
* Called back when tickets are loaded from the world to allow the
|
||||
* mod to re-register the chunks associated with those tickets.
|
||||
*
|
||||
* @param tickets The tickets that your mod should re-register
|
||||
* @param world The world
|
||||
* @param maxTicketCount The maximum number of tickets that will be allowed.
|
||||
* @return A list of the tickets this mod wishes to continue using. This list will be truncated
|
||||
* to "maxTicketCount" size after the call returns.
|
||||
*/
|
||||
public List<Ticket> ticketsLoaded(List<Ticket> tickets, World world, int maxTicketCount);
|
||||
}
|
||||
public enum Type
|
||||
{
|
||||
|
||||
|
@ -139,9 +168,9 @@ public class ForgeChunkManager
|
|||
*/
|
||||
public void setChunkListDepth(int depth)
|
||||
{
|
||||
if (depth > getMaxChunkDepthFor(modId))
|
||||
if (depth > getMaxChunkDepthFor(modId) || (depth <= 0 && getMaxChunkDepthFor(modId) > 0))
|
||||
{
|
||||
FMLLog.warning("The mod %s tried to modify the chunk ticket depth to: %d, greater than it's maximum: %d", modId, depth, getMaxChunkDepthFor(modId));
|
||||
FMLLog.warning("The mod %s tried to modify the chunk ticket depth to: %d, its allowed maximum is: %d", modId, depth, getMaxChunkDepthFor(modId));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -246,21 +275,17 @@ public class ForgeChunkManager
|
|||
continue;
|
||||
}
|
||||
|
||||
int maxTicketLength = getMaxTicketLengthFor(modId);
|
||||
|
||||
NBTTagList tickets = ticketHolder.getTagList("Tickets");
|
||||
if (tickets.tagCount() > maxTicketLength)
|
||||
{
|
||||
FMLLog.warning("The mod %s has more tickets in to load than it is allowed. Only the first %d will be loaded - the rest will be removed", modId, maxTicketLength);
|
||||
}
|
||||
for (int j = 0; j < Math.min(tickets.tagCount(), maxTicketLength); j++)
|
||||
for (int j = 0; j < tickets.tagCount(); j++)
|
||||
{
|
||||
NBTTagCompound ticket = (NBTTagCompound) tickets.tagAt(j);
|
||||
Type type = Type.values()[ticket.getByte("Type")];
|
||||
byte ticketChunkDepth = ticket.getByte("ChunkListDepth");
|
||||
NBTTagCompound modData = ticket.getCompoundTag("ModData");
|
||||
Ticket tick = new Ticket(modId, type, world);
|
||||
tick.modData = modData;
|
||||
if (ticket.hasKey("ModData"))
|
||||
{
|
||||
tick.modData = ticket.getCompoundTag("ModData");
|
||||
}
|
||||
if (type == Type.ENTITY)
|
||||
{
|
||||
tick.entityChunkX = ticket.getInteger("chunkX");
|
||||
|
@ -295,7 +320,29 @@ public class ForgeChunkManager
|
|||
// send callbacks
|
||||
for (String modId : loadedTickets.keySet())
|
||||
{
|
||||
callbacks.get(modId).ticketsLoaded(loadedTickets.get(modId), world);
|
||||
LoadingCallback loadingCallback = callbacks.get(modId);
|
||||
int maxTicketLength = getMaxTicketLengthFor(modId);
|
||||
List<Ticket> tickets = loadedTickets.get(modId);
|
||||
if (loadingCallback instanceof OrderedLoadingCallback)
|
||||
{
|
||||
OrderedLoadingCallback orderedLoadingCallback = (OrderedLoadingCallback) loadingCallback;
|
||||
tickets = orderedLoadingCallback.ticketsLoaded(tickets, world, maxTicketLength);
|
||||
if (tickets.size() > maxTicketLength)
|
||||
{
|
||||
FMLLog.warning("The mod %s has too many open chunkloading tickets %d. Excess will be dropped", modId, tickets.size());
|
||||
tickets.subList(maxTicketLength, tickets.size()).clear();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tickets.size() > maxTicketLength)
|
||||
{
|
||||
FMLLog.warning("The mod %s has too many open chunkloading tickets %d. Excess will be dropped", modId, tickets.size());
|
||||
tickets.subList(maxTicketLength, tickets.size()).clear();
|
||||
}
|
||||
loadingCallback.ticketsLoaded(tickets, world);
|
||||
}
|
||||
ForgeChunkManager.tickets.get(world).putAll(modId, tickets);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -441,6 +488,23 @@ public class ForgeChunkManager
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reorganize the internal chunk list so that the chunk supplied is at the *end* of the list
|
||||
* This helps if you wish to guarantee a certain "automatic unload ordering" for the chunks
|
||||
* in the ticket list
|
||||
*
|
||||
* @param ticket The ticket holding the chunk list
|
||||
* @param chunk The chunk you wish to push to the end (so that it would be unloaded last)
|
||||
*/
|
||||
public static void reorderChunk(Ticket ticket, ChunkCoordIntPair chunk)
|
||||
{
|
||||
if (ticket == null || chunk == null || !ticket.requestedChunks.contains(chunk))
|
||||
{
|
||||
return;
|
||||
}
|
||||
ticket.requestedChunks.remove(chunk);
|
||||
ticket.requestedChunks.add(chunk);
|
||||
}
|
||||
/**
|
||||
* Unforce the supplied chunk, allowing it to be unloaded and stop ticking.
|
||||
*
|
||||
|
@ -479,6 +543,7 @@ public class ForgeChunkManager
|
|||
dormantChunkCacheSize.comment = "Unloaded chunks can first be kept in a dormant cache for quicker\n" +
|
||||
"loading times. Specify the size of that cache here";
|
||||
dormantChunkCache = CacheBuilder.newBuilder().maximumSize(dormantChunkCacheSize.getInt(0)).build();
|
||||
FMLLog.info("Configured a dormant chunk cache size of %d", dormantChunkCacheSize.getInt(0));
|
||||
|
||||
Property modOverridesEnabled = config.getOrCreateBooleanProperty("enabled", "defaults", true);
|
||||
modOverridesEnabled.comment = "Are mod overrides enabled?";
|
||||
|
@ -549,13 +614,16 @@ public class ForgeChunkManager
|
|||
tickets.appendTag(ticket);
|
||||
ticket.setByte("Type", (byte) tick.ticketType.ordinal());
|
||||
ticket.setByte("ChunkListDepth", (byte) tick.maxDepth);
|
||||
ticket.setCompoundTag("ModData", tick.modData);
|
||||
if (tick.modData != null)
|
||||
{
|
||||
ticket.setCompoundTag("ModData", tick.modData);
|
||||
}
|
||||
if (tick.ticketType == Type.ENTITY)
|
||||
{
|
||||
ticket.setInteger("chunkX", MathHelper.floor_double(tick.entity.chunkCoordX));
|
||||
ticket.setInteger("chunkZ", MathHelper.floor_double(tick.entity.chunkCoordZ));
|
||||
ticket.setLong("persistentIDMSB", tick.entity.getPersistentID().getMostSignificantBits());
|
||||
ticket.setLong("persistentIDLSB", tick.entity.getPersistentID().getLeastSignificantBits());
|
||||
ticket.setLong("PersistentIDMSB", tick.entity.getPersistentID().getMostSignificantBits());
|
||||
ticket.setLong("PersistentIDLSB", tick.entity.getPersistentID().getLeastSignificantBits());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue