package gregtech.api.interfaces; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.function.BiPredicate; import java.util.function.ToLongFunction; import net.minecraftforge.common.util.ForgeDirection; import com.google.common.collect.ImmutableList; import com.gtnewhorizon.structurelib.structure.IStructureElement; import gregtech.api.interfaces.metatileentity.IMetaTileEntity; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; import gregtech.api.util.GT_StructureUtility; import gregtech.api.util.IGT_HatchAdder; public interface IHatchElement { List> mteClasses(); IGT_HatchAdder adder(); String name(); long count(T t); default IHatchElement withMteClass(Class aClass) { if (aClass == null) throw new IllegalArgumentException(); return withMteClasses(Collections.singletonList(aClass)); } @SuppressWarnings("unchecked") // can't set SafeVarargs :( default IHatchElement withMteClasses(Class... aClasses) { if (aClasses == null) throw new IllegalArgumentException(); return withMteClasses(Arrays.asList(aClasses)); } default IHatchElement withMteClasses(List> aClasses) { if (aClasses == null) throw new IllegalArgumentException(); return new HatchElement<>(aClasses, null, null, null, this); } default IHatchElement withAdder(IGT_HatchAdder aAdder) { if (aAdder == null) throw new IllegalArgumentException(); return new HatchElement<>(null, aAdder, null, null, this); } default IHatchElement withName(String aName) { if (aName == null) throw new IllegalArgumentException(); return new HatchElement<>(null, null, aName, null, this); } default IHatchElement withCount(ToLongFunction aCount) { if (aCount == null) throw new IllegalArgumentException(); return new HatchElement<>(null, null, null, aCount, this); } default IStructureElement newAny(int aCasingIndex, int aDot) { if (aCasingIndex < 0 || aDot < 0) throw new IllegalArgumentException(); return GT_StructureUtility.buildHatchAdder() .anyOf(this) .casingIndex(aCasingIndex) .dot(aDot) .continueIfSuccess() .build(); } default IStructureElement newAny(int aCasingIndex, int aDot, ForgeDirection... allowedFacings) { if (aCasingIndex < 0 || aDot < 0) throw new IllegalArgumentException(); return GT_StructureUtility.buildHatchAdder() .anyOf(this) .casingIndex(aCasingIndex) .dot(aDot) .continueIfSuccess() .allowOnly(allowedFacings) .build(); } default IStructureElement newAny(int aCasingIndex, int aDot, BiPredicate aShouldSkip) { if (aCasingIndex < 0 || aDot < 0 || aShouldSkip == null) throw new IllegalArgumentException(); return GT_StructureUtility.buildHatchAdder() .anyOf(this) .casingIndex(aCasingIndex) .dot(aDot) .shouldSkip(aShouldSkip) .continueIfSuccess() .build(); } default IHatchElement or(IHatchElement fallback) { return new HatchElementEither<>(this, fallback); } } class HatchElementEither implements IHatchElement { private final IHatchElement first, second; private ImmutableList> mMteClasses; private String name; HatchElementEither(IHatchElement first, IHatchElement second) { this.first = first; this.second = second; } @Override public List> mteClasses() { if (mMteClasses == null) mMteClasses = ImmutableList.>builder() .addAll(first.mteClasses()) .addAll(second.mteClasses()) .build(); return mMteClasses; } @Override public IGT_HatchAdder adder() { return ((t, te, i) -> first.adder() .apply(t, te, i) || second.adder() .apply(t, te, i)); } @Override public String name() { if (name == null) name = first.name() + " or " + second.name(); return name; } @Override public long count(T t) { return first.count(t) + second.count(t); } } class HatchElement implements IHatchElement { private final List> mClasses; private final IGT_HatchAdder mAdder; private final String mName; private final IHatchElement mBacking; private final ToLongFunction mCount; public HatchElement(List> aMteClasses, IGT_HatchAdder aAdder, String aName, ToLongFunction aCount, IHatchElement aBacking) { this.mClasses = aMteClasses; this.mAdder = aAdder; this.mName = aName; this.mCount = aCount; this.mBacking = aBacking; } @Override public List> mteClasses() { return mClasses == null ? mBacking.mteClasses() : mClasses; } @Override public IGT_HatchAdder adder() { return mAdder == null ? mBacking.adder() : mAdder; } @Override public String name() { return mName == null ? mBacking.name() : mName; } @Override public long count(T t) { return mCount == null ? mBacking.count(t) : mCount.applyAsLong(t); } @Override public IHatchElement withMteClasses(List> aClasses) { if (aClasses == null) throw new IllegalArgumentException(); return new HatchElement<>(aClasses, mAdder, mName, mCount, mBacking); } @Override public IHatchElement withAdder(IGT_HatchAdder aAdder) { if (aAdder == null) throw new IllegalArgumentException(); return new HatchElement<>(mClasses, aAdder, mName, mCount, mBacking); } @Override public IHatchElement withName(String aName) { if (aName == null) throw new IllegalArgumentException(); return new HatchElement<>(mClasses, mAdder, aName, mCount, mBacking); } @Override public IHatchElement withCount(ToLongFunction aCount) { if (aCount == null) throw new IllegalArgumentException(); return new HatchElement<>(mClasses, mAdder, mName, aCount, mBacking); } }