diff options
| author | bjculkin <bjculkin@BECK-GT5TRW1.wvu-ad.wvu.edu> | 2018-04-25 15:29:18 -0400 |
|---|---|---|
| committer | bjculkin <bjculkin@BECK-GT5TRW1.wvu-ad.wvu.edu> | 2018-04-25 15:29:18 -0400 |
| commit | d7bae4d2145d8337570fec03974272d49ba5269d (patch) | |
| tree | 2f44ef7a13315990836344a4616ceaeaa1486916 /base/src/main/java/bjc/utils/misc | |
| parent | 37e55c679f9a9ca1d57d061eac5e5deef0ef0a90 (diff) | |
Add some new classes
Import some new classes from an old project
Diffstat (limited to 'base/src/main/java/bjc/utils/misc')
| -rw-r--r-- | base/src/main/java/bjc/utils/misc/Direction.java | 221 | ||||
| -rw-r--r-- | base/src/main/java/bjc/utils/misc/PropertyDB.java | 155 | ||||
| -rw-r--r-- | base/src/main/java/bjc/utils/misc/RelativeDirection.java | 123 |
3 files changed, 499 insertions, 0 deletions
diff --git a/base/src/main/java/bjc/utils/misc/Direction.java b/base/src/main/java/bjc/utils/misc/Direction.java new file mode 100644 index 0000000..4833f14 --- /dev/null +++ b/base/src/main/java/bjc/utils/misc/Direction.java @@ -0,0 +1,221 @@ +package bjc.utils.misc; + +import java.util.Random; +import java.util.function.Consumer; + +import bjc.utils.exceptions.InvalidDirectionException; +import bjc.utils.funcdata.FunctionalList; +import bjc.utils.funcdata.IList; + +import org.apache.commons.lang3.text.WordUtils; + +/** + * A set of cardinal directions + * + * The particular axis assigned to the coordinates are based off of x being + * the bottom left axis on a conventional 3D plot + * + * @author ben + * + */ +public enum Direction { + /** + * Negative z-axis + */ + DOWN, + /** + * Positive y-axis + */ + EAST, + /** + * Positive x-axis + */ + NORTH, + /** + * Negative x-axis + */ + SOUTH, + /** + * Positive z-axis + */ + UP, + /** + * Negative y-axis + */ + WEST; + + /** + * The source of randomness for picking random directions + */ + private static final Random RNG = new Random(); + + /** + * Get a list of all the cardinal directions + * + * @return A list of all the cardinal directions + */ + public static IList<Direction> cardinals() { + return new FunctionalList<>(NORTH, SOUTH, EAST, WEST); + } + + /** + * Perform the specified action once with each of the cardinal + * directions + * + * @param act + * The action to perform for each cardinal direction + */ + public static void forCardinalDirections(Consumer<Direction> act) { + cardinals().forEach(act); + } + + /** + * Perform a specified action for a random number of cardinals. + * + * @param nCardinals + * The number of cardinal directions to act on. Must be + * greater than 0 and less then 5 + * @param act + * The action to perform for each of the cardinals + */ + public static void forRandomCardinals(int nCardinals, + Consumer<Direction> act) { + if (nCardinals <= 0 || nCardinals > 4) { + throw new IllegalArgumentException( + "Tried to do things with incorrect number of cardinal directions. Tried with " + + nCardinals); + } + + IList<Direction> cards = cardinals(); + + for (int i = 0; i <= 4 - nCardinals; i++) { + Direction rDir = cards.randItem(RNG::nextInt); + + cards.removeMatching(rDir); + } + + cards.forEach(act); + } + + /** + * Create a value of the enumeration from a string + * + * @param value + * The string to turn into a value + * @return The direction corresponding to the given value + */ + public static Direction properValueOf(String value) { + return valueOf(value.toUpperCase()); + } + + /** + * Test if this direction is a cardinal direction + * + * @return If the direction is cardinal or not + */ + public boolean isCardinal() { + switch (this) { + case EAST: + case NORTH: + case SOUTH: + case WEST: + return true; + case DOWN: + case UP: + return false; + default: + throw new InvalidDirectionException( + "WAT. Somehow ended up with an invalid direction " + + this); + } + } + + /** + * Get the direction that opposes the current one + * + * @return The direction that is in the opposite direction of the + * current one + */ + public Direction opposing() { + switch (this) { + case NORTH: + return SOUTH; + case EAST: + return WEST; + case SOUTH: + return NORTH; + case WEST: + return WEST; + case UP: + return DOWN; + case DOWN: + return UP; + default: + throw new IllegalStateException( + "Enumeration got into a invalid state. WAT"); + } + } + + /** + * Get the direction that is clockwise on the compass from this one. + * + * Only works on cardinals. + * + * @return The cardinal clockwise from this one + */ + public Direction rotateClockwise() { + switch (this) { + case NORTH: + return EAST; + case EAST: + return SOUTH; + case SOUTH: + return WEST; + case WEST: + return NORTH; + case UP: + case DOWN: + default: + throw new InvalidDirectionException( + "Can't rotate non-cardinal direction clockwise: " + + this); + + } + } + + /** + * Get the direction that is counter-clockwise on the compass from this + * one. + * + * Only works on cardinals. + * + * @return The cardinal counter-clockwise from this one + */ + public Direction rotateCounterClockwise() { + switch (this) { + case NORTH: + return WEST; + case EAST: + return NORTH; + case SOUTH: + return EAST; + case WEST: + return SOUTH; + case UP: + case DOWN: + default: + throw new InvalidDirectionException( + "Can't rotate non-cardinal direction counterclockwise: " + + this); + + } + } + + @Override + public String toString() { + /* + * Make sure the word is properly capitalized for english + */ + return WordUtils.capitalize(super.toString().toLowerCase()); + } +} diff --git a/base/src/main/java/bjc/utils/misc/PropertyDB.java b/base/src/main/java/bjc/utils/misc/PropertyDB.java new file mode 100644 index 0000000..c9434ef --- /dev/null +++ b/base/src/main/java/bjc/utils/misc/PropertyDB.java @@ -0,0 +1,155 @@ +package bjc.utils.misc; + +import java.util.HashMap; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.regex.Pattern; + +import bjc.utils.funcutils.LambdaLock; +import bjc.utils.ioutils.SimpleProperties; + +/** + * Database for storage of properties from external files. + * + * @author EVE + * + */ +public class PropertyDB { + /* Regex storage. */ + private static SimpleProperties regexes; + private static Map<String, Pattern> compiledRegexes; + + /* Format string storage. */ + private static SimpleProperties formats; + + /* + * Whether or not to log during the loading. + */ + private static final boolean LOGLOAD = false; + + /* + * The lock to use to ensure a read can't happen during a reload + */ + private static LambdaLock loadLock = new LambdaLock(); + + static { + /* Reload properties on class load. */ + reloadProperties(); + } + + /** + * Reload all the properties from their files. + * + * NOTE: Any attempts to read from the property DB while properties are + * being loaded will block, to prevent reads from partial states. + */ + public static void reloadProperties() { + /* * Do the load with the write lock taken. */ + loadLock.write(() -> { + if(LOGLOAD) { + System.out.println("Reading regex properties:"); + } + + /* * Load regexes. */ + regexes = new SimpleProperties(); + regexes.loadFrom(PropertyDB.class.getResourceAsStream("/regexes.sprop"), false); + if(LOGLOAD) { + regexes.outputProperties(); + System.out.println(); + } + compiledRegexes = new HashMap<>(); + + if(LOGLOAD) { + System.out.println("Reading format properties:"); + } + + /* * Load formats. */ + formats = new SimpleProperties(); + formats.loadFrom(PropertyDB.class.getResourceAsStream("/formats.sprop"), false); + if(LOGLOAD) { + formats.outputProperties(); + System.out.println(); + } + }); + } + + /** + * Retrieve a persisted regular expression. + * + * @param key + * The name of the regular expression. + * + * @return The regular expression with that name. + */ + public static String getRegex(final String key) { + return loadLock.read(() -> { + if(!regexes.containsKey(key)) { + final String msg = String.format("No regular expression named '%s' found", key); + + throw new NoSuchElementException(msg); + } + + return regexes.get(key); + }); + } + + /** + * Retrieve a persisted regular expression, compiled into a regular + * expression. + * + * @param key + * The name of the regular expression. + * + * @return The regular expression with that name. + */ + public static Pattern getCompiledRegex(final String key) { + return loadLock.read(() -> { + if(!regexes.containsKey(key)) { + final String msg = String.format("No regular expression named '%s' found", key); + + throw new NoSuchElementException(msg); + } + + /* * Get the regex, and cache a compiled version. */ + return compiledRegexes.computeIfAbsent(key, strang -> { + return Pattern.compile(regexes.get(strang)); + }); + }); + } + + /** + * Retrieve a persisted format string. + * + * @param key + * The name of the format string. + * + * @return The format string with that name. + */ + public static String getFormat(final String key) { + return loadLock.read(() -> { + if(!formats.containsKey(key)) { + final String msg = String.format("No format string named '%s' found", key); + + throw new NoSuchElementException(msg); + } + + return formats.get(key); + }); + } + + /** + * Retrieve a persisted format string, and apply it to a set of + * arguments. + * + * @param key + * The name of the format string. + * + * @param objects + * The parameters to the format string. + * + * @return The format string with that name. + */ + public static String applyFormat(final String key, final Object... objects) { + return String.format(getFormat(key), objects); + } +} diff --git a/base/src/main/java/bjc/utils/misc/RelativeDirection.java b/base/src/main/java/bjc/utils/misc/RelativeDirection.java new file mode 100644 index 0000000..d7ccf6e --- /dev/null +++ b/base/src/main/java/bjc/utils/misc/RelativeDirection.java @@ -0,0 +1,123 @@ +package bjc.utils.misc; + +import java.util.Random; +import java.util.function.Consumer; + +import bjc.utils.exceptions.InvalidDirectionException; +import bjc.utils.funcdata.FunctionalList; +import bjc.utils.funcdata.IList; + +/** + * Represents a direction that is relative to another direction + * + * @author ben + * + */ +public enum RelativeDirection { + /** + * Same as direction + */ + BACKWARD, + /** + * Opposing direction + */ + FORWARD, + /** + * Counterclockwise from direction + */ + LEFT, + /** + * Clockwise from direction + */ + RIGHT; + + private static Random RNG = new Random(); + + /** + * Perform a specified action for a random number of relative + * directions. + * + * @param numDirections + * The number of cardinal directions to act on. Must be + * greater than 0 and less then 5 + * @param action + * The action to perform for each of the relative directions + * @param ignoreBackwards + * Whether or not to not have a chance of one of the + * directions being backwards + */ + public static void forRandomDirections(int numDirections, + Consumer<RelativeDirection> action, boolean ignoreBackwards) { + int maxNDirections; + + if (ignoreBackwards) { + maxNDirections = 3; + } else { + maxNDirections = 4; + } + + if (numDirections <= 0 || numDirections > maxNDirections) { + throw new IllegalArgumentException( + "Tried to do things with incorrect number of relative directions. Tried with " + + numDirections); + } + + IList<RelativeDirection> relativeDirs = + new FunctionalList<>(values()); + + if (ignoreBackwards) { + relativeDirs.removeMatching(BACKWARD); + } + + for (int i = 0; i <= maxNDirections - numDirections; i++) { + RelativeDirection relativeDir = + relativeDirs.randItem(RNG::nextInt); + + relativeDirs.removeMatching(relativeDir); + } + + relativeDirs.forEach(action); + } + + /** + * Properly convert a string to a relative direction + * + * @param value + * The string to convert + * @return The relative direction represented by the string + */ + public static RelativeDirection properValueOf(String value) { + return valueOf(value.toUpperCase()); + } + + /** + * Change another direction by turning the way this direction specifies + * + * @param dir + * The direction to change + * @return The direction after turning this way + */ + public Direction makeAbsolute(Direction dir) { + // Only cardinal directions can be truly absolutized + if (dir.isCardinal()) { + switch (this) { + case BACKWARD: + return dir; + case FORWARD: + return dir.opposing(); + case LEFT: + return dir.rotateCounterClockwise(); + case RIGHT: + return dir.rotateClockwise(); + default: + throw new InvalidDirectionException( + "Attempted to make absolute a direction in a unknown way " + + this); + } + } + + // Since it isn't a cardinal direction, absolutize it against a + // random direction + return this.makeAbsolute(Direction.NORTH); + } +} |
