From a776afe1bf693bf797d876267adde1a1f7274d48 Mon Sep 17 00:00:00 2001 From: Christian Date: Mon, 24 Sep 2012 22:07:39 -0400 Subject: [PATCH] More modifications to the ticket callback handling system. There are up to two callbacks during world loading now. One to allow selective preference for ticket types. The other to actually allow the mod to force chunks. --- .../common/ForgeChunkManager.java | 45 +++++++++++-------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/common/net/minecraftforge/common/ForgeChunkManager.java b/common/net/minecraftforge/common/ForgeChunkManager.java index fe1657d09..6968a0eee 100644 --- a/common/net/minecraftforge/common/ForgeChunkManager.java +++ b/common/net/minecraftforge/common/ForgeChunkManager.java @@ -18,6 +18,7 @@ import com.google.common.cache.CacheBuilder; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSetMultimap; import com.google.common.collect.LinkedHashMultimap; @@ -92,10 +93,11 @@ 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. The list supplied * here is truncated to length prior to use. Tickets unwanted by the - * mod must be disposed of manually. + * mod must be disposed of manually unless the mod is an OrderedLoadingCallback instance + * in which case, they will have been disposed of by the earlier callback. * - * @param tickets - * @param world + * @param tickets The tickets to re-register. The list is immutable and cannot be manipulated directly. Copy it first. + * @param world the world */ public void ticketsLoaded(List tickets, World world); } @@ -116,13 +118,17 @@ 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 decide if it wants the ticket still, and prioritise overflow + * based on the ticket count. + * WARNING: You cannot force chunks in this callback, it is strictly for allowing the mod + * to be more selective in which tickets it wishes to preserve in an overflow situation * - * @param tickets The tickets that your mod should re-register + * @param tickets The tickets that you will want to select from. The list is immutable and cannot be manipulated directly. Copy it first. * @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. + * to "maxTicketCount" size after the call returns and then offered to the other callback + * method */ public List ticketsLoaded(List tickets, World world, int maxTicketCount); } @@ -326,23 +332,15 @@ public class ForgeChunkManager 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(); - } + tickets = orderedLoadingCallback.ticketsLoaded(ImmutableList.copyOf(tickets), world, maxTicketLength); } - else + if (tickets.size() > 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(); - } - loadingCallback.ticketsLoaded(tickets, world); + 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(); } ForgeChunkManager.tickets.get(world).putAll(modId, tickets); + loadingCallback.ticketsLoaded(ImmutableList.copyOf(tickets), world); } } } @@ -451,6 +449,10 @@ public class ForgeChunkManager { return; } + if (!tickets.get(ticket.world).containsEntry(ticket.modId, ticket)) + { + return; + } if (ticket.requestedChunks!=null) { for (ChunkCoordIntPair chunk : ImmutableSet.copyOf(ticket.requestedChunks)) @@ -479,6 +481,11 @@ public class ForgeChunkManager { throw new RuntimeException("Attempted to use an entity ticket to force a chunk, without an entity"); } + if (!tickets.get(ticket.world).containsEntry(ticket.modId, ticket)) + { + FMLLog.severe("The mod %s attempted to force load a chunk with an invalid ticket. This is not permitted.", ticket.modId); + return; + } ticket.requestedChunks.add(chunk); forcedChunks.get(ticket.world).put(chunk, ticket); if (ticket.maxDepth > 0 && ticket.requestedChunks.size() > ticket.maxDepth)