From dfa9f2d1a2ed96d29b5483dbbd627c9ee36af3e6 Mon Sep 17 00:00:00 2001 From: Player Date: Wed, 23 Apr 2014 01:49:07 +0200 Subject: [PATCH] Registry: Misc tweaks --- .../main/java/cpw/mods/fml/common/FMLLog.java | 5 + .../FMLControlledNamespacedRegistry.java | 49 +++++---- .../mods/fml/common/registry/GameData.java | 104 +++++++++++++----- .../fml/common/registry/GameRegistry.java | 34 ++++-- 4 files changed, 133 insertions(+), 59 deletions(-) diff --git a/fml/src/main/java/cpw/mods/fml/common/FMLLog.java b/fml/src/main/java/cpw/mods/fml/common/FMLLog.java index 863ab49ea..462fa86a8 100644 --- a/fml/src/main/java/cpw/mods/fml/common/FMLLog.java +++ b/fml/src/main/java/cpw/mods/fml/common/FMLLog.java @@ -47,8 +47,13 @@ public class FMLLog public static void bigWarning(String format, Object... data) { + StackTraceElement[] trace = Thread.currentThread().getStackTrace(); log(Level.WARN, "****************************************"); log(Level.WARN, "* "+format, data); + for (int i = 2; i < 8 && i < trace.length; i++) + { + log(Level.WARN, "* at %s%s", trace[i].toString(), i == 7 ? "..." : ""); + } log(Level.WARN, "****************************************"); } diff --git a/fml/src/main/java/cpw/mods/fml/common/registry/FMLControlledNamespacedRegistry.java b/fml/src/main/java/cpw/mods/fml/common/registry/FMLControlledNamespacedRegistry.java index 6c27d1cea..72d338b9f 100644 --- a/fml/src/main/java/cpw/mods/fml/common/registry/FMLControlledNamespacedRegistry.java +++ b/fml/src/main/java/cpw/mods/fml/common/registry/FMLControlledNamespacedRegistry.java @@ -10,7 +10,9 @@ import java.util.Map; import net.minecraft.util.ObjectIntIdentityMap; import net.minecraft.util.RegistryNamespaced; +import com.google.common.base.Function; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Iterables; import cpw.mods.fml.common.FMLLog; import cpw.mods.fml.common.Loader; @@ -50,7 +52,7 @@ public class FMLControlledNamespacedRegistry extends RegistryNamespaced { underlyingIntegerMap = new ObjectIntIdentityMap(); registryObjects.clear(); - for (I thing : (Iterable) registry) + for (I thing : registry.typeSafeIterable()) { addObjectRaw(registry.getId(thing), registry.getNameForObject(thing), thing); } @@ -80,12 +82,13 @@ public class FMLControlledNamespacedRegistry extends RegistryNamespaced { public void putObject(Object objName, Object obj) { String name = (String) objName; - I thing = (I) obj; + I thing = superType.cast(obj); if (name == null) throw new NullPointerException("Can't use a null-name for the registry."); if (name.isEmpty()) throw new IllegalArgumentException("Can't use an empty name for the registry."); if (thing == null) throw new NullPointerException("Can't add null-object to the registry."); + name = ensureNamespaced(name); String existingName = getNameForObject(thing); if (existingName == null) @@ -249,12 +252,17 @@ public class FMLControlledNamespacedRegistry extends RegistryNamespaced { return containsKey(itemName); } + public Iterable typeSafeIterable() + { + return Iterables.transform(this, new TypeCastFunction()); + } + // internal @SuppressWarnings("unchecked") public void serializeInto(Map idMapping) // for saving { - for (I thing : (Iterable) this) + for (I thing : this.typeSafeIterable()) { idMapping.put(discriminator+getNameForObject(thing), getId(thing)); } @@ -276,9 +284,10 @@ public class FMLControlledNamespacedRegistry extends RegistryNamespaced { */ int add(int id, String name, I thing, BitSet availabilityMap) { - if (name == null) throw new NullPointerException("Can't use a null-name for the registry."); - if (name.isEmpty()) throw new IllegalArgumentException("Can't use an empty name for the registry."); - if (thing == null) throw new NullPointerException("Can't add null-object to the registry."); + if (name == null) throw new NullPointerException(String.format("Can't use a null-name for the registry, object %s.", thing)); + if (name.isEmpty()) throw new IllegalArgumentException(String.format("Can't use an empty name for the registry, object %s.", thing)); + if (name.indexOf(':') == -1) throw new IllegalArgumentException(String.format("Can't add the name (%s) without a prefix, object %s", name, thing)); + if (thing == null) throw new NullPointerException(String.format("Can't add null-object to the registry, name %s.", name)); if (name.equals(optionalDefaultName)) { this.optionalDefaultObject = thing; @@ -294,14 +303,6 @@ public class FMLControlledNamespacedRegistry extends RegistryNamespaced { throw new RuntimeException(String.format("Invalid id %d - maximum id range exceeded.", idToUse)); } - ModContainer mc = Loader.instance().activeModContainer(); - if (mc != null) - { - String prefix = mc.getModId(); - if (name.contains(":")) FMLLog.bigWarning("Illegal extra prefix %s for name %s, invalid registry invocation/invalid name?", prefix, name); - name = prefix + ":"+ name; - } - if (getRaw(name) == thing) // already registered, return prev registration's id { FMLLog.bigWarning("The object %s has been registered twice for the same name %s.", thing, name); @@ -337,7 +338,7 @@ public class FMLControlledNamespacedRegistry extends RegistryNamespaced { { Map ret = new HashMap(); - for (I thing : (Iterable) this) + for (I thing : this.typeSafeIterable()) { if (!registry.field_148758_b.containsKey(thing)) ret.put(getNameForObject(thing), getId(thing)); } @@ -350,7 +351,7 @@ public class FMLControlledNamespacedRegistry extends RegistryNamespaced { { List ids = new ArrayList(); - for (I thing : (Iterable) this) + for (I thing : this.typeSafeIterable()) { ids.add(getId(thing)); } @@ -370,10 +371,20 @@ public class FMLControlledNamespacedRegistry extends RegistryNamespaced { */ private void addObjectRaw(int id, String name, I thing) { - if (name == null) throw new NullPointerException("internal registry bug"); - if (thing == null) throw new NullPointerException("internal registry bug"); + if (name == null) throw new NullPointerException("The name to be added to the registry is null. This can only happen with a corrupted registry state. Reflection/ASM hackery? Registry bug?"); + if (thing == null) throw new NullPointerException("The object to be added to the registry is null. This can only happen with a corrupted registry state. Reflection/ASM hackery? Registry bug?"); + if (!superType.isInstance(thing)) throw new IllegalArgumentException("The object to be added to the registry is not of the right type. Reflection/ASM hackery? Registry bug?"); underlyingIntegerMap.func_148746_a(thing, id); // obj <-> id - super.putObject(ensureNamespaced(name), thing); // name <-> obj + super.putObject(name, thing); // name <-> obj + } + + private class TypeCastFunction implements Function + { + @Override + public I apply(Object o) + { + return superType.cast(o); + } } } diff --git a/fml/src/main/java/cpw/mods/fml/common/registry/GameData.java b/fml/src/main/java/cpw/mods/fml/common/registry/GameData.java index 49d4497b3..5f679c400 100644 --- a/fml/src/main/java/cpw/mods/fml/common/registry/GameData.java +++ b/fml/src/main/java/cpw/mods/fml/common/registry/GameData.java @@ -64,12 +64,12 @@ public class GameData { private static final GameData mainData = new GameData(); /** - * @deprecated use {@link getBlockRegistry()} instead. + * @deprecated use {@link #getBlockRegistry()} instead. */ @Deprecated public static final FMLControlledNamespacedRegistry blockRegistry = getBlockRegistry(); /** - * @deprecated use {@link getItemRegistry()} instead. + * @deprecated use {@link #getItemRegistry()} instead. */ @Deprecated public static final FMLControlledNamespacedRegistry itemRegistry = getItemRegistry(); @@ -460,8 +460,14 @@ public class GameData { } // register - FMLControlledNamespacedRegistry srcRegistry = isBlock ? getMain().iBlockRegistry : getMain().iItemRegistry; - currId = newData.register(srcRegistry.getRaw(itemName), itemName, newId); + if (isBlock) + { + currId = newData.registerBlock(getMain().iBlockRegistry.getRaw(itemName), itemName, newId); + } + else + { + currId = newData.registerItem(getMain().iItemRegistry.getRaw(itemName), itemName, newId); + } if (currId != newId) { @@ -501,11 +507,11 @@ public class GameData { if (isBlock) { - newId = newData.registerBlock(frozen.iBlockRegistry.getRaw(itemName), itemName, null, currId); + newId = newData.registerBlock(frozen.iBlockRegistry.getRaw(itemName), itemName, currId); } else { - newId = newData.registerItem(frozen.iItemRegistry.getRaw(itemName), itemName, null, currId); + newId = newData.registerItem(frozen.iItemRegistry.getRaw(itemName), itemName, currId); } FMLLog.info("Injected new block/item %s: %d (init) -> %d (map).", itemName, currId, newId); @@ -551,7 +557,7 @@ public class GameData { newName = getMain().iBlockRegistry.getNameForObject(remap.getTarget()); FMLLog.fine("The Block %s is being remapped to %s.", remap.name, newName); - newId = gameData.registerBlock((Block) remap.getTarget(), newName, null, remap.id); + newId = gameData.registerBlock((Block) remap.getTarget(), newName, remap.id); gameData.iBlockRegistry.addAlias(remap.name, newName); } else @@ -560,7 +566,7 @@ public class GameData { newName = getMain().iItemRegistry.getNameForObject(remap.getTarget()); FMLLog.fine("The Item %s is being remapped to %s.", remap.name, newName); - newId = gameData.registerItem((Item) remap.getTarget(), newName, null, remap.id); + newId = gameData.registerItem((Item) remap.getTarget(), newName, remap.id); gameData.iItemRegistry.addAlias(remap.name, newName); } @@ -703,15 +709,18 @@ public class GameData { blockedIds.addAll(data.blockedIds); } - int register(Object obj, String name, int idHint) + int register(Object obj, String name, int idHint) // from FMLControlledNamespacedRegistry.addObject { + // tolerate extra name prefixes here since mc does it as well + name = addPrefix(name); + if (obj instanceof Block) { - return registerBlock((Block) obj, name, null, idHint); + return registerBlock((Block) obj, name, idHint); } else if (obj instanceof Item) { - return registerItem((Item) obj, name, null, idHint); + return registerItem((Item) obj, name, idHint); } else { @@ -719,18 +728,17 @@ public class GameData { } } - int registerItem(Item item, String name, String modId) + int registerItem(Item item, String name) // from GameRegistry { - return registerItem(item, name, modId, -1); + int index = name.indexOf(':'); + if (name.indexOf(':') != -1) FMLLog.bigWarning("Illegal extra prefix %s for name %s, invalid registry invocation/invalid name?", name.substring(0, index), name); + + name = addPrefix(name); + return registerItem(item, name, -1); } - int registerItem(Item item, String name, String modId, int idHint) + private int registerItem(Item item, String name, int idHint) { - if (modId != null) - { - ModContainer mc = Loader.instance().activeModContainer(); - customOwners.put(new UniqueIdentifier(modId, name), mc); - } if (item instanceof ItemBlock) // ItemBlock, adjust id and clear the slot already occupied by the corresponding block { Block block = ((ItemBlock) item).field_150939_a; @@ -772,23 +780,21 @@ public class GameData { return itemId; } - int registerBlock(Block block, String name, String modId) + int registerBlock(Block block, String name) // from GameRegistry { - return registerBlock(block, name, modId, -1); + int index = name.indexOf(':'); + if (name.indexOf(':') != -1) FMLLog.bigWarning("Illegal extra prefix %s for name %s, invalid registry invocation/invalid name?", name.substring(0, index), name); + + name = addPrefix(name); + return registerBlock(block, name, -1); } - int registerBlock(Block block, String name, String modId, int idHint) + private int registerBlock(Block block, String name, int idHint) { - if (modId != null) - { - ModContainer mc = Loader.instance().activeModContainer(); - customOwners.put(new UniqueIdentifier(modId, name), mc); - } - // handle ItemBlock-before-Block registrations ItemBlock itemBlock = null; - for (Item item : (Iterable) iItemRegistry) // find matching ItemBlock + for (Item item : iItemRegistry.typeSafeIterable()) // find matching ItemBlock { if (item instanceof ItemBlock && ((ItemBlock) item).field_150939_a == block) { @@ -854,6 +860,42 @@ public class GameData { availabilityMap.clear(id); } + /** + * Prefix the supplied name with the current mod id. + * + * If no mod id can be determined, minecraft will be assumed. + * The prefix is separated with a colon. + * + * If there's already a prefix, it'll be prefixed again if the new prefix + * doesn't match the old prefix, as used by vanilla calls to addObject. + * + * @param name name to prefix. + * @return prefixed name. + */ + private String addPrefix(String name) + { + int index = name.lastIndexOf(':'); + String oldPrefix = index == -1 ? "" : name.substring(0, index); + String prefix; + ModContainer mc = Loader.instance().activeModContainer(); + + if (mc != null) + { + prefix = mc.getModId(); + } + else // no mod container, assume minecraft + { + prefix = "minecraft"; + } + + if (!oldPrefix.equals(prefix)) + { + name = prefix + ":" + name; + } + + return name; + } + private void verifyItemBlockName(ItemBlock item) { String blockName = iBlockRegistry.getNameForObject(item.field_150939_a); @@ -896,6 +938,10 @@ public class GameData { if (id > (isBlock ? MAX_BLOCK_ID : MAX_ITEM_ID)) throw new IllegalStateException(String.format("Registry entry for %s %s, name %s uses the too large id %d.", type, obj, name)); // name lookup failed -> obj is not in the obj<->name map if (name == null) throw new IllegalStateException(String.format("Registry entry for %s %s, id %d, doesn't yield a name.", type, obj, id)); + // empty name + if (name.isEmpty()) throw new IllegalStateException(String.format("Registry entry for %s %s, id %d, yields an empty name.", type, obj, id)); + // non-prefixed name + if (name.indexOf(':') == -1) throw new IllegalStateException(String.format("Registry entry for %s %s, id %d, has the non-prefixed name %s.", type, obj, id, name)); // id -> obj lookup is inconsistent if (registry.getRaw(id) != obj) throw new IllegalStateException(String.format("Registry entry for id %d, name %s, doesn't yield the expected %s %s.", id, name, type, obj)); // name -> obj lookup is inconsistent diff --git a/fml/src/main/java/cpw/mods/fml/common/registry/GameRegistry.java b/fml/src/main/java/cpw/mods/fml/common/registry/GameRegistry.java index 909d867a3..da0352db8 100644 --- a/fml/src/main/java/cpw/mods/fml/common/registry/GameRegistry.java +++ b/fml/src/main/java/cpw/mods/fml/common/registry/GameRegistry.java @@ -61,7 +61,7 @@ public class GameRegistry * Register a world generator - something that inserts new block types into the world * * @param generator the generator - * @param weight a weight to assign to this generator. Heavy weights tend to sink to the bottom of + * @param modGenerationWeight a weight to assign to this generator. Heavy weights tend to sink to the bottom of * list of world generators (i.e. they run later) */ public static void registerWorldGenerator(IWorldGenerator generator, int modGenerationWeight) @@ -131,12 +131,12 @@ public class GameRegistry * Register the specified Item with a mod specific name : overrides the standard type based name * @param item The item to register * @param name The mod-unique name to register it as - null will remove a custom name - * @param modId An optional modId that will "own" this block - generally used by multi-mod systems + * @param modId deprecated, unused * where one mod should "own" all the blocks of all the mods, null defaults to the active mod */ public static Item registerItem(Item item, String name, String modId) { - GameData.getMain().registerItem(item, name, modId); + GameData.getMain().registerItem(item, name); return item; } @@ -145,33 +145,45 @@ public class GameRegistry { } + /** * Register a block with the specified mod specific name * @param block The block to register - * @param name The mod-unique name to register it as + * @param name The mod-unique name to register it as, will get prefixed by your modid. */ public static Block registerBlock(Block block, String name) { return registerBlock(block, ItemBlock.class, name); } + /** * Register a block with the world, with the specified item class and block name * @param block The block to register * @param itemclass The item type to register with it : null registers a block without associated item. - * @param name The mod-unique name to register it with + * @param name The mod-unique name to register it as, will get prefixed by your modid. */ public static Block registerBlock(Block block, Class itemclass, String name) { - return registerBlock(block, itemclass, name, null); + return registerBlock(block, itemclass, name, new Object[]{}); } + + /** + * @deprecated Use the registerBlock version without the modId parameter instead. + */ + @Deprecated + public static Block registerBlock(Block block, Class itemclass, String name, String modId, Object... itemCtorArgs) + { + return registerBlock(block, itemclass, name, itemCtorArgs); + } + /** * Register a block with the world, with the specified item class, block name and owning modId * @param block The block to register * @param itemclass The item type to register with it : null registers a block without associated item. - * @param name The mod-unique name to register it with - * @param modId The modId that will own the block name. null defaults to the active modId + * @param name The mod-unique name to register it as, will get prefixed by your modid. + * @param itemCtorArgs Arguments to pass to the ItemBlock constructor (optional). */ - public static Block registerBlock(Block block, Class itemclass, String name, String modId, Object... itemCtorArgs) + public static Block registerBlock(Block block, Class itemclass, String name, Object... itemCtorArgs) { if (Loader.instance().isInState(LoaderState.CONSTRUCTING)) { @@ -193,10 +205,10 @@ public class GameRegistry i = itemCtor.newInstance(ObjectArrays.concat(block, itemCtorArgs)); } // block registration has to happen first - GameData.getMain().registerBlock(block, name, modId); + GameData.getMain().registerBlock(block, name); if (i != null) { - GameData.getMain().registerItem(i, name, modId); + GameData.getMain().registerItem(i, name); } return block; }