package de.take_weiland.mods.commons.nbt; import com.google.common.base.Predicate; import com.google.common.base.Throwables; import de.take_weiland.mods.commons.serialize.Property; import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTTagCompound; import javax.annotation.Nullable; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import static java.lang.invoke.MethodType.methodType; /** * @author diesieben07 */ final class NBTSerializerMethods { static final MethodHandle GET_RAW_TYPE; static final MethodHandle SERIALIZED_NULL; static final MethodHandle IS_NULL; static final MethodHandle IS_SER_NULL; static final MethodHandle DO_NOTHING; static final MethodHandle IS_NONNULL; static final MethodHandle IS_ID; static final MethodHandle IS_NONNULL_AND_ID; static final MethodHandle IS_NONNULL_AND_NOT_SERNULL; static final MethodHandle CLASS_EQUAL; static final MethodHandle PREDICATE_APPLY; static { try { MethodHandles.Lookup lookup = MethodHandles.lookup(); GET_RAW_TYPE = lookup.findVirtual(Property.class, "getRawType", methodType(Class.class)); CLASS_EQUAL = lookup.findStatic(NBTSerializerMethods.class, "equal", methodType(boolean.class, Class.class, Class.class)); PREDICATE_APPLY = lookup.findVirtual(Predicate.class, "apply", methodType(boolean.class, Object.class)); SERIALIZED_NULL = lookup.findStatic(NBTData.class, "serializedNull", methodType(NBTBase.class)); IS_NULL = lookup.findStatic(NBTSerializerMethods.class, "isNull", methodType(boolean.class, Object.class)); IS_SER_NULL = lookup.findStatic(NBTSerializerMethods.class, "isRealSerializedNull", methodType(boolean.class, NBTBase.class)); DO_NOTHING = MethodHandles.constant(Void.class, null).asType(methodType(void.class)); IS_NONNULL = lookup.findStatic(NBTSerializerMethods.class, "isNonNull", methodType(boolean.class, NBTBase.class)); IS_ID = lookup.findStatic(NBTSerializerMethods.class, "isDesiredID", methodType(boolean.class, NBTBase.class, int.class)); IS_NONNULL_AND_ID = lookup.findStatic(NBTSerializerMethods.class, "isNonnullAndID", methodType(boolean.class, NBTBase.class, int.class)); IS_NONNULL_AND_NOT_SERNULL = lookup.findStatic(NBTSerializerMethods.class, "isNonNullAndNotSerNull", methodType(boolean.class, NBTBase.class)); } catch(ReflectiveOperationException e) { throw Throwables.propagate(e); } } private static boolean equal(Class<?> a, Class<?> b) { return a == b; } private static boolean isNull(@Nullable Object o) { return o == null; } private static boolean isRealSerializedNull(@Nullable NBTBase nbt) { return nbt != null && nbt.getId() == NBT.TAG_COMPOUND && ((NBTTagCompound) nbt).getByte(NBTData.NULL_KEY) == NBTData.NULL; } private static boolean isNonNull(@Nullable NBTBase nbt) { return nbt != null; } private static boolean isDesiredID(@Nullable NBTBase nbt, int id) { return nbt != null && nbt.getId() == id; } private static boolean isNonnullAndID(@Nullable NBTBase nbt, int id) { if (nbt == null) { return false; } if (nbt.getId() != id) { return false; } return id != NBT.TAG_COMPOUND || ((NBTTagCompound) nbt).getByte(NBTData.NULL_KEY) != NBTData.NULL; } private static boolean isNonNullAndNotSerNull(@Nullable NBTBase nbt) { return nbt != null && (nbt.getId() != NBT.TAG_COMPOUND || ((NBTTagCompound) nbt).getByte(NBTData.NULL_KEY) == NBTData.NULL); } private NBTSerializerMethods() { } }