diff --git a/src/mightypork/utils/Convert.java b/src/mightypork/utils/Convert.java
index d75a806..fa2c4ea 100644
--- a/src/mightypork/utils/Convert.java
+++ b/src/mightypork/utils/Convert.java
@@ -4,14 +4,14 @@ package mightypork.utils;
/**
* Utility for converting Object to data types; Can also convert strings to data
* types.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class Convert {
-
+
/**
* Get INTEGER
- *
+ *
* @param o object
* @param def default value
* @return integer
@@ -26,11 +26,11 @@ public class Convert {
} catch (final NumberFormatException e) {}
return def;
}
-
-
+
+
/**
* Get DOUBLE
- *
+ *
* @param o object
* @param def default value
* @return double
@@ -45,11 +45,11 @@ public class Convert {
} catch (final NumberFormatException e) {}
return def;
}
-
-
+
+
/**
* Get FLOAT
- *
+ *
* @param o object
* @param def default value
* @return float
@@ -62,11 +62,11 @@ public class Convert {
} catch (final NumberFormatException e) {}
return def;
}
-
-
+
+
/**
* Get BOOLEAN
- *
+ *
* @param o object
* @param def default value
* @return boolean
@@ -76,7 +76,7 @@ public class Convert {
if (o == null) return def;
if (o instanceof Boolean) return ((Boolean) o).booleanValue();
if (o instanceof Number) return ((Number) o).intValue() != 0;
-
+
if (o instanceof String) {
final String s = ((String) o).trim().toLowerCase();
if (s.equals("0")) return false;
@@ -85,26 +85,26 @@ public class Convert {
final double n = Double.parseDouble(s);
return n != 0;
} catch (final NumberFormatException e) {}
-
+
if (s.equals("true")) return true;
if (s.equals("yes")) return true;
if (s.equals("y")) return true;
if (s.equals("a")) return true;
if (s.equals("enabled")) return true;
-
+
if (s.equals("false")) return false;
if (s.equals("no")) return false;
if (s.equals("n")) return false;
if (s.equals("disabled")) return true;
}
-
+
return def;
}
-
-
+
+
/**
* Get STRING
- *
+ *
* @param o object
* @param def default value
* @return String
@@ -113,22 +113,22 @@ public class Convert {
{
if (o == null) return def;
if (o instanceof String) return ((String) o);
-
+
if (o instanceof Float) return Support.str((float) o);
-
+
if (o instanceof Double) return Support.str((double) o);
-
+
if (o instanceof Class>) {
return Support.str(o);
}
-
+
return o.toString();
}
-
-
+
+
/**
* Get INTEGER
- *
+ *
* @param o object
* @return integer
*/
@@ -136,11 +136,11 @@ public class Convert {
{
return toInteger(o, 0);
}
-
-
+
+
/**
* Get DOUBLE
- *
+ *
* @param o object
* @return double
*/
@@ -148,11 +148,11 @@ public class Convert {
{
return toDouble(o, 0d);
}
-
-
+
+
/**
* Get FLOAT
- *
+ *
* @param o object
* @return float
*/
@@ -160,11 +160,11 @@ public class Convert {
{
return toFloat(o, 0f);
}
-
-
+
+
/**
* Get BOOLEAN
- *
+ *
* @param o object
* @return boolean
*/
@@ -172,11 +172,11 @@ public class Convert {
{
return toBoolean(o, false);
}
-
-
+
+
/**
* Get STRING
- *
+ *
* @param o object
* @return String
*/
diff --git a/src/mightypork/utils/MapSort.java b/src/mightypork/utils/MapSort.java
index ca94859..55b9abe 100644
--- a/src/mightypork/utils/MapSort.java
+++ b/src/mightypork/utils/MapSort.java
@@ -1,20 +1,25 @@
package mightypork.utils;
-import java.util.*;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
import java.util.Map.Entry;
/**
* Map sorting utils
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class MapSort {
/**
* Sort a map by keys, maintaining key-value pairs, using natural order.
- *
+ *
* @param map map to be sorted
* @return linked hash map with sorted entries
*/
@@ -27,7 +32,7 @@ public class MapSort {
/**
* Sort a map by keys, maintaining key-value pairs.
- *
+ *
* @param map map to be sorted
* @param comparator a comparator, or null for natural ordering
* @return linked hash map with sorted entries
@@ -61,7 +66,7 @@ public class MapSort {
/**
* Sort a map by values, maintaining key-value pairs, using natural order.
- *
+ *
* @param map map to be sorted
* @return linked hash map with sorted entries
*/
@@ -74,7 +79,7 @@ public class MapSort {
/**
* Sort a map by values, maintaining key-value pairs.
- *
+ *
* @param map map to be sorted
* @param comparator a comparator, or null for natural ordering
* @return linked hash map with sorted entries
@@ -85,6 +90,7 @@ public class MapSort {
Collections.sort(entries, new Comparator>() {
+ @SuppressWarnings("unchecked")
@Override
public int compare(Entry o1, Entry o2)
{
diff --git a/src/mightypork/utils/Reflect.java b/src/mightypork/utils/Reflect.java
index a16deca..4edd3e2 100644
--- a/src/mightypork/utils/Reflect.java
+++ b/src/mightypork/utils/Reflect.java
@@ -10,14 +10,14 @@ import java.lang.reflect.Type;
/**
* Miscelanous reflection-related utilities
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class Reflect {
-
+
/**
* Get annotation of given type from an object
- *
+ *
* @param tested the examined object
* @param annotation annotation we want
* @return the anotation on that object, or null
@@ -26,11 +26,11 @@ public class Reflect {
{
return tested.getClass().getAnnotation(annotation);
}
-
-
+
+
/**
* Check if an object has an annotation of given trype
- *
+ *
* @param tested the examined object
* @param annotation annotation we want
* @return true if the annotation is present on the object
@@ -39,48 +39,58 @@ public class Reflect {
{
return tested.getClass().isAnnotationPresent(annotation);
}
-
-
+
+
/**
* Get generic parameters of a class
- *
+ *
* @param clazz the examined class
* @return parameter types
*/
public static Class>[] getGenericParameters(Class> clazz)
{
// BEHOLD, MAGIC!
-
+
final Type evtc = clazz.getGenericSuperclass();
-
+
if (evtc instanceof ParameterizedType) {
final Type[] types = ((ParameterizedType) evtc).getActualTypeArguments();
-
+
final Class>[] classes = new Class>[types.length];
-
+
for (int i = 0; i < types.length; i++) {
classes[i] = (Class>) types[i];
}
-
+
return classes;
}
-
+
throw new RuntimeException(Support.str(clazz) + " is not generic.");
}
-
-
+
+
+ /**
+ * Get value of a public static final field. If the modifiers don't match,
+ * an exception is thrown.
+ *
+ * @param objClass the class
+ * @param fieldName field to retrieve
+ * @return the field value
+ * @throws ReflectiveOperationException if the field is not constant, or if
+ * the value could not be retrieved.
+ */
public static Object getConstantFieldValue(Class> objClass, String fieldName) throws ReflectiveOperationException
{
final Field fld = objClass.getDeclaredField(fieldName);
-
+
final int modif = fld.getModifiers();
-
+
if (!Modifier.isFinal(modif) || !Modifier.isStatic(modif)) {
- throw new RuntimeException("The " + fieldName + " field of " + Support.str(objClass) + " must be static and final!");
+ throw new ReflectiveOperationException("The " + fieldName + " field of " + Support.str(objClass) + " must be static and final!");
}
-
+
fld.setAccessible(true);
return fld.get(null);
}
-
+
}
diff --git a/src/mightypork/utils/Support.java b/src/mightypork/utils/Support.java
index 8bf4b92..7923fd5 100644
--- a/src/mightypork/utils/Support.java
+++ b/src/mightypork/utils/Support.java
@@ -14,14 +14,14 @@ import mightypork.utils.annotations.Alias;
/**
* Miscelanous utilities
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public final class Support {
/**
* Create a new thread of the runnable, and start it.
- *
+ *
* @param r runnable
* @return the thread started
*/
@@ -35,7 +35,7 @@ public final class Support {
/**
* Pick first non-null option
- *
+ *
* @param options options
* @return the selected option
*/
@@ -51,7 +51,7 @@ public final class Support {
/**
* Get current time/date for given format.
- *
+ *
* @param format format, according to {@link DateFormat}.
* @return the formatted time/date
*/
@@ -64,7 +64,7 @@ public final class Support {
/**
* Parse array of vararg key, value pairs to a LinkedHashMap.
* Example:
- *
+ *
*
* Object[] array = {
* "one", 1,
@@ -72,10 +72,10 @@ public final class Support {
* "three", 9,
* "four", 16
* };
- *
+ *
* Map<String, Integer> args = parseVarArgs(array);
*
- *
+ *
* @param args varargs
* @return LinkedHashMap
* @throws ClassCastException in case of incompatible type in the array
@@ -107,7 +107,7 @@ public final class Support {
/**
* Get if an Object is in array (using equals)
- *
+ *
* @param needle checked Object
* @param haystack array of Objects
* @return is in array
@@ -123,7 +123,7 @@ public final class Support {
/**
* Get if string is in array
- *
+ *
* @param needle checked string
* @param case_sensitive case sensitive comparision
* @param haystack array of possible values
@@ -144,7 +144,7 @@ public final class Support {
/**
* Make enumeration iterable
- *
+ *
* @param enumeration enumeration
* @return iterable wrapper
*/
@@ -155,7 +155,7 @@ public final class Support {
/**
* Helper class for iterationg over an {@link Enumeration}
- *
+ *
* @author Ondřej Hruška (MightyPork)
* @param target element type (will be cast)
*/
@@ -167,7 +167,8 @@ public final class Support {
/**
* @param enumeration the iterated enumeration
*/
- public IterableEnumerationWrapper(Enumeration extends T> enumeration) {
+ public IterableEnumerationWrapper(Enumeration extends T> enumeration)
+ {
this.enumeration = enumeration;
}
@@ -205,9 +206,9 @@ public final class Support {
/**
* Convert a class to string, preserving name and outer class, but excluding
* path.
- *
- * @param cls
- * @return
+ *
+ * @param cls the class
+ * @return class name
*/
public static String str(Class> cls)
{
@@ -236,7 +237,7 @@ public final class Support {
/**
* Convert double to string, remove the mess at the end.
- *
+ *
* @param d double
* @return string
*/
@@ -253,7 +254,7 @@ public final class Support {
/**
* Convert float to string, remove the mess at the end.
- *
+ *
* @param f float
* @return string
*/
@@ -270,7 +271,7 @@ public final class Support {
/**
* Convert object to string. If the object overrides toString(), it is
* caled. Otherwise it's class name is converted to string.
- *
+ *
* @param o object
* @return string representation
*/
diff --git a/src/mightypork/utils/annotations/Alias.java b/src/mightypork/utils/annotations/Alias.java
index 7ffd1ad..e830233 100644
--- a/src/mightypork/utils/annotations/Alias.java
+++ b/src/mightypork/utils/annotations/Alias.java
@@ -1,13 +1,18 @@
package mightypork.utils.annotations;
-import java.lang.annotation.*;
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
/**
* Specify pretty name to be used when logging / converting class name to
* string.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
@Retention(RetentionPolicy.RUNTIME)
@@ -15,6 +20,6 @@ import java.lang.annotation.*;
@Documented
@Target(ElementType.TYPE)
public @interface Alias {
-
+
String name();
}
diff --git a/src/mightypork/utils/annotations/FactoryMethod.java b/src/mightypork/utils/annotations/FactoryMethod.java
index a502e90..50cd51a 100644
--- a/src/mightypork/utils/annotations/FactoryMethod.java
+++ b/src/mightypork/utils/annotations/FactoryMethod.java
@@ -11,12 +11,12 @@ import java.lang.annotation.Target;
/**
* Marks a static factory method. This is a description annotation and has no
* other function.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.METHOD)
@Documented
public @interface FactoryMethod {
-
+
}
diff --git a/src/mightypork/utils/annotations/Stub.java b/src/mightypork/utils/annotations/Stub.java
index 6e9d7a2..f27eba6 100644
--- a/src/mightypork/utils/annotations/Stub.java
+++ b/src/mightypork/utils/annotations/Stub.java
@@ -12,7 +12,7 @@ import java.lang.annotation.Target;
* Marked method can be safely overriden; it's left blank (or with default
* implementation) as a convenience.
* This is a description annotation and has no other function.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
@Documented
diff --git a/src/mightypork/utils/config/SimpleConfig.java b/src/mightypork/utils/config/SimpleConfig.java
index 29550ba..70f8f6f 100644
--- a/src/mightypork/utils/config/SimpleConfig.java
+++ b/src/mightypork/utils/config/SimpleConfig.java
@@ -19,14 +19,14 @@ import mightypork.utils.logging.Log;
* empty lines and lines without "=" are ignored
* lines with "=" must have "key = value" format, or a warning is logged.
* use "NULL" to create empty value.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class SimpleConfig {
-
+
/**
* Load list from file
- *
+ *
* @param file file
* @return map of keys and values
* @throws IOException
@@ -34,14 +34,14 @@ public class SimpleConfig {
public static List listFromFile(File file) throws IOException
{
final String fileText = FileUtil.fileToString(file);
-
+
return listFromString(fileText);
}
-
-
+
+
/**
* Load map from file
- *
+ *
* @param file file
* @return map of keys and values
* @throws IOException
@@ -49,98 +49,98 @@ public class SimpleConfig {
public static Map mapFromFile(File file) throws IOException
{
final String fileText = FileUtil.fileToString(file);
-
+
return mapFromString(fileText);
}
-
-
+
+
/**
* Load list from string
- *
+ *
* @param text text of the file
* @return map of keys and values
*/
public static List listFromString(String text)
{
final List list = new ArrayList<>();
-
+
final String[] groupsLines = text.split("\n");
-
+
for (String s : groupsLines) {
// ignore invalid lines
if (s.length() == 0) continue;
if (s.startsWith("#") || s.startsWith("//")) continue;
-
+
// NULL value
if (s.equalsIgnoreCase("NULL")) s = null;
-
+
if (s != null) s = s.replace("\\n", "\n");
-
+
// save extracted key-value pair
list.add(s);
}
-
+
return list;
}
-
-
+
+
/**
* Load map from string
- *
+ *
* @param text text of the file
* @return map of keys and values
*/
public static Map mapFromString(String text)
{
final LinkedHashMap pairs = new LinkedHashMap<>();
-
+
final String[] groupsLines = text.split("\n");
-
+
for (final String s : groupsLines) {
// ignore invalid lines
if (s.length() == 0) continue;
if (s.startsWith("#") || s.startsWith("//")) continue;
if (!s.contains("=")) continue;
-
+
// split and trim
String[] parts = s.split("=");
for (int i = 0; i < parts.length; i++) {
parts[i] = parts[i].trim();
}
-
+
// check if both parts are valid
if (parts.length == 0) {
Log.w("Bad line in config file: " + s);
continue;
}
-
+
if (parts.length == 1) {
parts = new String[] { parts[0], "" };
}
-
+
if (parts.length != 2) {
Log.w("Bad line in config file: " + s);
continue;
}
-
+
// NULL value
if (parts[0].equalsIgnoreCase("NULL")) parts[0] = null;
if (parts[1].equalsIgnoreCase("NULL")) parts[1] = null;
-
+
if (parts[0] != null) parts[0] = parts[0].replace("\\n", "\n");
if (parts[1] != null) parts[1] = parts[1].replace("\\n", "\n");
-
+
// save extracted key-value pair
pairs.put(parts[0], parts[1]);
}
-
+
return pairs;
}
-
-
+
+
/**
* Save map to file
- *
+ *
* @param target
* @param data
* @param allowNulls allow nulls.
@@ -149,38 +149,38 @@ public class SimpleConfig {
public static void mapToFile(File target, Map data, boolean allowNulls) throws IOException
{
final List lines = new ArrayList<>();
-
+
for (final Entry e : data.entrySet()) {
String key = e.getKey();
String value = e.getValue();
-
+
if (!allowNulls && (key == null || value == null || key.length() == 0 || value.length() == 0)) continue;
-
+
if (key == null) key = "NULL";
if (value == null) value = "NULL";
-
+
key = key.replace("\n", "\\n");
value = value.replace("\n", "\\n");
-
+
lines.add(key + " = " + value);
}
-
+
String text = ""; // # File written by SimpleConfig
-
+
for (final String s : lines) {
if (text.length() > 0) text += "\n";
-
+
text += s;
}
-
+
FileUtil.stringToFile(target, text);
-
+
}
-
-
+
+
/**
* Save list to file
- *
+ *
* @param target
* @param data
* @throws IOException
@@ -188,18 +188,18 @@ public class SimpleConfig {
public static void listToFile(File target, List data) throws IOException
{
String text = ""; // # File written by SimpleConfig
-
+
for (String s : data) {
if (text.length() > 0) text += "\n";
-
+
if (s == null) s = "NULL";
-
+
s = s.replace("\n", "\\n");
-
+
text += s;
}
-
+
FileUtil.stringToFile(target, text);
-
+
}
}
diff --git a/src/mightypork/utils/config/propmgr/Property.java b/src/mightypork/utils/config/propmgr/Property.java
index bea041a..f47a5ae 100644
--- a/src/mightypork/utils/config/propmgr/Property.java
+++ b/src/mightypork/utils/config/propmgr/Property.java
@@ -9,7 +9,7 @@ import mightypork.utils.annotations.Stub;
* Property entry for the {@link PropertyManager}.
* Extending this class can be used to add custom property types that are not
* supported by default.
- *
+ *
* @author Ondřej Hruška (MightyPork)
* @param property type
*/
@@ -24,26 +24,28 @@ public abstract class Property {
/**
* Create a property without comment
- *
+ *
* @param key key in the config file
* @param defaultValue defualt property value (used as fallback when
* parsing)
*/
- public Property(String key, T defaultValue) {
+ public Property(String key, T defaultValue)
+ {
this(key, defaultValue, null);
}
/**
* Create a property with a comment
- *
+ *
* @param key key in the config file
- * @param defaultValue defualt property value (used as fallback when
- * parsing)
+ * @param defaultValue default property value, used as fallback when
+ * parsing. Initially the value is assigned to defaultValue.
* @param comment optional property comment included above the property in
* the config file. Can be null.
*/
- public Property(String key, T defaultValue, String comment) {
+ public Property(String key, T defaultValue, String comment)
+ {
this.comment = comment;
this.key = key;
this.value = defaultValue;
@@ -54,7 +56,7 @@ public abstract class Property {
/**
* Parse a string representation of the value into this property. If the
* value cannot be decoded, use the default value instead.
- *
+ *
* @param string property value as string
*/
public abstract void fromString(String string);
@@ -62,7 +64,7 @@ public abstract class Property {
/**
* Get property value as string (compatible with `fromString())
- *
+ *
* @return property value as string
*/
@Override
@@ -75,7 +77,7 @@ public abstract class Property {
/**
* Get the current property value
- *
+ *
* @return the value
*/
public T getValue()
@@ -87,7 +89,7 @@ public abstract class Property {
/**
* Set property value.
* Uses Object to allow setValue(Object) method in {@link PropertyManager}
- *
+ *
* @param value value to set.
* @throws ClassCastException in case of incompatible type.
*/
@@ -100,7 +102,7 @@ public abstract class Property {
/**
* Get property comment.
- *
+ *
* @return the comment text (can be null if no comment is defined)
*/
public String getComment()
@@ -111,7 +113,7 @@ public abstract class Property {
/**
* Get property key
- *
+ *
* @return property key
*/
public String getKey()
diff --git a/src/mightypork/utils/config/propmgr/PropertyManager.java b/src/mightypork/utils/config/propmgr/PropertyManager.java
index 782e39e..a98e051 100644
--- a/src/mightypork/utils/config/propmgr/PropertyManager.java
+++ b/src/mightypork/utils/config/propmgr/PropertyManager.java
@@ -18,95 +18,97 @@ import mightypork.utils.logging.Log;
/**
* Property manager with advanced formatting and value checking.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class PropertyManager {
-
+
private final TreeMap> entries = new TreeMap<>();
private final TreeMap renameTable = new TreeMap<>();
- private PropertyStore props;
-
-
+ private final PropertyStore props;
+
+
/**
* Create property manager from file path and a header comment.
* This is the same as using a {@link PropertyFile} store.
- *
+ *
* @param file property file
* @param comment header comment.
*/
- public PropertyManager(File file, String comment) {
+ public PropertyManager(File file, String comment)
+ {
this(new PropertyFile(file, comment));
}
-
-
+
+
/**
* Create property manager based on provided {@link PropertyStore}
- *
+ *
* @param props a property store implementation backing this property
* manager
*/
- public PropertyManager(PropertyStore props) {
+ public PropertyManager(PropertyStore props)
+ {
this.props = props;
}
-
-
+
+
/**
* Load from file
*/
public void load()
{
props.load();
-
+
// rename keys (useful if keys change but value is to be kept)
for (final Entry entry : renameTable.entrySet()) {
-
+
final String value = props.getProperty(entry.getKey());
-
+
if (value == null) continue;
-
+
final String oldKey = entry.getKey();
final String newKey = entry.getValue();
-
+
props.removeProperty(oldKey);
props.setProperty(newKey, value, entries.get(newKey).getComment());
}
-
+
for (final Property> entry : entries.values()) {
entry.fromString(props.getProperty(entry.getKey()));
}
}
-
-
+
+
public void save()
{
try {
final ArrayList keyList = new ArrayList<>();
-
+
// validate entries one by one, replace with default when needed
for (final Property> entry : entries.values()) {
keyList.add(entry.getKey());
-
+
props.setProperty(entry.getKey(), entry.toString(), entry.getComment());
}
-
+
// removed unused props
for (final String key : props.keys()) {
if (!keyList.contains(key)) {
props.removeProperty(key);
}
}
-
+
props.save();
} catch (final IOException ioe) {
ioe.printStackTrace();
}
}
-
-
+
+
/**
* Get a property entry (rarely used)
- *
+ *
* @param k key
* @return the entry
*/
@@ -119,11 +121,11 @@ public class PropertyManager {
return null;
}
}
-
-
+
+
/**
* Get boolean property
- *
+ *
* @param k key
* @return the boolean found, or false
*/
@@ -131,11 +133,11 @@ public class PropertyManager {
{
return Convert.toBoolean(getProperty(k).getValue());
}
-
-
+
+
/**
* Get numeric property
- *
+ *
* @param k key
* @return the int found, or null
*/
@@ -143,11 +145,11 @@ public class PropertyManager {
{
return Convert.toInteger(getProperty(k).getValue());
}
-
-
+
+
/**
* Get numeric property as double
- *
+ *
* @param k key
* @return the double found, or null
*/
@@ -155,11 +157,11 @@ public class PropertyManager {
{
return Convert.toDouble(getProperty(k).getValue());
}
-
-
+
+
/**
* Get string property
- *
+ *
* @param k key
* @return the string found, or null
*/
@@ -167,11 +169,11 @@ public class PropertyManager {
{
return Convert.toString(getProperty(k).getValue());
}
-
-
+
+
/**
* Get arbitrary property. Make sure it's of the right type!
- *
+ *
* @param k key
* @return the prioperty found
*/
@@ -184,11 +186,11 @@ public class PropertyManager {
return null;
}
}
-
-
+
+
/**
* Add a boolean property
- *
+ *
* @param k key
* @param d default value
* @param comment the in-file comment
@@ -197,11 +199,11 @@ public class PropertyManager {
{
addProperty(new BooleanProperty(k, d, comment));
}
-
-
+
+
/**
* Add a numeric property (double)
- *
+ *
* @param k key
* @param d default value
* @param comment the in-file comment
@@ -210,11 +212,11 @@ public class PropertyManager {
{
addProperty(new DoubleProperty(k, d, comment));
}
-
-
+
+
/**
* Add a numeric property
- *
+ *
* @param k key
* @param d default value
* @param comment the in-file comment
@@ -223,11 +225,11 @@ public class PropertyManager {
{
addProperty(new IntegerProperty(k, d, comment));
}
-
-
+
+
/**
* Add a string property
- *
+ *
* @param k key
* @param d default value
* @param comment the in-file comment
@@ -236,22 +238,22 @@ public class PropertyManager {
{
addProperty(new StringProperty(k, d, comment));
}
-
-
+
+
/**
* Add a generic property (can be used with custom property types)
- *
+ *
* @param prop property to add
*/
public void addProperty(Property prop)
{
entries.put(prop.getKey(), prop);
}
-
-
+
+
/**
* Rename key before loading; value is preserved
- *
+ *
* @param oldKey old key
* @param newKey new key
*/
@@ -260,11 +262,11 @@ public class PropertyManager {
renameTable.put(oldKey, newKey);
return;
}
-
-
+
+
/**
* Set value saved to certain key.
- *
+ *
* @param key key
* @param value the saved value
*/
@@ -272,16 +274,16 @@ public class PropertyManager {
{
getProperty(key).setValue(value);
}
-
-
+
+
/**
* Set heading comment of the property store.
- *
+ *
* @param fileComment comment text (can be multi-line)
*/
public void setFileComment(String fileComment)
{
props.setComment(fileComment);
}
-
+
}
diff --git a/src/mightypork/utils/config/propmgr/PropertyStore.java b/src/mightypork/utils/config/propmgr/PropertyStore.java
index be881af..e2cce83 100644
--- a/src/mightypork/utils/config/propmgr/PropertyStore.java
+++ b/src/mightypork/utils/config/propmgr/PropertyStore.java
@@ -9,70 +9,70 @@ import java.util.Collection;
* Interface for a property store (used by {@link PropertyManager}).
* Due to this abstraction, different kind of property storage can be used, not
* only a file.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public interface PropertyStore {
-
+
/**
* Set a header comment
- *
+ *
* @param comment the comment text (can be multi-line)
*/
void setComment(String comment);
-
-
+
+
/**
* Load properties from the file / store. If the file does not exist or is
* inaccessible, nothing is loaded.
*/
void load();
-
-
+
+
/**
* Save properties to the file / store.
- *
+ *
* @throws IOException if the file cannot be created or written.
*/
void save() throws IOException;
-
-
+
+
/**
* Get a property value
- *
+ *
* @param key property key
* @return value retrieved from the file, or null if none found.
*/
String getProperty(String key);
-
-
+
+
/**
* Set a property value
- *
+ *
* @param key property key
* @param value property value to set
* @param comment property comment. Can be null.
*/
void setProperty(String key, String value, String comment);
-
-
+
+
/**
* Remove a property from the list.
- *
+ *
* @param key property key to remove
*/
void removeProperty(String key);
-
-
+
+
/**
* Clear the property list
*/
void clear();
-
-
+
+
/**
* Get keys collection (can be used for iterating)
- *
+ *
* @return keys collection
*/
public Collection keys();
diff --git a/src/mightypork/utils/config/propmgr/properties/BooleanProperty.java b/src/mightypork/utils/config/propmgr/properties/BooleanProperty.java
index 15bf83b..bf3cfd4 100644
--- a/src/mightypork/utils/config/propmgr/properties/BooleanProperty.java
+++ b/src/mightypork/utils/config/propmgr/properties/BooleanProperty.java
@@ -7,21 +7,23 @@ import mightypork.utils.config.propmgr.Property;
/**
* Boolean property
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class BooleanProperty extends Property {
-
- public BooleanProperty(String key, Boolean defaultValue) {
+
+ public BooleanProperty(String key, Boolean defaultValue)
+ {
super(key, defaultValue);
}
-
-
- public BooleanProperty(String key, Boolean defaultValue, String comment) {
+
+
+ public BooleanProperty(String key, Boolean defaultValue, String comment)
+ {
super(key, defaultValue, comment);
}
-
-
+
+
@Override
public void fromString(String string)
{
diff --git a/src/mightypork/utils/config/propmgr/properties/DoubleProperty.java b/src/mightypork/utils/config/propmgr/properties/DoubleProperty.java
index 97f6d66..71d2f71 100644
--- a/src/mightypork/utils/config/propmgr/properties/DoubleProperty.java
+++ b/src/mightypork/utils/config/propmgr/properties/DoubleProperty.java
@@ -7,21 +7,23 @@ import mightypork.utils.config.propmgr.Property;
/**
* Double property
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class DoubleProperty extends Property {
-
- public DoubleProperty(String key, Double defaultValue) {
+
+ public DoubleProperty(String key, Double defaultValue)
+ {
super(key, defaultValue);
}
-
-
- public DoubleProperty(String key, Double defaultValue, String comment) {
+
+
+ public DoubleProperty(String key, Double defaultValue, String comment)
+ {
super(key, defaultValue, comment);
}
-
-
+
+
@Override
public void fromString(String string)
{
diff --git a/src/mightypork/utils/config/propmgr/properties/IntegerProperty.java b/src/mightypork/utils/config/propmgr/properties/IntegerProperty.java
index 6ad0913..fc9fe7e 100644
--- a/src/mightypork/utils/config/propmgr/properties/IntegerProperty.java
+++ b/src/mightypork/utils/config/propmgr/properties/IntegerProperty.java
@@ -7,21 +7,23 @@ import mightypork.utils.config.propmgr.Property;
/**
* Integer property
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class IntegerProperty extends Property {
-
- public IntegerProperty(String key, Integer defaultValue) {
+
+ public IntegerProperty(String key, Integer defaultValue)
+ {
super(key, defaultValue);
}
-
-
- public IntegerProperty(String key, Integer defaultValue, String comment) {
+
+
+ public IntegerProperty(String key, Integer defaultValue, String comment)
+ {
super(key, defaultValue, comment);
}
-
-
+
+
@Override
public void fromString(String string)
{
diff --git a/src/mightypork/utils/config/propmgr/properties/StringProperty.java b/src/mightypork/utils/config/propmgr/properties/StringProperty.java
index 6032ba1..316693c 100644
--- a/src/mightypork/utils/config/propmgr/properties/StringProperty.java
+++ b/src/mightypork/utils/config/propmgr/properties/StringProperty.java
@@ -7,21 +7,23 @@ import mightypork.utils.config.propmgr.Property;
/**
* String property
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class StringProperty extends Property {
-
- public StringProperty(String key, String defaultValue) {
+
+ public StringProperty(String key, String defaultValue)
+ {
super(key, defaultValue);
}
-
-
- public StringProperty(String key, String defaultValue, String comment) {
+
+
+ public StringProperty(String key, String defaultValue, String comment)
+ {
super(key, defaultValue, comment);
}
-
-
+
+
@Override
public void fromString(String string)
{
diff --git a/src/mightypork/utils/config/propmgr/store/PropertyFile.java b/src/mightypork/utils/config/propmgr/store/PropertyFile.java
index 9bc8360..8fcb4e7 100644
--- a/src/mightypork/utils/config/propmgr/store/PropertyFile.java
+++ b/src/mightypork/utils/config/propmgr/store/PropertyFile.java
@@ -13,50 +13,52 @@ import mightypork.utils.config.propmgr.PropertyStore;
/**
* File based implementation utilizing {@link java.util.Properties}, hacked to
* support UTF-8.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class PropertyFile implements PropertyStore {
-
+
private String comment;
- private File file;
- private SortedProperties props;
-
-
- public PropertyFile(File file) {
+ private final File file;
+ private final SortedProperties props;
+
+
+ public PropertyFile(File file)
+ {
this.file = file;
this.comment = null;
this.props = new SortedProperties();
}
-
-
- public PropertyFile(File file, String comment) {
+
+
+ public PropertyFile(File file, String comment)
+ {
this.file = file;
this.comment = comment;
this.props = new SortedProperties();
}
-
-
+
+
@Override
public void setComment(String comment)
{
this.comment = comment;
}
-
-
+
+
@Override
public void load()
{
if (!file.exists()) return;
-
- try (FileInputStream in = new FileInputStream(file)) {
+
+ try(FileInputStream in = new FileInputStream(file)) {
props.load(in);
- } catch (IOException e) {
+ } catch (final IOException e) {
// ignore
}
}
-
-
+
+
@Override
public void save() throws IOException
{
@@ -65,55 +67,55 @@ public class PropertyFile implements PropertyStore {
throw new IOException("Cound not create config file.");
}
}
-
- try (FileOutputStream out = new FileOutputStream(file)) {
+
+ try(FileOutputStream out = new FileOutputStream(file)) {
props.store(out, comment);
}
}
-
-
+
+
@Override
public String getProperty(String key)
{
return props.getProperty(key);
}
-
-
+
+
@Override
public void setProperty(String key, String value, String comment)
{
props.setProperty(key, value);
props.setKeyComment(key, comment);
}
-
-
+
+
@Override
public void removeProperty(String key)
{
props.remove(key);
}
-
-
+
+
@Override
public void clear()
{
props.clear();
}
-
-
+
+
@SuppressWarnings("unchecked")
@Override
public Collection keys()
{
-
+
// Set keys = new HashSet<>();
// for (Object o : props.keySet()) {
// keys.add((String) o);
// }
// return keys;
-
+
// we know it is strings.
return (Collection) (Collection>) props.keySet();
}
-
+
}
diff --git a/src/mightypork/utils/config/propmgr/store/SortedProperties.java b/src/mightypork/utils/config/propmgr/store/SortedProperties.java
index bdd085a..093eeb1 100644
--- a/src/mightypork/utils/config/propmgr/store/SortedProperties.java
+++ b/src/mightypork/utils/config/propmgr/store/SortedProperties.java
@@ -1,7 +1,13 @@
package mightypork.utils.config.propmgr.store;
-import java.io.*;
+import java.io.BufferedWriter;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Hashtable;
@@ -13,19 +19,19 @@ import java.util.Vector;
* Uses UTF-8 encoding and each property can have it's own comment.
* FIXME The quality of this class is dubious. It would probably be a good idea
* to rewrite it without using {@link java.util.Properties} at all.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
class SortedProperties extends java.util.Properties {
-
+
/** Comments for individual keys */
private final Hashtable keyComments = new Hashtable<>();
-
-
+
+
private static void writeComments(BufferedWriter bw, String comm) throws IOException
{
final String comments = comm.replace("\n\n", "\n \n");
-
+
final int len = comments.length();
int current = 0;
int last = 0;
@@ -38,7 +44,7 @@ class SortedProperties extends java.util.Properties {
if (last != current) {
bw.write("# " + comments.substring(last, current));
}
-
+
if (c > '\u00ff') {
uu[2] = hexDigit(c, 12);
uu[3] = hexDigit(c, 8);
@@ -58,13 +64,13 @@ class SortedProperties extends java.util.Properties {
if (last != current) {
bw.write("# " + comments.substring(last, current));
}
-
+
bw.newLine();
bw.newLine();
bw.newLine();
}
-
-
+
+
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public synchronized Enumeration keys()
@@ -77,8 +83,8 @@ class SortedProperties extends java.util.Properties {
Collections.sort(keyList); //sort!
return keyList.elements();
}
-
-
+
+
private static String saveConvert(String theString, boolean escapeSpace, boolean escapeUnicode)
{
final int len = theString.length();
@@ -87,10 +93,10 @@ class SortedProperties extends java.util.Properties {
bufLen = Integer.MAX_VALUE;
}
final StringBuffer result = new StringBuffer(bufLen);
-
+
for (int x = 0; x < len; x++) {
final char ch = theString.charAt(x);
-
+
// Handle common case first, selecting largest block that
// avoids the specials below
if ((ch > 61) && (ch < 127)) {
@@ -102,7 +108,7 @@ class SortedProperties extends java.util.Properties {
result.append(ch);
continue;
}
-
+
switch (ch) {
case ' ':
if (x == 0 || escapeSpace) {
@@ -110,27 +116,27 @@ class SortedProperties extends java.util.Properties {
}
result.append(' ');
break;
-
+
case '\t':
result.append('\\');
result.append('t');
break;
-
+
case '\n':
result.append('\\');
result.append('n');
break;
-
+
case '\r':
result.append('\\');
result.append('r');
break;
-
+
case '\f':
result.append('\\');
result.append('f');
break;
-
+
case '=': // Fall through
case ':': // Fall through
case '#': // Fall through
@@ -138,7 +144,7 @@ class SortedProperties extends java.util.Properties {
result.append('\\');
result.append(ch);
break;
-
+
default:
if (((ch < 0x0020) || (ch > 0x007e)) & escapeUnicode) {
result.append('\\');
@@ -152,14 +158,14 @@ class SortedProperties extends java.util.Properties {
}
}
}
-
+
return result.toString();
}
-
-
+
+
/**
* Set additional comment to a key
- *
+ *
* @param key key for comment
* @param comment the comment
*/
@@ -167,75 +173,75 @@ class SortedProperties extends java.util.Properties {
{
keyComments.put(key, comment);
}
-
-
+
+
@SuppressWarnings("rawtypes")
@Override
public void store(OutputStream out, String comments) throws IOException
{
final BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"));
-
+
final boolean escUnicode = false;
boolean firstEntry = true;
String lastSectionBeginning = "";
-
+
if (comments != null) {
writeComments(bw, comments);
}
-
+
synchronized (this) {
for (final Enumeration e = keys(); e.hasMoreElements();) {
boolean wasNewLine = false;
-
+
String key = (String) e.nextElement();
String val = (String) get(key);
key = saveConvert(key, true, escUnicode);
val = saveConvert(val, false, escUnicode);
-
+
// separate sections
if (!lastSectionBeginning.equals(key.split("[.]")[0])) {
if (!firstEntry) {
bw.newLine();
bw.newLine();
}
-
+
wasNewLine = true;
lastSectionBeginning = key.split("[.]")[0];
}
-
+
if (keyComments.containsKey(key)) {
String cm = keyComments.get(key);
cm = cm.replace("\r", "\n");
cm = cm.replace("\r\n", "\n");
cm = cm.replace("\n\n", "\n \n");
-
+
final String[] cmlines = cm.split("\n");
-
+
// newline before comments
if (!wasNewLine && !firstEntry) {
bw.newLine();
}
-
+
for (final String cmline : cmlines) {
bw.write("# " + cmline);
bw.newLine();
}
}
-
+
bw.write(key + " = " + val);
bw.newLine();
-
+
firstEntry = false;
}
}
bw.flush();
}
-
-
+
+
private static String escapifyStr(String str)
{
final StringBuilder result = new StringBuilder();
-
+
final int len = str.length();
for (int x = 0; x < len; x++) {
final char ch = str.charAt(x);
@@ -243,7 +249,7 @@ class SortedProperties extends java.util.Properties {
result.append(ch);
continue;
}
-
+
result.append('\\');
result.append('u');
result.append(hexDigit(ch, 12));
@@ -253,26 +259,26 @@ class SortedProperties extends java.util.Properties {
}
return result.toString();
}
-
-
+
+
private static char hexDigit(char ch, int offset)
{
final int val = (ch >> offset) & 0xF;
if (val <= 9) {
return (char) ('0' + val);
}
-
+
return (char) ('A' + val - 10);
}
-
-
+
+
@Override
public synchronized void load(InputStream is) throws IOException
{
load(is, "utf-8");
}
-
-
+
+
public void load(InputStream is, String encoding) throws IOException
{
final StringBuilder sb = new StringBuilder();
@@ -282,18 +288,18 @@ class SortedProperties extends java.util.Properties {
if (temp < 0) {
break;
}
-
+
final char c = (char) temp;
sb.append(c);
}
-
+
// discard comments
final String read = sb.toString().replaceAll("(#|;|//|--)[^\n]*\n", "\n");
-
+
final String inputString = escapifyStr(read);
final byte[] bs = inputString.getBytes("ISO-8859-1");
final ByteArrayInputStream bais = new ByteArrayInputStream(bs);
-
+
super.load(bais);
}
}
diff --git a/src/mightypork/utils/eventbus/BusEvent.java b/src/mightypork/utils/eventbus/BusEvent.java
index 4ccf5f1..aba4f5e 100644
--- a/src/mightypork/utils/eventbus/BusEvent.java
+++ b/src/mightypork/utils/eventbus/BusEvent.java
@@ -26,73 +26,73 @@ import mightypork.utils.eventbus.events.flags.SingleReceiverEvent;
* Default sending mode (if not changed by annotations) is queued with
* zero delay.
*
- *
+ *
* @author Ondřej Hruška (MightyPork)
* @param handler type
*/
public abstract class BusEvent {
-
+
private boolean consumed;
private boolean served;
-
-
+
+
/**
* Ask handler to handle this message.
- *
+ *
* @param handler handler instance
*/
protected abstract void handleBy(HANDLER handler);
-
-
+
+
/**
* Consume the event, so no other clients will receive it.
- *
+ *
* @throws UnsupportedOperationException if the {@link NonConsumableEvent}
* annotation is present.
*/
public final void consume()
{
if (consumed) throw new IllegalStateException("Already consumed.");
-
+
if (getClass().isAnnotationPresent(NonConsumableEvent.class)) {
throw new UnsupportedOperationException("Not consumable.");
}
-
+
consumed = true;
}
-
-
+
+
/**
* Deliver to a handler using the handleBy method.
- *
+ *
* @param handler handler instance
*/
final void deliverTo(HANDLER handler)
{
handleBy(handler);
-
+
if (!served) {
if (getClass().isAnnotationPresent(SingleReceiverEvent.class)) {
consumed = true;
}
-
+
served = true;
}
}
-
-
+
+
/**
* Check if the event is consumed. When an event is consumed, no other
* clients will receive it.
- *
+ *
* @return true if consumed
*/
public final boolean isConsumed()
{
return consumed;
}
-
-
+
+
/**
* @return true if the event was served to at least 1 client
*/
@@ -100,8 +100,8 @@ public abstract class BusEvent {
{
return served;
}
-
-
+
+
/**
* Clear "served" and "consumed" flags before dispatching.
*/
@@ -110,11 +110,11 @@ public abstract class BusEvent {
served = false;
consumed = false;
}
-
-
+
+
/**
* Called after all clients have received the event.
- *
+ *
* @param bus event bus instance
*/
public void onDispatchComplete(EventBus bus)
diff --git a/src/mightypork/utils/eventbus/EventBus.java b/src/mightypork/utils/eventbus/EventBus.java
index 53a5ca1..366d3fa 100644
--- a/src/mightypork/utils/eventbus/EventBus.java
+++ b/src/mightypork/utils/eventbus/EventBus.java
@@ -22,75 +22,77 @@ import mightypork.utils.logging.Log;
/**
* An event bus, accommodating multiple EventChannels.
* Channel will be created when an event of type is first encountered.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
final public class EventBus implements Destroyable {
-
+
/**
* Queued event holder
*/
private class DelayQueueEntry implements Delayed {
-
+
private final long due;
private final BusEvent> evt;
-
-
- public DelayQueueEntry(double seconds, BusEvent> event) {
+
+
+ public DelayQueueEntry(double seconds, BusEvent> event)
+ {
super();
this.due = System.currentTimeMillis() + (long) (seconds * 1000);
this.evt = event;
}
-
-
+
+
@Override
public int compareTo(Delayed o)
{
return Long.valueOf(getDelay(TimeUnit.MILLISECONDS)).compareTo(o.getDelay(TimeUnit.MILLISECONDS));
}
-
-
+
+
@Override
public long getDelay(TimeUnit unit)
{
return unit.convert(due - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
}
-
-
+
+
public BusEvent> getEvent()
{
return evt;
}
-
+
}
-
+
/**
* Thread handling queued events
*/
private class QueuePollingThread extends Thread {
-
+
public volatile boolean stopped = false;
-
-
- public QueuePollingThread() {
+
+
+ public QueuePollingThread()
+ {
super("Queue Polling Thread");
}
-
-
+
+
@Override
public void run()
{
DelayQueueEntry evt;
-
+
while (!stopped) {
evt = null;
-
+
try {
evt = sendQueue.take();
} catch (final InterruptedException ignored) {
//
}
-
+
if (evt != null) {
try {
dispatch(evt.getEvent());
@@ -100,46 +102,47 @@ final public class EventBus implements Destroyable {
}
}
}
-
+
}
-
+
static final String logMark = "(bus) ";
-
-
+
+
private static Class> getEventListenerClass(BusEvent> event)
{
return Reflect.getGenericParameters(event.getClass())[0];
}
-
+
/** Log detailed messages (debug) */
public boolean detailedLogging = false;
-
+
/** Queue polling thread */
private final QueuePollingThread busThread;
-
+
/** Registered clients */
private final Set clients = Collections.newSetFromMap(new ConcurrentHashMap());
-
+
/** Whether the bus was destroyed */
private boolean dead = false;
-
+
/** Message channels */
private final Set> channels = Collections.newSetFromMap(new ConcurrentHashMap, Boolean>());
-
+
/** Messages queued for delivery */
private final DelayQueue sendQueue = new DelayQueue<>();
-
-
+
+
/**
* Make a new bus and start it's queue thread.
*/
- public EventBus() {
+ public EventBus()
+ {
busThread = new QueuePollingThread();
busThread.setDaemon(true);
busThread.start();
}
-
-
+
+
/**
* Halt bus thread and reject any future events.
*/
@@ -147,129 +150,129 @@ final public class EventBus implements Destroyable {
public void destroy()
{
assertLive();
-
+
busThread.stopped = true;
dead = true;
}
-
-
+
+
/**
* Send based on annotation
- *
+ *
* @param event event
*/
public void send(BusEvent> event)
{
assertLive();
-
+
final DelayedEvent adelay = Reflect.getAnnotation(event, DelayedEvent.class);
if (adelay != null) {
sendDelayed(event, adelay.delay());
return;
}
-
+
if (Reflect.hasAnnotation(event, DirectEvent.class)) {
sendDirect(event);
return;
}
-
+
sendQueued(event);
}
-
-
+
+
/**
* Add event to a queue
- *
+ *
* @param event event
*/
public void sendQueued(BusEvent> event)
{
assertLive();
-
+
sendDelayed(event, 0);
}
-
-
+
+
/**
* Add event to a queue, scheduled for given time.
- *
+ *
* @param event event
* @param delay delay before event is dispatched
*/
public void sendDelayed(BusEvent> event, double delay)
{
assertLive();
-
+
final DelayQueueEntry dm = new DelayQueueEntry(delay, event);
-
+
if (shallLog(event)) {
Log.f3(logMark + "Qu [" + Support.str(event) + "]" + (delay == 0 ? "" : (", delay: " + delay + "s")));
}
-
+
sendQueue.add(dm);
}
-
-
+
+
/**
* Send immediately.
* Should be used for real-time events that require immediate response, such
* as timing events.
- *
+ *
* @param event event
*/
public void sendDirect(BusEvent> event)
{
assertLive();
-
+
if (shallLog(event)) Log.f3(logMark + "Di [" + Support.str(event) + "]");
-
+
dispatch(event);
}
-
-
+
+
public void sendDirectToChildren(DelegatingClient delegatingClient, BusEvent> event)
{
assertLive();
-
+
if (shallLog(event)) Log.f3(logMark + "Di->sub [" + Support.str(event) + "]");
-
+
doDispatch(delegatingClient.getChildClients(), event);
}
-
-
+
+
/**
* Connect a client to the bus. The client will be connected to all current
* and future channels, until removed from the bus.
- *
+ *
* @param client the client
*/
public void subscribe(Object client)
{
assertLive();
-
+
if (client == null) return;
-
+
clients.add(client);
-
+
if (detailedLogging) Log.f3(logMark + "Client joined: " + Support.str(client));
}
-
-
+
+
/**
* Disconnect a client from the bus.
- *
+ *
* @param client the client
*/
public void unsubscribe(Object client)
{
assertLive();
-
+
clients.remove(client);
-
+
if (detailedLogging) Log.f3(logMark + "Client left: " + Support.str(client));
}
-
-
+
+
@SuppressWarnings("unchecked")
private boolean addChannelForEvent(BusEvent> event)
{
@@ -277,99 +280,99 @@ final public class EventBus implements Destroyable {
if (detailedLogging) {
Log.f3(logMark + "Setting up channel for new event type: " + Support.str(event.getClass()));
}
-
+
final Class> listener = getEventListenerClass(event);
final EventChannel, ?> ch = EventChannel.create(event.getClass(), listener);
-
+
if (ch.canBroadcast(event)) {
-
+
channels.add(ch);
//channels.flush();
-
+
if (detailedLogging) {
Log.f3(logMark + "Created new channel: " + Support.str(event.getClass()) + " -> " + Support.str(listener));
}
-
+
return true;
-
+
} else {
Log.w(logMark + "Could not create channel for event " + Support.str(event.getClass()));
}
-
+
} catch (final Throwable t) {
Log.w(logMark + "Error while trying to add channel for event.", t);
}
-
+
return false;
}
-
-
+
+
/**
* Make sure the bus is not destroyed.
- *
+ *
* @throws IllegalStateException if the bus is dead.
*/
private void assertLive() throws IllegalStateException
{
if (dead) throw new IllegalStateException("EventBus is dead.");
}
-
-
+
+
/**
* Send immediately.
* Should be used for real-time events that require immediate response, such
* as timing events.
- *
+ *
* @param event event
*/
private synchronized void dispatch(BusEvent> event)
{
assertLive();
-
+
doDispatch(clients, event);
event.onDispatchComplete(this);
}
-
-
+
+
/**
* Send to a set of clients
- *
+ *
* @param clients clients
* @param event event
*/
private synchronized void doDispatch(Collection> clients, BusEvent> event)
{
boolean accepted = false;
-
+
event.clearFlags();
-
+
for (int i = 0; i < 2; i++) { // two tries.
-
+
for (final EventChannel, ?> b : channels) {
if (b.canBroadcast(event)) {
accepted = true;
b.broadcast(event, clients);
}
-
+
if (event.isConsumed()) break;
}
-
+
if (!accepted) if (addChannelForEvent(event)) continue;
-
+
break;
}
-
+
if (!accepted) Log.e(logMark + "Not accepted by any channel: " + Support.str(event));
if (!event.wasServed() && shallLog(event)) Log.w(logMark + "Not delivered: " + Support.str(event));
}
-
-
+
+
private boolean shallLog(BusEvent> event)
{
if (!detailedLogging) return false;
if (Reflect.hasAnnotation(event, NotLoggedEvent.class)) return false;
-
+
return true;
}
-
+
}
diff --git a/src/mightypork/utils/eventbus/EventChannel.java b/src/mightypork/utils/eventbus/EventChannel.java
index 911615f..b16016b 100644
--- a/src/mightypork/utils/eventbus/EventChannel.java
+++ b/src/mightypork/utils/eventbus/EventChannel.java
@@ -14,52 +14,53 @@ import mightypork.utils.logging.Log;
/**
* Event delivery channel, module of {@link EventBus}
- *
+ *
* @author Ondřej Hruška (MightyPork)
* @param event type
* @param client (subscriber) type
*/
class EventChannel, CLIENT> {
-
+
private final Class clientClass;
private final Class eventClass;
-
-
+
+
/**
* Create a channel
- *
+ *
* @param eventClass event class
* @param clientClass client class
*/
- public EventChannel(Class eventClass, Class clientClass) {
-
+ public EventChannel(Class eventClass, Class clientClass)
+ {
+
if (eventClass == null || clientClass == null) {
throw new NullPointerException("Null Event or Client class.");
}
-
+
this.clientClass = clientClass;
this.eventClass = eventClass;
}
-
-
+
+
/**
* Try to broadcast a event.
* If event is of wrong type, false
is returned.
- *
+ *
* @param event a event to be sent
* @param clients collection of clients
*/
public void broadcast(BusEvent> event, Collection> clients)
{
if (!canBroadcast(event)) return;
-
+
doBroadcast(eventClass.cast(event), clients, new HashSet<>());
}
-
-
+
+
/**
* Send the event
- *
+ *
* @param event sent event
* @param clients subscribing clients
* @param processed clients already processed
@@ -67,49 +68,49 @@ class EventChannel, CLIENT> {
private void doBroadcast(final EVENT event, final Collection> clients, final Collection processed)
{
for (final Object client : clients) {
-
+
// exclude obvious non-clients
if (!isClientValid(client)) {
continue;
}
-
+
// avoid executing more times
if (processed.contains(client)) {
Log.w(EventBus.logMark + "Client already served: " + Support.str(client));
continue;
}
processed.add(client);
-
+
final boolean must_deliver = Reflect.hasAnnotation(event, NonRejectableEvent.class);
-
+
// opt-out
if (client instanceof ToggleableClient) {
if (!must_deliver && !((ToggleableClient) client).isListening()) continue;
}
-
+
sendTo(client, event);
-
+
if (event.isConsumed()) return;
-
+
// pass on to delegated clients
if (client instanceof DelegatingClient) {
if (must_deliver || ((DelegatingClient) client).doesDelegate()) {
-
+
final Collection> children = ((DelegatingClient) client).getChildClients();
-
+
if (children != null && children.size() > 0) {
doBroadcast(event, children, processed);
}
-
+
}
}
}
}
-
-
+
+
/**
* Send an event to a client.
- *
+ *
* @param client target client
* @param event event to send
*/
@@ -120,11 +121,11 @@ class EventChannel, CLIENT> {
((BusEvent) event).deliverTo((CLIENT) client);
}
}
-
-
+
+
/**
* Check if the given event can be broadcasted by this channel
- *
+ *
* @param event event object
* @return can be broadcasted
*/
@@ -132,11 +133,11 @@ class EventChannel, CLIENT> {
{
return event != null && eventClass.isInstance(event);
}
-
-
+
+
/**
* Create an instance for given types
- *
+ *
* @param eventClass event class
* @param clientClass client class
* @return the broadcaster
@@ -145,11 +146,11 @@ class EventChannel, CLIENT> {
{
return new EventChannel<>(eventClass, clientClass);
}
-
-
+
+
/**
* Check if client is of channel type
- *
+ *
* @param client client
* @return is of type
*/
@@ -157,11 +158,11 @@ class EventChannel, CLIENT> {
{
return clientClass.isInstance(client);
}
-
-
+
+
/**
* Check if the channel is compatible with given
- *
+ *
* @param client client
* @return is supported
*/
@@ -169,8 +170,8 @@ class EventChannel, CLIENT> {
{
return isClientOfChannelType(client) || (client instanceof DelegatingClient);
}
-
-
+
+
@Override
public int hashCode()
{
@@ -180,8 +181,8 @@ class EventChannel, CLIENT> {
result = prime * result + ((eventClass == null) ? 0 : eventClass.hashCode());
return result;
}
-
-
+
+
@Override
public boolean equals(Object obj)
{
@@ -197,8 +198,8 @@ class EventChannel, CLIENT> {
} else if (!eventClass.equals(other.eventClass)) return false;
return true;
}
-
-
+
+
@Override
public String toString()
{
diff --git a/src/mightypork/utils/eventbus/clients/BusNode.java b/src/mightypork/utils/eventbus/clients/BusNode.java
index 6ebf8ce..0e9eae5 100644
--- a/src/mightypork/utils/eventbus/clients/BusNode.java
+++ b/src/mightypork/utils/eventbus/clients/BusNode.java
@@ -11,40 +11,40 @@ import mightypork.utils.eventbus.EventBus;
/**
* Client that can be attached to the {@link EventBus}, or added as a child
* client to another {@link DelegatingClient}
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public abstract class BusNode implements ClientHub {
-
+
private final Set clients = new LinkedHashSet<>();
private boolean listening = true;
private boolean delegating = true;
-
-
+
+
@Override
public Collection getChildClients()
{
return clients;
}
-
-
+
+
@Override
public boolean doesDelegate()
{
return delegating;
}
-
-
+
+
@Override
public boolean isListening()
{
return listening;
}
-
-
+
+
/**
* Add a child subscriber to the {@link EventBus}.
- *
+ *
* @param client
*/
@Override
@@ -52,11 +52,11 @@ public abstract class BusNode implements ClientHub {
{
clients.add(client);
}
-
-
+
+
/**
* Remove a child subscriber
- *
+ *
* @param client subscriber to remove
*/
@Override
@@ -66,22 +66,22 @@ public abstract class BusNode implements ClientHub {
clients.remove(client);
}
}
-
-
+
+
/**
* Set whether events should be received.
- *
+ *
* @param listening receive events
*/
public void setListening(boolean listening)
{
this.listening = listening;
}
-
-
+
+
/**
* Set whether events should be passed on to child nodes
- *
+ *
* @param delegating
*/
public void setDelegating(boolean delegating)
diff --git a/src/mightypork/utils/eventbus/clients/ClientHub.java b/src/mightypork/utils/eventbus/clients/ClientHub.java
index 81011c3..14f2be3 100644
--- a/src/mightypork/utils/eventbus/clients/ClientHub.java
+++ b/src/mightypork/utils/eventbus/clients/ClientHub.java
@@ -8,34 +8,34 @@ import mightypork.utils.eventbus.EventBus;
/**
* Common methods for client hubs (ie delegating vlient implementations)
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public interface ClientHub extends DelegatingClient, ToggleableClient {
-
+
@Override
public boolean doesDelegate();
-
-
+
+
@Override
public Collection getChildClients();
-
-
+
+
@Override
public boolean isListening();
-
-
+
+
/**
* Add a child subscriber to the {@link EventBus}.
- *
+ *
* @param client
*/
public void addChildClient(Object client);
-
-
+
+
/**
* Remove a child subscriber
- *
+ *
* @param client subscriber to remove
*/
void removeChildClient(Object client);
diff --git a/src/mightypork/utils/eventbus/clients/ClientList.java b/src/mightypork/utils/eventbus/clients/ClientList.java
index f0bdae5..e4a873d 100644
--- a/src/mightypork/utils/eventbus/clients/ClientList.java
+++ b/src/mightypork/utils/eventbus/clients/ClientList.java
@@ -7,12 +7,13 @@ import java.util.ArrayList;
/**
* Array-list with varargs constructor, intended to wrap fre clients for
* delegating client.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class ClientList extends ArrayList {
-
- public ClientList(Object... clients) {
+
+ public ClientList(Object... clients)
+ {
for (final Object c : clients) {
super.add(c);
}
diff --git a/src/mightypork/utils/eventbus/clients/DelegatingClient.java b/src/mightypork/utils/eventbus/clients/DelegatingClient.java
index 5d202d3..2fad9fb 100644
--- a/src/mightypork/utils/eventbus/clients/DelegatingClient.java
+++ b/src/mightypork/utils/eventbus/clients/DelegatingClient.java
@@ -8,20 +8,20 @@ import java.util.Collection;
* Client containing child clients. According to the contract, if the collection
* of clients is ordered, the clients will be served in that order. In any case,
* the {@link DelegatingClient} itself will be served beforehand.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public interface DelegatingClient {
-
+
/**
* @return collection of child clients. Can not be null.
*/
public Collection> getChildClients();
-
-
+
+
/**
* @return true if delegating is active
*/
public boolean doesDelegate();
-
+
}
diff --git a/src/mightypork/utils/eventbus/clients/DelegatingList.java b/src/mightypork/utils/eventbus/clients/DelegatingList.java
index 29b94ff..4c2029d 100644
--- a/src/mightypork/utils/eventbus/clients/DelegatingList.java
+++ b/src/mightypork/utils/eventbus/clients/DelegatingList.java
@@ -8,59 +8,61 @@ import mightypork.utils.interfaces.Enableable;
/**
* List of clients, that can be used as a delegating client.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class DelegatingList extends ClientList implements DelegatingClient, Enableable, ToggleableClient {
-
+
private boolean enabled = true;
-
-
+
+
/**
* Delegating list with initial clients
- *
+ *
* @param clients initial list members (clients)
*/
- public DelegatingList(Object... clients) {
+ public DelegatingList(Object... clients)
+ {
super(clients);
}
-
-
+
+
/**
* Empty delegating list.
*/
- public DelegatingList() {
+ public DelegatingList()
+ {
}
-
-
+
+
@Override
public Collection> getChildClients()
{
return this;
}
-
-
+
+
@Override
public boolean doesDelegate()
{
return isEnabled();
}
-
-
+
+
@Override
public boolean isListening()
{
return isEnabled();
}
-
-
+
+
@Override
public void setEnabled(boolean yes)
{
enabled = yes;
}
-
-
+
+
@Override
public boolean isEnabled()
{
diff --git a/src/mightypork/utils/eventbus/clients/ToggleableClient.java b/src/mightypork/utils/eventbus/clients/ToggleableClient.java
index 52b0d41..98eee44 100644
--- a/src/mightypork/utils/eventbus/clients/ToggleableClient.java
+++ b/src/mightypork/utils/eventbus/clients/ToggleableClient.java
@@ -3,14 +3,14 @@ package mightypork.utils.eventbus.clients;
/**
* Client that can toggle receiving messages.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public interface ToggleableClient {
-
+
/**
* @return true if the client wants to receive messages
*/
public boolean isListening();
-
+
}
diff --git a/src/mightypork/utils/eventbus/events/DestroyEvent.java b/src/mightypork/utils/eventbus/events/DestroyEvent.java
index d07fe96..ceb345f 100644
--- a/src/mightypork/utils/eventbus/events/DestroyEvent.java
+++ b/src/mightypork/utils/eventbus/events/DestroyEvent.java
@@ -9,17 +9,17 @@ import mightypork.utils.interfaces.Destroyable;
/**
* Invoke destroy() method of all subscribers. Used to deinit a system.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
@DirectEvent
@NonConsumableEvent
public class DestroyEvent extends BusEvent {
-
+
@Override
public void handleBy(Destroyable handler)
{
handler.destroy();
}
-
+
}
diff --git a/src/mightypork/utils/eventbus/events/UpdateEvent.java b/src/mightypork/utils/eventbus/events/UpdateEvent.java
index d053f64..dfd78c6 100644
--- a/src/mightypork/utils/eventbus/events/UpdateEvent.java
+++ b/src/mightypork/utils/eventbus/events/UpdateEvent.java
@@ -10,25 +10,26 @@ import mightypork.utils.interfaces.Updateable;
/**
* Delta timing update event. Not logged.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
@NotLoggedEvent
@DirectEvent
@NonConsumableEvent
public class UpdateEvent extends BusEvent {
-
+
private final double deltaTime;
-
-
+
+
/**
* @param deltaTime time since last update (sec)
*/
- public UpdateEvent(double deltaTime) {
+ public UpdateEvent(double deltaTime)
+ {
this.deltaTime = deltaTime;
}
-
-
+
+
@Override
public void handleBy(Updateable handler)
{
diff --git a/src/mightypork/utils/eventbus/events/flags/DelayedEvent.java b/src/mightypork/utils/eventbus/events/flags/DelayedEvent.java
index 11bf9d0..39340f2 100644
--- a/src/mightypork/utils/eventbus/events/flags/DelayedEvent.java
+++ b/src/mightypork/utils/eventbus/events/flags/DelayedEvent.java
@@ -1,12 +1,17 @@
package mightypork.utils.eventbus.events.flags;
-import java.lang.annotation.*;
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
/**
* Event that should be queued with given delay (default: 0);
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
@Retention(RetentionPolicy.RUNTIME)
@@ -14,7 +19,7 @@ import java.lang.annotation.*;
@Inherited
@Documented
public @interface DelayedEvent {
-
+
/**
* @return event dispatch delay [seconds]
*/
diff --git a/src/mightypork/utils/eventbus/events/flags/DirectEvent.java b/src/mightypork/utils/eventbus/events/flags/DirectEvent.java
index fdfd138..d7ae285 100644
--- a/src/mightypork/utils/eventbus/events/flags/DirectEvent.java
+++ b/src/mightypork/utils/eventbus/events/flags/DirectEvent.java
@@ -1,12 +1,17 @@
package mightypork.utils.eventbus.events.flags;
-import java.lang.annotation.*;
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
/**
* Event that should not be queued.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
@Retention(RetentionPolicy.RUNTIME)
diff --git a/src/mightypork/utils/eventbus/events/flags/NonConsumableEvent.java b/src/mightypork/utils/eventbus/events/flags/NonConsumableEvent.java
index 873afdc..c6257ed 100644
--- a/src/mightypork/utils/eventbus/events/flags/NonConsumableEvent.java
+++ b/src/mightypork/utils/eventbus/events/flags/NonConsumableEvent.java
@@ -10,12 +10,12 @@ import java.lang.annotation.Target;
/**
* Event that cannot be consumed
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target(ElementType.TYPE)
public @interface NonConsumableEvent {
-
+
}
diff --git a/src/mightypork/utils/eventbus/events/flags/NonRejectableEvent.java b/src/mightypork/utils/eventbus/events/flags/NonRejectableEvent.java
index 164bf4a..d152a00 100644
--- a/src/mightypork/utils/eventbus/events/flags/NonRejectableEvent.java
+++ b/src/mightypork/utils/eventbus/events/flags/NonRejectableEvent.java
@@ -10,12 +10,12 @@ import java.lang.annotation.Target;
/**
* Event that is forcibly delivered to all clients (bypass Toggleable etc)
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target(ElementType.TYPE)
public @interface NonRejectableEvent {
-
+
}
diff --git a/src/mightypork/utils/eventbus/events/flags/NotLoggedEvent.java b/src/mightypork/utils/eventbus/events/flags/NotLoggedEvent.java
index aad9872..b7d9005 100644
--- a/src/mightypork/utils/eventbus/events/flags/NotLoggedEvent.java
+++ b/src/mightypork/utils/eventbus/events/flags/NotLoggedEvent.java
@@ -1,13 +1,18 @@
package mightypork.utils.eventbus.events.flags;
-import java.lang.annotation.*;
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
/**
* Event that's not worth logging, unless there was an error with it.
* Useful for common events that would otherwise clutter the log.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
@Retention(RetentionPolicy.RUNTIME)
diff --git a/src/mightypork/utils/eventbus/events/flags/SingleReceiverEvent.java b/src/mightypork/utils/eventbus/events/flags/SingleReceiverEvent.java
index a166ef2..405e03e 100644
--- a/src/mightypork/utils/eventbus/events/flags/SingleReceiverEvent.java
+++ b/src/mightypork/utils/eventbus/events/flags/SingleReceiverEvent.java
@@ -1,12 +1,17 @@
package mightypork.utils.eventbus.events.flags;
-import java.lang.annotation.*;
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
/**
* Handled only by the first client, then discarded.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
@Retention(RetentionPolicy.RUNTIME)
diff --git a/src/mightypork/utils/exceptions/CorruptDataException.java b/src/mightypork/utils/exceptions/CorruptDataException.java
index 9b43778..65aca35 100644
--- a/src/mightypork/utils/exceptions/CorruptDataException.java
+++ b/src/mightypork/utils/exceptions/CorruptDataException.java
@@ -6,28 +6,32 @@ import java.io.IOException;
/**
* Thrown when data could not be read successfully.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class CorruptDataException extends IOException {
-
- public CorruptDataException() {
+
+ public CorruptDataException()
+ {
super();
}
-
-
- public CorruptDataException(String message, Throwable cause) {
+
+
+ public CorruptDataException(String message, Throwable cause)
+ {
super(message, cause);
}
-
-
- public CorruptDataException(String message) {
+
+
+ public CorruptDataException(String message)
+ {
super(message);
}
-
-
- public CorruptDataException(Throwable cause) {
+
+
+ public CorruptDataException(Throwable cause)
+ {
super(cause);
}
-
+
}
diff --git a/src/mightypork/utils/exceptions/IllegalValueException.java b/src/mightypork/utils/exceptions/IllegalValueException.java
index f7c1f48..40fdeb4 100644
--- a/src/mightypork/utils/exceptions/IllegalValueException.java
+++ b/src/mightypork/utils/exceptions/IllegalValueException.java
@@ -4,27 +4,31 @@ package mightypork.utils.exceptions;
/**
* Thrown when a invalid value is given to a method, or found in a data object /
* file etc
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class IllegalValueException extends RuntimeException {
-
- public IllegalValueException() {
+
+ public IllegalValueException()
+ {
}
-
-
- public IllegalValueException(String message) {
+
+
+ public IllegalValueException(String message)
+ {
super(message);
}
-
-
- public IllegalValueException(Throwable cause) {
+
+
+ public IllegalValueException(Throwable cause)
+ {
super(cause);
}
-
-
- public IllegalValueException(String message, Throwable cause) {
+
+
+ public IllegalValueException(String message, Throwable cause)
+ {
super(message, cause);
}
-
+
}
diff --git a/src/mightypork/utils/exceptions/KeyAlreadyExistsException.java b/src/mightypork/utils/exceptions/KeyAlreadyExistsException.java
index 8e73c7f..a72b864 100644
--- a/src/mightypork/utils/exceptions/KeyAlreadyExistsException.java
+++ b/src/mightypork/utils/exceptions/KeyAlreadyExistsException.java
@@ -3,28 +3,32 @@ package mightypork.utils.exceptions;
/**
* Thrown by a map-like class when the key specified is already taken.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class KeyAlreadyExistsException extends RuntimeException {
-
- public KeyAlreadyExistsException() {
+
+ public KeyAlreadyExistsException()
+ {
super();
}
-
-
- public KeyAlreadyExistsException(String message, Throwable cause) {
+
+
+ public KeyAlreadyExistsException(String message, Throwable cause)
+ {
super(message, cause);
}
-
-
- public KeyAlreadyExistsException(String message) {
+
+
+ public KeyAlreadyExistsException(String message)
+ {
super(message);
}
-
-
- public KeyAlreadyExistsException(Throwable cause) {
+
+
+ public KeyAlreadyExistsException(Throwable cause)
+ {
super(cause);
}
-
+
}
diff --git a/src/mightypork/utils/files/FileSuffixFilter.java b/src/mightypork/utils/files/FileSuffixFilter.java
index ee0f87c..cc37235 100644
--- a/src/mightypork/utils/files/FileSuffixFilter.java
+++ b/src/mightypork/utils/files/FileSuffixFilter.java
@@ -7,39 +7,40 @@ import java.io.FileFilter;
/**
* File filter for certain suffixes
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class FileSuffixFilter implements FileFilter {
-
+
/** Array of allowed suffixes */
private String[] suffixes = null;
-
-
+
+
/**
* Suffix filter
- *
+ *
* @param suffixes var-args allowed suffixes, case insensitive
*/
- public FileSuffixFilter(String... suffixes) {
+ public FileSuffixFilter(String... suffixes)
+ {
this.suffixes = suffixes;
}
-
-
+
+
@Override
public boolean accept(File pathname)
{
if (!pathname.isFile()) return false;
-
+
final String fname = pathname.getName().toLowerCase().trim();
-
+
for (final String suffix : suffixes) {
if (fname.endsWith(suffix.toLowerCase().trim())) {
return true;
}
}
-
+
return false;
}
-
+
}
diff --git a/src/mightypork/utils/files/FileTreeDiff.java b/src/mightypork/utils/files/FileTreeDiff.java
index 6573e1d..19efc70 100644
--- a/src/mightypork/utils/files/FileTreeDiff.java
+++ b/src/mightypork/utils/files/FileTreeDiff.java
@@ -16,134 +16,138 @@ import mightypork.utils.logging.Log;
public class FileTreeDiff {
-
+
private static final byte[] BUFFER = new byte[2048];
private final Checksum ck1 = new Adler32();
private final Checksum ck2 = new Adler32();
-
+
private boolean logging = true;
-
+
private final List> compared = new ArrayList<>();
private final Comparator fileFirstSorter = new Comparator() {
-
+
@Override
public int compare(File o1, File o2)
{
if (!o1.isDirectory() && o2.isDirectory()) return -1;
if (o1.isDirectory() && !o2.isDirectory()) return 1;
-
+
return o1.getName().compareTo(o2.getName());
}
};
-
-
+
+
public void enableLogging(boolean state)
{
logging = state;
}
-
-
+
+
public boolean areEqual(File dir1, File dir2)
{
if (logging) Log.f3("Comparing directory trees:\n 1. " + dir1 + "\n 2. " + dir2);
-
+
try {
compared.clear();
buildList(dir1, dir2);
-
+
calcChecksum();
-
+
if (logging) Log.f3("No difference found.");
-
+
return true;
-
+
} catch (final NotEqualException e) {
if (logging) Log.f3("Difference found:\n" + e.getMessage());
-
+
return false;
}
}
-
-
+
+
private void calcChecksum() throws NotEqualException
{
-
+
for (final Tuple pair : compared) {
ck1.reset();
ck2.reset();
-
- try (FileInputStream in1 = new FileInputStream(pair.a); FileInputStream in2 = new FileInputStream(pair.b)) {
-
- try (CheckedInputStream cin1 = new CheckedInputStream(in1, ck1); CheckedInputStream cin2 = new CheckedInputStream(in2, ck2)) {
-
+
+ try(FileInputStream in1 = new FileInputStream(pair.a);
+ FileInputStream in2 = new FileInputStream(pair.b)) {
+
+ try(CheckedInputStream cin1 = new CheckedInputStream(in1, ck1);
+ CheckedInputStream cin2 = new CheckedInputStream(in2, ck2)) {
+
while (true) {
final int read1 = cin1.read(BUFFER);
final int read2 = cin2.read(BUFFER);
-
+
if (read1 != read2 || ck1.getValue() != ck2.getValue()) {
throw new NotEqualException("Bytes differ:\n" + pair.a + "\n" + pair.b);
}
-
+
if (read1 == -1) break;
}
}
-
+
} catch (final IOException e) {
// ignore
}
}
}
-
-
+
+
private void buildList(File f1, File f2) throws NotEqualException
{
if (f1.isDirectory() != f2.isDirectory()) throw new NotEqualException("isDirectory differs:\n" + f1 + "\n" + f2);
-
+
if (f1.isFile() && f2.isFile()) {
if (f1.length() != f2.length()) throw new NotEqualException("Sizes differ:\n" + f1 + "\n" + f2);
}
-
+
if (f1.isDirectory()) {
final File[] children1 = f1.listFiles();
final File[] children2 = f2.listFiles();
-
+
Arrays.sort(children1, fileFirstSorter);
Arrays.sort(children2, fileFirstSorter);
-
+
if (children1.length != children2.length) throw new NotEqualException("Child counts differ:\n" + f1 + "\n" + f2);
-
+
for (int i = 0; i < children1.length; i++) {
final File ch1 = children1[i];
final File ch2 = children2[i];
-
+
if (!ch1.getName().equals(ch2.getName())) throw new NotEqualException("Filenames differ:\n" + ch1 + "\n" + ch2);
-
+
buildList(ch1, ch2);
}
-
+
} else {
compared.add(new Tuple<>(f1, f2));
}
}
-
+
private class NotEqualException extends Exception {
-
- public NotEqualException(String msg) {
+
+ public NotEqualException(String msg)
+ {
super(msg);
}
-
+
}
-
+
private class Tuple {
-
+
public T a;
public T b;
-
-
- public Tuple(T a, T b) {
+
+
+ public Tuple(T a, T b)
+ {
this.a = a;
this.b = b;
}
}
-
+
}
diff --git a/src/mightypork/utils/files/FileUtil.java b/src/mightypork/utils/files/FileUtil.java
index e8e9c3c..e8b2acc 100644
--- a/src/mightypork/utils/files/FileUtil.java
+++ b/src/mightypork/utils/files/FileUtil.java
@@ -1,7 +1,19 @@
package mightypork.utils.files;
-import java.io.*;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
@@ -12,9 +24,10 @@ import mightypork.utils.string.validation.StringFilter;
public class FileUtil {
+
/**
* Copy directory recursively.
- *
+ *
* @param source source file
* @param target target file
* @throws IOException on error
@@ -27,7 +40,7 @@ public class FileUtil {
/**
* Copy directory recursively - advanced variant.
- *
+ *
* @param source source file
* @param target target file
* @param filter filter accepting only files and dirs to be copied
@@ -61,7 +74,7 @@ public class FileUtil {
/**
* List directory recursively
- *
+ *
* @param source source file
* @param filter filter accepting only files and dirs to be copied (or null)
* @param files list of the found files
@@ -87,7 +100,7 @@ public class FileUtil {
/**
* Copy file using streams. Make sure target directory exists!
- *
+ *
* @param source source file
* @param target target file
* @throws IOException on error
@@ -95,7 +108,8 @@ public class FileUtil {
public static void copyFile(File source, File target) throws IOException
{
- try (InputStream in = new FileInputStream(source); OutputStream out = new FileOutputStream(target)) {
+ try(InputStream in = new FileInputStream(source);
+ OutputStream out = new FileOutputStream(target)) {
copyStream(in, out);
}
@@ -104,7 +118,7 @@ public class FileUtil {
/**
* Copy bytes from input to output stream, leaving out stream open
- *
+ *
* @param in input stream
* @param out output stream
* @throws IOException on error
@@ -129,7 +143,7 @@ public class FileUtil {
/**
* Improved delete
- *
+ *
* @param path deleted path
* @param recursive recursive delete
* @return success
@@ -153,14 +167,14 @@ public class FileUtil {
/**
* Read entire file to a string.
- *
+ *
* @param file file
* @return file contents
* @throws IOException
*/
public static String fileToString(File file) throws IOException
{
- try (FileInputStream fin = new FileInputStream(file)) {
+ try(FileInputStream fin = new FileInputStream(file)) {
return streamToString(fin);
}
@@ -169,7 +183,7 @@ public class FileUtil {
/**
* Get files in a folder (create folder if needed)
- *
+ *
* @param dir folder
* @return list of files
*/
@@ -181,7 +195,7 @@ public class FileUtil {
/**
* Get files in a folder (create folder if needed)
- *
+ *
* @param dir folder
* @param filter file filter
* @return list of files
@@ -202,7 +216,7 @@ public class FileUtil {
/**
* Remove extension.
- *
+ *
* @param file file
* @return filename without extension
*/
@@ -226,7 +240,7 @@ public class FileUtil {
/**
* Remove extension.
- *
+ *
* @param filename
* @return filename and extension
*/
@@ -253,7 +267,7 @@ public class FileUtil {
/**
* Read entire input stream to a string, and close it.
- *
+ *
* @param in input stream
* @return file contents
*/
@@ -265,7 +279,7 @@ public class FileUtil {
/**
* Read input stream to a string, and close it.
- *
+ *
* @param in input stream
* @param lines max number of lines (-1 to disable limit)
* @return file contents
@@ -327,9 +341,8 @@ public class FileUtil {
if (in != null) return in;
try {
- return new FileInputStream(new File(".", path));
+ return new FileInputStream(WorkDir.getFile(path));
} catch (final FileNotFoundException e) {
- // error
Log.w("Could not open resource stream: " + path);
return null;
}
@@ -339,20 +352,20 @@ public class FileUtil {
public static String getResourceAsString(String path)
{
- return streamToString(FileUtil.class.getResourceAsStream(path));
+ return streamToString(getResource(path));
}
/**
* Save string to file
- *
+ *
* @param file file
* @param text string
* @throws IOException on error
*/
public static void stringToFile(File file, String text) throws IOException
{
- try (PrintStream out = new PrintStream(new FileOutputStream(file), false, "UTF-8")) {
+ try(PrintStream out = new PrintStream(new FileOutputStream(file), false, "UTF-8")) {
out.print(text);
@@ -393,14 +406,15 @@ public class FileUtil {
/**
* Copy resource to file
- *
+ *
* @param resname resource name
* @param file out file
* @throws IOException
*/
public static void resourceToFile(String resname, File file) throws IOException
{
- try (InputStream in = FileUtil.getResource(resname); OutputStream out = new FileOutputStream(file)) {
+ try(InputStream in = FileUtil.getResource(resname);
+ OutputStream out = new FileOutputStream(file)) {
FileUtil.copyStream(in, out);
}
@@ -410,14 +424,14 @@ public class FileUtil {
/**
* Get resource as string, safely closing streams.
- *
+ *
* @param resname resource name
* @return resource as string, empty string on failure
* @throws IOException on fail
*/
public static String resourceToString(String resname) throws IOException
{
- try (InputStream in = FileUtil.getResource(resname)) {
+ try(InputStream in = FileUtil.getResource(resname)) {
return streamToString(in);
}
}
diff --git a/src/mightypork/utils/files/InstanceLock.java b/src/mightypork/utils/files/InstanceLock.java
index 1ceff14..3355800 100644
--- a/src/mightypork/utils/files/InstanceLock.java
+++ b/src/mightypork/utils/files/InstanceLock.java
@@ -9,23 +9,23 @@ import java.nio.channels.FileLock;
/**
* Instance lock (avoid running twice)
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class InstanceLock {
-
+
@SuppressWarnings("resource")
public static boolean onFile(final File lockFile)
{
try {
lockFile.getParentFile().mkdirs();
final RandomAccessFile randomAccessFile = new RandomAccessFile(lockFile, "rw");
-
+
final FileLock fileLock = randomAccessFile.getChannel().tryLock();
if (fileLock != null) {
-
+
Runtime.getRuntime().addShutdownHook(new Thread() {
-
+
@Override
public void run()
{
@@ -39,10 +39,10 @@ public class InstanceLock {
}
}
});
-
+
return true;
}
-
+
return false;
} catch (final IOException e) {
System.err.println("IO error while obtaining lock.");
@@ -50,5 +50,5 @@ public class InstanceLock {
return false;
}
}
-
+
}
diff --git a/src/mightypork/utils/files/OsUtils.java b/src/mightypork/utils/files/OsUtils.java
index 5caf312..f0bc59f 100644
--- a/src/mightypork/utils/files/OsUtils.java
+++ b/src/mightypork/utils/files/OsUtils.java
@@ -5,90 +5,90 @@ import java.io.File;
public class OsUtils {
-
+
public static enum EnumOS
{
linux, macos, solaris, unknown, windows;
-
+
public boolean isLinux()
{
return this == linux || this == solaris;
}
-
-
+
+
public boolean isMac()
{
return this == macos;
}
-
-
+
+
public boolean isWindows()
{
return this == windows;
}
}
-
+
private static EnumOS cachedOs;
-
-
+
+
public static File getHomeWorkDir(String dirname)
{
final String userhome = System.getProperty("user.home", ".");
File file;
-
+
switch (getOs()) {
case linux:
case solaris:
file = new File(userhome, dirname + '/');
break;
-
+
case windows:
final String appdata = System.getenv("APPDATA");
-
+
if (appdata != null) {
file = new File(appdata, dirname + '/');
} else {
file = new File(userhome, dirname + '/');
}
-
+
break;
-
+
case macos:
file = new File(userhome, "Library/Application Support/" + dirname);
break;
-
+
default:
file = new File(userhome, dirname + "/");
break;
}
-
+
return file;
}
-
-
+
+
public static EnumOS getOs()
{
if (cachedOs != null) return cachedOs;
-
+
final String s = System.getProperty("os.name").toLowerCase();
-
+
if (s.contains("win")) {
cachedOs = EnumOS.windows;
-
+
} else if (s.contains("mac")) {
cachedOs = EnumOS.macos;
-
+
} else if (s.contains("linux") || s.contains("unix")) {
cachedOs = EnumOS.linux;
-
+
} else if (s.contains("solaris") || s.contains("sunos")) {
cachedOs = EnumOS.solaris;
-
+
} else {
cachedOs = EnumOS.unknown;
}
-
+
return cachedOs;
}
-
+
}
diff --git a/src/mightypork/utils/files/WorkDir.java b/src/mightypork/utils/files/WorkDir.java
new file mode 100644
index 0000000..f45e5de
--- /dev/null
+++ b/src/mightypork/utils/files/WorkDir.java
@@ -0,0 +1,96 @@
+package mightypork.utils.files;
+
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
+import mightypork.utils.logging.Log;
+
+
+/**
+ * Working directory helper.
+ *
+ * @author Ondřej Hruška (MightyPork)
+ */
+public class WorkDir {
+
+ private static File baseDir = new File(".");
+ private static Map namedPaths = new HashMap<>();
+
+
+ /**
+ * Initialize the workdir for the given root path
+ *
+ * @param workdir workdir root path
+ */
+ public static void setBaseDir(File workdir)
+ {
+ WorkDir.baseDir = workdir;
+ }
+
+
+ /**
+ * Add a path alias (dir or file), relative to the workdir.
+ *
+ * @param alias path alias
+ * @param path path relative to workdir
+ */
+ public static void addPath(String alias, String path)
+ {
+ namedPaths.put(alias, path);
+ }
+
+
+ /**
+ * Get workdir folder, create if not exists.
+ *
+ * @param path dir path relative to workdir
+ * @return dir file
+ */
+ public static File getDir(String path)
+ {
+ if (namedPaths.containsKey(path)) path = namedPaths.get(path);
+
+ final File f = new File(baseDir, path);
+ if (!f.exists()) {
+ if (!f.mkdirs()) {
+ Log.w("Could not create a directory: " + f + " (path: " + path + ")");
+ }
+ }
+
+ return f;
+ }
+
+
+ /**
+ * Get workdir file, create parent if not exists.
+ *
+ * @param path dir path relative to workdir
+ * @return dir file
+ */
+ public static File getFile(String path)
+ {
+ if (namedPaths.containsKey(path)) path = namedPaths.get(path);
+
+ final File f = new File(baseDir, path);
+
+ // create the parent dir
+ if (!f.getParent().equals(baseDir)) {
+ f.getParentFile().mkdirs();
+ }
+
+ return f;
+
+ }
+
+
+ /**
+ * @return the workdir File
+ */
+ public static File getBaseDir()
+ {
+ return baseDir;
+ }
+
+}
diff --git a/src/mightypork/utils/files/zip/ZipBuilder.java b/src/mightypork/utils/files/zip/ZipBuilder.java
index 39044aa..82ad8b9 100644
--- a/src/mightypork/utils/files/zip/ZipBuilder.java
+++ b/src/mightypork/utils/files/zip/ZipBuilder.java
@@ -16,31 +16,32 @@ import mightypork.utils.logging.Log;
/**
* Class for building a zip file
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class ZipBuilder {
-
+
private final ZipOutputStream out;
private final HashSet included = new HashSet<>();
-
-
+
+
/**
* @param target target zip file
* @throws IOException if the file is directory or cannot be created
*/
- public ZipBuilder(File target) throws IOException {
-
+ public ZipBuilder(File target) throws IOException
+ {
+
if (!target.getParentFile().mkdirs()) throw new IOException("Could not create output directory.");
-
+
final FileOutputStream dest = new FileOutputStream(target);
out = new ZipOutputStream(new BufferedOutputStream(dest));
}
-
-
+
+
/**
* Add stream to a path
- *
+ *
* @param path path
* @param in stream
* @throws IOException
@@ -53,16 +54,16 @@ public class ZipBuilder {
return; // ignore
}
included.add(path);
-
+
out.putNextEntry(new ZipEntry(path));
-
+
FileUtil.copyStream(in, out);
}
-
-
+
+
/**
* Add string as a file
- *
+ *
* @param path path
* @param text text to write
* @throws IOException
@@ -72,18 +73,18 @@ public class ZipBuilder {
path = preparePath(path);
if (included.contains(path)) return; // ignore
included.add(path);
-
+
out.putNextEntry(new ZipEntry(path));
-
- try (InputStream in = FileUtil.stringToStream(text)) {
+
+ try(InputStream in = FileUtil.stringToStream(text)) {
FileUtil.copyStream(in, out);
}
}
-
-
+
+
/**
* Add resource obtained via FileUtils.getResource()
- *
+ *
* @param path path
* @param resPath resource path
* @throws IOException
@@ -93,34 +94,34 @@ public class ZipBuilder {
path = preparePath(path);
if (included.contains(path)) return; // ignore
included.add(path);
-
+
out.putNextEntry(new ZipEntry(path));
-
- try (InputStream in = FileUtil.getResource(resPath)) {
+
+ try(InputStream in = FileUtil.getResource(resPath)) {
FileUtil.copyStream(in, out);
}
}
-
-
+
+
/**
* Normalize path
- *
+ *
* @param path original path
* @return normalized path
*/
private static String preparePath(String path)
{
path = path.replace("\\", "/");
-
+
if (path.charAt(0) == '/') path = path.substring(1);
-
+
return path;
}
-
-
+
+
/**
* Close the zip stream
- *
+ *
* @throws IOException
*/
public void close() throws IOException
diff --git a/src/mightypork/utils/files/zip/ZipUtils.java b/src/mightypork/utils/files/zip/ZipUtils.java
index 7ab4f42..7b2dfe5 100644
--- a/src/mightypork/utils/files/zip/ZipUtils.java
+++ b/src/mightypork/utils/files/zip/ZipUtils.java
@@ -1,7 +1,12 @@
package mightypork.utils.files.zip;
-import java.io.*;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
@@ -15,17 +20,17 @@ import mightypork.utils.string.validation.StringFilter;
/**
* Utilities for manipulating zip files
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class ZipUtils {
-
+
private static final int BUFFER_SIZE = 2048;
-
-
+
+
/**
* Extract zip file to target directory
- *
+ *
* @param file zip file
* @param outputDir target directory
* @param filter string filter (will be used to test entry names (paths))
@@ -34,15 +39,15 @@ public class ZipUtils {
*/
public static List extractZip(File file, File outputDir, StringFilter filter) throws IOException
{
- try (ZipFile zip = new ZipFile(file)) {
+ try(ZipFile zip = new ZipFile(file)) {
return extractZip(zip, outputDir, filter);
}
}
-
-
+
+
/**
* Extract zip file to target directory
- *
+ *
* @param zip open zip file
* @param outputDir target directory
* @param filter string filter (will be used to test entry names (paths))
@@ -52,53 +57,53 @@ public class ZipUtils {
public static List extractZip(ZipFile zip, File outputDir, StringFilter filter) throws IOException
{
final ArrayList files = new ArrayList<>();
-
+
if (!outputDir.mkdirs()) throw new IOException("Could not create output directory.");
-
+
final Enumeration extends ZipEntry> zipFileEntries = zip.entries();
-
+
// process each entry
while (zipFileEntries.hasMoreElements()) {
final ZipEntry entry = zipFileEntries.nextElement();
-
+
// parse filename and path
final String entryPath = entry.getName();
final File destFile = new File(outputDir, entryPath);
final File destinationParent = destFile.getParentFile();
-
+
if (entry.isDirectory() || (filter != null && !filter.isValid(entryPath))) continue;
-
+
// make sure directories exist
if (!destinationParent.mkdirs()) throw new IOException("Could not create directory.");
-
+
if (!entry.isDirectory()) {
extractZipEntry(zip, entry, destFile);
files.add(entryPath);
}
}
-
+
return files;
}
-
-
+
+
/**
* Read zip entries and add their paths to a list
- *
+ *
* @param zipFile open zip file
* @return list of entry names
* @throws IOException on error
*/
public static List listZip(File zipFile) throws IOException
{
- try (ZipFile zip = new ZipFile(zipFile)) {
+ try(ZipFile zip = new ZipFile(zipFile)) {
return listZip(zip);
}
}
-
-
+
+
/**
* Read zip entries and add their paths to a list
- *
+ *
* @param zip open zip file
* @return list of entry names
* @throws IOException on error
@@ -106,25 +111,25 @@ public class ZipUtils {
public static List listZip(ZipFile zip) throws IOException
{
final ArrayList files = new ArrayList<>();
-
+
final Enumeration extends ZipEntry> zipFileEntries = zip.entries();
-
+
// process each entry
while (zipFileEntries.hasMoreElements()) {
final ZipEntry entry = zipFileEntries.nextElement();
-
+
if (!entry.isDirectory()) {
files.add(entry.getName());
}
}
-
+
return files;
}
-
-
+
+
/**
* Extract one zip entry to target file
- *
+ *
* @param zip open zip file
* @param entry entry from the zip file
* @param destFile destination file ((NOT directory!)
@@ -133,17 +138,20 @@ public class ZipUtils {
public static void extractZipEntry(ZipFile zip, ZipEntry entry, File destFile) throws IOException
{
if (!destFile.getParentFile().mkdirs()) throw new IOException("Could not create output directory.");
-
- try (InputStream in = zip.getInputStream(entry); BufferedInputStream is = new BufferedInputStream(in); FileOutputStream fos = new FileOutputStream(destFile); BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER_SIZE)) {
-
+
+ try(InputStream in = zip.getInputStream(entry);
+ BufferedInputStream is = new BufferedInputStream(in);
+ FileOutputStream fos = new FileOutputStream(destFile);
+ BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER_SIZE)) {
+
FileUtil.copyStream(is, dest);
}
}
-
-
+
+
/**
* Load zip entry to String
- *
+ *
* @param zip open zip file
* @param entry entry from the zip file
* @return loaded string
@@ -164,16 +172,16 @@ public class ZipUtils {
}
}
}
-
-
+
+
public static boolean entryExists(File selectedFile, String string)
{
- try (ZipFile zf = new ZipFile(selectedFile)) {
+ try(ZipFile zf = new ZipFile(selectedFile)) {
return zf.getEntry(string) != null;
} catch (final IOException | RuntimeException e) {
Log.w("Error reading zip.", e);
return false;
}
-
+
}
}
diff --git a/src/mightypork/utils/interfaces/Destroyable.java b/src/mightypork/utils/interfaces/Destroyable.java
index d8cd13c..ae5991e 100644
--- a/src/mightypork/utils/interfaces/Destroyable.java
+++ b/src/mightypork/utils/interfaces/Destroyable.java
@@ -3,11 +3,11 @@ package mightypork.utils.interfaces;
/**
* Object that can be destroyed (free resources etc)
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public interface Destroyable {
-
+
/**
* Destroy this object
*/
diff --git a/src/mightypork/utils/interfaces/Enableable.java b/src/mightypork/utils/interfaces/Enableable.java
index fbdbf19..7b04629 100644
--- a/src/mightypork/utils/interfaces/Enableable.java
+++ b/src/mightypork/utils/interfaces/Enableable.java
@@ -5,19 +5,19 @@ package mightypork.utils.interfaces;
* Can be enabled or disabled.
* Implementations should take appropriate action (ie. stop listening to events,
* updating etc.)
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public interface Enableable {
-
+
/**
* Change enabled state
- *
+ *
* @param yes enabled
*/
public void setEnabled(boolean yes);
-
-
+
+
/**
* @return true if enabled
*/
diff --git a/src/mightypork/utils/interfaces/Hideable.java b/src/mightypork/utils/interfaces/Hideable.java
index 32b3fc2..d34f15c 100644
--- a/src/mightypork/utils/interfaces/Hideable.java
+++ b/src/mightypork/utils/interfaces/Hideable.java
@@ -3,13 +3,13 @@ package mightypork.utils.interfaces;
/**
* Element that can be hidden or visible
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public interface Hideable {
-
+
void setVisible(boolean yes);
-
-
+
+
boolean isVisible();
}
diff --git a/src/mightypork/utils/interfaces/Pauseable.java b/src/mightypork/utils/interfaces/Pauseable.java
index 662e870..c241200 100644
--- a/src/mightypork/utils/interfaces/Pauseable.java
+++ b/src/mightypork/utils/interfaces/Pauseable.java
@@ -3,26 +3,26 @@ package mightypork.utils.interfaces;
/**
* Can be paused & resumed
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public interface Pauseable {
-
+
/**
* Pause operation
*/
public void pause();
-
-
+
+
/**
* Resume operation
*/
public void resume();
-
-
+
+
/**
* @return paused state
*/
public boolean isPaused();
-
+
}
diff --git a/src/mightypork/utils/interfaces/Pollable.java b/src/mightypork/utils/interfaces/Pollable.java
index bc10bd6..2a04d3d 100644
--- a/src/mightypork/utils/interfaces/Pollable.java
+++ b/src/mightypork/utils/interfaces/Pollable.java
@@ -3,11 +3,11 @@ package mightypork.utils.interfaces;
/**
* Can be asked to update it's state
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public interface Pollable {
-
+
/**
* Update internal state
*/
diff --git a/src/mightypork/utils/interfaces/Updateable.java b/src/mightypork/utils/interfaces/Updateable.java
index dfd1310..59dca74 100644
--- a/src/mightypork/utils/interfaces/Updateable.java
+++ b/src/mightypork/utils/interfaces/Updateable.java
@@ -3,14 +3,14 @@ package mightypork.utils.interfaces;
/**
* Uses delta timing
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public interface Updateable {
-
+
/**
* Update item state based on elapsed time
- *
+ *
* @param delta time elapsed since last update, in seconds
*/
public void update(double delta);
diff --git a/src/mightypork/utils/ion/Ion.java b/src/mightypork/utils/ion/Ion.java
index c5184fb..961962c 100644
--- a/src/mightypork/utils/ion/Ion.java
+++ b/src/mightypork/utils/ion/Ion.java
@@ -1,7 +1,12 @@
package mightypork.utils.ion;
-import java.io.*;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -13,17 +18,17 @@ import mightypork.utils.Support;
/**
* Universal data storage system (main API class)
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class Ion {
-
+
private static final int RESERVED_LOW = 0;
private static final int RESERVED_HIGH = 49;
-
+
private static final int RANGE_LOW = 0;
private static final int RANGE_HIGH = 255;
-
+
// marks for object saving
/** Null mark */
static final int NULL = 0;
@@ -79,31 +84,31 @@ public class Ion {
public static final int MAP = 25;
/** Array of arbitrary objects */
public static final int OBJECT_ARRAY = 26;
-
+
/** Ionizables */
private static Map> markToClass = new HashMap<>();
private static Map, Integer> classToMark = new HashMap<>();
-
+
private static Map, IonizerBinary>> ionizersBinary = new HashMap<>();
private static Map, IonizerBundled>> ionizersBundled = new HashMap<>();
-
+
private static boolean reservedMarkChecking;
-
+
static {
reservedMarkChecking = false;
-
+
// register built-ins
register(ION_BUNDLE, IonDataBundle.class);
register(SEQUENCE_WRAPPER, IonSequenceWrapper.class);
register(MAP_WRAPPER, IonMapWrapper.class);
-
+
reservedMarkChecking = true;
}
-
-
+
+
/**
* Register a type for writing/loading.
- *
+ *
* @param mark binary ION mark
* @param objClass class of the registered object
*/
@@ -114,16 +119,16 @@ public class Ion {
throw new IllegalArgumentException("Cannot register directly: " + Support.str(objClass));
}
}
-
+
assertHasImplicitConstructor(objClass);
-
+
registerUsingMark(mark, objClass);
}
-
-
+
+
/**
* Try to register a type using a static final ION_MARK int field.
- *
+ *
* @param objClass type class
*/
public static void register(Class> objClass)
@@ -133,66 +138,66 @@ public class Ion {
throw new IllegalArgumentException("Cannot register directly: " + Support.str(objClass));
}
}
-
+
assertHasImplicitConstructor(objClass);
registerUsingConstant(objClass);
}
-
-
+
+
private static void registerUsingMark(int mark, Class> objClass)
{
assertMarkAvailable(mark, objClass);
-
+
markToClass.put(mark, objClass);
classToMark.put(objClass, mark);
}
-
-
+
+
public static void registerUsingConstant(Class> objClass)
{
try {
final int mark = ((Number) Reflect.getConstantFieldValue(objClass, "ION_MARK")).intValue();
-
+
registerUsingMark(mark, objClass);
-
+
} catch (final Exception e) {
throw new RuntimeException("Could not register " + Support.str(objClass) + " using an ION_MARK field.", e);
}
}
-
-
+
+
/**
* Register new binary ionizer.
- *
+ *
* @param mark binary ION mark
* @param ionizer ionizer
*/
public static void registerIndirect(int mark, IonizerBinary> ionizer)
{
final Class> objClass = Reflect.getGenericParameters(ionizer.getClass())[0];
-
+
registerUsingMark(mark, objClass);
-
+
ionizersBinary.put(objClass, ionizer);
}
-
-
+
+
/**
* Register new bundled ionizer.
- *
+ *
* @param mark binary ION mark
* @param ionizer ionizer
*/
public static void registerIndirect(int mark, IonizerBundled> ionizer)
{
final Class> objClass = Reflect.getGenericParameters(ionizer.getClass())[0];
-
+
registerUsingMark(mark, objClass);
-
+
ionizersBundled.put(objClass, ionizer);
}
-
-
+
+
private static void assertHasImplicitConstructor(Class> objClass)
{
try {
@@ -201,28 +206,28 @@ public class Ion {
throw new RuntimeException("Class " + objClass + " doesn't have an implicit constructor.");
}
}
-
-
+
+
private static void assertMarkAvailable(int mark, Class> objClass)
{
// negative marks are allowed.
if (mark > RANGE_HIGH) throw new IllegalArgumentException("Mark must be < 256.");
if (mark < RANGE_LOW) throw new IllegalArgumentException("Mark must be positive.");
-
+
if (reservedMarkChecking && isMarkReserved(mark)) {
throw new IllegalArgumentException("Marks " + RESERVED_LOW + ".." + RESERVED_HIGH + " are reserved.");
}
-
+
if (markToClass.containsKey(mark)) {
throw new IllegalArgumentException("Mark " + mark + " is already in use.");
}
-
+
if (classToMark.containsKey(objClass)) {
throw new IllegalArgumentException(Support.str(objClass) + " is already registered.");
}
}
-
-
+
+
/**
* Load binary from file and cast.
*/
@@ -230,19 +235,19 @@ public class Ion {
{
return fromFile(new File(path));
}
-
-
+
+
/**
* Load binary from file and cast.
*/
public static T fromFile(File file) throws IOException
{
- try (InputStream in = new FileInputStream(file)) {
+ try(InputStream in = new FileInputStream(file)) {
return fromStream(in);
}
}
-
-
+
+
/**
* Write binary to file with mark.
*/
@@ -250,49 +255,49 @@ public class Ion {
{
toFile(new File(path), obj);
}
-
-
+
+
/**
* Write binary to file with mark.
*/
public static void toFile(File file, Object obj) throws IOException
{
- try (OutputStream out = new FileOutputStream(file)) {
-
+ try(OutputStream out = new FileOutputStream(file)) {
+
toStream(out, obj);
-
+
out.flush();
} catch (final Exception e) {
throw new IOException("Error writing to ION file.", e);
}
}
-
-
+
+
/**
* Load object from stream based on mark, try to cast.
*/
public static T fromStream(InputStream in) throws IOException
{
- try (final IonInput inp = new IonInput(in)) {
+ try(final IonInput inp = new IonInput(in)) {
return (T) inp.readObject();
}
}
-
-
+
+
/**
* Write object to output with a mark.
*/
public static void toStream(OutputStream out, Object obj) throws IOException
{
- try (IonOutput iout = new IonOutput(out)) {
+ try(IonOutput iout = new IonOutput(out)) {
iout.writeObject(obj);
}
}
-
-
+
+
/**
* Get ion input
- *
+ *
* @param path file path to read
* @return input
* @throws IOException
@@ -301,11 +306,11 @@ public class Ion {
{
return getInput(new File(path));
}
-
-
+
+
/**
* Get ion input
- *
+ *
* @param file file to read
* @return input
* @throws IOException
@@ -315,11 +320,11 @@ public class Ion {
{
return new IonInput(new FileInputStream(file));
}
-
-
+
+
/**
* Get ion output
- *
+ *
* @param path file path to write
* @return output
* @throws IOException
@@ -328,11 +333,11 @@ public class Ion {
{
return getOutput(new File(path));
}
-
-
+
+
/**
* Get ion output
- *
+ *
* @param file file to write
* @return output
* @throws IOException
@@ -342,8 +347,8 @@ public class Ion {
{
return new IonOutput(new FileOutputStream(file));
}
-
-
+
+
/**
* Create new bundle and write the object to it.
*/
@@ -353,12 +358,12 @@ public class Ion {
content.save(ib);
return ib;
}
-
-
+
+
/**
* Try to unwrap an object from bundle. The object class must have implicit
* accessible constructor.
- *
+ *
* @param bundle unwrapped bundle
* @param objClass class of desired object
* @return the object unwrapped
@@ -374,56 +379,56 @@ public class Ion {
throw new IOException("Could not instantiate " + Support.str(objClass) + ".");
}
}
-
-
+
+
static Class> getClassForMark(int mark)
{
return markToClass.get(mark);
}
-
-
+
+
static IonizerBinary> getIonizerBinaryForClass(Class> clz)
{
return ionizersBinary.get(clz);
}
-
-
+
+
static IonizerBundled> getIonizerBundledForClass(Class> clz)
{
return ionizersBundled.get(clz);
}
-
-
+
+
public static int getMark(Object object)
{
assertRegistered(object);
-
+
return classToMark.get(object.getClass());
}
-
-
+
+
/**
* @return true if the mark is for a registered {@link IonBinary} object
*/
static boolean isMarkForBinary(int mark)
{
if (!markToClass.containsKey(mark)) return false;
-
+
return IonBinary.class.isAssignableFrom(markToClass.get(mark));
}
-
-
+
+
/**
* @return true if the mark is for a registered {@link IonBinary} object
*/
static boolean isMarkForBundled(int mark)
{
if (!markToClass.containsKey(mark)) return false;
-
+
return IonBundled.class.isAssignableFrom(markToClass.get(mark));
}
-
-
+
+
/**
* @return true if the mark is for a registered indirectly saved binary
* object
@@ -431,11 +436,11 @@ public class Ion {
static boolean isMarkForIndirectBinary(int mark)
{
if (!markToClass.containsKey(mark)) return false;
-
+
return ionizersBinary.containsKey(markToClass.get(mark));
}
-
-
+
+
/**
* @return true if the mark is for a registered indirectly saved bundled
* object
@@ -443,11 +448,11 @@ public class Ion {
static boolean isMarkForIndirectBundled(int mark)
{
if (!markToClass.containsKey(mark)) return false;
-
+
return ionizersBundled.containsKey(markToClass.get(mark));
}
-
-
+
+
/**
* @return true if the mark is reserved for internal use
*/
@@ -455,8 +460,8 @@ public class Ion {
{
return mark >= RESERVED_LOW && mark <= RESERVED_HIGH;
}
-
-
+
+
/**
* @return true if the mark is for a registered {@link IonBinary} object
*/
@@ -464,14 +469,14 @@ public class Ion {
{
final Class> clazz = object.getClass();
if (classToMark.containsKey(clazz)) return true;
-
+
return false;
}
-
-
+
+
/**
* Make sure object is registered in the table.
- *
+ *
* @throws IOException if not registered or class mismatch
*/
static void assertRegistered(Object obj)
@@ -480,8 +485,8 @@ public class Ion {
throw new RuntimeException("Type not registered: " + Support.str(obj.getClass()));
}
}
-
-
+
+
/**
* For get all external registered types - just like if the class was
* freshly loaded. Can be used for unit tests.
@@ -489,31 +494,31 @@ public class Ion {
public static void reset()
{
final List toRemove = new ArrayList<>();
-
- // remove direct
+
+ // remove direct
for (final Integer mark : markToClass.keySet()) {
if (!isMarkReserved(mark)) {
toRemove.add(mark);
}
}
-
+
for (final int i : toRemove) {
-
+
final Class> clz = markToClass.remove(i);
-
+
classToMark.remove(clz);
ionizersBinary.remove(clz);
ionizersBundled.remove(clz);
}
}
-
-
+
+
public static boolean isObjectIndirectBundled(Object obj)
{
return ionizersBundled.containsKey(obj.getClass());
}
-
-
+
+
public static boolean isObjectIndirectBinary(Object obj)
{
return ionizersBinary.containsKey(obj.getClass());
diff --git a/src/mightypork/utils/ion/IonBinary.java b/src/mightypork/utils/ion/IonBinary.java
index 0b5bf1e..2499da1 100644
--- a/src/mightypork/utils/ion/IonBinary.java
+++ b/src/mightypork/utils/ion/IonBinary.java
@@ -7,24 +7,24 @@ import java.io.IOException;
/**
* Binary ion object. If a class implements both binary and bundled, then binary
* will be preferred by both IonInput and IonOutput.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public interface IonBinary {
-
+
/**
* Load data from the input stream.
- *
+ *
* @param in input stream
* @throws IOException
*/
void load(IonInput in) throws IOException;
-
-
+
+
/**
* Store data to output stream (in such way that the load method will later
* be able to read it).
- *
+ *
* @param out Output stream
* @throws IOException
*/
diff --git a/src/mightypork/utils/ion/IonBundled.java b/src/mightypork/utils/ion/IonBundled.java
index e74d9aa..ec0a1de 100644
--- a/src/mightypork/utils/ion/IonBundled.java
+++ b/src/mightypork/utils/ion/IonBundled.java
@@ -4,22 +4,22 @@ package mightypork.utils.ion;
/**
* Bundled ion object. If a class implements both binary and bundled, then
* binary will be preferred by both IonInput and IonOutput.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public interface IonBundled {
-
+
/**
* Load this object from the data bundle
- *
+ *
* @param in bundle to load from
*/
void load(IonDataBundle in);
-
-
+
+
/**
* Save this object to the data bundle
- *
+ *
* @param out bundle to save into
*/
void save(IonDataBundle out);
diff --git a/src/mightypork/utils/ion/IonDataBundle.java b/src/mightypork/utils/ion/IonDataBundle.java
index e6cfdb7..4b34666 100644
--- a/src/mightypork/utils/ion/IonDataBundle.java
+++ b/src/mightypork/utils/ion/IonDataBundle.java
@@ -12,34 +12,34 @@ import java.util.Map;
/**
* Ion data bundle - simplified Map with facilities for storing maps and
* sequences.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class IonDataBundle implements IonBinary {
-
+
private final Map backingMap = new HashMap<>();
-
-
+
+
/**
* Clear & fill a provided bundle with elements from a bundle value
- *
+ *
* @param key key
* @param filled bundle to fill
*/
public void loadBundle(String key, IonDataBundle filled)
{
if (!containsKey(key)) return;
-
+
final IonDataBundle ib = get(key, new IonDataBundle());
-
+
filled.clear();
filled.putAll(ib);
}
-
-
+
+
/**
* Check if a key is used in the bundle
- *
+ *
* @param key key to check
* @return true if this key is used in the bundle
*/
@@ -47,11 +47,11 @@ public class IonDataBundle implements IonBinary {
{
return backingMap.containsKey(key);
}
-
-
+
+
/**
* Check if a value is contained in the bundle
- *
+ *
* @param value value to check
* @return true if this value is contained in the bundle
*/
@@ -59,11 +59,11 @@ public class IonDataBundle implements IonBinary {
{
return backingMap.containsValue(value);
}
-
-
+
+
/**
* Get a map value
- *
+ *
* @param key key
* @return a new Map with elements from that value
*/
@@ -71,11 +71,11 @@ public class IonDataBundle implements IonBinary {
{
return loadMap(key, new LinkedHashMap());
}
-
-
+
+
/**
* Clear & fill the provided map with elements from a map value
- *
+ *
* @param key key
* @param filled Map to fill
*/
@@ -87,11 +87,11 @@ public class IonDataBundle implements IonBinary {
imw.fill(filled);
return filled;
}
-
-
+
+
/**
* Get a sequence value
- *
+ *
* @param key key
* @return a new Collection with elements from that value
*/
@@ -99,11 +99,11 @@ public class IonDataBundle implements IonBinary {
{
return loadSequence(key, new ArrayList());
}
-
-
+
+
/**
* Clear & fill the provided Collection with elements from a sequence value
- *
+ *
* @param key key
* @param filled Collection to fill
* @return the filled collection
@@ -114,15 +114,15 @@ public class IonDataBundle implements IonBinary {
if (isw == null) throw new RuntimeException("No such key: " + key);
filled.clear();
isw.fill(filled);
-
+
return filled;
}
-
-
+
+
/**
* Load a bundled object from a bundle value.
* The object does not have to be registered.
- *
+ *
* @param key key
* @param loaded loaded object
* @return the loaded object
@@ -131,17 +131,17 @@ public class IonDataBundle implements IonBinary {
{
final IonDataBundle bu = get(key, null);
if (bu == null) throw new RuntimeException("No such key: " + key);
-
+
loaded.load(bu);
-
+
return loaded;
}
-
-
+
+
/**
* Save a bundled object to a bundle value.
* The object does not have to be registered.
- *
+ *
* @param key key
* @param saved saved object
*/
@@ -151,11 +151,11 @@ public class IonDataBundle implements IonBinary {
saved.save(bu);
put(key, bu);
}
-
-
+
+
/**
* Get value, or fallback (if none found of with bad type).
- *
+ *
* @param key
* @param fallback value
* @return value
@@ -170,11 +170,11 @@ public class IonDataBundle implements IonBinary {
return fallback;
}
}
-
-
+
+
/**
* Get value, or null (if none found of with bad type).
- *
+ *
* @param key
* @return value
*/
@@ -182,127 +182,127 @@ public class IonDataBundle implements IonBinary {
{
return get(key, (T) null);
}
-
-
+
+
public void put(String key, Object value)
{
if (key == null || value == null) return;
if (!Ion.isRegistered(value)) throw new IllegalArgumentException("Cannot add to bundle, not registered: " + value);
backingMap.put(key, value);
}
-
-
+
+
public void put(String key, boolean value)
{
backingMap.put(key, value);
}
-
-
+
+
public void put(String key, byte value)
{
backingMap.put(key, value);
}
-
-
+
+
public void put(String key, char value)
{
backingMap.put(key, value);
}
-
-
+
+
public void put(String key, short value)
{
backingMap.put(key, value);
}
-
-
+
+
public void put(String key, int value)
{
backingMap.put(key, value);
}
-
-
+
+
public void put(String key, long value)
{
backingMap.put(key, value);
}
-
-
+
+
public void put(String key, double value)
{
backingMap.put(key, value);
}
-
-
+
+
public void put(String key, float value)
{
backingMap.put(key, value);
}
-
-
+
+
public void put(String key, String value)
{
backingMap.put(key, value);
}
-
-
+
+
public void put(String key, boolean[] value)
{
backingMap.put(key, value);
}
-
-
+
+
public void put(String key, char[] value)
{
backingMap.put(key, value);
}
-
-
+
+
public void put(String key, short[] value)
{
backingMap.put(key, value);
}
-
-
+
+
public void put(String key, int[] value)
{
backingMap.put(key, value);
}
-
-
+
+
public void put(String key, long[] value)
{
backingMap.put(key, value);
}
-
-
+
+
public void put(String key, double[] value)
{
backingMap.put(key, value);
}
-
-
+
+
public void put(String key, float[] value)
{
backingMap.put(key, value);
}
-
-
+
+
public void put(String key, String[] value)
{
backingMap.put(key, value);
}
-
-
+
+
public void put(String key, Object[] value)
{
backingMap.put(key, value);
}
-
-
+
+
/**
* Put a sequence to the bundle.
- *
+ *
* @param key key
* @param c value (Collection)
*/
@@ -311,11 +311,11 @@ public class IonDataBundle implements IonBinary {
{
backingMap.put(key, new IonSequenceWrapper(c));
}
-
-
+
+
/**
* Put a map to the bundle.
- *
+ *
* @param key key
* @param m value (Map)
*/
@@ -324,44 +324,44 @@ public class IonDataBundle implements IonBinary {
{
backingMap.put(key, new IonMapWrapper(m));
}
-
-
+
+
@Override
public void load(IonInput in) throws IOException
{
in.readMap(backingMap);
}
-
-
+
+
@Override
public void save(IonOutput out) throws IOException
{
out.writeMap(backingMap);
}
-
-
+
+
/**
* Get number of elements in the bundle
- *
+ *
* @return size
*/
public int size()
{
return backingMap.size();
}
-
-
+
+
/**
* Check whether the bundle is empty
- *
+ *
* @return true if empty
*/
public boolean isEmpty()
{
return backingMap.isEmpty();
}
-
-
+
+
/**
* Remove all elements
*/
@@ -369,11 +369,11 @@ public class IonDataBundle implements IonBinary {
{
backingMap.clear();
}
-
-
+
+
/**
* Remove a value by key
- *
+ *
* @param key key to remove
* @return the removed object
*/
@@ -381,26 +381,26 @@ public class IonDataBundle implements IonBinary {
{
return backingMap.remove(key);
}
-
-
+
+
/**
* Put all from another bundle
- *
+ *
* @param anotherBundle another bundle
*/
public void putAll(IonDataBundle anotherBundle)
{
backingMap.putAll(anotherBundle.backingMap);
}
-
-
+
+
@Override
public String toString()
{
return backingMap.toString();
}
-
-
+
+
@Override
public int hashCode()
{
@@ -409,8 +409,8 @@ public class IonDataBundle implements IonBinary {
result = prime * result + ((backingMap == null) ? 0 : backingMap.hashCode());
return result;
}
-
-
+
+
@Override
public boolean equals(Object obj)
{
diff --git a/src/mightypork/utils/ion/IonInput.java b/src/mightypork/utils/ion/IonInput.java
index 33a0092..87e2ef9 100644
--- a/src/mightypork/utils/ion/IonInput.java
+++ b/src/mightypork/utils/ion/IonInput.java
@@ -1,7 +1,14 @@
package mightypork.utils.ion;
-import java.io.*;
+import java.io.Closeable;
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@@ -12,31 +19,33 @@ import mightypork.utils.exceptions.CorruptDataException;
/**
* Ion input stream
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class IonInput implements Closeable {
-
+
private final DataInput in;
private final InputStream stream;
-
-
+
+
@SuppressWarnings("resource")
- public IonInput(File inFile) throws FileNotFoundException {
+ public IonInput(File inFile) throws FileNotFoundException
+ {
this(new FileInputStream(inFile));
}
-
-
- public IonInput(InputStream in) {
+
+
+ public IonInput(InputStream in)
+ {
this.stream = in;
this.in = new DataInputStream(in);
}
-
-
+
+
/**
* Read int 0-255. Suitable when the int was written using
* writeIntByte()
method.
- *
+ *
* @return int
* @throws IOException
*/
@@ -44,12 +53,12 @@ public class IonInput implements Closeable {
{
return in.readUnsignedByte();
}
-
-
+
+
/**
* Read an int 0-65535. Suitable when the int was written using
* writeIntShort()
method.
- *
+ *
* @return int
* @throws IOException
*/
@@ -57,62 +66,62 @@ public class IonInput implements Closeable {
{
return in.readUnsignedShort();
}
-
-
+
+
public boolean readBoolean() throws IOException
{
return in.readBoolean();
}
-
-
+
+
public byte readByte() throws IOException
{
return in.readByte();
}
-
-
+
+
public short readShort() throws IOException
{
return in.readShort();
}
-
-
+
+
public char readChar() throws IOException
{
return in.readChar();
}
-
-
+
+
public int readInt() throws IOException
{
return in.readInt();
}
-
-
+
+
public long readLong() throws IOException
{
return in.readLong();
}
-
-
+
+
public float readFloat() throws IOException
{
return in.readFloat();
}
-
-
+
+
public double readDouble() throws IOException
{
return in.readDouble();
}
-
-
+
+
public String readString() throws IOException
{
return in.readUTF();
}
-
-
+
+
public boolean[] readBooleans() throws IOException
{
final int length = readLength();
@@ -122,8 +131,8 @@ public class IonInput implements Closeable {
}
return arr;
}
-
-
+
+
public byte[] readBytes() throws IOException
{
final int length = readLength();
@@ -133,8 +142,8 @@ public class IonInput implements Closeable {
}
return arr;
}
-
-
+
+
public char[] readChars() throws IOException
{
final int length = readLength();
@@ -144,8 +153,8 @@ public class IonInput implements Closeable {
}
return arr;
}
-
-
+
+
public short[] readShorts() throws IOException
{
final int length = readLength();
@@ -155,8 +164,8 @@ public class IonInput implements Closeable {
}
return arr;
}
-
-
+
+
public int[] readInts() throws IOException
{
final int length = readLength();
@@ -166,8 +175,8 @@ public class IonInput implements Closeable {
}
return arr;
}
-
-
+
+
public long[] readLongs() throws IOException
{
final int length = readLength();
@@ -177,8 +186,8 @@ public class IonInput implements Closeable {
}
return arr;
}
-
-
+
+
public float[] readFloats() throws IOException
{
final int length = readLength();
@@ -188,8 +197,8 @@ public class IonInput implements Closeable {
}
return arr;
}
-
-
+
+
public double[] readDoubles() throws IOException
{
final int length = readLength();
@@ -199,8 +208,8 @@ public class IonInput implements Closeable {
}
return arr;
}
-
-
+
+
public String[] readStrings() throws IOException
{
final int length = readLength();
@@ -210,8 +219,8 @@ public class IonInput implements Closeable {
}
return arr;
}
-
-
+
+
public Object[] readObjects() throws IOException
{
final int length = readLength();
@@ -221,8 +230,8 @@ public class IonInput implements Closeable {
}
return arr;
}
-
-
+
+
/**
* Read bundle without a mark
*/
@@ -232,8 +241,8 @@ public class IonInput implements Closeable {
ib.load(this);
return ib;
}
-
-
+
+
/**
* Read bundle without a mark, load into a provided one
*/
@@ -242,20 +251,20 @@ public class IonInput implements Closeable {
filled.clear();
filled.load(this);
}
-
-
+
+
private int readMark() throws IOException
{
return readIntByte();
}
-
-
+
+
private int readLength() throws IOException
{
return readInt();
}
-
-
+
+
/**
*
* Read object based on mark; if null mark is found, returns default value.
@@ -264,7 +273,7 @@ public class IonInput implements Closeable {
* If, however, an object of invalid or different type is found, an
* exception will be thrown.
*
- *
+ *
* @param def default value.
* @return the loaded object
* @throws CorruptDataException
@@ -279,130 +288,130 @@ public class IonInput implements Closeable {
throw new CorruptDataException("Could not load object.", e);
}
}
-
-
+
+
/**
* Read single object, preceded by a mark.
- *
+ *
* @return the loaded object
* @throws IOException
*/
public Object readObject() throws IOException
{
final int mark = readMark();
-
+
try {
-
+
if (Ion.isMarkForBinary(mark)) {
IonBinary loaded;
-
+
loaded = (IonBinary) Ion.getClassForMark(mark).newInstance();
-
+
loaded.load(this);
return loaded;
}
-
+
if (Ion.isMarkForBundled(mark)) {
IonBundled loaded;
-
+
loaded = (IonBundled) Ion.getClassForMark(mark).newInstance();
-
+
final IonDataBundle ib = readBundle();
loaded.load(ib);
return loaded;
}
-
+
if (Ion.isMarkForIndirectBundled(mark)) {
final IonizerBundled> ionizer = Ion.getIonizerBundledForClass(Ion.getClassForMark(mark));
return ionizer.load(readBundle());
}
-
+
if (Ion.isMarkForIndirectBinary(mark)) {
final IonizerBinary> ionizer = Ion.getIonizerBinaryForClass(Ion.getClassForMark(mark));
return ionizer.load(this);
}
-
+
} catch (final Exception e) {
throw new RuntimeException("Could not load object for mark: " + mark, e);
}
-
+
switch (mark) {
case Ion.NULL:
return null;
-
+
case Ion.BOOLEAN:
return readBoolean();
-
+
case Ion.BYTE:
return readByte();
-
+
case Ion.CHAR:
return readChar();
-
+
case Ion.SHORT:
return readShort();
-
+
case Ion.INT:
return readInt();
-
+
case Ion.LONG:
return readLong();
-
+
case Ion.FLOAT:
return readFloat();
-
+
case Ion.DOUBLE:
return readDouble();
-
+
case Ion.STRING:
return readString();
-
+
case Ion.BOOLEAN_ARRAY:
return readBooleans();
-
+
case Ion.BYTE_ARRAY:
return readBytes();
-
+
case Ion.CHAR_ARRAY:
return readChars();
-
+
case Ion.SHORT_ARRAY:
return readShorts();
-
+
case Ion.INT_ARRAY:
return readInts();
-
+
case Ion.LONG_ARRAY:
return readLongs();
-
+
case Ion.FLOAT_ARRAY:
return readFloats();
-
+
case Ion.DOUBLE_ARRAY:
return readDoubles();
-
+
case Ion.STRING_ARRAY:
return readStrings();
-
+
case Ion.OBJECT_ARRAY:
return readObjects();
-
+
case Ion.MAP:
return readMap();
-
+
case Ion.SEQUENCE:
return readSequence();
-
+
default:
throw new CorruptDataException("Invalid mark: " + mark);
}
}
-
-
+
+
/**
* Reads mark and returns true if the mark is ENTRY, false if the mark is
* END. Throws an exception otherwise.
- *
+ *
* @return mark was ENTRY
* @throws IOException when the mark is neither ENTRY or END.
*/
@@ -411,14 +420,14 @@ public class IonInput implements Closeable {
final int mark = readMark();
if (mark == Ion.ENTRY) return true;
if (mark == Ion.END) return false;
-
+
throw new CorruptDataException("Unexpected mark in sequence: " + mark);
}
-
-
+
+
/**
* Read a sequence of elements into an ArrayList
- *
+ *
* @return the collection
* @throws IOException
*/
@@ -426,11 +435,11 @@ public class IonInput implements Closeable {
{
return readSequence(new ArrayList());
}
-
-
+
+
/**
* Load entries into a collection. The collection is cleaned first.
- *
+ *
* @param filled collection to populate
* @return the collection
* @throws IOException
@@ -448,11 +457,11 @@ public class IonInput implements Closeable {
throw new CorruptDataException("Unexpected element type in sequence.", e);
}
}
-
-
+
+
/**
* Read element pairs into a HashMap
- *
+ *
* @return the map
* @throws IOException
*/
@@ -460,11 +469,11 @@ public class IonInput implements Closeable {
{
return readMap(new HashMap());
}
-
-
+
+
/**
* Load data into a map. The map is cleaned first.
- *
+ *
* @param filled filled map
* @return the map
* @throws IOException
@@ -477,7 +486,7 @@ public class IonInput implements Closeable {
while (hasNextEntry()) {
final K key = (K) readObject();
final V value = (V) readObject();
-
+
filled.put(key, value);
}
return filled;
@@ -485,8 +494,8 @@ public class IonInput implements Closeable {
throw new CorruptDataException("Unexpected element type in map.", e);
}
}
-
-
+
+
@Override
public void close() throws IOException
{
diff --git a/src/mightypork/utils/ion/IonMapWrapper.java b/src/mightypork/utils/ion/IonMapWrapper.java
index 765944d..6c90980 100644
--- a/src/mightypork/utils/ion/IonMapWrapper.java
+++ b/src/mightypork/utils/ion/IonMapWrapper.java
@@ -8,45 +8,47 @@ import java.util.Map;
@SuppressWarnings({ "rawtypes", "unchecked" })
class IonMapWrapper implements IonBinary {
-
+
private final Map map;
-
-
- public IonMapWrapper() {
+
+
+ public IonMapWrapper()
+ {
map = new LinkedHashMap<>();
}
-
-
- public IonMapWrapper(Map saved) {
+
+
+ public IonMapWrapper(Map saved)
+ {
map = saved;
}
-
-
+
+
@Override
public void load(IonInput in) throws IOException
{
map.clear();
in.readMap(map);
}
-
-
+
+
@Override
public void save(IonOutput out) throws IOException
{
out.writeMap(map);
}
-
-
+
+
public void fill(Map o)
{
o.clear();
o.putAll(map);
}
-
-
+
+
public Map getMap()
{
return map;
}
-
+
}
diff --git a/src/mightypork/utils/ion/IonOutput.java b/src/mightypork/utils/ion/IonOutput.java
index 863ddf8..c82a9e4 100644
--- a/src/mightypork/utils/ion/IonOutput.java
+++ b/src/mightypork/utils/ion/IonOutput.java
@@ -1,7 +1,14 @@
package mightypork.utils.ion;
-import java.io.*;
+import java.io.Closeable;
+import java.io.DataOutput;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
import java.util.Collection;
import java.util.Map;
import java.util.Map.Entry;
@@ -9,99 +16,101 @@ import java.util.Map.Entry;
/**
* Ion output stream
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class IonOutput implements Closeable {
-
+
private final DataOutput out;
private final OutputStream stream;
-
-
+
+
@SuppressWarnings("resource")
- public IonOutput(File outFile) throws FileNotFoundException {
+ public IonOutput(File outFile) throws FileNotFoundException
+ {
this(new FileOutputStream(outFile));
}
-
-
- public IonOutput(OutputStream out) {
+
+
+ public IonOutput(OutputStream out)
+ {
this.stream = out;
this.out = new DataOutputStream(out);
}
-
-
+
+
public void writeBoolean(boolean a) throws IOException
{
out.writeBoolean(a);
}
-
-
+
+
public void writeByte(int a) throws IOException
{
out.writeByte(a);
}
-
-
+
+
public void writeShort(int a) throws IOException
{
out.writeShort(a);
}
-
-
+
+
public void writeChar(int a) throws IOException
{
out.writeChar(a);
}
-
-
+
+
public void writeInt(int a) throws IOException
{
out.writeInt(a);
}
-
-
+
+
public void writeIntShort(int a) throws IOException
{
out.writeShort(a);
}
-
-
+
+
public void writeIntByte(int a) throws IOException
{
out.writeByte(a);
}
-
-
+
+
public void writeLong(long a) throws IOException
{
out.writeLong(a);
}
-
-
+
+
public void writeFloat(float a) throws IOException
{
out.writeFloat(a);
}
-
-
+
+
public void writeDouble(double a) throws IOException
{
out.writeDouble(a);
}
-
-
+
+
public void writeBytes(String a) throws IOException
{
out.writeBytes(a);
}
-
-
+
+
public void writeString(String a) throws IOException
{
out.writeUTF(a);
}
-
-
+
+
public void writeBooleans(boolean[] arr) throws IOException
{
writeLength(arr.length);
@@ -109,8 +118,8 @@ public class IonOutput implements Closeable {
out.writeBoolean(a);
}
}
-
-
+
+
public void writeBytes(byte[] arr) throws IOException
{
writeLength(arr.length);
@@ -118,8 +127,8 @@ public class IonOutput implements Closeable {
out.writeByte(a);
}
}
-
-
+
+
public void writeChars(char[] arr) throws IOException
{
writeLength(arr.length);
@@ -127,8 +136,8 @@ public class IonOutput implements Closeable {
out.writeChar(a);
}
}
-
-
+
+
public void writeShorts(short[] arr) throws IOException
{
writeLength(arr.length);
@@ -136,8 +145,8 @@ public class IonOutput implements Closeable {
out.writeShort(a);
}
}
-
-
+
+
public void writeInts(int[] arr) throws IOException
{
writeLength(arr.length);
@@ -145,8 +154,8 @@ public class IonOutput implements Closeable {
out.writeInt(a);
}
}
-
-
+
+
public void writeLongs(long[] arr) throws IOException
{
writeLength(arr.length);
@@ -154,8 +163,8 @@ public class IonOutput implements Closeable {
out.writeLong(a);
}
}
-
-
+
+
public void writeFloats(float[] arr) throws IOException
{
writeLength(arr.length);
@@ -163,8 +172,8 @@ public class IonOutput implements Closeable {
out.writeFloat(a);
}
}
-
-
+
+
public void writeDoubles(double[] arr) throws IOException
{
writeLength(arr.length);
@@ -172,8 +181,8 @@ public class IonOutput implements Closeable {
out.writeDouble(a);
}
}
-
-
+
+
public void writeStrings(String[] arr) throws IOException
{
writeLength(arr.length);
@@ -181,8 +190,8 @@ public class IonOutput implements Closeable {
out.writeUTF(a);
}
}
-
-
+
+
/**
* Write a bundle without a mark
*/
@@ -190,11 +199,11 @@ public class IonOutput implements Closeable {
{
bundle.save(this);
}
-
-
+
+
/**
* Write array of objects. Works with all that is supported by writeObject()
- *
+ *
* @param arr array to write
* @throws IOException on IO error or on invalid object type.
*/
@@ -205,8 +214,8 @@ public class IonOutput implements Closeable {
writeObject(a);
}
}
-
-
+
+
public void writeSequence(Collection sequence) throws IOException
{
for (final T element : sequence) {
@@ -215,51 +224,51 @@ public class IonOutput implements Closeable {
}
endSequence();
}
-
-
+
+
public void writeMap(Map map) throws IOException
{
for (final Entry e : map.entrySet()) {
if (e.getValue() == null) {
continue;
}
-
+
startEntry();
writeObject(e.getKey());
writeObject(e.getValue());
}
endSequence();
}
-
-
+
+
public void endSequence() throws IOException
{
writeMark(Ion.END);
}
-
-
+
+
public void startEntry() throws IOException
{
writeMark(Ion.ENTRY);
}
-
-
+
+
private void writeMark(int mark) throws IOException
{
writeIntByte(mark);
}
-
-
+
+
private void writeLength(int length) throws IOException
{
writeInt(length);
}
-
-
+
+
/**
* Write an object. Supported are built-in types and types registered to
* Ion.
- *
+ *
* @param obj obj to write
* @throws IOException on IO error or invalid object type.
*/
@@ -269,177 +278,177 @@ public class IonOutput implements Closeable {
writeMark(Ion.NULL);
return;
}
-
+
if (obj instanceof IonBinary) {
final IonBinary iObj = (IonBinary) obj;
-
+
writeMark(Ion.getMark(obj));
iObj.save(this);
return;
}
-
+
if (obj instanceof IonBundled) {
final IonBundled iObj = (IonBundled) obj;
-
+
writeMark(Ion.getMark(obj));
-
+
final IonDataBundle bundle = new IonDataBundle();
iObj.save(bundle);
writeBundle(bundle);
-
+
return;
}
-
+
if (Ion.isObjectIndirectBundled(obj)) {
final IonizerBundled> ionizer = Ion.getIonizerBundledForClass(obj.getClass());
-
+
writeMark(Ion.getMark(obj));
-
+
final IonDataBundle bundle = new IonDataBundle();
ionizer._save(obj, bundle);
writeBundle(bundle);
return;
}
-
+
if (Ion.isObjectIndirectBinary(obj)) {
final IonizerBinary> ionizer = Ion.getIonizerBinaryForClass(obj.getClass());
-
+
writeMark(Ion.getMark(obj));
-
+
ionizer._save(obj, this);
return;
}
-
+
if (obj instanceof Map) {
writeMark(Ion.MAP);
writeMap((Map, ?>) obj);
return;
}
-
+
if (obj instanceof Collection) {
writeMark(Ion.SEQUENCE);
writeSequence((Collection>) obj);
return;
}
-
+
if (obj instanceof Boolean) {
writeMark(Ion.BOOLEAN);
writeBoolean((Boolean) obj);
return;
}
-
+
if (obj instanceof Byte) {
writeMark(Ion.BYTE);
writeByte((Byte) obj);
return;
}
-
+
if (obj instanceof Character) {
writeMark(Ion.CHAR);
writeChar((Character) obj);
return;
}
-
+
if (obj instanceof Short) {
writeMark(Ion.SHORT);
writeShort((Short) obj);
return;
}
-
+
if (obj instanceof Integer) {
writeMark(Ion.INT);
writeInt((Integer) obj);
return;
}
-
+
if (obj instanceof Long) {
writeMark(Ion.LONG);
writeLong((Long) obj);
return;
}
-
+
if (obj instanceof Float) {
writeMark(Ion.FLOAT);
writeFloat((Float) obj);
return;
}
-
+
if (obj instanceof Double) {
writeMark(Ion.DOUBLE);
writeDouble((Double) obj);
return;
}
-
+
if (obj instanceof String) {
writeMark(Ion.STRING);
writeString((String) obj);
return;
}
-
+
if (obj instanceof boolean[]) {
writeMark(Ion.BOOLEAN_ARRAY);
writeBooleans((boolean[]) obj);
return;
}
-
+
if (obj instanceof byte[]) {
writeMark(Ion.BYTE_ARRAY);
writeBytes((byte[]) obj);
return;
}
-
+
if (obj instanceof char[]) {
writeMark(Ion.CHAR_ARRAY);
writeChars((char[]) obj);
return;
}
-
+
if (obj instanceof short[]) {
writeMark(Ion.SHORT_ARRAY);
writeShorts((short[]) obj);
return;
}
-
+
if (obj instanceof int[]) {
writeMark(Ion.INT_ARRAY);
writeInts((int[]) obj);
return;
}
-
+
if (obj instanceof long[]) {
writeMark(Ion.LONG_ARRAY);
writeLongs((long[]) obj);
return;
}
-
+
if (obj instanceof float[]) {
writeMark(Ion.FLOAT_ARRAY);
writeFloats((float[]) obj);
return;
}
-
+
if (obj instanceof double[]) {
writeMark(Ion.DOUBLE_ARRAY);
writeDoubles((double[]) obj);
return;
}
-
+
if (obj instanceof String[]) {
writeMark(Ion.STRING_ARRAY);
writeStrings((String[]) obj);
return;
}
-
+
if (obj instanceof Object[]) {
writeMark(Ion.OBJECT_ARRAY);
writeObjects((Object[]) obj);
return;
}
-
+
throw new IOException("Object " + obj + " could not be be written to stream.");
}
-
-
+
+
@Override
public void close() throws IOException
{
diff --git a/src/mightypork/utils/ion/IonSequenceWrapper.java b/src/mightypork/utils/ion/IonSequenceWrapper.java
index 54fdefd..0b98fa7 100644
--- a/src/mightypork/utils/ion/IonSequenceWrapper.java
+++ b/src/mightypork/utils/ion/IonSequenceWrapper.java
@@ -8,45 +8,47 @@ import java.util.Collection;
@SuppressWarnings({ "rawtypes", "unchecked" })
class IonSequenceWrapper implements IonBinary {
-
+
private Collection collection = new ArrayList();
-
-
- public IonSequenceWrapper() {
+
+
+ public IonSequenceWrapper()
+ {
collection = new ArrayList();
}
-
-
- public IonSequenceWrapper(Collection saved) {
+
+
+ public IonSequenceWrapper(Collection saved)
+ {
collection = saved;
}
-
-
+
+
@Override
public void load(IonInput in) throws IOException
{
collection.clear();
in.readSequence(collection);
}
-
-
+
+
@Override
public void save(IonOutput out) throws IOException
{
out.writeSequence(collection);
}
-
-
+
+
public void fill(Collection o)
{
o.clear();
o.addAll(collection);
}
-
-
+
+
public Collection getSequence()
{
return collection;
}
-
+
}
diff --git a/src/mightypork/utils/ion/IonizerBinary.java b/src/mightypork/utils/ion/IonizerBinary.java
index 6471ef6..f12da43 100644
--- a/src/mightypork/utils/ion/IonizerBinary.java
+++ b/src/mightypork/utils/ion/IonizerBinary.java
@@ -7,35 +7,35 @@ import java.io.IOException;
/**
* External ionizer using a IonOutput / IonInput - can be used if the data type
* cannot be modified to implement the proper interface
- *
+ *
* @author Ondřej Hruška (MightyPork)
* @param
*/
public abstract class IonizerBinary {
-
+
@SuppressWarnings("unchecked")
final void _save(Object object, IonOutput out) throws IOException
{
save((T) object, out);
}
-
-
+
+
/**
* Save an object to ion output
- *
+ *
* @param object object to save
* @param out ion output
* @throws IOException
*/
public abstract void save(T object, IonOutput out) throws IOException;
-
-
+
+
/**
* Load an object from ion input
- *
+ *
* @param in ion input
* @return the loaded object
*/
public abstract T load(IonInput in) throws IOException;
-
+
}
diff --git a/src/mightypork/utils/ion/IonizerBundled.java b/src/mightypork/utils/ion/IonizerBundled.java
index 63a657f..14731ff 100644
--- a/src/mightypork/utils/ion/IonizerBundled.java
+++ b/src/mightypork/utils/ion/IonizerBundled.java
@@ -4,34 +4,34 @@ package mightypork.utils.ion;
/**
* External ionizer using a data bundle - can be used if the data type cannot be
* modified to implement the proper interface
- *
+ *
* @author Ondřej Hruška (MightyPork)
* @param
*/
public abstract class IonizerBundled {
-
+
@SuppressWarnings("unchecked")
final void _save(Object object, IonDataBundle out)
{
save((T) object, out);
}
-
-
+
+
/**
* Save an object to data bundle
- *
+ *
* @param object object to save
* @param out bundle to save to
*/
public abstract void save(T object, IonDataBundle out);
-
-
+
+
/**
* Load an object from a bundle
- *
+ *
* @param in bundle to load from
* @return the loaded object
*/
public abstract T load(IonDataBundle in);
-
+
}
diff --git a/src/mightypork/utils/logging/Log.java b/src/mightypork/utils/logging/Log.java
index 152e67f..b61123e 100644
--- a/src/mightypork/utils/logging/Log.java
+++ b/src/mightypork/utils/logging/Log.java
@@ -18,23 +18,23 @@ import mightypork.utils.string.StringUtil;
/**
* A log.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class Log {
-
+
private static LogWriter main = null;
private static boolean enabled = true;
private static final LogMonitorStdout sysoMonitor = new LogMonitorStdout();
private static final long start_ms = System.currentTimeMillis();
-
+
private static HashMap logs = new HashMap<>();
-
-
+
+
/**
* Create a logger. If another with the name already exists, it'll be
* retrieved instead of creating a new one.
- *
+ *
* @param logName log name (used for filename, should be application-unique)
* @param logFile log file; old logs will be kept here too.
* @param oldLogsCount number of old logs to keep, -1 infinite, 0 none.
@@ -44,20 +44,20 @@ public class Log {
public static synchronized LogWriter create(String logName, File logFile, int oldLogsCount)
{
if (logs.containsKey(logName)) return logs.get(logName);
-
+
final ArchivingLog log = new ArchivingLog(logName, logFile, oldLogsCount);
log.init();
-
+
logs.put(logName, log);
-
+
return log;
}
-
-
+
+
/**
* Create a logger. If another with the name already exists, it'll be
* retrieved instead of creating a new one.
- *
+ *
* @param logName log name (used for filename, must be application-unique)
* @param logFile log file; old logs will be kept here too.
* @return the created Log instance
@@ -66,53 +66,53 @@ public class Log {
public static synchronized LogWriter create(String logName, File logFile)
{
if (logs.containsKey(logName)) return logs.get(logName);
-
+
final SimpleLog log = new SimpleLog(logName, logFile);
log.init();
-
+
logs.put(logName, log);
-
+
return log;
}
-
-
+
+
public static void setMainLogger(LogWriter log)
{
main = log;
}
-
-
+
+
public static LogWriter getMainLogger()
{
return main;
}
-
-
+
+
public static void addMonitor(LogMonitor mon)
{
assertInited();
-
+
main.addMonitor(mon);
}
-
-
+
+
public static void removeMonitor(LogMonitor mon)
{
assertInited();
-
+
main.removeMonitor(mon);
}
-
-
+
+
private static void assertInited()
{
if (main == null) throw new IllegalStateException("Main logger not initialized.");
}
-
-
+
+
/**
* Log a message
- *
+ *
* @param level message level
* @param msg message text
*/
@@ -120,17 +120,17 @@ public class Log {
{
if (enabled) {
sysoMonitor.onMessageLogged(level, formatMessage(level, msg, null, start_ms));
-
+
if (main != null) {
main.log(level, msg);
}
}
}
-
-
+
+
/**
* Log a message
- *
+ *
* @param level message level
* @param msg message text
* @param t thrown exception
@@ -139,83 +139,83 @@ public class Log {
{
if (enabled) {
sysoMonitor.onMessageLogged(level, formatMessage(level, msg, t, start_ms));
-
+
if (main != null) {
main.log(level, msg, t);
}
}
}
-
-
+
+
/**
* Log FINE message
- *
+ *
* @param msg message
*/
public static void f1(String msg)
{
log(Level.FINE, msg);
}
-
-
+
+
/**
* Log FINER message
- *
+ *
* @param msg message
*/
public static void f2(String msg)
{
log(Level.FINER, msg);
}
-
-
+
+
/**
* Log FINEST message
- *
+ *
* @param msg message
*/
public static void f3(String msg)
{
log(Level.FINEST, msg);
}
-
-
+
+
/**
* Log INFO message
- *
+ *
* @param msg message
*/
public static void i(String msg)
{
log(Level.INFO, msg);
}
-
-
+
+
/**
* Log WARNING message (less severe than ERROR)
- *
+ *
* @param msg message
*/
public static void w(String msg)
{
log(Level.WARNING, msg);
}
-
-
+
+
/**
* Log ERROR message
- *
+ *
* @param msg message
*/
public static void e(String msg)
{
log(Level.SEVERE, msg);
}
-
-
+
+
/**
* Log warning message with exception
- *
+ *
* @param msg message
* @param thrown thrown exception
*/
@@ -223,22 +223,22 @@ public class Log {
{
log(Level.WARNING, msg, thrown);
}
-
-
+
+
/**
* Log exception thrown as warning
- *
+ *
* @param thrown thrown exception
*/
public static void w(Throwable thrown)
{
log(Level.WARNING, null, thrown);
}
-
-
+
+
/**
* Log error message
- *
+ *
* @param msg message
* @param thrown thrown exception
*/
@@ -246,42 +246,42 @@ public class Log {
{
log(Level.SEVERE, msg, thrown);
}
-
-
+
+
/**
* Log exception thrown as error
- *
+ *
* @param thrown thrown exception
*/
public static void e(Throwable thrown)
{
log(Level.SEVERE, null, thrown);
}
-
-
+
+
public static void enable(boolean flag)
{
enabled = flag;
}
-
-
+
+
public static void setSysoutLevel(Level level)
{
sysoMonitor.setLevel(level);
}
-
-
+
+
public static void setLevel(Level level)
{
assertInited();
-
+
main.setLevel(level);
}
-
-
+
+
/**
* Get stack trace from throwable
- *
+ *
* @param t
* @return trace
*/
@@ -294,31 +294,31 @@ public class Log {
sw.flush();
return sw.toString();
}
-
-
+
+
public static String formatMessage(Level level, String message, Throwable throwable, long start_ms)
{
if (message == null) message = "";
-
+
final String nl = System.getProperty("line.separator");
-
+
if (message.length() > 0) {
if (message.equals("\n")) {
return nl;
}
-
+
if (message.charAt(0) == '\n') {
message = nl + message.substring(1);
}
}
-
+
final long time_ms = (System.currentTimeMillis() - start_ms);
final double time_s = time_ms / 1000D;
final String time = String.format("%6.2f ", time_s);
final String time_blank = StringUtil.repeat(" ", time.length());
-
+
String prefix = "[ ? ]";
-
+
if (level == Level.FINE) {
prefix = "[ # ] ";
} else if (level == Level.FINER) {
@@ -332,13 +332,13 @@ public class Log {
} else if (level == Level.WARNING) {
prefix = "[!W!] ";
}
-
+
message = time + prefix + message.replaceAll("\n", nl + time_blank + prefix) + nl;
-
+
if (throwable != null) {
message += getStackTrace(throwable);
}
-
+
return message;
}
}
diff --git a/src/mightypork/utils/logging/monitors/LogMonitor.java b/src/mightypork/utils/logging/monitors/LogMonitor.java
index aaef36e..50552d6 100644
--- a/src/mightypork/utils/logging/monitors/LogMonitor.java
+++ b/src/mightypork/utils/logging/monitors/LogMonitor.java
@@ -5,32 +5,32 @@ import java.util.logging.Level;
public abstract class LogMonitor {
-
+
private boolean enabled = true;
private Level accepted = Level.ALL;
-
-
+
+
public void onMessageLogged(Level level, String message)
{
if (!enabled) return;
if (accepted.intValue() > level.intValue()) return;
-
+
logMessage(level, message);
}
-
-
+
+
protected abstract void logMessage(Level level, String message);
-
-
+
+
public void setLevel(Level level)
{
this.accepted = level;
}
-
-
+
+
public void enable(boolean flag)
{
this.enabled = flag;
}
-
+
}
diff --git a/src/mightypork/utils/logging/monitors/LogMonitorStdout.java b/src/mightypork/utils/logging/monitors/LogMonitorStdout.java
index 964f6b5..c87dc59 100644
--- a/src/mightypork/utils/logging/monitors/LogMonitorStdout.java
+++ b/src/mightypork/utils/logging/monitors/LogMonitorStdout.java
@@ -5,7 +5,7 @@ import java.util.logging.Level;
public class LogMonitorStdout extends LogMonitor {
-
+
@Override
protected void logMessage(Level level, String message)
{
@@ -15,5 +15,5 @@ public class LogMonitorStdout extends LogMonitor {
System.out.print(message);
}
}
-
+
}
diff --git a/src/mightypork/utils/logging/writers/ArchivingLog.java b/src/mightypork/utils/logging/writers/ArchivingLog.java
index c5f2cb8..a6a9f62 100644
--- a/src/mightypork/utils/logging/writers/ArchivingLog.java
+++ b/src/mightypork/utils/logging/writers/ArchivingLog.java
@@ -15,100 +15,102 @@ import mightypork.utils.string.StringUtil;
/**
* Logger that cleans directory & archives old logs
- *
+ *
* @author Ondřej Hruška (MightyPork)
* @copy (c) 2014
*/
public class ArchivingLog extends SimpleLog {
-
+
/** Number of old logs to keep */
private final int logs_to_keep;
-
-
+
+
/**
* Log
- *
+ *
* @param name log name
* @param file log file (in log directory)
* @param oldLogCount number of old log files to keep: -1 all, 0 none.
*/
- public ArchivingLog(String name, File file, int oldLogCount) {
+ public ArchivingLog(String name, File file, int oldLogCount)
+ {
super(name, file);
this.logs_to_keep = oldLogCount;
}
-
-
+
+
/**
* Log, not keeping 5 last log files (default);
- *
+ *
* @param name log name
* @param file log file (in log directory)
*/
- public ArchivingLog(String name, File file) {
+ public ArchivingLog(String name, File file)
+ {
super(name, file);
this.logs_to_keep = 5;
}
-
-
+
+
@Override
public void init()
{
cleanLoggingDirectory();
-
+
super.init();
}
-
-
+
+
private void cleanLoggingDirectory()
{
if (logs_to_keep == 0) return; // overwrite
-
+
final File log_file = getFile();
final File log_dir = log_file.getParentFile();
final String fname = FileUtil.getBasename(log_file.toString());
-
+
// move old file
for (final File f : FileUtil.listDirectory(log_dir)) {
if (!f.isFile()) continue;
if (f.equals(getFile())) {
-
+
final Date d = new Date(f.lastModified());
final String fbase = fname + '_' + (new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss")).format(d);
final String suff = "." + getSuffix();
String cntStr = "";
File f2;
-
+
for (int cnt = 0; (f2 = new File(log_dir, fbase + cntStr + suff)).exists(); cntStr = "_" + (++cnt)) {}
-
+
if (!f.renameTo(f2)) throw new RuntimeException("Could not move log file.");
}
}
-
+
if (logs_to_keep == -1) return; // keep all
-
+
final List oldLogs = FileUtil.listDirectory(log_dir, new FileFilter() {
-
+
@Override
public boolean accept(File f)
{
if (f.isDirectory()) return false;
if (!f.getName().endsWith(getSuffix())) return false;
if (!f.getName().startsWith(fname)) return false;
-
+
return true;
}
-
+
});
-
+
Collections.sort(oldLogs, new Comparator() {
-
+
@Override
public int compare(File o1, File o2)
{
return o1.getName().compareTo(o2.getName());
}
});
-
+
// playing with fireee
for (int i = 0; i < oldLogs.size() - logs_to_keep; i++) {
if (!oldLogs.get(i).delete()) {
@@ -116,8 +118,8 @@ public class ArchivingLog extends SimpleLog {
}
}
}
-
-
+
+
/**
* @return log filename suffix
*/
diff --git a/src/mightypork/utils/logging/writers/LogWriter.java b/src/mightypork/utils/logging/writers/LogWriter.java
index fc52f5b..cfbd7d5 100644
--- a/src/mightypork/utils/logging/writers/LogWriter.java
+++ b/src/mightypork/utils/logging/writers/LogWriter.java
@@ -8,65 +8,65 @@ import mightypork.utils.logging.monitors.LogMonitor;
/**
* Log interface
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public interface LogWriter {
-
+
/**
* Prepare logs for logging
*/
void init();
-
-
+
+
/**
* Add log monitor
- *
+ *
* @param mon monitor
*/
void addMonitor(LogMonitor mon);
-
-
+
+
/**
* Remove a monitor
- *
+ *
* @param removed monitor to remove
*/
void removeMonitor(LogMonitor removed);
-
-
+
+
/**
* Set logging level
- *
+ *
* @param level
*/
void setLevel(Level level);
-
-
+
+
/**
* Enable logging.
- *
+ *
* @param flag do enable logging
*/
void enable(boolean flag);
-
-
+
+
/**
* Log a message
- *
+ *
* @param level message level
* @param msg message text
*/
void log(Level level, String msg);
-
-
+
+
/**
* Log a message
- *
+ *
* @param level message level
* @param msg message text
* @param t thrown exception
*/
void log(Level level, String msg, Throwable t);
-
+
}
diff --git a/src/mightypork/utils/logging/writers/SimpleLog.java b/src/mightypork/utils/logging/writers/SimpleLog.java
index cd3b4bc..0c0ad6b 100644
--- a/src/mightypork/utils/logging/writers/SimpleLog.java
+++ b/src/mightypork/utils/logging/writers/SimpleLog.java
@@ -17,75 +17,76 @@ import mightypork.utils.logging.monitors.LogMonitor;
/**
* Basic logger
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class SimpleLog implements LogWriter {
-
+
/**
* Log file formatter.
*/
class LogFormatter extends Formatter {
-
+
@Override
public String format(LogRecord record)
{
return Log.formatMessage(record.getLevel(), record.getMessage(), record.getThrown(), started_ms);
}
}
-
+
/** Log file */
private final File file;
-
+
/** Log name */
private final String name;
-
+
/** Logger instance. */
private Logger logger;
-
+
private boolean enabled = true;
private final HashSet monitors = new HashSet<>();
private final long started_ms;
-
-
- public SimpleLog(String name, File file) {
+
+
+ public SimpleLog(String name, File file)
+ {
this.name = name;
this.file = file;
this.started_ms = System.currentTimeMillis();
}
-
-
+
+
@Override
public void init()
{
logger = Logger.getLogger(getName());
-
+
FileHandler handler = null;
try {
handler = new FileHandler(getFile().getPath());
} catch (final Throwable t) {
throw new RuntimeException("Failed to init log.", t);
}
-
+
handler.setFormatter(new LogFormatter());
logger.addHandler(handler);
logger.setUseParentHandlers(false);
logger.setLevel(Level.ALL);
-
+
printHeader();
}
-
-
+
+
protected void printHeader()
{
final String stamp = (new SimpleDateFormat("yyyy/MM/dd HH:mm:ss")).format(new Date());
log(Level.INFO, "Logger \"" + getName() + "\" initialized.\n" + stamp);
}
-
-
+
+
/**
* Add log monitor
- *
+ *
* @param mon monitor
*/
@Override
@@ -93,11 +94,11 @@ public class SimpleLog implements LogWriter {
{
monitors.add(mon);
}
-
-
+
+
/**
* Remove a monitor
- *
+ *
* @param removed monitor to remove
*/
@Override
@@ -105,61 +106,61 @@ public class SimpleLog implements LogWriter {
{
monitors.remove(removed);
}
-
-
+
+
@Override
public void setLevel(Level level)
{
logger.setLevel(level);
}
-
-
+
+
@Override
public void enable(boolean flag)
{
enabled = flag;
}
-
-
+
+
public File getFile()
{
return file;
}
-
-
+
+
public String getName()
{
return name;
}
-
-
+
+
@Override
public void log(Level level, String msg)
{
if (enabled) {
logger.log(level, msg);
-
+
final String fmt = Log.formatMessage(level, msg, null, started_ms);
-
+
for (final LogMonitor mon : monitors) {
mon.onMessageLogged(level, fmt);
}
}
}
-
-
+
+
@Override
public void log(Level level, String msg, Throwable t)
{
if (enabled) {
logger.log(level, msg, t);
-
+
final String fmt = Log.formatMessage(level, msg, t, started_ms);
-
+
for (final LogMonitor mon : monitors) {
mon.onMessageLogged(level, fmt);
}
}
}
-
+
}
diff --git a/src/mightypork/utils/math/AlignX.java b/src/mightypork/utils/math/AlignX.java
index a52cbc8..baa0c65 100644
--- a/src/mightypork/utils/math/AlignX.java
+++ b/src/mightypork/utils/math/AlignX.java
@@ -3,7 +3,7 @@ package mightypork.utils.math;
/**
* Horizontal align sides
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public enum AlignX
diff --git a/src/mightypork/utils/math/AlignY.java b/src/mightypork/utils/math/AlignY.java
index 24f5faa..3c5aff4 100644
--- a/src/mightypork/utils/math/AlignY.java
+++ b/src/mightypork/utils/math/AlignY.java
@@ -3,7 +3,7 @@ package mightypork.utils.math;
/**
* Vertical align sides
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public enum AlignY
diff --git a/src/mightypork/utils/math/Calc.java b/src/mightypork/utils/math/Calc.java
index e0d4bdd..134886a 100644
--- a/src/mightypork/utils/math/Calc.java
+++ b/src/mightypork/utils/math/Calc.java
@@ -13,22 +13,23 @@ import mightypork.utils.math.constraints.vect.Vect;
/**
* Math utils
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public final class Calc {
-
- private Calc() {
+
+ private Calc()
+ {
// not instantiable
}
-
+
/** Square root of two */
public static final double SQ2 = 1.41421356237;
-
-
+
+
/**
* Get distance from 2D line to 2D point [X,Y]
- *
+ *
* @param lineDirVec line directional vector
* @param linePoint point of line
* @param point point coordinate
@@ -39,56 +40,56 @@ public final class Calc {
// line point L[lx,ly]
final double lx = linePoint.x();
final double ly = linePoint.y();
-
+
// line equation ax+by+c=0
final double a = -lineDirVec.y();
final double b = lineDirVec.x();
final double c = -a * lx - b * ly;
-
+
// checked point P[x,y]
final double x = point.x();
final double y = point.y();
-
+
// distance
return Math.abs(a * x + b * y + c) / Math.sqrt(a * a + b * b);
}
-
+
public static final Random rand = new Random();
-
-
+
+
public static double sphereSurface(double radius)
{
return 4D * Math.PI * square(radius);
}
-
-
+
+
public static double sphereVolume(double radius)
{
return (4D / 3D) * Math.PI * cube(radius);
}
-
-
+
+
public static double sphereRadius(double volume)
{
return Math.cbrt((3D * volume) / (4 * Math.PI));
}
-
-
+
+
public static double circleSurface(double radius)
{
return Math.PI * square(radius);
}
-
-
+
+
public static double circleRadius(double surface)
{
return Math.sqrt(surface / Math.PI);
}
-
-
+
+
/**
* Safe equals that works with nulls
- *
+ *
* @param a
* @param b
* @return are equal
@@ -97,11 +98,11 @@ public final class Calc {
{
return a == null ? b == null : a.equals(b);
}
-
-
+
+
/**
* Clamp integer
- *
+ *
* @param number
* @param min
* @param max
@@ -111,11 +112,11 @@ public final class Calc {
{
return number < min ? min : number > max ? max : number;
}
-
-
+
+
/**
* Clamp double
- *
+ *
* @param number
* @param min
* @param max
@@ -125,17 +126,17 @@ public final class Calc {
{
return number < min ? min : number > max ? max : number;
}
-
-
+
+
public static boolean isInRange(double number, double left, double right)
{
return number >= left && number <= right;
}
-
-
+
+
/**
* Get number from A to B at delta time (A -> B)
- *
+ *
* @param from
* @param to
* @param elapsed progress ratio 0..1
@@ -146,11 +147,11 @@ public final class Calc {
{
return from + (to - from) * easing.get(elapsed);
}
-
-
+
+
/**
* Get angle [degrees] from A to B at delta time (tween A to B)
- *
+ *
* @param from
* @param to
* @param elapsed progress ratio 0..1
@@ -161,11 +162,11 @@ public final class Calc {
{
return Deg.norm(from - Deg.delta(to, from) * easing.get(elapsed));
}
-
-
+
+
/**
* Get angle [radians] from A to B at delta time (tween A to B)
- *
+ *
* @param from
* @param to
* @param elapsed progress ratio 0..1
@@ -176,8 +177,8 @@ public final class Calc {
{
return Rad.norm(from - Rad.delta(to, from) * easing.get(elapsed));
}
-
-
+
+
public static double max(double... numbers)
{
double highest = numbers[0];
@@ -186,8 +187,8 @@ public final class Calc {
}
return highest;
}
-
-
+
+
public static int max(int... numbers)
{
int highest = numbers[0];
@@ -196,8 +197,8 @@ public final class Calc {
}
return highest;
}
-
-
+
+
public static double min(double... numbers)
{
double lowest = numbers[0];
@@ -206,8 +207,8 @@ public final class Calc {
}
return lowest;
}
-
-
+
+
public static int min(int... numbers)
{
int lowest = numbers[0];
@@ -216,11 +217,11 @@ public final class Calc {
}
return lowest;
}
-
-
+
+
/**
* Split comma separated list of integers.
- *
+ *
* @param list String containing the list.
* @param delimiter delimiter character
* @return array of integers or null.
@@ -230,24 +231,24 @@ public final class Calc {
if (list == null) {
return null;
}
-
+
final String[] parts = list.split(Character.toString(delimiter));
-
+
final ArrayList intList = new ArrayList<>();
-
+
for (final String part : parts) {
try {
intList.add(Integer.parseInt(part.trim()));
} catch (final NumberFormatException e) {}
}
-
+
return intList;
}
-
-
+
+
/**
* Pick random element from a given list.
- *
+ *
* @param list list of choices
* @return picked element
*/
@@ -255,11 +256,11 @@ public final class Calc {
{
return pick(rand, list);
}
-
-
+
+
/**
* Pick random element from a given list.
- *
+ *
* @param rand RNG
* @param list list of choices
* @return picked element
@@ -269,11 +270,11 @@ public final class Calc {
if (list.size() == 0) return null;
return list.get(rand.nextInt(list.size()));
}
-
-
+
+
/**
* Take a square
- *
+ *
* @param a value
* @return value squared
*/
@@ -281,11 +282,11 @@ public final class Calc {
{
return a * a;
}
-
-
+
+
/**
* Take a cube
- *
+ *
* @param a value
* @return value cubed
*/
@@ -293,8 +294,8 @@ public final class Calc {
{
return a * a * a;
}
-
-
+
+
/**
* @param d number
* @return fractional part
@@ -303,11 +304,11 @@ public final class Calc {
{
return d - Math.floor(d);
}
-
-
+
+
/**
* Make sure value is within array length.
- *
+ *
* @param index tested index
* @param length array length
* @throws IndexOutOfBoundsException if the index is not in range.
@@ -318,11 +319,11 @@ public final class Calc {
throw new IndexOutOfBoundsException();
}
}
-
-
+
+
/**
* Get distance of two coordinates in 2D plane
- *
+ *
* @param x1 first coordinate X
* @param y1 first coordinate y
* @param x2 second coordinate X
@@ -333,24 +334,24 @@ public final class Calc {
{
return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
}
-
-
+
+
public static int randInt(Random rand, int low, int high)
{
final int range = Math.abs(high - low) + 1;
return low + rand.nextInt(range);
}
-
-
+
+
public static int randInt(int low, int high)
{
return randInt(rand, low, high);
}
-
-
+
+
/**
* Get ordinal version of numbers (1 = 1st, 5 = 5th etc.)
- *
+ *
* @param number number
* @return ordinal, string
*/
@@ -363,11 +364,11 @@ public final class Calc {
}
return number + "th";
}
-
-
+
+
/**
* Format number with thousands separated.
- *
+ *
* @param number number
* @param thousandSep
* @return string
@@ -377,18 +378,18 @@ public final class Calc {
final String num = String.valueOf(number);
final String dot = String.valueOf(thousandSep);
String out = "";
-
+
int cnt = 1;
for (int i = num.length() - 1; i >= 0; i--) {
out = num.charAt(i) + out;
if (cnt % 3 == 0 && i > 0) out = dot + out;
cnt++;
}
-
+
return out;
}
-
-
+
+
public static int countBits(byte b)
{
int c = 0;
diff --git a/src/mightypork/utils/math/Polar.java b/src/mightypork/utils/math/Polar.java
index 8f32e73..b455303 100644
--- a/src/mightypork/utils/math/Polar.java
+++ b/src/mightypork/utils/math/Polar.java
@@ -6,44 +6,46 @@ import mightypork.utils.math.constraints.vect.Vect;
/**
* Polar coordinate
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class Polar {
-
+
/** angle in radians */
private double angle = 0;
-
+
/** distance in units */
private double radius = 0;
-
+
private Vect coord = null;
-
-
+
+
/**
* Create a polar
- *
+ *
* @param angle angle in RAD
* @param distance distance from origin
*/
- public Polar(double angle, double distance) {
+ public Polar(double angle, double distance)
+ {
this(angle, false, distance);
}
-
-
+
+
/**
* Create a polar
- *
+ *
* @param angle angle
* @param deg angle is in DEG
* @param distance radius
*/
- public Polar(double angle, boolean deg, double distance) {
+ public Polar(double angle, boolean deg, double distance)
+ {
this.radius = distance;
this.angle = deg ? Math.toRadians(angle) : angle;
}
-
-
+
+
/**
* @return angle in RAD
*/
@@ -51,8 +53,8 @@ public class Polar {
{
return angle;
}
-
-
+
+
/**
* @return angle in DEG
*/
@@ -60,8 +62,8 @@ public class Polar {
{
return Math.toDegrees(angle);
}
-
-
+
+
/**
* @param angle angle in RAD
*/
@@ -69,8 +71,8 @@ public class Polar {
{
this.angle = angle;
}
-
-
+
+
/**
* @param angle angle in DEG
*/
@@ -78,8 +80,8 @@ public class Polar {
{
this.angle = Math.toRadians(angle);
}
-
-
+
+
/**
* @return radius
*/
@@ -87,8 +89,8 @@ public class Polar {
{
return radius;
}
-
-
+
+
/**
* @param r radius
*/
@@ -96,24 +98,24 @@ public class Polar {
{
this.radius = r;
}
-
-
+
+
/**
* Make polar from coord
- *
+ *
* @param coord coord
* @return polar
*/
public static Polar fromCoord(Vect coord)
{
return Polar.fromCoord(coord.x(), coord.y());
-
+
}
-
-
+
+
/**
* Make polar from coords
- *
+ *
* @param x x coord
* @param y y coord
* @return polar
@@ -122,46 +124,46 @@ public class Polar {
{
final double a = Math.atan2(y, x);
final double r = Math.sqrt(x * x + y * y);
-
+
return new Polar(a, r);
}
-
-
+
+
/**
* Get coord from polar
- *
+ *
* @return coord
*/
public Vect toCoord()
{
// lazy init
if (coord == null) coord = new Vect() {
-
+
@Override
public double x()
{
return radius * Math.cos(angle);
}
-
-
+
+
@Override
public double y()
{
return radius * Math.sin(angle);
}
};
-
+
return coord;
}
-
-
+
+
@Override
public String toString()
{
return "Polar(" + angle + "rad, " + radius + ")";
}
-
-
+
+
@Override
public int hashCode()
{
@@ -174,8 +176,8 @@ public class Polar {
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
-
-
+
+
@Override
public boolean equals(Object obj)
{
diff --git a/src/mightypork/utils/math/Range.java b/src/mightypork/utils/math/Range.java
index 63f9db4..53f0675 100644
--- a/src/mightypork/utils/math/Range.java
+++ b/src/mightypork/utils/math/Range.java
@@ -6,82 +6,85 @@ import java.util.Random;
/**
* Numeric range, able to generate random numbers and give min/max values.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class Range {
-
+
public static Range make(double low, double high)
{
return new Range(low, high);
}
-
+
private double min = 0;
private double max = 1;
-
-
+
+
/**
* Implicit range constructor 0-1
*/
- public Range() {
+ public Range()
+ {
}
-
-
+
+
/**
* Create new range
- *
+ *
* @param min min number
* @param max max number
*/
- public Range(double min, double max) {
+ public Range(double min, double max)
+ {
this.min = min;
this.max = max;
norm();
}
-
-
+
+
/**
* Create new range
- *
+ *
* @param minmax min = max number
*/
- public Range(double minmax) {
+ public Range(double minmax)
+ {
this.min = minmax;
this.max = minmax;
}
-
-
+
+
public static Range fromString(String string)
{
try {
String s = string.trim();
-
+
// drop whitespace
s = s.replaceAll("\\s", "");
-
+
// drop brackets
s = s.replaceAll("[\\(\\[\\{\\)\\]\\}]", "");
-
+
// norm separators
s = s.replaceAll("[:;]", "|").replace("..", "|");
-
+
// norm floating point
s = s.replaceAll("[,]", ".");
-
+
// dash to pipe, if not a minus sign
s = s.replaceAll("([0-9])\\s?[\\-]", "$1|");
-
+
final String[] parts = s.split("[|]");
-
+
if (parts.length >= 1) {
-
+
final double low = Double.parseDouble(parts[0].trim());
-
+
if (parts.length == 2) {
final double high = Double.parseDouble(parts[1].trim());
return Range.make(low, high);
}
-
+
return Range.make(low, low);
}
} catch (final RuntimeException e) {
@@ -89,15 +92,15 @@ public class Range {
}
return null;
}
-
-
+
+
@Override
public String toString()
{
return String.format("(%f : %f)", getMin(), getMax());
}
-
-
+
+
/**
* Make sure min is <= max
*/
@@ -109,33 +112,33 @@ public class Range {
max = t;
}
}
-
-
+
+
/**
* Get random integer from range
- *
+ *
* @return random int
*/
public int randInt()
{
return randInt(Calc.rand);
}
-
-
+
+
/**
* Get random double from this range
- *
+ *
* @return random double
*/
public double randDouble()
{
return randDouble(Calc.rand);
}
-
-
+
+
/**
* Get random integer from range
- *
+ *
* @param rand RNG
* @return random int
*/
@@ -143,11 +146,11 @@ public class Range {
{
return Calc.randInt(rand, (int) Math.round(min), (int) Math.round(min));
}
-
-
+
+
/**
* Get random double from this range
- *
+ *
* @param rand RNG
* @return random double
*/
@@ -155,33 +158,33 @@ public class Range {
{
return min + rand.nextDouble() * (max - min);
}
-
-
+
+
/**
* Get min
- *
+ *
* @return min number
*/
public double getMin()
{
return min;
}
-
-
+
+
/**
* Get max
- *
+ *
* @return max number
*/
public double getMax()
{
return max;
}
-
-
+
+
/**
* Set min
- *
+ *
* @param min min value
*/
public void setMin(double min)
@@ -189,11 +192,11 @@ public class Range {
this.min = min;
norm();
}
-
-
+
+
/**
* Set max
- *
+ *
* @param max max value
*/
public void setMax(double max)
@@ -201,22 +204,22 @@ public class Range {
this.max = max;
norm();
}
-
-
+
+
/**
* Get identical copy
- *
+ *
* @return copy
*/
public Range copy()
{
return new Range(min, max);
}
-
-
+
+
/**
* Set to value of other range
- *
+ *
* @param other copied range
*/
public void setTo(Range other)
@@ -226,11 +229,11 @@ public class Range {
max = other.max;
norm();
}
-
-
+
+
/**
* Set to min-max values
- *
+ *
* @param min min value
* @param max max value
*/
diff --git a/src/mightypork/utils/math/algo/Coord.java b/src/mightypork/utils/math/algo/Coord.java
index 8e7ad2b..df74a2c 100644
--- a/src/mightypork/utils/math/algo/Coord.java
+++ b/src/mightypork/utils/math/algo/Coord.java
@@ -9,63 +9,66 @@ import mightypork.utils.math.constraints.vect.VectConst;
/**
* Very simple integer coordinate
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class Coord {
-
+
public int x;
public int y;
-
-
+
+
@FactoryMethod
public static Coord make(int x, int y)
{
return new Coord(x, y);
}
-
-
+
+
@FactoryMethod
public static Coord make(Coord other)
{
return new Coord(other);
}
-
-
+
+
@FactoryMethod
public static Coord zero()
{
return make(0, 0);
}
-
-
- public Coord() {
+
+
+ public Coord()
+ {
// for ion
}
-
-
- public Coord(int x, int y) {
+
+
+ public Coord(int x, int y)
+ {
super();
this.x = x;
this.y = y;
}
-
-
- public Coord(Coord other) {
+
+
+ public Coord(Coord other)
+ {
this.x = other.x;
this.y = other.y;
}
-
-
+
+
public Coord add(int addX, int addY)
{
return new Coord(x + addX, y + addY);
}
-
-
+
+
/**
* Add other coord in a copy
- *
+ *
* @param added
* @return changed copy
*/
@@ -73,36 +76,36 @@ public class Coord {
{
return add(added.x, added.y);
}
-
-
+
+
public Coord add(Move added)
{
return add(added.x(), added.y());
}
-
-
+
+
public Coord copy()
{
return make(this);
}
-
-
+
+
public void setTo(int x, int y)
{
this.x = x;
this.y = y;
}
-
-
+
+
public void setTo(Coord pos)
{
setTo(pos.x, pos.y);
}
-
-
+
+
/**
* Check if coord is in a range (inclusive)
- *
+ *
* @param x0 range min x
* @param y0 range min y
* @param x1 range max x
@@ -113,27 +116,27 @@ public class Coord {
{
return !(x < x0 || x > x1 || y < y0 || y > y1);
}
-
-
+
+
public double dist(Coord coord)
{
return Calc.dist(x, y, coord.x, coord.y);
}
-
-
+
+
public VectConst toVect()
{
return Vect.make(x, y);
}
-
-
+
+
@Override
public String toString()
{
return "Coord(" + x + "," + y + ")";
}
-
-
+
+
@Override
public int hashCode()
{
@@ -143,8 +146,8 @@ public class Coord {
result = prime * result + y;
return result;
}
-
-
+
+
@Override
public boolean equals(Object obj)
{
@@ -156,8 +159,8 @@ public class Coord {
if (y != other.y) return false;
return true;
}
-
-
+
+
public static Coord fromVect(Vect vect)
{
return make((int) Math.floor(vect.x()), (int) Math.floor(vect.y()));
diff --git a/src/mightypork/utils/math/algo/Move.java b/src/mightypork/utils/math/algo/Move.java
index c9f7fbe..f97d7cf 100644
--- a/src/mightypork/utils/math/algo/Move.java
+++ b/src/mightypork/utils/math/algo/Move.java
@@ -4,60 +4,61 @@ package mightypork.utils.math.algo;
/**
* Path step.
* Must be binary in order to be saveable in lists.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class Move {
-
+
public static final Move NORTH = new Move(0, -1);
public static final Move SOUTH = new Move(0, 1);
public static final Move EAST = new Move(1, 0);
public static final Move WEST = new Move(-1, 0);
public static final Move NONE = new Move(0, 0);
-
-
+
+
public static Move make(int x, int y)
{
x = x < 0 ? -1 : x > 0 ? 1 : 0;
y = y < 0 ? -1 : y > 0 ? 1 : 0;
-
+
if (y == -1 && x == 0) return NORTH;
if (y == 1 && x == 0) return SOUTH;
if (x == -1 && y == 0) return WEST;
if (x == 1 && y == 0) return EAST;
if (x == 0 && y == 0) return NONE;
-
+
return new Move(x, y);
}
-
+
private final byte x;
private final byte y;
-
-
- public Move(int x, int y) {
+
+
+ public Move(int x, int y)
+ {
this.x = (byte) (x < 0 ? -1 : x > 0 ? 1 : 0);
this.y = (byte) (y < 0 ? -1 : y > 0 ? 1 : 0);
}
-
-
+
+
public int x()
{
return x;
}
-
-
+
+
public int y()
{
return y;
}
-
-
+
+
public Coord toCoord()
{
return Coord.make(x, y);
}
-
-
+
+
@Override
public String toString()
{
diff --git a/src/mightypork/utils/math/algo/Moves.java b/src/mightypork/utils/math/algo/Moves.java
index 7c466ad..8877a23 100644
--- a/src/mightypork/utils/math/algo/Moves.java
+++ b/src/mightypork/utils/math/algo/Moves.java
@@ -11,11 +11,11 @@ import mightypork.utils.math.Calc;
/**
* Move lists, bit masks and other utilities
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class Moves {
-
+
public static final byte BIT_NW = (byte) 0b10000000;
public static final byte BIT_N = (byte) 0b01000000;
public static final byte BIT_NE = (byte) 0b00100000;
@@ -24,15 +24,15 @@ public class Moves {
public static final byte BIT_S = (byte) 0b00000100;
public static final byte BIT_SW = (byte) 0b00000010;
public static final byte BIT_W = (byte) 0b00000001;
-
+
public static final byte BITS_CARDINAL = BIT_N | BIT_S | BIT_E | BIT_W;
public static final byte BITS_DIAGONAL = BIT_NE | BIT_NW | BIT_SE | BIT_SW;
-
+
public static final byte BITS_NW_CORNER = BIT_W | BIT_NW | BIT_N;
public static final byte BITS_NE_CORNER = BIT_E | BIT_NE | BIT_N;
public static final byte BITS_SW_CORNER = BIT_W | BIT_SW | BIT_S;
public static final byte BITS_SE_CORNER = BIT_E | BIT_SE | BIT_S;
-
+
public static final Move NW = Move.make(-1, -1);
public static final Move N = Move.make(0, -1);
public static final Move NE = Move.make(1, -1);
@@ -41,32 +41,32 @@ public class Moves {
public static final Move S = Move.make(0, 1);
public static final Move SW = Move.make(-1, 1);
public static final Move W = Move.make(-1, 0);
-
- //@formatter:off
+
+ //@formatter:off
/** All sides, in the order of bits. */
public final static List ALL_SIDES = Collections.unmodifiableList(Arrays.asList(
- NW,
- N,
- NE,
- E,
- SE,
- S,
- SW,
- W
- ));
-
+ NW,
+ N,
+ NE,
+ E,
+ SE,
+ S,
+ SW,
+ W
+ ));
+
public final static List CARDINAL_SIDES = Collections.unmodifiableList(Arrays.asList(
- N,
- E,
- S,
- W
- ));
-
+ N,
+ E,
+ S,
+ W
+ ));
+
//@formatter:on
-
+
/**
* Get element from all sides
- *
+ *
* @param i side index
* @return the side coord
*/
@@ -74,20 +74,20 @@ public class Moves {
{
return ALL_SIDES.get(i);
}
-
-
+
+
public static byte getBit(int i)
{
return (byte) (1 << (7 - i));
}
-
-
+
+
public static Move randomCardinal()
{
return Calc.pick(CARDINAL_SIDES);
}
-
-
+
+
public static Move randomCardinal(Random rand)
{
return Calc.pick(rand, CARDINAL_SIDES);
diff --git a/src/mightypork/utils/math/algo/floodfill/FloodFill.java b/src/mightypork/utils/math/algo/floodfill/FloodFill.java
index a9a8198..2e12bc8 100644
--- a/src/mightypork/utils/math/algo/floodfill/FloodFill.java
+++ b/src/mightypork/utils/math/algo/floodfill/FloodFill.java
@@ -11,33 +11,33 @@ import mightypork.utils.math.algo.Move;
public abstract class FloodFill {
-
+
public abstract boolean canEnter(Coord pos);
-
-
+
+
public abstract boolean canSpreadFrom(Coord pos);
-
-
+
+
public abstract List getSpreadSides();
-
-
+
+
/**
* Get the max distance filled form start point. Use -1 for unlimited range.
- *
+ *
* @return max distance
*/
public abstract double getMaxDistance();
-
-
+
+
/**
* @return true if start should be spread no matter what
*/
public abstract boolean forceSpreadStart();
-
-
+
+
/**
* Fill an area
- *
+ *
* @param start start point
* @param foundNodes collection to put filled coords in
* @return true if fill was successful; false if max range was reached.
@@ -45,32 +45,32 @@ public abstract class FloodFill {
public final boolean fill(Coord start, Collection foundNodes)
{
final Queue activeNodes = new LinkedList<>();
-
+
final double maxDist = getMaxDistance();
-
+
activeNodes.add(start);
-
+
boolean forceSpreadNext = forceSpreadStart();
-
+
boolean limitReached = false;
-
+
while (!activeNodes.isEmpty()) {
final Coord current = activeNodes.poll();
foundNodes.add(current);
-
+
if (!canSpreadFrom(current) && !forceSpreadNext) continue;
-
+
forceSpreadNext = false;
-
+
for (final Move spr : getSpreadSides()) {
final Coord next = current.add(spr);
if (activeNodes.contains(next) || foundNodes.contains(next)) continue;
-
+
if (next.dist(start) > maxDist) {
limitReached = true;
continue;
}
-
+
if (canEnter(next)) {
activeNodes.add(next);
} else {
@@ -78,7 +78,7 @@ public abstract class FloodFill {
}
}
}
-
+
return !limitReached;
}
}
diff --git a/src/mightypork/utils/math/algo/pathfinding/Heuristic.java b/src/mightypork/utils/math/algo/pathfinding/Heuristic.java
index ed1d913..a035ccb 100644
--- a/src/mightypork/utils/math/algo/pathfinding/Heuristic.java
+++ b/src/mightypork/utils/math/algo/pathfinding/Heuristic.java
@@ -5,10 +5,10 @@ import mightypork.utils.math.algo.Coord;
public abstract class Heuristic {
-
+
/**
* Get tile cost (estimate of how many tiles remain to the target)
- *
+ *
* @param pos current pos
* @param target target pos
* @return estimated number of tiles
diff --git a/src/mightypork/utils/math/algo/pathfinding/PathFinder.java b/src/mightypork/utils/math/algo/pathfinding/PathFinder.java
index 46ea1a5..3a77647 100644
--- a/src/mightypork/utils/math/algo/pathfinding/PathFinder.java
+++ b/src/mightypork/utils/math/algo/pathfinding/PathFinder.java
@@ -15,34 +15,34 @@ import mightypork.utils.math.algo.pathfinding.heuristics.ManhattanHeuristic;
/**
* A* pathfinder
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public abstract class PathFinder {
-
+
private static final FComparator F_COMPARATOR = new FComparator();
-
+
public static final Heuristic CORNER_HEURISTIC = new ManhattanHeuristic();
public static final Heuristic DIAGONAL_HEURISTIC = new DiagonalHeuristic();
-
+
private boolean ignoreStart;
private boolean ignoreEnd;
-
-
+
+
public List findPathRelative(Coord start, Coord end)
{
return findPathRelative(start, end, ignoreStart, ignoreEnd);
}
-
-
+
+
public List findPathRelative(Coord start, Coord end, boolean ignoreStart, boolean ignoreEnd)
{
final List path = findPath(start, end, ignoreStart, ignoreEnd);
-
+
if (path == null) return null;
-
+
final List out = new ArrayList<>();
-
+
final Coord current = start.copy();
for (final Coord c : path) {
if (c.equals(current)) continue;
@@ -50,24 +50,24 @@ public abstract class PathFinder {
current.x = c.x;
current.y = c.y;
}
-
+
return out;
}
-
-
+
+
public List findPath(Coord start, Coord end)
{
return findPath(start, end, ignoreStart, ignoreEnd);
}
-
-
+
+
public List findPath(Coord start, Coord end, boolean ignoreStart, boolean ignoreEnd)
{
final LinkedList open = new LinkedList<>();
final LinkedList closed = new LinkedList<>();
-
+
final Heuristic heuristic = getHeuristic();
-
+
// add first node
{
final Node n = new Node(start);
@@ -75,37 +75,37 @@ public abstract class PathFinder {
n.g_cost = 0;
open.add(n);
}
-
+
Node current = null;
-
+
while (true) {
current = open.poll();
-
+
if (current == null) {
break;
}
-
+
closed.add(current);
-
+
if (current.pos.equals(end)) {
break;
}
-
+
for (final Move go : getWalkSides()) {
-
+
final Coord c = current.pos.add(go);
if (!isAccessible(c) && !(c.equals(end) && ignoreEnd) && !(c.equals(start) && ignoreStart)) continue;
final Node a = new Node(c);
a.g_cost = current.g_cost + getCost(c, a.pos);
a.h_cost = (int) (heuristic.getCost(a.pos, end) * getMinCost());
a.parent = current;
-
+
if (!closed.contains(a)) {
-
+
if (open.contains(a)) {
-
+
boolean needSort = false;
-
+
// find where it is
for (final Node n : open) {
if (n.pos.equals(a.pos)) { // found it
@@ -117,51 +117,52 @@ public abstract class PathFinder {
break;
}
}
-
+
if (needSort) Collections.sort(open, F_COMPARATOR);
-
+
} else {
open.add(a);
}
}
}
-
+
}
-
+
if (current == null) {
return null; // no path found
}
-
+
final LinkedList path = new LinkedList<>();
-
+
// extract path elements
while (current != null) {
path.addFirst(current.pos);
current = current.parent;
}
-
+
return path;
}
-
+
private static class Node {
-
+
Coord pos;
int g_cost; // to get there
int h_cost; // to target
Node parent;
-
-
- public Node(Coord pos) {
+
+
+ public Node(Coord pos)
+ {
this.pos = pos;
}
-
-
+
+
int fCost()
{
return g_cost + h_cost;
}
-
-
+
+
@Override
public int hashCode()
{
@@ -170,8 +171,8 @@ public abstract class PathFinder {
result = prime * result + ((pos == null) ? 0 : pos.hashCode());
return result;
}
-
-
+
+
@Override
public boolean equals(Object obj)
{
@@ -184,63 +185,63 @@ public abstract class PathFinder {
} else if (!pos.equals(other.pos)) return false;
return true;
}
-
-
+
+
@Override
public String toString()
{
return "N " + pos + ", G =" + g_cost + ", H = " + h_cost;
}
}
-
+
private static class FComparator implements Comparator {
-
+
@Override
public int compare(Node n1, Node n2)
{
return n1.fCost() - n2.fCost();
}
}
-
-
+
+
public void setIgnoreEnd(boolean ignoreEnd)
{
this.ignoreEnd = ignoreEnd;
}
-
-
+
+
public void setIgnoreStart(boolean ignoreStart)
{
this.ignoreStart = ignoreStart;
}
-
-
+
+
/**
* @return used heuristic
*/
protected abstract Heuristic getHeuristic();
-
-
+
+
protected abstract List getWalkSides();
-
-
+
+
/**
* @param pos tile pos
* @return true if the tile is walkable
*/
public abstract boolean isAccessible(Coord pos);
-
-
+
+
/**
* Cost of walking onto a tile. It's useful to use ie. 10 for basic step.
- *
+ *
* @param from last tile
* @param to current tile
* @return cost
*/
protected abstract int getCost(Coord from, Coord to);
-
-
+
+
/**
* @return lowest cost. Used to multiply heuristics.
*/
diff --git a/src/mightypork/utils/math/algo/pathfinding/PathFinderProxy.java b/src/mightypork/utils/math/algo/pathfinding/PathFinderProxy.java
index bf21ab3..e4984f7 100644
--- a/src/mightypork/utils/math/algo/pathfinding/PathFinderProxy.java
+++ b/src/mightypork/utils/math/algo/pathfinding/PathFinderProxy.java
@@ -10,51 +10,52 @@ import mightypork.utils.math.algo.Move;
/**
* Pathfinder proxy. Can be used to override individual methods but keep the
* rest as is.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class PathFinderProxy extends PathFinder {
-
+
private final PathFinder source;
-
-
- public PathFinderProxy(PathFinder other) {
+
+
+ public PathFinderProxy(PathFinder other)
+ {
this.source = other;
}
-
-
+
+
@Override
public boolean isAccessible(Coord pos)
{
return source.isAccessible(pos);
}
-
-
+
+
@Override
public int getCost(Coord from, Coord to)
{
return source.getCost(from, to);
}
-
-
+
+
@Override
public int getMinCost()
{
return source.getMinCost();
}
-
-
+
+
@Override
protected Heuristic getHeuristic()
{
return source.getHeuristic();
}
-
-
+
+
@Override
protected List getWalkSides()
{
return source.getWalkSides();
}
-
+
}
diff --git a/src/mightypork/utils/math/algo/pathfinding/heuristics/DiagonalHeuristic.java b/src/mightypork/utils/math/algo/pathfinding/heuristics/DiagonalHeuristic.java
index 4820eac..1bdc684 100644
--- a/src/mightypork/utils/math/algo/pathfinding/heuristics/DiagonalHeuristic.java
+++ b/src/mightypork/utils/math/algo/pathfinding/heuristics/DiagonalHeuristic.java
@@ -6,7 +6,7 @@ import mightypork.utils.math.algo.pathfinding.Heuristic;
public class DiagonalHeuristic extends Heuristic {
-
+
@Override
public double getCost(Coord pos, Coord target)
{
diff --git a/src/mightypork/utils/math/algo/pathfinding/heuristics/ManhattanHeuristic.java b/src/mightypork/utils/math/algo/pathfinding/heuristics/ManhattanHeuristic.java
index 9725794..d869054 100644
--- a/src/mightypork/utils/math/algo/pathfinding/heuristics/ManhattanHeuristic.java
+++ b/src/mightypork/utils/math/algo/pathfinding/heuristics/ManhattanHeuristic.java
@@ -6,7 +6,7 @@ import mightypork.utils.math.algo.pathfinding.Heuristic;
public class ManhattanHeuristic extends Heuristic {
-
+
@Override
public double getCost(Coord pos, Coord target)
{
diff --git a/src/mightypork/utils/math/angles/Angles.java b/src/mightypork/utils/math/angles/Angles.java
index 20c1cec..263aacf 100644
--- a/src/mightypork/utils/math/angles/Angles.java
+++ b/src/mightypork/utils/math/angles/Angles.java
@@ -3,14 +3,14 @@ package mightypork.utils.math.angles;
/**
* Common angles functionality
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
class Angles {
-
+
/**
* Delta of two angles (positive or negative - positive is CCW)
- *
+ *
* @param alpha first angle
* @param beta second angle
* @param fullAngle value of full angle
@@ -22,14 +22,14 @@ class Angles {
alpha = norm(alpha + fullAngle / 2D, fullAngle);
beta = norm(beta + fullAngle / 2D, fullAngle);
}
-
+
return beta - alpha;
}
-
-
+
+
/**
* Difference of two angles (same as delta, but always positive)
- *
+ *
* @param alpha first angle
* @param beta second angle
* @param fullAngle value of full angle
@@ -39,11 +39,11 @@ class Angles {
{
return Math.abs(delta(alpha, beta, fullAngle));
}
-
-
+
+
/**
* Normalize angle to 0-full range
- *
+ *
* @param angle angle
* @param fullAngle full angle
* @return angle normalized
diff --git a/src/mightypork/utils/math/angles/Deg.java b/src/mightypork/utils/math/angles/Deg.java
index f9e0f4a..c39b96e 100644
--- a/src/mightypork/utils/math/angles/Deg.java
+++ b/src/mightypork/utils/math/angles/Deg.java
@@ -3,11 +3,11 @@ package mightypork.utils.math.angles;
/**
* Angle calculations for degrees.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class Deg {
-
+
/** 180° in degrees */
public static final double a180 = 180;
/** 270° in degrees */
@@ -18,11 +18,11 @@ public class Deg {
public static final double a45 = 45;
/** 90° in degrees */
public static final double a90 = 90;
-
-
+
+
/**
* Subtract two angles alpha - beta
- *
+ *
* @param alpha first angle
* @param beta second angle
* @return (alpha - beta) in degrees
@@ -31,11 +31,11 @@ public class Deg {
{
return Angles.delta(alpha, beta, a360);
}
-
-
+
+
/**
* Difference of two angles (absolute value of delta)
- *
+ *
* @param alpha first angle
* @param beta second angle
* @return difference in radians
@@ -44,11 +44,11 @@ public class Deg {
{
return Angles.diff(alpha, beta, a360);
}
-
-
+
+
/**
* Cosinus in degrees
- *
+ *
* @param deg angle in degrees
* @return cosinus
*/
@@ -56,11 +56,11 @@ public class Deg {
{
return Math.cos(toRad(deg));
}
-
-
+
+
/**
* Sinus in degrees
- *
+ *
* @param deg angle in degrees
* @return sinus
*/
@@ -68,11 +68,11 @@ public class Deg {
{
return Math.sin(toRad(deg));
}
-
-
+
+
/**
* Tangents in degrees
- *
+ *
* @param deg angle in degrees
* @return tangents
*/
@@ -80,11 +80,11 @@ public class Deg {
{
return Math.tan(toRad(deg));
}
-
-
+
+
/**
* Angle normalized to 0-360 range
- *
+ *
* @param angle angle to normalize
* @return normalized angle
*/
@@ -92,11 +92,11 @@ public class Deg {
{
return Angles.norm(angle, a360);
}
-
-
+
+
/**
* Convert to radians
- *
+ *
* @param deg degrees
* @return radians
*/
@@ -104,11 +104,11 @@ public class Deg {
{
return Math.toRadians(deg);
}
-
-
+
+
/**
* Round angle to 0,45,90,135...
- *
+ *
* @param deg angle in deg. to round
* @param increment rounding increment (45 - round to 0,45,90...)
* @return rounded
@@ -123,11 +123,11 @@ public class Deg {
if (a == 360) a = 0;
return (int) Math.round(a);
}
-
-
+
+
/**
* Round angle to 0,15,30,45,60,75,90...
- *
+ *
* @param deg angle in deg to round
* @return rounded
*/
@@ -135,11 +135,11 @@ public class Deg {
{
return roundToIncrement(deg, 15);
}
-
-
+
+
/**
* Round angle to 0,45,90,135...
- *
+ *
* @param deg angle in deg. to round
* @return rounded
*/
@@ -147,11 +147,11 @@ public class Deg {
{
return roundToIncrement(deg, 45);
}
-
-
+
+
/**
* Round angle to 0,90,180,270
- *
+ *
* @param deg angle in deg. to round
* @return rounded
*/
diff --git a/src/mightypork/utils/math/angles/Rad.java b/src/mightypork/utils/math/angles/Rad.java
index ffe088f..3e45106 100644
--- a/src/mightypork/utils/math/angles/Rad.java
+++ b/src/mightypork/utils/math/angles/Rad.java
@@ -3,11 +3,11 @@ package mightypork.utils.math.angles;
/**
* Angle calculations for radians.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class Rad {
-
+
/** 180° in radians */
public static final double a180 = Math.PI;
/** 270° in radians */
@@ -18,11 +18,11 @@ public class Rad {
public static final double a45 = Math.PI / 4D;
/** 90° in radians */
public static final double a90 = Math.PI / 2D;
-
-
+
+
/**
* Subtract two angles alpha - beta
- *
+ *
* @param alpha first angle
* @param beta second angle
* @return (alpha - beta) in radians
@@ -31,11 +31,11 @@ public class Rad {
{
return Angles.delta(alpha, beta, a360);
}
-
-
+
+
/**
* Difference of two angles (absolute value of delta)
- *
+ *
* @param alpha first angle
* @param beta second angle
* @return difference in radians
@@ -44,11 +44,11 @@ public class Rad {
{
return Angles.delta(alpha, beta, a360);
}
-
-
+
+
/**
* Cos
- *
+ *
* @param rad angle in rads
* @return cos
*/
@@ -56,11 +56,11 @@ public class Rad {
{
return Math.cos(rad);
}
-
-
+
+
/**
* Sin
- *
+ *
* @param rad angle in rads
* @return sin
*/
@@ -68,11 +68,11 @@ public class Rad {
{
return Math.sin(rad);
}
-
-
+
+
/**
* Tan
- *
+ *
* @param rad angle in rads
* @return tan
*/
@@ -80,11 +80,11 @@ public class Rad {
{
return Math.tan(rad);
}
-
-
+
+
/**
* Angle normalized to 0-2*PI range
- *
+ *
* @param angle angle to normalize
* @return normalized angle
*/
@@ -92,11 +92,11 @@ public class Rad {
{
return Angles.norm(angle, a360);
}
-
-
+
+
/**
* Convert to degrees
- *
+ *
* @param rad radians
* @return degrees
*/
diff --git a/src/mightypork/utils/math/animation/Animator.java b/src/mightypork/utils/math/animation/Animator.java
index 2486e21..e5cc6c9 100644
--- a/src/mightypork/utils/math/animation/Animator.java
+++ b/src/mightypork/utils/math/animation/Animator.java
@@ -10,124 +10,128 @@ import mightypork.utils.math.constraints.num.NumBound;
public abstract class Animator implements NumBound, Updateable, Pauseable {
-
+
private final NumAnimated numAnim;
private final Num animatorValue;
private final double highValue;
private final double lowValue;
-
-
- public Animator(double period) {
+
+
+ public Animator(double period)
+ {
this(0, 1, period, Easing.LINEAR);
}
-
-
- public Animator(double start, double end, double period) {
+
+
+ public Animator(double start, double end, double period)
+ {
this(start, end, period, Easing.LINEAR);
}
-
-
- public Animator(double period, Easing easing) {
+
+
+ public Animator(double period, Easing easing)
+ {
this(0, 1, period, easing);
}
-
-
- public Animator(double start, double end, double period, Easing easing) {
+
+
+ public Animator(double start, double end, double period, Easing easing)
+ {
numAnim = new NumAnimated(0, easing);
numAnim.setDefaultDuration(period);
-
+
this.lowValue = start;
this.highValue = end;
-
+
this.animatorValue = numAnim.mul(end - start).add(start);
}
-
-
+
+
@Override
public void pause()
{
numAnim.pause();
}
-
-
+
+
public void start()
{
resume();
}
-
-
+
+
@Override
public void resume()
{
numAnim.resume();
}
-
-
+
+
@Override
public boolean isPaused()
{
return numAnim.isPaused();
}
-
-
+
+
public void reset()
{
numAnim.reset();
}
-
-
+
+
public void restart()
{
reset();
resume();
}
-
-
+
+
public void setDuration(double secs)
{
numAnim.setDefaultDuration(secs);
}
-
-
+
+
public double getDuration()
{
return numAnim.getDefaultDuration();
}
-
-
+
+
@Override
public Num getNum()
{
return animatorValue;
}
-
-
+
+
public double getValue()
{
return animatorValue.value();
}
-
-
+
+
@Override
public void update(double delta)
{
numAnim.update(delta);
if (numAnim.isFinished()) nextCycle(numAnim);
}
-
-
+
+
@Stub
protected abstract void nextCycle(NumAnimated anim);
-
-
+
+
public void setProgress(double value)
{
final double target = numAnim.getEnd();
numAnim.setTo(Calc.clamp(value, lowValue, highValue));
numAnim.animate((target < value ? highValue : lowValue), target, numAnim.getDefaultDuration());
}
-
-
+
+
public double getProgress()
{
return numAnim.value();
diff --git a/src/mightypork/utils/math/animation/AnimatorBounce.java b/src/mightypork/utils/math/animation/AnimatorBounce.java
index 5610bc6..4c79808 100644
--- a/src/mightypork/utils/math/animation/AnimatorBounce.java
+++ b/src/mightypork/utils/math/animation/AnimatorBounce.java
@@ -3,34 +3,38 @@ package mightypork.utils.math.animation;
/**
* Animator that upon reaching max, animates back down and then up again
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class AnimatorBounce extends Animator {
-
+
private boolean wasUp = false;
-
-
- public AnimatorBounce(double start, double end, double period, Easing easing) {
+
+
+ public AnimatorBounce(double start, double end, double period, Easing easing)
+ {
super(start, end, period, easing);
}
-
-
- public AnimatorBounce(double start, double end, double period) {
+
+
+ public AnimatorBounce(double start, double end, double period)
+ {
super(start, end, period);
}
-
-
- public AnimatorBounce(double period, Easing easing) {
+
+
+ public AnimatorBounce(double period, Easing easing)
+ {
super(period, easing);
}
-
-
- public AnimatorBounce(double period) {
+
+
+ public AnimatorBounce(double period)
+ {
super(period);
}
-
-
+
+
@Override
protected void nextCycle(NumAnimated anim)
{
@@ -39,8 +43,8 @@ public class AnimatorBounce extends Animator {
} else {
anim.fadeIn();
}
-
+
wasUp = !wasUp;
}
-
+
}
diff --git a/src/mightypork/utils/math/animation/AnimatorRewind.java b/src/mightypork/utils/math/animation/AnimatorRewind.java
index 161d82c..b976c5e 100644
--- a/src/mightypork/utils/math/animation/AnimatorRewind.java
+++ b/src/mightypork/utils/math/animation/AnimatorRewind.java
@@ -4,36 +4,40 @@ package mightypork.utils.math.animation;
/**
* Animator that upon reaching top, jumps straight to zero and continues another
* cycle.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class AnimatorRewind extends Animator {
-
- public AnimatorRewind(double start, double end, double period, Easing easing) {
+
+ public AnimatorRewind(double start, double end, double period, Easing easing)
+ {
super(start, end, period, easing);
}
-
-
- public AnimatorRewind(double start, double end, double period) {
+
+
+ public AnimatorRewind(double start, double end, double period)
+ {
super(start, end, period);
}
-
-
- public AnimatorRewind(double period, Easing easing) {
+
+
+ public AnimatorRewind(double period, Easing easing)
+ {
super(period, easing);
}
-
-
- public AnimatorRewind(double period) {
+
+
+ public AnimatorRewind(double period)
+ {
super(period);
}
-
-
+
+
@Override
protected void nextCycle(NumAnimated anim)
{
anim.reset();
anim.fadeIn();
}
-
+
}
diff --git a/src/mightypork/utils/math/animation/Easing.java b/src/mightypork/utils/math/animation/Easing.java
index 778c7b9..31bc069 100644
--- a/src/mightypork/utils/math/animation/Easing.java
+++ b/src/mightypork/utils/math/animation/Easing.java
@@ -3,23 +3,23 @@ package mightypork.utils.math.animation;
/**
* EasingFunction function.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public abstract class Easing {
-
+
/**
* Get value at time t.
- *
+ *
* @param t time parameter (t = 1..1)
* @return value at given t (0..1, can exceed if needed)
*/
public abstract double get(double t);
-
-
+
+
/**
* Reverse an easing (factory method)
- *
+ *
* @param original original easing
* @return reversed easing
*/
@@ -27,11 +27,11 @@ public abstract class Easing {
{
return new Reverse(original);
}
-
-
+
+
/**
* Combine two easings (factory method)
- *
+ *
* @param in initial easing
* @param out terminal easing
* @return product
@@ -40,12 +40,12 @@ public abstract class Easing {
{
return new Composite(in, out);
}
-
-
+
+
/**
* Create "bilinear" easing - compose of straight and reverse. (factory
* method)
- *
+ *
* @param in initial easing
* @return product
*/
@@ -53,55 +53,57 @@ public abstract class Easing {
{
return combine(in, reverse(in));
}
-
+
/**
* Reverse EasingFunction
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
private static class Reverse extends Easing {
-
+
private final Easing ea;
-
-
+
+
/**
* @param in Easing to reverse
*/
- public Reverse(Easing in) {
+ public Reverse(Easing in)
+ {
this.ea = in;
}
-
-
+
+
@Override
public double get(double t)
{
return 1 - ea.get(1 - t);
}
}
-
+
/**
* Composite EasingFunction (0-0.5 EasingFunction A, 0.5-1 EasingFunction B)
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
private static class Composite extends Easing {
-
+
private final Easing in;
private final Easing out;
-
-
+
+
/**
* Create a composite EasingFunction
- *
+ *
* @param in initial EasingFunction
* @param out terminal EasingFunction
*/
- public Composite(Easing in, Easing out) {
+ public Composite(Easing in, Easing out)
+ {
this.in = in;
this.out = out;
}
-
-
+
+
@Override
public double get(double t)
{
@@ -109,172 +111,172 @@ public abstract class Easing {
return 0.5 + out.get(2 * t - 1) * 0.5;
}
}
-
+
/** No easing; At t=0.5 goes high. */
public static final Easing NONE = new Easing() {
-
+
@Override
public double get(double t)
{
return (t < 0.5 ? 0 : 1);
}
};
-
+
/** Linear (y=t) easing */
public static final Easing LINEAR = new Easing() {
-
+
@Override
public double get(double t)
{
return t;
}
};
-
+
/** Quadratic (y=t^2) easing in */
public static final Easing QUADRATIC_IN = new Easing() {
-
+
@Override
public double get(double t)
{
return t * t;
}
};
-
+
/** Quadratic (y=t^2) easing out */
public static final Easing QUADRATIC_OUT = reverse(QUADRATIC_IN);
-
+
/** Quadratic (y=t^2) easing both */
public static final Easing QUADRATIC_BOTH = inOut(QUADRATIC_IN);
-
+
/** Cubic (y=t^3) easing in */
public static final Easing CUBIC_IN = new Easing() {
-
+
@Override
public double get(double t)
{
return t * t * t;
}
};
-
+
/** Cubic (y=t^3) easing out */
public static final Easing CUBIC_OUT = reverse(CUBIC_IN);
-
+
/** Cubic (y=t^3) easing both */
public static final Easing CUBIC_BOTH = inOut(CUBIC_IN);
-
+
/** Quartic (y=t^4) easing in */
public static final Easing QUARTIC_IN = new Easing() {
-
+
@Override
public double get(double t)
{
return t * t * t * t;
}
};
-
+
/** Quartic (y=t^4) easing out */
public static final Easing QUARTIC_OUT = reverse(QUADRATIC_IN);
-
+
/** Quartic (y=t^4) easing both */
public static final Easing QUARTIC_BOTH = inOut(QUADRATIC_IN);
-
+
/** Quintic (y=t^5) easing in */
public static final Easing QUINTIC_IN = new Easing() {
-
+
@Override
public double get(double t)
{
return t * t * t * t * t;
}
};
-
+
/** Quintic (y=t^5) easing out */
public static final Easing QUINTIC_OUT = reverse(QUINTIC_IN);
-
+
/** Quintic (y=t^5) easing both */
public static final Easing QUINTIC_BOTH = inOut(QUINTIC_IN);
-
+
/** Sine easing in */
public static final Easing SINE_IN = new Easing() {
-
+
@Override
public double get(double t)
{
return 1 - Math.cos(t * (Math.PI / 2));
}
};
-
+
/** Sine easing out */
public static final Easing SINE_OUT = reverse(SINE_IN);
-
+
/** Sine easing both */
public static final Easing SINE_BOTH = inOut(SINE_IN);
-
+
/** Exponential easing in */
public static final Easing EXPO_IN = new Easing() {
-
+
@Override
public double get(double t)
{
return Math.pow(2, 10 * (t - 1));
}
};
-
+
/** Exponential easing out */
public static final Easing EXPO_OUT = reverse(EXPO_IN);
-
+
/** Exponential easing both */
public static final Easing EXPO_BOTH = inOut(EXPO_IN);
-
+
/** Circular easing in */
public static final Easing CIRC_IN = new Easing() {
-
+
@Override
public double get(double t)
{
return 1 - Math.sqrt(1 - t * t);
}
};
-
+
/** Circular easing out */
public static final Easing CIRC_OUT = reverse(CIRC_IN);
-
+
/** Circular easing both */
public static final Easing CIRC_BOTH = inOut(CIRC_IN);
-
+
/** Bounce easing in */
public static final Easing BOUNCE_OUT = new Easing() {
-
+
@Override
public double get(double t)
{
if (t < (1 / 2.75f)) {
return (7.5625f * t * t);
-
+
} else if (t < (2 / 2.75f)) {
t -= (1.5f / 2.75f);
return (7.5625f * t * t + 0.75f);
-
+
} else if (t < (2.5 / 2.75)) {
t -= (2.25f / 2.75f);
return (7.5625f * t * t + 0.9375f);
-
+
} else {
t -= (2.625f / 2.75f);
return (7.5625f * t * t + 0.984375f);
}
}
};
-
+
/** Bounce easing out */
public static final Easing BOUNCE_IN = reverse(BOUNCE_OUT);
-
+
/** Bounce easing both */
public static final Easing BOUNCE_BOTH = inOut(BOUNCE_IN);
-
+
/** Back easing in */
public static final Easing BACK_IN = new Easing() {
-
+
@Override
public double get(double t)
{
@@ -282,31 +284,31 @@ public abstract class Easing {
return t * t * ((s + 1) * t - s);
}
};
-
+
/** Back easing out */
public static final Easing BACK_OUT = reverse(BACK_IN);
-
+
/** Back easing both */
public static final Easing BACK_BOTH = inOut(BACK_IN);
-
+
/** Elastic easing in */
public static final Easing ELASTIC_IN = new Easing() {
-
+
@Override
public double get(double t)
{
if (t == 0) return 0;
if (t == 1) return 1;
-
+
final double p = .3f;
final double s = p / 4;
return -(Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p));
}
};
-
+
/** Elastic easing out */
public static final Easing ELASTIC_OUT = reverse(ELASTIC_IN);
-
+
/** Elastic easing both */
public static final Easing ELASTIC_BOTH = inOut(ELASTIC_IN);
}
diff --git a/src/mightypork/utils/math/animation/NumAnimated.java b/src/mightypork/utils/math/animation/NumAnimated.java
index f7d295c..4f2517c 100644
--- a/src/mightypork/utils/math/animation/NumAnimated.java
+++ b/src/mightypork/utils/math/animation/NumAnimated.java
@@ -11,109 +11,115 @@ import mightypork.utils.math.constraints.num.var.NumMutable;
* Double which supports delta timing.
* When both in and out easings are set differently, then they'll be used for
* fade-in and fade-out respectively. Otherwise both use the same.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class NumAnimated extends NumMutable implements Updateable, Pauseable {
-
+
/** target double */
protected double to = 0;
-
+
/** last tick double */
protected double from = 0;
-
+
/** how long the transition should last */
protected double duration = 0;
-
+
/** current anim time */
protected double elapsedTime = 0;
-
+
/** True if this animator is paused */
protected boolean paused = false;
-
+
/** Easing fn */
protected Easing easingCurrent = Easing.LINEAR;
protected Easing easingOut = Easing.LINEAR;
protected Easing easingIn = Easing.LINEAR;
-
+
/** Default duration (seconds) */
private double defaultDuration = 1;
-
-
+
+
/**
* With linear easing
- *
+ *
* @param value initial value
*/
- public NumAnimated(double value) {
+ public NumAnimated(double value)
+ {
setTo(value);
}
-
-
+
+
/**
* Create animator with easing
- *
+ *
* @param value initial value
* @param easing easing function
*/
- public NumAnimated(double value, Easing easing) {
+ public NumAnimated(double value, Easing easing)
+ {
this(value);
setEasing(easing);
}
-
-
+
+
/**
* Create animator with easing
- *
+ *
* @param value initial value
* @param easingIn easing function (fade in)
* @param easingOut easing function (fade out)
*/
- public NumAnimated(double value, Easing easingIn, Easing easingOut) {
+ public NumAnimated(double value, Easing easingIn, Easing easingOut)
+ {
this(value);
setEasing(easingIn, easingOut);
}
-
-
+
+
/**
* Create animator with easing
- *
+ *
* @param value initial value
* @param easing easing function
* @param defaultDuration default fade duration
*/
- public NumAnimated(double value, Easing easing, double defaultDuration) {
+ public NumAnimated(double value, Easing easing, double defaultDuration)
+ {
this(value);
setEasing(easing);
setDefaultDuration(defaultDuration);
}
-
-
+
+
/**
* Create animator with easing
- *
+ *
* @param value initial value
* @param easingIn easing function (fade in)
* @param easingOut easing function (fade out)
* @param defaultDuration default fade duration
*/
- public NumAnimated(double value, Easing easingIn, Easing easingOut, double defaultDuration) {
+ public NumAnimated(double value, Easing easingIn, Easing easingOut, double defaultDuration)
+ {
this(value);
setEasing(easingIn, easingOut);
setDefaultDuration(defaultDuration);
}
-
-
+
+
/**
* Create as copy of another
- *
+ *
* @param other other animator
*/
- public NumAnimated(NumAnimated other) {
+ public NumAnimated(NumAnimated other)
+ {
setTo(other);
}
-
-
+
+
/**
* @param easing easing function
*/
@@ -121,8 +127,8 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
{
this.easingCurrent = this.easingIn = this.easingOut = easing;
}
-
-
+
+
/**
* @param easingIn easing for fade in
* @param easingOut easing for fade out
@@ -133,30 +139,30 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
this.easingOut = easingOut;
this.easingCurrent = easingIn;
}
-
-
+
+
/**
* Get start value
- *
+ *
* @return number
*/
public double getStart()
{
return from;
}
-
-
+
+
/**
* Get end value
- *
+ *
* @return number
*/
public double getEnd()
{
return to;
}
-
-
+
+
/**
* @return current animation duration (seconds)
*/
@@ -164,8 +170,8 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
{
return duration;
}
-
-
+
+
/**
* @return elapsed time in current animation (seconds)
*/
@@ -173,8 +179,8 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
{
return elapsedTime;
}
-
-
+
+
/**
* @return default animation duration (seconds)
*/
@@ -182,8 +188,8 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
{
return defaultDuration;
}
-
-
+
+
/**
* @param defaultDuration default animation duration (seconds)
*/
@@ -191,11 +197,11 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
{
this.defaultDuration = defaultDuration;
}
-
-
+
+
/**
* Get value at delta time
- *
+ *
* @return the value
*/
@Override
@@ -204,11 +210,11 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
if (duration == 0) return to;
return Calc.interpolate(from, to, (elapsedTime / duration), easingCurrent);
}
-
-
+
+
/**
* Get how much of the animation is already finished
- *
+ *
* @return completion ratio (0 to 1)
*/
public double getProgress()
@@ -216,13 +222,13 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
if (duration == 0) return 1;
return elapsedTime / duration;
}
-
-
+
+
@Override
public void update(double delta)
{
if (paused || isFinished()) return;
-
+
elapsedTime = Calc.clamp(elapsedTime + delta, 0, duration);
if (isFinished()) {
duration = 0;
@@ -230,22 +236,22 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
from = to;
}
}
-
-
+
+
/**
* Get if animation is finished
- *
+ *
* @return is finished
*/
public boolean isFinished()
{
return duration == 0 || elapsedTime >= duration;
}
-
-
+
+
/**
* Set to a value (without animation)
- *
+ *
* @param value
*/
@Override
@@ -255,11 +261,11 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
elapsedTime = 0;
duration = 0;
}
-
-
+
+
/**
* Copy other
- *
+ *
* @param other
*/
public void setTo(NumAnimated other)
@@ -274,11 +280,11 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
this.easingOut = other.easingOut;
this.defaultDuration = other.defaultDuration;
}
-
-
+
+
/**
* Animate between two states, start from current value (if it's in between)
- *
+ *
* @param from start value
* @param to target state
* @param time animation time (secs)
@@ -286,45 +292,45 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
public void animate(double from, double to, double time)
{
final double current = value();
-
+
this.from = from;
this.to = to;
-
+
final double progress = getProgressFromValue(current);
-
+
this.from = (progress > 0 ? current : from);
-
+
this.duration = time * (1 - progress);
this.elapsedTime = 0;
}
-
-
+
+
/**
* Get progress already elapsed based on current value.
* Used to resume animation from current point in fading etc.
- *
+ *
* @param value current value
* @return progress ratio 0-1
*/
protected double getProgressFromValue(double value)
{
double p = 0;
-
+
if (from == to) return 0;
-
+
if (value >= from && value <= to) { // up
p = ((value - from) / (to - from));
} else if (value >= to && value <= from) { // down
p = ((from - value) / (from - to));
}
-
+
return p;
}
-
-
+
+
/**
* Animate to a value from current value
- *
+ *
* @param to target state
* @param duration animation duration (speeds)
*/
@@ -335,11 +341,11 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
this.duration = duration;
this.elapsedTime = 0;
}
-
-
+
+
/**
* Animate 0 to 1
- *
+ *
* @param time animation time (secs)
*/
public void fadeIn(double time)
@@ -347,11 +353,11 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
easingCurrent = easingIn;
animate(0, 1, time);
}
-
-
+
+
/**
* Animate 1 to 0
- *
+ *
* @param time animation time (secs)
*/
public void fadeOut(double time)
@@ -359,8 +365,8 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
easingCurrent = easingOut;
animate(1, 0, time);
}
-
-
+
+
/**
* Animate 0 to 1 with default duration
*/
@@ -369,8 +375,8 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
easingCurrent = easingIn;
animate(0, 1, defaultDuration);
}
-
-
+
+
/**
* Animate 1 to 0 with default duration
*/
@@ -379,11 +385,11 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
easingCurrent = easingOut;
animate(1, 0, defaultDuration);
}
-
-
+
+
/**
* Make a copy
- *
+ *
* @return copy
*/
@Override
@@ -391,15 +397,15 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
{
return new NumAnimated(this);
}
-
-
+
+
@Override
public String toString()
{
return "Animation(" + from + " -> " + to + ", t=" + duration + "s, elapsed=" + elapsedTime + "s)";
}
-
-
+
+
/**
* Set to zero and stop animation
*/
@@ -410,8 +416,8 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
duration = 0;
paused = false;
}
-
-
+
+
/**
* Stop animation, keep current value
*/
@@ -421,29 +427,29 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
elapsedTime = 0;
duration = 0;
}
-
-
+
+
@Override
public void pause()
{
paused = true;
}
-
-
+
+
@Override
public void resume()
{
paused = false;
}
-
-
+
+
@Override
public boolean isPaused()
{
return paused;
}
-
-
+
+
public boolean isInProgress()
{
return !isFinished() && !isPaused();
diff --git a/src/mightypork/utils/math/animation/NumAnimatedDeg.java b/src/mightypork/utils/math/animation/NumAnimatedDeg.java
index 32b2b06..fc4529e 100644
--- a/src/mightypork/utils/math/animation/NumAnimatedDeg.java
+++ b/src/mightypork/utils/math/animation/NumAnimatedDeg.java
@@ -7,34 +7,37 @@ import mightypork.utils.math.angles.Deg;
/**
* Degree animator
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class NumAnimatedDeg extends NumAnimated {
-
- public NumAnimatedDeg(NumAnimated other) {
+
+ public NumAnimatedDeg(NumAnimated other)
+ {
super(other);
}
-
-
- public NumAnimatedDeg(double value) {
+
+
+ public NumAnimatedDeg(double value)
+ {
super(value);
}
-
-
- public NumAnimatedDeg(double value, Easing easing) {
+
+
+ public NumAnimatedDeg(double value, Easing easing)
+ {
super(value, easing);
}
-
-
+
+
@Override
public double value()
{
if (duration == 0) return Deg.norm(to);
return Calc.interpolateDeg(from, to, (elapsedTime / duration), easingCurrent);
}
-
-
+
+
@Override
protected double getProgressFromValue(double value)
{
@@ -43,7 +46,7 @@ public class NumAnimatedDeg extends NumAnimated {
final double partial = Deg.diff(from, value);
return partial / whole;
}
-
+
return 0;
}
}
diff --git a/src/mightypork/utils/math/animation/NumAnimatedRad.java b/src/mightypork/utils/math/animation/NumAnimatedRad.java
index 7057a63..569f799 100644
--- a/src/mightypork/utils/math/animation/NumAnimatedRad.java
+++ b/src/mightypork/utils/math/animation/NumAnimatedRad.java
@@ -7,34 +7,37 @@ import mightypork.utils.math.angles.Rad;
/**
* Radians animator
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class NumAnimatedRad extends NumAnimated {
-
- public NumAnimatedRad(NumAnimated other) {
+
+ public NumAnimatedRad(NumAnimated other)
+ {
super(other);
}
-
-
- public NumAnimatedRad(double value) {
+
+
+ public NumAnimatedRad(double value)
+ {
super(value);
}
-
-
- public NumAnimatedRad(double value, Easing easing) {
+
+
+ public NumAnimatedRad(double value, Easing easing)
+ {
super(value, easing);
}
-
-
+
+
@Override
public double value()
{
if (duration == 0) return Rad.norm(to);
return Calc.interpolateRad(from, to, (elapsedTime / duration), easingCurrent);
}
-
-
+
+
@Override
protected double getProgressFromValue(double value)
{
@@ -43,7 +46,7 @@ public class NumAnimatedRad extends NumAnimated {
final double partial = Rad.diff(from, value);
return partial / whole;
}
-
+
return 0;
}
}
diff --git a/src/mightypork/utils/math/animation/VectAnimated.java b/src/mightypork/utils/math/animation/VectAnimated.java
index 32cd357..75fdbcf 100644
--- a/src/mightypork/utils/math/animation/VectAnimated.java
+++ b/src/mightypork/utils/math/animation/VectAnimated.java
@@ -10,64 +10,66 @@ import mightypork.utils.math.constraints.vect.var.VectMutable;
/**
* 3D coordinated with support for transitions, mutable.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class VectAnimated extends VectMutable implements Pauseable, Updateable {
-
+
private final NumAnimated x, y, z;
private double defaultDuration = 0.5;
-
-
+
+
/**
* Create an animated vector; This way different easing / settings can be
* specified for each coordinate.
- *
+ *
* @param x x animator
* @param y y animator
* @param z z animator
*/
- public VectAnimated(NumAnimated x, NumAnimated y, NumAnimated z) {
+ public VectAnimated(NumAnimated x, NumAnimated y, NumAnimated z)
+ {
this.x = x;
this.y = y;
this.z = z;
}
-
-
+
+
/**
* Create an animated vector
- *
+ *
* @param start initial positioon
* @param easing animation easing
*/
- public VectAnimated(Vect start, Easing easing) {
+ public VectAnimated(Vect start, Easing easing)
+ {
x = new NumAnimated(start.x(), easing);
y = new NumAnimated(start.y(), easing);
z = new NumAnimated(start.z(), easing);
}
-
-
+
+
@Override
public double x()
{
return x.value();
}
-
-
+
+
@Override
public double y()
{
return y.value();
}
-
-
+
+
@Override
public double z()
{
return z.value();
}
-
-
+
+
@Override
public void setTo(double x, double y, double z)
{
@@ -75,35 +77,35 @@ public class VectAnimated extends VectMutable implements Pauseable, Updateable {
setY(y);
setZ(z);
}
-
-
+
+
@Override
public void setX(double x)
{
this.x.setTo(x);
}
-
-
+
+
@Override
public void setY(double y)
{
this.y.setTo(y);
}
-
-
+
+
@Override
public void setZ(double z)
{
this.z.setTo(z);
}
-
-
+
+
public void add(Vect offset, double duration)
{
animate(this.add(offset), duration);
}
-
-
+
+
public VectAnimated animate(double x, double y, double z, double duration)
{
this.x.animate(x, duration);
@@ -111,15 +113,15 @@ public class VectAnimated extends VectMutable implements Pauseable, Updateable {
this.z.animate(z, duration);
return this;
}
-
-
+
+
public VectAnimated animate(Vect target, double duration)
{
animate(target.x(), target.y(), target.z(), duration);
return this;
}
-
-
+
+
public VectAnimated animate(double x, double y, double z)
{
this.x.animate(x, defaultDuration);
@@ -127,15 +129,15 @@ public class VectAnimated extends VectMutable implements Pauseable, Updateable {
this.z.animate(z, defaultDuration);
return this;
}
-
-
+
+
public VectAnimated animate(Vect target)
{
animate(target.x(), target.y(), target.z());
return this;
}
-
-
+
+
/**
* @return the default duration (seconds)
*/
@@ -143,19 +145,19 @@ public class VectAnimated extends VectMutable implements Pauseable, Updateable {
{
return defaultDuration;
}
-
-
+
+
/**
* Set default animation duration (when changed without using animate())
- *
+ *
* @param defaultDuration default duration (seconds)
*/
public void setDefaultDuration(double defaultDuration)
{
this.defaultDuration = defaultDuration;
}
-
-
+
+
@Override
public void update(double delta)
{
@@ -163,8 +165,8 @@ public class VectAnimated extends VectMutable implements Pauseable, Updateable {
y.update(delta);
z.update(delta);
}
-
-
+
+
@Override
public void pause()
{
@@ -172,8 +174,8 @@ public class VectAnimated extends VectMutable implements Pauseable, Updateable {
y.pause();
z.pause();
}
-
-
+
+
@Override
public void resume()
{
@@ -181,15 +183,15 @@ public class VectAnimated extends VectMutable implements Pauseable, Updateable {
y.resume();
z.resume();
}
-
-
+
+
@Override
public boolean isPaused()
{
return x.isPaused(); // BÚNO
}
-
-
+
+
/**
* @return true if the animation is finished
*/
@@ -197,8 +199,8 @@ public class VectAnimated extends VectMutable implements Pauseable, Updateable {
{
return x.isFinished(); // BÚNO
}
-
-
+
+
/**
* @return current animation duration
*/
@@ -206,8 +208,8 @@ public class VectAnimated extends VectMutable implements Pauseable, Updateable {
{
return x.getDuration(); // BÚNO
}
-
-
+
+
/**
* @return elapsed time since the start of the animation
*/
@@ -215,8 +217,8 @@ public class VectAnimated extends VectMutable implements Pauseable, Updateable {
{
return x.getElapsed(); // BÚNO
}
-
-
+
+
/**
* @return animation progress (elapsed / duration)
*/
@@ -224,11 +226,11 @@ public class VectAnimated extends VectMutable implements Pauseable, Updateable {
{
return x.getProgress(); // BÚNO
}
-
-
+
+
/**
* Set easing for all three coordinates
- *
+ *
* @param easing
*/
public void setEasing(Easing easing)
@@ -237,12 +239,12 @@ public class VectAnimated extends VectMutable implements Pauseable, Updateable {
y.setEasing(easing);
z.setEasing(easing);
}
-
-
+
+
/**
* Create an animated vector; This way different easing / settings can be
* specified for each coordinate.
- *
+ *
* @param x x animator
* @param y y animator
* @param z z animator
@@ -253,11 +255,11 @@ public class VectAnimated extends VectMutable implements Pauseable, Updateable {
{
return new VectAnimated(x, y, z);
}
-
-
+
+
/**
* Create an animated vector
- *
+ *
* @param start initial positioon
* @param easing animation easing
* @return animated mutable vector
@@ -267,11 +269,11 @@ public class VectAnimated extends VectMutable implements Pauseable, Updateable {
{
return new VectAnimated(start, easing);
}
-
-
+
+
/**
* Create an animated vector, initialized at 0,0,0
- *
+ *
* @param easing animation easing
* @return animated mutable vector
*/
@@ -280,5 +282,5 @@ public class VectAnimated extends VectMutable implements Pauseable, Updateable {
{
return new VectAnimated(Vect.ZERO, easing);
}
-
+
}
diff --git a/src/mightypork/utils/math/color/Color.java b/src/mightypork/utils/math/color/Color.java
index c848904..13704b5 100644
--- a/src/mightypork/utils/math/color/Color.java
+++ b/src/mightypork/utils/math/color/Color.java
@@ -12,15 +12,15 @@ import mightypork.utils.math.constraints.num.Num;
/**
* Color.
* All values are 0-1
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public abstract class Color {
-
+
private static final Stack alphaStack = new Stack<>();
private static volatile boolean alphaStackEnabled = true;
-
-
+
+
@FactoryMethod
public static final Color fromHex(int rgb_hex)
{
@@ -29,146 +29,146 @@ public abstract class Color {
final int ri = (rgb_hex >> 16) & 0xff;
return rgb(ri / 255D, gi / 255D, bi / 255D);
}
-
-
+
+
@FactoryMethod
public static final Color rgb(double r, double g, double b)
{
return rgba(Num.make(r), Num.make(g), Num.make(b), Num.ONE);
}
-
-
+
+
@FactoryMethod
public static final Color rgba(double r, double g, double b, double a)
{
return rgba(Num.make(r), Num.make(g), Num.make(b), Num.make(a));
}
-
-
+
+
@FactoryMethod
public static final Color rgb(Num r, Num g, Num b)
{
return rgba(r, g, b, Num.ONE);
}
-
-
+
+
@FactoryMethod
public static final Color rgba(Num r, Num g, Num b, Num a)
{
return new ColorRgb(r, g, b, a);
}
-
-
+
+
@FactoryMethod
public static final Color hsb(double h, double s, double b)
{
return hsba(Num.make(h), Num.make(s), Num.make(b), Num.ONE);
}
-
-
+
+
@FactoryMethod
public static final Color hsba(double h, double s, double b, double a)
{
return hsba(Num.make(h), Num.make(s), Num.make(b), Num.make(a));
}
-
-
+
+
@FactoryMethod
public static final Color hsb(Num h, Num s, Num b)
{
return hsba(h, s, b, Num.ONE);
}
-
-
+
+
@FactoryMethod
public static final Color hsba(Num h, Num s, Num b, Num a)
{
return new ColorHsb(h, s, b, a);
}
-
-
+
+
@FactoryMethod
public static final Color light(double a)
{
return light(Num.make(a));
}
-
-
+
+
@FactoryMethod
public static final Color light(Num a)
{
return rgba(Num.ONE, Num.ONE, Num.ONE, a);
}
-
-
+
+
@FactoryMethod
public static final Color dark(double a)
{
return dark(Num.make(a));
}
-
-
+
+
@FactoryMethod
public static final Color dark(Num a)
{
return rgba(Num.ZERO, Num.ZERO, Num.ZERO, a);
}
-
-
+
+
protected static final double clamp(Num n)
{
return Calc.clamp(n.value(), 0, 1);
}
-
-
+
+
protected static final double clamp(double n)
{
return Calc.clamp(n, 0, 1);
}
-
-
+
+
/**
* @return red 0-1
*/
public abstract double r();
-
-
+
+
/**
* @return green 0-1
*/
public abstract double g();
-
-
+
+
/**
* @return blue 0-1
*/
public abstract double b();
-
-
+
+
/**
* @return alpha 0-1
*/
public final double a()
{
double alpha = rawAlpha();
-
+
if (alphaStackEnabled) {
-
+
for (final Num n : alphaStack) {
alpha *= clamp(n.value());
}
}
-
+
return clamp(alpha);
}
-
-
+
+
/**
* @return alpha 0-1, before multiplying with the global alpha value.
*/
protected abstract double rawAlpha();
-
-
+
+
/**
*
* Push alpha multiplier on the stack (can be animated or whatever you
@@ -180,7 +180,7 @@ public abstract class Color {
* multiplier value should not exceed the range 0..1, otherwise it will be
* clamped to it.
*
- *
+ *
* @param alpha alpha multiplier
*/
public static void pushAlpha(Num alpha)
@@ -188,15 +188,15 @@ public abstract class Color {
if (!alphaStackEnabled) {
return;
}
-
+
alphaStack.push(alpha);
}
-
-
+
+
/**
* Remove a pushed alpha multiplier from the stack. If there's no remaining
* multiplier on the stack, an exception is raised.
- *
+ *
* @throws EmptyStackException if the stack is empty
*/
public static void popAlpha()
@@ -204,27 +204,27 @@ public abstract class Color {
if (!alphaStackEnabled) {
return;
}
-
+
if (alphaStack.isEmpty()) {
throw new EmptyStackException();
}
-
+
alphaStack.pop();
}
-
-
+
+
/**
* Enable alpha stack. When disabled, pushAlpha() and popAlpha() have no
* effect.
- *
+ *
* @param yes
*/
public static void enableAlphaStack(boolean yes)
{
alphaStackEnabled = yes;
}
-
-
+
+
/**
* @return true if alpha stack is enabled.
*/
@@ -232,20 +232,20 @@ public abstract class Color {
{
return alphaStackEnabled;
}
-
-
+
+
public Color withAlpha(double multiplier)
{
return new ColorAlphaAdjuster(this, Num.make(multiplier));
}
-
-
+
+
public Color withAlpha(Num multiplier)
{
return new ColorAlphaAdjuster(this, multiplier);
}
-
-
+
+
@Override
public int hashCode()
{
@@ -262,15 +262,15 @@ public abstract class Color {
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
-
-
+
+
@Override
public boolean equals(Object obj)
{
if (this == obj) return true;
if (obj == null) return false;
if (!(obj instanceof Color)) return false;
- Color other = (Color) obj;
+ final Color other = (Color) obj;
if (Double.doubleToLongBits(b()) != Double.doubleToLongBits(other.b())) return false;
if (Double.doubleToLongBits(g()) != Double.doubleToLongBits(other.g())) return false;
if (Double.doubleToLongBits(r()) != Double.doubleToLongBits(other.r())) return false;
diff --git a/src/mightypork/utils/math/color/ColorAlphaAdjuster.java b/src/mightypork/utils/math/color/ColorAlphaAdjuster.java
index 9d58577..5d87c43 100644
--- a/src/mightypork/utils/math/color/ColorAlphaAdjuster.java
+++ b/src/mightypork/utils/math/color/ColorAlphaAdjuster.java
@@ -5,42 +5,43 @@ import mightypork.utils.math.constraints.num.Num;
public class ColorAlphaAdjuster extends Color {
-
+
private final Color source;
private final Num alphaAdjust;
-
-
- public ColorAlphaAdjuster(Color source, Num alphaMul) {
+
+
+ public ColorAlphaAdjuster(Color source, Num alphaMul)
+ {
this.source = source;
this.alphaAdjust = alphaMul;
}
-
-
+
+
@Override
public double r()
{
return source.r();
}
-
-
+
+
@Override
public double g()
{
return source.g();
}
-
-
+
+
@Override
public double b()
{
return source.b();
}
-
-
+
+
@Override
protected double rawAlpha()
{
return source.rawAlpha() * alphaAdjust.value();
}
-
+
}
diff --git a/src/mightypork/utils/math/color/ColorHsb.java b/src/mightypork/utils/math/color/ColorHsb.java
index 781873f..c70b3dc 100644
--- a/src/mightypork/utils/math/color/ColorHsb.java
+++ b/src/mightypork/utils/math/color/ColorHsb.java
@@ -5,57 +5,58 @@ import mightypork.utils.math.constraints.num.Num;
public class ColorHsb extends Color {
-
+
private final Num h;
private final Num s;
private final Num b;
private final Num a;
-
-
- public ColorHsb(Num h, Num s, Num b, Num a) {
+
+
+ public ColorHsb(Num h, Num s, Num b, Num a)
+ {
this.h = h;
this.s = s;
this.b = b;
this.a = a;
}
-
-
+
+
private double[] asRgb()
{
final int hex = java.awt.Color.HSBtoRGB((float) clamp(h), (float) clamp(s), (float) clamp(b));
-
+
final int bi = hex & 0xff;
final int gi = (hex >> 8) & 0xff;
final int ri = (hex >> 16) & 0xff;
return new double[] { ri / 255D, gi / 255D, bi / 255D, clamp(a) };
}
-
-
+
+
@Override
public double r()
{
return asRgb()[0];
}
-
-
+
+
@Override
public double g()
{
return asRgb()[1];
}
-
-
+
+
@Override
public double b()
{
return asRgb()[2];
}
-
-
+
+
@Override
protected double rawAlpha()
{
return asRgb()[3];
}
-
+
}
diff --git a/src/mightypork/utils/math/color/ColorRgb.java b/src/mightypork/utils/math/color/ColorRgb.java
index 38eb212..37065af 100644
--- a/src/mightypork/utils/math/color/ColorRgb.java
+++ b/src/mightypork/utils/math/color/ColorRgb.java
@@ -5,46 +5,47 @@ import mightypork.utils.math.constraints.num.Num;
public class ColorRgb extends Color {
-
+
private final Num r;
private final Num g;
private final Num b;
private final Num a;
-
-
- public ColorRgb(Num r, Num g, Num b, Num a) {
+
+
+ public ColorRgb(Num r, Num g, Num b, Num a)
+ {
this.r = r;
this.g = g;
this.b = b;
this.a = a;
}
-
-
+
+
@Override
public double r()
{
return clamp(r);
}
-
-
+
+
@Override
public double g()
{
return clamp(g);
}
-
-
+
+
@Override
public double b()
{
return clamp(b);
}
-
-
+
+
@Override
protected double rawAlpha()
{
return clamp(a);
}
-
+
}
diff --git a/src/mightypork/utils/math/color/Grad.java b/src/mightypork/utils/math/color/Grad.java
index 7385b6a..ddf3fd6 100644
--- a/src/mightypork/utils/math/color/Grad.java
+++ b/src/mightypork/utils/math/color/Grad.java
@@ -1,27 +1,26 @@
package mightypork.utils.math.color;
-
-
/**
* Linear gradient (each corner can have different color)
- *
+ *
* @author MightyPork
*/
public class Grad {
-
+
public final Color leftTop, rightTop, rightBottom, leftBottom;
-
-
+
+
/**
* Create a gradient
- *
+ *
* @param leftTop left top color
* @param rightTop right top color
* @param rightBottom right bottom color
* @param leftBottom left bottom color
*/
- public Grad(Color leftTop, Color rightTop, Color rightBottom, Color leftBottom) {
+ public Grad(Color leftTop, Color rightTop, Color rightBottom, Color leftBottom)
+ {
this.leftTop = leftTop;
this.rightTop = rightTop;
this.rightBottom = rightBottom;
diff --git a/src/mightypork/utils/math/color/GradH.java b/src/mightypork/utils/math/color/GradH.java
index 17d758c..76eb2c0 100644
--- a/src/mightypork/utils/math/color/GradH.java
+++ b/src/mightypork/utils/math/color/GradH.java
@@ -1,16 +1,15 @@
package mightypork.utils.math.color;
-
-
/**
* Linear horizontal gradient
- *
+ *
* @author MightyPork
*/
public class GradH extends Grad {
-
- public GradH(Color left, Color right) {
+
+ public GradH(Color left, Color right)
+ {
super(left, right, right, left);
}
}
diff --git a/src/mightypork/utils/math/color/GradV.java b/src/mightypork/utils/math/color/GradV.java
index b723d25..dfc92ca 100644
--- a/src/mightypork/utils/math/color/GradV.java
+++ b/src/mightypork/utils/math/color/GradV.java
@@ -1,16 +1,15 @@
package mightypork.utils.math.color;
-
-
/**
* Linear vertical gradient
- *
+ *
* @author MightyPork
*/
public class GradV extends Grad {
-
- public GradV(Color top, Color bottom) {
+
+ public GradV(Color top, Color bottom)
+ {
super(top, top, bottom, bottom);
}
}
diff --git a/src/mightypork/utils/math/color/pal/CGA.java b/src/mightypork/utils/math/color/pal/CGA.java
index 82a8125..3544033 100644
--- a/src/mightypork/utils/math/color/pal/CGA.java
+++ b/src/mightypork/utils/math/color/pal/CGA.java
@@ -6,16 +6,16 @@ import mightypork.utils.math.color.Color;
/**
* CGA palette
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public interface CGA {
-
+
Color BLACK = Color.fromHex(0x000000);
Color GRAY_DARK = Color.fromHex(0x686868);
Color GRAY_LIGHT = Color.fromHex(0xB8B8B8);
Color WHITE = Color.fromHex(0xFFFFFF);
-
+
Color RED_DARK = Color.fromHex(0xC41F0C);
Color RED_LIGHT = Color.fromHex(0xFF706A);
Color MAGENTA_DARK = Color.fromHex(0xC12BB6);
@@ -26,7 +26,7 @@ public interface CGA {
Color CYAN_LIGHT = Color.fromHex(0x23FCFE);
Color GREEN_DARK = Color.fromHex(0x00B41D);
Color GREEN_LIGHT = Color.fromHex(0x39FA6F);
-
+
Color YELLOW = Color.fromHex(0xFFFD72);
Color BROWN = Color.fromHex(0xC16A14);
}
diff --git a/src/mightypork/utils/math/color/pal/CMDR.java b/src/mightypork/utils/math/color/pal/CMDR.java
index d8d5b75..c7d3c39 100644
--- a/src/mightypork/utils/math/color/pal/CMDR.java
+++ b/src/mightypork/utils/math/color/pal/CMDR.java
@@ -6,11 +6,11 @@ import mightypork.utils.math.color.Color;
/**
* COMMODORE palette
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public interface CMDR {
-
+
Color BLACK = Color.fromHex(0x040013);
Color WHITE = Color.fromHex(0xFFFFFF);
Color RED = Color.fromHex(0x883932);
diff --git a/src/mightypork/utils/math/color/pal/PAL16.java b/src/mightypork/utils/math/color/pal/PAL16.java
index fb32202..55f2375 100644
--- a/src/mightypork/utils/math/color/pal/PAL16.java
+++ b/src/mightypork/utils/math/color/pal/PAL16.java
@@ -6,27 +6,27 @@ import mightypork.utils.math.color.Color;
/**
* PAL16 palette via http://androidarts.com/palette/16pal.htm
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public interface PAL16 {
-
+
Color VOID = Color.fromHex(0x000000);
Color ASH = Color.fromHex(0x9D9D9D);
Color BLIND = Color.fromHex(0xFFFFFF);
-
+
Color BLOODRED = Color.fromHex(0xBE2633);
Color PIGMEAT = Color.fromHex(0xE06F8B);
-
+
Color OLDPOOP = Color.fromHex(0x493C2B);
Color NEWPOOP = Color.fromHex(0xA46422);
Color BLAZE = Color.fromHex(0xEB8931);
Color ZORNSKIN = Color.fromHex(0xF7E26B);
-
+
Color SHADEGREEN = Color.fromHex(0x2F484E);
Color LEAFGREEN = Color.fromHex(0x44891A);
Color SLIMEGREEN = Color.fromHex(0xA3CE27);
-
+
Color NIGHTBLUE = Color.fromHex(0x1B2632);
Color SEABLUE = Color.fromHex(0x005784);
Color SKYBLUE = Color.fromHex(0x31A2F2);
diff --git a/src/mightypork/utils/math/color/pal/RGB.java b/src/mightypork/utils/math/color/pal/RGB.java
index 1dc490e..ee9179e 100644
--- a/src/mightypork/utils/math/color/pal/RGB.java
+++ b/src/mightypork/utils/math/color/pal/RGB.java
@@ -6,11 +6,11 @@ import mightypork.utils.math.color.Color;
/**
* Basic RGB palette
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class RGB {
-
+
public static final Color BLACK_10 = Color.rgba(0, 0, 0, 0.1);
public static final Color BLACK_20 = Color.rgba(0, 0, 0, 0.2);
public static final Color BLACK_30 = Color.rgba(0, 0, 0, 0.3);
@@ -20,24 +20,24 @@ public class RGB {
public static final Color BLACK_70 = Color.rgba(0, 0, 0, 0.7);
public static final Color BLACK_80 = Color.rgba(0, 0, 0, 0.8);
public static final Color BLACK_90 = Color.rgba(0, 0, 0, 0.9);
-
+
public static final Color WHITE = Color.fromHex(0xFFFFFF);
public static final Color BLACK = Color.fromHex(0x000000);
public static final Color GRAY_DARK = Color.fromHex(0x808080);
public static final Color GRAY = Color.fromHex(0xA0A0A0);
public static final Color GRAY_LIGHT = Color.fromHex(0xC0C0C0);
-
+
public static final Color RED = Color.fromHex(0xFF0000);
public static final Color GREEN = Color.fromHex(0x00FF00);
public static final Color BLUE = Color.fromHex(0x0000FF);
-
+
public static final Color YELLOW = Color.fromHex(0xFFFF00);
public static final Color CYAN = Color.fromHex(0x00FFFF);
public static final Color MAGENTA = Color.fromHex(0xFF00FF);
-
+
public static final Color PINK = Color.fromHex(0xFF3FFC);
public static final Color ORANGE = Color.fromHex(0xFC4800);
public static final Color BROWN = Color.fromHex(0x83501B);
-
+
public static final Color NONE = Color.rgba(0, 0, 0, 0);
}
diff --git a/src/mightypork/utils/math/color/pal/ZX.java b/src/mightypork/utils/math/color/pal/ZX.java
index ac2baf3..9715be5 100644
--- a/src/mightypork/utils/math/color/pal/ZX.java
+++ b/src/mightypork/utils/math/color/pal/ZX.java
@@ -6,15 +6,15 @@ import mightypork.utils.math.color.Color;
/**
* ZX Spectrum palette
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public interface ZX {
-
+
Color BLACK = Color.fromHex(0x000000);
Color GRAY = Color.fromHex(0xCBCBCB);
Color WHITE = Color.fromHex(0xFFFFFF);
-
+
Color RED_DARK = Color.fromHex(0xD8240F);
Color RED_LIGHT = Color.fromHex(0xFF3016);
Color MAGENTA_DARK = Color.fromHex(0xD530C9);
@@ -25,7 +25,7 @@ public interface ZX {
Color CYAN_LIGHT = Color.fromHex(0xFFFD33);
Color GREEN_DARK = Color.fromHex(0x00C721);
Color GREEN_LIGHT = Color.fromHex(0x00F92C);
-
+
Color YELLOW_DARK = Color.fromHex(0xCECA26);
Color YELLOW_LIGHT = Color.fromHex(0xFFFD33);
}
diff --git a/src/mightypork/utils/math/constraints/CachedConstraint.java b/src/mightypork/utils/math/constraints/CachedConstraint.java
index dede4e2..f2ba4f0 100644
--- a/src/mightypork/utils/math/constraints/CachedConstraint.java
+++ b/src/mightypork/utils/math/constraints/CachedConstraint.java
@@ -6,38 +6,38 @@ import mightypork.utils.interfaces.Pollable;
/**
* Constraint that is cached
- *
+ *
* @author Ondřej Hruška (MightyPork)
* @param constraint type
*/
public interface CachedConstraint extends Pollable {
-
+
/**
* Called after the cache has changed value (and digest).
*/
void onConstraintChanged();
-
-
+
+
/**
* @return the cached value
*/
C getCacheSource();
-
-
+
+
/**
* Enable caching & digest caching
- *
+ *
* @param yes enable caching
*/
void enableCaching(boolean yes);
-
-
+
+
/**
* @return true if caching is on
*/
boolean isCachingEnabled();
-
-
+
+
/**
* Update cached value and cached digest (if digest caching is enabled).
* source constraint is polled beforehand.
diff --git a/src/mightypork/utils/math/constraints/CachedDigestable.java b/src/mightypork/utils/math/constraints/CachedDigestable.java
index e0060a3..7925b18 100644
--- a/src/mightypork/utils/math/constraints/CachedDigestable.java
+++ b/src/mightypork/utils/math/constraints/CachedDigestable.java
@@ -17,12 +17,12 @@ package mightypork.utils.math.constraints;
* Implementing class typically needs a field to store the last digest, a flag
* that digest caching is enabled, and a flag that a digest is dirty.
*
- *
+ *
* @author Ondřej Hruška (MightyPork)
* @param digest class
*/
public interface CachedDigestable extends Digestable {
-
+
/**
*
* Toggle digest caching.
@@ -30,22 +30,22 @@ public interface CachedDigestable extends Digestable {
*
* To trigger update of the cache, call the poll()
method.
*
- *
+ *
* @param yes
*/
void enableDigestCaching(boolean yes);
-
-
+
+
/**
* @return true if digest caching is enabled.
*/
boolean isDigestCachingEnabled();
-
-
+
+
/**
* If digest caching is enabled, mark current cached value as "dirty". Dirty
* digest should be re-created next time a value is requested.
*/
void markDigestDirty();
-
+
}
diff --git a/src/mightypork/utils/math/constraints/DigestCache.java b/src/mightypork/utils/math/constraints/DigestCache.java
index 36e0da3..4640f9c 100644
--- a/src/mightypork/utils/math/constraints/DigestCache.java
+++ b/src/mightypork/utils/math/constraints/DigestCache.java
@@ -3,17 +3,17 @@ package mightypork.utils.math.constraints;
/**
* Parametrized implementation of a {@link CachedDigestable}
- *
+ *
* @author Ondřej Hruška (MightyPork)
* @param digest class
*/
public abstract class DigestCache implements CachedDigestable {
-
+
private D last_digest;
private boolean caching_enabled = false;
private boolean dirty = true;
-
-
+
+
@Override
public final D digest()
{
@@ -22,39 +22,39 @@ public abstract class DigestCache implements CachedDigestable {
last_digest = createDigest();
dirty = false;
}
-
+
return last_digest;
}
-
+
return createDigest();
}
-
-
+
+
/**
* @return fresh new digest
*/
protected abstract D createDigest();
-
-
+
+
@Override
public final void enableDigestCaching(boolean yes)
{
caching_enabled = yes;
markDigestDirty(); // mark dirty
}
-
-
+
+
@Override
public final boolean isDigestCachingEnabled()
{
return caching_enabled;
}
-
-
+
+
@Override
public final void markDigestDirty()
{
dirty = true;
}
-
+
}
diff --git a/src/mightypork/utils/math/constraints/Digestable.java b/src/mightypork/utils/math/constraints/Digestable.java
index 7fd28b4..b1d6acc 100644
--- a/src/mightypork/utils/math/constraints/Digestable.java
+++ b/src/mightypork/utils/math/constraints/Digestable.java
@@ -3,18 +3,18 @@ package mightypork.utils.math.constraints;
/**
* COnstraint that can be converted to a digest, representing current state
- *
+ *
* @author Ondřej Hruška (MightyPork)
* @param
*/
public interface Digestable {
-
+
/**
* Take a digest. If digest caching is enabled and the cached digest is
* marked as dirty, a new one should be made.
- *
+ *
* @return digest
*/
D digest();
-
+
}
diff --git a/src/mightypork/utils/math/constraints/num/Num.java b/src/mightypork/utils/math/constraints/num/Num.java
index 415eb88..e97a8da 100644
--- a/src/mightypork/utils/math/constraints/num/Num.java
+++ b/src/mightypork/utils/math/constraints/num/Num.java
@@ -12,45 +12,45 @@ import mightypork.utils.math.constraints.vect.Vect;
public abstract class Num implements NumBound, CachedDigestable {
-
+
public static final NumConst ZERO = Num.make(0);
public static final NumConst ONE = Num.make(1);
-
-
+
+
@FactoryMethod
public static Num make(NumBound bound)
{
return new NumProxy(bound);
}
-
-
+
+
@FactoryMethod
public static NumConst make(double value)
{
return new NumConst(value);
}
-
-
+
+
@FactoryMethod
public static NumVar makeVar()
{
return makeVar(0);
}
-
-
+
+
@FactoryMethod
public static NumVar makeVar(double value)
{
return new NumVar(value);
}
-
-
+
+
@FactoryMethod
public static NumVar makeVar(Num copied)
{
return new NumVar(copied.value());
}
-
+
private Num p_ceil;
private Num p_floor;
private Num p_sgn;
@@ -67,89 +67,89 @@ public abstract class Num implements NumBound, CachedDigestable {
private Num p_square;
private Num p_neg;
private Num p_abs;
-
+
private final DigestCache dc = new DigestCache() {
-
+
@Override
protected NumDigest createDigest()
{
return new NumDigest(Num.this);
}
};
-
-
+
+
public NumConst freeze()
{
return new NumConst(value());
}
-
-
+
+
/**
* Wrap this constraint into a caching adapter. Value will stay fixed (ie.
* no re-calculations) until cache receives a poll() call.
- *
+ *
* @return the caching adapter
*/
public NumCache cached()
{
return new NumCache(this);
}
-
-
+
+
/**
* Get a snapshot of the current state, to be used for processing.
- *
+ *
* @return digest
*/
-
+
@Override
public NumDigest digest()
{
return dc.digest();
}
-
-
+
+
@Override
public void enableDigestCaching(boolean yes)
{
dc.enableDigestCaching(yes);
}
-
-
+
+
@Override
public boolean isDigestCachingEnabled()
{
return dc.isDigestCachingEnabled();
}
-
-
+
+
@Override
public void markDigestDirty()
{
dc.markDigestDirty();
}
-
-
+
+
@Override
public Num getNum()
{
return this;
}
-
-
+
+
/**
* @return the number
*/
public abstract double value();
-
-
+
+
public Num add(final double addend)
{
return new Num() {
-
+
private final Num t = Num.this;
-
-
+
+
@Override
public double value()
{
@@ -157,15 +157,15 @@ public abstract class Num implements NumBound, CachedDigestable {
}
};
}
-
-
+
+
public Num add(final Num addend)
{
return new Num() {
-
+
final Num t = Num.this;
-
-
+
+
@Override
public double value()
{
@@ -173,39 +173,39 @@ public abstract class Num implements NumBound, CachedDigestable {
}
};
}
-
-
+
+
public Num sub(final double subtrahend)
{
return add(-subtrahend);
}
-
-
+
+
public Num abs()
{
if (p_abs == null) p_abs = new Num() {
-
+
final Num t = Num.this;
-
-
+
+
@Override
public double value()
{
return Math.abs(t.value());
}
};
-
+
return p_abs;
}
-
-
+
+
public Num sub(final Num subtrahend)
{
return new Num() {
-
+
final Num t = Num.this;
-
-
+
+
@Override
public double value()
{
@@ -213,22 +213,22 @@ public abstract class Num implements NumBound, CachedDigestable {
}
};
}
-
-
+
+
public Num div(final double factor)
{
return mul(1 / factor);
}
-
-
+
+
public Num div(final Num factor)
{
-
+
return new Num() {
-
+
final Num t = Num.this;
-
-
+
+
@Override
public double value()
{
@@ -236,15 +236,15 @@ public abstract class Num implements NumBound, CachedDigestable {
}
};
}
-
-
+
+
public Num mul(final double factor)
{
return new Num() {
-
+
private final Num t = Num.this;
-
-
+
+
@Override
public double value()
{
@@ -252,16 +252,16 @@ public abstract class Num implements NumBound, CachedDigestable {
}
};
}
-
-
+
+
public Num mul(final Num factor)
{
-
+
return new Num() {
-
+
final Num t = Num.this;
-
-
+
+
@Override
public double value()
{
@@ -269,15 +269,15 @@ public abstract class Num implements NumBound, CachedDigestable {
}
};
}
-
-
+
+
public Num average(final double other)
{
return new Num() {
-
+
final Num t = Num.this;
-
-
+
+
@Override
public double value()
{
@@ -285,15 +285,15 @@ public abstract class Num implements NumBound, CachedDigestable {
}
};
}
-
-
+
+
public Num average(final Num other)
{
return new Num() {
-
+
final Num t = Num.this;
-
-
+
+
@Override
public double value()
{
@@ -301,21 +301,21 @@ public abstract class Num implements NumBound, CachedDigestable {
}
};
}
-
-
+
+
public Num perc(final double percent)
{
return mul(percent / 100D);
}
-
-
+
+
public Num perc(final Num percent)
{
return new Num() {
-
+
final Num t = Num.this;
-
-
+
+
@Override
public double value()
{
@@ -323,231 +323,231 @@ public abstract class Num implements NumBound, CachedDigestable {
}
};
}
-
-
+
+
public Num cos()
{
if (p_cos == null) p_cos = new Num() {
-
+
final Num t = Num.this;
-
-
+
+
@Override
public double value()
{
return Math.cos(t.value());
}
};
-
+
return p_cos;
}
-
-
+
+
public Num acos()
{
if (p_acos == null) p_acos = new Num() {
-
+
final Num t = Num.this;
-
-
+
+
@Override
public double value()
{
return Math.acos(t.value());
}
};
-
+
return p_acos;
}
-
-
+
+
public Num sin()
{
if (p_sin == null) p_sin = new Num() {
-
+
final Num t = Num.this;
-
-
+
+
@Override
public double value()
{
return Math.sin(t.value());
}
};
-
+
return p_sin;
}
-
-
+
+
public Num asin()
{
if (p_asin == null) p_asin = new Num() {
-
+
final Num t = Num.this;
-
-
+
+
@Override
public double value()
{
return Math.asin(t.value());
}
};
-
+
return p_asin;
}
-
-
+
+
public Num tan()
{
if (p_tan == null) p_tan = new Num() {
-
+
final Num t = Num.this;
-
-
+
+
@Override
public double value()
{
return Math.tan(t.value());
}
};
-
+
return p_tan;
}
-
-
+
+
public Num atan()
{
if (p_atan == null) p_atan = new Num() {
-
+
final Num t = Num.this;
-
-
+
+
@Override
public double value()
{
return Math.atan(t.value());
}
};
-
+
return p_atan;
}
-
-
+
+
public Num cbrt()
{
if (p_cbrt == null) p_cbrt = new Num() {
-
+
final Num t = Num.this;
-
-
+
+
@Override
public double value()
{
return Math.cbrt(t.value());
}
};
-
+
return p_cbrt;
}
-
-
+
+
public Num sqrt()
{
if (p_sqrt == null) p_sqrt = new Num() {
-
+
final Num t = Num.this;
-
-
+
+
@Override
public double value()
{
return Math.sqrt(t.value());
}
};
-
+
return p_sqrt;
}
-
-
+
+
public Num neg()
{
if (p_neg == null) p_neg = new Num() {
-
+
final Num t = Num.this;
-
-
+
+
@Override
public double value()
{
return -1 * t.value();
}
};
-
+
return p_neg;
}
-
-
+
+
public Num round()
{
if (p_round == null) p_round = new Num() {
-
+
final Num t = Num.this;
-
-
+
+
@Override
public double value()
{
return Math.round(t.value());
}
};
-
+
return p_round;
}
-
-
+
+
public Num floor()
{
if (p_floor == null) p_floor = new Num() {
-
+
final Num t = Num.this;
-
-
+
+
@Override
public double value()
{
return Math.floor(t.value());
}
};
-
+
return p_floor;
}
-
-
+
+
public Num ceil()
{
if (p_ceil == null) p_ceil = new Num() {
-
+
final Num t = Num.this;
-
-
+
+
@Override
public double value()
{
return Math.round(t.value());
}
};
-
+
return p_ceil;
}
-
-
+
+
public Num pow(final double other)
{
return new Num() {
-
+
final Num t = Num.this;
-
-
+
+
@Override
public double value()
{
@@ -555,15 +555,15 @@ public abstract class Num implements NumBound, CachedDigestable {
}
};
}
-
-
+
+
public Num pow(final Num power)
{
return new Num() {
-
+
final Num t = Num.this;
-
-
+
+
@Override
public double value()
{
@@ -571,15 +571,15 @@ public abstract class Num implements NumBound, CachedDigestable {
}
};
}
-
-
+
+
public Num cube()
{
if (p_cube == null) p_cube = new Num() {
-
+
final Num t = Num.this;
-
-
+
+
@Override
public double value()
{
@@ -587,18 +587,18 @@ public abstract class Num implements NumBound, CachedDigestable {
return v * v * v;
}
};
-
+
return p_cube;
}
-
-
+
+
public Num square()
{
if (p_square == null) p_square = new Num() {
-
+
final Num t = Num.this;
-
-
+
+
@Override
public double value()
{
@@ -606,24 +606,24 @@ public abstract class Num implements NumBound, CachedDigestable {
return v * v;
}
};
-
+
return p_square;
}
-
-
+
+
public Num half()
{
return mul(0.5);
}
-
-
+
+
public Num max(final double other)
{
return new Num() {
-
+
final Num t = Num.this;
-
-
+
+
@Override
public double value()
{
@@ -631,15 +631,15 @@ public abstract class Num implements NumBound, CachedDigestable {
}
};
}
-
-
+
+
public Num max(final Num other)
{
return new Num() {
-
+
final Num t = Num.this;
-
-
+
+
@Override
public double value()
{
@@ -647,15 +647,15 @@ public abstract class Num implements NumBound, CachedDigestable {
}
};
}
-
-
+
+
public Num min(final Num other)
{
return new Num() {
-
+
final Num t = Num.this;
-
-
+
+
@Override
public double value()
{
@@ -663,15 +663,15 @@ public abstract class Num implements NumBound, CachedDigestable {
}
};
}
-
-
+
+
public Num min(final double other)
{
return new Num() {
-
+
final Num t = Num.this;
-
-
+
+
@Override
public double value()
{
@@ -679,44 +679,44 @@ public abstract class Num implements NumBound, CachedDigestable {
}
};
}
-
-
+
+
public Num signum()
{
if (p_sgn == null) p_sgn = new Num() {
-
+
final Num t = Num.this;
-
-
+
+
@Override
public double value()
{
return Math.signum(t.value());
}
};
-
+
return p_sgn;
}
-
-
+
+
public boolean isNegative()
{
return value() < 0;
}
-
-
+
+
public boolean isPositive()
{
return value() > 0;
}
-
-
+
+
public boolean isZero()
{
return value() == 0;
}
-
-
+
+
@Override
public int hashCode()
{
@@ -727,8 +727,8 @@ public abstract class Num implements NumBound, CachedDigestable {
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
-
-
+
+
@Override
public boolean equals(Object obj)
{
@@ -736,18 +736,18 @@ public abstract class Num implements NumBound, CachedDigestable {
if (obj == null) return false;
if (!(obj instanceof Num)) return false;
final Num other = (Num) obj;
-
+
return value() == other.value();
}
-
-
+
+
@Override
public String toString()
{
return Double.toString(value());
}
-
-
+
+
/**
* @return vect with both coords of this size
*/
diff --git a/src/mightypork/utils/math/constraints/num/NumBound.java b/src/mightypork/utils/math/constraints/num/NumBound.java
index 168f32d..b896abf 100644
--- a/src/mightypork/utils/math/constraints/num/NumBound.java
+++ b/src/mightypork/utils/math/constraints/num/NumBound.java
@@ -3,14 +3,14 @@ package mightypork.utils.math.constraints.num;
/**
* Interface for something that has/is a Num. Num itself implements it as well.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public interface NumBound {
-
+
/**
* @return the Num value
*/
Num getNum();
-
+
}
diff --git a/src/mightypork/utils/math/constraints/num/NumConst.java b/src/mightypork/utils/math/constraints/num/NumConst.java
index b29ac42..31c7761 100644
--- a/src/mightypork/utils/math/constraints/num/NumConst.java
+++ b/src/mightypork/utils/math/constraints/num/NumConst.java
@@ -8,32 +8,34 @@ import mightypork.utils.math.constraints.num.caching.NumDigest;
* Constant number.
* It's arranged so that operations with constant arguments yield constant
* results.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class NumConst extends Num {
-
+
private final double value;
private NumDigest digest;
-
-
- NumConst(Num copied) {
+
+
+ NumConst(Num copied)
+ {
this.value = copied.value();
}
-
-
- NumConst(double value) {
+
+
+ NumConst(double value)
+ {
this.value = value;
}
-
-
+
+
@Override
public double value()
{
return value;
}
-
-
+
+
/**
* @deprecated No good to copy a constant.
*/
@@ -43,226 +45,226 @@ public class NumConst extends Num {
{
return this;
}
-
-
+
+
@Override
public NumDigest digest()
{
return (digest != null) ? digest : (digest = super.digest());
}
-
-
+
+
@Override
public NumConst add(double addend)
{
return Num.make(value() + addend);
}
-
-
+
+
public NumConst add(NumConst addend)
{
return Num.make(value + addend.value);
}
-
-
+
+
@Override
public NumConst sub(double subtrahend)
{
return add(-subtrahend);
}
-
-
+
+
public NumConst sub(NumConst addend)
{
return Num.make(value - addend.value);
}
-
-
+
+
@Override
public NumConst mul(double factor)
{
return Num.make(value() * factor);
}
-
-
+
+
public NumConst mul(NumConst addend)
{
return Num.make(value * addend.value);
}
-
-
+
+
@Override
public NumConst div(double factor)
{
return mul(1 / factor);
}
-
-
+
+
public NumConst div(NumConst addend)
{
return Num.make(value / addend.value);
}
-
-
+
+
@Override
public NumConst perc(double percents)
{
return mul(percents / 100);
}
-
-
+
+
@Override
public NumConst neg()
{
return mul(-1);
}
-
-
+
+
@Override
public NumConst abs()
{
return Num.make(Math.abs(value()));
}
-
-
+
+
@Override
public NumConst max(double other)
{
return Num.make(Math.max(value(), other));
}
-
-
+
+
@Override
public NumConst min(double other)
{
return Num.make(Math.min(value(), other));
}
-
-
+
+
@Override
public NumConst pow(double power)
{
return Num.make(Math.pow(value(), power));
}
-
-
+
+
@Override
public NumConst square()
{
final double v = value();
return Num.make(v * v);
}
-
-
+
+
@Override
public NumConst cube()
{
final double v = value();
return Num.make(v * v * v);
}
-
-
+
+
@Override
public NumConst sqrt()
{
return Num.make(Math.sqrt(value()));
}
-
-
+
+
@Override
public NumConst cbrt()
{
return Num.make(Math.cbrt(value()));
}
-
-
+
+
@Override
public NumConst sin()
{
return Num.make(Math.sin(value()));
}
-
-
+
+
@Override
public NumConst cos()
{
return Num.make(Math.cos(value()));
}
-
-
+
+
@Override
public NumConst tan()
{
return Num.make(Math.tan(value()));
}
-
-
+
+
@Override
public NumConst asin()
{
return Num.make(Math.asin(value()));
}
-
-
+
+
@Override
public NumConst acos()
{
return Num.make(Math.acos(value()));
}
-
-
+
+
@Override
public NumConst atan()
{
return Num.make(Math.atan(value()));
}
-
-
+
+
@Override
public NumConst signum()
{
return Num.make(Math.signum(value()));
}
-
-
+
+
@Override
public NumConst average(double other)
{
return Num.make((value() + other) / 2);
}
-
-
+
+
public NumConst average(NumConst other)
{
return super.average(other).freeze();
}
-
-
+
+
@Override
public NumConst round()
{
return Num.make(Math.round(value()));
}
-
-
+
+
@Override
public NumConst ceil()
{
return Num.make(Math.ceil(value()));
}
-
-
+
+
@Override
public NumConst floor()
{
return Num.make(Math.floor(value()));
}
-
-
+
+
@Override
public NumConst half()
{
return mul(0.5);
}
-
+
}
diff --git a/src/mightypork/utils/math/constraints/num/PluggableNumBound.java b/src/mightypork/utils/math/constraints/num/PluggableNumBound.java
index 032bdc9..55ef7fb 100644
--- a/src/mightypork/utils/math/constraints/num/PluggableNumBound.java
+++ b/src/mightypork/utils/math/constraints/num/PluggableNumBound.java
@@ -3,14 +3,14 @@ package mightypork.utils.math.constraints.num;
/**
* Pluggable numeric constraint
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public interface PluggableNumBound extends NumBound {
-
+
/**
* @param num bound to set
*/
abstract void setNum(NumBound num);
-
+
}
diff --git a/src/mightypork/utils/math/constraints/num/batch/NumMul.java b/src/mightypork/utils/math/constraints/num/batch/NumMul.java
index 016bea5..43dfdc2 100644
--- a/src/mightypork/utils/math/constraints/num/batch/NumMul.java
+++ b/src/mightypork/utils/math/constraints/num/batch/NumMul.java
@@ -9,14 +9,14 @@ import mightypork.utils.math.constraints.num.Num;
/**
* Expandable multiplication of multiple numbers
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class NumMul extends Num {
-
+
private final List factors = new ArrayList<>();
-
-
+
+
@Override
public double value()
{
@@ -26,22 +26,22 @@ public class NumMul extends Num {
}
return v;
}
-
-
+
+
/**
* Add a number to the multiplication
- *
+ *
* @param factor added number
*/
public void addFactor(Num factor)
{
factors.add(factor);
}
-
-
+
+
/**
* Add a number to the multiplication
- *
+ *
* @param factor added number
*/
public void addFactor(double factor)
diff --git a/src/mightypork/utils/math/constraints/num/batch/NumSum.java b/src/mightypork/utils/math/constraints/num/batch/NumSum.java
index f63f5fe..8e9e201 100644
--- a/src/mightypork/utils/math/constraints/num/batch/NumSum.java
+++ b/src/mightypork/utils/math/constraints/num/batch/NumSum.java
@@ -9,14 +9,14 @@ import mightypork.utils.math.constraints.num.Num;
/**
* Expandable sum of multiple numbers
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class NumSum extends Num {
-
+
private final List summands = new ArrayList<>();
-
-
+
+
@Override
public double value()
{
@@ -26,22 +26,22 @@ public class NumSum extends Num {
}
return v;
}
-
-
+
+
/**
* Add a number to the sum
- *
+ *
* @param summand added number
*/
public void addSummand(Num summand)
{
summands.add(summand);
}
-
-
+
+
/**
* Add a number to the sum
- *
+ *
* @param summand added number
*/
public void addSummand(double summand)
diff --git a/src/mightypork/utils/math/constraints/num/caching/AbstractNumCache.java b/src/mightypork/utils/math/constraints/num/caching/AbstractNumCache.java
index 83c6809..1099dab 100644
--- a/src/mightypork/utils/math/constraints/num/caching/AbstractNumCache.java
+++ b/src/mightypork/utils/math/constraints/num/caching/AbstractNumCache.java
@@ -15,69 +15,70 @@ import mightypork.utils.math.constraints.num.var.NumVar;
* Values are held in a caching VectVar, and digest caching is enabled by
* default.
*
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public abstract class AbstractNumCache extends NumAdapter implements CachedConstraint {
-
+
private final NumVar cache = Num.makeVar();
private boolean inited = false;
private boolean cachingEnabled = true;
-
-
- public AbstractNumCache() {
+
+
+ public AbstractNumCache()
+ {
enableDigestCaching(true); // it changes only on poll
}
-
-
+
+
@Override
protected final Num getSource()
{
if (!inited) markDigestDirty();
-
+
return (cachingEnabled ? cache : getCacheSource());
}
-
-
+
+
@Override
public final void poll()
{
inited = true;
-
+
// poll source
final Num source = getCacheSource();
source.markDigestDirty(); // poll cached
-
+
// store source value
cache.setTo(source);
-
+
// mark my digest dirty
markDigestDirty();
-
+
onConstraintChanged();
}
-
-
+
+
@Override
public abstract void onConstraintChanged();
-
-
+
+
@Override
public abstract Num getCacheSource();
-
-
+
+
@Override
public final void enableCaching(boolean yes)
{
cachingEnabled = yes;
enableDigestCaching(yes);
}
-
-
+
+
@Override
public final boolean isCachingEnabled()
{
return cachingEnabled;
}
-
+
}
diff --git a/src/mightypork/utils/math/constraints/num/caching/NumCache.java b/src/mightypork/utils/math/constraints/num/caching/NumCache.java
index 4e10d19..a2173e2 100644
--- a/src/mightypork/utils/math/constraints/num/caching/NumCache.java
+++ b/src/mightypork/utils/math/constraints/num/caching/NumCache.java
@@ -6,29 +6,30 @@ import mightypork.utils.math.constraints.num.Num;
/**
* Num cache implementation
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class NumCache extends AbstractNumCache {
-
+
private final Num source;
-
-
- public NumCache(Num source) {
+
+
+ public NumCache(Num source)
+ {
this.source = source;
}
-
-
+
+
@Override
public final Num getCacheSource()
{
return source;
}
-
-
+
+
@Override
public void onConstraintChanged()
{
}
-
+
}
diff --git a/src/mightypork/utils/math/constraints/num/caching/NumDigest.java b/src/mightypork/utils/math/constraints/num/caching/NumDigest.java
index 599706a..edb1e3a 100644
--- a/src/mightypork/utils/math/constraints/num/caching/NumDigest.java
+++ b/src/mightypork/utils/math/constraints/num/caching/NumDigest.java
@@ -5,15 +5,16 @@ import mightypork.utils.math.constraints.num.Num;
public class NumDigest {
-
+
public final double value;
-
-
- public NumDigest(Num num) {
+
+
+ public NumDigest(Num num)
+ {
this.value = num.value();
}
-
-
+
+
@Override
public String toString()
{
diff --git a/src/mightypork/utils/math/constraints/num/proxy/NumAdapter.java b/src/mightypork/utils/math/constraints/num/proxy/NumAdapter.java
index 5b2693d..19de7b7 100644
--- a/src/mightypork/utils/math/constraints/num/proxy/NumAdapter.java
+++ b/src/mightypork/utils/math/constraints/num/proxy/NumAdapter.java
@@ -5,14 +5,14 @@ import mightypork.utils.math.constraints.num.Num;
public abstract class NumAdapter extends Num {
-
+
protected abstract Num getSource();
-
-
+
+
@Override
public double value()
{
return getSource().value();
}
-
+
}
diff --git a/src/mightypork/utils/math/constraints/num/proxy/NumProxy.java b/src/mightypork/utils/math/constraints/num/proxy/NumProxy.java
index da9b67f..96f8687 100644
--- a/src/mightypork/utils/math/constraints/num/proxy/NumProxy.java
+++ b/src/mightypork/utils/math/constraints/num/proxy/NumProxy.java
@@ -8,34 +8,36 @@ import mightypork.utils.math.constraints.num.PluggableNumBound;
/**
* Pluggable num proxy
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class NumProxy extends NumAdapter implements PluggableNumBound {
-
+
private NumBound backing = null;
-
-
- public NumProxy() {
+
+
+ public NumProxy()
+ {
}
-
-
- public NumProxy(NumBound bound) {
+
+
+ public NumProxy(NumBound bound)
+ {
backing = bound;
}
-
-
+
+
@Override
public void setNum(NumBound num)
{
this.backing = num;
}
-
-
+
+
@Override
protected Num getSource()
{
return backing.getNum();
}
-
+
}
diff --git a/src/mightypork/utils/math/constraints/num/var/NumMutable.java b/src/mightypork/utils/math/constraints/num/var/NumMutable.java
index e359473..4a22609 100644
--- a/src/mightypork/utils/math/constraints/num/var/NumMutable.java
+++ b/src/mightypork/utils/math/constraints/num/var/NumMutable.java
@@ -6,30 +6,30 @@ import mightypork.utils.math.constraints.num.Num;
/**
* Mutable numeric variable
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public abstract class NumMutable extends Num {
-
+
/**
* Assign a value
- *
+ *
* @param value new value
*/
public abstract void setTo(double value);
-
-
+
+
/**
* Assign a value
- *
+ *
* @param value new value
*/
public void setTo(Num value)
{
setTo(value.value());
}
-
-
+
+
/**
* Set to zero
*/
@@ -37,5 +37,5 @@ public abstract class NumMutable extends Num {
{
setTo(0);
}
-
+
}
diff --git a/src/mightypork/utils/math/constraints/num/var/NumVar.java b/src/mightypork/utils/math/constraints/num/var/NumVar.java
index 015fe41..54ed86b 100644
--- a/src/mightypork/utils/math/constraints/num/var/NumVar.java
+++ b/src/mightypork/utils/math/constraints/num/var/NumVar.java
@@ -6,35 +6,37 @@ import mightypork.utils.math.constraints.num.Num;
/**
* Mutable numeric variable.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class NumVar extends NumMutable {
-
+
private double value;
-
-
- public NumVar(Num value) {
+
+
+ public NumVar(Num value)
+ {
this(value.value());
}
-
-
- public NumVar(double value) {
+
+
+ public NumVar(double value)
+ {
this.value = value;
}
-
-
+
+
@Override
public double value()
{
return value;
}
-
-
+
+
@Override
public void setTo(double value)
{
this.value = value;
}
-
+
}
diff --git a/src/mightypork/utils/math/constraints/rect/PluggableRectBound.java b/src/mightypork/utils/math/constraints/rect/PluggableRectBound.java
index c29a0e9..acf94d8 100644
--- a/src/mightypork/utils/math/constraints/rect/PluggableRectBound.java
+++ b/src/mightypork/utils/math/constraints/rect/PluggableRectBound.java
@@ -3,14 +3,14 @@ package mightypork.utils.math.constraints.rect;
/**
* Pluggable rect bound
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public interface PluggableRectBound extends RectBound {
-
+
/**
* @param rect context to set
*/
abstract void setRect(RectBound rect);
-
+
}
diff --git a/src/mightypork/utils/math/constraints/rect/Rect.java b/src/mightypork/utils/math/constraints/rect/Rect.java
index d8b8ea7..dc20741 100644
--- a/src/mightypork/utils/math/constraints/rect/Rect.java
+++ b/src/mightypork/utils/math/constraints/rect/Rect.java
@@ -18,166 +18,166 @@ import mightypork.utils.math.constraints.vect.VectConst;
/**
* Common methods for all kinds of Rects
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public abstract class Rect implements RectBound, CachedDigestable {
-
+
public static final RectConst ZERO = new RectConst(0, 0, 0, 0);
public static final RectConst ONE = new RectConst(0, 0, 1, 1);
-
-
+
+
@FactoryMethod
public static Rect make(Num width, Num height)
{
final Vect origin = Vect.ZERO;
final Vect size = Vect.make(width, height);
-
+
return Rect.make(origin, size);
}
-
-
+
+
public static Rect make(Vect size)
{
return Rect.make(size.xn(), size.yn());
}
-
-
+
+
@FactoryMethod
public static Rect make(RectBound bound)
{
return new RectProxy(bound);
}
-
-
+
+
@FactoryMethod
public static Rect make(Num x, Num y, Num width, Num height)
{
final Vect origin = Vect.make(x, y);
final Vect size = Vect.make(width, height);
-
+
return Rect.make(origin, size);
}
-
-
+
+
@FactoryMethod
public static Rect make(Vect origin, Num width, Num height)
{
return make(origin, Vect.make(width, height));
}
-
-
+
+
@FactoryMethod
public static Rect make(final Vect origin, final Vect size)
{
return new RectVectAdapter(origin, size);
}
-
-
+
+
@FactoryMethod
public static RectConst make(NumConst width, NumConst height)
{
final VectConst origin = Vect.ZERO;
final VectConst size = Vect.make(width, height);
-
+
return Rect.make(origin, size);
}
-
-
+
+
public static Rect make(Num side)
{
return make(side, side);
}
-
-
+
+
public static RectConst make(NumConst side)
{
return make(side, side);
}
-
-
+
+
public static RectConst make(double side)
{
return make(side, side);
}
-
-
+
+
@FactoryMethod
public static RectConst make(NumConst x, NumConst y, NumConst width, NumConst height)
{
final VectConst origin = Vect.make(x, y);
final VectConst size = Vect.make(width, height);
-
+
return Rect.make(origin, size);
}
-
-
+
+
@FactoryMethod
public static RectConst make(final VectConst origin, final VectConst size)
{
return new RectConst(origin, size);
}
-
-
+
+
@FactoryMethod
public static RectConst make(double width, double height)
{
return Rect.make(0, 0, width, height);
}
-
-
+
+
@FactoryMethod
public static RectConst make(double x, double y, double width, double height)
{
return new RectConst(x, y, width, height);
}
-
-
+
+
@FactoryMethod
public static RectVar makeVar(double x, double y)
{
return Rect.makeVar(0, 0, x, y);
}
-
-
+
+
@FactoryMethod
public static RectVar makeVar(Rect copied)
{
return Rect.makeVar(copied.origin(), copied.size());
}
-
-
+
+
@FactoryMethod
public static RectVar makeVar(Vect origin, Vect size)
{
return Rect.makeVar(origin.x(), origin.y(), size.x(), size.y());
}
-
-
+
+
@FactoryMethod
public static RectVar makeVar(double x, double y, double width, double height)
{
return new RectVar(x, y, width, height);
}
-
-
+
+
@FactoryMethod
public static RectVar makeVar()
{
return Rect.makeVar(Rect.ZERO);
}
-
+
private Vect p_bl;
private Vect p_bc;
private Vect p_br;
// p_t == origin
private Vect p_tc;
private Vect p_tr;
-
+
private Vect p_cl;
private Vect p_cc;
private Vect p_cr;
-
+
private Num p_x;
private Num p_y;
private Num p_w;
@@ -192,20 +192,20 @@ public abstract class Rect implements RectBound, CachedDigestable {
private Rect p_edge_b;
private Rect p_axis_v;
private Rect p_axis_h;
-
+
private final DigestCache dc = new DigestCache() {
-
+
@Override
protected RectDigest createDigest()
{
return new RectDigest(Rect.this);
}
};
-
-
+
+
/**
* Get a copy of current value
- *
+ *
* @return copy
*/
public RectConst freeze()
@@ -213,135 +213,135 @@ public abstract class Rect implements RectBound, CachedDigestable {
// must NOT call RectVal.make, it'd cause infinite recursion.
return new RectConst(this);
}
-
-
+
+
/**
* Wrap this constraint into a caching adapter. Value will stay fixed (ie.
* no re-calculations) until cache receives a poll() call.
- *
+ *
* @return the caching adapter
*/
public RectCache cached()
{
return new RectCache(this);
}
-
-
+
+
@Override
public RectDigest digest()
{
return dc.digest();
}
-
-
+
+
@Override
public void enableDigestCaching(boolean yes)
{
dc.enableDigestCaching(yes);
}
-
-
+
+
@Override
public boolean isDigestCachingEnabled()
{
return dc.isDigestCachingEnabled();
}
-
-
+
+
@Override
public void markDigestDirty()
{
dc.markDigestDirty();
}
-
-
+
+
@Override
public Rect getRect()
{
return this;
}
-
-
+
+
@Override
public String toString()
{
return String.format("Rect { at %s , size %s }", origin(), size());
}
-
-
+
+
/**
* Origin (top left).
- *
+ *
* @return origin (top left)
*/
public abstract Vect origin();
-
-
+
+
/**
* Size (spanning right down from Origin).
- *
+ *
* @return size vector
*/
public abstract Vect size();
-
-
+
+
/**
* Add vector to origin
- *
+ *
* @param move offset vector
* @return result
*/
public Rect move(final Vect move)
{
return new Rect() {
-
+
private final Rect t = Rect.this;
-
-
+
+
@Override
public Vect size()
{
return t.size();
}
-
-
+
+
@Override
public Vect origin()
{
return t.origin().add(move);
}
-
+
};
}
-
-
+
+
public Rect moveX(Num x)
{
return move(x, Num.ZERO);
}
-
-
+
+
public Rect moveY(Num y)
{
return move(Num.ZERO, y);
}
-
-
+
+
public Rect moveX(double x)
{
return move(x, 0);
}
-
-
+
+
public Rect moveY(double y)
{
return move(0, y);
}
-
-
+
+
/**
* Add X and Y to origin
- *
+ *
* @param x x to add
* @param y y to add
* @return result
@@ -349,67 +349,67 @@ public abstract class Rect implements RectBound, CachedDigestable {
public Rect move(final double x, final double y)
{
return new Rect() {
-
+
private final Rect t = Rect.this;
-
-
+
+
@Override
public Vect size()
{
return t.size();
}
-
-
+
+
@Override
public Vect origin()
{
return t.origin().add(x, y);
}
-
+
};
}
-
-
+
+
public Rect move(final Num x, final Num y)
{
return new Rect() {
-
+
private final Rect t = Rect.this;
-
-
+
+
@Override
public Vect size()
{
return t.size();
}
-
-
+
+
@Override
public Vect origin()
{
return t.origin().add(x, y);
}
-
+
};
}
-
-
+
+
/**
* Shrink to sides
- *
+ *
* @param shrink shrink size (horizontal and vertical)
* @return result
*/
-
+
public Rect shrink(Vect shrink)
{
return shrink(shrink.x(), shrink.y());
}
-
-
+
+
/**
* Shrink to all sides
- *
+ *
* @param shrink shrink
* @return result
*/
@@ -417,11 +417,11 @@ public abstract class Rect implements RectBound, CachedDigestable {
{
return shrink(shrink, shrink, shrink, shrink);
}
-
-
+
+
/**
* Shrink to all sides
- *
+ *
* @param shrink shrink
* @return result
*/
@@ -429,11 +429,11 @@ public abstract class Rect implements RectBound, CachedDigestable {
{
return shrink(shrink, shrink, shrink, shrink);
}
-
-
+
+
/**
* Shrink to sides at sides
- *
+ *
* @param x horizontal shrink
* @param y vertical shrink
* @return result
@@ -442,17 +442,17 @@ public abstract class Rect implements RectBound, CachedDigestable {
{
return shrink(x, x, y, y);
}
-
-
+
+
public Rect shrink(Num x, Num y)
{
return shrink(x, x, y, y);
}
-
-
+
+
/**
* Shrink the rect
- *
+ *
* @param left shrink
* @param right shrink
* @param top shrink
@@ -463,107 +463,107 @@ public abstract class Rect implements RectBound, CachedDigestable {
{
return grow(-left, -right, -top, -bottom);
}
-
-
+
+
public Rect shrinkLeft(final double shrink)
{
return growLeft(-shrink);
}
-
-
+
+
public Rect shrinkRight(final double shrink)
{
return growRight(-shrink);
}
-
-
+
+
public Rect shrinkTop(final double shrink)
{
return growUp(-shrink);
}
-
-
+
+
public Rect shrinkBottom(final double shrink)
{
return growDown(-shrink);
}
-
-
+
+
public Rect growLeft(final double shrink)
{
return grow(shrink, 0, 0, 0);
}
-
-
+
+
public Rect growRight(final double shrink)
{
return grow(0, shrink, 0, 0);
}
-
-
+
+
public Rect growUp(final double shrink)
{
return grow(0, 0, shrink, 0);
}
-
-
+
+
public Rect growDown(final double shrink)
{
return grow(0, 0, 0, shrink);
}
-
-
+
+
public Rect shrinkLeft(final Num shrink)
{
return shrink(shrink, Num.ZERO, Num.ZERO, Num.ZERO);
}
-
-
+
+
public Rect shrinkRight(final Num shrink)
{
return shrink(Num.ZERO, shrink, Num.ZERO, Num.ZERO);
}
-
-
+
+
public Rect shrinkTop(final Num shrink)
{
return shrink(Num.ZERO, Num.ZERO, shrink, Num.ZERO);
}
-
-
+
+
public Rect shrinkBottom(final Num shrink)
{
return shrink(Num.ZERO, Num.ZERO, Num.ZERO, shrink);
}
-
-
+
+
public Rect growLeft(final Num shrink)
{
return grow(shrink, Num.ZERO, Num.ZERO, Num.ZERO);
}
-
-
+
+
public Rect growRight(final Num shrink)
{
return grow(Num.ZERO, shrink, Num.ZERO, Num.ZERO);
}
-
-
+
+
public Rect growUp(final Num shrink)
{
return grow(Num.ZERO, Num.ZERO, shrink, Num.ZERO);
}
-
-
+
+
public Rect growDown(final Num shrink)
{
return grow(Num.ZERO, Num.ZERO, Num.ZERO, shrink);
}
-
-
+
+
/**
* Grow to sides
- *
+ *
* @param grow grow size (added to each side)
* @return grown copy
*/
@@ -571,11 +571,11 @@ public abstract class Rect implements RectBound, CachedDigestable {
{
return grow(grow.x(), grow.y());
}
-
-
+
+
/**
* Grow to all sides
- *
+ *
* @param grow grow
* @return result
*/
@@ -583,11 +583,11 @@ public abstract class Rect implements RectBound, CachedDigestable {
{
return grow(grow, grow, grow, grow);
}
-
-
+
+
/**
* Grow to all sides
- *
+ *
* @param grow grow
* @return result
*/
@@ -595,11 +595,11 @@ public abstract class Rect implements RectBound, CachedDigestable {
{
return grow(grow, grow, grow, grow);
}
-
-
+
+
/**
* Grow to sides
- *
+ *
* @param x horizontal grow
* @param y vertical grow
* @return result
@@ -608,17 +608,17 @@ public abstract class Rect implements RectBound, CachedDigestable {
{
return grow(x, x, y, y);
}
-
-
+
+
public Rect grow(Num x, Num y)
{
return grow(x, x, y, y);
}
-
-
+
+
/**
* Grow the rect
- *
+ *
* @param left growth
* @param right growth
* @param top growth
@@ -628,324 +628,324 @@ public abstract class Rect implements RectBound, CachedDigestable {
public Rect grow(final double left, final double right, final double top, final double bottom)
{
return new Rect() {
-
+
private final Rect t = Rect.this;
-
-
+
+
@Override
public Vect size()
{
return t.size().add(left + right, top + bottom);
}
-
-
+
+
@Override
public Vect origin()
{
return t.origin().sub(left, top);
}
-
+
};
}
-
-
+
+
public Rect shrink(final Num left, final Num right, final Num top, final Num bottom)
{
return new Rect() {
-
+
private final Rect t = Rect.this;
-
-
+
+
@Override
public Vect size()
{
return t.size().sub(left.add(right), top.add(bottom));
}
-
-
+
+
@Override
public Vect origin()
{
return t.origin().add(left, top);
}
-
+
};
}
-
-
+
+
public Rect grow(final Num left, final Num right, final Num top, final Num bottom)
{
-
+
return new Rect() {
-
+
private final Rect t = Rect.this;
-
-
+
+
@Override
public Vect size()
{
return t.size().add(left.add(right), top.add(bottom));
}
-
-
+
+
@Override
public Vect origin()
{
return t.origin().sub(left, top);
}
-
+
};
}
-
-
+
+
/**
* Round coords
- *
+ *
* @return result
*/
public Rect round()
{
-
+
return new Rect() {
-
+
private final Rect t = Rect.this;
-
-
+
+
@Override
public Vect size()
{
return t.size().round();
}
-
-
+
+
@Override
public Vect origin()
{
return t.origin().round();
}
-
+
};
}
-
-
+
+
/**
* Round coords down
- *
+ *
* @return result
*/
public Rect floor()
{
-
+
return new Rect() {
-
+
private final Rect t = Rect.this;
-
-
+
+
@Override
public Vect size()
{
return t.size().floor();
}
-
-
+
+
@Override
public Vect origin()
{
return t.origin().floor();
}
-
+
};
}
-
-
+
+
/**
* Round coords up
- *
+ *
* @return result
*/
public Rect ceil()
{
-
+
return new Rect() {
-
+
private final Rect t = Rect.this;
-
-
+
+
@Override
public Vect size()
{
return t.size().ceil();
}
-
-
+
+
@Override
public Vect origin()
{
return t.origin().ceil();
}
-
+
};
}
-
-
+
+
public Num x()
{
return p_x != null ? p_x : (p_x = origin().xn());
}
-
-
+
+
public Num y()
{
return p_y != null ? p_y : (p_y = origin().yn());
}
-
-
+
+
public Num width()
{
return p_w != null ? p_w : (p_w = size().xn());
}
-
-
+
+
public Num height()
{
return p_h != null ? p_h : (p_h = size().yn());
}
-
-
+
+
public Num left()
{
return p_l != null ? p_l : (p_l = origin().xn());
}
-
-
+
+
public Num right()
{
return p_r != null ? p_r : (p_r = origin().xn().add(size().xn()));
}
-
-
+
+
public Num top()
{
return p_t != null ? p_t : (p_t = origin().yn());
}
-
-
+
+
public Num bottom()
{
return p_b != null ? p_b : (p_b = origin().yn().add(size().yn()));
}
-
-
+
+
public Vect topLeft()
{
return origin();
}
-
-
+
+
public Vect topCenter()
{
return p_tc != null ? p_tc : (p_tc = origin().add(size().xn().half(), Num.ZERO));
}
-
-
+
+
public Vect topRight()
{
return p_tr != null ? p_tr : (p_tr = origin().add(size().xn(), Num.ZERO));
}
-
-
+
+
public Vect centerLeft()
{
return p_cl != null ? p_cl : (p_cl = origin().add(Num.ZERO, size().yn().half()));
}
-
-
+
+
public Vect center()
{
return p_cc != null ? p_cc : (p_cc = origin().add(size().half()));
}
-
-
+
+
public Vect centerRight()
{
return p_cr != null ? p_cr : (p_cr = origin().add(size().xn(), size().yn().half()));
}
-
-
+
+
public Vect bottomLeft()
{
return p_bl != null ? p_bl : (p_bl = origin().add(Num.ZERO, size().yn()));
}
-
-
+
+
public Vect bottomCenter()
{
return p_bc != null ? p_bc : (p_bc = origin().add(size().xn().half(), size().yn()));
}
-
-
+
+
public Vect bottomRight()
{
return p_br != null ? p_br : (p_br = origin().add(size().xn(), size().yn()));
}
-
-
+
+
public Rect leftEdge()
{
return p_edge_l != null ? p_edge_l : (p_edge_l = topLeft().expand(Num.ZERO, Num.ZERO, Num.ZERO, height()));
}
-
-
+
+
public Rect rightEdge()
{
return p_edge_r != null ? p_edge_r : (p_edge_r = topRight().expand(Num.ZERO, Num.ZERO, Num.ZERO, height()));
}
-
-
+
+
public Rect topEdge()
{
return p_edge_t != null ? p_edge_t : (p_edge_t = topLeft().expand(Num.ZERO, width(), Num.ZERO, Num.ZERO));
}
-
-
+
+
public Rect bottomEdge()
{
return p_edge_b != null ? p_edge_b : (p_edge_b = bottomLeft().expand(Num.ZERO, width(), Num.ZERO, Num.ZERO));
}
-
-
+
+
public Rect axisV()
{
return p_axis_v != null ? p_axis_v : (p_axis_v = topCenter().expand(Num.ZERO, Num.ZERO, Num.ZERO, height()));
}
-
-
+
+
public Rect axisH()
{
return p_axis_h != null ? p_axis_h : (p_axis_h = centerLeft().expand(Num.ZERO, width(), Num.ZERO, Num.ZERO));
}
-
-
+
+
/**
* Center to given point
- *
+ *
* @param point new center
* @return centered
*/
public Rect centerTo(final Vect point)
{
return new Rect() {
-
+
Rect t = Rect.this;
-
-
+
+
@Override
public Vect size()
{
return t.size();
}
-
-
+
+
@Override
public Vect origin()
{
@@ -953,11 +953,11 @@ public abstract class Rect implements RectBound, CachedDigestable {
}
};
}
-
-
+
+
/**
* Check if point is inside this rectangle
- *
+ *
* @param point point to test
* @return is inside
*/
@@ -965,19 +965,19 @@ public abstract class Rect implements RectBound, CachedDigestable {
{
final double x = point.x();
final double y = point.y();
-
+
final double x1 = origin().x();
final double y1 = origin().y();
final double x2 = x1 + size().x();
final double y2 = y1 + size().y();
-
+
return x >= x1 && y >= y1 && x <= x2 && y <= y2;
}
-
-
+
+
/**
* Center to given rect's center
- *
+ *
* @param parent rect to center to
* @return centered
*/
@@ -985,12 +985,12 @@ public abstract class Rect implements RectBound, CachedDigestable {
{
return centerTo(parent.center());
}
-
-
+
+
/**
* Get TiledRect with given number of evenly spaced tiles. Tile indexes are
* one-based by default.
- *
+ *
* @param horizontal horizontal tile count
* @param vertical vertical tile count
* @return tiled rect
@@ -999,12 +999,12 @@ public abstract class Rect implements RectBound, CachedDigestable {
{
return new TiledRect(this, horizontal, vertical);
}
-
-
+
+
/**
* Get TiledRect with N columns and 1 row. Column indexes are one-based by
* default.
- *
+ *
* @param columns number of columns
* @return tiled rect
*/
@@ -1012,12 +1012,12 @@ public abstract class Rect implements RectBound, CachedDigestable {
{
return new TiledRect(this, columns, 1);
}
-
-
+
+
/**
* Get TiledRect with N rows and 1 column. Row indexes are one-based by
* default.
- *
+ *
* @param rows number of columns
* @return tiled rect
*/
@@ -1025,11 +1025,11 @@ public abstract class Rect implements RectBound, CachedDigestable {
{
return new TiledRect(this, 1, rows);
}
-
-
+
+
/**
* Check for intersection
- *
+ *
* @param other other rect
* @return true if they intersect
*/
@@ -1039,23 +1039,23 @@ public abstract class Rect implements RectBound, CachedDigestable {
double th = this.size().y();
double rw = other.size().x();
double rh = other.size().y();
-
+
if (rw <= 0 || rh <= 0 || tw <= 0 || th <= 0) {
return false;
}
-
+
final double tx = this.origin().x();
final double ty = this.origin().y();
final double rx = other.origin().x();
final double ry = other.origin().y();
-
+
rw += rx;
rh += ry;
tw += tx;
th += ty;
-
+
// overflow || intersect
return ((rw < rx || rw > tx) && (rh < ry || rh > ty) && (tw < tx || tw > rx) && (th < ty || th > ry));
}
-
+
}
diff --git a/src/mightypork/utils/math/constraints/rect/RectBound.java b/src/mightypork/utils/math/constraints/rect/RectBound.java
index 900913b..84d7859 100644
--- a/src/mightypork/utils/math/constraints/rect/RectBound.java
+++ b/src/mightypork/utils/math/constraints/rect/RectBound.java
@@ -4,11 +4,11 @@ package mightypork.utils.math.constraints.rect;
/**
* Interface for something that has/is a Rect. Rect itself implements it as
* well.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public interface RectBound {
-
+
/**
* @return the Rect value
*/
diff --git a/src/mightypork/utils/math/constraints/rect/RectConst.java b/src/mightypork/utils/math/constraints/rect/RectConst.java
index c1195a8..9f74fb5 100644
--- a/src/mightypork/utils/math/constraints/rect/RectConst.java
+++ b/src/mightypork/utils/math/constraints/rect/RectConst.java
@@ -11,14 +11,14 @@ import mightypork.utils.math.constraints.vect.VectConst;
* Rectangle with constant bounds, that can never change.
* It's arranged so that operations with constant arguments yield constant
* results.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class RectConst extends Rect {
-
+
private final VectConst pos;
private final VectConst size;
-
+
// cached with lazy loading
private NumConst v_b;
private NumConst v_r;
@@ -40,45 +40,48 @@ public class RectConst extends Rect {
private RectConst v_ceil;
private RectConst v_axis_v;
private RectConst v_axis_h;
-
-
+
+
/**
* Create at given origin, with given size.
- *
+ *
* @param x
* @param y
* @param width
* @param height
*/
- RectConst(double x, double y, double width, double height) {
+ RectConst(double x, double y, double width, double height)
+ {
this.pos = Vect.make(x, y);
this.size = Vect.make(width, height);
}
-
-
+
+
/**
* Create at given origin, with given size.
- *
+ *
* @param origin
* @param size
*/
- RectConst(Vect origin, Vect size) {
+ RectConst(Vect origin, Vect size)
+ {
this.pos = origin.freeze();
this.size = size.freeze();
}
-
-
+
+
/**
* Create at given origin, with given size.
- *
+ *
* @param another other coord
*/
- RectConst(Rect another) {
+ RectConst(Rect another)
+ {
this.pos = another.origin().freeze();
this.size = another.size().freeze();
}
-
-
+
+
/**
* @deprecated it's useless to copy a constant
*/
@@ -88,394 +91,394 @@ public class RectConst extends Rect {
{
return this; // already constant
}
-
-
+
+
@Override
public RectDigest digest()
{
return (digest != null) ? digest : (digest = super.digest());
}
-
-
+
+
@Override
public VectConst origin()
{
return pos;
}
-
-
+
+
@Override
public VectConst size()
{
return size;
}
-
-
+
+
@Override
public RectConst move(Vect move)
{
return move(move.x(), move.y());
}
-
-
+
+
@Override
public RectConst move(double x, double y)
{
return Rect.make(pos.add(x, y), size);
}
-
-
+
+
public RectConst move(NumConst x, NumConst y)
{
return super.move(x, y).freeze();
}
-
-
+
+
@Override
public RectConst shrink(double left, double right, double top, double bottom)
{
return super.shrink(left, right, top, bottom).freeze();
-
+
}
-
-
+
+
@Override
public RectConst grow(double left, double right, double top, double bottom)
{
return super.grow(left, right, top, bottom).freeze();
}
-
-
+
+
@Override
public RectConst round()
{
return (v_round != null) ? v_round : (v_round = Rect.make(pos.round(), size.round()));
}
-
-
+
+
@Override
public RectConst floor()
{
return (v_floor != null) ? v_floor : (v_floor = Rect.make(pos.floor(), size.floor()));
}
-
-
+
+
@Override
public RectConst ceil()
{
return (v_ceil != null) ? v_ceil : (v_ceil = Rect.make(pos.ceil(), size.ceil()));
}
-
-
+
+
@Override
public NumConst x()
{
return pos.xn();
}
-
-
+
+
@Override
public NumConst y()
{
return pos.yn();
}
-
-
+
+
@Override
public NumConst width()
{
return size.xn();
}
-
-
+
+
@Override
public NumConst height()
{
return size.yn();
}
-
-
+
+
@Override
public NumConst left()
{
return pos.xn();
}
-
-
+
+
@Override
public NumConst right()
{
return (v_r != null) ? v_r : (v_r = super.right().freeze());
}
-
-
+
+
@Override
public NumConst top()
{
return pos.yn();
}
-
-
+
+
@Override
public NumConst bottom()
{
return (v_b != null) ? v_b : (v_b = super.bottom().freeze());
}
-
-
+
+
@Override
public VectConst topLeft()
{
return pos;
}
-
-
+
+
@Override
public VectConst topCenter()
{
return (v_tc != null) ? v_tc : (v_tc = super.topCenter().freeze());
}
-
-
+
+
@Override
public VectConst topRight()
{
return (v_tr != null) ? v_tr : (v_tr = super.topRight().freeze());
}
-
-
+
+
@Override
public VectConst centerLeft()
{
return (v_cl != null) ? v_cl : (v_cl = super.centerLeft().freeze());
}
-
-
+
+
@Override
public VectConst center()
{
return (v_c != null) ? v_c : (v_c = super.center().freeze());
}
-
-
+
+
@Override
public VectConst centerRight()
{
return (v_cr != null) ? v_cr : (v_cr = super.centerRight().freeze());
}
-
-
+
+
@Override
public VectConst bottomLeft()
{
return (v_bl != null) ? v_bl : (v_bl = super.bottomLeft().freeze());
}
-
-
+
+
@Override
public VectConst bottomCenter()
{
return (v_bc != null) ? v_bc : (v_bc = super.bottomCenter().freeze());
}
-
-
+
+
@Override
public VectConst bottomRight()
{
return (v_br != null) ? v_br : (v_br = super.bottomRight().freeze());
}
-
-
+
+
@Override
public RectConst leftEdge()
{
return (v_edge_l != null) ? v_edge_l : (v_edge_l = super.leftEdge().freeze());
}
-
-
+
+
@Override
public RectConst rightEdge()
{
return (v_edge_r != null) ? v_edge_r : (v_edge_r = super.rightEdge().freeze());
}
-
-
+
+
@Override
public RectConst topEdge()
{
return (v_edge_t != null) ? v_edge_t : (v_edge_t = super.topEdge().freeze());
}
-
-
+
+
@Override
public RectConst bottomEdge()
{
return (v_edge_b != null) ? v_edge_b : (v_edge_b = super.bottomEdge().freeze());
}
-
-
+
+
@Override
public Rect axisV()
{
return (v_axis_v != null) ? v_axis_v : (v_axis_v = super.axisV().freeze());
}
-
-
+
+
@Override
public Rect axisH()
{
return (v_axis_h != null) ? v_axis_h : (v_axis_h = super.axisH().freeze());
}
-
-
+
+
@Override
public Rect shrink(Vect shrink)
{
return super.shrink(shrink);
}
-
-
+
+
@Override
public RectConst shrink(double x, double y)
{
return super.shrink(x, y).freeze();
}
-
-
+
+
public RectConst shrink(NumConst left, NumConst right, NumConst top, NumConst bottom)
{
return super.shrink(left, right, top, bottom).freeze();
}
-
-
+
+
public RectConst grow(NumConst left, NumConst right, NumConst top, NumConst bottom)
{
return super.grow(left, right, top, bottom).freeze();
}
-
-
+
+
@Override
public RectConst shrinkLeft(double shrink)
{
return super.shrinkLeft(shrink).freeze();
}
-
-
+
+
@Override
public RectConst shrinkRight(double shrink)
{
return super.shrinkRight(shrink).freeze();
}
-
-
+
+
@Override
public RectConst shrinkTop(double shrink)
{
return super.shrinkTop(shrink).freeze();
}
-
-
+
+
@Override
public RectConst shrinkBottom(double shrink)
{
return super.shrinkBottom(shrink).freeze();
}
-
-
+
+
@Override
public RectConst growLeft(double shrink)
{
return super.growLeft(shrink).freeze();
}
-
-
+
+
@Override
public RectConst growRight(double shrink)
{
return super.growRight(shrink).freeze();
}
-
-
+
+
@Override
public RectConst growUp(double shrink)
{
return super.growUp(shrink).freeze();
}
-
-
+
+
@Override
public RectConst growDown(double shrink)
{
return super.growDown(shrink).freeze();
}
-
-
+
+
public RectConst shrinkLeft(NumConst shrink)
{
return super.shrinkLeft(shrink).freeze();
}
-
-
+
+
public RectConst shrinkRight(NumConst shrink)
{
return super.shrinkRight(shrink).freeze();
}
-
-
+
+
public RectConst shrinkTop(NumConst shrink)
{
return super.shrinkTop(shrink).freeze();
}
-
-
+
+
public RectConst shrinkBottom(NumConst shrink)
{
return super.shrinkBottom(shrink).freeze();
}
-
-
+
+
public RectConst growLeft(NumConst shrink)
{
return super.growLeft(shrink).freeze();
}
-
-
+
+
public RectConst growRight(NumConst shrink)
{
return super.growRight(shrink).freeze();
}
-
-
+
+
public RectConst growUp(NumConst shrink)
{
return super.growUp(shrink).freeze();
}
-
-
+
+
public RectConst growBottom(NumConst shrink)
{
return super.growDown(shrink).freeze();
}
-
-
+
+
public RectConst centerTo(VectConst point)
{
return super.centerTo(point).freeze();
}
-
-
+
+
public RectConst centerTo(RectConst parent)
{
return super.centerTo(parent).freeze();
}
-
-
+
+
public RectConst shrink(NumConst x, NumConst y)
{
return super.shrink(x, y).freeze();
}
-
-
+
+
public RectConst grow(NumConst x, NumConst y)
{
return super.grow(x, y).freeze();
diff --git a/src/mightypork/utils/math/constraints/rect/builders/TiledRect.java b/src/mightypork/utils/math/constraints/rect/builders/TiledRect.java
index 0b63f4f..49849d7 100644
--- a/src/mightypork/utils/math/constraints/rect/builders/TiledRect.java
+++ b/src/mightypork/utils/math/constraints/rect/builders/TiledRect.java
@@ -9,46 +9,47 @@ import mightypork.utils.math.constraints.vect.Vect;
/**
* Utility for cutting rect into evenly sized cells.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class TiledRect extends RectProxy {
-
+
final private int tilesY;
final private int tilesX;
final private Num perRow;
final private Num perCol;
-
+
/** Left top tile */
private Rect aTile;
-
-
- public TiledRect(Rect source, int horizontal, int vertical) {
+
+
+ public TiledRect(Rect source, int horizontal, int vertical)
+ {
super(source);
this.tilesX = horizontal;
this.tilesY = vertical;
-
+
this.perRow = height().div(vertical);
this.perCol = width().div(horizontal);
-
+
this.aTile = Rect.make(origin(), perCol, perRow);
}
-
-
+
+
/**
* Set tile overlap. Applies only to tile, not span.
- *
+ *
* @param overlap how far to overlap to neighbouring tiles on all sides
*/
public void setOverlap(double overlap)
{
aTile = aTile.grow(overlap);
}
-
-
+
+
/**
* Get a tile.
- *
+ *
* @param x x position
* @param y y position
* @return tile
@@ -59,18 +60,18 @@ public class TiledRect extends RectProxy {
if (x >= tilesX || x < 0) {
throw new IndexOutOfBoundsException("X coordinate out fo range: " + x);
}
-
+
if (y >= tilesY || y < 0) {
throw new IndexOutOfBoundsException("Y coordinate out of range: " + y);
}
-
+
return aTile.move(perCol.mul(x), perRow.mul(y));
}
-
-
+
+
/**
* Get a span (tile spanning across multiple cells)
- *
+ *
* @param x x start position
* @param y y start position
* @param size_x horizontal size (columns)
@@ -82,28 +83,28 @@ public class TiledRect extends RectProxy {
{
final int x_to = x + size_x - 1;
final int y_to = y + size_y - 1;
-
+
if (size_x <= 0 || size_y <= 0) {
throw new IndexOutOfBoundsException("Size must be > 0.");
}
-
+
if (x >= tilesX || x < 0 || x_to >= tilesX || x_to < 0) {
throw new IndexOutOfBoundsException("X coordinate(s) out of range.");
}
-
+
if (y >= tilesY || y < 0 || y_to >= tilesY || y_to < 0) {
throw new IndexOutOfBoundsException("Y coordinate(s) out of range.");
}
-
+
final Vect orig = origin().add(perCol.mul(x), perRow.mul(y));
-
+
return Rect.make(orig, perCol.mul(size_x), perRow.mul(size_y));
}
-
-
+
+
/**
* Get n-th column
- *
+ *
* @param n column index
* @return the column tile
* @throws IndexOutOfBoundsException when invalid index is specified.
@@ -112,11 +113,11 @@ public class TiledRect extends RectProxy {
{
return tile(n, 0);
}
-
-
+
+
/**
* Get n-th row
- *
+ *
* @param n row index
* @return the row rect
* @throws IndexOutOfBoundsException when invalid index is specified.
diff --git a/src/mightypork/utils/math/constraints/rect/caching/AbstractRectCache.java b/src/mightypork/utils/math/constraints/rect/caching/AbstractRectCache.java
index 75c27a9..33e69fe 100644
--- a/src/mightypork/utils/math/constraints/rect/caching/AbstractRectCache.java
+++ b/src/mightypork/utils/math/constraints/rect/caching/AbstractRectCache.java
@@ -15,60 +15,61 @@ import mightypork.utils.math.constraints.rect.var.RectVar;
* Values are held in a caching VectVar, and digest caching is enabled by
* default.
*
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public abstract class AbstractRectCache extends RectAdapter implements CachedConstraint {
-
+
private final RectVar cache = Rect.makeVar();
private boolean inited = false;
private boolean cachingEnabled = true;
-
-
- public AbstractRectCache() {
+
+
+ public AbstractRectCache()
+ {
enableDigestCaching(true); // it changes only on poll
}
-
-
+
+
@Override
protected final Rect getSource()
{
if (!inited) poll();
-
+
return (cachingEnabled ? cache : getCacheSource());
}
-
-
+
+
@Override
public final void poll()
{
inited = true;
-
+
// poll source
final Rect source = getCacheSource();
source.markDigestDirty(); // poll cached
-
+
// store source value
cache.setTo(source);
-
+
markDigestDirty();
-
+
onConstraintChanged();
}
-
-
+
+
@Override
public final void enableCaching(boolean yes)
{
cachingEnabled = yes;
enableDigestCaching(yes);
}
-
-
+
+
@Override
public final boolean isCachingEnabled()
{
return cachingEnabled;
}
-
+
}
diff --git a/src/mightypork/utils/math/constraints/rect/caching/RectCache.java b/src/mightypork/utils/math/constraints/rect/caching/RectCache.java
index db1b858..9f386c7 100644
--- a/src/mightypork/utils/math/constraints/rect/caching/RectCache.java
+++ b/src/mightypork/utils/math/constraints/rect/caching/RectCache.java
@@ -6,29 +6,30 @@ import mightypork.utils.math.constraints.rect.Rect;
/**
* Rect cache implementation
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class RectCache extends AbstractRectCache {
-
+
private final Rect source;
-
-
- public RectCache(Rect source) {
+
+
+ public RectCache(Rect source)
+ {
this.source = source;
}
-
-
+
+
@Override
public final Rect getCacheSource()
{
return source;
}
-
-
+
+
@Override
public void onConstraintChanged()
{
}
-
+
}
diff --git a/src/mightypork/utils/math/constraints/rect/caching/RectDigest.java b/src/mightypork/utils/math/constraints/rect/caching/RectDigest.java
index 3007b9b..e5aee62 100644
--- a/src/mightypork/utils/math/constraints/rect/caching/RectDigest.java
+++ b/src/mightypork/utils/math/constraints/rect/caching/RectDigest.java
@@ -5,35 +5,37 @@ import mightypork.utils.math.constraints.rect.Rect;
public class RectDigest {
-
+
public final double x;
public final double y;
public final double width;
public final double height;
-
+
public final double left;
public final double right;
public final double top;
public final double bottom;
-
-
- public RectDigest(Rect rect) {
+
+
+ public RectDigest(Rect rect)
+ {
this.x = rect.origin().x();
this.y = rect.origin().y();
-
+
this.width = rect.size().x();
this.height = rect.size().y();
-
+
this.left = x;
this.right = x + width;
this.top = y;
this.bottom = y + height;
}
-
-
+
+
@Override
public String toString()
{
- return String.format("Rect{ at: (%.1f, %.1f), size: (%.1f, %.1f), bounds: L %.1f R %.1f T %.1f B %.1f }", x, y, width, height, left, right, top, bottom);
+ return String
+ .format("Rect{ at: (%.1f, %.1f), size: (%.1f, %.1f), bounds: L %.1f R %.1f T %.1f B %.1f }", x, y, width, height, left, right, top, bottom);
}
}
diff --git a/src/mightypork/utils/math/constraints/rect/proxy/RectAdapter.java b/src/mightypork/utils/math/constraints/rect/proxy/RectAdapter.java
index cd1cd85..9b5b2ea 100644
--- a/src/mightypork/utils/math/constraints/rect/proxy/RectAdapter.java
+++ b/src/mightypork/utils/math/constraints/rect/proxy/RectAdapter.java
@@ -9,50 +9,50 @@ import mightypork.utils.math.constraints.vect.proxy.VectAdapter;
/**
* Rect proxy with abstract method for plugging in / generating rect
* dynamically.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public abstract class RectAdapter extends Rect {
-
+
// adapters are needed in case the vect returned from source changes
// (is replaced). This way, references to origin and rect will stay intact.
-
+
private final VectAdapter originAdapter = new VectAdapter() {
-
+
@Override
protected Vect getSource()
{
return RectAdapter.this.getSource().origin();
}
};
-
+
private final VectAdapter sizeAdapter = new VectAdapter() {
-
+
@Override
protected Vect getSource()
{
return RectAdapter.this.getSource().size();
}
};
-
-
+
+
/**
* @return the proxied coord
*/
protected abstract Rect getSource();
-
-
+
+
@Override
public Vect origin()
{
return originAdapter;
}
-
-
+
+
@Override
public Vect size()
{
return sizeAdapter;
}
-
+
}
diff --git a/src/mightypork/utils/math/constraints/rect/proxy/RectProxy.java b/src/mightypork/utils/math/constraints/rect/proxy/RectProxy.java
index 415f30f..db8b984 100644
--- a/src/mightypork/utils/math/constraints/rect/proxy/RectProxy.java
+++ b/src/mightypork/utils/math/constraints/rect/proxy/RectProxy.java
@@ -8,34 +8,36 @@ import mightypork.utils.math.constraints.rect.RectBound;
/**
* Pluggable rect proxy
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class RectProxy extends RectAdapter implements PluggableRectBound {
-
+
private RectBound backing = null;
-
-
- public RectProxy() {
+
+
+ public RectProxy()
+ {
}
-
-
- public RectProxy(RectBound proxied) {
+
+
+ public RectProxy(RectBound proxied)
+ {
backing = proxied;
}
-
-
+
+
@Override
public void setRect(RectBound proxied)
{
this.backing = proxied;
}
-
-
+
+
@Override
public Rect getSource()
{
return backing.getRect();
}
-
+
}
diff --git a/src/mightypork/utils/math/constraints/rect/proxy/RectVectAdapter.java b/src/mightypork/utils/math/constraints/rect/proxy/RectVectAdapter.java
index 95a2156..35c2f91 100644
--- a/src/mightypork/utils/math/constraints/rect/proxy/RectVectAdapter.java
+++ b/src/mightypork/utils/math/constraints/rect/proxy/RectVectAdapter.java
@@ -7,32 +7,33 @@ import mightypork.utils.math.constraints.vect.Vect;
/**
* Rect made of two {@link Vect}s
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class RectVectAdapter extends Rect {
-
+
private final Vect origin;
private final Vect size;
-
-
- public RectVectAdapter(Vect origin, Vect size) {
+
+
+ public RectVectAdapter(Vect origin, Vect size)
+ {
this.origin = origin;
this.size = size;
}
-
-
+
+
@Override
public Vect origin()
{
return origin;
}
-
-
+
+
@Override
public Vect size()
{
return size;
}
-
+
}
diff --git a/src/mightypork/utils/math/constraints/rect/var/RectMutable.java b/src/mightypork/utils/math/constraints/rect/var/RectMutable.java
index 0506dd8..dfa13e8 100644
--- a/src/mightypork/utils/math/constraints/rect/var/RectMutable.java
+++ b/src/mightypork/utils/math/constraints/rect/var/RectMutable.java
@@ -7,25 +7,25 @@ import mightypork.utils.math.constraints.vect.Vect;
/**
* Mutable rectangle; operations change it's state.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public abstract class RectMutable extends Rect {
-
+
/**
* Set to other rect's coordinates
- *
+ *
* @param rect other rect
*/
public void setTo(Rect rect)
{
setTo(rect.origin(), rect.size());
}
-
-
+
+
/**
* Set to given size and position
- *
+ *
* @param origin new origin
* @param width new width
* @param height new height
@@ -34,11 +34,11 @@ public abstract class RectMutable extends Rect {
{
setTo(origin, Vect.make(width, height));
}
-
-
+
+
/**
* Set to given size and position
- *
+ *
* @param x origin.x
* @param y origin.y
* @param width new width
@@ -48,11 +48,11 @@ public abstract class RectMutable extends Rect {
{
setTo(Vect.make(x, y), Vect.make(width, height));
}
-
-
+
+
/**
* Set to given size and position
- *
+ *
* @param origin new origin
* @param size new size
*/
@@ -61,8 +61,8 @@ public abstract class RectMutable extends Rect {
setOrigin(origin);
setSize(size);
}
-
-
+
+
/**
* Set to zero
*/
@@ -70,22 +70,22 @@ public abstract class RectMutable extends Rect {
{
setTo(Vect.ZERO, Vect.ZERO);
}
-
-
+
+
public abstract void setOrigin(double x, double y);
-
-
+
+
public void setOrigin(Vect origin)
{
setOrigin(origin.x(), origin.y());
}
-
-
+
+
public void setSize(Vect size)
{
setSize(size.x(), size.y());
}
-
-
+
+
public abstract void setSize(double x, double y);
}
diff --git a/src/mightypork/utils/math/constraints/rect/var/RectVar.java b/src/mightypork/utils/math/constraints/rect/var/RectVar.java
index 3ce2824..c04413a 100644
--- a/src/mightypork/utils/math/constraints/rect/var/RectVar.java
+++ b/src/mightypork/utils/math/constraints/rect/var/RectVar.java
@@ -6,46 +6,47 @@ import mightypork.utils.math.constraints.vect.var.VectVar;
public class RectVar extends RectMutable {
-
+
final VectVar pos = Vect.makeVar();
final VectVar size = Vect.makeVar();
-
-
+
+
/**
* Create at given origin, with given size.
- *
+ *
* @param x
* @param y
* @param width
* @param height
*/
- public RectVar(double x, double y, double width, double height) {
+ public RectVar(double x, double y, double width, double height)
+ {
this.pos.setTo(x, y);
this.size.setTo(width, height);
}
-
-
+
+
@Override
public Vect origin()
{
return pos;
}
-
-
+
+
@Override
public Vect size()
{
return size;
}
-
-
+
+
@Override
public void setOrigin(double x, double y)
{
this.pos.setTo(x, y);
}
-
-
+
+
@Override
public void setSize(double x, double y)
{
diff --git a/src/mightypork/utils/math/constraints/vect/PluggableVectBound.java b/src/mightypork/utils/math/constraints/vect/PluggableVectBound.java
index 29c9884..b4142e0 100644
--- a/src/mightypork/utils/math/constraints/vect/PluggableVectBound.java
+++ b/src/mightypork/utils/math/constraints/vect/PluggableVectBound.java
@@ -3,14 +3,14 @@ package mightypork.utils.math.constraints.vect;
/**
* Pluggable vector constraint
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public interface PluggableVectBound extends VectBound {
-
+
/**
* @param num bound to set
*/
abstract void setVect(VectBound num);
-
+
}
diff --git a/src/mightypork/utils/math/constraints/vect/Vect.java b/src/mightypork/utils/math/constraints/vect/Vect.java
index 4841f9b..927931f 100644
--- a/src/mightypork/utils/math/constraints/vect/Vect.java
+++ b/src/mightypork/utils/math/constraints/vect/Vect.java
@@ -16,201 +16,201 @@ import mightypork.utils.math.constraints.vect.var.VectVar;
/**
* The most basic Vec methods
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public abstract class Vect implements VectBound, CachedDigestable {
-
+
public static final VectConst ZERO = new VectConst(0, 0, 0);
public static final VectConst ONE = new VectConst(1, 1, 1);
-
-
+
+
@FactoryMethod
public static Vect make(Num xy)
{
return make(xy, xy);
}
-
-
+
+
@FactoryMethod
public static Vect make(Num xc, Num yc)
{
return Vect.make(xc, yc, Num.ZERO);
}
-
-
+
+
@FactoryMethod
public static Vect make(Num xc, Num yc, Num zc)
{
return new VectNumAdapter(xc, yc, zc);
}
-
-
+
+
@FactoryMethod
public static Vect make(VectBound bound)
{
return new VectProxy(bound);
}
-
-
+
+
@FactoryMethod
public static VectConst make(NumConst xy)
{
return make(xy, xy);
}
-
-
+
+
@FactoryMethod
public static VectConst make(NumConst xc, NumConst yc)
{
return Vect.make(xc, yc, Num.ZERO);
}
-
-
+
+
@FactoryMethod
public static VectConst make(NumConst xc, NumConst yc, NumConst zc)
{
return new VectConst(xc.value(), yc.value(), zc.value());
}
-
-
+
+
@FactoryMethod
public static VectConst make(double xy)
{
return make(xy, xy);
}
-
-
+
+
@FactoryMethod
public static VectConst make(double x, double y)
{
return Vect.make(x, y, 0);
}
-
-
+
+
@FactoryMethod
public static VectConst make(double x, double y, double z)
{
return new VectConst(x, y, z);
}
-
-
+
+
@FactoryMethod
public static VectVar makeVar()
{
return Vect.makeVar(Vect.ZERO);
}
-
-
+
+
@FactoryMethod
public static VectVar makeVar(double x, double y)
{
return Vect.makeVar(x, y, 0);
}
-
-
+
+
@FactoryMethod
public static VectVar makeVar(Vect copied)
{
return Vect.makeVar(copied.x(), copied.y(), copied.z());
}
-
-
+
+
@FactoryMethod
public static VectVar makeVar(double x, double y, double z)
{
return new VectVar(x, y, z);
}
-
-
+
+
public static VectConst fromString(String string)
{
try {
String s = string.trim();
-
+
// drop whitespace
s = s.replaceAll("\\s", "");
-
+
// drop brackets
s = s.replaceAll("[\\(\\[\\{\\)\\]\\}]", "");
-
+
// norm separators
s = s.replaceAll("[:;]", "|");
-
+
// norm floating point
s = s.replaceAll("[,]", ".");
-
+
final String[] parts = s.split("[|]");
-
+
if (parts.length >= 2) {
-
+
final double x = Double.parseDouble(parts[0].trim());
final double y = Double.parseDouble(parts[1].trim());
-
+
if (parts.length == 2) {
return Vect.make(x, y);
}
-
+
final double z = Double.parseDouble(parts[2].trim());
-
+
return Vect.make(x, y, z);
}
-
+
} catch (final RuntimeException e) {
return null;
}
return null;
}
-
-
+
+
@Override
public String toString()
{
return String.format("(%.1f ; %.1f ; %.1f)", x(), y(), z());
}
-
+
private Num p_size;
private Vect p_neg;
private Vect p_half;
private Vect p_abs;
-
+
private Num p_xc;
private Num p_yc;
private Num p_zc;
-
+
private final DigestCache dc = new DigestCache() {
-
+
@Override
protected VectDigest createDigest()
{
return new VectDigest(Vect.this);
}
};
-
-
+
+
/**
* @return X coordinate
*/
public abstract double x();
-
-
+
+
/**
* @return Y coordinate
*/
public abstract double y();
-
-
+
+
/**
* (Implemented in Vect for convenience when creating 2D vects)
- *
+ *
* @return Z coordinate
*/
public double z()
{
return 0;
}
-
-
+
+
/**
* @return X rounded
*/
@@ -218,8 +218,8 @@ public abstract class Vect implements VectBound, CachedDigestable {
{
return (int) Math.round(x());
}
-
-
+
+
/**
* @return Y rounded
*/
@@ -227,8 +227,8 @@ public abstract class Vect implements VectBound, CachedDigestable {
{
return (int) Math.round(y());
}
-
-
+
+
/**
* @return Z rounded
*/
@@ -236,69 +236,69 @@ public abstract class Vect implements VectBound, CachedDigestable {
{
return (int) Math.round(z());
}
-
-
+
+
/**
* @return X constraint
*/
public Num xn()
{
if (p_xc == null) p_xc = new Num() {
-
+
@Override
public double value()
{
return x();
}
};
-
+
return p_xc;
}
-
-
+
+
/**
* @return Y constraint
*/
public Num yn()
{
if (p_yc == null) p_yc = new Num() {
-
+
@Override
public double value()
{
return y();
}
};
-
+
return p_yc;
}
-
-
+
+
/**
* @return Z constraint
*/
public Num zn()
{
if (p_zc == null) p_zc = new Num() {
-
+
@Override
public double value()
{
return z();
}
};
-
+
return p_zc;
}
-
-
+
+
@Override
public final Vect getVect()
{
return this;
}
-
-
+
+
/**
* @return true if zero
*/
@@ -306,62 +306,62 @@ public abstract class Vect implements VectBound, CachedDigestable {
{
return x() == 0 && y() == 0 && z() == 0;
}
-
-
+
+
/**
* Get a static immutable copy of the current state.
- *
+ *
* @return a immutable copy
*/
public VectConst freeze()
{
return new VectConst(this);
}
-
-
+
+
/**
* Wrap this constraint into a caching adapter. Value will stay fixed (ie.
* no re-calculations) until cache receives a poll() call.
- *
+ *
* @return the caching adapter
*/
public VectCache cached()
{
return new VectCache(this);
}
-
-
+
+
@Override
public VectDigest digest()
{
return dc.digest();
}
-
-
+
+
@Override
public void enableDigestCaching(boolean yes)
{
dc.enableDigestCaching(yes);
}
-
-
+
+
@Override
public boolean isDigestCachingEnabled()
{
return dc.isDigestCachingEnabled();
}
-
-
+
+
@Override
public void markDigestDirty()
{
dc.markDigestDirty();
}
-
-
+
+
/**
* Get a view with X set to given value
- *
+ *
* @param x x coordinate
* @return result
*/
@@ -369,11 +369,11 @@ public abstract class Vect implements VectBound, CachedDigestable {
{
return withX(Num.make(x));
}
-
-
+
+
/**
* Get a view with Y set to given value
- *
+ *
* @param y y coordinate
* @return result
*/
@@ -381,11 +381,11 @@ public abstract class Vect implements VectBound, CachedDigestable {
{
return withY(Num.make(y));
}
-
-
+
+
/**
* Get a view with Z set to given value
- *
+ *
* @param z z coordinate
* @return result
*/
@@ -393,29 +393,29 @@ public abstract class Vect implements VectBound, CachedDigestable {
{
return withZ(Num.make(z));
}
-
-
+
+
public Vect withX(final Num x)
{
return new Vect() {
-
+
final Vect t = Vect.this;
-
-
+
+
@Override
public double x()
{
return x.value();
}
-
-
+
+
@Override
public double y()
{
return t.z();
}
-
-
+
+
@Override
public double z()
{
@@ -423,29 +423,29 @@ public abstract class Vect implements VectBound, CachedDigestable {
}
};
}
-
-
+
+
public Vect withY(final Num y)
{
return new Vect() {
-
+
final Vect t = Vect.this;
-
-
+
+
@Override
public double x()
{
return t.x();
}
-
-
+
+
@Override
public double y()
{
return y.value();
}
-
-
+
+
@Override
public double z()
{
@@ -453,29 +453,29 @@ public abstract class Vect implements VectBound, CachedDigestable {
}
};
}
-
-
+
+
public Vect withZ(final Num z)
{
return new Vect() {
-
+
final Vect t = Vect.this;
-
-
+
+
@Override
public double x()
{
return t.x();
}
-
-
+
+
@Override
public double y()
{
return t.y();
}
-
-
+
+
@Override
public double z()
{
@@ -483,48 +483,48 @@ public abstract class Vect implements VectBound, CachedDigestable {
}
};
}
-
-
+
+
/**
* Get absolute value (positive)
- *
+ *
* @return result
*/
public Vect abs()
{
if (p_abs == null) p_abs = new Vect() {
-
+
final Vect t = Vect.this;
-
-
+
+
@Override
public double x()
{
return Math.abs(t.x());
}
-
-
+
+
@Override
public double y()
{
return Math.abs(t.y());
}
-
-
+
+
@Override
public double z()
{
return Math.abs(t.z());
}
};
-
+
return p_abs;
}
-
-
+
+
/**
* Add a vector.
- *
+ *
* @param vec offset
* @return result
*/
@@ -532,12 +532,12 @@ public abstract class Vect implements VectBound, CachedDigestable {
{
return add(vec.xn(), vec.yn(), vec.zn());
}
-
-
+
+
/**
* Add to each component.
* Z is unchanged.
- *
+ *
* @param x x offset
* @param y y offset
* @return result
@@ -546,11 +546,11 @@ public abstract class Vect implements VectBound, CachedDigestable {
{
return add(x, y, 0);
}
-
-
+
+
/**
* Add to each component.
- *
+ *
* @param x x offset
* @param y y offset
* @param z z offset
@@ -559,24 +559,24 @@ public abstract class Vect implements VectBound, CachedDigestable {
public Vect add(final double x, final double y, final double z)
{
return new Vect() {
-
+
final Vect t = Vect.this;
-
-
+
+
@Override
public double x()
{
return t.x() + x;
}
-
-
+
+
@Override
public double y()
{
return t.y() + y;
}
-
-
+
+
@Override
public double z()
{
@@ -584,35 +584,35 @@ public abstract class Vect implements VectBound, CachedDigestable {
}
};
}
-
-
+
+
public Vect add(Num x, Num y)
{
return add(x, y, Num.ZERO);
}
-
-
+
+
public Vect add(final Num x, final Num y, final Num z)
{
return new Vect() {
-
+
final Vect t = Vect.this;
-
-
+
+
@Override
public double x()
{
return t.x() + x.value();
}
-
-
+
+
@Override
public double y()
{
return t.y() + y.value();
}
-
-
+
+
@Override
public double z()
{
@@ -620,11 +620,11 @@ public abstract class Vect implements VectBound, CachedDigestable {
}
};
}
-
-
+
+
/**
* Get copy divided by two
- *
+ *
* @return result
*/
public Vect half()
@@ -632,11 +632,11 @@ public abstract class Vect implements VectBound, CachedDigestable {
if (p_half == null) p_half = mul(0.5);
return p_half;
}
-
-
+
+
/**
* Multiply each component.
- *
+ *
* @param d multiplier
* @return result
*/
@@ -644,11 +644,11 @@ public abstract class Vect implements VectBound, CachedDigestable {
{
return mul(d, d, d);
}
-
-
+
+
/**
* Multiply each component.
- *
+ *
* @param vec vector of multipliers
* @return result
*/
@@ -656,12 +656,12 @@ public abstract class Vect implements VectBound, CachedDigestable {
{
return mul(vec.xn(), vec.yn(), vec.zn());
}
-
-
+
+
/**
* Multiply each component.
* Z is unchanged.
- *
+ *
* @param x x multiplier
* @param y y multiplier
* @return result
@@ -670,11 +670,11 @@ public abstract class Vect implements VectBound, CachedDigestable {
{
return mul(x, y, 1);
}
-
-
+
+
/**
* Multiply each component.
- *
+ *
* @param x x multiplier
* @param y y multiplier
* @param z z multiplier
@@ -683,24 +683,24 @@ public abstract class Vect implements VectBound, CachedDigestable {
public Vect mul(final double x, final double y, final double z)
{
return new Vect() {
-
+
final Vect t = Vect.this;
-
-
+
+
@Override
public double x()
{
return t.x() * x;
}
-
-
+
+
@Override
public double y()
{
return t.y() * y;
}
-
-
+
+
@Override
public double z()
{
@@ -708,11 +708,11 @@ public abstract class Vect implements VectBound, CachedDigestable {
}
};
}
-
-
+
+
/**
* Multiply each component.
- *
+ *
* @param d multiplier
* @return result
*/
@@ -720,11 +720,11 @@ public abstract class Vect implements VectBound, CachedDigestable {
{
return mul(d, d, d);
}
-
-
+
+
/**
* Multiply each component.
- *
+ *
* @param x x multiplier
* @param y y multiplier
* @return result
@@ -733,11 +733,11 @@ public abstract class Vect implements VectBound, CachedDigestable {
{
return mul(x, y, Num.ONE);
}
-
-
+
+
/**
* Multiply each component.
- *
+ *
* @param x x multiplier
* @param y y multiplier
* @param z z multiplier
@@ -746,24 +746,24 @@ public abstract class Vect implements VectBound, CachedDigestable {
public Vect mul(final Num x, final Num y, final Num z)
{
return new Vect() {
-
+
final Vect t = Vect.this;
-
-
+
+
@Override
public double x()
{
return t.x() * x.value();
}
-
-
+
+
@Override
public double y()
{
return t.y() * y.value();
}
-
-
+
+
@Override
public double z()
{
@@ -771,34 +771,34 @@ public abstract class Vect implements VectBound, CachedDigestable {
}
};
}
-
-
+
+
/**
* Round coordinates.
- *
+ *
* @return result
*/
public Vect round()
{
return new Vect() {
-
+
final Vect t = Vect.this;
-
-
+
+
@Override
public double x()
{
return Math.round(t.x());
}
-
-
+
+
@Override
public double y()
{
return Math.round(t.y());
}
-
-
+
+
@Override
public double z()
{
@@ -806,34 +806,34 @@ public abstract class Vect implements VectBound, CachedDigestable {
}
};
}
-
-
+
+
/**
* Round coordinates down.
- *
+ *
* @return result
*/
public Vect floor()
{
return new Vect() {
-
+
final Vect t = Vect.this;
-
-
+
+
@Override
public double x()
{
return Math.floor(t.x());
}
-
-
+
+
@Override
public double y()
{
return Math.floor(t.y());
}
-
-
+
+
@Override
public double z()
{
@@ -841,34 +841,34 @@ public abstract class Vect implements VectBound, CachedDigestable {
}
};
}
-
-
+
+
/**
* Round coordinates up.
- *
+ *
* @return result
*/
public Vect ceil()
{
return new Vect() {
-
+
final Vect t = Vect.this;
-
-
+
+
@Override
public double x()
{
return Math.ceil(t.x());
}
-
-
+
+
@Override
public double y()
{
return Math.ceil(t.y());
}
-
-
+
+
@Override
public double z()
{
@@ -876,11 +876,11 @@ public abstract class Vect implements VectBound, CachedDigestable {
}
};
}
-
-
+
+
/**
* Subtract vector.
- *
+ *
* @param vec offset
* @return result
*/
@@ -888,12 +888,12 @@ public abstract class Vect implements VectBound, CachedDigestable {
{
return sub(vec.xn(), vec.yn(), vec.zn());
}
-
-
+
+
/**
* Subtract a 2D vector.
* Z is unchanged.
- *
+ *
* @param x x offset
* @param y y offset
* @return result
@@ -902,11 +902,11 @@ public abstract class Vect implements VectBound, CachedDigestable {
{
return add(-x, -y, 0);
}
-
-
+
+
/**
* Subtract a 3D vector.
- *
+ *
* @param x x offset
* @param y y offset
* @param z z offset
@@ -916,35 +916,35 @@ public abstract class Vect implements VectBound, CachedDigestable {
{
return add(-x, -y, -z);
}
-
-
+
+
public Vect sub(Num x, Num y)
{
return sub(x, y, Num.ZERO);
}
-
-
+
+
public Vect sub(final Num x, final Num y, final Num z)
{
return new Vect() {
-
+
final Vect t = Vect.this;
-
-
+
+
@Override
public double x()
{
return t.x() - x.value();
}
-
-
+
+
@Override
public double y()
{
return t.y() - y.value();
}
-
-
+
+
@Override
public double z()
{
@@ -952,11 +952,11 @@ public abstract class Vect implements VectBound, CachedDigestable {
}
};
}
-
-
+
+
/**
* Negate all coordinates (* -1)
- *
+ *
* @return result
*/
public Vect neg()
@@ -964,118 +964,118 @@ public abstract class Vect implements VectBound, CachedDigestable {
if (p_neg == null) p_neg = mul(-1);
return p_neg;
}
-
-
+
+
/**
* Scale vector to given size.
- *
+ *
* @param size size we need
* @return result
*/
public Vect norm(final Num size)
{
return new Vect() {
-
+
final Vect t = Vect.this;
-
-
+
+
@Override
public double x()
{
final double tSize = t.size().value();
final double nSize = size.value();
-
+
if (tSize == 0 || nSize == 0) return 0;
-
+
return t.x() / (nSize / tSize);
}
-
-
+
+
@Override
public double y()
{
final double tSize = t.size().value();
final double nSize = size.value();
-
+
if (tSize == 0 || nSize == 0) return 0;
-
+
return t.y() / (nSize / tSize);
}
-
-
+
+
@Override
public double z()
{
final double tSize = t.size().value();
final double nSize = size.value();
-
+
if (tSize == 0 || nSize == 0) return 0;
-
+
return t.z() / (nSize / tSize);
}
};
}
-
-
+
+
public Vect norm(final double size)
{
return norm(Num.make(size));
}
-
-
+
+
/**
* Get distance to other point
- *
+ *
* @param point other point
* @return distance
*/
public Num dist(final Vect point)
{
return new Num() {
-
+
final Vect t = Vect.this;
-
-
+
+
@Override
public double value()
{
final double dx = t.x() - point.x();
final double dy = t.y() - point.y();
final double dz = t.z() - point.z();
-
+
return Math.sqrt(dx * dx + dy * dy + dz * dz);
}
};
}
-
-
+
+
/**
* Get middle of line to other point
- *
+ *
* @param point other point
* @return result
*/
public Vect midTo(final Vect point)
{
return new Vect() {
-
+
final Vect t = Vect.this;
-
-
+
+
@Override
public double x()
{
return (point.x() + t.x()) * 0.5;
}
-
-
+
+
@Override
public double y()
{
return (point.y() + t.y()) * 0.5;
}
-
-
+
+
@Override
public double z()
{
@@ -1083,35 +1083,35 @@ public abstract class Vect implements VectBound, CachedDigestable {
}
};
}
-
-
+
+
/**
* Create vector from this point to other point
- *
+ *
* @param point second point
* @return result
*/
public Vect vectTo(final Vect point)
{
return new Vect() {
-
+
final Vect t = Vect.this;
-
-
+
+
@Override
public double x()
{
return (point.x() - t.x());
}
-
-
+
+
@Override
public double y()
{
return (point.y() - t.y());
}
-
-
+
+
@Override
public double z()
{
@@ -1119,35 +1119,35 @@ public abstract class Vect implements VectBound, CachedDigestable {
}
};
}
-
-
+
+
/**
* Get cross product (vector multiplication)
- *
+ *
* @param vec other vector
* @return result
*/
public Vect cross(final Vect vec)
{
return new Vect() {
-
+
final Vect t = Vect.this;
-
-
+
+
@Override
public double x()
{
return t.y() * vec.z() - t.z() * vec.y();
}
-
-
+
+
@Override
public double y()
{
return t.z() * vec.x() - t.x() * vec.z();
}
-
-
+
+
@Override
public double z()
{
@@ -1155,21 +1155,21 @@ public abstract class Vect implements VectBound, CachedDigestable {
}
};
}
-
-
+
+
/**
* Get dot product (scalar multiplication)
- *
+ *
* @param vec other vector
* @return dot product
*/
public Num dot(final Vect vec)
{
return new Num() {
-
+
final Vect t = Vect.this;
-
-
+
+
@Override
public double value()
{
@@ -1177,20 +1177,20 @@ public abstract class Vect implements VectBound, CachedDigestable {
}
};
}
-
-
+
+
/**
* Get vector size
- *
+ *
* @return size
*/
public Num size()
{
if (p_size == null) p_size = new Num() {
-
+
final Vect t = Vect.this;
-
-
+
+
@Override
public double value()
{
@@ -1198,14 +1198,14 @@ public abstract class Vect implements VectBound, CachedDigestable {
return Math.sqrt(x * x + y * y + z * z);
}
};
-
+
return p_size;
}
-
-
+
+
/**
* Expand to a rect, with given growth to each side.
- *
+ *
* @param left
* @param right
* @param top
@@ -1216,11 +1216,11 @@ public abstract class Vect implements VectBound, CachedDigestable {
{
return Rect.make(this, Vect.ZERO).grow(left, right, top, bottom);
}
-
-
+
+
/**
* Expand to a rect, with given growth to each side.
- *
+ *
* @param left
* @param right
* @param top
@@ -1231,8 +1231,8 @@ public abstract class Vect implements VectBound, CachedDigestable {
{
return Rect.make(this, Vect.ZERO).grow(left, right, top, bottom);
}
-
-
+
+
@Override
public int hashCode()
{
@@ -1243,8 +1243,8 @@ public abstract class Vect implements VectBound, CachedDigestable {
result = prime * result + Double.valueOf(z()).hashCode();
return result;
}
-
-
+
+
@Override
public boolean equals(Object obj)
{
@@ -1252,17 +1252,17 @@ public abstract class Vect implements VectBound, CachedDigestable {
if (obj == null) return false;
if (!(obj instanceof Vect)) return false;
final Vect other = (Vect) obj;
-
+
return x() == other.x() && y() == other.y() && z() == other.z();
}
-
-
+
+
public final boolean isInside(Rect bounds)
{
return bounds.contains(this);
}
-
-
+
+
public Rect startRect()
{
return expand(0, 0, 0, 0);
diff --git a/src/mightypork/utils/math/constraints/vect/VectBound.java b/src/mightypork/utils/math/constraints/vect/VectBound.java
index 5d7bd3c..f0f6601 100644
--- a/src/mightypork/utils/math/constraints/vect/VectBound.java
+++ b/src/mightypork/utils/math/constraints/vect/VectBound.java
@@ -4,11 +4,11 @@ package mightypork.utils.math.constraints.vect;
/**
* Interface for something that has/is a Vect. Vect itself implements it as
* well.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public interface VectBound {
-
+
/**
* @return the Vect value
*/
diff --git a/src/mightypork/utils/math/constraints/vect/VectConst.java b/src/mightypork/utils/math/constraints/vect/VectConst.java
index 56feb52..3b1e418 100644
--- a/src/mightypork/utils/math/constraints/vect/VectConst.java
+++ b/src/mightypork/utils/math/constraints/vect/VectConst.java
@@ -12,11 +12,11 @@ import mightypork.utils.math.constraints.vect.caching.VectDigest;
* This coordinate is guaranteed to never change, as opposed to view.
* It's arranged so that operations with constant arguments yield constant
* results.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public final class VectConst extends Vect {
-
+
private final double x, y, z;
// non-parametric operations are cached using lazy load.
private NumConst v_size;
@@ -30,344 +30,346 @@ public final class VectConst extends Vect {
private NumConst v_yc;
private NumConst v_zc;
private VectDigest digest;
-
-
- VectConst(Vect other) {
+
+
+ VectConst(Vect other)
+ {
this(other.x(), other.y(), other.z());
}
-
-
- VectConst(double x, double y, double z) {
+
+
+ VectConst(double x, double y, double z)
+ {
this.x = x;
this.y = y;
this.z = z;
}
-
-
+
+
@Override
public double x()
{
return x;
}
-
-
+
+
@Override
public double y()
{
return y;
}
-
-
+
+
@Override
public double z()
{
return z;
}
-
-
+
+
/**
* @return X constraint
*/
-
+
@Override
public final NumConst xn()
{
return (v_xc != null) ? v_xc : (v_xc = Num.make(this.x));
}
-
-
+
+
/**
* @return Y constraint
*/
-
+
@Override
public final NumConst yn()
{
return (v_yc != null) ? v_yc : (v_yc = Num.make(this.y));
}
-
-
+
+
/**
* @return Z constraint
*/
-
+
@Override
public final NumConst zn()
{
return (v_zc != null) ? v_zc : (v_zc = Num.make(this.z));
}
-
-
+
+
/**
* @deprecated it's useless to copy a constant
*/
-
+
@Override
@Deprecated
public VectConst freeze()
{
return this; // it's constant already
}
-
-
+
+
@Override
public VectDigest digest()
{
return (digest != null) ? digest : (digest = super.digest());
}
-
-
+
+
@Override
public VectConst abs()
{
return (v_abs != null) ? v_abs : (v_abs = super.abs().freeze());
}
-
-
+
+
@Override
public VectConst add(double x, double y)
{
return super.add(x, y).freeze();
}
-
-
+
+
@Override
public VectConst add(double x, double y, double z)
{
return super.add(x, y, z).freeze();
}
-
-
+
+
@Override
public VectConst half()
{
return (v_half != null) ? v_half : (v_half = super.half().freeze());
}
-
-
+
+
@Override
public VectConst mul(double d)
{
return super.mul(d).freeze();
}
-
-
+
+
@Override
public VectConst mul(double x, double y)
{
return super.mul(x, y).freeze();
}
-
-
+
+
@Override
public VectConst mul(double x, double y, double z)
{
return super.mul(x, y, z).freeze();
}
-
-
+
+
@Override
public VectConst round()
{
return (v_round != null) ? v_round : (v_round = super.round().freeze());
}
-
-
+
+
@Override
public VectConst floor()
{
return (v_floor != null) ? v_floor : (v_floor = super.floor().freeze());
}
-
-
+
+
@Override
public VectConst ceil()
{
if (v_ceil != null) return v_ceil;
return v_ceil = super.ceil().freeze();
}
-
-
+
+
@Override
public VectConst sub(double x, double y)
{
return super.sub(x, y).freeze();
}
-
-
+
+
@Override
public VectConst sub(double x, double y, double z)
{
return super.sub(x, y, z).freeze();
}
-
-
+
+
@Override
public VectConst neg()
{
return (v_neg != null) ? v_neg : (v_neg = super.neg().freeze());
}
-
-
+
+
@Override
public VectConst norm(double size)
{
return super.norm(size).freeze();
}
-
-
+
+
@Override
public NumConst size()
{
return (v_size != null) ? v_size : (v_size = super.size().freeze());
}
-
-
+
+
@Override
public VectConst withX(double x)
{
return super.withX(x).freeze();
}
-
-
+
+
@Override
public VectConst withY(double y)
{
return super.withY(y).freeze();
}
-
-
+
+
@Override
public VectConst withZ(double z)
{
return super.withZ(z).freeze();
}
-
-
+
+
public VectConst withX(NumConst x)
{
return super.withX(x).freeze();
}
-
-
+
+
public VectConst withY(NumConst y)
{
return super.withY(y).freeze();
}
-
-
+
+
public VectConst withZ(NumConst z)
{
return super.withZ(z).freeze();
}
-
-
+
+
public VectConst add(VectConst vec)
{
return super.add(vec).freeze();
}
-
-
+
+
public VectConst add(NumConst x, NumConst y)
{
return super.add(x, y).freeze();
}
-
-
+
+
public VectConst add(NumConst x, NumConst y, NumConst z)
{
return super.add(x, y, z).freeze();
}
-
-
+
+
public VectConst mul(VectConst vec)
{
return super.mul(vec).freeze();
}
-
-
+
+
public VectConst mul(NumConst d)
{
return super.mul(d).freeze();
}
-
-
+
+
public VectConst mul(NumConst x, NumConst y)
{
return super.mul(x, y).freeze();
}
-
-
+
+
public VectConst mul(NumConst x, NumConst y, NumConst z)
{
return super.mul(x, y, z).freeze();
}
-
-
+
+
public VectConst sub(VectConst vec)
{
return super.sub(vec).freeze();
}
-
-
+
+
public VectConst sub(NumConst x, NumConst y)
{
return super.sub(x, y).freeze();
}
-
-
+
+
public VectConst sub(NumConst x, NumConst y, NumConst z)
{
return super.sub(x, y, z).freeze();
}
-
-
+
+
public VectConst norm(NumConst size)
{
return super.norm(size).freeze();
}
-
-
+
+
public NumConst dist(VectConst point)
{
return super.dist(point).freeze();
}
-
-
+
+
public VectConst midTo(VectConst point)
{
return super.midTo(point).freeze();
}
-
-
+
+
public VectConst vectTo(VectConst point)
{
return super.vectTo(point).freeze();
}
-
-
+
+
public NumConst dot(VectConst vec)
{
return super.dot(vec).freeze();
}
-
-
+
+
public VectConst cross(VectConst vec)
{
return super.cross(vec).freeze();
}
-
-
+
+
@Override
public RectConst expand(double left, double right, double top, double bottom)
{
return super.expand(left, right, top, bottom).freeze();
}
-
-
+
+
public RectConst expand(NumConst left, NumConst right, NumConst top, NumConst bottom)
{
return super.expand(left, right, top, bottom).freeze();
}
-
+
}
diff --git a/src/mightypork/utils/math/constraints/vect/caching/AbstractVectCache.java b/src/mightypork/utils/math/constraints/vect/caching/AbstractVectCache.java
index 2994c3e..a1258c2 100644
--- a/src/mightypork/utils/math/constraints/vect/caching/AbstractVectCache.java
+++ b/src/mightypork/utils/math/constraints/vect/caching/AbstractVectCache.java
@@ -15,60 +15,61 @@ import mightypork.utils.math.constraints.vect.var.VectVar;
* Values are held in a caching VectVar, and digest caching is enabled by
* default.
*
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public abstract class AbstractVectCache extends VectAdapter implements CachedConstraint {
-
+
private final VectVar cache = Vect.makeVar();
private boolean inited = false;
private boolean cachingEnabled = true;
-
-
- public AbstractVectCache() {
+
+
+ public AbstractVectCache()
+ {
enableDigestCaching(true); // it changes only on poll
}
-
-
+
+
@Override
protected final Vect getSource()
{
if (!inited) markDigestDirty();
-
+
return (cachingEnabled ? cache : getCacheSource());
}
-
-
+
+
@Override
public final void poll()
{
inited = true;
-
+
// poll source
final Vect source = getCacheSource();
source.markDigestDirty(); // poll cached
-
+
// store source value
cache.setTo(source);
-
+
markDigestDirty();
-
+
onConstraintChanged();
}
-
-
+
+
@Override
public final void enableCaching(boolean yes)
{
cachingEnabled = yes;
enableDigestCaching(yes);
}
-
-
+
+
@Override
public final boolean isCachingEnabled()
{
return cachingEnabled;
}
-
+
}
diff --git a/src/mightypork/utils/math/constraints/vect/caching/VectCache.java b/src/mightypork/utils/math/constraints/vect/caching/VectCache.java
index 84e5db3..5fbad9b 100644
--- a/src/mightypork/utils/math/constraints/vect/caching/VectCache.java
+++ b/src/mightypork/utils/math/constraints/vect/caching/VectCache.java
@@ -6,27 +6,28 @@ import mightypork.utils.math.constraints.vect.Vect;
/**
* Vect cache implementation
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class VectCache extends AbstractVectCache {
-
+
private final Vect source;
-
-
- public VectCache(Vect source) {
+
+
+ public VectCache(Vect source)
+ {
this.source = source;
enableDigestCaching(true);
}
-
-
+
+
@Override
public Vect getCacheSource()
{
return source;
}
-
-
+
+
@Override
public void onConstraintChanged()
{
diff --git a/src/mightypork/utils/math/constraints/vect/caching/VectDigest.java b/src/mightypork/utils/math/constraints/vect/caching/VectDigest.java
index 48a5797..d858ef1 100644
--- a/src/mightypork/utils/math/constraints/vect/caching/VectDigest.java
+++ b/src/mightypork/utils/math/constraints/vect/caching/VectDigest.java
@@ -5,19 +5,20 @@ import mightypork.utils.math.constraints.vect.Vect;
public class VectDigest {
-
+
public final double x;
public final double y;
public final double z;
-
-
- public VectDigest(Vect vect) {
+
+
+ public VectDigest(Vect vect)
+ {
this.x = vect.x();
this.y = vect.y();
this.z = vect.z();
}
-
-
+
+
@Override
public String toString()
{
diff --git a/src/mightypork/utils/math/constraints/vect/proxy/VectAdapter.java b/src/mightypork/utils/math/constraints/vect/proxy/VectAdapter.java
index e5ade38..d51efa2 100644
--- a/src/mightypork/utils/math/constraints/vect/proxy/VectAdapter.java
+++ b/src/mightypork/utils/math/constraints/vect/proxy/VectAdapter.java
@@ -7,35 +7,35 @@ import mightypork.utils.math.constraints.vect.Vect;
/**
* Vect proxy with abstract method for plugging in / generating coordinates
* dynamically.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public abstract class VectAdapter extends Vect {
-
+
/**
* @return the proxied coord
*/
protected abstract Vect getSource();
-
-
+
+
@Override
public double x()
{
return getSource().x();
}
-
-
+
+
@Override
public double y()
{
return getSource().y();
}
-
-
+
+
@Override
public double z()
{
return getSource().z();
}
-
+
}
diff --git a/src/mightypork/utils/math/constraints/vect/proxy/VectNumAdapter.java b/src/mightypork/utils/math/constraints/vect/proxy/VectNumAdapter.java
index 40b348c..1b6bb2e 100644
--- a/src/mightypork/utils/math/constraints/vect/proxy/VectNumAdapter.java
+++ b/src/mightypork/utils/math/constraints/vect/proxy/VectNumAdapter.java
@@ -8,48 +8,50 @@ import mightypork.utils.math.constraints.vect.Vect;
/**
* Coord view composed of given {@link NumBound}s, using their current values.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class VectNumAdapter extends Vect {
-
+
private final Num constrX;
private final Num constrY;
private final Num constrZ;
-
-
- public VectNumAdapter(Num x, Num y, Num z) {
+
+
+ public VectNumAdapter(Num x, Num y, Num z)
+ {
this.constrX = x;
this.constrY = y;
this.constrZ = z;
}
-
-
- public VectNumAdapter(Num x, Num y) {
+
+
+ public VectNumAdapter(Num x, Num y)
+ {
this.constrX = x;
this.constrY = y;
this.constrZ = Num.ZERO;
}
-
-
+
+
@Override
public double x()
{
return constrX.value();
}
-
-
+
+
@Override
public double y()
{
return constrY.value();
}
-
-
+
+
@Override
public double z()
{
return constrZ.value();
}
-
+
}
diff --git a/src/mightypork/utils/math/constraints/vect/proxy/VectProxy.java b/src/mightypork/utils/math/constraints/vect/proxy/VectProxy.java
index 862fb81..35acc0f 100644
--- a/src/mightypork/utils/math/constraints/vect/proxy/VectProxy.java
+++ b/src/mightypork/utils/math/constraints/vect/proxy/VectProxy.java
@@ -8,34 +8,36 @@ import mightypork.utils.math.constraints.vect.VectBound;
/**
* Pluggable vect proxy
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class VectProxy extends VectAdapter implements PluggableVectBound {
-
+
private VectBound backing = null;
-
-
- public VectProxy() {
+
+
+ public VectProxy()
+ {
}
-
-
- public VectProxy(VectBound proxied) {
+
+
+ public VectProxy(VectBound proxied)
+ {
backing = proxied;
}
-
-
+
+
@Override
public void setVect(VectBound proxied)
{
this.backing = proxied;
}
-
-
+
+
@Override
protected Vect getSource()
{
return backing.getVect();
}
-
+
}
diff --git a/src/mightypork/utils/math/constraints/vect/var/VectMutable.java b/src/mightypork/utils/math/constraints/vect/var/VectMutable.java
index dd00e06..e90bbc5 100644
--- a/src/mightypork/utils/math/constraints/vect/var/VectMutable.java
+++ b/src/mightypork/utils/math/constraints/vect/var/VectMutable.java
@@ -6,11 +6,11 @@ import mightypork.utils.math.constraints.vect.Vect;
/**
* Mutable coord
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public abstract class VectMutable extends Vect {
-
+
/**
* Set all to zeros.
*/
@@ -18,23 +18,23 @@ public abstract class VectMutable extends Vect {
{
setTo(0, 0, 0);
}
-
-
+
+
/**
* Set coordinates to match other coord.
- *
+ *
* @param copied coord whose coordinates are used
*/
public void setTo(Vect copied)
{
setTo(copied.x(), copied.y(), copied.z());
}
-
-
+
+
/**
* Set 2D coordinates.
* Z is unchanged.
- *
+ *
* @param x x coordinate
* @param y y coordinate
*/
@@ -43,37 +43,37 @@ public abstract class VectMutable extends Vect {
setX(x);
setY(y);
}
-
-
+
+
/**
* Set coordinates.
- *
+ *
* @param x x coordinate
* @param y y coordinate
* @param z z coordinate
*/
public abstract void setTo(double x, double y, double z);
-
-
+
+
/**
* Set X coordinate.
- *
+ *
* @param x x coordinate
*/
public abstract void setX(double x);
-
-
+
+
/**
* Set Y coordinate.
- *
+ *
* @param y y coordinate
*/
public abstract void setY(double y);
-
-
+
+
/**
* Set Z coordinate.
- *
+ *
* @param z z coordinate
*/
public abstract void setZ(double z);
diff --git a/src/mightypork/utils/math/constraints/vect/var/VectVar.java b/src/mightypork/utils/math/constraints/vect/var/VectVar.java
index 2e64189..d0ff355 100644
--- a/src/mightypork/utils/math/constraints/vect/var/VectVar.java
+++ b/src/mightypork/utils/math/constraints/vect/var/VectVar.java
@@ -4,48 +4,49 @@ package mightypork.utils.math.constraints.vect.var;
/**
* Mutable coordinate.
* All Vec methods (except copy) alter data values and return this instance.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class VectVar extends VectMutable {
-
+
private double x, y, z;
-
-
+
+
/**
* @param x X coordinate
* @param y Y coordinate
* @param z Z coordinate
*/
- public VectVar(double x, double y, double z) {
+ public VectVar(double x, double y, double z)
+ {
super();
this.x = x;
this.y = y;
this.z = z;
}
-
-
+
+
@Override
public double x()
{
return x;
}
-
-
+
+
@Override
public double y()
{
return y;
}
-
-
+
+
@Override
public double z()
{
return z;
}
-
-
+
+
@Override
public void setTo(double x, double y, double z)
{
@@ -53,22 +54,22 @@ public class VectVar extends VectMutable {
this.y = y;
this.z = z;
}
-
-
+
+
@Override
public void setX(double x)
{
this.x = x;
}
-
-
+
+
@Override
public void setY(double y)
{
this.y = y;
}
-
-
+
+
@Override
public void setZ(double z)
{
diff --git a/src/mightypork/utils/math/noise/NoiseGen.java b/src/mightypork/utils/math/noise/NoiseGen.java
index 37c49b9..2b0fbd3 100644
--- a/src/mightypork/utils/math/noise/NoiseGen.java
+++ b/src/mightypork/utils/math/noise/NoiseGen.java
@@ -3,66 +3,68 @@ package mightypork.utils.math.noise;
/**
* 2D Perlin noise generator
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class NoiseGen {
-
+
private static final double lowBound = -0.7072;
private static final double highBound = 0.7072;
-
+
private final PerlinNoiseGenerator noiser;
-
+
private final double lowMul;
private final double highMul;
private final double middle;
private final double density;
-
-
+
+
/**
* make a new noise generator with a random seed
- *
+ *
* @param density noise density (0..1). Lower density means larger "spots".
* @param low low bound ("valley")
* @param middle middle bound ("surface")
* @param high high bound ("hill")
*/
- public NoiseGen(double density, double low, double middle, double high) {
+ public NoiseGen(double density, double low, double middle, double high)
+ {
this(density, low, middle, high, Double.doubleToLongBits(Math.random()));
}
-
-
+
+
/**
* make a new noise generator
- *
+ *
* @param density noise density (0..1). Lower density means larger "spots".
* @param low low bound ("valley")
* @param middle middle bound ("surface")
* @param high high bound ("hill")
* @param seed random seed to use
*/
- public NoiseGen(double density, double low, double middle, double high, long seed) {
+ public NoiseGen(double density, double low, double middle, double high, long seed)
+ {
if (low > middle || middle > high) throw new IllegalArgumentException("Invalid value range.");
-
+
this.density = density;
-
+
// norm low and high to be around zero
low -= middle;
high -= middle;
-
- // scale
+
+ // scale
this.middle = middle;
-
+
lowMul = Math.abs(low / lowBound);
highMul = Math.abs(high / highBound);
-
+
noiser = new PerlinNoiseGenerator(seed);
}
-
-
+
+
/**
* Get value at coord
- *
+ *
* @param x x coordinate
* @param y y coordinate
* @return value
@@ -70,24 +72,24 @@ public class NoiseGen {
public double valueAt(double x, double y)
{
double raw = noiser.noise2(x * density, y * density);
-
+
if (raw < lowBound) {
raw = lowBound;
} else if (raw > highBound) {
raw = highBound;
}
-
+
if (raw < 0) {
return middle + lowMul * raw;
} else {
return middle + highMul * raw;
}
}
-
-
+
+
/**
* Build a map [height][width] of noise values
- *
+ *
* @param width map width (number of columns)
* @param height map height (number of rows )
* @return the map
@@ -95,13 +97,13 @@ public class NoiseGen {
public double[][] buildMap(int width, int height)
{
final double[][] map = new double[height][width];
-
+
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
map[y][x] = valueAt(x, y);
}
}
-
+
return map;
}
}
diff --git a/src/mightypork/utils/math/noise/PerlinNoiseGenerator.java b/src/mightypork/utils/math/noise/PerlinNoiseGenerator.java
index 19afdc3..96f6114 100644
--- a/src/mightypork/utils/math/noise/PerlinNoiseGenerator.java
+++ b/src/mightypork/utils/math/noise/PerlinNoiseGenerator.java
@@ -25,61 +25,63 @@ import java.util.Random;
*
* Computing noise for one and two dimensions can make use of the 3D problem
* space by just setting the un-needed dimensions to a fixed value.
- *
+ *
* @author Justin Couch
* @edited by Ondřej Hruška
* @version $Revision: 1.4 $
* @source http://code.j3d.org/download.html
*/
public class PerlinNoiseGenerator {
-
+
// Constants for setting up the Perlin-1 noise functions
private static final int B = 0x1000;
private static final int BM = 0xff;
-
+
private static final int N = 0x1000;
-
+
/** Default seed to use for the random number generation */
private static final int DEFAULT_SEED = 100;
-
+
/** Default sample size to work with */
private static final int DEFAULT_SAMPLE_SIZE = 256;
-
+
private final Random rand = new Random(DEFAULT_SEED);
-
+
/** Permutation array for the improved noise function */
private final int[] p_imp;
-
+
/** P array for perline 1 noise */
private int[] p;
private double[][] g3;
private double[][] g2;
private double[] g1;
-
-
+
+
/**
* Create a new noise creator with the default seed value
*/
- public PerlinNoiseGenerator() {
+ public PerlinNoiseGenerator()
+ {
this(DEFAULT_SEED);
}
-
-
+
+
/**
* Create a new noise creator with the given seed value for the randomness
- *
+ *
* @param seed The seed value to use
*/
- public PerlinNoiseGenerator(long seed) {
+ public PerlinNoiseGenerator(long seed)
+ {
p_imp = new int[DEFAULT_SAMPLE_SIZE << 1];
-
+
int i, j, k;
rand.setSeed(seed);
-
+
// Calculate the table of psuedo-random coefficients.
for (i = 0; i < DEFAULT_SAMPLE_SIZE; i++)
p_imp[i] = i;
-
+
// generate the psuedo-random permutation table.
while (--i > 0) {
k = p_imp[i];
@@ -87,14 +89,14 @@ public class PerlinNoiseGenerator {
p_imp[i] = p_imp[j];
p_imp[j] = k;
}
-
+
initPerlin1();
}
-
-
+
+
/**
* Computes noise function for three dimensions at the point (x,y,z).
- *
+ *
* @param x x dimension parameter
* @param y y dimension parameter
* @param z z dimension parameter
@@ -106,27 +108,27 @@ public class PerlinNoiseGenerator {
final int uc_x = (int) Math.floor(x) & 255;
final int uc_y = (int) Math.floor(y) & 255;
final int uc_z = (int) Math.floor(z) & 255;
-
+
// Relative location of the point in the unit cube
final double xo = x - Math.floor(x);
final double yo = y - Math.floor(y);
final double zo = z - Math.floor(z);
-
+
// Fade curves for x, y and z
final double u = fade(xo);
final double v = fade(yo);
final double w = fade(zo);
-
+
// Generate a hash for each coordinate to find out where in the cube
// it lies.
final int a = p_imp[uc_x] + uc_y;
final int aa = p_imp[a] + uc_z;
final int ab = p_imp[a + 1] + uc_z;
-
+
final int b = p_imp[uc_x + 1] + uc_y;
final int ba = p_imp[b] + uc_z;
final int bb = p_imp[b + 1] + uc_z;
-
+
// blend results from the 8 corners based on the noise function
final double c1 = grad(p_imp[aa], xo, yo, zo);
final double c2 = grad(p_imp[ba], xo - 1, yo, zo);
@@ -136,14 +138,14 @@ public class PerlinNoiseGenerator {
final double c6 = grad(p_imp[ba + 1], xo - 1, yo, zo - 1);
final double c7 = grad(p_imp[ab + 1], xo, yo - 1, zo - 1);
final double c8 = grad(p_imp[bb + 1], xo - 1, yo - 1, zo - 1);
-
+
return lerp(w, lerp(v, lerp(u, c1, c2), lerp(u, c3, c4)), lerp(v, lerp(u, c5, c6), lerp(u, c7, c8)));
}
-
-
+
+
/**
* 1-D noise generation function using the original perlin algorithm.
- *
+ *
* @param x Seed for the noise function
* @return The noisy output
*/
@@ -154,19 +156,19 @@ public class PerlinNoiseGenerator {
final int bx1 = (bx0 + 1) & BM;
final double rx0 = t - (int) t;
final double rx1 = rx0 - 1;
-
+
final double sx = sCurve(rx0);
-
+
final double u = rx0 * g1[p[bx0]];
final double v = rx1 * g1[p[bx1]];
-
+
return lerp(sx, u, v);
}
-
-
+
+
/**
* Create noise in a 2D space using the orignal perlin noise algorithm.
- *
+ *
* @param x The X coordinate of the location to sample
* @param y The Y coordinate of the location to sample
* @return A noisy value at the given position
@@ -178,43 +180,43 @@ public class PerlinNoiseGenerator {
final int bx1 = (bx0 + 1) & BM;
final double rx0 = t - (int) t;
final double rx1 = rx0 - 1;
-
+
t = y + N;
final int by0 = ((int) t) & BM;
final int by1 = (by0 + 1) & BM;
final double ry0 = t - (int) t;
final double ry1 = ry0 - 1;
-
+
final int i = p[bx0];
final int j = p[bx1];
-
+
final int b00 = p[i + by0];
final int b10 = p[j + by0];
final int b01 = p[i + by1];
final int b11 = p[j + by1];
-
+
final double sx = sCurve(rx0);
final double sy = sCurve(ry0);
-
+
double[] q = g2[b00];
double u = rx0 * q[0] + ry0 * q[1];
q = g2[b10];
double v = rx1 * q[0] + ry0 * q[1];
final double a = lerp(sx, u, v);
-
+
q = g2[b01];
u = rx0 * q[0] + ry1 * q[1];
q = g2[b11];
v = rx1 * q[0] + ry1 * q[1];
final double b = lerp(sx, u, v);
-
+
return lerp(sy, a, b);
}
-
-
+
+
/**
* Create noise in a 3D space using the orignal perlin noise algorithm.
- *
+ *
* @param x The X coordinate of the location to sample
* @param y The Y coordinate of the location to sample
* @param z The Z coordinate of the location to sample
@@ -227,73 +229,73 @@ public class PerlinNoiseGenerator {
final int bx1 = (bx0 + 1) & BM;
final double rx0 = t - (int) t;
final double rx1 = rx0 - 1;
-
+
t = y + N;
final int by0 = ((int) t) & BM;
final int by1 = (by0 + 1) & BM;
final double ry0 = t - (int) t;
final double ry1 = ry0 - 1;
-
+
t = z + N;
final int bz0 = ((int) t) & BM;
final int bz1 = (bz0 + 1) & BM;
final double rz0 = t - (int) t;
final double rz1 = rz0 - 1;
-
+
final int i = p[bx0];
final int j = p[bx1];
-
+
final int b00 = p[i + by0];
final int b10 = p[j + by0];
final int b01 = p[i + by1];
final int b11 = p[j + by1];
-
+
t = sCurve(rx0);
final double sy = sCurve(ry0);
final double sz = sCurve(rz0);
-
+
double[] q = g3[b00 + bz0];
double u = (rx0 * q[0] + ry0 * q[1] + rz0 * q[2]);
q = g3[b10 + bz0];
double v = (rx1 * q[0] + ry0 * q[1] + rz0 * q[2]);
double a = lerp(t, u, v);
-
+
q = g3[b01 + bz0];
u = (rx0 * q[0] + ry1 * q[1] + rz0 * q[2]);
q = g3[b11 + bz0];
v = (rx1 * q[0] + ry1 * q[1] + rz0 * q[2]);
double b = lerp(t, u, v);
-
+
final double c = lerp(sy, a, b);
-
+
q = g3[b00 + bz1];
u = (rx0 * q[0] + ry0 * q[1] + rz1 * q[2]);
q = g3[b10 + bz1];
v = (rx1 * q[0] + ry0 * q[1] + rz1 * q[2]);
a = lerp(t, u, v);
-
+
q = g3[b01 + bz1];
u = (rx0 * q[0] + ry1 * q[1] + rz1 * q[2]);
q = g3[b11 + bz1];
v = (rx1 * q[0] + ry1 * q[1] + rz1 * q[2]);
b = lerp(t, u, v);
-
+
final double d = lerp(sy, a, b);
-
+
return lerp(sz, c, d);
}
-
-
+
+
/**
* Create a turbulent noise output based on the core noise function. This
* uses the noise as a base function and is suitable for creating clouds,
* marble and explosion effects. For example, a typical marble effect would
* set the colour to be:
- *
+ *
*
- * sin(point + turbulence(point) * point.x);
- *
- *
+ * sin(point + turbulence(point) * point.x);
+ *
+ *
* @param x
* @param y
* @param z
@@ -308,23 +310,23 @@ public class PerlinNoiseGenerator {
double p_z = z;
double t = 0;
double f;
-
+
for (f = loF; f < hiF; f *= 2) {
t += Math.abs(improvedNoise(p_x, p_y, p_z)) / f;
-
+
p_x *= 2;
p_y *= 2;
p_z *= 2;
}
-
+
return t - 0.3;
}
-
-
+
+
/**
* Create a turbulance function in 2D using the original perlin noise
* function.
- *
+ *
* @param x The X coordinate of the location to sample
* @param y The Y coordinate of the location to sample
* @param freq The frequency of the turbluance to create
@@ -333,20 +335,20 @@ public class PerlinNoiseGenerator {
public double turbulence2(double x, double y, double freq)
{
double t = 0;
-
+
do {
t += noise2(freq * x, freq * y) / freq;
freq *= 0.5f;
} while (freq >= 1);
-
+
return t;
}
-
-
+
+
/**
* Create a turbulance function in 3D using the original perlin noise
* function.
- *
+ *
* @param x The X coordinate of the location to sample
* @param y The Y coordinate of the location to sample
* @param z The Z coordinate of the location to sample
@@ -356,19 +358,19 @@ public class PerlinNoiseGenerator {
public double turbulence3(double x, double y, double z, double freq)
{
double t = 0;
-
+
do {
t += noise3(freq * x, freq * y, freq * z) / freq;
freq *= 0.5f;
} while (freq >= 1);
-
+
return t;
}
-
-
+
+
/**
* Create a 1D tileable noise function for the given width.
- *
+ *
* @param x The X coordinate to generate the noise for
* @param w The width of the tiled block
* @return The value of the noise at the given coordinate
@@ -377,11 +379,11 @@ public class PerlinNoiseGenerator {
{
return (noise1(x) * (w - x) + noise1(x - w) * x) / w;
}
-
-
+
+
/**
* Create a 2D tileable noise function for the given width and height.
- *
+ *
* @param x The X coordinate to generate the noise for
* @param y The Y coordinate to generate the noise for
* @param w The width of the tiled block
@@ -392,12 +394,12 @@ public class PerlinNoiseGenerator {
{
return (noise2(x, y) * (w - x) * (h - y) + noise2(x - w, y) * x * (h - y) + noise2(x, y - h) * (w - x) * y + noise2(x - w, y - h) * x * y) / (w * h);
}
-
-
+
+
/**
* Create a 3D tileable noise function for the given width, height and
* depth.
- *
+ *
* @param x The X coordinate to generate the noise for
* @param y The Y coordinate to generate the noise for
* @param z The Z coordinate to generate the noise for
@@ -408,13 +410,16 @@ public class PerlinNoiseGenerator {
*/
public double tileableNoise3(double x, double y, double z, double w, double h, double d)
{
- return (noise3(x, y, z) * (w - x) * (h - y) * (d - z) + noise3(x - w, y, z) * x * (h - y) * (d - z) + noise3(x, y - h, z) * (w - x) * y * (d - z) + noise3(x - w, y - h, z) * x * y * (d - z) + noise3(x, y, z - d) * (w - x) * (h - y) * z + noise3(x - w, y, z - d) * x * (h - y) * z + noise3(x, y - h, z - d) * (w - x) * y * z + noise3(x - w, y - h, z - d) * x * y * z) / (w * h * d);
+ return (noise3(x, y, z) * (w - x) * (h - y) * (d - z) + noise3(x - w, y, z) * x * (h - y) * (d - z) + noise3(x, y - h, z) * (w - x) * y * (d - z)
+ + noise3(x - w, y - h, z) * x * y * (d - z) + noise3(x, y, z - d) * (w - x) * (h - y) * z + noise3(x - w, y, z - d) * x * (h - y) * z
+ + noise3(x, y - h, z - d) * (w - x) * y * z + noise3(x - w, y - h, z - d) * x * y * z)
+ / (w * h * d);
}
-
-
+
+
/**
* Create a turbulance function that can be tiled across a surface in 2D.
- *
+ *
* @param x The X coordinate of the location to sample
* @param y The Y coordinate of the location to sample
* @param w The width to tile over
@@ -425,19 +430,19 @@ public class PerlinNoiseGenerator {
public double tileableTurbulence2(double x, double y, double w, double h, double freq)
{
double t = 0;
-
+
do {
t += tileableNoise2(freq * x, freq * y, w * freq, h * freq) / freq;
freq *= 0.5f;
} while (freq >= 1);
-
+
return t;
}
-
-
+
+
/**
* Create a turbulance function that can be tiled across a surface in 3D.
- *
+ *
* @param x The X coordinate of the location to sample
* @param y The Y coordinate of the location to sample
* @param z The Z coordinate of the location to sample
@@ -450,16 +455,16 @@ public class PerlinNoiseGenerator {
public double tileableTurbulence3(double x, double y, double z, double w, double h, double d, double freq)
{
double t = 0;
-
+
do {
t += tileableNoise3(freq * x, freq * y, freq * z, w * freq, h * freq, d * freq) / freq;
freq *= 0.5f;
} while (freq >= 1);
-
+
return t;
}
-
-
+
+
/**
* Simple lerp function using doubles.
*/
@@ -467,12 +472,12 @@ public class PerlinNoiseGenerator {
{
return a + t * (b - a);
}
-
-
+
+
/**
* Fade curve calculation which is 6t^5 - 15t^4 + 10t^3. This is the new
* algorithm, where the old one used to be 3t^2 - 2t^3.
- *
+ *
* @param t The t parameter to calculate the fade for
* @return the drop-off amount.
*/
@@ -480,8 +485,8 @@ public class PerlinNoiseGenerator {
{
return t * t * t * (t * (t * 6 - 15) + 10);
}
-
-
+
+
/**
* Calculate the gradient function based on the hash code.
*/
@@ -491,11 +496,11 @@ public class PerlinNoiseGenerator {
final int h = hash & 15;
final double u = (h < 8 || h == 12 || h == 13) ? x : y;
final double v = (h < 4 || h == 12 || h == 13) ? y : z;
-
+
return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
}
-
-
+
+
/**
* S-curve function for value distribution for Perlin-1 noise function.
*/
@@ -503,8 +508,8 @@ public class PerlinNoiseGenerator {
{
return (t * t * (3 - 2 * t));
}
-
-
+
+
/**
* 2D-vector normalisation function.
*/
@@ -514,8 +519,8 @@ public class PerlinNoiseGenerator {
v[0] *= s;
v[1] *= s;
}
-
-
+
+
/**
* 3D-vector normalisation function.
*/
@@ -526,8 +531,8 @@ public class PerlinNoiseGenerator {
v[1] *= s;
v[2] *= s;
}
-
-
+
+
/**
* Initialise the lookup arrays used by Perlin 1 function.
*/
@@ -538,28 +543,28 @@ public class PerlinNoiseGenerator {
g2 = new double[B + B + 2][2];
g1 = new double[B + B + 2];
int i, j, k;
-
+
for (i = 0; i < B; i++) {
p[i] = i;
-
+
g1[i] = (((rand.nextDouble() * Integer.MAX_VALUE) % (B + B)) - B) / B;
-
+
for (j = 0; j < 2; j++)
g2[i][j] = (((rand.nextDouble() * Integer.MAX_VALUE) % (B + B)) - B) / B;
normalize2(g2[i]);
-
+
for (j = 0; j < 3; j++)
g3[i][j] = (((rand.nextDouble() * Integer.MAX_VALUE) % (B + B)) - B) / B;
normalize3(g3[i]);
}
-
+
while (--i > 0) {
k = p[i];
j = (int) ((rand.nextDouble() * Integer.MAX_VALUE) % B);
p[i] = p[j];
p[j] = k;
}
-
+
for (i = 0; i < B + 2; i++) {
p[B + i] = p[i];
g1[B + i] = g1[i];
diff --git a/src/mightypork/utils/math/timing/FpsMeter.java b/src/mightypork/utils/math/timing/FpsMeter.java
index 1c22e49..aaeb15d 100644
--- a/src/mightypork/utils/math/timing/FpsMeter.java
+++ b/src/mightypork/utils/math/timing/FpsMeter.java
@@ -4,16 +4,16 @@ package mightypork.utils.math.timing;
/**
* Class for counting FPS in games.
* This class can be used also as a simple frequency meter - output is in Hz.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class FpsMeter {
-
+
private long frames = 0;
private long lastTimeMillis = System.currentTimeMillis();
private long lastSecFPS = 0;
-
-
+
+
/**
* @return current second's FPS
*/
@@ -21,8 +21,8 @@ public class FpsMeter {
{
return lastSecFPS;
}
-
-
+
+
/**
* Notification that frame was rendered
*/
diff --git a/src/mightypork/utils/math/timing/Profiler.java b/src/mightypork/utils/math/timing/Profiler.java
index 79700c8..b4a5f93 100644
--- a/src/mightypork/utils/math/timing/Profiler.java
+++ b/src/mightypork/utils/math/timing/Profiler.java
@@ -4,29 +4,60 @@ package mightypork.utils.math.timing;
import mightypork.utils.Support;
+/**
+ * Time metering utils for profiling.
+ * The profiler work with long (starting ms time), so it has very little
+ * overhead and you can easily have multiple "profilers" running at the same
+ * time.
+ *
+ * @author Ondřej Hruška (MightyPork)
+ */
public class Profiler {
-
+
+ /**
+ * Get current time, to be later used in the end*() methods
+ *
+ * @return current time (ms)
+ */
public static long begin()
{
return System.currentTimeMillis();
}
-
-
+
+
+ /**
+ * Get seconds since begin.
+ *
+ * @param begun profiling start time (ms), obtained using begin()
+ * @return seconds elapsed
+ */
public static double end(long begun)
{
- return endLong(begun) / 1000D;
+ return endMs(begun) / 1000D;
}
-
-
- public static long endLong(long begun)
+
+
+ /**
+ * Get milliseconds since begin.
+ *
+ * @param begun profiling start time (ms), obtained using begin()
+ * @return milliseconds elapsed
+ */
+ public static long endMs(long begun)
{
return System.currentTimeMillis() - begun;
}
-
-
+
+
+ /**
+ * Elapsed time in human readable format, in seconds.
+ *
+ * @param begun profiling start time (ms), obtained using begin()
+ * @return something like "0.121 s"
+ */
public static String endStr(long begun)
{
return Support.str(end(begun)) + " s";
}
-
+
}
diff --git a/src/mightypork/utils/math/timing/TaskRepeater.java b/src/mightypork/utils/math/timing/TaskRepeater.java
index f221101..10960c8 100644
--- a/src/mightypork/utils/math/timing/TaskRepeater.java
+++ b/src/mightypork/utils/math/timing/TaskRepeater.java
@@ -7,38 +7,39 @@ import mightypork.utils.math.animation.NumAnimated;
public abstract class TaskRepeater extends AnimatorRewind implements Runnable, Enableable {
-
+
private boolean enabled = true;
-
-
- public TaskRepeater(double period) {
+
+
+ public TaskRepeater(double period)
+ {
super(period);
}
-
-
+
+
@Override
protected void nextCycle(NumAnimated anim)
{
if (isEnabled()) run();
super.nextCycle(anim);
}
-
-
+
+
@Override
public void setEnabled(boolean yes)
{
this.enabled = yes;
}
-
-
+
+
@Override
public boolean isEnabled()
{
return enabled;
}
-
-
+
+
@Override
public abstract void run();
-
+
}
diff --git a/src/mightypork/utils/math/timing/TimedTask.java b/src/mightypork/utils/math/timing/TimedTask.java
index 7bebf05..11407fc 100644
--- a/src/mightypork/utils/math/timing/TimedTask.java
+++ b/src/mightypork/utils/math/timing/TimedTask.java
@@ -7,15 +7,15 @@ import mightypork.utils.math.animation.NumAnimated;
/**
* Delayed runnable controlled by delta timing.
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public abstract class TimedTask implements Runnable, Updateable {
-
+
private final NumAnimated timer = new NumAnimated(0);
private boolean running = false;
-
-
+
+
@Override
public void update(double delta)
{
@@ -27,26 +27,26 @@ public abstract class TimedTask implements Runnable, Updateable {
}
}
}
-
-
+
+
public boolean isRunning()
{
return !timer.isFinished();
}
-
-
+
+
public void start(double seconds)
{
timer.reset();
timer.animate(1, seconds);
running = true;
}
-
-
+
+
public void stop()
{
running = false;
timer.reset();
}
-
+
}
diff --git a/src/mightypork/utils/math/timing/TimerDelta.java b/src/mightypork/utils/math/timing/TimerDelta.java
index 8833e0c..851d8c7 100644
--- a/src/mightypork/utils/math/timing/TimerDelta.java
+++ b/src/mightypork/utils/math/timing/TimerDelta.java
@@ -3,38 +3,39 @@ package mightypork.utils.math.timing;
/**
* Timer for delta timing
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class TimerDelta {
-
+
private long lastFrame;
-
+
private static final long SECOND = 1000000000; // a million nanoseconds
-
-
+
+
/**
* New delta timer
*/
- public TimerDelta() {
+ public TimerDelta()
+ {
lastFrame = System.nanoTime();
}
-
-
+
+
/**
* Get current time in NS
- *
+ *
* @return current time NS
*/
public long getTime()
{
return System.nanoTime();
}
-
-
+
+
/**
* Get time since the last "getDelta()" call.
- *
+ *
* @return delta time (seconds)
*/
public double getDelta()
diff --git a/src/mightypork/utils/math/timing/TimerFps.java b/src/mightypork/utils/math/timing/TimerFps.java
index 786a443..a44fb30 100644
--- a/src/mightypork/utils/math/timing/TimerFps.java
+++ b/src/mightypork/utils/math/timing/TimerFps.java
@@ -3,33 +3,34 @@ package mightypork.utils.math.timing;
/**
* Timer for interpolated timing
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class TimerFps {
-
+
private long lastFrame = 0;
private long nextFrame = 0;
private long skipped = 0;
private long lastSkipped = 0;
-
+
private static final long SECOND = 1000000000; // a million nanoseconds
private final long FRAME; // a time of one frame in nanoseconds
-
-
+
+
/**
* New interpolated timer
- *
+ *
* @param fps target FPS
*/
- public TimerFps(long fps) {
+ public TimerFps(long fps)
+ {
FRAME = Math.round(SECOND / (double) fps);
-
+
lastFrame = System.nanoTime();
nextFrame = System.nanoTime() + FRAME;
}
-
-
+
+
/**
* Sync and calculate dropped frames etc.
*/
@@ -43,22 +44,22 @@ public class TimerFps {
nextFrame += skippedNow * FRAME;
}
}
-
-
+
+
/**
* Get nanotime
- *
+ *
* @return nanotime
*/
public long getTime()
{
return System.nanoTime();
}
-
-
+
+
/**
* Get fraction of next frame
- *
+ *
* @return fraction
*/
public double getFraction()
@@ -66,20 +67,20 @@ public class TimerFps {
if (getSkipped() >= 1) {
return 1;
}
-
+
final long time = getTime();
-
+
if (time <= nextFrame) {
return (double) (time - lastFrame) / (double) FRAME;
}
-
+
return 1;
}
-
-
+
+
/**
* Get number of elapsed ticks
- *
+ *
* @return ticks
*/
public int getSkipped()
@@ -88,8 +89,8 @@ public class TimerFps {
lastSkipped = skipped;
return (int) change;
}
-
-
+
+
/**
* Clear timer and start counting new tick.
*/
diff --git a/src/mightypork/utils/string/AlphanumComparator.java b/src/mightypork/utils/string/AlphanumComparator.java
index db8ab08..dee9f0b 100644
--- a/src/mightypork/utils/string/AlphanumComparator.java
+++ b/src/mightypork/utils/string/AlphanumComparator.java
@@ -30,23 +30,23 @@ import java.util.Comparator;
/**
* String comparator taking care of strings with numbers.
- *
+ *
* @author Daniel Migowski
* @author Andre Bogus
* @author David Koelle
* @author Ondřej Hruška (MightyPork)
*/
public class AlphanumComparator implements Comparator {
-
+
public static final AlphanumComparator instance = new AlphanumComparator();
-
-
+
+
private final boolean isDigit(char ch)
{
return ch >= '0' && ch <= '9';
}
-
-
+
+
/**
* Length of string is passed in for improved efficiency (only need to
* calculate it once)
@@ -57,7 +57,7 @@ public class AlphanumComparator implements Comparator {
char c = s.charAt(marker);
chunk.append(c);
marker++;
-
+
if (isDigit(c)) {
while (marker < slength) {
c = s.charAt(marker);
@@ -75,8 +75,8 @@ public class AlphanumComparator implements Comparator {
}
return chunk.toString();
}
-
-
+
+
@Override
public int compare(String s1, String s2)
{
@@ -84,14 +84,14 @@ public class AlphanumComparator implements Comparator {
int thatMarker = 0;
final int s1Length = s1.length();
final int s2Length = s2.length();
-
+
while (thisMarker < s1Length && thatMarker < s2Length) {
final String thisChunk = getChunk(s1, s1Length, thisMarker);
thisMarker += thisChunk.length();
-
+
final String thatChunk = getChunk(s2, s2Length, thatMarker);
thatMarker += thatChunk.length();
-
+
// If both chunks contain numeric characters, sort them numerically
int result = 0;
if (isDigit(thisChunk.charAt(0)) && isDigit(thatChunk.charAt(0))) {
@@ -110,10 +110,10 @@ public class AlphanumComparator implements Comparator {
} else {
result = thisChunk.compareTo(thatChunk);
}
-
+
if (result != 0) return result;
}
-
+
return s1Length - s2Length;
}
}
diff --git a/src/mightypork/utils/string/StringProvider.java b/src/mightypork/utils/string/StringProvider.java
index 5376c91..41fcf63 100644
--- a/src/mightypork/utils/string/StringProvider.java
+++ b/src/mightypork/utils/string/StringProvider.java
@@ -3,10 +3,10 @@ package mightypork.utils.string;
/**
* Can be used for dynamic string generating
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public interface StringProvider {
-
+
String getString();
}
diff --git a/src/mightypork/utils/string/StringUtil.java b/src/mightypork/utils/string/StringUtil.java
index 1c2e472..659d74f 100644
--- a/src/mightypork/utils/string/StringUtil.java
+++ b/src/mightypork/utils/string/StringUtil.java
@@ -3,41 +3,41 @@ package mightypork.utils.string;
/**
* General purpose string utilities
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class StringUtil {
-
+
public static String fromLastDot(String s)
{
return fromLastChar(s, '.');
}
-
-
+
+
public static String toLastDot(String s)
{
return toLastChar(s, '.');
}
-
-
+
+
public static String fromLastChar(String s, char c)
{
if (s == null) return null;
return s.substring(s.lastIndexOf(c) + 1, s.length());
}
-
-
+
+
public static String toLastChar(String s, char c)
{
if (s == null) return null;
if (s.lastIndexOf(c) == -1) return s;
return s.substring(0, s.lastIndexOf(c));
}
-
-
+
+
/**
* Repeat a string
- *
+ *
* @param repeated string
* @param count
* @return output
@@ -49,20 +49,20 @@ public class StringUtil {
s += repeated;
return s;
}
-
-
+
+
public static boolean isValidFilenameChar(char ch)
{
return isValidFilenameString(Character.toString(ch));
}
-
-
+
+
public static boolean isValidFilenameString(String filename)
{
return filename.matches("[a-zA-Z0-9 +\\-.,_%@#!]+");
}
-
-
+
+
public static String ellipsisStart(String orig, int length)
{
if (orig.length() > length) {
@@ -70,8 +70,8 @@ public class StringUtil {
}
return orig;
}
-
-
+
+
public static String ellipsisEnd(String orig, int length)
{
if (orig.length() > length) {
diff --git a/src/mightypork/utils/string/StringWrapper.java b/src/mightypork/utils/string/StringWrapper.java
index 551583c..586f399 100644
--- a/src/mightypork/utils/string/StringWrapper.java
+++ b/src/mightypork/utils/string/StringWrapper.java
@@ -2,16 +2,33 @@ package mightypork.utils.string;
/**
- * String provider with constant string
- *
+ * String provider that holds a string.
+ *
* @author Ondřej Hruška (MightyPork)
*/
public class StringWrapper implements StringProvider {
- private final String value;
+ private String value;
- public StringWrapper(String value) {
+ /**
+ * Create a string wrapper
+ *
+ * @param value original value
+ */
+ public StringWrapper(String value)
+ {
+ this.value = value;
+ }
+
+
+ /**
+ * Set the string
+ *
+ * @param value string to set
+ */
+ public void setString(String value)
+ {
this.value = value;
}
diff --git a/src/mightypork/utils/string/validation/CharFilter.java b/src/mightypork/utils/string/validation/CharFilter.java
index 33ecd31..7354360 100644
--- a/src/mightypork/utils/string/validation/CharFilter.java
+++ b/src/mightypork/utils/string/validation/CharFilter.java
@@ -2,6 +2,6 @@ package mightypork.utils.string.validation;
public interface CharFilter {
-
+
public boolean isValid(char c);
}
diff --git a/src/mightypork/utils/string/validation/CharFilterRegex.java b/src/mightypork/utils/string/validation/CharFilterRegex.java
index 1272dbf..dc58303 100644
--- a/src/mightypork/utils/string/validation/CharFilterRegex.java
+++ b/src/mightypork/utils/string/validation/CharFilterRegex.java
@@ -2,19 +2,20 @@ package mightypork.utils.string.validation;
public class CharFilterRegex implements CharFilter {
-
+
private final String formula;
-
-
- public CharFilterRegex(String regex) {
+
+
+ public CharFilterRegex(String regex)
+ {
this.formula = regex;
}
-
-
+
+
@Override
public boolean isValid(char c)
{
return Character.toString(c).matches(formula);
}
-
+
}
diff --git a/src/mightypork/utils/string/validation/CharFilterWhitelist.java b/src/mightypork/utils/string/validation/CharFilterWhitelist.java
index 5ab41e6..6a83f7f 100644
--- a/src/mightypork/utils/string/validation/CharFilterWhitelist.java
+++ b/src/mightypork/utils/string/validation/CharFilterWhitelist.java
@@ -2,19 +2,20 @@ package mightypork.utils.string.validation;
public class CharFilterWhitelist implements CharFilter {
-
+
private final String whitelist;
-
-
- public CharFilterWhitelist(String allowed) {
+
+
+ public CharFilterWhitelist(String allowed)
+ {
this.whitelist = allowed;
}
-
-
+
+
@Override
public boolean isValid(char c)
{
return whitelist.contains(Character.toString(c));
}
-
+
}
diff --git a/src/mightypork/utils/string/validation/StringFilter.java b/src/mightypork/utils/string/validation/StringFilter.java
index 79a883a..4d656c1 100644
--- a/src/mightypork/utils/string/validation/StringFilter.java
+++ b/src/mightypork/utils/string/validation/StringFilter.java
@@ -3,10 +3,10 @@ package mightypork.utils.string.validation;
/**
* Utility interface for string filters (accepting filepaths and similar)
- *
+ *
* @author Ondřej Hruška (MightyPork)
*/
public interface StringFilter {
-
+
public boolean isValid(String entry);
}
diff --git a/src/mightypork/utils/struct/Mutable.java b/src/mightypork/utils/struct/Mutable.java
index fdf1ad9..30aa004 100644
--- a/src/mightypork/utils/struct/Mutable.java
+++ b/src/mightypork/utils/struct/Mutable.java
@@ -3,56 +3,57 @@ package mightypork.utils.struct;
/**
* Mutable object
- *
+ *
* @author Ondřej Hruška (MightyPork)
* @param type
*/
public class Mutable {
-
+
/** The wrapped value */
private T o = null;
-
-
+
+
/**
* New mutable object
- *
+ *
* @param o value
*/
- public Mutable(T o) {
+ public Mutable(T o)
+ {
this.o = o;
}
-
-
+
+
/**
* Get the wrapped value
- *
+ *
* @return value
*/
public T get()
{
return o;
}
-
-
+
+
/**
* Set value
- *
+ *
* @param o new value to set
*/
public void set(T o)
{
this.o = o;
}
-
-
+
+
@Override
public String toString()
{
if (o == null) return "";
return o.toString();
}
-
-
+
+
@Override
public int hashCode()
{
@@ -61,8 +62,8 @@ public class Mutable {
result = prime * result + ((o == null) ? 0 : o.hashCode());
return result;
}
-
-
+
+
@Override
public boolean equals(Object obj)
{
diff --git a/src/mightypork/utils/struct/Pair.java b/src/mightypork/utils/struct/Pair.java
index 0c04b96..757bb12 100644
--- a/src/mightypork/utils/struct/Pair.java
+++ b/src/mightypork/utils/struct/Pair.java
@@ -3,37 +3,38 @@ package mightypork.utils.struct;
/**
* Structure of 2 objects.
- *
+ *
* @author Ondřej Hruška (MightyPork)
* @copy (c) 2012
* @param 1st object class
* @param 2nd object class
*/
public class Pair {
-
+
/**
* 1st object
*/
public T1 first;
-
+
/**
* 2nd object
*/
public T2 second;
-
-
+
+
/**
* Make structure of 2 objects
- *
+ *
* @param first 1st object
* @param second 2nd object
*/
- public Pair(T1 first, T2 second) {
+ public Pair(T1 first, T2 second)
+ {
this.first = first;
this.second = second;
}
-
-
+
+
/**
* @return 1st object
*/
@@ -41,8 +42,8 @@ public class Pair {
{
return first;
}
-
-
+
+
/**
* @return 2nd object
*/
@@ -50,8 +51,8 @@ public class Pair {
{
return second;
}
-
-
+
+
@Override
public boolean equals(Object obj)
{
@@ -67,8 +68,8 @@ public class Pair {
} else if (!second.equals(other.second)) return false;
return true;
}
-
-
+
+
@Override
public int hashCode()
{
@@ -78,12 +79,12 @@ public class Pair {
result = prime * result + ((second == null) ? 0 : second.hashCode());
return result;
}
-
-
+
+
@Override
public String toString()
{
return "PAIR{" + first + "," + second + "}";
}
-
+
}
diff --git a/src/mightypork/utils/struct/Triad.java b/src/mightypork/utils/struct/Triad.java
index aa788ac..e200f4a 100644
--- a/src/mightypork/utils/struct/Triad.java
+++ b/src/mightypork/utils/struct/Triad.java
@@ -3,7 +3,7 @@ package mightypork.utils.struct;
/**
* Structure of 3 objects.
- *
+ *
* @author Ondřej Hruška (MightyPork)
* @copy (c) 2012
* @param 1st object class
@@ -11,26 +11,27 @@ package mightypork.utils.struct;
* @param 3rd object class
*/
public class Triad extends Pair {
-
+
/**
* 3rd object
*/
public T3 third;
-
-
+
+
/**
* Make structure of 3 objects
- *
+ *
* @param objA 1st object
* @param objB 2nd object
* @param objC 3rd object
*/
- public Triad(T1 objA, T2 objB, T3 objC) {
+ public Triad(T1 objA, T2 objB, T3 objC)
+ {
super(objA, objB);
third = objC;
}
-
-
+
+
/**
* @return 3rd object
*/
@@ -38,49 +39,49 @@ public class Triad extends Pair {
{
return third;
}
-
-
+
+
/**
* Set 1st object
- *
+ *
* @param obj 1st object
*/
public void setThird(T3 obj)
{
third = obj;
}
-
-
+
+
@Override
public boolean equals(Object obj)
{
if (this == obj) return true;
if (obj == null) return false;
if (!(obj instanceof Triad)) return false;
-
+
if (!super.equals(obj)) return false;
-
+
final Triad, ?, ?> other = (Triad, ?, ?>) obj;
-
+
if (third == null) {
if (other.third != null) return false;
} else if (!third.equals(other.third)) return false;
-
+
return true;
}
-
-
+
+
@Override
public int hashCode()
{
return super.hashCode() + (third == null ? 0 : third.hashCode());
}
-
-
+
+
@Override
public String toString()
{
return "TRIAD{" + first + "," + second + "," + third + "}";
}
-
+
}