Search in sources :

Example 1 with IRegistry

use of net.minecraft.util.registry.IRegistry in project FoamFix by asiekierka.

the class Deduplicator method deduplicateObject.

public Object deduplicateObject(Object o, int recursion) {
    if (o == null || recursion > maxRecursion)
        return o;
    Class c = o.getClass();
    if (!shouldCheckClass(c))
        return o;
    if (!deduplicatedObjects.add(o))
        return o;
    boolean canTrim = o instanceof Predicate || TRIM_ARRAYS_CLASSES.contains(c);
    if (canTrim) {
        if (c == SimpleBakedModel.class) {
            for (EnumFacing facing : EnumFacing.VALUES) {
                List l = ((SimpleBakedModel) o).getQuads(null, facing, 0);
                trimArray(l);
            }
        }
    }
    if (o instanceof IBakedModel) {
        if (o instanceof PerspectiveMapWrapper) {
            try {
                Object to = IPAM_MW_TRANSFORMS_GETTER.invoke(o);
                Object toD = deduplicate0(to);
                if (toD != null && to != toD) {
                    IPAM_MW_TRANSFORMS_SETTER.invoke(o, toD);
                }
            } catch (Throwable t) {
                t.printStackTrace();
            }
        } else if ("net.minecraftforge.client.model.BakedItemModel".equals(c.getName())) {
            try {
                Object to = BIM_TRANSFORMS_GETTER.invoke(o);
                Object toD = deduplicate0(to);
                if (toD != null && to != toD) {
                    BIM_TRANSFORMS_SETTER.invoke(o, toD);
                }
            } catch (Throwable t) {
                t.printStackTrace();
            }
        }
    }
    if (c == BlockPartFace.class) {
        ((BlockPartFace) o).blockFaceUV.uvs = (float[]) deduplicate0(((BlockPartFace) o).blockFaceUV.uvs);
        return o;
    }
    if (o instanceof BakedQuad) {
        if (c == BakedQuad.class) {
            if (FoamFixShared.config.expUnpackBakedQuads) {
                BakedQuad quad = (BakedQuad) o;
                UnpackedBakedQuad.Builder builder = new UnpackedBakedQuad.Builder(quad.getFormat());
                quad.pipe(builder);
                o = builder.build();
                c = UnpackedBakedQuad.class;
            }
        }
        if (c == UnpackedBakedQuad.class) {
            try {
                float[][][] array = (float[][][]) FIELD_UNPACKED_DATA_GETTER.invokeExact((UnpackedBakedQuad) o);
                // float[][][]s are not currently deduplicated
                deduplicate0(array);
            } catch (Throwable t) {
                t.printStackTrace();
            }
        }
    } else if (o instanceof ResourceLocation || c == TRSRTransformation.class || c == Style.class) {
        return deduplicate0(o);
    } else if (c == ItemCameraTransforms.class || c == Vec3d.class || c == Vec3i.class || c == BlockPos.class) {
        return deduplicate0(o);
    /* if (d != o)
                return d;
            TODO: Add ItemTransformVec3f dedup, maybe
            return o; */
    } else if (o instanceof Item || o instanceof Block || o instanceof World || o instanceof Entity || o instanceof Logger || o instanceof IRegistry) {
        BLACKLIST_CLASS.add(c);
        return o;
    } else if (o instanceof ItemOverrideList && o != ItemOverrideList.NONE) {
        try {
            List list = (List) IOL_OVERRIDES_GETTER.invokeExact((ItemOverrideList) o);
            if (list.isEmpty()) {
                if (c == ItemOverrideList.class) {
                    successfuls++;
                    return ItemOverrideList.NONE;
                } else if (c == AnimationItemOverrideList.class) {
                    IOL_OVERRIDES_SETTER.invokeExact((ItemOverrideList) o, (List) ImmutableList.of());
                    successfuls++;
                }
            }
        } catch (Throwable t) {
        }
    } else if (o instanceof java.util.Optional) {
        java.util.Optional opt = (java.util.Optional) o;
        if (opt.isPresent()) {
            Object b = deduplicateObject(opt.get(), recursion + 1);
            if (b != null) {
                if (JAVA_OPTIONALS.containsKey(b)) {
                    successfuls++;
                    return JAVA_OPTIONALS.get(b);
                }
                if (b != opt.get()) {
                    java.util.Optional opt2 = java.util.Optional.of(b);
                    JAVA_OPTIONALS.put(b, opt2);
                    return opt2;
                } else {
                    JAVA_OPTIONALS.put(opt.get(), opt);
                    return opt;
                }
            }
        } else {
            return opt;
        }
    } else if (o instanceof com.google.common.base.Optional) {
        Optional opt = (Optional) o;
        if (opt.isPresent()) {
            Object b = deduplicateObject(opt.get(), recursion + 1);
            if (b != null) {
                if (GUAVA_OPTIONALS.containsKey(b)) {
                    successfuls++;
                    return GUAVA_OPTIONALS.get(b);
                }
                if (b != opt.get()) {
                    com.google.common.base.Optional opt2 = com.google.common.base.Optional.of(b);
                    GUAVA_OPTIONALS.put(b, opt2);
                    return opt2;
                } else {
                    GUAVA_OPTIONALS.put(opt.get(), opt);
                    return opt;
                }
            }
        } else {
            return opt;
        }
    } else if (o instanceof Multimap) {
        if (o instanceof ImmutableMultimap || o instanceof SortedSetMultimap) {
            for (Object value : ((Multimap) o).values()) {
                deduplicateObject(value, recursion + 1);
            }
        } else {
            for (Object key : ((Multimap) o).keySet()) {
                List l = Lists.newArrayList(((Multimap) o).values());
                for (int i = 0; i < l.size(); i++) {
                    l.set(i, deduplicateObject(l.get(i), recursion + 1));
                }
                ((Multimap) o).replaceValues(key, l);
            }
        }
    } else if (o instanceof Map) {
        for (Object v : ((Map) o).keySet()) {
            deduplicateObject(v, recursion + 1);
        }
        if (o instanceof SortedMap || IMMUTABLE_CLASS.contains(c)) {
            for (Object v : ((Map) o).values()) {
                deduplicateObject(v, recursion + 1);
            }
        } else if (o instanceof ImmutableMap) {
            ImmutableMap im = (ImmutableMap) o;
            ImmutableMap.Builder newMap = (o instanceof ImmutableBiMap) ? ImmutableBiMap.builder() : ImmutableMap.builder();
            boolean deduplicated = false;
            for (Object key : im.keySet()) {
                Object a = im.get(key);
                Object b = deduplicateObject(a, recursion + 1);
                newMap.put(key, b != null ? b : a);
                if (b != null && b != a)
                    deduplicated = true;
            }
            return deduplicated ? newMap.build() : o;
        } else {
            try {
                for (Object key : ((Map) o).keySet()) {
                    Object value = ((Map) o).get(key);
                    Object valueD = deduplicateObject(value, recursion + 1);
                    if (valueD != null && value != valueD)
                        ((Map) o).put(key, valueD);
                }
            } catch (UnsupportedOperationException e) {
                IMMUTABLE_CLASS.add(c);
                for (Object v : ((Map) o).values()) {
                    deduplicateObject(v, recursion + 1);
                }
            }
        }
    } else if (o instanceof List) {
        if (IMMUTABLE_CLASS.contains(c)) {
            List l = (List) o;
            for (int i = 0; i < l.size(); i++) {
                deduplicateObject(l.get(i), recursion + 1);
            }
        } else if (o instanceof ImmutableList) {
            ImmutableList il = (ImmutableList) o;
            ImmutableList.Builder builder = ImmutableList.builder();
            boolean deduplicated = false;
            for (int i = 0; i < il.size(); i++) {
                Object a = il.get(i);
                Object b = deduplicateObject(a, recursion + 1);
                builder.add(b != null ? b : a);
                if (b != null && b != a)
                    deduplicated = true;
            }
            if (deduplicated) {
                return builder.build();
            }
        } else {
            List l = (List) o;
            try {
                for (int i = 0; i < l.size(); i++) {
                    l.set(i, deduplicateObject(l.get(i), recursion + 1));
                }
            } catch (UnsupportedOperationException e) {
                IMMUTABLE_CLASS.add(c);
                for (int i = 0; i < l.size(); i++) {
                    deduplicateObject(l.get(i), recursion + 1);
                }
            }
        }
    } else if (o instanceof ImmutableSet) {
        if (!(o instanceof ImmutableSortedSet)) {
            ImmutableSet.Builder builder = new ImmutableSet.Builder();
            for (Object o1 : ((Set) o)) {
                builder.add(deduplicateObject(o1, recursion + 1));
            }
            o = builder.build();
        } else {
            for (Object o1 : ((Set) o)) {
                deduplicateObject(o1, recursion + 1);
            }
        }
    } else if (o instanceof Collection) {
        if (!(o instanceof SortedSet)) {
            if (!COLLECTION_CONSTRUCTORS.containsKey(c)) {
                try {
                    COLLECTION_CONSTRUCTORS.put(c, MethodHandles.publicLookup().findConstructor(c, MethodType.methodType(void.class)));
                } catch (Exception e) {
                    COLLECTION_CONSTRUCTORS.put(c, null);
                }
            }
            MethodHandle constructor = COLLECTION_CONSTRUCTORS.get(c);
            if (constructor != null) {
                try {
                    Collection nc = (Collection) constructor.invoke();
                    if (nc != null) {
                        for (Object o1 : ((Collection) o)) {
                            nc.add(deduplicateObject(o1, recursion + 1));
                        }
                        return nc;
                    }
                } catch (Throwable t) {
                    COLLECTION_CONSTRUCTORS.put(c, null);
                }
            }
        }
        // fallback
        for (Object o1 : ((Collection) o)) {
            deduplicateObject(o1, recursion + 1);
        }
    } else if (c.isArray()) {
        for (int i = 0; i < Array.getLength(o); i++) {
            Object entry = Array.get(o, i);
            Object entryD = deduplicateObject(entry, recursion + 1);
            if (entryD != null && entry != entryD)
                Array.set(o, i, entryD);
        }
    } else {
        if (!CLASS_FIELDS.containsKey(c)) {
            ImmutableSet.Builder<MethodHandle[]> fsBuilder = ImmutableSet.builder();
            Class cc = c;
            do {
                for (Field f : cc.getDeclaredFields()) {
                    if ((f.getModifiers() & Modifier.STATIC) != 0)
                        continue;
                    if (shouldCheckClass(f.getType())) {
                        try {
                            f.setAccessible(true);
                            fsBuilder.add(new MethodHandle[] { MethodHandles.lookup().unreflectGetter(f), MethodHandles.lookup().unreflectSetter(f) });
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    }
                }
            } while ((cc = cc.getSuperclass()) != Object.class);
            CLASS_FIELDS.put(c, fsBuilder.build());
        }
        for (MethodHandle[] mh : CLASS_FIELDS.get(c)) {
            try {
                // System.out.println("-" + Strings.repeat("-", recursion) + "* " + f.getName());
                Object value = mh[0].invoke(o);
                Object valueD = deduplicateObject(value, recursion + 1);
                if (canTrim)
                    trimArray(valueD);
                if (valueD != null && value != valueD)
                    mh[1].invoke(o, valueD);
            } catch (IllegalAccessException e) {
            } catch (Throwable t) {
                t.printStackTrace();
            }
        }
    }
    return o;
}
Also used : Entity(net.minecraft.entity.Entity) UnpackedBakedQuad(net.minecraftforge.client.model.pipeline.UnpackedBakedQuad) BufferBuilder(net.minecraft.client.renderer.BufferBuilder) World(net.minecraft.world.World) Predicate(com.google.common.base.Predicate) Item(net.minecraft.item.Item) Optional(com.google.common.base.Optional) AnimationItemOverrideList(net.minecraftforge.client.model.animation.AnimationItemOverrideList) BlockPos(net.minecraft.util.math.BlockPos) IRegistry(net.minecraft.util.registry.IRegistry) Optional(com.google.common.base.Optional) PerspectiveMapWrapper(net.minecraftforge.client.model.PerspectiveMapWrapper) java.util(java.util) Block(net.minecraft.block.Block) MethodHandle(java.lang.invoke.MethodHandle) UnpackedBakedQuad(net.minecraftforge.client.model.pipeline.UnpackedBakedQuad) TRSRTransformation(net.minecraftforge.common.model.TRSRTransformation) EnumFacing(net.minecraft.util.EnumFacing) Logger(org.apache.logging.log4j.Logger) Field(java.lang.reflect.Field) ResourceLocation(net.minecraft.util.ResourceLocation) AnimationItemOverrideList(net.minecraftforge.client.model.animation.AnimationItemOverrideList) AnimationItemOverrideList(net.minecraftforge.client.model.animation.AnimationItemOverrideList) Vec3d(net.minecraft.util.math.Vec3d)

Example 2 with IRegistry

use of net.minecraft.util.registry.IRegistry in project FoamFix by asiekierka.

the class FoamFixModelRegistryDuplicateWipe method onTextureStitchPost.

@SubscribeEvent
public void onTextureStitchPost(TextureStitchEvent.Post event) {
    ItemModelMesher imm = Minecraft.getMinecraft().getRenderItem().getItemModelMesher();
    BlockModelShapes bms = Minecraft.getMinecraft().getBlockRendererDispatcher().getBlockModelShapes();
    ModelManager mgr = bms.getModelManager();
    Field f = ReflectionHelper.findField(ModelManager.class, "modelRegistry", "field_174958_a");
    try {
        IRegistry<ModelResourceLocation, IBakedModel> registry = (IRegistry<ModelResourceLocation, IBakedModel>) f.get(mgr);
        FoamFix.logger.info("Clearing unnecessary model registry of size " + registry.getKeys().size() + ".");
        for (ModelResourceLocation l : registry.getKeys()) {
            registry.putObject(l, ProxyClient.DUMMY_MODEL);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    f = ReflectionHelper.findField(BlockModelShapes.class, "bakedModelStore", "field_178129_a");
    try {
        Map<IBlockState, IBakedModel> modelStore = (Map<IBlockState, IBakedModel>) f.get(bms);
        FoamFix.logger.info("Clearing unnecessary model store of size " + modelStore.size() + ".");
        modelStore.clear();
    } catch (Exception e) {
        e.printStackTrace();
    }
    if (imm instanceof ItemModelMesherForge) {
        f = ReflectionHelper.findField(ItemModelMesherForge.class, "models");
        try {
            Map<IRegistryDelegate<Item>, TIntObjectHashMap<IBakedModel>> modelStore = (Map<IRegistryDelegate<Item>, TIntObjectHashMap<IBakedModel>>) f.get(imm);
            FoamFix.logger.info("Clearing unnecessary item shapes cache of size " + modelStore.size() + ".");
            modelStore.clear();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
Also used : IBlockState(net.minecraft.block.state.IBlockState) ModelResourceLocation(net.minecraft.client.renderer.block.model.ModelResourceLocation) ModelManager(net.minecraft.client.renderer.block.model.ModelManager) BlockModelShapes(net.minecraft.client.renderer.BlockModelShapes) Field(java.lang.reflect.Field) Item(net.minecraft.item.Item) ItemModelMesher(net.minecraft.client.renderer.ItemModelMesher) IRegistryDelegate(net.minecraftforge.registries.IRegistryDelegate) TIntObjectHashMap(gnu.trove.map.hash.TIntObjectHashMap) IBakedModel(net.minecraft.client.renderer.block.model.IBakedModel) ItemModelMesherForge(net.minecraftforge.client.ItemModelMesherForge) IRegistry(net.minecraft.util.registry.IRegistry) TIntObjectHashMap(gnu.trove.map.hash.TIntObjectHashMap) IdentityHashMap(java.util.IdentityHashMap) HashMap(java.util.HashMap) Map(java.util.Map) SubscribeEvent(net.minecraftforge.fml.common.eventhandler.SubscribeEvent)

Aggregations

Field (java.lang.reflect.Field)2 Item (net.minecraft.item.Item)2 IRegistry (net.minecraft.util.registry.IRegistry)2 Optional (com.google.common.base.Optional)1 Predicate (com.google.common.base.Predicate)1 TIntObjectHashMap (gnu.trove.map.hash.TIntObjectHashMap)1 MethodHandle (java.lang.invoke.MethodHandle)1 java.util (java.util)1 HashMap (java.util.HashMap)1 IdentityHashMap (java.util.IdentityHashMap)1 Map (java.util.Map)1 Block (net.minecraft.block.Block)1 IBlockState (net.minecraft.block.state.IBlockState)1 BlockModelShapes (net.minecraft.client.renderer.BlockModelShapes)1 BufferBuilder (net.minecraft.client.renderer.BufferBuilder)1 ItemModelMesher (net.minecraft.client.renderer.ItemModelMesher)1 IBakedModel (net.minecraft.client.renderer.block.model.IBakedModel)1 ModelManager (net.minecraft.client.renderer.block.model.ModelManager)1 ModelResourceLocation (net.minecraft.client.renderer.block.model.ModelResourceLocation)1 Entity (net.minecraft.entity.Entity)1