diff options
Diffstat (limited to 'BJC-Utils2/src/main/java/bjc/utils')
29 files changed, 989 insertions, 441 deletions
diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommandMode.java b/BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommandMode.java index a9c9054..0007616 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommandMode.java +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommandMode.java @@ -82,11 +82,11 @@ public class GenericCommandMode implements ICommandMode { } else { ICommand aliasedCommand; if (defaultHandlers.containsKey(commandName)) { - aliasedCommand = - defaultHandlers.get(commandName).createAlias(); + aliasedCommand = defaultHandlers.get(commandName) + .createAlias(); } else { - aliasedCommand = - commandHandlers.get(commandName).createAlias(); + aliasedCommand = commandHandlers.get(commandName) + .createAlias(); } commandHandlers.put(aliasName, aliasedCommand); diff --git a/BJC-Utils2/src/main/java/bjc/utils/components/FileComponentRepository.java b/BJC-Utils2/src/main/java/bjc/utils/components/FileComponentRepository.java index bc1b990..e05afc0 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/components/FileComponentRepository.java +++ b/BJC-Utils2/src/main/java/bjc/utils/components/FileComponentRepository.java @@ -57,7 +57,7 @@ public class FileComponentRepository<E extends IDescribedComponent> * The function to use to convert files to components */ public FileComponentRepository(File directory, - Function<File, E> componentReader) { + Function<File, ? extends E> componentReader) { if (!directory.isDirectory()) { throw new IllegalArgumentException("File " + directory + " is not a directory.\n" @@ -123,7 +123,7 @@ public class FileComponentRepository<E extends IDescribedComponent> return "Components read from directory " + sourceDirectory + "."; } - private void loadComponent(Function<File, E> componentReader, + private void loadComponent(Function<File, ? extends E> componentReader, Path pth) { try { E component = componentReader.apply(pth.toFile()); diff --git a/BJC-Utils2/src/main/java/bjc/utils/configuration/ConfigFile.java b/BJC-Utils2/src/main/java/bjc/utils/configuration/ConfigFile.java deleted file mode 100644 index aa436ee..0000000 --- a/BJC-Utils2/src/main/java/bjc/utils/configuration/ConfigFile.java +++ /dev/null @@ -1,162 +0,0 @@ -package bjc.utils.configuration; - -import java.io.InputStream; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import java.util.Scanner; - -import javax.lang.model.SourceVersion; - -/** - * A config file with support for categories, comments and other thins - * - * @author ben - * - */ -public class ConfigFile { - /** - * A category in a configuration file - * - * @author ben - * - */ - public static class ConfigCategory { - private Map<String, ConfigCategory> children; - - /** - * Create a new config category - */ - public ConfigCategory() { - children = new HashMap<>(); - } - - /** - * Add a child category to this category - * - * @param childName - * The name of the child - * @param child - * The child category - */ - public void addChild(String childName, ConfigCategory child) { - children.put(childName, child); - } - } - - private static Map<String, ConfigCategory> topLevelCategories; - - private static boolean isCommentMarker(String token) { - switch (token) { - case "#": - case "//": - return true; - default: - return false; - } - } - - /** - * Parse the values in a config file from a stream - * - * @param source - * The stream to parse values from - * @return A config file with values parsed from the stream - */ - public static ConfigFile parse(InputStream source) { - Scanner scn = new Scanner(source); - - ConfigFile returnedFile = new ConfigFile(); - - while (scn.hasNextLine()) { - String currentLine = scn.nextLine(); - - // Ignore blank lines - if (currentLine.equals("")) { - continue; - } - - String[] currentTokens = currentLine.split(" "); - - // Ignore lines that start with a comment marker - if (isCommentMarker(currentTokens[0])) { - continue; - } else if (SourceVersion.isName(currentTokens[0]) - && currentTokens[1].equals("{")) { - topLevelCategories.put(currentTokens[0], - parseCategory(currentTokens[0], scn)); - } - } - - scn.close(); - - return returnedFile; - } - - private static ConfigCategory parseCategory( - @SuppressWarnings("unused") String categoryName, - Scanner inputSource) { - ConfigCategory category = new ConfigCategory(); - - String currentLine = inputSource.nextLine(); - - String[] tokens = currentLine.split("\\s+ "); - - // Parse contents of category - while (!tokens[0].equals("}")) { - // Ignore lines starting with comment marker - if (isCommentMarker(tokens[0])) { - continue; - } - - int initialCommandToken = 0; - - // Skip over blank tokens from lots of spacing - for (int i = 0; i < tokens.length; i++) { - String token = tokens[i]; - - if (token.equals("")) { - continue; - } else { - initialCommandToken = i; - break; - } - } - - String[] relevantTokens = Arrays.copyOfRange(tokens, - initialCommandToken, tokens.length); - - // Parse child subcategories - if (SourceVersion.isName(relevantTokens[0]) - && relevantTokens[1].equals("{")) { - parseCategory(relevantTokens[0], inputSource); - } else { - // Parse config fields - parseEntry(category, relevantTokens); - } - currentLine = inputSource.nextLine(); - - tokens = currentLine.split("\\s+ "); - } - - return category; - } - - private static void parseEntry( - @SuppressWarnings("unused") ConfigCategory category, - String[] entryParts) { - String entry = String.join("", entryParts); - - String[] expParts = entry.split("="); - - String[] expSpecifiers = expParts[0].split(":"); - - String expType = expSpecifiers[0]; - @SuppressWarnings("unused") - String expName = expSpecifiers[1]; - - switch (expType) { - - } - } -} diff --git a/BJC-Utils2/src/main/java/bjc/utils/configuration/Configuration.java b/BJC-Utils2/src/main/java/bjc/utils/configuration/Configuration.java deleted file mode 100644 index 7944c44..0000000 --- a/BJC-Utils2/src/main/java/bjc/utils/configuration/Configuration.java +++ /dev/null @@ -1,26 +0,0 @@ -package bjc.utils.configuration; - -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; - -/** - * Annotation that marks a class as having a config file bound to it - * - * For this annotation to be valid to apply to the class, the class must - * meet two qualities - * - * 1. Have a public no-args constructor - * - * 2. Have one or more fields annoted with a {@link FieldMarker} annotation - * - * @author ben - * - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -@Documented -public @interface Configuration { -}
\ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/configuration/Configurator.java b/BJC-Utils2/src/main/java/bjc/utils/configuration/Configurator.java deleted file mode 100644 index e116dea..0000000 --- a/BJC-Utils2/src/main/java/bjc/utils/configuration/Configurator.java +++ /dev/null @@ -1,44 +0,0 @@ -package bjc.utils.configuration; - -import java.io.InputStream; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; - -/** - * Bind the values in a prepared class to a config file - * - * @author ben - * - */ -public class Configurator { - /** - * Bind the values in a config file to the values in a class, - * substituting default values if none are appropriate - * - * @param <E> - * The type of the object to bind - * @param clasz - * The class of the object to bind - * @param inputSource - * The source to get input from - * @return A instance of the provided class, with values filled in from - * a config file - */ - public static <E> E readConfig(Class<E> clasz, - InputStream inputSource) { - try { - Constructor<E> noArgConstructor = clasz.getConstructor(); - - E backingStore = noArgConstructor.newInstance(); - - return backingStore; - } catch (NoSuchMethodException | SecurityException - | InstantiationException | IllegalAccessException - | IllegalArgumentException | InvocationTargetException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - - return null; - } - } -} diff --git a/BJC-Utils2/src/main/java/bjc/utils/configuration/FieldMarker.java b/BJC-Utils2/src/main/java/bjc/utils/configuration/FieldMarker.java deleted file mode 100644 index 1d59fa3..0000000 --- a/BJC-Utils2/src/main/java/bjc/utils/configuration/FieldMarker.java +++ /dev/null @@ -1,25 +0,0 @@ -package bjc.utils.configuration; - -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; - -/** - * Annotation to bind a field to a field in a config file - * - * @author ben - * - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -@Documented -public @interface FieldMarker { - /** - * The type of config field being represented - * - * @return The type of config field being represented - */ - public FieldType value(); -} diff --git a/BJC-Utils2/src/main/java/bjc/utils/configuration/FieldType.java b/BJC-Utils2/src/main/java/bjc/utils/configuration/FieldType.java deleted file mode 100644 index a1545e5..0000000 --- a/BJC-Utils2/src/main/java/bjc/utils/configuration/FieldType.java +++ /dev/null @@ -1,147 +0,0 @@ -package bjc.utils.configuration; - -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; - -/** - * Container interface for field type markers - * - * There can't be a String field type, so for fields of a single string, - * use FieldType itself - * - * @author ben - * - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -@Documented -public @interface FieldType { - /** - * Marker to indicate a field as a single boolean flag - * - * @author Benjamin - * - */ - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.FIELD) - public @interface Flag { - /** - * The default value of the flag - * - * @return The default value of the flag - */ - boolean value() default false; - } - - /** - * Marker to indicate a fields as an array of boolean flags - * - * @author Benjamin - * - */ - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.FIELD) - public @interface Flags { - /** - * The default value of the flags - * - * @return The default value of the flags - */ - boolean[] value() default { false }; - } - - /** - * Marker to indicate a field as a single floating point value - * - * @author Benjamin - * - */ - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.FIELD) - public @interface Float { - /** - * The default value of the number - * - * @return The default value of the number - */ - double value() default 0.0; - } - - /** - * Marker to indicate a fields as an array of floating point values - * - * @author Benjamin - * - */ - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.FIELD) - public @interface Floats { - /** - * The default value of the numbers - * - * @return The default value of the numbers - */ - double[] value() default { 0.0 }; - } - - /** - * Marker to indicate a field as a single integral value - * - * @author Benjamin - * - */ - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.FIELD) - public @interface Integer { - /** - * The default value of the integer - * - * @return The default value of the integer - */ - int value() default 0; - } - - /** - * Marker to indicate a fields as an array of integral values - * - * @author Benjamin - * - */ - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.FIELD) - public @interface Integers { - /** - * The default value of the integers - * - * @return The default value of the integers - */ - int[] value() default { 0 }; - } - - /** - * Marker to indicate a fields as an array of strings - * - * @author Benjamin - * - */ - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.FIELD) - public @interface Strings { - /** - * The default value of each of the strings - * - * @return The default value of each of the strings - */ - String[] value() default { "" }; - } - - /** - * The default value of the string - * - * @return The default value of the strings - */ - public String value() default ""; -} diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/BoundLazy.java b/BJC-Utils2/src/main/java/bjc/utils/data/BoundLazy.java index ce47eb9..9ab3c05 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/BoundLazy.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/BoundLazy.java @@ -96,4 +96,12 @@ class BoundLazy<OldType, BoundContainedType> return boundHolder.unwrap(unwrapper); } + + @Override + public <NewType> Function<BoundContainedType, IHolder<NewType>> lift( + Function<BoundContainedType, NewType> func) { + return (val) -> { + return new Lazy<>(func.apply(val)); + }; + } }
\ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/BoundLazyPair.java b/BJC-Utils2/src/main/java/bjc/utils/data/BoundLazyPair.java index a49bb9a..1635e06 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/BoundLazyPair.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/BoundLazyPair.java @@ -90,8 +90,8 @@ class BoundLazyPair<OldLeft, OldRight, NewLeft, NewRight> } @Override - public <MergedType> MergedType merge( - BiFunction<NewLeft, NewRight, MergedType> merger) { + public <MergedType> MergedType + merge(BiFunction<NewLeft, NewRight, MergedType> merger) { if (!pairBound) { boundPair = binder.apply(leftSupplier.get(), rightSupplier.get()); @@ -110,4 +110,60 @@ class BoundLazyPair<OldLeft, OldRight, NewLeft, NewRight> return "(un-materialized)"; } + + @Override + public <NewLeftType> IPair<NewLeftType, NewRight> + mapLeft(Function<NewLeft, NewLeftType> mapper) { + Supplier<NewLeftType> leftSupp = () -> { + if (!pairBound) { + NewLeft leftVal = binder + .apply(leftSupplier.get(), rightSupplier.get()) + .getLeft(); + + return mapper.apply(leftVal); + } + + return mapper.apply(boundPair.getLeft()); + }; + + Supplier<NewRight> rightSupp = () -> { + if (!pairBound) { + return binder + .apply(leftSupplier.get(), rightSupplier.get()) + .getRight(); + } + + return boundPair.getRight(); + }; + + return new LazyPair<>(leftSupp, rightSupp); + } + + @Override + public <NewRightType> IPair<NewLeft, NewRightType> + mapRight(Function<NewRight, NewRightType> mapper) { + Supplier<NewLeft> leftSupp = () -> { + if (!pairBound) { + return binder + .apply(leftSupplier.get(), rightSupplier.get()) + .getLeft(); + } + + return boundPair.getLeft(); + }; + + Supplier<NewRightType> rightSupp = () -> { + if (!pairBound) { + NewRight rightVal = binder + .apply(leftSupplier.get(), rightSupplier.get()) + .getRight(); + + return mapper.apply(rightVal); + } + + return mapper.apply(boundPair.getRight()); + }; + + return new LazyPair<>(leftSupp, rightSupp); + } }
\ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/BoundListHolder.java b/BJC-Utils2/src/main/java/bjc/utils/data/BoundListHolder.java new file mode 100644 index 0000000..fcb62f6 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/data/BoundListHolder.java @@ -0,0 +1,61 @@ +package bjc.utils.data; + +import java.util.function.Function; +import java.util.function.UnaryOperator; + +import bjc.utils.funcdata.IFunctionalList; + +class BoundListHolder<ContainedType> implements IHolder<ContainedType> { + private IFunctionalList<IHolder<ContainedType>> heldHolders; + + public BoundListHolder( + IFunctionalList<IHolder<ContainedType>> toHold) { + heldHolders = toHold; + } + + @Override + public <BoundType> IHolder<BoundType> bind( + Function<ContainedType, IHolder<BoundType>> binder) { + IFunctionalList<IHolder<BoundType>> boundHolders = heldHolders + .map((containedHolder) -> { + return containedHolder.bind(binder); + }); + + return new BoundListHolder<>(boundHolders); + } + + @Override + public <MappedType> IHolder<MappedType> map( + Function<ContainedType, MappedType> mapper) { + IFunctionalList<IHolder<MappedType>> mappedHolders = heldHolders + .map((containedHolder) -> { + return containedHolder.map(mapper); + }); + + return new BoundListHolder<>(mappedHolders); + } + + @Override + public IHolder<ContainedType> transform( + UnaryOperator<ContainedType> transformer) { + heldHolders.forEach((containedHolder) -> { + containedHolder.transform(transformer); + }); + + return this; + } + + @Override + public <UnwrappedType> UnwrappedType unwrap( + Function<ContainedType, UnwrappedType> unwrapper) { + return heldHolders.randItem().unwrap(unwrapper); + } + + @Override + public <NewType> Function<ContainedType, IHolder<NewType>> lift( + Function<ContainedType, NewType> func) { + return (val) -> { + return new ListHolder<>(func.apply(val)); + }; + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/HalfBoundLazyPair.java b/BJC-Utils2/src/main/java/bjc/utils/data/HalfBoundLazyPair.java index 037dddf..9e26924 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/HalfBoundLazyPair.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/HalfBoundLazyPair.java @@ -80,8 +80,8 @@ class HalfBoundLazyPair<OldType, NewLeft, NewRight> } @Override - public <MergedType> MergedType merge( - BiFunction<NewLeft, NewRight, MergedType> merger) { + public <MergedType> MergedType + merge(BiFunction<NewLeft, NewRight, MergedType> merger) { if (!pairBound) { boundPair = binder.apply(oldSupplier.get()); @@ -90,4 +90,52 @@ class HalfBoundLazyPair<OldType, NewLeft, NewRight> return boundPair.merge(merger); } + + @Override + public <NewLeftType> IPair<NewLeftType, NewRight> + mapLeft(Function<NewLeft, NewLeftType> mapper) { + Supplier<NewLeftType> leftSupp = () -> { + if (pairBound) { + return mapper.apply(boundPair.getLeft()); + } + + NewLeft leftVal = binder.apply(oldSupplier.get()).getLeft(); + + return mapper.apply(leftVal); + }; + + Supplier<NewRight> rightSupp = () -> { + if (pairBound) { + return boundPair.getRight(); + } + + return binder.apply(oldSupplier.get()).getRight(); + }; + + return new LazyPair<>(leftSupp, rightSupp); + } + + @Override + public <NewRightType> IPair<NewLeft, NewRightType> + mapRight(Function<NewRight, NewRightType> mapper) { + Supplier<NewLeft> leftSupp = () -> { + if (pairBound) { + return boundPair.getLeft(); + } + + return binder.apply(oldSupplier.get()).getLeft(); + }; + + Supplier<NewRightType> rightSupp = () -> { + if (pairBound) { + return mapper.apply(boundPair.getRight()); + } + + NewRight rightVal = binder.apply(oldSupplier.get()).getRight(); + + return mapper.apply(rightVal); + }; + + return new LazyPair<>(leftSupp, rightSupp); + } }
\ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/IHolder.java b/BJC-Utils2/src/main/java/bjc/utils/data/IHolder.java index ecf3f14..58ae5db 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/IHolder.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/IHolder.java @@ -4,6 +4,9 @@ import java.util.function.Consumer; import java.util.function.Function; import java.util.function.UnaryOperator; +import bjc.utils.funcdata.FunctionalList; +import bjc.utils.funcdata.theory.Functor; + /** * A holder of a single value. * @@ -12,7 +15,7 @@ import java.util.function.UnaryOperator; * @param <ContainedType> * The type of value held */ -public interface IHolder<ContainedType> { +public interface IHolder<ContainedType> extends Functor<ContainedType> { /** * Bind a function across the value in this container * @@ -22,8 +25,8 @@ public interface IHolder<ContainedType> { * The function to bind to the value * @return A holder from binding the value */ - public <BoundType> IHolder<BoundType> bind( - Function<ContainedType, IHolder<BoundType>> binder); + public <BoundType> IHolder<BoundType> + bind(Function<ContainedType, IHolder<BoundType>> binder); /** * Apply an action to the value @@ -31,7 +34,7 @@ public interface IHolder<ContainedType> { * @param action * The action to apply to the value */ - public default void doWith(Consumer<ContainedType> action) { + public default void doWith(Consumer<? super ContainedType> action) { transform((value) -> { action.accept(value); @@ -39,13 +42,64 @@ public interface IHolder<ContainedType> { }); } + @Override + default <ArgType, ReturnType> + Function<Functor<ArgType>, Functor<ReturnType>> + fmap(Function<ArgType, ReturnType> func) { + return (argumentFunctor) -> { + if (!(argumentFunctor instanceof IHolder<?>)) { + throw new IllegalArgumentException( + "This functor only supports mapping over instances of IHolder"); + } + + IHolder<ArgType> holder = (IHolder<ArgType>) argumentFunctor; + + return holder.map(func); + }; + } + + @Override + public default ContainedType getValue() { + return unwrap((value) -> value); + } + /** - * Get the value contained in this holder without changing it. + * Lifts a function to bind over this holder * - * @return The value held in this holder + * @param <NewType> + * The type of the functions return + * @param func + * The function to lift over the holder + * @return The function lifted over the holder */ - public default ContainedType getValue() { - return unwrap((value) -> value); + public <NewType> Function<ContainedType, IHolder<NewType>> + lift(Function<ContainedType, NewType> func); + + /** + * Make this holder lazy + * + * @return A lazy version of this holder + */ + public default IHolder<ContainedType> makeLazy() { + return new WrappedLazy<>(this); + } + + /** + * Make this holder a list + * + * @return A list version of this holder + */ + public default IHolder<ContainedType> makeList() { + return new BoundListHolder<>(new FunctionalList<>(this)); + } + + /** + * Make this holder optional + * + * @return An optional version of this holder + */ + public default IHolder<ContainedType> makeOptional() { + return new WrappedOption<>(this); } /** @@ -60,8 +114,8 @@ public interface IHolder<ContainedType> { * The function to do mapping with * @return A holder with the mapped value */ - public <MappedType> IHolder<MappedType> map( - Function<ContainedType, MappedType> mapper); + public <MappedType> IHolder<MappedType> + map(Function<ContainedType, MappedType> mapper); /** * Replace the held value with a new one @@ -83,8 +137,8 @@ public interface IHolder<ContainedType> { * The function to transform the value with * @return The holder itself, for easy chaining */ - public IHolder<ContainedType> transform( - UnaryOperator<ContainedType> transformer); + public IHolder<ContainedType> + transform(UnaryOperator<ContainedType> transformer); /** * Unwrap the value contained in this holder so that it is no longer @@ -96,6 +150,6 @@ public interface IHolder<ContainedType> { * The function to use to unwrap the value * @return The unwrapped held value */ - public <UnwrappedType> UnwrappedType unwrap( - Function<ContainedType, UnwrappedType> unwrapper); + public <UnwrappedType> UnwrappedType + unwrap(Function<ContainedType, UnwrappedType> unwrapper); } diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/IPair.java b/BJC-Utils2/src/main/java/bjc/utils/data/IPair.java index 316074e..707724b 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/IPair.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/IPair.java @@ -4,6 +4,8 @@ import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.Function; +import bjc.utils.funcdata.theory.Bifunctor; + /** * Represents a pair of values * @@ -14,7 +16,8 @@ import java.util.function.Function; * The type of the right side of the pair * */ -public interface IPair<LeftType, RightType> { +public interface IPair<LeftType, RightType> + extends Bifunctor<LeftType, RightType> { /** * Bind a function across the values in this pair * @@ -68,11 +71,45 @@ public interface IPair<LeftType, RightType> { }); } + @Override + default <OldLeft, OldRight, NewLeft> + Function<Bifunctor<OldLeft, OldRight>, Bifunctor<NewLeft, OldRight>> + fmapLeft(Function<OldLeft, NewLeft> func) { + return (argumentPair) -> { + if (!(argumentPair instanceof IPair<?, ?>)) { + throw new IllegalArgumentException( + "This function can only be applied to instances of IPair"); + } + + IPair<OldLeft, OldRight> argPair = (IPair<OldLeft, OldRight>) argumentPair; + + return argPair.mapLeft(func); + }; + } + + @Override + default <OldLeft, OldRight, NewRight> + Function<Bifunctor<OldLeft, OldRight>, Bifunctor<OldLeft, NewRight>> + + fmapRight(Function<OldRight, NewRight> func) { + return (argumentPair) -> { + if (!(argumentPair instanceof IPair<?, ?>)) { + throw new IllegalArgumentException( + "This function can only be applied to instances of IPair"); + } + + IPair<OldLeft, OldRight> argPair = (IPair<OldLeft, OldRight>) argumentPair; + + return argPair.mapRight(func); + }; + } + /** * Get the value on the left side of the pair * * @return The value on the left side of the pair */ + @Override public default LeftType getLeft() { return merge((leftValue, rightValue) -> leftValue); } @@ -82,11 +119,40 @@ public interface IPair<LeftType, RightType> { * * @return The value on the right side of the pair */ + @Override public default RightType getRight() { return merge((leftValue, rightValue) -> rightValue); } /** + * Transform the value on the left side of the pair. Doesn't modify the + * pair + * + * @param <NewLeft> + * The new type of the left part of the pair + * @param mapper + * The function to use to transform the left part of the + * pair + * @return The pair, with its left part transformed + */ + public <NewLeft> IPair<NewLeft, RightType> + mapLeft(Function<LeftType, NewLeft> mapper); + + /** + * Transform the value on the right side of the pair. Doesn't modify + * the pair + * + * @param <NewRight> + * The new type of the right part of the pair + * @param mapper + * The function to use to transform the right part of the + * pair + * @return The pair, with its right part transformed + */ + public <NewRight> IPair<LeftType, NewRight> + mapRight(Function<RightType, NewRight> mapper); + + /** * Merge the two values in this pair into a single value * * @param <MergedType> @@ -95,6 +161,6 @@ public interface IPair<LeftType, RightType> { * The function to use for merging * @return The pair, merged into a single value */ - public <MergedType> MergedType merge( - BiFunction<LeftType, RightType, MergedType> merger); + public <MergedType> MergedType + merge(BiFunction<LeftType, RightType, MergedType> merger); } diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/Identity.java b/BJC-Utils2/src/main/java/bjc/utils/data/Identity.java index dcc7bef..f42ceb7 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/Identity.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/Identity.java @@ -112,4 +112,12 @@ public class Identity<ContainedType> implements IHolder<ContainedType> { Function<ContainedType, UnwrappedType> unwrapper) { return unwrapper.apply(heldValue); } + + @Override + public <NewType> Function<ContainedType, IHolder<NewType>> lift( + Function<ContainedType, NewType> func) { + return (val) -> { + return new Identity<>(func.apply(val)); + }; + } }
\ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/Lazy.java b/BJC-Utils2/src/main/java/bjc/utils/data/Lazy.java index 061486e..62b0bb0 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/Lazy.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/Lazy.java @@ -133,4 +133,13 @@ public class Lazy<ContainedType> implements IHolder<ContainedType> { return unwrapper.apply(heldValue); } + + @Override + public <NewType> Function<ContainedType, IHolder<NewType>> lift( + Function<ContainedType, NewType> func) { + // TODO Auto-generated method stub + return (val) -> { + return new Lazy<>(func.apply(val)); + }; + } } diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/LazyPair.java b/BJC-Utils2/src/main/java/bjc/utils/data/LazyPair.java index b02d9cb..6f1be10 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/LazyPair.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/LazyPair.java @@ -115,8 +115,8 @@ public class LazyPair<LeftType, RightType> } @Override - public <MergedType> MergedType merge( - BiFunction<LeftType, RightType, MergedType> merger) { + public <MergedType> MergedType + merge(BiFunction<LeftType, RightType, MergedType> merger) { if (!leftMaterialized) { leftValue = leftSupplier.get(); @@ -154,4 +154,48 @@ public class LazyPair<LeftType, RightType> return sb.toString(); } + + @Override + public <NewLeft> IPair<NewLeft, RightType> + mapLeft(Function<LeftType, NewLeft> mapper) { + Supplier<NewLeft> leftSupp = () -> { + if (leftMaterialized) { + return mapper.apply(leftValue); + } + + return mapper.apply(leftSupplier.get()); + }; + + Supplier<RightType> rightSupp = () -> { + if (rightMaterialized) { + return rightValue; + } + + return rightSupplier.get(); + }; + + return new LazyPair<>(leftSupp, rightSupp); + } + + @Override + public <NewRight> IPair<LeftType, NewRight> + mapRight(Function<RightType, NewRight> mapper) { + Supplier<LeftType> leftSupp = () -> { + if (leftMaterialized) { + return leftValue; + } + + return leftSupplier.get(); + }; + + Supplier<NewRight> rightSupp = () -> { + if (rightMaterialized) { + return mapper.apply(rightValue); + } + + return mapper.apply(rightSupplier.get()); + }; + + return new LazyPair<>(leftSupp, rightSupp); + } } diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/ListHolder.java b/BJC-Utils2/src/main/java/bjc/utils/data/ListHolder.java new file mode 100644 index 0000000..8dc33d3 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/data/ListHolder.java @@ -0,0 +1,79 @@ +package bjc.utils.data; + +import java.util.function.Function; +import java.util.function.UnaryOperator; + +import bjc.utils.funcdata.FunctionalList; +import bjc.utils.funcdata.IFunctionalList; + +/** + * A holder that represents a set of non-deterministic computations + * + * @author ben + * + * @param <ContainedType> + * The type of contained value + */ +public class ListHolder<ContainedType> implements IHolder<ContainedType> { + private IFunctionalList<ContainedType> heldValues; + + private ListHolder(IFunctionalList<ContainedType> toHold) { + heldValues = toHold; + } + + /** + * Create a new list holder + * + * @param values + * The possible values for the computation + */ + @SafeVarargs + public ListHolder(ContainedType... values) { + heldValues = new FunctionalList<>(); + + if (values != null) { + for (ContainedType containedValue : values) { + heldValues.add(containedValue); + } + } + } + + @Override + public <BoundType> IHolder<BoundType> bind( + Function<ContainedType, IHolder<BoundType>> binder) { + IFunctionalList<IHolder<BoundType>> boundValues = heldValues + .map(binder); + + return new BoundListHolder<>(boundValues); + } + + @Override + public <MappedType> IHolder<MappedType> map( + Function<ContainedType, MappedType> mapper) { + IFunctionalList<MappedType> mappedValues = heldValues.map(mapper); + + return new ListHolder<>(mappedValues); + } + + @Override + public IHolder<ContainedType> transform( + UnaryOperator<ContainedType> transformer) { + heldValues = heldValues.map(transformer); + + return this; + } + + @Override + public <UnwrappedType> UnwrappedType unwrap( + Function<ContainedType, UnwrappedType> unwrapper) { + return unwrapper.apply(heldValues.randItem()); + } + + @Override + public <NewType> Function<ContainedType, IHolder<NewType>> lift( + Function<ContainedType, NewType> func) { + return (val) -> { + return new ListHolder<>(new FunctionalList<>(func.apply(val))); + }; + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/Option.java b/BJC-Utils2/src/main/java/bjc/utils/data/Option.java new file mode 100644 index 0000000..9f6d448 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/data/Option.java @@ -0,0 +1,74 @@ +package bjc.utils.data; + +import java.util.function.Function; +import java.util.function.UnaryOperator; + +/** + * A holder that may or may not contain a value + * + * @author ben + * + * @param <ContainedType> + * The type of the value that may or may not be held + */ +public class Option<ContainedType> implements IHolder<ContainedType> { + private ContainedType held; + + /** + * Create a new optional, using the given initial value + * + * @param seedValue + * The initial value for the optional + */ + public Option(ContainedType seedValue) { + held = seedValue; + } + + @Override + public <BoundType> IHolder<BoundType> bind( + Function<ContainedType, IHolder<BoundType>> binder) { + if (held == null) { + return new Option<>(null); + } + + return binder.apply(held); + } + + @Override + public <MappedType> IHolder<MappedType> map( + Function<ContainedType, MappedType> mapper) { + if (held == null) { + return new Option<>(null); + } + + return new Option<>(mapper.apply(held)); + } + + @Override + public IHolder<ContainedType> transform( + UnaryOperator<ContainedType> transformer) { + if (held != null) { + held = transformer.apply(held); + } + + return this; + } + + @Override + public <UnwrappedType> UnwrappedType unwrap( + Function<ContainedType, UnwrappedType> unwrapper) { + if (held == null) { + return null; + } + + return unwrapper.apply(held); + } + + @Override + public <NewType> Function<ContainedType, IHolder<NewType>> lift( + Function<ContainedType, NewType> func) { + return (val) -> { + return new Option<>(func.apply(val)); + }; + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/Pair.java b/BJC-Utils2/src/main/java/bjc/utils/data/Pair.java index 05955b6..0d2c1b0 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/Pair.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/Pair.java @@ -56,8 +56,8 @@ public class Pair<LeftType, RightType> } @Override - public <MergedType> MergedType merge( - BiFunction<LeftType, RightType, MergedType> merger) { + public <MergedType> MergedType + merge(BiFunction<LeftType, RightType, MergedType> merger) { return merger.apply(leftValue, rightValue); } @@ -66,4 +66,16 @@ public class Pair<LeftType, RightType> return "pair[l=" + leftValue.toString() + ", r=" + rightValue.toString() + "]"; } + + @Override + public <NewLeft> IPair<NewLeft, RightType> + mapLeft(Function<LeftType, NewLeft> mapper) { + return new Pair<>(mapper.apply(leftValue), rightValue); + } + + @Override + public <NewRight> IPair<LeftType, NewRight> + mapRight(Function<RightType, NewRight> mapper) { + return new Pair<>(leftValue, mapper.apply(rightValue)); + } }
\ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/WrappedLazy.java b/BJC-Utils2/src/main/java/bjc/utils/data/WrappedLazy.java new file mode 100644 index 0000000..737482c --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/data/WrappedLazy.java @@ -0,0 +1,69 @@ +package bjc.utils.data; + +import java.util.function.Function; +import java.util.function.UnaryOperator; + +class WrappedLazy<ContainedType> implements IHolder<ContainedType> { + private IHolder<IHolder<ContainedType>> held; + + // This has an extra parameter, because otherwise it erases to the same + // as the public one + private WrappedLazy(IHolder<IHolder<ContainedType>> wrappedHolder, + @SuppressWarnings("unused") boolean dummy) { + held = wrappedHolder; + } + + public WrappedLazy(IHolder<ContainedType> wrappedHolder) { + held = new Lazy<>(wrappedHolder); + } + + @Override + public <BoundType> IHolder<BoundType> bind( + Function<ContainedType, IHolder<BoundType>> binder) { + IHolder<IHolder<BoundType>> newHolder = held + .map((containedHolder) -> { + return containedHolder.bind(binder); + }); + + return new WrappedLazy<>(newHolder, false); + } + + @Override + public <MappedType> IHolder<MappedType> map( + Function<ContainedType, MappedType> mapper) { + IHolder<IHolder<MappedType>> newHolder = held + .map((containedHolder) -> { + return containedHolder.map(mapper); + }); + + return new WrappedLazy<>(newHolder, false); + } + + @Override + public IHolder<ContainedType> transform( + UnaryOperator<ContainedType> transformer) { + // FIXME this smells bad to me, but I can't figure out how else to + // do it + held.transform((containedHolder) -> { + return containedHolder.transform(transformer); + }); + + return this; + } + + @Override + public <UnwrappedType> UnwrappedType unwrap( + Function<ContainedType, UnwrappedType> unwrapper) { + return held.unwrap((containedHolder) -> { + return containedHolder.unwrap(unwrapper); + }); + } + + @Override + public <NewType> Function<ContainedType, IHolder<NewType>> lift( + Function<ContainedType, NewType> func) { + return (val) -> { + return new Lazy<>(func.apply(val)); + }; + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/WrappedOption.java b/BJC-Utils2/src/main/java/bjc/utils/data/WrappedOption.java new file mode 100644 index 0000000..c36cafa --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/data/WrappedOption.java @@ -0,0 +1,89 @@ +package bjc.utils.data; + +import java.util.function.Function; +import java.util.function.UnaryOperator; + +class WrappedOption<ContainedType> implements IHolder<ContainedType> { + private IHolder<IHolder<ContainedType>> held; + + private WrappedOption(IHolder<IHolder<ContainedType>> toHold, + @SuppressWarnings("unused") boolean dummy) { + held = toHold; + } + + public WrappedOption(IHolder<ContainedType> seedValue) { + held = new Option<>(seedValue); + } + + @Override + public <BoundType> IHolder<BoundType> bind( + Function<ContainedType, IHolder<BoundType>> binder) { + IHolder<IHolder<BoundType>> newHolder = held + .map((containedHolder) -> { + return containedHolder.bind((containedValue) -> { + if (containedValue == null) { + return new Option<>(null); + } + + return binder.apply(containedValue); + }); + }); + + return new WrappedOption<>(newHolder, false); + } + + @Override + public <MappedType> IHolder<MappedType> map( + Function<ContainedType, MappedType> mapper) { + IHolder<IHolder<MappedType>> newHolder = held + .map((containedHolder) -> { + return containedHolder.map((containedValue) -> { + if (containedValue == null) { + return null; + } + + return mapper.apply(containedValue); + }); + }); + + return new WrappedOption<>(newHolder, false); + } + + @Override + public IHolder<ContainedType> transform( + UnaryOperator<ContainedType> transformer) { + held.transform((containedHolder) -> { + return containedHolder.transform((containedValue) -> { + if (containedValue == null) { + return null; + } + + return transformer.apply(containedValue); + }); + }); + + return this; + } + + @Override + public <UnwrappedType> UnwrappedType unwrap( + Function<ContainedType, UnwrappedType> unwrapper) { + return held.unwrap((containedHolder) -> { + return containedHolder.unwrap((containedValue) -> { + if (containedValue == null) { + return null; + } + + return unwrapper.apply(containedValue); + }); + }); + } + + @Override + public <NewType> Function<ContainedType, IHolder<NewType>> lift( + Function<ContainedType, NewType> func) { + return (val) -> { + return new Option<>(func.apply(val)); + }; + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalList.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalList.java index 91b2ba3..5327dbe 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalList.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalList.java @@ -246,6 +246,16 @@ public interface IFunctionalList<ContainedType> { ContainedType randItem(Function<Integer, Integer> rnd); /** + * Select a random item from the list, using a default random number + * generator + * + * @return A random item from the list + */ + default ContainedType randItem() { + return randItem((num) -> (int) (Math.random() * num)); + } + + /** * Reduce this list to a single value, using a accumulative approach. * * @param <StateType> diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/PushdownMap.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/PushdownMap.java new file mode 100644 index 0000000..cc31923 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/PushdownMap.java @@ -0,0 +1,91 @@ +package bjc.utils.funcdata; + +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.function.Function; + +/** + * A map where + * + * @author ben + * + * @param <KeyType> + * @param <ValueType> + */ +public class PushdownMap<KeyType, ValueType> + implements IFunctionalMap<KeyType, ValueType> { + + @Override + public boolean containsKey(KeyType key) { + // TODO Auto-generated method stub + return false; + } + + @Override + public IFunctionalMap<KeyType, ValueType> extend() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void forEach(BiConsumer<KeyType, ValueType> action) { + // TODO Auto-generated method stub + + } + + @Override + public void forEachKey(Consumer<KeyType> action) { + // TODO Auto-generated method stub + + } + + @Override + public void forEachValue(Consumer<ValueType> action) { + // TODO Auto-generated method stub + + } + + @Override + public ValueType get(KeyType key) { + // TODO Auto-generated method stub + return null; + } + + @Override + public int getSize() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public IFunctionalList<KeyType> keyList() { + // TODO Auto-generated method stub + return null; + } + + @Override + public <V2> IFunctionalMap<KeyType, V2> mapValues( + Function<ValueType, V2> transformer) { + // TODO Auto-generated method stub + return null; + } + + @Override + public ValueType put(KeyType key, ValueType val) { + // TODO Auto-generated method stub + return null; + } + + @Override + public ValueType remove(KeyType key) { + // TODO Auto-generated method stub + return null; + } + + @Override + public IFunctionalList<ValueType> valueList() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/theory/Bifunctor.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/theory/Bifunctor.java new file mode 100644 index 0000000..3bea135 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/theory/Bifunctor.java @@ -0,0 +1,66 @@ +package bjc.utils.funcdata.theory; + +import java.util.function.Function; + +/** + * A functor over a pair of heterogenous types + * + * @author ben + * @param <LeftType> + * The type stored on the 'left' of the pair + * @param <RightType> + * The type stored on the 'right' of the pair + * + */ +public interface Bifunctor<LeftType, RightType> { + /** + * Lift a function to operate over the left part of this pair + * + * @param <OldLeft> + * The old left type of the pair + * @param <OldRight> + * The old right type of the pair + * @param <NewLeft> + * The new left type of the pair + * @param func + * The function to lift to work over the left side of the + * pair + * @return The function lifted to work over the left side of bifunctors + */ + public <OldLeft, OldRight, NewLeft> + Function<Bifunctor<OldLeft, OldRight>, Bifunctor<NewLeft, OldRight>> + fmapLeft(Function<OldLeft, NewLeft> func); + + /** + * Lift a function to operate over the right part of this pair + * + * @param <OldLeft> + * The old left type of the pair + * @param <OldRight> + * The old right type of the pair + * @param <NewRight> + * The new right type of the pair + * @param func + * The function to lift to work over the right side of the + * pair + * @return The function lifted to work over the right side of + * bifunctors + */ + public <OldLeft, OldRight, NewRight> + Function<Bifunctor<OldLeft, OldRight>, Bifunctor<OldLeft, NewRight>> + fmapRight(Function<OldRight, NewRight> func); + + /** + * Get the value contained on the left of this bifunctor + * + * @return The value on the left side of this bifunctor + */ + public LeftType getLeft(); + + /** + * Get the value contained on the right of this bifunctor + * + * @return The value on the right of this bifunctor + */ + public RightType getRight(); +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/theory/Functor.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/theory/Functor.java new file mode 100644 index 0000000..76f48e2 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/theory/Functor.java @@ -0,0 +1,39 @@ +package bjc.utils.funcdata.theory; + +import java.util.function.Function; + +/** + * Represents a container or context some sort usually, but the precise + * definition is that it represents exactly what it is defined as + * + * @author ben + * @param <ContainedType> + * The value inside the functor + */ +public interface Functor<ContainedType> { + /** + * Converts a normal function to operate over values in a functor. + * + * N.B: Even though the type signature implies that you can apply the + * resulting function to any type of functor, it is only safe to call + * it on instances of the type of functor you called fmap on. + * + * @param <ArgType> + * The argument of the function + * @param <ReturnType> + * The return type of the function + * @param func + * The function to convert + * @return The passed in function converted to work over a particular + * type of functors + */ + public <ArgType, ReturnType> Function<Functor<ArgType>, Functor<ReturnType>> fmap( + Function<ArgType, ReturnType> func); + + /** + * Retrieve the thing inside this functor + * + * @return The thing inside this functor + */ + public ContainedType getValue(); +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/theory/package-info.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/theory/package-info.java new file mode 100644 index 0000000..33c80d6 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/theory/package-info.java @@ -0,0 +1,7 @@ +/** + * Random functional type things that don't belong elsewhere + * + * @author ben + * + */ +package bjc.utils.funcdata.theory;
\ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcutils/StringUtils.java b/BJC-Utils2/src/main/java/bjc/utils/funcutils/StringUtils.java index 2f8aa09..9401b7e 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcutils/StringUtils.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcutils/StringUtils.java @@ -74,8 +74,14 @@ public class StringUtils { } } + /** + * Print out a deque with a special case for easily showing a deque is empty + * @param <ContainedType> The type in the deque + * @param queue The deque to print + * @return A string version of the deque, with allowance for an empty deque + */ public static <ContainedType> String printDeque( - Deque<ContainedType> queuedTrees) { - return queuedTrees.isEmpty() ? "(none)" : queuedTrees.toString(); + Deque<ContainedType> queue) { + return queue.isEmpty() ? "(none)" : queue.toString(); } } diff --git a/BJC-Utils2/src/main/java/bjc/utils/gui/HolderOutputPanel.java b/BJC-Utils2/src/main/java/bjc/utils/gui/HolderOutputPanel.java index 4cbfb61..49c7283 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/gui/HolderOutputPanel.java +++ b/BJC-Utils2/src/main/java/bjc/utils/gui/HolderOutputPanel.java @@ -17,25 +17,31 @@ public class HolderOutputPanel extends JPanel { private static final long serialVersionUID = 166573313903782080L; private Timer updateTimer; private JLabel value; + private int nDelay; + private IHolder<String> val; /** * Create a new display panel, backed by a holder * * @param lab * The label to attach to this field - * @param val + * @param valueHolder * The holder to get the value from * @param nDelay * The delay in ms between value updates */ - public HolderOutputPanel(String lab, IHolder<String> val, int nDelay) { + public HolderOutputPanel(String lab, IHolder<String> valueHolder, + int nDelay) { + this.val = valueHolder; + this.nDelay = nDelay; + setLayout(new HLayout(2)); JLabel label = new JLabel(lab); - value = new JLabel(val.getValue() + " (stopped)"); + value = new JLabel("(stopped)"); updateTimer = new Timer(nDelay, (event) -> { - value.setText(val.getValue()); + value.setText(valueHolder.getValue()); }); add(label); @@ -57,4 +63,17 @@ public class HolderOutputPanel extends JPanel { value.setText(value.getText() + " (stopped)"); } + + /** + * Set this panel back to its initial state + */ + public void reset() { + stopUpdating(); + + value.setText("(stopped)"); + + updateTimer = new Timer(nDelay, (event) -> { + value.setText(val.getValue()); + }); + } } diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/StackBasedConfigReader.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/StackBasedConfigReader.java new file mode 100644 index 0000000..2d15711 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/StackBasedConfigReader.java @@ -0,0 +1,37 @@ +package bjc.utils.parserutils; + +/** + * This class parses a config file written in RPN and uses it to construct + * data items + * + * @author ben + * + * TODO implement me + */ +public class StackBasedConfigReader { + public static interface IItem { + public ItemType getType(); + } + + /** + * Represents the types of item that can be found on stacks + * + * @author ben + * + */ + public static enum ItemType { + /** + * Represents an integral number + */ + INTEGER, + /** + * Represents a string of characters + */ + STRING, + /** + * Represents an arbitrary object + */ + OBJECT + } + +} |
