diff --git a/src/main/java/com/gtnewhorizon/structurelib/alignment/AlignmentLimits.java b/src/main/java/com/gtnewhorizon/structurelib/alignment/AlignmentLimits.java index 480a3188..3ffbf05a 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/alignment/AlignmentLimits.java +++ b/src/main/java/com/gtnewhorizon/structurelib/alignment/AlignmentLimits.java @@ -1,183 +1,19 @@ package com.gtnewhorizon.structurelib.alignment; -import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; import com.gtnewhorizon.structurelib.alignment.enumerable.Flip; import com.gtnewhorizon.structurelib.alignment.enumerable.Rotation; import net.minecraftforge.common.util.ForgeDirection; -import java.util.Arrays; -import java.util.Optional; -import java.util.Random; -import java.util.function.Function; +class AlignmentLimits implements IAlignmentLimits { -import static com.gtnewhorizon.structurelib.alignment.IAlignment.STATES_COUNT; + protected final boolean[] validStates; -public class AlignmentLimits implements IAlignmentLimits { - - protected final boolean[] validStates=new boolean[STATES_COUNT]; - - public AlignmentLimits() { - allowAll(); - } - - AlignmentLimits allowAll(){ - Arrays.fill(validStates,true); - return this; - } - - AlignmentLimits denyAll(){ - Arrays.fill(validStates,false); - return this; - } - - AlignmentLimits randomAll(Random random){ - for (int i = 0; i < validStates.length; i++) { - validStates[i]=random.nextBoolean(); - } - return this; - } - - AlignmentLimits deny(ExtendedFacing... deny){ - if(deny!=null){ - for (ExtendedFacing extendedFacing : deny) { - validStates[extendedFacing.getIndex()]=false; - } - } - return this; - } - - AlignmentLimits allow(ExtendedFacing... allow){ - if(allow!=null){ - for (ExtendedFacing extendedFacing : allow) { - validStates[extendedFacing.getIndex()]=false; - } - } - return this; - } - - AlignmentLimits deny(ForgeDirection... deny){ - if(deny!=null){ - for (ExtendedFacing value : ExtendedFacing.VALUES) { - for (ForgeDirection direction : deny) { - if (value.getDirection() == direction) { - validStates[value.getIndex()] = false; - break; - } - } - } - } - return this; - } - - AlignmentLimits allow(ForgeDirection... allow){ - if(allow!=null){ - for (ExtendedFacing value : ExtendedFacing.VALUES) { - for (ForgeDirection direction : allow) { - if (value.getDirection() == direction) { - validStates[value.getIndex()] = true; - break; - } - } - } - } - return this; - } - - AlignmentLimits deny(Rotation... deny){ - if(deny!=null){ - for (ExtendedFacing value : ExtendedFacing.VALUES) { - for (Rotation rotation : deny) { - if (value.getRotation() == rotation) { - validStates[value.getIndex()] = false; - break; - } - } - } - } - return this; - } - - AlignmentLimits allow(Rotation... allow){ - if(allow!=null){ - for (ExtendedFacing value : ExtendedFacing.VALUES) { - for (Rotation rotation : allow) { - if (value.getRotation() == rotation) { - validStates[value.getIndex()] = true; - break; - } - } - } - } - return this; - } - - AlignmentLimits deny(Flip... deny){ - if(deny!=null){ - for (ExtendedFacing value : ExtendedFacing.VALUES) { - for (Flip flip : deny) { - if (value.getFlip() == flip) { - validStates[value.getIndex()] = false; - break; - } - } - } - } - return this; - } - - AlignmentLimits allow(Flip... allow){ - if(allow!=null){ - for (ExtendedFacing value : ExtendedFacing.VALUES) { - for (Flip flip : allow) { - if (value.getFlip() == flip) { - validStates[value.getIndex()] = true; - break; - } - } - } - } - return this; - } - - AlignmentLimits predicateApply(Function> predicate){ - for (ExtendedFacing value : ExtendedFacing.VALUES) { - predicate.apply(value).ifPresent(bool->validStates[value.getIndex()]=bool); - } - return this; - } - - AlignmentLimits ensureDuplicates(){ - for (ExtendedFacing value : ExtendedFacing.VALUES) { - if(validStates[value.getIndex()]){ - validStates[value.getDuplicate().getIndex()]=true; - } - } - return this; - } - - /** - * Prefers rotation over flip, so both flip will get translated to opposite rotation and no flip - * @param flip the preferred flip to be used Horizontal or vertical - * @return this - */ - AlignmentLimits ensureNoDuplicates(Flip flip){ - if(flip==Flip.BOTH||flip==Flip.NONE){ - throw new IllegalArgumentException("Preffered Flip must be Horizontal or Vertical"); - } - flip=flip.getOpposite(); - for (ExtendedFacing value : ExtendedFacing.VALUES) { - if(validStates[value.getIndex()]){ - if(value.getFlip()==Flip.BOTH || value.getFlip()==flip){ - validStates[value.getIndex()]=false; - validStates[value.getDuplicate().getIndex()]=true; - } - } - } - return this; + AlignmentLimits(boolean[] validStates) { + this.validStates = validStates; } @Override public boolean isNewExtendedFacingValid(ForgeDirection direction, Rotation rotation, Flip flip) { - return validStates[IAlignment.getAlignmentIndex(direction,rotation,flip)]; + return validStates[IAlignment.getAlignmentIndex(direction, rotation, flip)]; } } diff --git a/src/main/java/com/gtnewhorizon/structurelib/alignment/IAlignmentLimits.java b/src/main/java/com/gtnewhorizon/structurelib/alignment/IAlignmentLimits.java index 258b6145..169625c5 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/alignment/IAlignmentLimits.java +++ b/src/main/java/com/gtnewhorizon/structurelib/alignment/IAlignmentLimits.java @@ -4,16 +4,110 @@ import com.gtnewhorizon.structurelib.alignment.enumerable.Flip; import com.gtnewhorizon.structurelib.alignment.enumerable.Rotation; import net.minecraftforge.common.util.ForgeDirection; +import java.util.Arrays; +import java.util.Optional; +import java.util.function.Function; + +import static com.gtnewhorizon.structurelib.alignment.IAlignment.STATES_COUNT; + public interface IAlignmentLimits { - IAlignmentLimits UNLIMITED= (direction, rotation, flip) -> true; + IAlignmentLimits UNLIMITED = (direction, rotation, flip) -> true; boolean isNewExtendedFacingValid(ForgeDirection direction, Rotation rotation, Flip flip); - default boolean isNewExtendedFacingValid(ExtendedFacing alignment){ + default boolean isNewExtendedFacingValid(ExtendedFacing alignment) { return isNewExtendedFacingValid( alignment.getDirection(), alignment.getRotation(), alignment.getFlip()); } + + class Builder { + protected final boolean[] validStates = new boolean[STATES_COUNT]; + + public static Builder allowAll() { + Builder b = new Builder(); + Arrays.fill(b.validStates, true); + return b; + } + + public static Builder denyAll() { + Builder b = new Builder(); + Arrays.fill(b.validStates, true); + return b; + } + + public Builder deny(ForgeDirection fd) { + ExtendedFacing.getAllWith(fd).stream().mapToInt(ExtendedFacing::getIndex).forEach(v -> validStates[v] = false); + return this; + } + + public Builder allow(ForgeDirection fd) { + ExtendedFacing.getAllWith(fd).stream().mapToInt(ExtendedFacing::getIndex).forEach(v -> validStates[v] = true); + return this; + } + + public Builder deny(Rotation fd) { + ExtendedFacing.getAllWith(fd).stream().mapToInt(ExtendedFacing::getIndex).forEach(v -> validStates[v] = false); + return this; + } + + public Builder allow(Rotation fd) { + ExtendedFacing.getAllWith(fd).stream().mapToInt(ExtendedFacing::getIndex).forEach(v -> validStates[v] = true); + return this; + } + + public Builder deny(Flip fd) { + ExtendedFacing.getAllWith(fd).stream().mapToInt(ExtendedFacing::getIndex).forEach(v -> validStates[v] = false); + return this; + } + + public Builder allow(Flip fd) { + ExtendedFacing.getAllWith(fd).stream().mapToInt(ExtendedFacing::getIndex).forEach(v -> validStates[v] = true); + return this; + } + + public Builder filter(Function> predicate) { + for (ExtendedFacing value : ExtendedFacing.VALUES) { + predicate.apply(value).ifPresent(bool -> validStates[value.getIndex()] = bool); + } + return this; + } + + public Builder ensureDuplicates() { + for (ExtendedFacing value : ExtendedFacing.VALUES) { + if (validStates[value.getIndex()]) { + validStates[value.getDuplicate().getIndex()] = true; + } + } + return this; + } + + /** + * Prefers rotation over flip, so both flip will get translated to opposite rotation and no flip + * + * @param flip the preferred flip to be used Horizontal or vertical + * @return this + */ + public Builder ensureNoDuplicates(Flip flip) { + if (flip == Flip.BOTH || flip == Flip.NONE) { + throw new IllegalArgumentException("Preffered Flip must be Horizontal or Vertical"); + } + flip = flip.getOpposite(); + for (ExtendedFacing value : ExtendedFacing.VALUES) { + if (validStates[value.getIndex()]) { + if (value.getFlip() == Flip.BOTH || value.getFlip() == flip) { + validStates[value.getIndex()] = false; + validStates[value.getDuplicate().getIndex()] = true; + } + } + } + return this; + } + + public IAlignmentLimits build() { + return new AlignmentLimits(validStates); + } + } } diff --git a/src/main/java/com/gtnewhorizon/structurelib/alignment/enumerable/ExtendedFacing.java b/src/main/java/com/gtnewhorizon/structurelib/alignment/enumerable/ExtendedFacing.java index 376d0d7f..3e3a36dd 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/alignment/enumerable/ExtendedFacing.java +++ b/src/main/java/com/gtnewhorizon/structurelib/alignment/enumerable/ExtendedFacing.java @@ -1,5 +1,6 @@ package com.gtnewhorizon.structurelib.alignment.enumerable; +import com.google.common.collect.ImmutableSet; import com.gtnewhorizon.structurelib.alignment.IAlignment; import com.gtnewhorizon.structurelib.alignment.IntegerAxisSwap; import com.gtnewhorizon.structurelib.util.Vec3Impl; @@ -12,7 +13,7 @@ import static com.gtnewhorizon.structurelib.alignment.IAlignment.FLIPS_COUNT; import static com.gtnewhorizon.structurelib.alignment.IAlignment.ROTATIONS_COUNT; import static java.lang.Math.abs; import static java.util.Arrays.stream; -import static java.util.stream.Collectors.toMap; +import static java.util.stream.Collectors.*; public enum ExtendedFacing { DOWN_NORMAL_NONE("down normal none"), @@ -117,18 +118,21 @@ public enum ExtendedFacing { public static final Map> FOR_FACING=new HashMap<>(); static { stream(values()).forEach(extendedFacing -> - FOR_FACING.compute(extendedFacing.direction,((forgeDirection, extendedFacings) -> { - if(extendedFacings==null){ + FOR_FACING.compute(extendedFacing.direction, ((forgeDirection, extendedFacings) -> { + if (extendedFacings == null) { extendedFacings = new ArrayList<>(); } extendedFacings.add(extendedFacing); return extendedFacings; }))); } - private static final Map NAME_LOOKUP = stream(VALUES).collect(toMap(ExtendedFacing::getName2, (extendedFacing) -> extendedFacing)); + private static final Map NAME_LOOKUP = stream(VALUES).collect(toMap(ExtendedFacing::getName2, (extendedFacing) -> extendedFacing)); + private static final EnumMap> LOOKUP_BY_DIRECTION = stream(VALUES).collect(groupingBy(ExtendedFacing::getDirection, () -> new EnumMap<>(ForgeDirection.class), collectingAndThen(toSet(), ImmutableSet::copyOf))); + private static final EnumMap> LOOKUP_BY_ROTATION = stream(VALUES).collect(groupingBy(ExtendedFacing::getRotation, () -> new EnumMap<>(Rotation.class), collectingAndThen(toSet(), ImmutableSet::copyOf))); + private static final EnumMap> LOOKUP_BY_FLIP = stream(VALUES).collect(groupingBy(ExtendedFacing::getFlip, () -> new EnumMap<>(Flip.class), collectingAndThen(toSet(), ImmutableSet::copyOf))); private final ForgeDirection direction; - private final ForgeDirection a,b,c; + private final ForgeDirection a, b, c; private final Rotation rotation; private final Flip flip; @@ -227,6 +231,10 @@ public enum ExtendedFacing { return VALUES[IAlignment.getAlignmentIndex(direction, Rotation.NORMAL, Flip.NONE)]; } + public static ImmutableSet getAllWith(ForgeDirection direction) { return LOOKUP_BY_DIRECTION.get(direction);} + public static ImmutableSet getAllWith(Rotation rotation) { return LOOKUP_BY_ROTATION.get(rotation);} + public static ImmutableSet getAllWith(Flip flip) { return LOOKUP_BY_FLIP.get(flip);} + public ExtendedFacing with(ForgeDirection direction){ return of(direction,rotation,flip); }