From da1ef6c8c792a9e13fc1620db64790692753ecdc Mon Sep 17 00:00:00 2001 From: FalsePattern <30945458+FalsePattern@users.noreply.github.com> Date: Sat, 6 Aug 2022 13:12:55 +0200 Subject: [PATCH] Annotate all the things --- .../falsepattern/lib/DeprecationDetails.java | 5 +- .../java/com/falsepattern/lib/StableAPI.java | 40 ++++ .../com/falsepattern/lib/asm/ASMUtil.java | 13 ++ .../lib/asm/IClassNodeTransformer.java | 6 + .../lib/asm/SmartTransformer.java | 4 + .../exceptions/AsmClassNotFoundException.java | 4 + .../exceptions/AsmFieldNotFoundException.java | 4 + .../AsmMethodNotFoundException.java | 3 + .../asm/exceptions/AsmTransformException.java | 6 + .../com/falsepattern/lib/compat/BlockPos.java | 65 +++++-- .../com/falsepattern/lib/compat/ChunkPos.java | 10 + .../com/falsepattern/lib/compat/GuiLabel.java | 10 + .../falsepattern/lib/compat/MathHelper.java | 35 ++++ .../com/falsepattern/lib/compat/Rotation.java | 7 + .../com/falsepattern/lib/compat/Vec3i.java | 11 ++ .../com/falsepattern/lib/config/Config.java | 35 +++- .../lib/config/ConfigException.java | 2 + .../lib/config/ConfigurationManager.java | 6 +- .../lib/config/IConfigElementProxy.java | 178 ------------------ .../lib/config/SimpleGuiConfig.java | 5 +- .../lib/config/event/AllConfigSyncEvent.java | 15 +- .../lib/config/event/ConfigSyncEvent.java | 27 +-- .../config/event/ConfigSyncRequestEvent.java | 17 +- .../event/ConfigValidationFailureEvent.java | 66 ++++--- .../lib/dependencies/ComplexVersion.java | 1 + .../lib/dependencies/DependencyLoader.java | 2 + .../lib/dependencies/SemanticVersion.java | 3 + .../lib/dependencies/Version.java | 1 + .../{util => internal}/ReflectionUtil.java | 2 +- .../lib/internal/config/LibraryConfig.java | 5 + .../lib/internal/config/LibraryGuiConfig.java | 2 +- .../internal/config/LibraryGuiFactory.java | 2 + .../lib/internal/config/ToastConfig.java | 4 + .../impl/config/ParsedConfiguration.java | 8 +- .../impl/config/fields/AConfigField.java | 2 +- .../config/fields/BooleanListConfigField.java | 2 +- .../lib/mapping/MappingManager.java | 16 +- .../lib/mapping/storage/Lookup.java | 7 + .../lib/mapping/storage/MappedString.java | 10 + .../lib/mapping/types/MappingType.java | 6 + .../lib/mapping/types/NameType.java | 5 + .../lib/mapping/types/UniversalClass.java | 16 +- .../lib/mapping/types/UniversalField.java | 30 ++- .../lib/mapping/types/UniversalMethod.java | 44 ++++- .../com/falsepattern/lib/mixin/IMixin.java | 21 ++- .../falsepattern/lib/mixin/IMixinPlugin.java | 18 +- .../falsepattern/lib/mixin/ITargetedMod.java | 9 +- .../lib/mixin/MinecraftURLClassPath.java | 3 + .../falsepattern/lib/text/FormattedText.java | 12 ++ .../com/falsepattern/lib/toasts/GuiToast.java | 6 +- .../com/falsepattern/lib/toasts/IToast.java | 14 +- .../falsepattern/lib/toasts/SimpleToast.java | 2 +- .../falsepattern/lib/toasts/icon/ToastBG.java | 18 +- .../lib/toasts/icon/ToastIcon.java | 4 +- .../lib/toasts/icon/ToastTexture.java | 10 +- .../lib/updates/ModUpdateInfo.java | 5 + .../lib/updates/UpdateCheckException.java | 4 + .../lib/updates/UpdateChecker.java | 3 + .../com/falsepattern/lib/util/FileUtil.java | 1 + .../com/falsepattern/lib/util/LangUtil.java | 3 + .../com/falsepattern/lib/util/MathUtil.java | 107 +++++------ .../com/falsepattern/lib/util/RenderUtil.java | 2 + .../falsepattern/lib/util/ResourceUtil.java | 8 + 63 files changed, 623 insertions(+), 369 deletions(-) delete mode 100644 src/main/java/com/falsepattern/lib/config/IConfigElementProxy.java rename src/main/java/com/falsepattern/lib/{util => internal}/ReflectionUtil.java (97%) diff --git a/src/main/java/com/falsepattern/lib/DeprecationDetails.java b/src/main/java/com/falsepattern/lib/DeprecationDetails.java index 663b790..119119f 100644 --- a/src/main/java/com/falsepattern/lib/DeprecationDetails.java +++ b/src/main/java/com/falsepattern/lib/DeprecationDetails.java @@ -12,7 +12,6 @@ import java.lang.annotation.RetentionPolicy; @Retention(RetentionPolicy.RUNTIME) @StableAPI(since = "0.10.0") public @interface DeprecationDetails { - @StableAPI(since = "0.10.0") String stableSince() default ""; - - @StableAPI(since = "0.10.0") String deprecatedSince(); + @StableAPI.Expose + String deprecatedSince(); } diff --git a/src/main/java/com/falsepattern/lib/StableAPI.java b/src/main/java/com/falsepattern/lib/StableAPI.java index 227e468..d2e0be4 100644 --- a/src/main/java/com/falsepattern/lib/StableAPI.java +++ b/src/main/java/com/falsepattern/lib/StableAPI.java @@ -21,8 +21,10 @@ package com.falsepattern.lib; import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; /** * Anything annotated with this annotation will be considered stable, and the class/method/field will not get breaking @@ -31,17 +33,55 @@ import java.lang.annotation.RetentionPolicy; * If a class or method is NOT annotated with this annotation, it will be considered unstable, and the package/method * arguments/etc. can freely change between patch releases without notice. *

+ * If you have a class implementing another class, you don't need to annotate the {@link Override}-annotated methods with + * StableAPI, because the StableAPI system conforms to inheritance. You should still annotate the class itself, or any extra + * fields or non-override methods you may have added if you want to expose those too. + *

* NOTICE: You should no longer use this annotation exclusively on classes themselves, and instead, annotate every single * public or protected member you want to expose as a public API! *

* Private members will never be considered stable, and can be removed without notice. + *

+ * You may set the {@link #since()} attribute to "__INTERNAL__", this will signal that even though the specific class/member + * has been marked as stable, it is still for internal use only. This may be done for reference purposes in multi-developer + * projects, where you need to communicate intent even in internal code. */ @Documented @Retention(RetentionPolicy.RUNTIME) +@Target(value = {ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.CONSTRUCTOR}) @StableAPI(since = "0.6.0") public @interface StableAPI { /** * The version this API was introduced/stabilized in. Used for library version tracking. */ @StableAPI(since = "0.6.0") String since(); + + /** + * You may use this annotation if you want a member to have an equal effective {@link #since()} value as its owner + * class. + *

+ * Everything else from the {@link StableAPI} class still applies, this is only here for brevity's sake. + * Note that if you add a new field in a version newer than the class, you must use {@link StableAPI} with the + * correct version! + *

+ * Also note that this only works for class members (methods and fields), + * inner classes still need to use {@link StableAPI}. + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.FIELD, ElementType.METHOD, ElementType.CONSTRUCTOR}) + @StableAPI(since = "0.10.0") + @interface Expose {} + + /** + * Use this if you want to explicitly mark specific members of a {@link StableAPI} class as internal-use only. + *

+ * Library consumers should never use class members marked with this annotation, as said members can be freely + * changed or removed in any version in the library without prior notice. + */ + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(value = {ElementType.FIELD, ElementType.METHOD, ElementType.CONSTRUCTOR}) + @StableAPI(since = "0.10.0") + @interface Internal {} } diff --git a/src/main/java/com/falsepattern/lib/asm/ASMUtil.java b/src/main/java/com/falsepattern/lib/asm/ASMUtil.java index e17b9b2..db8f82d 100644 --- a/src/main/java/com/falsepattern/lib/asm/ASMUtil.java +++ b/src/main/java/com/falsepattern/lib/asm/ASMUtil.java @@ -20,6 +20,7 @@ */ package com.falsepattern.lib.asm; +import com.falsepattern.lib.StableAPI; import com.falsepattern.lib.asm.exceptions.AsmClassNotFoundException; import com.falsepattern.lib.asm.exceptions.AsmFieldNotFoundException; import com.falsepattern.lib.asm.exceptions.AsmMethodNotFoundException; @@ -42,7 +43,9 @@ import org.objectweb.asm.tree.MethodNode; import java.util.Arrays; import java.util.Objects; +@StableAPI(since = "0.10.0") public class ASMUtil { + @StableAPI.Expose public static FieldNode findFieldStandard(ClassNode cn, String name, boolean optional) { for (final FieldNode ret : cn.fields) { if (name.equals(ret.name)) { @@ -56,6 +59,7 @@ public class ASMUtil { } @SneakyThrows + @StableAPI.Expose public static FieldNode findFieldFromMCP(ClassNode cn, String fieldName, boolean optional) { val classMapping = discoverClassMappingType(cn); if (classMapping == null) { @@ -67,6 +71,7 @@ public class ASMUtil { .getName(classMapping), optional); } + @StableAPI.Expose public static FieldNode findFieldFromUniversal(ClassNode cn, UniversalField field, boolean optional) { String[] possibilities = CoreLoadingPlugin.isObfuscated() ? new String[]{field.getName(MappingType.SRG), field.getName(MappingType.Notch)} @@ -83,6 +88,7 @@ public class ASMUtil { possibilities.length == 1 ? possibilities[0] : Arrays.toString(possibilities)); } + @StableAPI.Expose public static MethodNode findMethodStandard(ClassNode cn, String name, String descriptor, boolean optional) { for (final MethodNode ret : cn.methods) { if (name.equals(ret.name) && descriptor.equals(ret.desc)) { @@ -96,6 +102,7 @@ public class ASMUtil { } @SneakyThrows + @StableAPI.Expose public static MethodNode findMethodFromMCP(ClassNode cn, String mcpName, String mcpDescriptor, boolean optional) { val classMapping = discoverClassMappingType(cn); if (classMapping == null) { @@ -107,6 +114,7 @@ public class ASMUtil { return findMethodStandard(cn, method.getName(classMapping), method.getDescriptor(classMapping), optional); } + @StableAPI.Expose public static MethodNode findMethodFromUniversal(ClassNode cn, UniversalMethod method, boolean optional) { String[] possibleNames = CoreLoadingPlugin.isObfuscated() ? new String[]{method.getName(MappingType.SRG), method.getName(MappingType.Notch)} @@ -127,6 +135,7 @@ public class ASMUtil { possibleDescriptors.length == 1 ? possibleDescriptors[0] : Arrays.toString(possibleDescriptors)); } + @StableAPI.Expose public static MappingType discoverClassMappingType(ClassNode cn) { if (CoreLoadingPlugin.isObfuscated()) { if (MappingManager.containsClass(NameType.Internal, MappingType.MCP, cn.name)) { @@ -140,6 +149,7 @@ public class ASMUtil { return null; } + @StableAPI.Expose public static UniversalClass toUniversalClass(ClassNode cn) { if (CoreLoadingPlugin.isObfuscated()) { try { @@ -160,6 +170,7 @@ public class ASMUtil { } } + @StableAPI.Expose public static ClassNode parseClass(byte[] bytes, int readerFlags) { val cn = new ClassNode(Opcodes.ASM5); val reader = new ClassReader(bytes); @@ -167,11 +178,13 @@ public class ASMUtil { return cn; } + @StableAPI.Expose public static byte[] serializeClass(ClassNode cn, int writerFlags) { val writer = new ClassWriter(writerFlags); return writer.toByteArray(); } + @StableAPI.Expose public static boolean anyEquals(String str, String... options) { for (val option : options) { if (Objects.equals(str, option)) { diff --git a/src/main/java/com/falsepattern/lib/asm/IClassNodeTransformer.java b/src/main/java/com/falsepattern/lib/asm/IClassNodeTransformer.java index 78a3515..d6c0048 100644 --- a/src/main/java/com/falsepattern/lib/asm/IClassNodeTransformer.java +++ b/src/main/java/com/falsepattern/lib/asm/IClassNodeTransformer.java @@ -20,16 +20,22 @@ */ package com.falsepattern.lib.asm; +import com.falsepattern.lib.StableAPI; import org.objectweb.asm.tree.ClassNode; +@StableAPI(since = "0.10.0") public interface IClassNodeTransformer { + @StableAPI.Expose String getName(); + @StableAPI.Expose boolean shouldTransform(ClassNode cn, String transformedName, boolean obfuscated); + @StableAPI.Expose default int internalSortingOrder() { return 0; } + @StableAPI.Expose void transform(ClassNode cn, String transformedName, boolean obfuscated); } diff --git a/src/main/java/com/falsepattern/lib/asm/SmartTransformer.java b/src/main/java/com/falsepattern/lib/asm/SmartTransformer.java index d141c24..12996c9 100644 --- a/src/main/java/com/falsepattern/lib/asm/SmartTransformer.java +++ b/src/main/java/com/falsepattern/lib/asm/SmartTransformer.java @@ -20,6 +20,7 @@ */ package com.falsepattern.lib.asm; +import com.falsepattern.lib.StableAPI; import com.falsepattern.lib.internal.CoreLoadingPlugin; import lombok.val; import org.apache.logging.log4j.Logger; @@ -35,9 +36,12 @@ import java.util.List; /** * An ASM transformation dispatcher utility, inspired by mixins. */ +@StableAPI(since = "0.10.0") public interface SmartTransformer extends IClassTransformer { + @StableAPI.Expose Logger logger(); + @StableAPI.Expose List transformers(); @Override diff --git a/src/main/java/com/falsepattern/lib/asm/exceptions/AsmClassNotFoundException.java b/src/main/java/com/falsepattern/lib/asm/exceptions/AsmClassNotFoundException.java index 4455331..6e46abc 100644 --- a/src/main/java/com/falsepattern/lib/asm/exceptions/AsmClassNotFoundException.java +++ b/src/main/java/com/falsepattern/lib/asm/exceptions/AsmClassNotFoundException.java @@ -20,7 +20,11 @@ */ package com.falsepattern.lib.asm.exceptions; +import com.falsepattern.lib.StableAPI; + +@StableAPI(since = "0.10.0") public class AsmClassNotFoundException extends AsmTransformException { + @StableAPI.Internal public AsmClassNotFoundException(final String clazz) { super("can't find class " + clazz); } diff --git a/src/main/java/com/falsepattern/lib/asm/exceptions/AsmFieldNotFoundException.java b/src/main/java/com/falsepattern/lib/asm/exceptions/AsmFieldNotFoundException.java index 53f809e..fe4596c 100644 --- a/src/main/java/com/falsepattern/lib/asm/exceptions/AsmFieldNotFoundException.java +++ b/src/main/java/com/falsepattern/lib/asm/exceptions/AsmFieldNotFoundException.java @@ -20,7 +20,11 @@ */ package com.falsepattern.lib.asm.exceptions; +import com.falsepattern.lib.StableAPI; + +@StableAPI(since = "0.10.0") public class AsmFieldNotFoundException extends AsmTransformException { + @StableAPI.Internal public AsmFieldNotFoundException(final String field) { super("can't find field " + field); } diff --git a/src/main/java/com/falsepattern/lib/asm/exceptions/AsmMethodNotFoundException.java b/src/main/java/com/falsepattern/lib/asm/exceptions/AsmMethodNotFoundException.java index 24e0586..62551c7 100644 --- a/src/main/java/com/falsepattern/lib/asm/exceptions/AsmMethodNotFoundException.java +++ b/src/main/java/com/falsepattern/lib/asm/exceptions/AsmMethodNotFoundException.java @@ -20,6 +20,9 @@ */ package com.falsepattern.lib.asm.exceptions; +import com.falsepattern.lib.StableAPI; + +@StableAPI(since = "0.10.0") public class AsmMethodNotFoundException extends AsmTransformException { public AsmMethodNotFoundException(final String method) { super("can't find method " + method); diff --git a/src/main/java/com/falsepattern/lib/asm/exceptions/AsmTransformException.java b/src/main/java/com/falsepattern/lib/asm/exceptions/AsmTransformException.java index 8532287..f21c3c3 100644 --- a/src/main/java/com/falsepattern/lib/asm/exceptions/AsmTransformException.java +++ b/src/main/java/com/falsepattern/lib/asm/exceptions/AsmTransformException.java @@ -20,15 +20,21 @@ */ package com.falsepattern.lib.asm.exceptions; +import com.falsepattern.lib.StableAPI; + +@StableAPI(since = "0.10.0") public class AsmTransformException extends RuntimeException { + @StableAPI.Expose public AsmTransformException(final String message) { super(message); } + @StableAPI.Expose public AsmTransformException(final Throwable cause) { super(cause); } + @StableAPI.Expose public AsmTransformException(final String message, final Throwable cause) { super(message, cause); } diff --git a/src/main/java/com/falsepattern/lib/compat/BlockPos.java b/src/main/java/com/falsepattern/lib/compat/BlockPos.java index a3a5700..aeb1742 100644 --- a/src/main/java/com/falsepattern/lib/compat/BlockPos.java +++ b/src/main/java/com/falsepattern/lib/compat/BlockPos.java @@ -33,8 +33,6 @@ import org.apache.logging.log4j.Logger; import net.minecraft.entity.Entity; import net.minecraft.util.EnumFacing; import net.minecraft.util.Vec3; -import cpw.mods.fml.relauncher.Side; -import cpw.mods.fml.relauncher.SideOnly; import javax.annotation.concurrent.Immutable; import java.util.ArrayList; @@ -53,6 +51,7 @@ public class BlockPos extends Vec3i { /** * An immutable block pos with zero as all coordinates. */ + @StableAPI.Expose public static final BlockPos ORIGIN = new BlockPos(0, 0, 0); private static final Logger LOGGER = LogManager.getLogger(); private static final int NUM_X_BITS = 1 + MathUtil.log2(MathUtil.smallestEncompassingPowerOfTwo(30000000)); @@ -64,22 +63,27 @@ public class BlockPos extends Vec3i { private static final long Z_MASK = (1L << NUM_Z_BITS) - 1L; private static final long X_MASK = (1L << NUM_X_BITS) - 1L; + @StableAPI.Expose public BlockPos(@NonNull Entity source) { this(source.posX, source.posY, source.posZ); } + @StableAPI.Expose public BlockPos(double x, double y, double z) { super(x, y, z); } + @StableAPI.Expose public BlockPos(@NonNull Vec3 vec) { this(vec.xCoord, vec.yCoord, vec.zCoord); } + @StableAPI.Expose public BlockPos(@NonNull Vec3i source) { this(source.getX(), source.getY(), source.getZ()); } + @StableAPI.Expose public BlockPos(int x, int y, int z) { super(x, y, z); } @@ -87,6 +91,7 @@ public class BlockPos extends Vec3i { /** * Create a BlockPos from a serialized long value (created by toLong) */ + @StableAPI.Expose public static BlockPos fromLong(long serialized) { return new BlockPos((int) (serialized << 64 - X_SHIFT - NUM_X_BITS >> 64 - NUM_X_BITS), (int) (serialized << 64 - Y_SHIFT - NUM_Y_BITS >> 64 - NUM_Y_BITS), @@ -99,13 +104,14 @@ public class BlockPos extends Vec3i { *

* In situations where it is usable, prefer * {@link #getAllInBoxMutable(BlockPos, BlockPos) instead as it has better performance (fewer allocations) - * + *

* @param from One corner of the box * @param to Another corner of the box - * + *

* @see #getAllInBox(int, int, int, int, int, int) * @see #getAllInBoxMutable(BlockPos, BlockPos) */ + @StableAPI.Expose public static Iterable getAllInBox(@NonNull BlockPos from, @NonNull BlockPos to) { return getAllInBox(Math.min(from.getX(), to.getX()), Math.min(from.getY(), to.getY()), Math.min(from.getZ(), to.getZ()), Math.max(from.getX(), to.getX()), @@ -118,17 +124,18 @@ public class BlockPos extends Vec3i { *

* In situations where it is usable, prefer * {@link #getAllInBoxMutable(BlockPos, BlockPos) instead as it has better performance (fewer allocations) - * + *

* @param x0 The lower x coordinate * @param y0 The lower y coordinate * @param z0 The lower z coordinate * @param x1 The upper x coordinate * @param y1 The upper y coordinate * @param z1 The upper z coordinate - * + *

* @see #getAllInBox(BlockPos, BlockPos) * @see #getAllInBoxMutable(BlockPos, BlockPos) */ + @StableAPI.Expose public static Iterable getAllInBox(final int x0, final int y0, final int z0, final int x1, final int y1, final int z1) { return () -> new AbstractIterator() { private boolean first = true; @@ -179,6 +186,7 @@ public class BlockPos extends Vec3i { * @see #getAllInBox(int, int, int, int, int, int) * @see #getAllInBoxMutable(BlockPos, BlockPos) */ + @StableAPI.Expose public static Iterable getAllInBoxMutable(@NonNull BlockPos from, @NonNull BlockPos to) { return getAllInBoxMutable(Math.min(from.getX(), to.getX()), Math.min(from.getY(), to.getY()), Math.min(from.getZ(), to.getZ()), Math.max(from.getX(), to.getX()), @@ -205,6 +213,7 @@ public class BlockPos extends Vec3i { * @see #getAllInBox(int, int, int, int, int, int) * @see #getAllInBoxMutable(BlockPos, BlockPos) */ + @StableAPI.Expose public static Iterable getAllInBoxMutable(final int x0, final int y0, final int z0, final int x1, final int y1, final int z1) { return () -> new AbstractIterator() { private MutableBlockPos pos; @@ -233,6 +242,7 @@ public class BlockPos extends Vec3i { }; } + @StableAPI.Expose public long toLong() { return ((long) x & X_MASK) << X_SHIFT | ((long) y & Y_MASK) << Y_SHIFT | ((long) z & Z_MASK); } @@ -240,6 +250,7 @@ public class BlockPos extends Vec3i { /** * Add the given coordinates to the coordinates of this BlockPos */ + @StableAPI.Expose public BlockPos add(double x, double y, double z) { if (x == 0.0D && y == 0.0D && z == 0.0D) { return this; @@ -250,6 +261,7 @@ public class BlockPos extends Vec3i { /** * Add the given Vector to this BlockPos */ + @StableAPI.Expose public BlockPos add(@NonNull Vec3i vec) { return add(vec.getX(), vec.getY(), vec.getZ()); } @@ -257,6 +269,7 @@ public class BlockPos extends Vec3i { /** * Add the given coordinates to the coordinates of this BlockPos */ + @StableAPI.Expose public BlockPos add(int x, int y, int z) { if (x == 0 && y == 0 && z == 0) { return this; @@ -267,18 +280,22 @@ public class BlockPos extends Vec3i { /** * Subtract the given Vector from this BlockPos */ + @StableAPI.Expose public BlockPos subtract(@NonNull Vec3i vec) { return add(-vec.getX(), -vec.getY(), -vec.getZ()); } + @StableAPI.Expose public BlockPos up() { return up(1); } + @StableAPI.Expose public BlockPos up(int blocks) { return offset(UP, blocks); } + @StableAPI.Expose public BlockPos offset(@NonNull EnumFacing facing, int blocks) { if (blocks == 0) { return this; @@ -287,50 +304,62 @@ public class BlockPos extends Vec3i { z + facing.getFrontOffsetZ() * blocks); } + @StableAPI.Expose public BlockPos down() { return down(1); } + @StableAPI.Expose public BlockPos down(int blocks) { return offset(DOWN, blocks); } + @StableAPI.Expose public BlockPos north() { return north(1); } + @StableAPI.Expose public BlockPos north(int blocks) { return offset(NORTH, blocks); } + @StableAPI.Expose public BlockPos south() { return south(1); } + @StableAPI.Expose public BlockPos south(int blocks) { return offset(SOUTH, blocks); } + @StableAPI.Expose public BlockPos west() { return west(1); } + @StableAPI.Expose public BlockPos west(int blocks) { return offset(WEST, blocks); } + @StableAPI.Expose public BlockPos east() { return east(1); } + @StableAPI.Expose public BlockPos east(int blocks) { return offset(EAST, blocks); } + @StableAPI.Expose public BlockPos offset(@NonNull EnumFacing facing) { return offset(facing, 1); } + @StableAPI.Expose public BlockPos rotate(@NonNull Rotation rotation) { switch (rotation) { case NONE: @@ -351,12 +380,14 @@ public class BlockPos extends Vec3i { x * vec.getY() - y * vec.getX()); } + @StableAPI.Expose public BlockPos toImmutable() { return this; } - @Setter - @Getter + @Setter(onMethod_ = @StableAPI.Expose) + @Getter(onMethod_ = @StableAPI.Expose) + @StableAPI(since = "0.10.0") public static class MutableBlockPos extends BlockPos { /** * Mutable X Coordinate @@ -371,14 +402,17 @@ public class BlockPos extends Vec3i { */ protected int z; + @StableAPI.Expose public MutableBlockPos() { this(ORIGIN); } + @StableAPI.Expose public MutableBlockPos(@NonNull BlockPos blockPos) { this(blockPos.getX(), blockPos.getY(), blockPos.getZ()); } + @StableAPI.Expose public MutableBlockPos(int x, int y, int z) { super(ORIGIN); this.x = x; @@ -406,19 +440,21 @@ public class BlockPos extends Vec3i { return super.rotate(rotation).toImmutable(); } + @StableAPI.Expose public BlockPos toImmutable() { return new BlockPos(this); } - @SideOnly(Side.CLIENT) public BlockPos.MutableBlockPos setPos(@NonNull Entity entity) { return this.setPos(entity.posX, entity.posY, entity.posZ); } + @StableAPI.Expose public BlockPos.MutableBlockPos setPos(double x, double y, double z) { return setPos(MathUtil.floor(x), MathUtil.floor(y), MathUtil.floor(z)); } + @StableAPI.Expose public BlockPos.MutableBlockPos setPos(int x, int y, int z) { this.x = x; this.y = y; @@ -426,20 +462,24 @@ public class BlockPos extends Vec3i { return this; } + @StableAPI.Expose public BlockPos.MutableBlockPos setPos(@NonNull Vec3i vec) { return this.setPos(vec.getX(), vec.getY(), vec.getZ()); } + @StableAPI.Expose public BlockPos.MutableBlockPos move(@NonNull EnumFacing facing) { return this.move(facing, 1); } + @StableAPI.Expose public BlockPos.MutableBlockPos move(@NonNull EnumFacing facing, int blocks) { return this.setPos(x + facing.getFrontOffsetX() * blocks, y + facing.getFrontOffsetY() * blocks, z + facing.getFrontOffsetZ() * blocks); } } + @StableAPI(since = "0.10.0") public static final class PooledMutableBlockPos extends BlockPos.MutableBlockPos { private static final List POOL = new ArrayList<>(); private boolean released; @@ -448,10 +488,12 @@ public class BlockPos extends Vec3i { super(x, y, z); } + @StableAPI.Expose public static BlockPos.PooledMutableBlockPos retain() { return retain(0, 0, 0); } + @StableAPI.Expose public static BlockPos.PooledMutableBlockPos retain(int x, int y, int z) { synchronized (POOL) { if (!POOL.isEmpty()) { @@ -466,15 +508,17 @@ public class BlockPos extends Vec3i { return new BlockPos.PooledMutableBlockPos(x, y, z); } + @StableAPI.Expose public static BlockPos.PooledMutableBlockPos retain(double x, double y, double z) { return retain(MathUtil.floor(x), MathUtil.floor(y), MathUtil.floor(z)); } - @SideOnly(Side.CLIENT) + @StableAPI.Expose public static BlockPos.PooledMutableBlockPos retain(@NonNull Vec3i vec) { return retain(vec.getX(), vec.getY(), vec.getZ()); } + @StableAPI.Expose public void release() { synchronized (POOL) { if (POOL.size() < 100) { @@ -485,7 +529,6 @@ public class BlockPos extends Vec3i { } @Override - @SideOnly(Side.CLIENT) public BlockPos.PooledMutableBlockPos setPos(@NonNull Entity entity) { return (BlockPos.PooledMutableBlockPos) super.setPos(entity); } diff --git a/src/main/java/com/falsepattern/lib/compat/ChunkPos.java b/src/main/java/com/falsepattern/lib/compat/ChunkPos.java index 4e124f2..18128c3 100644 --- a/src/main/java/com/falsepattern/lib/compat/ChunkPos.java +++ b/src/main/java/com/falsepattern/lib/compat/ChunkPos.java @@ -41,10 +41,12 @@ public class ChunkPos { /** * The x position of the chunk. */ + @StableAPI.Expose public final int x; /** * The z position of the chunk. */ + @StableAPI.Expose public final int z; /** @@ -52,6 +54,7 @@ public class ChunkPos { * * @param blockPos the block pos */ + @StableAPI.Expose public ChunkPos(@NonNull BlockPos blockPos) { x = blockPos.getX() >> 4; z = blockPos.getZ() >> 4; @@ -65,6 +68,7 @@ public class ChunkPos { * * @return the unique chunk long */ + @StableAPI.Expose public static long asLong(int x, int z) { return (long) x & 0xFFFFFFFFL | ((long) z & 0xFFFFFFFFL) << 32; } @@ -76,6 +80,7 @@ public class ChunkPos { * * @return the distance sq */ + @StableAPI.Expose public double getDistanceSq(@NonNull Entity entity) { val dX = ((x << 4) + 8) - entity.posX; val dY = ((z << 4) + 8) - entity.posZ; @@ -87,6 +92,7 @@ public class ChunkPos { * * @return the x start */ + @StableAPI.Expose public int getXStart() { return x << 4; } @@ -96,6 +102,7 @@ public class ChunkPos { * * @return the z start */ + @StableAPI.Expose public int getZStart() { return z << 4; } @@ -105,6 +112,7 @@ public class ChunkPos { * * @return the x end */ + @StableAPI.Expose public int getXEnd() { return (x << 4) + 15; } @@ -114,6 +122,7 @@ public class ChunkPos { * * @return the z end */ + @StableAPI.Expose public int getZEnd() { return (z << 4) + 15; } @@ -127,6 +136,7 @@ public class ChunkPos { * * @return the relative block position */ + @StableAPI.Expose public BlockPos getBlock(int x, int y, int z) { return new BlockPos((this.x << 4) + x, y, (this.z << 4) + z); } diff --git a/src/main/java/com/falsepattern/lib/compat/GuiLabel.java b/src/main/java/com/falsepattern/lib/compat/GuiLabel.java index 31fffbd..88ee657 100644 --- a/src/main/java/com/falsepattern/lib/compat/GuiLabel.java +++ b/src/main/java/com/falsepattern/lib/compat/GuiLabel.java @@ -49,26 +49,32 @@ public class GuiLabel extends Gui { /** * The id of the label. */ + @StableAPI.Expose public int id; /** * The x position of the label. */ + @StableAPI.Expose public int x; /** * The y position of the label. */ + @StableAPI.Expose public int y; /** * The visibility of the label. */ + @StableAPI.Expose public boolean visible = true; /** * The label width. */ + @StableAPI.Expose protected int width; /** * The label height. */ + @StableAPI.Expose protected int height; private boolean centered = false; @@ -83,6 +89,7 @@ public class GuiLabel extends Gui { * @param height the height * @param textColour the text colour */ + @StableAPI.Expose public GuiLabel(@NonNull FontRenderer fontRenderer, int id, int x, int y, int width, int height, int textColour) { this.fontRenderer = fontRenderer; this.id = id; @@ -98,6 +105,7 @@ public class GuiLabel extends Gui { * * @param text string to add */ + @StableAPI.Expose public void addLine(@NonNull String text) { lines.add(I18n.format(text)); } @@ -107,6 +115,7 @@ public class GuiLabel extends Gui { * * @return the GuiLabel itself */ + @StableAPI.Expose public GuiLabel setCentered() { centered = true; return this; @@ -120,6 +129,7 @@ public class GuiLabel extends Gui { * @param mouseX the mouse x * @param mouseY the mouse y */ + @StableAPI.Expose public void drawLabel(@NonNull Minecraft minecraft, int mouseX, int mouseY) { if (!visible) { return; diff --git a/src/main/java/com/falsepattern/lib/compat/MathHelper.java b/src/main/java/com/falsepattern/lib/compat/MathHelper.java index 0539eef..c0f44f8 100644 --- a/src/main/java/com/falsepattern/lib/compat/MathHelper.java +++ b/src/main/java/com/falsepattern/lib/compat/MathHelper.java @@ -21,6 +21,7 @@ package com.falsepattern.lib.compat; import com.falsepattern.lib.DeprecationDetails; +import com.falsepattern.lib.StableAPI; import com.falsepattern.lib.util.MathUtil; import java.util.Random; @@ -30,6 +31,7 @@ import java.util.Random; */ @Deprecated @DeprecationDetails(deprecatedSince = "0.10.0") +@StableAPI(since = "0.9.2") public class MathHelper { /** * Though it looks like an array, this is really more like a mapping. Key (index of this array) is the upper 5 bits @@ -54,6 +56,7 @@ public class MathHelper { /** * sin looked up in a table */ + @StableAPI.Expose public static float sin(float a) { return SIN_TABLE[(int) (a * 10430.378F) & 65535]; } @@ -61,14 +64,17 @@ public class MathHelper { /** * cos looked up in the sin table with the appropriate offset */ + @StableAPI.Expose public static float cos(float a) { return SIN_TABLE[(int) (a * 10430.378F + 16384.0F) & 65535]; } + @StableAPI.Expose public static float sqrt_float(float a) { return (float) Math.sqrt(a); } + @StableAPI.Expose public static float sqrt_double(double a) { return (float) Math.sqrt(a); } @@ -76,6 +82,7 @@ public class MathHelper { /** * Returns the greatest integer less than or equal to the float argument */ + @StableAPI.Expose public static int floor_float(float a) { int i = (int) a; return a < (float) i ? i - 1 : i; @@ -84,6 +91,7 @@ public class MathHelper { /** * returns par0 cast as an int, and no greater than Integer.MAX_VALUE-1024 */ + @StableAPI.Expose public static int truncateDoubleToInt(double a) { return (int) (a + 1024.0D) - 1024; } @@ -91,6 +99,7 @@ public class MathHelper { /** * Returns the greatest integer less than or equal to the double argument */ + @StableAPI.Expose public static int floor_double(double a) { int i = (int) a; return a < (double) i ? i - 1 : i; @@ -99,15 +108,18 @@ public class MathHelper { /** * Long version of floor_double */ + @StableAPI.Expose public static long floor_double_long(double a) { long i = (long) a; return a < (double) i ? i - 1L : i; } + @StableAPI.Expose public static int absFloor(double a) { return (int) (a >= 0.0D ? a : -a + 1.0D); } + @StableAPI.Expose public static float abs(float a) { return a >= 0.0F ? a : -a; } @@ -115,15 +127,18 @@ public class MathHelper { /** * Returns the unsigned value of an int. */ + @StableAPI.Expose public static int abs_int(int a) { return a >= 0 ? a : -a; } + @StableAPI.Expose public static int ceiling_float_int(float a) { int i = (int) a; return a > (float) i ? i + 1 : i; } + @StableAPI.Expose public static int ceiling_double_int(double a) { int i = (int) a; return a > (double) i ? i + 1 : i; @@ -133,6 +148,7 @@ public class MathHelper { * Returns the value of the first parameter, clamped to be within the lower and upper limits given by the second and * third parameters. */ + @StableAPI.Expose public static int clamp_int(int a, int min, int max) { return a < min ? min : (Math.min(a, max)); } @@ -141,14 +157,17 @@ public class MathHelper { * Returns the value of the first parameter, clamped to be within the lower and upper limits given by the second and * third parameters */ + @StableAPI.Expose public static float clamp_float(float a, float min, float max) { return a < min ? min : Math.min(a, max); } + @StableAPI.Expose public static double clamp_double(double a, double min, double max) { return a < min ? min : Math.min(a, max); } + @StableAPI.Expose public static double denormalizeClamp(double min, double max, double normalized) { return normalized < 0.0D ? min : (normalized > 1.0D ? max : min + (max - min) * normalized); } @@ -156,6 +175,7 @@ public class MathHelper { /** * Maximum of the absolute value of two numbers. */ + @StableAPI.Expose public static double abs_max(double a, double b) { if (a < 0.0D) { a = -a; @@ -171,6 +191,7 @@ public class MathHelper { /** * Buckets an integer with specified bucket sizes. Args: i, bucketSize */ + @StableAPI.Expose public static int bucketInt(int i, int bucketSize) { return i < 0 ? -((-i - 1) / bucketSize) - 1 : i / bucketSize; } @@ -178,22 +199,27 @@ public class MathHelper { /** * Tests if a string is null or of length zero */ + @StableAPI.Expose public static boolean stringNullOrLengthZero(String str) { return str == null || str.length() == 0; } + @StableAPI.Expose public static int getRandomIntegerInRange(Random rng, int min, int max) { return min >= max ? min : rng.nextInt(max - min + 1) + min; } + @StableAPI.Expose public static float randomFloatClamp(Random rng, float min, float max) { return min >= max ? min : rng.nextFloat() * (max - min) + min; } + @StableAPI.Expose public static double getRandomDoubleInRange(Random rng, double min, double max) { return min >= max ? min : rng.nextDouble() * (max - min) + min; } + @StableAPI.Expose public static double average(long[] values) { long i = 0L; @@ -207,6 +233,7 @@ public class MathHelper { /** * the angle is reduced to an angle between -180 and +180 by mod, and a 360 check */ + @StableAPI.Expose public static float wrapAngleTo180_float(float angle) { angle %= 360.0F; @@ -224,6 +251,7 @@ public class MathHelper { /** * the angle is reduced to an angle between -180 and +180 by mod, and a 360 check */ + @StableAPI.Expose public static double wrapAngleTo180_double(double angle) { angle %= 360.0D; @@ -241,6 +269,7 @@ public class MathHelper { /** * parses the string as integer or returns the second parameter if it fails */ + @StableAPI.Expose public static int parseIntWithDefault(String str, int def) { try { return Integer.parseInt(str); @@ -252,6 +281,7 @@ public class MathHelper { /** * parses the string as integer or returns the second parameter if it fails. this value is capped to par2 */ + @StableAPI.Expose public static int parseIntWithDefaultAndMax(String str, int def, int min) { int k; @@ -271,6 +301,7 @@ public class MathHelper { /** * parses the string as double or returns the second parameter if it fails. */ + @StableAPI.Expose public static double parseDoubleWithDefault(String str, double def) { double d1 = def; @@ -282,6 +313,7 @@ public class MathHelper { return d1; } + @StableAPI.Expose public static double parseDoubleWithDefaultAndMin(String str, double def, double min) { double d2; @@ -301,6 +333,7 @@ public class MathHelper { /** * Returns the input value rounded up to the next highest power of two. */ + @StableAPI.Expose public static int roundUpToPowerOfTwo(int a) { int j = a - 1; j |= j >> 1; @@ -332,6 +365,7 @@ public class MathHelper { * Efficiently calculates the floor of the base-2 log of an integer value. This is effectively the index of the * highest bit that is set. For example, if the number in binary is 0...100101, this will return 5. */ + @StableAPI.Expose public static int calculateLogBaseTwo(int a) { /* * Uses a B(2, 5) De Bruijn sequence and a lookup table to efficiently calculate the log-base-two of the given @@ -341,6 +375,7 @@ public class MathHelper { return calculateLogBaseTwoDeBruijn(a) - (isPowerOfTwo(a) ? 0 : 1); } + @StableAPI.Expose public static int roundUp(int a, int b) { if (b == 0) { return 0; diff --git a/src/main/java/com/falsepattern/lib/compat/Rotation.java b/src/main/java/com/falsepattern/lib/compat/Rotation.java index 42e49dc..9bff26b 100644 --- a/src/main/java/com/falsepattern/lib/compat/Rotation.java +++ b/src/main/java/com/falsepattern/lib/compat/Rotation.java @@ -28,16 +28,22 @@ import net.minecraft.util.EnumFacing; @StableAPI(since = "0.6.0") public enum Rotation { + @StableAPI.Expose NONE, + @StableAPI.Expose CLOCKWISE_90, + @StableAPI.Expose CLOCKWISE_180, + @StableAPI.Expose COUNTERCLOCKWISE_90; + @StableAPI.Expose public Rotation add(@NonNull Rotation rotation) { val values = Rotation.values(); return values[(ordinal() + rotation.ordinal()) % values.length]; } + @StableAPI.Expose public EnumFacing rotate(@NonNull EnumFacing facing) { if (facing == EnumFacing.UP || facing == EnumFacing.DOWN) { return facing; @@ -87,6 +93,7 @@ public enum Rotation { } } + @StableAPI.Expose public int rotate(int x, int z) { switch (this) { case CLOCKWISE_90: diff --git a/src/main/java/com/falsepattern/lib/compat/Vec3i.java b/src/main/java/com/falsepattern/lib/compat/Vec3i.java index 349cac9..07c43a1 100644 --- a/src/main/java/com/falsepattern/lib/compat/Vec3i.java +++ b/src/main/java/com/falsepattern/lib/compat/Vec3i.java @@ -42,10 +42,14 @@ public class Vec3i implements Comparable { /** * A static zero vector */ + @StableAPI.Expose public static final Vec3i NULL_VECTOR = new Vec3i(0, 0, 0); + @StableAPI.Expose protected final int x; + @StableAPI.Expose protected final int y; + @StableAPI.Expose protected final int z; /** @@ -55,10 +59,12 @@ public class Vec3i implements Comparable { * @param y the y * @param z the z */ + @StableAPI.Expose public Vec3i(double x, double y, double z) { this(MathUtil.floor(x), MathUtil.floor(y), MathUtil.floor(z)); } + @Override public int compareTo(@NonNull Vec3i vec) { return y == vec.getY() ? z == vec.getZ() ? x - vec.getX() : z - vec.getZ() : y - vec.getY(); } @@ -70,6 +76,7 @@ public class Vec3i implements Comparable { * * @return the new resulting vector */ + @StableAPI.Expose public Vec3i crossProduct(@NonNull Vec3i vec) { return new Vec3i(y * vec.getZ() - z * vec.getY(), z * vec.getX() - x * vec.getZ(), x * vec.getY() - y * vec.getX()); @@ -84,6 +91,7 @@ public class Vec3i implements Comparable { * * @return the distance */ + @StableAPI.Expose public double getDistance(int x, int y, int z) { return Math.sqrt(distanceSq(x, y, z)); } @@ -97,6 +105,7 @@ public class Vec3i implements Comparable { * * @return the square distance */ + @StableAPI.Expose public double distanceSq(int x, int y, int z) { val dX = this.x - x; val dY = this.y - y; @@ -111,6 +120,7 @@ public class Vec3i implements Comparable { * * @return the square distance */ + @StableAPI.Expose public double distanceSq(@NonNull Vec3i vec) { return distanceSq(vec.getX(), vec.getY(), vec.getZ()); } @@ -124,6 +134,7 @@ public class Vec3i implements Comparable { * * @return the square distance to center */ + @StableAPI.Expose public double distanceSqToCenter(double x, double y, double z) { val dX = this.x + 0.5D - x; val dY = this.y + 0.5D - y; diff --git a/src/main/java/com/falsepattern/lib/config/Config.java b/src/main/java/com/falsepattern/lib/config/Config.java index eb676df..b9f8607 100644 --- a/src/main/java/com/falsepattern/lib/config/Config.java +++ b/src/main/java/com/falsepattern/lib/config/Config.java @@ -44,11 +44,13 @@ public @interface Config { /** * The mod id that this configuration is associated with. */ + @StableAPI.Expose String modid(); /** * Root element category, defaults to "general". You must not specify an empty string. */ + @StableAPI.Expose String category() default "general"; /** @@ -59,6 +61,7 @@ public @interface Config { @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) @interface LangKey { + @StableAPI.Expose String value(); } @@ -70,6 +73,7 @@ public @interface Config { @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @interface Comment { + @StableAPI.Expose String[] value(); } @@ -93,6 +97,7 @@ public @interface Config { @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @interface DefaultBoolean { + @StableAPI.Expose boolean value(); } @@ -104,8 +109,9 @@ public @interface Config { @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @interface RangeInt { + @StableAPI.Expose int min() default Integer.MIN_VALUE; - + @StableAPI.Expose int max() default Integer.MAX_VALUE; } @@ -118,6 +124,7 @@ public @interface Config { @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @interface DefaultInt { + @StableAPI.Expose int value(); } @@ -126,14 +133,15 @@ public @interface Config { * Notice: float configs are deprecated! Use double configs instead! */ @Deprecated - @DeprecationDetails(stableSince = "0.6.0", - deprecatedSince = "0.10.0") + @DeprecationDetails(deprecatedSince = "0.10.0") @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) + @StableAPI(since = "0.6.0") @interface RangeFloat { + @StableAPI.Expose float min() default -Float.MAX_VALUE; - + @StableAPI.Expose float max() default Float.MAX_VALUE; } @@ -143,12 +151,13 @@ public @interface Config { * Notice: float configs are deprecated! Use double configs instead! */ @Deprecated - @DeprecationDetails(stableSince = "0.6.0", - deprecatedSince = "0.10.0") + @DeprecationDetails(deprecatedSince = "0.10.0") @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) + @StableAPI(since = "0.6.0") @interface DefaultFloat { + @StableAPI.Expose float value(); } @@ -160,8 +169,9 @@ public @interface Config { @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @interface RangeDouble { + @StableAPI.Expose double min() default -Double.MAX_VALUE; - + @StableAPI.Expose double max() default Double.MAX_VALUE; } @@ -174,6 +184,7 @@ public @interface Config { @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @interface DefaultDouble { + @StableAPI.Expose double value(); } @@ -186,6 +197,7 @@ public @interface Config { @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @interface DefaultString { + @StableAPI.Expose String value(); } @@ -203,6 +215,7 @@ public @interface Config { @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @interface StringMaxLength { + @StableAPI.Expose int value(); } @@ -214,6 +227,7 @@ public @interface Config { @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @interface Pattern { + @StableAPI.Expose String value(); } @@ -226,6 +240,7 @@ public @interface Config { @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @interface DefaultEnum { + @StableAPI.Expose String value(); } @@ -238,6 +253,7 @@ public @interface Config { @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @interface DefaultStringList { + @StableAPI.Expose String[] value(); } @@ -250,6 +266,7 @@ public @interface Config { @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @interface DefaultDoubleList { + @StableAPI.Expose double[] value(); } @@ -262,6 +279,7 @@ public @interface Config { @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @interface DefaultIntList { + @StableAPI.Expose int[] value(); } @@ -274,6 +292,7 @@ public @interface Config { @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @interface DefaultBooleanList { + @StableAPI.Expose boolean[] value(); } @@ -300,6 +319,7 @@ public @interface Config { @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @interface ListMaxLength { + @StableAPI.Expose int value(); } @@ -312,6 +332,7 @@ public @interface Config { @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @interface Name { + @StableAPI.Expose String value(); } diff --git a/src/main/java/com/falsepattern/lib/config/ConfigException.java b/src/main/java/com/falsepattern/lib/config/ConfigException.java index 026da1a..6b137f3 100644 --- a/src/main/java/com/falsepattern/lib/config/ConfigException.java +++ b/src/main/java/com/falsepattern/lib/config/ConfigException.java @@ -28,10 +28,12 @@ import com.falsepattern.lib.StableAPI; @StableAPI(since = "0.6.0") public class ConfigException extends Exception { + @StableAPI.Internal public ConfigException(String message) { super(message); } + @StableAPI.Internal public ConfigException(Throwable cause) { super(cause); } diff --git a/src/main/java/com/falsepattern/lib/config/ConfigurationManager.java b/src/main/java/com/falsepattern/lib/config/ConfigurationManager.java index e3dabc9..4d05c6e 100644 --- a/src/main/java/com/falsepattern/lib/config/ConfigurationManager.java +++ b/src/main/java/com/falsepattern/lib/config/ConfigurationManager.java @@ -97,8 +97,8 @@ public class ConfigurationManager { * @param configClass The class to register. */ @Deprecated - @DeprecationDetails(stableSince = "0.6.0", - deprecatedSince = "0.10.0") + @DeprecationDetails(deprecatedSince = "0.10.0") + @StableAPI.Expose public static void registerConfig(Class configClass) throws ConfigException { FalsePatternLib.getLog() .warn("A mod is using the deprecated config registration method! The following exception contains the stacktrace.", @@ -114,7 +114,7 @@ public class ConfigurationManager { * @return The configuration elements. */ @SuppressWarnings("rawtypes") - @StableAPI(since = "0.6.0") + @StableAPI.Expose public static List getConfigElements(Class configClass) throws ConfigException { return ConfigurationManagerImpl.getConfigElements(configClass); } diff --git a/src/main/java/com/falsepattern/lib/config/IConfigElementProxy.java b/src/main/java/com/falsepattern/lib/config/IConfigElementProxy.java deleted file mode 100644 index 476cef9..0000000 --- a/src/main/java/com/falsepattern/lib/config/IConfigElementProxy.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (C) 2022 FalsePattern - * All Rights Reserved - * - * The above copyright notice, this permission notice and the word "SNEED" - * shall be included in all copies or substantial portions of the Software. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ -package com.falsepattern.lib.config; - -import cpw.mods.fml.client.config.ConfigGuiType; -import cpw.mods.fml.client.config.GuiConfigEntries; -import cpw.mods.fml.client.config.GuiEditArrayEntries; -import cpw.mods.fml.client.config.IConfigElement; - -import java.util.List; -import java.util.regex.Pattern; - -public class IConfigElementProxy implements IConfigElement { - private final IConfigElement proxied; - private final Runnable onUpdate; - - public IConfigElementProxy(IConfigElement proxied, Runnable onUpdate) { - this.proxied = proxied; - this.onUpdate = onUpdate; - } - - @Override - public boolean isProperty() { - return proxied.isProperty(); - } - - @SuppressWarnings("rawtypes") - @Override - public Class getConfigEntryClass() { - return proxied.getConfigEntryClass(); - } - - @Override - public Class getArrayEntryClass() { - return proxied.getArrayEntryClass(); - } - - @Override - public String getName() { - return proxied.getName(); - } - - @Override - public String getQualifiedName() { - return proxied.getQualifiedName(); - } - - @Override - public String getLanguageKey() { - return proxied.getLanguageKey(); - } - - @Override - public String getComment() { - return proxied.getComment(); - } - - @SuppressWarnings("rawtypes") - @Override - public List getChildElements() { - return proxied.getChildElements(); - } - - @Override - public ConfigGuiType getType() { - return proxied.getType(); - } - - @Override - public boolean isList() { - return proxied.isList(); - } - - @Override - public boolean isListLengthFixed() { - return proxied.isListLengthFixed(); - } - - @Override - public int getMaxListLength() { - return proxied.getMaxListLength(); - } - - @Override - public boolean isDefault() { - return proxied.isDefault(); - } - - @Override - public Object getDefault() { - return proxied.getDefault(); - } - - @Override - public Object[] getDefaults() { - return proxied.getDefaults(); - } - - @Override - public void setToDefault() { - proxied.setToDefault(); - } - - @Override - public boolean requiresWorldRestart() { - return proxied.requiresWorldRestart(); - } - - @Override - public boolean showInGui() { - return proxied.showInGui(); - } - - @Override - public boolean requiresMcRestart() { - return proxied.requiresMcRestart(); - } - - @Override - public Object get() { - return proxied.get(); - } - - @Override - public Object[] getList() { - return proxied.getList(); - } - - @Override - public void set(T value) { - proxied.set(value); - onUpdate.run(); - } - - @Override - public void set(T[] aVal) { - proxied.set(aVal); - onUpdate.run(); - } - - @Override - public String[] getValidValues() { - return proxied.getValidValues(); - } - - @Override - public T getMinValue() { - return proxied.getMinValue(); - } - - @Override - public T getMaxValue() { - return proxied.getMaxValue(); - } - - @Override - public Pattern getValidationPattern() { - return proxied.getValidationPattern(); - } -} diff --git a/src/main/java/com/falsepattern/lib/config/SimpleGuiConfig.java b/src/main/java/com/falsepattern/lib/config/SimpleGuiConfig.java index 697be26..07f573f 100644 --- a/src/main/java/com/falsepattern/lib/config/SimpleGuiConfig.java +++ b/src/main/java/com/falsepattern/lib/config/SimpleGuiConfig.java @@ -31,13 +31,14 @@ import cpw.mods.fml.relauncher.SideOnly; @SideOnly(Side.CLIENT) @StableAPI(since = "0.9.0") public class SimpleGuiConfig extends GuiConfig { + @StableAPI.Expose public SimpleGuiConfig(GuiScreen parent, Class configClass, String modID, String modName) throws ConfigException { - this(parent, new Class[]{configClass}, modID, modName); + this(parent, modID, modName, configClass); } @StableAPI(since = "0.10.0") - public SimpleGuiConfig(GuiScreen parent, Class[] configClasses, String modID, String modName) + public SimpleGuiConfig(GuiScreen parent, String modID, String modName, Class... configClasses) throws ConfigException { super(parent, ConfigurationManager.getConfigElementsMulti(configClasses), modID, false, false, modName + " Configuration", I18n.format("falsepatternlib.gui.config.description")); diff --git a/src/main/java/com/falsepattern/lib/config/event/AllConfigSyncEvent.java b/src/main/java/com/falsepattern/lib/config/event/AllConfigSyncEvent.java index f082db2..8e70bca 100644 --- a/src/main/java/com/falsepattern/lib/config/event/AllConfigSyncEvent.java +++ b/src/main/java/com/falsepattern/lib/config/event/AllConfigSyncEvent.java @@ -37,23 +37,27 @@ import cpw.mods.fml.relauncher.SideOnly; */ @SideOnly(Side.CLIENT) @StableAPI(since = "0.10.0") -@NoArgsConstructor(access = AccessLevel.PROTECTED) +@NoArgsConstructor(access = AccessLevel.PROTECTED, + onConstructor_ = @StableAPI.Internal) public class AllConfigSyncEvent extends Event { + @StableAPI.Internal public static boolean postStart() { val event = new Start(); FMLCommonHandler.instance().bus().post(event); return !event.isCanceled(); } + @StableAPI.Internal public static void postEnd() { FMLCommonHandler.instance().bus().post(new End()); } @SideOnly(Side.CLIENT) @StableAPI(since = "0.10.0") - @NoArgsConstructor(access = AccessLevel.PRIVATE) - public static class Start extends AllConfigSyncEvent { + @NoArgsConstructor(access = AccessLevel.PUBLIC, + onConstructor_ = @StableAPI.Internal) + public static final class Start extends AllConfigSyncEvent { @Override public boolean isCancelable() { return true; @@ -62,7 +66,8 @@ public class AllConfigSyncEvent extends Event { @SideOnly(Side.CLIENT) @StableAPI(since = "0.10.0") - @NoArgsConstructor(access = AccessLevel.PRIVATE) - public static class End extends AllConfigSyncEvent { + @NoArgsConstructor(access = AccessLevel.PUBLIC, + onConstructor_ = @StableAPI.Internal) + public static final class End extends AllConfigSyncEvent { } } diff --git a/src/main/java/com/falsepattern/lib/config/event/ConfigSyncEvent.java b/src/main/java/com/falsepattern/lib/config/event/ConfigSyncEvent.java index bc8361a..25ae335 100644 --- a/src/main/java/com/falsepattern/lib/config/event/ConfigSyncEvent.java +++ b/src/main/java/com/falsepattern/lib/config/event/ConfigSyncEvent.java @@ -37,29 +37,35 @@ import cpw.mods.fml.relauncher.SideOnly; */ @SideOnly(Side.CLIENT) @StableAPI(since = "0.10.0") -@RequiredArgsConstructor(access = AccessLevel.PROTECTED) +@RequiredArgsConstructor(access = AccessLevel.PROTECTED, + onConstructor_ = @StableAPI.Internal) public class ConfigSyncEvent extends Event { - @StableAPI(since = "0.10.0") + @StableAPI.Expose public final Class configClass; + @StableAPI.Internal public static boolean postStart(Class configClass) { val event = new Start(configClass); FMLCommonHandler.instance().bus().post(event); return !event.isCanceled(); } + @StableAPI.Internal public static void postEndSuccess(Class configClass) { FMLCommonHandler.instance().bus().post(new End(configClass, true, null)); } + @StableAPI.Internal public static void postEndFailure(Class configClass, Throwable error) { FMLCommonHandler.instance().bus().post(new End(configClass, false, error)); } @SideOnly(Side.CLIENT) @StableAPI(since = "0.10.0") - public static class Start extends ConfigSyncEvent { - private Start(Class configClass) { + public static final class Start extends ConfigSyncEvent { + + @StableAPI.Internal + public Start(Class configClass) { super(configClass); } @@ -71,16 +77,15 @@ public class ConfigSyncEvent extends Event { @SideOnly(Side.CLIENT) @StableAPI(since = "0.10.0") - public static class End extends ConfigSyncEvent { - @StableAPI(since = "0.10.0") + public static final class End extends ConfigSyncEvent { + @StableAPI.Expose public final boolean successful; - /** - * null if successful == true. - */ - @StableAPI(since = "0.10.0") + + @StableAPI.Expose public final Throwable error; - private End(Class configClass, boolean successful, Throwable error) { + @StableAPI.Internal + public End(Class configClass, boolean successful, Throwable error) { super(configClass); this.successful = successful; this.error = error; diff --git a/src/main/java/com/falsepattern/lib/config/event/ConfigSyncRequestEvent.java b/src/main/java/com/falsepattern/lib/config/event/ConfigSyncRequestEvent.java index 0f11a02..406c3d6 100644 --- a/src/main/java/com/falsepattern/lib/config/event/ConfigSyncRequestEvent.java +++ b/src/main/java/com/falsepattern/lib/config/event/ConfigSyncRequestEvent.java @@ -38,28 +38,33 @@ import java.util.List; * {@link #postClient} */ @StableAPI(since = "0.10.0") -@RequiredArgsConstructor(access = AccessLevel.PROTECTED) +@RequiredArgsConstructor(access = AccessLevel.PROTECTED, + onConstructor_ = @StableAPI.Internal) public class ConfigSyncRequestEvent extends Event { - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static void postClient() { FMLCommonHandler.instance().bus().post(new Client()); } - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static void postServer(List players) { FMLCommonHandler.instance().bus().post(new Server(new ArrayList<>(players))); } @StableAPI(since = "0.10.0") - public static class Client extends ConfigSyncRequestEvent { + @RequiredArgsConstructor(access = AccessLevel.PROTECTED, + onConstructor_ = @StableAPI.Internal) + public static final class Client extends ConfigSyncRequestEvent { } - @RequiredArgsConstructor(access = AccessLevel.PRIVATE) @StableAPI(since = "0.10.0") - public static class Server extends ConfigSyncRequestEvent { + @RequiredArgsConstructor(access = AccessLevel.PUBLIC, + onConstructor_ = @StableAPI.Internal) + public static final class Server extends ConfigSyncRequestEvent { private final List players; + @StableAPI.Expose public List getPlayers() { return Collections.unmodifiableList(players); } diff --git a/src/main/java/com/falsepattern/lib/config/event/ConfigValidationFailureEvent.java b/src/main/java/com/falsepattern/lib/config/event/ConfigValidationFailureEvent.java index a94bea6..54071d7 100644 --- a/src/main/java/com/falsepattern/lib/config/event/ConfigValidationFailureEvent.java +++ b/src/main/java/com/falsepattern/lib/config/event/ConfigValidationFailureEvent.java @@ -40,19 +40,21 @@ import cpw.mods.fml.relauncher.SideOnly; import java.lang.reflect.Field; @StableAPI(since = "0.10.0") -@RequiredArgsConstructor(access = AccessLevel.PROTECTED) +@RequiredArgsConstructor(access = AccessLevel.PROTECTED, + onConstructor_ = @StableAPI.Internal) public abstract class ConfigValidationFailureEvent extends Event { - @StableAPI(since = "0.10.0") + @StableAPI.Expose public final String reason; - @StableAPI(since = "0.10.0") + @StableAPI.Expose public final Class configClass; - @StableAPI(since = "0.10.0") + @StableAPI.Expose public final String fieldName; - @StableAPI(since = "0.10.0") + @StableAPI.Expose public final boolean listElement; - @StableAPI(since = "0.10.0") + @StableAPI.Expose public final int listIndex; + @StableAPI.Internal public static void postNumericRangeOutOfBounds(Field field, int listIndex, String value, String min, String max) { FMLCommonHandler.instance() .bus() @@ -60,6 +62,7 @@ public abstract class ConfigValidationFailureEvent extends Event { min, max)); } + @StableAPI.Internal public static void postSize(Field field, int requestedSize, boolean fixedSize, int maxSize, int defaultSize) { FMLCommonHandler.instance() .bus() @@ -67,6 +70,7 @@ public abstract class ConfigValidationFailureEvent extends Event { fixedSize, maxSize, defaultSize)); } + @StableAPI.Internal public static void postStringSizeOutOfBounds(Field field, int listIndex, String text, int maxSize) { FMLCommonHandler.instance() .bus() @@ -74,10 +78,12 @@ public abstract class ConfigValidationFailureEvent extends Event { maxSize)); } + @StableAPI.Internal public static void fieldIsNull(Field field, int listIndex) { FMLCommonHandler.instance().bus().post(new FieldIsNull(field.getDeclaringClass(), field.getName(), listIndex)); } + @StableAPI.Internal public static void postStringPatternMismatch(Field field, int listIndex, String text, String pattern) { FMLCommonHandler.instance() .bus() @@ -86,6 +92,7 @@ public abstract class ConfigValidationFailureEvent extends Event { } @SideOnly(Side.CLIENT) + @StableAPI.Internal public void toast() { val ann = configClass.getAnnotation(Config.class); val toast = new SimpleToast(ToastBG.TOAST_DARK, null, @@ -97,8 +104,10 @@ public abstract class ConfigValidationFailureEvent extends Event { GuiToast.add(toast); } + @StableAPI.Internal protected abstract void customText(StringBuilder b); + @StableAPI.Internal public void logWarn() { val errorString = new StringBuilder("Error validating configuration field!"); errorString.append("\nReason: ").append(reason); @@ -111,14 +120,15 @@ public abstract class ConfigValidationFailureEvent extends Event { } @StableAPI(since = "0.10.0") - public static class NumericRangeOutOfBounds extends ConfigValidationFailureEvent { - @StableAPI(since = "0.10.0") + public static final class NumericRangeOutOfBounds extends ConfigValidationFailureEvent { + @StableAPI.Expose public final String value; - @StableAPI(since = "0.10.0") + @StableAPI.Expose public final String min; - @StableAPI(since = "0.10.0") + @StableAPI.Expose public final String max; + @StableAPI.Internal public NumericRangeOutOfBounds(Class configClass, String fieldName, int listIndex, String value, String min, String max) { super("Number range out of bounds", configClass, fieldName, listIndex >= 0, listIndex); this.value = value; @@ -133,17 +143,18 @@ public abstract class ConfigValidationFailureEvent extends Event { } @StableAPI(since = "0.10.0") - public static class ListSizeOutOfBounds extends ConfigValidationFailureEvent { - @StableAPI(since = "0.10.0") + public static final class ListSizeOutOfBounds extends ConfigValidationFailureEvent { + @StableAPI.Expose public final int size; - @StableAPI(since = "0.10.0") + @StableAPI.Expose public final boolean fixedSize; - @StableAPI(since = "0.10.0") + @StableAPI.Expose public final int maxSize; - @StableAPI(since = "0.10.0") + @StableAPI.Expose public final int defaultSize; - private ListSizeOutOfBounds(Class configClass, String fieldName, int size, boolean fixedSize, int maxSize, int defaultSize) { + @StableAPI.Internal + public ListSizeOutOfBounds(Class configClass, String fieldName, int size, boolean fixedSize, int maxSize, int defaultSize) { super("Array size out of bounds", configClass, fieldName, false, -1); this.size = size; this.fixedSize = fixedSize; @@ -162,13 +173,14 @@ public abstract class ConfigValidationFailureEvent extends Event { } @StableAPI(since = "0.10.0") - public static class StringSizeOutOfBounds extends ConfigValidationFailureEvent { - @StableAPI(since = "0.10.0") + public static final class StringSizeOutOfBounds extends ConfigValidationFailureEvent { + @StableAPI.Expose public final String text; - @StableAPI(since = "0.10.0") + @StableAPI.Expose public final int maxSize; - private StringSizeOutOfBounds(Class configClass, String fieldName, int listIndex, String text, int maxSize) { + @StableAPI.Internal + public StringSizeOutOfBounds(Class configClass, String fieldName, int listIndex, String text, int maxSize) { super("String size out of bounds", configClass, fieldName, listIndex >= 0, listIndex); this.text = text; this.maxSize = maxSize; @@ -186,8 +198,9 @@ public abstract class ConfigValidationFailureEvent extends Event { } @StableAPI(since = "0.10.0") - public static class FieldIsNull extends ConfigValidationFailureEvent { - private FieldIsNull(Class configClass, String fieldName, int listIndex) { + public static final class FieldIsNull extends ConfigValidationFailureEvent { + @StableAPI.Internal + public FieldIsNull(Class configClass, String fieldName, int listIndex) { super("Unexpected null", configClass, fieldName, listIndex >= 0, listIndex); } @@ -198,13 +211,14 @@ public abstract class ConfigValidationFailureEvent extends Event { } @StableAPI(since = "0.10.0") - public static class StringPatternMismatch extends ConfigValidationFailureEvent { - @StableAPI(since = "0.10.0") + public static final class StringPatternMismatch extends ConfigValidationFailureEvent { + @StableAPI.Expose public final String text; - @StableAPI(since = "0.10.0") + @StableAPI.Expose public final String pattern; - private StringPatternMismatch(Class configClass, String fieldName, int listIndex, String text, String pattern) { + @StableAPI.Internal + public StringPatternMismatch(Class configClass, String fieldName, int listIndex, String text, String pattern) { super("String pattern mismatch", configClass, fieldName, listIndex >= 0, listIndex); this.text = text; this.pattern = pattern; diff --git a/src/main/java/com/falsepattern/lib/dependencies/ComplexVersion.java b/src/main/java/com/falsepattern/lib/dependencies/ComplexVersion.java index 3279dbd..59bd9cb 100644 --- a/src/main/java/com/falsepattern/lib/dependencies/ComplexVersion.java +++ b/src/main/java/com/falsepattern/lib/dependencies/ComplexVersion.java @@ -31,6 +31,7 @@ import java.util.stream.Collectors; public class ComplexVersion extends Version { final Version[] versions; + @StableAPI.Expose public ComplexVersion(@NonNull Version mainVersion, Version... subVersions) { this.versions = new Version[subVersions.length + 1]; this.versions[0] = mainVersion; diff --git a/src/main/java/com/falsepattern/lib/dependencies/DependencyLoader.java b/src/main/java/com/falsepattern/lib/dependencies/DependencyLoader.java index 7001ce9..23b7df3 100644 --- a/src/main/java/com/falsepattern/lib/dependencies/DependencyLoader.java +++ b/src/main/java/com/falsepattern/lib/dependencies/DependencyLoader.java @@ -29,11 +29,13 @@ import lombok.NonNull; @StableAPI(since = "0.6.0") public class DependencyLoader { + @StableAPI.Expose public static void addMavenRepo(String url) { DependencyLoaderImpl.addMavenRepo(url); } @Builder + @StableAPI.Expose public static void loadLibrary(@NonNull String loadingModId, @NonNull String groupId, @NonNull String artifactId, @NonNull Version minVersion, Version maxVersion, @NonNull Version preferredVersion, String regularSuffix, String devSuffix) { DependencyLoaderImpl.loadLibrary(loadingModId, groupId, artifactId, minVersion, maxVersion, preferredVersion, regularSuffix, devSuffix); diff --git a/src/main/java/com/falsepattern/lib/dependencies/SemanticVersion.java b/src/main/java/com/falsepattern/lib/dependencies/SemanticVersion.java index 8370d8c..235c0e9 100644 --- a/src/main/java/com/falsepattern/lib/dependencies/SemanticVersion.java +++ b/src/main/java/com/falsepattern/lib/dependencies/SemanticVersion.java @@ -41,11 +41,13 @@ public class SemanticVersion extends Version { @Getter private final String build; + @StableAPI.Expose public SemanticVersion(int majorVersion, int minorVersion, int patchVersion, String preRelease) { this(majorVersion, minorVersion, patchVersion, preRelease, null); } @Builder + @StableAPI.Expose public SemanticVersion(int majorVersion, int minorVersion, int patchVersion, String preRelease, String build) { this.majorVersion = majorVersion; this.minorVersion = minorVersion; @@ -56,6 +58,7 @@ public class SemanticVersion extends Version { this.build = "".equals(build) ? null : build; } + @StableAPI.Expose public SemanticVersion(int majorVersion, int minorVersion, int patchVersion) { this(majorVersion, minorVersion, patchVersion, null, null); } diff --git a/src/main/java/com/falsepattern/lib/dependencies/Version.java b/src/main/java/com/falsepattern/lib/dependencies/Version.java index 073349e..69bf470 100644 --- a/src/main/java/com/falsepattern/lib/dependencies/Version.java +++ b/src/main/java/com/falsepattern/lib/dependencies/Version.java @@ -35,6 +35,7 @@ public abstract class Version implements Comparable { return equals((Version) obj); } + @StableAPI.Expose public boolean equals(Version other) { return compareTo(other) == 0; } diff --git a/src/main/java/com/falsepattern/lib/util/ReflectionUtil.java b/src/main/java/com/falsepattern/lib/internal/ReflectionUtil.java similarity index 97% rename from src/main/java/com/falsepattern/lib/util/ReflectionUtil.java rename to src/main/java/com/falsepattern/lib/internal/ReflectionUtil.java index 8067392..fb172f4 100644 --- a/src/main/java/com/falsepattern/lib/util/ReflectionUtil.java +++ b/src/main/java/com/falsepattern/lib/internal/ReflectionUtil.java @@ -18,7 +18,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ -package com.falsepattern.lib.util; +package com.falsepattern.lib.internal; import lombok.SneakyThrows; diff --git a/src/main/java/com/falsepattern/lib/internal/config/LibraryConfig.java b/src/main/java/com/falsepattern/lib/internal/config/LibraryConfig.java index da91a24..6f18cdf 100644 --- a/src/main/java/com/falsepattern/lib/internal/config/LibraryConfig.java +++ b/src/main/java/com/falsepattern/lib/internal/config/LibraryConfig.java @@ -20,6 +20,7 @@ */ package com.falsepattern.lib.internal.config; +import com.falsepattern.lib.StableAPI; import com.falsepattern.lib.config.Config; import com.falsepattern.lib.internal.Tags; @@ -44,9 +45,13 @@ public class LibraryConfig { @Config.DefaultEnum("Log") public static ValidationLogging CONFIG_ERROR_LOUDNESS; + @StableAPI(since = "__INTERNAL__") public enum ValidationLogging { + @StableAPI.Expose None, + @StableAPI.Expose Log, + @StableAPI.Expose LogAndToast } } diff --git a/src/main/java/com/falsepattern/lib/internal/config/LibraryGuiConfig.java b/src/main/java/com/falsepattern/lib/internal/config/LibraryGuiConfig.java index e525c6f..09cb12f 100644 --- a/src/main/java/com/falsepattern/lib/internal/config/LibraryGuiConfig.java +++ b/src/main/java/com/falsepattern/lib/internal/config/LibraryGuiConfig.java @@ -31,6 +31,6 @@ import cpw.mods.fml.relauncher.SideOnly; @SideOnly(Side.CLIENT) public class LibraryGuiConfig extends SimpleGuiConfig { public LibraryGuiConfig(GuiScreen parent) throws ConfigException { - super(parent, new Class[]{LibraryConfig.class, ToastConfig.class}, Tags.MODID, Tags.MODNAME); + super(parent, Tags.MODID, Tags.MODNAME, LibraryConfig.class, ToastConfig.class); } } diff --git a/src/main/java/com/falsepattern/lib/internal/config/LibraryGuiFactory.java b/src/main/java/com/falsepattern/lib/internal/config/LibraryGuiFactory.java index ea51600..cb1002f 100644 --- a/src/main/java/com/falsepattern/lib/internal/config/LibraryGuiFactory.java +++ b/src/main/java/com/falsepattern/lib/internal/config/LibraryGuiFactory.java @@ -20,6 +20,7 @@ */ package com.falsepattern.lib.internal.config; +import com.falsepattern.lib.StableAPI; import com.falsepattern.lib.config.SimpleGuiFactory; import net.minecraft.client.gui.GuiScreen; @@ -27,6 +28,7 @@ import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; @SideOnly(Side.CLIENT) +@StableAPI(since = "__INTERNAL__") public class LibraryGuiFactory implements SimpleGuiFactory { @Override public Class mainConfigGuiClass() { diff --git a/src/main/java/com/falsepattern/lib/internal/config/ToastConfig.java b/src/main/java/com/falsepattern/lib/internal/config/ToastConfig.java index 2e6eaa0..07078f7 100644 --- a/src/main/java/com/falsepattern/lib/internal/config/ToastConfig.java +++ b/src/main/java/com/falsepattern/lib/internal/config/ToastConfig.java @@ -20,6 +20,7 @@ */ package com.falsepattern.lib.internal.config; +import com.falsepattern.lib.StableAPI; import com.falsepattern.lib.config.Config; import com.falsepattern.lib.internal.Tags; @@ -53,8 +54,11 @@ public class ToastConfig { return ALIGN == Side.Left; } + @StableAPI(since = "__INTERNAL__") public enum Side { + @StableAPI.Expose Left, + @StableAPI.Expose Right } } diff --git a/src/main/java/com/falsepattern/lib/internal/impl/config/ParsedConfiguration.java b/src/main/java/com/falsepattern/lib/internal/impl/config/ParsedConfiguration.java index 38ce24d..4014c25 100644 --- a/src/main/java/com/falsepattern/lib/internal/impl/config/ParsedConfiguration.java +++ b/src/main/java/com/falsepattern/lib/internal/impl/config/ParsedConfiguration.java @@ -24,6 +24,8 @@ import com.falsepattern.lib.config.Config; import com.falsepattern.lib.config.ConfigException; import com.falsepattern.lib.internal.impl.config.fields.AConfigField; import com.falsepattern.lib.internal.impl.config.fields.BooleanConfigField; +import com.falsepattern.lib.internal.impl.config.fields.BooleanListConfigField; +import com.falsepattern.lib.internal.impl.config.fields.DoubleConfigField; import com.falsepattern.lib.internal.impl.config.fields.DoubleListConfigField; import com.falsepattern.lib.internal.impl.config.fields.EnumConfigField; import com.falsepattern.lib.internal.impl.config.fields.FloatConfigField; @@ -31,7 +33,7 @@ import com.falsepattern.lib.internal.impl.config.fields.IntConfigField; import com.falsepattern.lib.internal.impl.config.fields.IntListConfigField; import com.falsepattern.lib.internal.impl.config.fields.StringConfigField; import com.falsepattern.lib.internal.impl.config.fields.StringListConfigField; -import com.falsepattern.lib.util.ReflectionUtil; +import com.falsepattern.lib.internal.ReflectionUtil; import lombok.AccessLevel; import lombok.RequiredArgsConstructor; import lombok.val; @@ -175,12 +177,14 @@ public class ParsedConfiguration { } else if (fieldClass.equals(Float.class) || fieldClass.equals(float.class)) { //noinspection deprecation fields.put(name, new FloatConfigField(field, rawConfig, category)); + } else if (fieldClass.equals(Double.class) || fieldClass.equals(double.class)) { + fields.put(name, new DoubleConfigField(field, rawConfig, category)); } else if (fieldClass.equals(String.class)) { fields.put(name, new StringConfigField(field, rawConfig, category)); } else if (fieldClass.isEnum()) { fields.put(name, new EnumConfigField<>(field, rawConfig, category)); } else if (fieldClass.isArray() && fieldClass.getComponentType().equals(boolean.class)) { - fields.put(name, new StringListConfigField(field, rawConfig, category)); + fields.put(name, new BooleanListConfigField(field, rawConfig, category)); } else if (fieldClass.isArray() && fieldClass.getComponentType().equals(int.class)) { fields.put(name, new IntListConfigField(field, rawConfig, category)); } else if (fieldClass.isArray() && fieldClass.getComponentType().equals(double.class)) { diff --git a/src/main/java/com/falsepattern/lib/internal/impl/config/fields/AConfigField.java b/src/main/java/com/falsepattern/lib/internal/impl/config/fields/AConfigField.java index 702ba76..0c81dde 100644 --- a/src/main/java/com/falsepattern/lib/internal/impl/config/fields/AConfigField.java +++ b/src/main/java/com/falsepattern/lib/internal/impl/config/fields/AConfigField.java @@ -40,7 +40,7 @@ public abstract class AConfigField { protected final String langKey; protected final Property.Type type; protected final Property property; - protected String comment; + protected final String comment; protected AConfigField(Field field, Configuration configuration, String category, Property.Type type) { this(field, configuration, category, type, false); diff --git a/src/main/java/com/falsepattern/lib/internal/impl/config/fields/BooleanListConfigField.java b/src/main/java/com/falsepattern/lib/internal/impl/config/fields/BooleanListConfigField.java index 10f7154..9d44019 100644 --- a/src/main/java/com/falsepattern/lib/internal/impl/config/fields/BooleanListConfigField.java +++ b/src/main/java/com/falsepattern/lib/internal/impl/config/fields/BooleanListConfigField.java @@ -38,7 +38,7 @@ import java.util.Optional; public class BooleanListConfigField extends AListConfigField { private final boolean[] defaultValue; - protected BooleanListConfigField(Field field, Configuration configuration, String category) throws ConfigException { + public BooleanListConfigField(Field field, Configuration configuration, String category) throws ConfigException { super(field, configuration, category, Property.Type.BOOLEAN); defaultValue = Optional.ofNullable(field.getAnnotation(Config.DefaultBooleanList.class)) .map(Config.DefaultBooleanList::value) diff --git a/src/main/java/com/falsepattern/lib/mapping/MappingManager.java b/src/main/java/com/falsepattern/lib/mapping/MappingManager.java index 91ac8c0..2082b9f 100644 --- a/src/main/java/com/falsepattern/lib/mapping/MappingManager.java +++ b/src/main/java/com/falsepattern/lib/mapping/MappingManager.java @@ -20,6 +20,7 @@ */ package com.falsepattern.lib.mapping; +import com.falsepattern.lib.StableAPI; import com.falsepattern.lib.internal.CoreLoadingPlugin; import com.falsepattern.lib.internal.FalsePatternLib; import com.falsepattern.lib.mapping.storage.Lookup; @@ -35,10 +36,13 @@ import org.objectweb.asm.tree.FieldInsnNode; import org.objectweb.asm.tree.MethodInsnNode; import java.util.HashMap; +import java.util.Map; +@StableAPI(since = "0.10.0") public class MappingManager { private static final Lookup internalLookup = new Lookup<>(); private static final Lookup regularLookup = new Lookup<>(); + private static final Map stringPool = new HashMap<>(); private static boolean initialized = false; @SneakyThrows @@ -47,8 +51,6 @@ public class MappingManager { return; } initialized = true; - long start = System.nanoTime(); - val stringPool = new HashMap(); { val classMappings = ResourceUtil.getResourceStringFromJar("/classes.csv", FalsePatternLib.class).split("\n"); @@ -64,7 +66,7 @@ public class MappingManager { for (int i = 1; i < fieldMappings.length; i++) { val line = fieldMappings[i].split(","); val clazz = internalLookup.get(MappingType.Notch, line[0].substring(0, line[0].lastIndexOf('/'))); - new UniversalField(clazz, line, stringPool); + UniversalField.createAndAddToParent(clazz, line, stringPool); } } { @@ -73,13 +75,12 @@ public class MappingManager { for (int i = 1; i < methodMappings.length; i++) { val line = methodMappings[i].split(","); val clazz = internalLookup.get(MappingType.Notch, line[0].substring(0, line[0].lastIndexOf('/'))); - new UniversalMethod(clazz, line, stringPool); + UniversalMethod.createAndAddToParent(clazz, line, stringPool); } } - long end = System.nanoTime(); - System.out.println("Parsed in " + (end - start) / 1000000 + "ms"); } + @StableAPI.Expose public static UniversalClass classForName(NameType nameType, MappingType mappingType, String className) throws ClassNotFoundException { initialize(); @@ -99,6 +100,7 @@ public class MappingManager { } } + @StableAPI.Expose public static boolean containsClass(NameType nameType, MappingType mappingType, String className) { switch (nameType) { case Internal: @@ -110,6 +112,7 @@ public class MappingManager { } } + @StableAPI.Expose public static UniversalField getField(FieldInsnNode instruction) throws ClassNotFoundException, NoSuchFieldException { if (!CoreLoadingPlugin.isObfuscated()) { @@ -136,6 +139,7 @@ public class MappingManager { } } + @StableAPI.Expose public static UniversalMethod getMethod(MethodInsnNode instruction) throws ClassNotFoundException, NoSuchMethodException { if (!CoreLoadingPlugin.isObfuscated()) { diff --git a/src/main/java/com/falsepattern/lib/mapping/storage/Lookup.java b/src/main/java/com/falsepattern/lib/mapping/storage/Lookup.java index 47120fc..570d26a 100644 --- a/src/main/java/com/falsepattern/lib/mapping/storage/Lookup.java +++ b/src/main/java/com/falsepattern/lib/mapping/storage/Lookup.java @@ -20,6 +20,7 @@ */ package com.falsepattern.lib.mapping.storage; +import com.falsepattern.lib.StableAPI; import com.falsepattern.lib.mapping.types.MappingType; import lombok.EqualsAndHashCode; import lombok.NonNull; @@ -34,6 +35,7 @@ import java.util.Set; @Accessors(fluent = true) @EqualsAndHashCode +@StableAPI(since = "0.10.0") public class Lookup { private final Set values = new HashSet<>(); private final Map notch = new HashMap<>(); @@ -50,10 +52,12 @@ public class Lookup { } } + @StableAPI.Expose public boolean contains(T value) { return values.contains(value); } + @StableAPI.Expose public boolean containsKey(MappingType mappingType, String key) { switch (mappingType) { case Notch: @@ -67,6 +71,7 @@ public class Lookup { } } + @StableAPI.Expose public void unwrap(@NonNull MappedString mappedString, @NonNull T value) { if (contains(value)) { //Collision avoidance. @@ -81,6 +86,7 @@ public class Lookup { mcp.put(mappedString.mcp, value); } + @StableAPI.Expose public T get(MappingType mappingType, String key) throws LookupException { T result; switch (mappingType) { @@ -102,6 +108,7 @@ public class Lookup { return result; } + @StableAPI(since = "0.10.0") public static class LookupException extends Exception { public LookupException(String message) { super(message); diff --git a/src/main/java/com/falsepattern/lib/mapping/storage/MappedString.java b/src/main/java/com/falsepattern/lib/mapping/storage/MappedString.java index 957d83a..1600bc6 100644 --- a/src/main/java/com/falsepattern/lib/mapping/storage/MappedString.java +++ b/src/main/java/com/falsepattern/lib/mapping/storage/MappedString.java @@ -20,6 +20,7 @@ */ package com.falsepattern.lib.mapping.storage; +import com.falsepattern.lib.StableAPI; import com.falsepattern.lib.mapping.types.MappingType; import lombok.AccessLevel; import lombok.EqualsAndHashCode; @@ -36,23 +37,32 @@ import java.util.function.Function; @EqualsAndHashCode @Getter @RequiredArgsConstructor(access = AccessLevel.PRIVATE) +@StableAPI(since = "0.10.0") public class MappedString { + @StableAPI.Expose public final String notch; + + @StableAPI.Expose public final String srg; + + @StableAPI.Expose public final String mcp; + @StableAPI.Expose public MappedString(String[] source, int offset, int stride, Function remapper, Map stringPool) { notch = stringPool.computeIfAbsent(remapper.apply(source[offset]), (str) -> str); srg = stringPool.computeIfAbsent(remapper.apply(source[offset + stride]), (str) -> str); mcp = stringPool.computeIfAbsent(remapper.apply(source[offset + stride * 2]), (str) -> str); } + @StableAPI.Expose public static MappedString fuse(MappedString a, MappedString b, String delimiter, Map stringPool) { return new MappedString(stringPool.computeIfAbsent(a.notch + delimiter + b.notch, (str) -> str), stringPool.computeIfAbsent(a.srg + delimiter + b.srg, (str) -> str), stringPool.computeIfAbsent(a.mcp + delimiter + b.mcp, (str) -> str)); } + @StableAPI.Expose public String get(MappingType type) { switch (type) { case Notch: diff --git a/src/main/java/com/falsepattern/lib/mapping/types/MappingType.java b/src/main/java/com/falsepattern/lib/mapping/types/MappingType.java index a240717..d16e4c3 100644 --- a/src/main/java/com/falsepattern/lib/mapping/types/MappingType.java +++ b/src/main/java/com/falsepattern/lib/mapping/types/MappingType.java @@ -20,8 +20,14 @@ */ package com.falsepattern.lib.mapping.types; +import com.falsepattern.lib.StableAPI; + +@StableAPI(since = "0.10.0") public enum MappingType { + @StableAPI.Expose Notch, + @StableAPI.Expose SRG, + @StableAPI.Expose MCP } diff --git a/src/main/java/com/falsepattern/lib/mapping/types/NameType.java b/src/main/java/com/falsepattern/lib/mapping/types/NameType.java index 5250481..691677d 100644 --- a/src/main/java/com/falsepattern/lib/mapping/types/NameType.java +++ b/src/main/java/com/falsepattern/lib/mapping/types/NameType.java @@ -20,7 +20,12 @@ */ package com.falsepattern.lib.mapping.types; +import com.falsepattern.lib.StableAPI; + +@StableAPI(since = "0.10.0") public enum NameType { + @StableAPI.Expose Internal, + @StableAPI.Expose Regular } \ No newline at end of file diff --git a/src/main/java/com/falsepattern/lib/mapping/types/UniversalClass.java b/src/main/java/com/falsepattern/lib/mapping/types/UniversalClass.java index 2b7d9af..b6fbd31 100644 --- a/src/main/java/com/falsepattern/lib/mapping/types/UniversalClass.java +++ b/src/main/java/com/falsepattern/lib/mapping/types/UniversalClass.java @@ -20,6 +20,7 @@ */ package com.falsepattern.lib.mapping.types; +import com.falsepattern.lib.StableAPI; import com.falsepattern.lib.internal.CoreLoadingPlugin; import com.falsepattern.lib.mapping.storage.Lookup; import com.falsepattern.lib.mapping.storage.MappedString; @@ -33,12 +34,13 @@ import java.util.Map; @Accessors(fluent = true) @ToString(onlyExplicitlyIncluded = true) @EqualsAndHashCode(onlyExplicitlyIncluded = true) +@StableAPI(since = "0.10.0") public class UniversalClass { - @Getter + @Getter(onMethod_ = @StableAPI.Expose) @ToString.Include @EqualsAndHashCode.Include public final MappedString internalName; - @Getter + @Getter(onMethod_ = @StableAPI.Expose) @ToString.Include @EqualsAndHashCode.Include public final MappedString regularName; @@ -50,25 +52,27 @@ public class UniversalClass { @Getter private MappingType realClassMapping = null; + @StableAPI.Expose public UniversalClass(String[] names, Map stringPool) { internalName = new MappedString(names, 0, 1, (str) -> str, stringPool); regularName = new MappedString(names, 0, 1, (str) -> str.replace('/', '.'), stringPool); } - public void addField(UniversalField field) { + void addField(UniversalField field) { if (field.parent != this) { throw new IllegalArgumentException("Field's parent is not this class"); } fields.unwrap(field.name, field); } - public void addMethod(UniversalMethod method) { + void addMethod(UniversalMethod method) { if (method.parent != this) { throw new IllegalArgumentException("Method's parent is not this class"); } methods.unwrap(method.fusedNameDescriptor, method); } + @StableAPI.Expose public Class asJavaClass() throws ClassNotFoundException { if (javaClassCache != null) { return javaClassCache; @@ -93,6 +97,7 @@ public class UniversalClass { return javaClassCache; } + @StableAPI.Expose public String getName(NameType nameType, MappingType mappingType) { switch (nameType) { case Internal: @@ -104,10 +109,12 @@ public class UniversalClass { } } + @StableAPI.Expose public String getNameAsDescriptor(MappingType mappingType) { return "L" + getName(NameType.Internal, mappingType) + ";"; } + @StableAPI.Expose public UniversalField getField(MappingType mappingType, String fieldName) throws NoSuchFieldException { try { return fields.get(mappingType, fieldName); @@ -116,6 +123,7 @@ public class UniversalClass { } } + @StableAPI.Expose public UniversalMethod getMethod(MappingType mappingType, String methodName, String methodDescriptor) throws NoSuchMethodException { try { diff --git a/src/main/java/com/falsepattern/lib/mapping/types/UniversalField.java b/src/main/java/com/falsepattern/lib/mapping/types/UniversalField.java index cf35d67..10d6eaf 100644 --- a/src/main/java/com/falsepattern/lib/mapping/types/UniversalField.java +++ b/src/main/java/com/falsepattern/lib/mapping/types/UniversalField.java @@ -20,11 +20,13 @@ */ package com.falsepattern.lib.mapping.types; +import com.falsepattern.lib.StableAPI; import com.falsepattern.lib.mapping.storage.MappedString; -import com.falsepattern.lib.util.ReflectionUtil; +import com.falsepattern.lib.internal.ReflectionUtil; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; +import lombok.SneakyThrows; import lombok.ToString; import lombok.experimental.Accessors; import lombok.val; @@ -36,27 +38,35 @@ import java.util.Map; @Accessors(fluent = true) @ToString @EqualsAndHashCode +@StableAPI(since = "0.10.0") public class UniversalField { - @Getter + @Getter(onMethod_ = @StableAPI.Expose) @ToString.Exclude @EqualsAndHashCode.Exclude public final UniversalClass parent; - @Getter + @Getter(onMethod_ = @StableAPI.Expose) public final MappedString name; private Field javaFieldCache = null; - public UniversalField(@NonNull UniversalClass parent, String[] names, Map stringPool) { + private UniversalField(@NonNull UniversalClass parent, String[] names, Map stringPool) { this.parent = parent; name = new MappedString(names, 0, 1, (str) -> str.substring(str.lastIndexOf('/') + 1), stringPool); parent.addField(this); } + @StableAPI.Expose + public static void createAndAddToParent(@NonNull UniversalClass parent, String[] names, Map stringPool) { + new UniversalField(parent, names, stringPool); + } + + @StableAPI.Expose public String getName(MappingType mappingType) { return name.get(mappingType); } + @StableAPI.Expose public Field asJavaField() throws ClassNotFoundException, NoSuchFieldException { if (javaFieldCache != null) { return javaFieldCache; @@ -67,6 +77,18 @@ public class UniversalField { return javaFieldCache; } + /** + * A convenience method for {@link Field#get(Object)} with a {@link SneakyThrows} annotation, so that + * you don't need to manually handle exceptions. + */ + @SuppressWarnings("unchecked") + @StableAPI.Expose + public T get(Object instance) throws NoSuchFieldException, ClassNotFoundException, IllegalAccessException { + val field = asJavaField(); + return (T) field.get(instance); + } + + @StableAPI.Expose public FieldInsnNode asInstruction(int opcode, MappingType mapping, String descriptor) { return new FieldInsnNode(opcode, parent.getName(NameType.Internal, mapping), getName(mapping), descriptor); } diff --git a/src/main/java/com/falsepattern/lib/mapping/types/UniversalMethod.java b/src/main/java/com/falsepattern/lib/mapping/types/UniversalMethod.java index d512a4f..7750065 100644 --- a/src/main/java/com/falsepattern/lib/mapping/types/UniversalMethod.java +++ b/src/main/java/com/falsepattern/lib/mapping/types/UniversalMethod.java @@ -20,11 +20,13 @@ */ package com.falsepattern.lib.mapping.types; +import com.falsepattern.lib.StableAPI; import com.falsepattern.lib.mapping.storage.MappedString; -import com.falsepattern.lib.util.ReflectionUtil; +import com.falsepattern.lib.internal.ReflectionUtil; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; +import lombok.SneakyThrows; import lombok.ToString; import lombok.experimental.Accessors; import lombok.val; @@ -38,22 +40,25 @@ import java.util.Map; @Accessors(fluent = true) @ToString @EqualsAndHashCode +@StableAPI(since = "0.10.0") public class UniversalMethod { - @Getter + @Getter(onMethod_ = @StableAPI.Expose) @ToString.Exclude @EqualsAndHashCode.Exclude public final UniversalClass parent; - @Getter + @Getter(onMethod_ = @StableAPI.Expose) public final MappedString name; - @Getter + + @Getter(onMethod_ = @StableAPI.Expose) public final MappedString descriptor; - @Getter + + @Getter(onMethod_ = @StableAPI.Expose) public final MappedString fusedNameDescriptor; private Method javaMethodCache = null; - public UniversalMethod(@NonNull UniversalClass parent, String[] names, Map stringPool) { + private UniversalMethod(@NonNull UniversalClass parent, String[] names, Map stringPool) { this.parent = parent; name = new MappedString(names, 0, 2, (str) -> str.substring(str.lastIndexOf('/') + 1), stringPool); descriptor = new MappedString(names, 1, 2, (str) -> str, stringPool); @@ -61,6 +66,11 @@ public class UniversalMethod { parent.addMethod(this); } + @StableAPI.Expose + public static void createAndAddToParent(@NonNull UniversalClass parent, String[] names, Map stringPool) { + new UniversalMethod(parent, names, stringPool); + } + private static Class[] decodeMethodDescriptor(String desc) throws ClassNotFoundException { val result = new ArrayList>(); val buf = new StringBuilder(); @@ -124,14 +134,17 @@ public class UniversalMethod { return result.toArray(new Class[0]); } + @StableAPI.Expose public String getName(MappingType mappingType) { return name.get(mappingType); } + @StableAPI.Expose public String getDescriptor(MappingType mappingType) { return descriptor.get(mappingType); } + @StableAPI.Expose public Method asJavaMethod() throws ClassNotFoundException, NoSuchMethodException { if (javaMethodCache != null) { return javaMethodCache; @@ -143,15 +156,34 @@ public class UniversalMethod { return javaMethodCache; } + /** + * A convenience method for {@link Method#invoke(Object, Object...)} with a {@link SneakyThrows} annotation, so that + * you don't need to manually handle exceptions. + */ + @SuppressWarnings("unchecked") + @SneakyThrows + @StableAPI.Expose + public T invoke(Object instance, Object... arguments) { + val m = asJavaMethod(); + return (T) m.invoke(instance, arguments); + } + + @StableAPI.Expose + public T invokeStatic(Object... arguments) { + return invoke(null, arguments); + } + /** * This is only here for completeness' sake, given that MethodInsnNode itself also has a deprecated yet functional constructor. */ @Deprecated + @StableAPI.Expose public MethodInsnNode asInstruction(int opcode, MappingType mapping) { return new MethodInsnNode(opcode, parent.getName(NameType.Internal, mapping), getName(mapping), getDescriptor(mapping)); } + @StableAPI.Expose public MethodInsnNode asInstruction(int opcode, MappingType mapping, boolean itf) { return new MethodInsnNode(opcode, parent.getName(NameType.Internal, mapping), getName(mapping), getDescriptor(mapping), itf); diff --git a/src/main/java/com/falsepattern/lib/mixin/IMixin.java b/src/main/java/com/falsepattern/lib/mixin/IMixin.java index b579788..0b99371 100644 --- a/src/main/java/com/falsepattern/lib/mixin/IMixin.java +++ b/src/main/java/com/falsepattern/lib/mixin/IMixin.java @@ -32,41 +32,54 @@ import java.util.function.Supplier; @StableAPI(since = "0.8.0") public interface IMixin { + @StableAPI.Expose String getMixin(); + @StableAPI.Expose + Side getSide(); + + @StableAPI.Expose + Predicate> getFilter(); + default boolean shouldLoad(List loadedMods) { val side = getSide(); return (side == Side.COMMON || side == Side.SERVER && FMLLaunchHandler.side().isServer() || side == Side.CLIENT && FMLLaunchHandler.side().isClient()) && getFilter().test(loadedMods); } - Side getSide(); - - Predicate> getFilter(); - + @StableAPI(since = "0.10.0") enum Side { + @StableAPI.Expose COMMON, + @StableAPI.Expose CLIENT, + @StableAPI.Expose SERVER } + @StableAPI(since = "0.10.0") final class PredicateHelpers { + @StableAPI.Expose public static Predicate> never() { return (list) -> false; } + @StableAPI.Expose public static Predicate> condition(Supplier condition) { return (list) -> condition.get(); } + @StableAPI.Expose public static Predicate> always() { return (list) -> true; } + @StableAPI.Expose public static Predicate> require(ITargetedMod mod) { return (list) -> list.contains(mod); } + @StableAPI.Expose public static Predicate> avoid(ITargetedMod mod) { return (list) -> !list.contains(mod); } diff --git a/src/main/java/com/falsepattern/lib/mixin/IMixinPlugin.java b/src/main/java/com/falsepattern/lib/mixin/IMixinPlugin.java index 1eeff02..4cf177e 100644 --- a/src/main/java/com/falsepattern/lib/mixin/IMixinPlugin.java +++ b/src/main/java/com/falsepattern/lib/mixin/IMixinPlugin.java @@ -45,12 +45,15 @@ import static java.nio.file.Files.walk; @StableAPI(since = "0.8.0") public interface IMixinPlugin extends IMixinConfigPlugin { + @StableAPI.Expose Path MODS_DIRECTORY_PATH = FileUtil.getMinecraftHome().toPath().resolve("mods"); + @StableAPI.Expose static Logger createLogger(String modName) { return LogManager.getLogger(modName + " Mixin Loader"); } + @StableAPI.Expose static File findJarOf(final ITargetedMod mod) { try (val stream = walk(MODS_DIRECTORY_PATH)) { return stream.filter(mod::isMatchingJar).map(Path::toFile).findFirst().orElse(null); @@ -60,6 +63,15 @@ public interface IMixinPlugin extends IMixinConfigPlugin { } } + @StableAPI.Expose + Logger getLogger(); + + @StableAPI.Expose + IMixin[] getMixinEnumValues(); + + @StableAPI.Expose + ITargetedMod[] getTargetedModEnumValues(); + @Override default void onLoad(String mixinPackage) { @@ -107,8 +119,6 @@ public interface IMixinPlugin extends IMixinConfigPlugin { return mixins; } - ITargetedMod[] getTargetedModEnumValues(); - default boolean loadJarOf(final ITargetedMod mod) { boolean success = false; try { @@ -130,10 +140,6 @@ public interface IMixinPlugin extends IMixinConfigPlugin { return success; } - Logger getLogger(); - - IMixin[] getMixinEnumValues(); - @Override default void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { diff --git a/src/main/java/com/falsepattern/lib/mixin/ITargetedMod.java b/src/main/java/com/falsepattern/lib/mixin/ITargetedMod.java index 4493455..3217f96 100644 --- a/src/main/java/com/falsepattern/lib/mixin/ITargetedMod.java +++ b/src/main/java/com/falsepattern/lib/mixin/ITargetedMod.java @@ -29,11 +29,14 @@ import java.util.function.Predicate; @StableAPI(since = "0.8.0") public interface ITargetedMod { + @StableAPI.Expose String getModName(); + @StableAPI.Expose boolean isLoadInDevelopment(); @SuppressWarnings("UnstableApiUsage") + @StableAPI.Expose default boolean isMatchingJar(Path path) { String pathString = path.toString(); String nameLowerCase = Files.getNameWithoutExtension(pathString).toLowerCase(); @@ -41,18 +44,22 @@ public interface ITargetedMod { return "jar".equals(fileExtension) && getCondition().test(nameLowerCase); } - + @StableAPI.Expose Predicate getCondition(); + @StableAPI(since = "0.5.0") final class PredicateHelpers { + @StableAPI.Expose public static Predicate startsWith(String subString) { return (name) -> name.startsWith(subString.toLowerCase()); } + @StableAPI.Expose public static Predicate contains(String subString) { return (name) -> name.contains(subString.toLowerCase()); } + @StableAPI.Expose public static Predicate matches(String regex) { return (name) -> name.matches(regex); } diff --git a/src/main/java/com/falsepattern/lib/mixin/MinecraftURLClassPath.java b/src/main/java/com/falsepattern/lib/mixin/MinecraftURLClassPath.java index 1eb44ed..e6293a8 100644 --- a/src/main/java/com/falsepattern/lib/mixin/MinecraftURLClassPath.java +++ b/src/main/java/com/falsepattern/lib/mixin/MinecraftURLClassPath.java @@ -20,6 +20,7 @@ */ package com.falsepattern.lib.mixin; +import com.falsepattern.lib.StableAPI; import lombok.AccessLevel; import lombok.NoArgsConstructor; import lombok.val; @@ -38,6 +39,7 @@ import java.net.URL; * Also added Grimoire protection. */ @NoArgsConstructor(access = AccessLevel.PRIVATE) +@StableAPI(since = "0.10.0") public final class MinecraftURLClassPath { /** * Utility to manipulate the minecraft URL ClassPath @@ -93,6 +95,7 @@ public final class MinecraftURLClassPath { * Adds a Jar to the Minecraft URL ClassPath - Needed when using mixins on classes outside of Minecraft or other * coremods */ + @StableAPI.Expose public static void addJar(File pathToJar) throws Exception { if (!GRIMOIRE) { addURL.invoke(ucp, pathToJar.toURI().toURL()); diff --git a/src/main/java/com/falsepattern/lib/text/FormattedText.java b/src/main/java/com/falsepattern/lib/text/FormattedText.java index a41cf25..f7ae9eb 100644 --- a/src/main/java/com/falsepattern/lib/text/FormattedText.java +++ b/src/main/java/com/falsepattern/lib/text/FormattedText.java @@ -149,6 +149,7 @@ public final class FormattedText { * * @return The parsed text structure */ + @StableAPI.Expose public static FormattedText parse(String text) { EnumChatFormatting currentColorStyle = EnumChatFormatting.WHITE; val currentFancyStyle = new HashSet(); @@ -198,6 +199,7 @@ public final class FormattedText { return result; } + @StableAPI.Expose public void addChatMessage(ICommandSender target) { addChatMessage(target::addChatMessage); } @@ -214,6 +216,7 @@ public final class FormattedText { * * @return The chat component. */ + @StableAPI.Expose public List toChatText() { var thisComponent = toChatTextSingle(); val result = new ArrayList(); @@ -261,27 +264,33 @@ public final class FormattedText { } @SideOnly(Side.CLIENT) + @StableAPI.Expose public void addChatMessage(EntityOtherPlayerMP target) { addChatMessage(target::addChatMessage); } @SideOnly(Side.CLIENT) + @StableAPI.Expose public void addChatMessage(EntityPlayerSP target) { addChatMessage(target::addChatMessage); } + @StableAPI.Expose public void addChatMessage(CommandBlockLogic target) { addChatMessage(target::addChatMessage); } + @StableAPI.Expose public void addChatMessage(EntityPlayerMP target) { addChatMessage(target::addChatMessage); } + @StableAPI.Expose public void addChatMessage(RConConsoleSource target) { addChatMessage(target::addChatMessage); } + @StableAPI.Expose public void addChatMessage(MinecraftServer target) { addChatMessage(target::addChatMessage); } @@ -294,6 +303,7 @@ public final class FormattedText { * @param y Top side */ @SideOnly(Side.CLIENT) + @StableAPI.Expose public void draw(FontRenderer renderer, int x, int y) { draw(renderer, x, y, false); } @@ -307,6 +317,7 @@ public final class FormattedText { * @param shadow Whether to have drop shadow under the text */ @SideOnly(Side.CLIENT) + @StableAPI.Expose public void draw(FontRenderer renderer, int x, int y, boolean shadow) { int startX = x; x = renderer.drawString(text, x, y, colorMap.get(colorStyle).getRGB(), shadow); @@ -331,6 +342,7 @@ public final class FormattedText { * @param y Top side */ @SideOnly(Side.CLIENT) + @StableAPI.Expose public void drawWithShadow(FontRenderer renderer, int x, int y) { draw(renderer, x, y, true); } diff --git a/src/main/java/com/falsepattern/lib/toasts/GuiToast.java b/src/main/java/com/falsepattern/lib/toasts/GuiToast.java index 9f15bb8..b84ca15 100644 --- a/src/main/java/com/falsepattern/lib/toasts/GuiToast.java +++ b/src/main/java/com/falsepattern/lib/toasts/GuiToast.java @@ -31,18 +31,18 @@ import javax.annotation.Nullable; @SideOnly(Side.CLIENT) @StableAPI(since = "0.10.0") public class GuiToast { - @StableAPI(since = "0.10.0") @Nullable + @StableAPI.Expose public static T getToast(Class toastClass, Object type) { return GuiToastImpl.getInstance().getToast(toastClass, type); } - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static void clear() { GuiToastImpl.getInstance().clear(); } - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static void add(IToast toastIn) { GuiToastImpl.getInstance().add(toastIn); } diff --git a/src/main/java/com/falsepattern/lib/toasts/IToast.java b/src/main/java/com/falsepattern/lib/toasts/IToast.java index c0b5309..ae4c630 100644 --- a/src/main/java/com/falsepattern/lib/toasts/IToast.java +++ b/src/main/java/com/falsepattern/lib/toasts/IToast.java @@ -33,25 +33,25 @@ import cpw.mods.fml.relauncher.SideOnly; @SideOnly(Side.CLIENT) @StableAPI(since = "0.10.0") public interface IToast { - @StableAPI(since = "0.10.0") + @StableAPI.Expose Object NO_TOKEN = new Object(); - @StableAPI(since = "0.10.0") + @StableAPI.Expose Visibility draw(GuiToastImpl toastGui, long delta); - @StableAPI(since = "0.10.0") + @StableAPI.Expose int width(); - @StableAPI(since = "0.10.0") + @StableAPI.Expose int height(); - @StableAPI(since = "0.10.0") + @StableAPI.Expose default Object getType() { return NO_TOKEN; } - @StableAPI(since = "0.10.0") @SideOnly(Side.CLIENT) + @StableAPI(since = "0.10.0") enum Visibility { SHOW(new ResourceLocation(Tags.MODID, "ui.toast.in")), HIDE(new ResourceLocation(Tags.MODID, "ui.toast.out")); @@ -62,7 +62,7 @@ public interface IToast { this.sound = soundIn; } - @StableAPI(since = "0.10.0") + @StableAPI.Expose public void playSound(SoundHandler handler) { handler.playSound(PositionedSoundRecord.func_147674_a(this.sound, 1.0F)); } diff --git a/src/main/java/com/falsepattern/lib/toasts/SimpleToast.java b/src/main/java/com/falsepattern/lib/toasts/SimpleToast.java index fb72d87..abc62d1 100644 --- a/src/main/java/com/falsepattern/lib/toasts/SimpleToast.java +++ b/src/main/java/com/falsepattern/lib/toasts/SimpleToast.java @@ -50,7 +50,7 @@ public class SimpleToast implements IToast { private float displayedProgress; private float currentProgress; - @StableAPI(since = "0.10.0") + @StableAPI.Expose public SimpleToast(@NonNull ToastBG background, @Nullable ToastIcon icon, IChatComponent titleComponent, @Nullable IChatComponent subtitleComponent, boolean drawProgressBar, long timeout) { diff --git a/src/main/java/com/falsepattern/lib/toasts/icon/ToastBG.java b/src/main/java/com/falsepattern/lib/toasts/icon/ToastBG.java index a0acf26..25818cf 100644 --- a/src/main/java/com/falsepattern/lib/toasts/icon/ToastBG.java +++ b/src/main/java/com/falsepattern/lib/toasts/icon/ToastBG.java @@ -35,36 +35,36 @@ import cpw.mods.fml.relauncher.SideOnly; @SideOnly(Side.CLIENT) @StableAPI(since = "0.10.0") public class ToastBG extends ToastTexture { - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static final ToastBG TOAST_DARK = new ToastBG(new ResourceLocation(Tags.MODID, "textures/gui/toast_dark.png"), 160, 32, 0xFFFFFFFF); - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static final ToastBG TOAST_DARK_ROUNDED = new ToastBG(new ResourceLocation(Tags.MODID, "textures/gui/toast_dark_rounded.png"), 160, 32, 0xFFFFFFFF); - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static final ToastBG TOAST_NARRATOR = new ToastBG(new ResourceLocation(Tags.MODID, "textures/gui/toast_narrator.png"), 160, 32, 0xFFAAAA00); - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static final ToastBG TOAST_NARRATOR_ROUNDED = new ToastBG(new ResourceLocation(Tags.MODID, "textures/gui/toast_narrator_rounded.png"), 160, 32, 0xFFAAAA00); - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static final ToastBG TOAST_WHITE = new ToastBG(new ResourceLocation(Tags.MODID, "textures/gui/toast_white.png"), 160, 32, 0xFF500050); - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static final ToastBG TOAST_WHITE_ROUNDED = new ToastBG(new ResourceLocation(Tags.MODID, "textures/gui/toast_white_rounded.png"), 160, 32, 0xFF500050); - @StableAPI(since = "0.10.0") + @StableAPI.Expose public final int defaultTextColor; - @StableAPI(since = "0.10.0") + @StableAPI.Expose public ToastBG(@NonNull ResourceLocation texture, int width, int height, int defaultTextColor) { super(texture, width, height); this.defaultTextColor = defaultTextColor; } - @StableAPI(since = "0.10.0") + @StableAPI.Expose public ToastBG(@NonNull ResourceLocation texture, @NonNull IIcon icon, int defaultTextColor) { super(texture, icon); this.defaultTextColor = defaultTextColor; diff --git a/src/main/java/com/falsepattern/lib/toasts/icon/ToastIcon.java b/src/main/java/com/falsepattern/lib/toasts/icon/ToastIcon.java index 2a4dcff..07029fc 100644 --- a/src/main/java/com/falsepattern/lib/toasts/icon/ToastIcon.java +++ b/src/main/java/com/falsepattern/lib/toasts/icon/ToastIcon.java @@ -34,12 +34,12 @@ import cpw.mods.fml.relauncher.SideOnly; @SideOnly(Side.CLIENT) @StableAPI(since = "0.10.0") public class ToastIcon extends ToastTexture { - @StableAPI(since = "0.10.0") + @StableAPI.Expose public ToastIcon(@NonNull ResourceLocation texture, int width, int height) { super(texture, width, height); } - @StableAPI(since = "0.10.0") + @StableAPI.Expose public ToastIcon(@NonNull ResourceLocation texture, @NonNull IIcon icon) { super(texture, icon); } diff --git a/src/main/java/com/falsepattern/lib/toasts/icon/ToastTexture.java b/src/main/java/com/falsepattern/lib/toasts/icon/ToastTexture.java index 60f7fca..743c0be 100644 --- a/src/main/java/com/falsepattern/lib/toasts/icon/ToastTexture.java +++ b/src/main/java/com/falsepattern/lib/toasts/icon/ToastTexture.java @@ -34,17 +34,17 @@ import cpw.mods.fml.relauncher.SideOnly; @SideOnly(Side.CLIENT) @StableAPI(since = "0.10.0") public abstract class ToastTexture { - @Getter(onMethod_ = {@StableAPI(since = "0.10.0")}) + @Getter(onMethod_ = @StableAPI.Expose) protected final IIcon icon; - @Getter(onMethod_ = {@StableAPI(since = "0.10.0")}) + @Getter(onMethod_ = @StableAPI.Expose) protected final ResourceLocation texture; - @StableAPI(since = "0.10.0") + @StableAPI.Expose public ToastTexture(@NonNull ResourceLocation texture, int width, int height) { this(texture, RenderUtil.getFullTextureIcon(texture.toString(), width, height)); } - @StableAPI(since = "0.10.0") + @StableAPI.Expose public ToastTexture(@NonNull ResourceLocation texture, @NonNull IIcon icon) { this.icon = icon; this.texture = texture; @@ -53,6 +53,6 @@ public abstract class ToastTexture { /** * Draws the icon at the specified position in the specified Gui */ - @StableAPI(since = "0.10.0") + @StableAPI.Expose public abstract void draw(Gui guiIn, int x, int y); } \ No newline at end of file diff --git a/src/main/java/com/falsepattern/lib/updates/ModUpdateInfo.java b/src/main/java/com/falsepattern/lib/updates/ModUpdateInfo.java index 2954623..e51ae9e 100644 --- a/src/main/java/com/falsepattern/lib/updates/ModUpdateInfo.java +++ b/src/main/java/com/falsepattern/lib/updates/ModUpdateInfo.java @@ -29,14 +29,19 @@ import org.apache.logging.log4j.Logger; @StableAPI(since = "0.8.0") public class ModUpdateInfo { @NonNull + @StableAPI.Expose public final String modID; @NonNull + @StableAPI.Expose public final String currentVersion; @NonNull + @StableAPI.Expose public final String latestVersion; @NonNull + @StableAPI.Expose public final String updateURL; + @StableAPI.Expose public void log(Logger logger) { logger.info("Updates are available for mod {}: Currently installed version is {}, " + "latest available version is {}. Update URL: {}", modID, currentVersion, latestVersion, diff --git a/src/main/java/com/falsepattern/lib/updates/UpdateCheckException.java b/src/main/java/com/falsepattern/lib/updates/UpdateCheckException.java index 6642762..16b495f 100644 --- a/src/main/java/com/falsepattern/lib/updates/UpdateCheckException.java +++ b/src/main/java/com/falsepattern/lib/updates/UpdateCheckException.java @@ -24,18 +24,22 @@ import com.falsepattern.lib.StableAPI; @StableAPI(since = "0.8.3") public class UpdateCheckException extends Exception { + @StableAPI.Expose public UpdateCheckException(String message) { super(message); } + @StableAPI.Expose public UpdateCheckException(String message, Throwable cause) { super(message, cause); } + @StableAPI.Expose public UpdateCheckException(Throwable cause) { super(cause); } + @StableAPI.Expose protected UpdateCheckException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); } diff --git a/src/main/java/com/falsepattern/lib/updates/UpdateChecker.java b/src/main/java/com/falsepattern/lib/updates/UpdateChecker.java index 339c6d1..f33f074 100644 --- a/src/main/java/com/falsepattern/lib/updates/UpdateChecker.java +++ b/src/main/java/com/falsepattern/lib/updates/UpdateChecker.java @@ -73,6 +73,7 @@ public class UpdateChecker { * * @return A list of mods that were both available on the URL and installed */ + @StableAPI.Expose public static CompletableFuture> fetchUpdatesAsync(String url) { return CompletableFuture.supplyAsync(() -> { if (!LibraryConfig.ENABLE_UPDATE_CHECKER) { @@ -168,6 +169,7 @@ public class UpdateChecker { * * @throws UpdateCheckException If the update checker is disabled in config, the URL is invalid, or */ + @StableAPI.Expose public static List fetchUpdates(String url) throws UpdateCheckException { try { return fetchUpdatesAsync(url).join(); @@ -190,6 +192,7 @@ public class UpdateChecker { * * @return A list of chat messages that can be sent to players */ + @StableAPI.Expose public static List updateListToChatMessages(String initiator, List updates) { if (updates == null || updates.size() == 0) { return null; diff --git a/src/main/java/com/falsepattern/lib/util/FileUtil.java b/src/main/java/com/falsepattern/lib/util/FileUtil.java index 54a572f..c351ab2 100644 --- a/src/main/java/com/falsepattern/lib/util/FileUtil.java +++ b/src/main/java/com/falsepattern/lib/util/FileUtil.java @@ -28,6 +28,7 @@ import java.io.File; @StableAPI(since = "0.8.2") public class FileUtil { + @StableAPI.Expose public static File getMinecraftHome() { return Launch.minecraftHome == null ? new File(".") : Launch.minecraftHome; } diff --git a/src/main/java/com/falsepattern/lib/util/LangUtil.java b/src/main/java/com/falsepattern/lib/util/LangUtil.java index 996079b..3ed8c60 100644 --- a/src/main/java/com/falsepattern/lib/util/LangUtil.java +++ b/src/main/java/com/falsepattern/lib/util/LangUtil.java @@ -35,13 +35,16 @@ import static lombok.AccessLevel.PRIVATE; @NoArgsConstructor(access = PRIVATE) @StableAPI(since = "0.8.0") public final class LangUtil { + @StableAPI.Expose public static final String DEFAULT_LOCALE = "en_US"; private static final ThreadLocal> tempMap = ThreadLocal.withInitial(HashMap::new); + @StableAPI.Expose public static void defaultLocalization(@NonNull Map localeMap) { localeMap.forEach(LangUtil::defaultLocalization); } + @StableAPI.Expose public static void defaultLocalization(@NonNull String key, @NonNull String value) { if (!LanguageRegistry.instance().getStringLocalization(key, DEFAULT_LOCALE).isEmpty()) { return; diff --git a/src/main/java/com/falsepattern/lib/util/MathUtil.java b/src/main/java/com/falsepattern/lib/util/MathUtil.java index 4fbf352..298cff9 100644 --- a/src/main/java/com/falsepattern/lib/util/MathUtil.java +++ b/src/main/java/com/falsepattern/lib/util/MathUtil.java @@ -26,8 +26,9 @@ import com.falsepattern.lib.compat.Vec3i; import java.util.Random; import java.util.UUID; +@StableAPI(since = "0.10.0") public class MathUtil { - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static final float SQRT_2 = sqrt(2.0F); /** * A table of sin values computed from 0 (inclusive) to 2*pi (exclusive), with steps of 2*PI / 65536. @@ -69,7 +70,7 @@ public class MathUtil { /** * sin looked up in a table */ - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static float sin(float value) { return SIN_TABLE[(int) (value * 10430.378F) & 65535]; } @@ -78,17 +79,17 @@ public class MathUtil { * cos looked up in the sin table with the appropriate offset */ - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static float cos(float value) { return SIN_TABLE[(int) (value * 10430.378F + 16384.0F) & 65535]; } - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static float sqrt(float value) { return (float) Math.sqrt(value); } - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static float sqrt(double value) { return (float) Math.sqrt(value); } @@ -96,7 +97,7 @@ public class MathUtil { /** * Returns the greatest integer less than or equal to the float argument */ - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static int floor(float value) { int i = (int) value; return value < (float) i ? i - 1 : i; @@ -105,7 +106,7 @@ public class MathUtil { /** * returns par0 cast as an int, and no greater than Integer.MAX_VALUE-1024 */ - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static int fastFloor(double value) { return (int) (value + 1024.0D) - 1024; } @@ -113,7 +114,7 @@ public class MathUtil { /** * Returns the greatest integer less than or equal to the double argument */ - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static int floor(double value) { int i = (int) value; return value < (double) i ? i - 1 : i; @@ -122,18 +123,18 @@ public class MathUtil { /** * Long version of floor() */ - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static long lfloor(double value) { long i = (long) value; return value < (double) i ? i - 1L : i; } - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static int absFloor(double value) { return (int) (value >= 0.0D ? value : -value + 1.0D); } - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static float abs(float value) { return value >= 0.0F ? value : -value; } @@ -141,18 +142,18 @@ public class MathUtil { /** * Returns the unsigned value of an int. */ - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static int abs(int value) { return value >= 0 ? value : -value; } - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static int ceil(float value) { int i = (int) value; return value > (float) i ? i + 1 : i; } - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static int ceil(double value) { int i = (int) value; return value > (double) i ? i + 1 : i; @@ -162,7 +163,7 @@ public class MathUtil { * Returns the value of the first parameter, clamped to be within the lower and upper limits given by the second and * third parameters. */ - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static int clamp(int num, int min, int max) { return num < min ? min : Math.min(num, max); } @@ -171,17 +172,17 @@ public class MathUtil { * Returns the value of the first parameter, clamped to be within the lower and upper limits given by the second and * third parameters */ - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static float clamp(float num, float min, float max) { return num < min ? min : Math.min(num, max); } - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static double clamp(double num, double min, double max) { return num < min ? min : Math.min(num, max); } - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static double clampedLerp(double lowerBnd, double upperBnd, double slide) { if (slide < 0.0D) { return lowerBnd; @@ -193,7 +194,7 @@ public class MathUtil { /** * Maximum of the absolute value of two numbers. */ - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static double absMax(double a, double b) { if (a < 0.0D) { a = -a; @@ -209,27 +210,27 @@ public class MathUtil { /** * Buckets an integer with specified bucket sizes. */ - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static int intFloorDiv(int number, int bucket) { return number < 0 ? -((-number - 1) / bucket) - 1 : number / bucket; } - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static int getInt(Random random, int minimum, int maximum) { return minimum >= maximum ? minimum : random.nextInt(maximum - minimum + 1) + minimum; } - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static float nextFloat(Random random, float minimum, float maximum) { return minimum >= maximum ? minimum : random.nextFloat() * (maximum - minimum) + minimum; } - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static double nextDouble(Random random, double minimum, double maximum) { return minimum >= maximum ? minimum : random.nextDouble() * (maximum - minimum) + minimum; } - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static double average(long[] values) { long i = 0L; @@ -240,22 +241,22 @@ public class MathUtil { return (double) i / (double) values.length; } - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static boolean epsilonEquals(float a, float b) { return abs(b - a) < 1.0E-5F; } - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static int normalizeAngle(int a, int b) { return (a % b + b) % b; } - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static float positiveModulo(float numerator, float denominator) { return (numerator % denominator + denominator) % denominator; } - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static double positiveModulo(double numerator, double denominator) { return (numerator % denominator + denominator) % denominator; } @@ -263,7 +264,7 @@ public class MathUtil { /** * the angle is reduced to an angle between -180 and +180 by mod, and a 360 check */ - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static float wrapDegrees(float value) { value = value % 360.0F; @@ -281,7 +282,7 @@ public class MathUtil { /** * the angle is reduced to an angle between -180 and +180 by mod, and a 360 check */ - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static double wrapDegrees(double value) { value = value % 360.0D; @@ -299,7 +300,7 @@ public class MathUtil { /** * Adjust the angle so that his value is in range [-180;180[ */ - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static int wrapDegrees(int angle) { angle = angle % 360; @@ -317,7 +318,7 @@ public class MathUtil { /** * parses the string as integer or returns the second parameter if it fails */ - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static int getInt(String value, int defaultValue) { try { return Integer.parseInt(value); @@ -329,7 +330,7 @@ public class MathUtil { /** * parses the string as integer or returns the second parameter if it fails. this value is capped to par2 */ - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static int getInt(String value, int defaultValue, int max) { return Math.max(max, getInt(value, defaultValue)); } @@ -337,7 +338,7 @@ public class MathUtil { /** * parses the string as double or returns the second parameter if it fails. */ - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static double getDouble(String value, double defaultValue) { try { return Double.parseDouble(value); @@ -346,7 +347,7 @@ public class MathUtil { } } - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static double getDouble(String value, double defaultValue, double max) { return Math.max(max, getDouble(value, defaultValue)); } @@ -354,7 +355,7 @@ public class MathUtil { /** * Returns the input value rounded up to the next highest power of two. */ - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static int smallestEncompassingPowerOfTwo(int value) { int i = value - 1; i = i | i >> 1; @@ -368,7 +369,7 @@ public class MathUtil { /** * Is the given value a power of two? (1, 2, 4, 8, 16, ...) */ - @StableAPI(since = "0.10.0") + @StableAPI.Expose private static boolean isPowerOfTwo(int value) { return value != 0 && (value & value - 1) == 0; } @@ -378,7 +379,7 @@ public class MathUtil { * value. Optimized for cases where the input value is a power-of-two. If the input value is not a power-of-two, * then subtract 1 from the return value. */ - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static int log2DeBruijn(int value) { value = isPowerOfTwo(value) ? value : smallestEncompassingPowerOfTwo(value); return MULTIPLY_DE_BRUIJN_BIT_POSITION[(int) ((long) value * 125613361L >> 27) & 31]; @@ -388,7 +389,7 @@ public class MathUtil { * Efficiently calculates the floor of the base-2 log of an integer value. This is effectively the index of the * highest bit that is set. For example, if the number in binary is 0...100101, this will return 5. */ - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static int log2(int value) { return log2DeBruijn(value) - (isPowerOfTwo(value) ? 0 : 1); } @@ -399,7 +400,7 @@ public class MathUtil { * For instance, {@code roundUp(1, 4)} returns 4; {@code roundUp(0, 4)} returns 0; and {@code roundUp(4, 4)} returns * 4. */ - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static int roundUp(int number, int interval) { if (interval == 0) { return 0; @@ -415,7 +416,7 @@ public class MathUtil { } } - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static long getCoordinateRandom(int x, int y, int z) { long i = (x * 3129871L) ^ (long) z * 116129781L ^ (long) y; i = i * i * 42317861L + i * 11L; @@ -425,7 +426,7 @@ public class MathUtil { /** * Makes an integer color from the given red, green, and blue float values */ - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static int rgb(float rIn, float gIn, float bIn) { return rgb(floor(rIn * 255.0F), floor(gIn * 255.0F), floor(bIn * 255.0F)); } @@ -433,14 +434,14 @@ public class MathUtil { /** * Makes a single int color with the given red, green, and blue values. */ - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static int rgb(int rIn, int gIn, int bIn) { int lvt_3_1_ = (rIn << 8) + gIn; lvt_3_1_ = (lvt_3_1_ << 8) + bIn; return lvt_3_1_; } - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static int multiplyColor(int colorA, int colorB) { int rA = (colorA & 0xFF0000) >> 16; int rB = (colorB & 0xFF0000) >> 16; @@ -457,17 +458,17 @@ public class MathUtil { /** * Gets the decimal portion of the given double. For instance, {@code frac(5.5)} returns {@code .5}. */ - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static double frac(double number) { return number - Math.floor(number); } - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static long getPositionRandom(Vec3i pos) { return getCoordinateRandom(pos.getX(), pos.getY(), pos.getZ()); } - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static UUID getRandomUUID(Random rand) { long i = rand.nextLong() & -61441L | 16384L; long j = rand.nextLong() & 4611686018427387903L | Long.MIN_VALUE; @@ -477,17 +478,17 @@ public class MathUtil { /** * Generates a random UUID using the shared random */ - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static UUID getRandomUUID() { return getRandomUUID(RANDOM); } - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static double pct(double a, double b, double c) { return (a - b) / (c - b); } - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static double atan2(double y, double x) { double d0 = x * x + y * y; @@ -547,7 +548,7 @@ public class MathUtil { * Computes 1/sqrt(n) using the fast inverse square * root with a constant of 0x5FE6EB50C7B537AA. */ - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static double fastInvSqrt(double x) { double d0 = 0.5D * x; long i = Double.doubleToRawLongBits(x); @@ -557,7 +558,7 @@ public class MathUtil { return x; } - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static int hsvToRGB(float hue, float saturation, float value) { int i = (int) (hue * 6.0F) % 6; float f = hue * 6.0F - (float) i; @@ -611,7 +612,7 @@ public class MathUtil { return j << 16 | k << 8 | l; } - @StableAPI(since = "0.10.0") + @StableAPI.Expose public static int hash(int x) { x = x ^ x >>> 16; x = x * -2048144789; diff --git a/src/main/java/com/falsepattern/lib/util/RenderUtil.java b/src/main/java/com/falsepattern/lib/util/RenderUtil.java index 9615709..4a56cca 100644 --- a/src/main/java/com/falsepattern/lib/util/RenderUtil.java +++ b/src/main/java/com/falsepattern/lib/util/RenderUtil.java @@ -41,6 +41,7 @@ import static net.minecraft.client.Minecraft.getMinecraft; public final class RenderUtil { private final static Timer MINECRAFT_TIMER = getMinecraftTimer(); + @StableAPI.Expose @SneakyThrows private static Timer getMinecraftTimer() { val timerField = ReflectionHelper.findField(Minecraft.class, "timer", "field_71428_T"); @@ -98,6 +99,7 @@ public final class RenderUtil { }; } + @StableAPI.Expose public static float partialTick() { return MINECRAFT_TIMER.renderPartialTicks; } diff --git a/src/main/java/com/falsepattern/lib/util/ResourceUtil.java b/src/main/java/com/falsepattern/lib/util/ResourceUtil.java index ea3c352..87cfb0e 100644 --- a/src/main/java/com/falsepattern/lib/util/ResourceUtil.java +++ b/src/main/java/com/falsepattern/lib/util/ResourceUtil.java @@ -48,6 +48,7 @@ public class ResourceUtil { * * @throws IOException From {@link #readBytes(InputStream)} */ + @StableAPI.Expose public static String getResourceStringFromJar(String resourcePath, Class referenceClass) throws IOException { return getResourceStringFromJar(resourcePath, referenceClass, StandardCharsets.UTF_8); } @@ -64,6 +65,7 @@ public class ResourceUtil { * * @throws IOException From {@link #readBytes(InputStream)} */ + @StableAPI.Expose public static String getResourceStringFromJar(String resourcePath, Class referenceClass, Charset charset) throws IOException { return new String(getResourceBytesFromJar(resourcePath, referenceClass), charset); @@ -79,6 +81,7 @@ public class ResourceUtil { * * @throws IOException From {@link #readBytes(InputStream)} */ + @StableAPI.Expose public static byte[] getResourceBytesFromJar(String resourcePath, Class referenceClass) throws IOException { return readBytesSafe(getResourceFromJar(resourcePath, referenceClass), resourcePath); } @@ -100,6 +103,7 @@ public class ResourceUtil { * * @return The resource, or null if it was not found. */ + @StableAPI.Expose public static InputStream getResourceFromJar(String resourcePath, Class referenceClass) { URL classFile = referenceClass.getResource('/' + referenceClass.getName().replace('.', '/') + ".class"); lookup: @@ -136,6 +140,7 @@ public class ResourceUtil { * * @throws IOException From {@link InputStream#read(byte[])} */ + @StableAPI.Expose public static byte[] readBytes(InputStream stream) throws IOException { val out = new ByteArrayOutputStream(); val buf = new byte[4096]; @@ -155,6 +160,7 @@ public class ResourceUtil { * * @throws IOException From {@link #readBytes(InputStream)} */ + @StableAPI.Expose public static String getResourceString(String resourcePath) throws IOException { return getResourceString(resourcePath, StandardCharsets.UTF_8); } @@ -169,6 +175,7 @@ public class ResourceUtil { * * @throws IOException From {@link #readBytes(InputStream)} */ + @StableAPI.Expose public static String getResourceString(String resourcePath, Charset charset) throws IOException { return new String(getResourceBytes(resourcePath), charset); } @@ -182,6 +189,7 @@ public class ResourceUtil { * * @throws IOException From {@link #readBytes(InputStream)} */ + @StableAPI.Expose public static byte[] getResourceBytes(String resourcePath) throws IOException { return readBytesSafe(ResourceUtil.class.getResourceAsStream(resourcePath), resourcePath); }