Some refactoring and cleaning, string utils.
This commit is contained in:
@@ -8,7 +8,7 @@ package mightypork.utils;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class Convert {
|
public class Convert {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get INTEGER
|
* Get INTEGER
|
||||||
*
|
*
|
||||||
@@ -26,8 +26,8 @@ public class Convert {
|
|||||||
} catch (final NumberFormatException e) {}
|
} catch (final NumberFormatException e) {}
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get DOUBLE
|
* Get DOUBLE
|
||||||
*
|
*
|
||||||
@@ -45,8 +45,8 @@ public class Convert {
|
|||||||
} catch (final NumberFormatException e) {}
|
} catch (final NumberFormatException e) {}
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get FLOAT
|
* Get FLOAT
|
||||||
*
|
*
|
||||||
@@ -62,8 +62,8 @@ public class Convert {
|
|||||||
} catch (final NumberFormatException e) {}
|
} catch (final NumberFormatException e) {}
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get BOOLEAN
|
* Get BOOLEAN
|
||||||
*
|
*
|
||||||
@@ -76,7 +76,7 @@ public class Convert {
|
|||||||
if (o == null) return def;
|
if (o == null) return def;
|
||||||
if (o instanceof Boolean) return ((Boolean) o).booleanValue();
|
if (o instanceof Boolean) return ((Boolean) o).booleanValue();
|
||||||
if (o instanceof Number) return ((Number) o).intValue() != 0;
|
if (o instanceof Number) return ((Number) o).intValue() != 0;
|
||||||
|
|
||||||
if (o instanceof String) {
|
if (o instanceof String) {
|
||||||
final String s = ((String) o).trim().toLowerCase();
|
final String s = ((String) o).trim().toLowerCase();
|
||||||
if (s.equals("0")) return false;
|
if (s.equals("0")) return false;
|
||||||
@@ -85,23 +85,23 @@ public class Convert {
|
|||||||
final double n = Double.parseDouble(s);
|
final double n = Double.parseDouble(s);
|
||||||
return n != 0;
|
return n != 0;
|
||||||
} catch (final NumberFormatException e) {}
|
} catch (final NumberFormatException e) {}
|
||||||
|
|
||||||
if (s.equals("true")) return true;
|
if (s.equals("true")) return true;
|
||||||
if (s.equals("yes")) return true;
|
if (s.equals("yes")) return true;
|
||||||
if (s.equals("y")) return true;
|
if (s.equals("y")) return true;
|
||||||
if (s.equals("a")) return true;
|
if (s.equals("a")) return true;
|
||||||
if (s.equals("enabled")) return true;
|
if (s.equals("enabled")) return true;
|
||||||
|
|
||||||
if (s.equals("false")) return false;
|
if (s.equals("false")) return false;
|
||||||
if (s.equals("no")) return false;
|
if (s.equals("no")) return false;
|
||||||
if (s.equals("n")) return false;
|
if (s.equals("n")) return false;
|
||||||
if (s.equals("disabled")) return true;
|
if (s.equals("disabled")) return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get STRING
|
* Get STRING
|
||||||
*
|
*
|
||||||
@@ -113,19 +113,19 @@ public class Convert {
|
|||||||
{
|
{
|
||||||
if (o == null) return def;
|
if (o == null) return def;
|
||||||
if (o instanceof String) return ((String) o);
|
if (o instanceof String) return ((String) o);
|
||||||
|
|
||||||
if (o instanceof Float) return Support.str((float) o);
|
if (o instanceof Float) return Str.val((float) o);
|
||||||
|
|
||||||
if (o instanceof Double) return Support.str((double) o);
|
if (o instanceof Double) return Str.val((double) o);
|
||||||
|
|
||||||
if (o instanceof Class<?>) {
|
if (o instanceof Class<?>) {
|
||||||
return Support.str(o);
|
return Str.val(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
return o.toString();
|
return o.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get INTEGER
|
* Get INTEGER
|
||||||
*
|
*
|
||||||
@@ -136,8 +136,8 @@ public class Convert {
|
|||||||
{
|
{
|
||||||
return toInteger(o, 0);
|
return toInteger(o, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get DOUBLE
|
* Get DOUBLE
|
||||||
*
|
*
|
||||||
@@ -148,8 +148,8 @@ public class Convert {
|
|||||||
{
|
{
|
||||||
return toDouble(o, 0d);
|
return toDouble(o, 0d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get FLOAT
|
* Get FLOAT
|
||||||
*
|
*
|
||||||
@@ -160,8 +160,8 @@ public class Convert {
|
|||||||
{
|
{
|
||||||
return toFloat(o, 0f);
|
return toFloat(o, 0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get BOOLEAN
|
* Get BOOLEAN
|
||||||
*
|
*
|
||||||
@@ -172,8 +172,8 @@ public class Convert {
|
|||||||
{
|
{
|
||||||
return toBoolean(o, false);
|
return toBoolean(o, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get STRING
|
* Get STRING
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import java.util.Map.Entry;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class MapSort {
|
public class MapSort {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sort a map by keys, maintaining key-value pairs, using natural order.
|
* Sort a map by keys, maintaining key-value pairs, using natural order.
|
||||||
*
|
*
|
||||||
@@ -28,8 +28,8 @@ public class MapSort {
|
|||||||
{
|
{
|
||||||
return byKeys(map, null);
|
return byKeys(map, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sort a map by keys, maintaining key-value pairs.
|
* Sort a map by keys, maintaining key-value pairs.
|
||||||
*
|
*
|
||||||
@@ -41,10 +41,10 @@ public class MapSort {
|
|||||||
public static <K, V> LinkedHashMap<K, V> byKeys(Map<K, V> map, Comparator<K> comparator)
|
public static <K, V> LinkedHashMap<K, V> byKeys(Map<K, V> map, Comparator<K> comparator)
|
||||||
{
|
{
|
||||||
final List<K> keys = new LinkedList<>(map.keySet());
|
final List<K> keys = new LinkedList<>(map.keySet());
|
||||||
|
|
||||||
if (comparator == null) {
|
if (comparator == null) {
|
||||||
comparator = new Comparator<K>() {
|
comparator = new Comparator<K>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compare(K arg0, K arg1)
|
public int compare(K arg0, K arg1)
|
||||||
{
|
{
|
||||||
@@ -52,18 +52,18 @@ public class MapSort {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Collections.sort(keys, comparator);
|
Collections.sort(keys, comparator);
|
||||||
|
|
||||||
final LinkedHashMap<K, V> sortedMap = new LinkedHashMap<>();
|
final LinkedHashMap<K, V> sortedMap = new LinkedHashMap<>();
|
||||||
for (final K key : keys) {
|
for (final K key : keys) {
|
||||||
sortedMap.put(key, map.get(key));
|
sortedMap.put(key, map.get(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
return sortedMap;
|
return sortedMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sort a map by values, maintaining key-value pairs, using natural order.
|
* Sort a map by values, maintaining key-value pairs, using natural order.
|
||||||
*
|
*
|
||||||
@@ -75,8 +75,8 @@ public class MapSort {
|
|||||||
{
|
{
|
||||||
return byValues(map, null);
|
return byValues(map, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sort a map by values, maintaining key-value pairs.
|
* Sort a map by values, maintaining key-value pairs.
|
||||||
*
|
*
|
||||||
@@ -87,9 +87,9 @@ public class MapSort {
|
|||||||
public static <K, V> LinkedHashMap<K, V> byValues(Map<K, V> map, final Comparator<V> comparator)
|
public static <K, V> LinkedHashMap<K, V> byValues(Map<K, V> map, final Comparator<V> comparator)
|
||||||
{
|
{
|
||||||
final List<Map.Entry<K, V>> entries = new LinkedList<>(map.entrySet());
|
final List<Map.Entry<K, V>> entries = new LinkedList<>(map.entrySet());
|
||||||
|
|
||||||
Collections.sort(entries, new Comparator<Map.Entry<K, V>>() {
|
Collections.sort(entries, new Comparator<Map.Entry<K, V>>() {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public int compare(Entry<K, V> o1, Entry<K, V> o2)
|
public int compare(Entry<K, V> o1, Entry<K, V> o2)
|
||||||
@@ -98,13 +98,13 @@ public class MapSort {
|
|||||||
return comparator.compare(o1.getValue(), o2.getValue());
|
return comparator.compare(o1.getValue(), o2.getValue());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
final LinkedHashMap<K, V> sortedMap = new LinkedHashMap<>();
|
final LinkedHashMap<K, V> sortedMap = new LinkedHashMap<>();
|
||||||
|
|
||||||
for (final Map.Entry<K, V> entry : entries) {
|
for (final Map.Entry<K, V> entry : entries) {
|
||||||
sortedMap.put(entry.getKey(), entry.getValue());
|
sortedMap.put(entry.getKey(), entry.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
return sortedMap;
|
return sortedMap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import java.lang.reflect.Type;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class Reflect {
|
public class Reflect {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get annotation of given type from an object
|
* Get annotation of given type from an object
|
||||||
*
|
*
|
||||||
@@ -26,8 +26,8 @@ public class Reflect {
|
|||||||
{
|
{
|
||||||
return tested.getClass().getAnnotation(annotation);
|
return tested.getClass().getAnnotation(annotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if an object has an annotation of given trype
|
* Check if an object has an annotation of given trype
|
||||||
*
|
*
|
||||||
@@ -39,8 +39,8 @@ public class Reflect {
|
|||||||
{
|
{
|
||||||
return tested.getClass().isAnnotationPresent(annotation);
|
return tested.getClass().isAnnotationPresent(annotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get generic parameters of a class
|
* Get generic parameters of a class
|
||||||
*
|
*
|
||||||
@@ -50,25 +50,25 @@ public class Reflect {
|
|||||||
public static Class<?>[] getGenericParameters(Class<?> clazz)
|
public static Class<?>[] getGenericParameters(Class<?> clazz)
|
||||||
{
|
{
|
||||||
// BEHOLD, MAGIC!
|
// BEHOLD, MAGIC!
|
||||||
|
|
||||||
final Type evtc = clazz.getGenericSuperclass();
|
final Type evtc = clazz.getGenericSuperclass();
|
||||||
|
|
||||||
if (evtc instanceof ParameterizedType) {
|
if (evtc instanceof ParameterizedType) {
|
||||||
final Type[] types = ((ParameterizedType) evtc).getActualTypeArguments();
|
final Type[] types = ((ParameterizedType) evtc).getActualTypeArguments();
|
||||||
|
|
||||||
final Class<?>[] classes = new Class<?>[types.length];
|
final Class<?>[] classes = new Class<?>[types.length];
|
||||||
|
|
||||||
for (int i = 0; i < types.length; i++) {
|
for (int i = 0; i < types.length; i++) {
|
||||||
classes[i] = (Class<?>) types[i];
|
classes[i] = (Class<?>) types[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return classes;
|
return classes;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new RuntimeException(Support.str(clazz) + " is not generic.");
|
throw new RuntimeException(Str.val(clazz) + " is not generic.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get value of a public static final field. If the modifiers don't match,
|
* Get value of a public static final field. If the modifiers don't match,
|
||||||
* an exception is thrown.
|
* an exception is thrown.
|
||||||
@@ -82,15 +82,15 @@ public class Reflect {
|
|||||||
public static Object getConstantFieldValue(Class<?> objClass, String fieldName) throws ReflectiveOperationException
|
public static Object getConstantFieldValue(Class<?> objClass, String fieldName) throws ReflectiveOperationException
|
||||||
{
|
{
|
||||||
final Field fld = objClass.getDeclaredField(fieldName);
|
final Field fld = objClass.getDeclaredField(fieldName);
|
||||||
|
|
||||||
final int modif = fld.getModifiers();
|
final int modif = fld.getModifiers();
|
||||||
|
|
||||||
if (!Modifier.isFinal(modif) || !Modifier.isStatic(modif)) {
|
if (!Modifier.isFinal(modif) || !Modifier.isStatic(modif)) {
|
||||||
throw new ReflectiveOperationException("The " + fieldName + " field of " + Support.str(objClass) + " must be static and final!");
|
throw new ReflectiveOperationException("The " + fieldName + " field of " + Str.val(objClass) + " must be static and final!");
|
||||||
}
|
}
|
||||||
|
|
||||||
fld.setAccessible(true);
|
fld.setAccessible(true);
|
||||||
return fld.get(null);
|
return fld.get(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,231 @@
|
|||||||
|
package mightypork.utils;
|
||||||
|
|
||||||
|
|
||||||
|
import mightypork.utils.annotations.Alias;
|
||||||
|
import mightypork.utils.math.AlignX;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* General purpose string utilities
|
||||||
|
*
|
||||||
|
* @author Ondřej Hruška (MightyPork)
|
||||||
|
*/
|
||||||
|
public class Str {
|
||||||
|
|
||||||
|
public static String fromLastDot(String s)
|
||||||
|
{
|
||||||
|
return fromLast(s, '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String toLastDot(String s)
|
||||||
|
{
|
||||||
|
return toLast(s, '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String fromLast(String s, char c)
|
||||||
|
{
|
||||||
|
if (s == null) return null;
|
||||||
|
if (s.lastIndexOf(c) == -1) return "";
|
||||||
|
return s.substring(s.lastIndexOf(c) + 1, s.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String toLast(String s, char c)
|
||||||
|
{
|
||||||
|
if (s == null) return null;
|
||||||
|
if (s.lastIndexOf(c) == -1) return s;
|
||||||
|
return s.substring(0, s.lastIndexOf(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String fromFirst(String s, char c)
|
||||||
|
{
|
||||||
|
if (s == null) return null;
|
||||||
|
if (s.indexOf(c) == -1) return "";
|
||||||
|
return s.substring(s.indexOf(c) + 1, s.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String toFirst(String s, char c)
|
||||||
|
{
|
||||||
|
if (s == null) return null;
|
||||||
|
if (s.indexOf(c) == -1) return s;
|
||||||
|
return s.substring(0, s.indexOf(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String fromEnd(String s, int chars)
|
||||||
|
{
|
||||||
|
return s.substring(s.length() - chars, s.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String fromStart(String s, int chars)
|
||||||
|
{
|
||||||
|
return s.substring(0, chars);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String pad(String s, int length)
|
||||||
|
{
|
||||||
|
return pad(s, length, AlignX.LEFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String pad(String s, int length, AlignX align)
|
||||||
|
{
|
||||||
|
return pad(s, length, align, ' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String pad(String s, int length, AlignX align, char fill)
|
||||||
|
{
|
||||||
|
final String filling = repeat("" + fill, length);
|
||||||
|
|
||||||
|
switch (align) {
|
||||||
|
case LEFT:
|
||||||
|
s += filling;
|
||||||
|
return fromStart(s, length);
|
||||||
|
|
||||||
|
case RIGHT:
|
||||||
|
s += filling;
|
||||||
|
return fromEnd(s, length);
|
||||||
|
|
||||||
|
case CENTER:
|
||||||
|
|
||||||
|
if (s.length() >= length) return s;
|
||||||
|
|
||||||
|
s = filling + s + filling;
|
||||||
|
|
||||||
|
final int cut = (int) (s.length() / 2D - length / 2D);
|
||||||
|
return s.substring(cut, s.length() - cut);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalArgumentException("Impossible error.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Repeat a string
|
||||||
|
*
|
||||||
|
* @param repeated string
|
||||||
|
* @param count
|
||||||
|
* @return output
|
||||||
|
*/
|
||||||
|
public static String repeat(String repeated, int count)
|
||||||
|
{
|
||||||
|
String s = "";
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
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) {
|
||||||
|
orig = "\u2026" + orig.substring(length, orig.length());
|
||||||
|
}
|
||||||
|
return orig;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String ellipsisEnd(String orig, int length)
|
||||||
|
{
|
||||||
|
if (orig.length() > length) {
|
||||||
|
orig = orig.substring(0, length - 1) + "\u2026";
|
||||||
|
}
|
||||||
|
return orig;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a class to string, preserving name and outer class, but excluding
|
||||||
|
* path.
|
||||||
|
*
|
||||||
|
* @param cls the class
|
||||||
|
* @return class name
|
||||||
|
*/
|
||||||
|
public static String val(Class<?> cls)
|
||||||
|
{
|
||||||
|
final Alias ln = cls.getAnnotation(Alias.class);
|
||||||
|
if (ln != null) {
|
||||||
|
return ln.name();
|
||||||
|
}
|
||||||
|
|
||||||
|
String name = cls.getName();
|
||||||
|
|
||||||
|
String sep = "";
|
||||||
|
|
||||||
|
if (name.contains("$")) {
|
||||||
|
name = name.substring(name.lastIndexOf("$") + 1);
|
||||||
|
sep = "$";
|
||||||
|
} else {
|
||||||
|
name = name.substring(name.lastIndexOf(".") + 1);
|
||||||
|
sep = ".";
|
||||||
|
}
|
||||||
|
|
||||||
|
final Class<?> enclosing = cls.getEnclosingClass();
|
||||||
|
|
||||||
|
return (enclosing == null ? "" : Str.val(enclosing) + sep) + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert double to string, remove the mess at the end.
|
||||||
|
*
|
||||||
|
* @param d double
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static String val(Double d)
|
||||||
|
{
|
||||||
|
String s = d.toString();
|
||||||
|
s = s.replace(',', '.');
|
||||||
|
s = s.replaceAll("([0-9]+\\.[0-9]+)00+[0-9]+", "$1");
|
||||||
|
s = s.replaceAll("0+$", "");
|
||||||
|
s = s.replaceAll("\\.$", "");
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
public static String val(Object o)
|
||||||
|
{
|
||||||
|
if (o == null) return "<null>";
|
||||||
|
|
||||||
|
boolean hasToString = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
hasToString = (o.getClass().getMethod("toString").getDeclaringClass() != Object.class);
|
||||||
|
} catch (final Throwable t) {
|
||||||
|
// oh well..
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasToString) {
|
||||||
|
return o.toString();
|
||||||
|
} else {
|
||||||
|
|
||||||
|
return val(o.getClass());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,8 +9,6 @@ import java.util.Iterator;
|
|||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import mightypork.utils.annotations.Alias;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Miscelanous utilities
|
* Miscelanous utilities
|
||||||
@@ -18,7 +16,7 @@ import mightypork.utils.annotations.Alias;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public final class Support {
|
public final class Support {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new thread of the runnable, and start it.
|
* Create a new thread of the runnable, and start it.
|
||||||
*
|
*
|
||||||
@@ -31,8 +29,8 @@ public final class Support {
|
|||||||
t.start();
|
t.start();
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pick first non-null option
|
* Pick first non-null option
|
||||||
*
|
*
|
||||||
@@ -44,11 +42,11 @@ public final class Support {
|
|||||||
for (final Object o : options) {
|
for (final Object o : options) {
|
||||||
if (o != null) return o;
|
if (o != null) return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null; // all null
|
return null; // all null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get current time/date for given format.
|
* Get current time/date for given format.
|
||||||
*
|
*
|
||||||
@@ -59,8 +57,8 @@ public final class Support {
|
|||||||
{
|
{
|
||||||
return (new SimpleDateFormat(format)).format(new Date());
|
return (new SimpleDateFormat(format)).format(new Date());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse array of vararg key, value pairs to a LinkedHashMap.<br>
|
* Parse array of vararg key, value pairs to a LinkedHashMap.<br>
|
||||||
* Example:
|
* Example:
|
||||||
@@ -85,11 +83,11 @@ public final class Support {
|
|||||||
public static <K, V> Map<K, V> parseVarArgs(Object... args) throws ClassCastException, IllegalArgumentException
|
public static <K, V> Map<K, V> parseVarArgs(Object... args) throws ClassCastException, IllegalArgumentException
|
||||||
{
|
{
|
||||||
final LinkedHashMap<K, V> attrs = new LinkedHashMap<>();
|
final LinkedHashMap<K, V> attrs = new LinkedHashMap<>();
|
||||||
|
|
||||||
if (args.length % 2 != 0) {
|
if (args.length % 2 != 0) {
|
||||||
throw new IllegalArgumentException("Odd number of elements in varargs map!");
|
throw new IllegalArgumentException("Odd number of elements in varargs map!");
|
||||||
}
|
}
|
||||||
|
|
||||||
K key = null;
|
K key = null;
|
||||||
for (final Object o : args) {
|
for (final Object o : args) {
|
||||||
if (key == null) {
|
if (key == null) {
|
||||||
@@ -100,11 +98,11 @@ public final class Support {
|
|||||||
key = null;
|
key = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return attrs;
|
return attrs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get if an Object is in array (using equals)
|
* Get if an Object is in array (using equals)
|
||||||
*
|
*
|
||||||
@@ -119,8 +117,8 @@ public final class Support {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get if string is in array
|
* Get if string is in array
|
||||||
*
|
*
|
||||||
@@ -140,8 +138,8 @@ public final class Support {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make enumeration iterable
|
* Make enumeration iterable
|
||||||
*
|
*
|
||||||
@@ -152,7 +150,7 @@ public final class Support {
|
|||||||
{
|
{
|
||||||
return new IterableEnumerationWrapper<>(enumeration);
|
return new IterableEnumerationWrapper<>(enumeration);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class for iterationg over an {@link Enumeration}
|
* Helper class for iterationg over an {@link Enumeration}
|
||||||
*
|
*
|
||||||
@@ -160,10 +158,10 @@ public final class Support {
|
|||||||
* @param <T> target element type (will be cast)
|
* @param <T> target element type (will be cast)
|
||||||
*/
|
*/
|
||||||
private static class IterableEnumerationWrapper<T> implements Iterable<T> {
|
private static class IterableEnumerationWrapper<T> implements Iterable<T> {
|
||||||
|
|
||||||
private final Enumeration<? extends T> enumeration;
|
private final Enumeration<? extends T> enumeration;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param enumeration the iterated enumeration
|
* @param enumeration the iterated enumeration
|
||||||
*/
|
*/
|
||||||
@@ -171,27 +169,27 @@ public final class Support {
|
|||||||
{
|
{
|
||||||
this.enumeration = enumeration;
|
this.enumeration = enumeration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator<T> iterator()
|
public Iterator<T> iterator()
|
||||||
{
|
{
|
||||||
return new Iterator<T>() {
|
return new Iterator<T>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasNext()
|
public boolean hasNext()
|
||||||
{
|
{
|
||||||
return enumeration.hasMoreElements();
|
return enumeration.hasMoreElements();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T next()
|
public T next()
|
||||||
{
|
{
|
||||||
return enumeration.nextElement();
|
return enumeration.nextElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void remove()
|
public void remove()
|
||||||
{
|
{
|
||||||
@@ -199,99 +197,6 @@ public final class Support {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert a class to string, preserving name and outer class, but excluding
|
|
||||||
* path.
|
|
||||||
*
|
|
||||||
* @param cls the class
|
|
||||||
* @return class name
|
|
||||||
*/
|
|
||||||
public static String str(Class<?> cls)
|
|
||||||
{
|
|
||||||
final Alias ln = cls.getAnnotation(Alias.class);
|
|
||||||
if (ln != null) {
|
|
||||||
return ln.name();
|
|
||||||
}
|
|
||||||
|
|
||||||
String name = cls.getName();
|
|
||||||
|
|
||||||
String sep = "";
|
|
||||||
|
|
||||||
if (name.contains("$")) {
|
|
||||||
name = name.substring(name.lastIndexOf("$") + 1);
|
|
||||||
sep = "$";
|
|
||||||
} else {
|
|
||||||
name = name.substring(name.lastIndexOf(".") + 1);
|
|
||||||
sep = ".";
|
|
||||||
}
|
|
||||||
|
|
||||||
final Class<?> enclosing = cls.getEnclosingClass();
|
|
||||||
|
|
||||||
return (enclosing == null ? "" : Support.str(enclosing) + sep) + name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert double to string, remove the mess at the end.
|
|
||||||
*
|
|
||||||
* @param d double
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static String str(Double d)
|
|
||||||
{
|
|
||||||
String s = d.toString();
|
|
||||||
s = s.replace(',', '.');
|
|
||||||
s = s.replaceAll("([0-9]+\\.[0-9]+)00+[0-9]+", "$1");
|
|
||||||
s = s.replaceAll("0+$", "");
|
|
||||||
s = s.replaceAll("\\.$", "");
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert float to string, remove the mess at the end.
|
|
||||||
*
|
|
||||||
* @param f float
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static String str(Float f)
|
|
||||||
{
|
|
||||||
String s = f.toString();
|
|
||||||
s = s.replaceAll("([0-9]+\\.[0-9]+)00+[0-9]+", "$1");
|
|
||||||
s = s.replaceAll("0+$", "");
|
|
||||||
s = s.replaceAll("\\.$", "");
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
public static String str(Object o)
|
|
||||||
{
|
|
||||||
if (o == null) return "<null>";
|
|
||||||
|
|
||||||
boolean hasToString = false;
|
|
||||||
|
|
||||||
try {
|
|
||||||
hasToString = (o.getClass().getMethod("toString").getDeclaringClass() != Object.class);
|
|
||||||
} catch (final Throwable t) {
|
|
||||||
// oh well..
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasToString) {
|
|
||||||
return o.toString();
|
|
||||||
} else {
|
|
||||||
|
|
||||||
return str(o.getClass());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,6 @@ import java.lang.annotation.Target;
|
|||||||
@Documented
|
@Documented
|
||||||
@Target(ElementType.TYPE)
|
@Target(ElementType.TYPE)
|
||||||
public @interface Alias {
|
public @interface Alias {
|
||||||
|
|
||||||
String name();
|
String name();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,5 +18,5 @@ import java.lang.annotation.Target;
|
|||||||
@Target(ElementType.METHOD)
|
@Target(ElementType.METHOD)
|
||||||
@Documented
|
@Documented
|
||||||
public @interface FactoryMethod {
|
public @interface FactoryMethod {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import mightypork.utils.logging.Log;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class SimpleConfig {
|
public class SimpleConfig {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load list from file
|
* Load list from file
|
||||||
*
|
*
|
||||||
@@ -34,11 +34,11 @@ public class SimpleConfig {
|
|||||||
public static List<String> listFromFile(File file) throws IOException
|
public static List<String> listFromFile(File file) throws IOException
|
||||||
{
|
{
|
||||||
final String fileText = FileUtil.fileToString(file);
|
final String fileText = FileUtil.fileToString(file);
|
||||||
|
|
||||||
return listFromString(fileText);
|
return listFromString(fileText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load map from file
|
* Load map from file
|
||||||
*
|
*
|
||||||
@@ -49,11 +49,11 @@ public class SimpleConfig {
|
|||||||
public static Map<String, String> mapFromFile(File file) throws IOException
|
public static Map<String, String> mapFromFile(File file) throws IOException
|
||||||
{
|
{
|
||||||
final String fileText = FileUtil.fileToString(file);
|
final String fileText = FileUtil.fileToString(file);
|
||||||
|
|
||||||
return mapFromString(fileText);
|
return mapFromString(fileText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load list from string
|
* Load list from string
|
||||||
*
|
*
|
||||||
@@ -63,27 +63,27 @@ public class SimpleConfig {
|
|||||||
public static List<String> listFromString(String text)
|
public static List<String> listFromString(String text)
|
||||||
{
|
{
|
||||||
final List<String> list = new ArrayList<>();
|
final List<String> list = new ArrayList<>();
|
||||||
|
|
||||||
final String[] groupsLines = text.split("\n");
|
final String[] groupsLines = text.split("\n");
|
||||||
|
|
||||||
for (String s : groupsLines) {
|
for (String s : groupsLines) {
|
||||||
// ignore invalid lines
|
// ignore invalid lines
|
||||||
if (s.length() == 0) continue;
|
if (s.length() == 0) continue;
|
||||||
if (s.startsWith("#") || s.startsWith("//")) continue;
|
if (s.startsWith("#") || s.startsWith("//")) continue;
|
||||||
|
|
||||||
// NULL value
|
// NULL value
|
||||||
if (s.equalsIgnoreCase("NULL")) s = null;
|
if (s.equalsIgnoreCase("NULL")) s = null;
|
||||||
|
|
||||||
if (s != null) s = s.replace("\\n", "\n");
|
if (s != null) s = s.replace("\\n", "\n");
|
||||||
|
|
||||||
// save extracted key-value pair
|
// save extracted key-value pair
|
||||||
list.add(s);
|
list.add(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load map from string
|
* Load map from string
|
||||||
*
|
*
|
||||||
@@ -93,51 +93,51 @@ public class SimpleConfig {
|
|||||||
public static Map<String, String> mapFromString(String text)
|
public static Map<String, String> mapFromString(String text)
|
||||||
{
|
{
|
||||||
final LinkedHashMap<String, String> pairs = new LinkedHashMap<>();
|
final LinkedHashMap<String, String> pairs = new LinkedHashMap<>();
|
||||||
|
|
||||||
final String[] groupsLines = text.split("\n");
|
final String[] groupsLines = text.split("\n");
|
||||||
|
|
||||||
for (final String s : groupsLines) {
|
for (final String s : groupsLines) {
|
||||||
// ignore invalid lines
|
// ignore invalid lines
|
||||||
if (s.length() == 0) continue;
|
if (s.length() == 0) continue;
|
||||||
if (s.startsWith("#") || s.startsWith("//")) continue;
|
if (s.startsWith("#") || s.startsWith("//")) continue;
|
||||||
if (!s.contains("=")) continue;
|
if (!s.contains("=")) continue;
|
||||||
|
|
||||||
// split and trim
|
// split and trim
|
||||||
String[] parts = s.split("=");
|
String[] parts = s.split("=");
|
||||||
for (int i = 0; i < parts.length; i++) {
|
for (int i = 0; i < parts.length; i++) {
|
||||||
parts[i] = parts[i].trim();
|
parts[i] = parts[i].trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if both parts are valid
|
// check if both parts are valid
|
||||||
if (parts.length == 0) {
|
if (parts.length == 0) {
|
||||||
Log.w("Bad line in config file: " + s);
|
Log.w("Bad line in config file: " + s);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parts.length == 1) {
|
if (parts.length == 1) {
|
||||||
parts = new String[] { parts[0], "" };
|
parts = new String[] { parts[0], "" };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parts.length != 2) {
|
if (parts.length != 2) {
|
||||||
Log.w("Bad line in config file: " + s);
|
Log.w("Bad line in config file: " + s);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NULL value
|
// NULL value
|
||||||
if (parts[0].equalsIgnoreCase("NULL")) parts[0] = null;
|
if (parts[0].equalsIgnoreCase("NULL")) parts[0] = null;
|
||||||
if (parts[1].equalsIgnoreCase("NULL")) parts[1] = null;
|
if (parts[1].equalsIgnoreCase("NULL")) parts[1] = null;
|
||||||
|
|
||||||
if (parts[0] != null) parts[0] = parts[0].replace("\\n", "\n");
|
if (parts[0] != null) parts[0] = parts[0].replace("\\n", "\n");
|
||||||
if (parts[1] != null) parts[1] = parts[1].replace("\\n", "\n");
|
if (parts[1] != null) parts[1] = parts[1].replace("\\n", "\n");
|
||||||
|
|
||||||
// save extracted key-value pair
|
// save extracted key-value pair
|
||||||
pairs.put(parts[0], parts[1]);
|
pairs.put(parts[0], parts[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return pairs;
|
return pairs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save map to file
|
* Save map to file
|
||||||
*
|
*
|
||||||
@@ -149,35 +149,35 @@ public class SimpleConfig {
|
|||||||
public static void mapToFile(File target, Map<String, String> data, boolean allowNulls) throws IOException
|
public static void mapToFile(File target, Map<String, String> data, boolean allowNulls) throws IOException
|
||||||
{
|
{
|
||||||
final List<String> lines = new ArrayList<>();
|
final List<String> lines = new ArrayList<>();
|
||||||
|
|
||||||
for (final Entry<String, String> e : data.entrySet()) {
|
for (final Entry<String, String> e : data.entrySet()) {
|
||||||
String key = e.getKey();
|
String key = e.getKey();
|
||||||
String value = e.getValue();
|
String value = e.getValue();
|
||||||
|
|
||||||
if (!allowNulls && (key == null || value == null || key.length() == 0 || value.length() == 0)) continue;
|
if (!allowNulls && (key == null || value == null || key.length() == 0 || value.length() == 0)) continue;
|
||||||
|
|
||||||
if (key == null) key = "NULL";
|
if (key == null) key = "NULL";
|
||||||
if (value == null) value = "NULL";
|
if (value == null) value = "NULL";
|
||||||
|
|
||||||
key = key.replace("\n", "\\n");
|
key = key.replace("\n", "\\n");
|
||||||
value = value.replace("\n", "\\n");
|
value = value.replace("\n", "\\n");
|
||||||
|
|
||||||
lines.add(key + " = " + value);
|
lines.add(key + " = " + value);
|
||||||
}
|
}
|
||||||
|
|
||||||
String text = ""; // # File written by SimpleConfig
|
String text = ""; // # File written by SimpleConfig
|
||||||
|
|
||||||
for (final String s : lines) {
|
for (final String s : lines) {
|
||||||
if (text.length() > 0) text += "\n";
|
if (text.length() > 0) text += "\n";
|
||||||
|
|
||||||
text += s;
|
text += s;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileUtil.stringToFile(target, text);
|
FileUtil.stringToFile(target, text);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save list to file
|
* Save list to file
|
||||||
*
|
*
|
||||||
@@ -188,18 +188,18 @@ public class SimpleConfig {
|
|||||||
public static void listToFile(File target, List<String> data) throws IOException
|
public static void listToFile(File target, List<String> data) throws IOException
|
||||||
{
|
{
|
||||||
String text = ""; // # File written by SimpleConfig
|
String text = ""; // # File written by SimpleConfig
|
||||||
|
|
||||||
for (String s : data) {
|
for (String s : data) {
|
||||||
if (text.length() > 0) text += "\n";
|
if (text.length() > 0) text += "\n";
|
||||||
|
|
||||||
if (s == null) s = "NULL";
|
if (s == null) s = "NULL";
|
||||||
|
|
||||||
s = s.replace("\n", "\\n");
|
s = s.replace("\n", "\\n");
|
||||||
|
|
||||||
text += s;
|
text += s;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileUtil.stringToFile(target, text);
|
FileUtil.stringToFile(target, text);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,14 +14,14 @@ import mightypork.utils.annotations.Stub;
|
|||||||
* @param <T> property type
|
* @param <T> property type
|
||||||
*/
|
*/
|
||||||
public abstract class Property<T> {
|
public abstract class Property<T> {
|
||||||
|
|
||||||
protected final String comment;
|
protected final String comment;
|
||||||
protected final String key;
|
protected final String key;
|
||||||
|
|
||||||
protected T value;
|
protected T value;
|
||||||
protected final T defaultValue;
|
protected final T defaultValue;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a property without comment
|
* Create a property without comment
|
||||||
*
|
*
|
||||||
@@ -33,8 +33,8 @@ public abstract class Property<T> {
|
|||||||
{
|
{
|
||||||
this(key, defaultValue, null);
|
this(key, defaultValue, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a property with a comment
|
* Create a property with a comment
|
||||||
*
|
*
|
||||||
@@ -51,8 +51,8 @@ public abstract class Property<T> {
|
|||||||
this.value = defaultValue;
|
this.value = defaultValue;
|
||||||
this.defaultValue = defaultValue;
|
this.defaultValue = defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse a string representation of the value into this property. If the
|
* Parse a string representation of the value into this property. If the
|
||||||
* value cannot be decoded, use the default value instead.
|
* value cannot be decoded, use the default value instead.
|
||||||
@@ -60,8 +60,8 @@ public abstract class Property<T> {
|
|||||||
* @param string property value as string
|
* @param string property value as string
|
||||||
*/
|
*/
|
||||||
public abstract void fromString(String string);
|
public abstract void fromString(String string);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get property value as string (compatible with `fromString())
|
* Get property value as string (compatible with `fromString())
|
||||||
*
|
*
|
||||||
@@ -73,8 +73,8 @@ public abstract class Property<T> {
|
|||||||
{
|
{
|
||||||
return Convert.toString(value, Convert.toString(defaultValue));
|
return Convert.toString(value, Convert.toString(defaultValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current property value
|
* Get the current property value
|
||||||
*
|
*
|
||||||
@@ -84,8 +84,8 @@ public abstract class Property<T> {
|
|||||||
{
|
{
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set property value.<br>
|
* Set property value.<br>
|
||||||
* Uses Object to allow setValue(Object) method in {@link PropertyManager}
|
* Uses Object to allow setValue(Object) method in {@link PropertyManager}
|
||||||
@@ -98,8 +98,8 @@ public abstract class Property<T> {
|
|||||||
{
|
{
|
||||||
this.value = (T) value;
|
this.value = (T) value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get property comment.
|
* Get property comment.
|
||||||
*
|
*
|
||||||
@@ -109,8 +109,8 @@ public abstract class Property<T> {
|
|||||||
{
|
{
|
||||||
return comment;
|
return comment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get property key
|
* Get property key
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -22,12 +22,12 @@ import mightypork.utils.logging.Log;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class PropertyManager {
|
public class PropertyManager {
|
||||||
|
|
||||||
private final TreeMap<String, Property<?>> entries = new TreeMap<>();
|
private final TreeMap<String, Property<?>> entries = new TreeMap<>();
|
||||||
private final TreeMap<String, String> renameTable = new TreeMap<>();
|
private final TreeMap<String, String> renameTable = new TreeMap<>();
|
||||||
private final PropertyStore props;
|
private final PropertyStore props;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create property manager from file path and a header comment.<br>
|
* Create property manager from file path and a header comment.<br>
|
||||||
* This is the same as using a {@link PropertyFile} store.
|
* This is the same as using a {@link PropertyFile} store.
|
||||||
@@ -39,8 +39,8 @@ public class PropertyManager {
|
|||||||
{
|
{
|
||||||
this(new PropertyFile(file, comment));
|
this(new PropertyFile(file, comment));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create property manager based on provided {@link PropertyStore}
|
* Create property manager based on provided {@link PropertyStore}
|
||||||
*
|
*
|
||||||
@@ -51,61 +51,61 @@ public class PropertyManager {
|
|||||||
{
|
{
|
||||||
this.props = props;
|
this.props = props;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load from file
|
* Load from file
|
||||||
*/
|
*/
|
||||||
public void load()
|
public void load()
|
||||||
{
|
{
|
||||||
props.load();
|
props.load();
|
||||||
|
|
||||||
// rename keys (useful if keys change but value is to be kept)
|
// rename keys (useful if keys change but value is to be kept)
|
||||||
for (final Entry<String, String> entry : renameTable.entrySet()) {
|
for (final Entry<String, String> entry : renameTable.entrySet()) {
|
||||||
|
|
||||||
final String value = props.getProperty(entry.getKey());
|
final String value = props.getProperty(entry.getKey());
|
||||||
|
|
||||||
if (value == null) continue;
|
if (value == null) continue;
|
||||||
|
|
||||||
final String oldKey = entry.getKey();
|
final String oldKey = entry.getKey();
|
||||||
final String newKey = entry.getValue();
|
final String newKey = entry.getValue();
|
||||||
|
|
||||||
props.removeProperty(oldKey);
|
props.removeProperty(oldKey);
|
||||||
props.setProperty(newKey, value, entries.get(newKey).getComment());
|
props.setProperty(newKey, value, entries.get(newKey).getComment());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final Property<?> entry : entries.values()) {
|
for (final Property<?> entry : entries.values()) {
|
||||||
entry.fromString(props.getProperty(entry.getKey()));
|
entry.fromString(props.getProperty(entry.getKey()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void save()
|
public void save()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
final ArrayList<String> keyList = new ArrayList<>();
|
final ArrayList<String> keyList = new ArrayList<>();
|
||||||
|
|
||||||
// validate entries one by one, replace with default when needed
|
// validate entries one by one, replace with default when needed
|
||||||
for (final Property<?> entry : entries.values()) {
|
for (final Property<?> entry : entries.values()) {
|
||||||
keyList.add(entry.getKey());
|
keyList.add(entry.getKey());
|
||||||
|
|
||||||
props.setProperty(entry.getKey(), entry.toString(), entry.getComment());
|
props.setProperty(entry.getKey(), entry.toString(), entry.getComment());
|
||||||
}
|
}
|
||||||
|
|
||||||
// removed unused props
|
// removed unused props
|
||||||
for (final String key : props.keys()) {
|
for (final String key : props.keys()) {
|
||||||
if (!keyList.contains(key)) {
|
if (!keyList.contains(key)) {
|
||||||
props.removeProperty(key);
|
props.removeProperty(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
props.save();
|
props.save();
|
||||||
} catch (final IOException ioe) {
|
} catch (final IOException ioe) {
|
||||||
ioe.printStackTrace();
|
ioe.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a property entry (rarely used)
|
* Get a property entry (rarely used)
|
||||||
*
|
*
|
||||||
@@ -121,8 +121,8 @@ public class PropertyManager {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get boolean property
|
* Get boolean property
|
||||||
*
|
*
|
||||||
@@ -133,8 +133,8 @@ public class PropertyManager {
|
|||||||
{
|
{
|
||||||
return Convert.toBoolean(getProperty(k).getValue());
|
return Convert.toBoolean(getProperty(k).getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get numeric property
|
* Get numeric property
|
||||||
*
|
*
|
||||||
@@ -145,8 +145,8 @@ public class PropertyManager {
|
|||||||
{
|
{
|
||||||
return Convert.toInteger(getProperty(k).getValue());
|
return Convert.toInteger(getProperty(k).getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get numeric property as double
|
* Get numeric property as double
|
||||||
*
|
*
|
||||||
@@ -157,8 +157,8 @@ public class PropertyManager {
|
|||||||
{
|
{
|
||||||
return Convert.toDouble(getProperty(k).getValue());
|
return Convert.toDouble(getProperty(k).getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get string property
|
* Get string property
|
||||||
*
|
*
|
||||||
@@ -169,8 +169,8 @@ public class PropertyManager {
|
|||||||
{
|
{
|
||||||
return Convert.toString(getProperty(k).getValue());
|
return Convert.toString(getProperty(k).getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get arbitrary property. Make sure it's of the right type!
|
* Get arbitrary property. Make sure it's of the right type!
|
||||||
*
|
*
|
||||||
@@ -186,8 +186,8 @@ public class PropertyManager {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a boolean property
|
* Add a boolean property
|
||||||
*
|
*
|
||||||
@@ -199,8 +199,8 @@ public class PropertyManager {
|
|||||||
{
|
{
|
||||||
addProperty(new BooleanProperty(k, d, comment));
|
addProperty(new BooleanProperty(k, d, comment));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a numeric property (double)
|
* Add a numeric property (double)
|
||||||
*
|
*
|
||||||
@@ -212,8 +212,8 @@ public class PropertyManager {
|
|||||||
{
|
{
|
||||||
addProperty(new DoubleProperty(k, d, comment));
|
addProperty(new DoubleProperty(k, d, comment));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a numeric property
|
* Add a numeric property
|
||||||
*
|
*
|
||||||
@@ -225,8 +225,8 @@ public class PropertyManager {
|
|||||||
{
|
{
|
||||||
addProperty(new IntegerProperty(k, d, comment));
|
addProperty(new IntegerProperty(k, d, comment));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a string property
|
* Add a string property
|
||||||
*
|
*
|
||||||
@@ -238,8 +238,8 @@ public class PropertyManager {
|
|||||||
{
|
{
|
||||||
addProperty(new StringProperty(k, d, comment));
|
addProperty(new StringProperty(k, d, comment));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a generic property (can be used with custom property types)
|
* Add a generic property (can be used with custom property types)
|
||||||
*
|
*
|
||||||
@@ -249,8 +249,8 @@ public class PropertyManager {
|
|||||||
{
|
{
|
||||||
entries.put(prop.getKey(), prop);
|
entries.put(prop.getKey(), prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rename key before loading; value is preserved
|
* Rename key before loading; value is preserved
|
||||||
*
|
*
|
||||||
@@ -262,8 +262,8 @@ public class PropertyManager {
|
|||||||
renameTable.put(oldKey, newKey);
|
renameTable.put(oldKey, newKey);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set value saved to certain key.
|
* Set value saved to certain key.
|
||||||
*
|
*
|
||||||
@@ -274,8 +274,8 @@ public class PropertyManager {
|
|||||||
{
|
{
|
||||||
getProperty(key).setValue(value);
|
getProperty(key).setValue(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set heading comment of the property store.
|
* Set heading comment of the property store.
|
||||||
*
|
*
|
||||||
@@ -285,5 +285,5 @@ public class PropertyManager {
|
|||||||
{
|
{
|
||||||
props.setComment(fileComment);
|
props.setComment(fileComment);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,30 +13,30 @@ import java.util.Collection;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public interface PropertyStore {
|
public interface PropertyStore {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a header comment
|
* Set a header comment
|
||||||
*
|
*
|
||||||
* @param comment the comment text (can be multi-line)
|
* @param comment the comment text (can be multi-line)
|
||||||
*/
|
*/
|
||||||
void setComment(String comment);
|
void setComment(String comment);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load properties from the file / store. If the file does not exist or is
|
* Load properties from the file / store. If the file does not exist or is
|
||||||
* inaccessible, nothing is loaded.
|
* inaccessible, nothing is loaded.
|
||||||
*/
|
*/
|
||||||
void load();
|
void load();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save properties to the file / store.
|
* Save properties to the file / store.
|
||||||
*
|
*
|
||||||
* @throws IOException if the file cannot be created or written.
|
* @throws IOException if the file cannot be created or written.
|
||||||
*/
|
*/
|
||||||
void save() throws IOException;
|
void save() throws IOException;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a property value
|
* Get a property value
|
||||||
*
|
*
|
||||||
@@ -44,8 +44,8 @@ public interface PropertyStore {
|
|||||||
* @return value retrieved from the file, or null if none found.
|
* @return value retrieved from the file, or null if none found.
|
||||||
*/
|
*/
|
||||||
String getProperty(String key);
|
String getProperty(String key);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a property value
|
* Set a property value
|
||||||
*
|
*
|
||||||
@@ -54,22 +54,22 @@ public interface PropertyStore {
|
|||||||
* @param comment property comment. Can be null.
|
* @param comment property comment. Can be null.
|
||||||
*/
|
*/
|
||||||
void setProperty(String key, String value, String comment);
|
void setProperty(String key, String value, String comment);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a property from the list.
|
* Remove a property from the list.
|
||||||
*
|
*
|
||||||
* @param key property key to remove
|
* @param key property key to remove
|
||||||
*/
|
*/
|
||||||
void removeProperty(String key);
|
void removeProperty(String key);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear the property list
|
* Clear the property list
|
||||||
*/
|
*/
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get keys collection (can be used for iterating)
|
* Get keys collection (can be used for iterating)
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -11,19 +11,19 @@ import mightypork.utils.config.propmgr.Property;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class BooleanProperty extends Property<Boolean> {
|
public class BooleanProperty extends Property<Boolean> {
|
||||||
|
|
||||||
public BooleanProperty(String key, Boolean defaultValue)
|
public BooleanProperty(String key, Boolean defaultValue)
|
||||||
{
|
{
|
||||||
super(key, defaultValue);
|
super(key, defaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public BooleanProperty(String key, Boolean defaultValue, String comment)
|
public BooleanProperty(String key, Boolean defaultValue, String comment)
|
||||||
{
|
{
|
||||||
super(key, defaultValue, comment);
|
super(key, defaultValue, comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fromString(String string)
|
public void fromString(String string)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,19 +11,19 @@ import mightypork.utils.config.propmgr.Property;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class DoubleProperty extends Property<Double> {
|
public class DoubleProperty extends Property<Double> {
|
||||||
|
|
||||||
public DoubleProperty(String key, Double defaultValue)
|
public DoubleProperty(String key, Double defaultValue)
|
||||||
{
|
{
|
||||||
super(key, defaultValue);
|
super(key, defaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public DoubleProperty(String key, Double defaultValue, String comment)
|
public DoubleProperty(String key, Double defaultValue, String comment)
|
||||||
{
|
{
|
||||||
super(key, defaultValue, comment);
|
super(key, defaultValue, comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fromString(String string)
|
public void fromString(String string)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,19 +11,19 @@ import mightypork.utils.config.propmgr.Property;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class IntegerProperty extends Property<Integer> {
|
public class IntegerProperty extends Property<Integer> {
|
||||||
|
|
||||||
public IntegerProperty(String key, Integer defaultValue)
|
public IntegerProperty(String key, Integer defaultValue)
|
||||||
{
|
{
|
||||||
super(key, defaultValue);
|
super(key, defaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public IntegerProperty(String key, Integer defaultValue, String comment)
|
public IntegerProperty(String key, Integer defaultValue, String comment)
|
||||||
{
|
{
|
||||||
super(key, defaultValue, comment);
|
super(key, defaultValue, comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fromString(String string)
|
public void fromString(String string)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,19 +11,19 @@ import mightypork.utils.config.propmgr.Property;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class StringProperty extends Property<String> {
|
public class StringProperty extends Property<String> {
|
||||||
|
|
||||||
public StringProperty(String key, String defaultValue)
|
public StringProperty(String key, String defaultValue)
|
||||||
{
|
{
|
||||||
super(key, defaultValue);
|
super(key, defaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public StringProperty(String key, String defaultValue, String comment)
|
public StringProperty(String key, String defaultValue, String comment)
|
||||||
{
|
{
|
||||||
super(key, defaultValue, comment);
|
super(key, defaultValue, comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fromString(String string)
|
public void fromString(String string)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -17,48 +17,48 @@ import mightypork.utils.config.propmgr.PropertyStore;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class PropertyFile implements PropertyStore {
|
public class PropertyFile implements PropertyStore {
|
||||||
|
|
||||||
private String comment;
|
private String comment;
|
||||||
private final File file;
|
private final File file;
|
||||||
private final SortedProperties props;
|
private final SortedProperties props;
|
||||||
|
|
||||||
|
|
||||||
public PropertyFile(File file)
|
public PropertyFile(File file)
|
||||||
{
|
{
|
||||||
this.file = file;
|
this.file = file;
|
||||||
this.comment = null;
|
this.comment = null;
|
||||||
this.props = new SortedProperties();
|
this.props = new SortedProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public PropertyFile(File file, String comment)
|
public PropertyFile(File file, String comment)
|
||||||
{
|
{
|
||||||
this.file = file;
|
this.file = file;
|
||||||
this.comment = comment;
|
this.comment = comment;
|
||||||
this.props = new SortedProperties();
|
this.props = new SortedProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setComment(String comment)
|
public void setComment(String comment)
|
||||||
{
|
{
|
||||||
this.comment = comment;
|
this.comment = comment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load()
|
public void load()
|
||||||
{
|
{
|
||||||
if (!file.exists()) return;
|
if (!file.exists()) return;
|
||||||
|
|
||||||
try(FileInputStream in = new FileInputStream(file)) {
|
try(FileInputStream in = new FileInputStream(file)) {
|
||||||
props.load(in);
|
props.load(in);
|
||||||
} catch (final IOException e) {
|
} catch (final IOException e) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void save() throws IOException
|
public void save() throws IOException
|
||||||
{
|
{
|
||||||
@@ -67,55 +67,55 @@ public class PropertyFile implements PropertyStore {
|
|||||||
throw new IOException("Cound not create config file.");
|
throw new IOException("Cound not create config file.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try(FileOutputStream out = new FileOutputStream(file)) {
|
try(FileOutputStream out = new FileOutputStream(file)) {
|
||||||
props.store(out, comment);
|
props.store(out, comment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getProperty(String key)
|
public String getProperty(String key)
|
||||||
{
|
{
|
||||||
return props.getProperty(key);
|
return props.getProperty(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setProperty(String key, String value, String comment)
|
public void setProperty(String key, String value, String comment)
|
||||||
{
|
{
|
||||||
props.setProperty(key, value);
|
props.setProperty(key, value);
|
||||||
props.setKeyComment(key, comment);
|
props.setKeyComment(key, comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeProperty(String key)
|
public void removeProperty(String key)
|
||||||
{
|
{
|
||||||
props.remove(key);
|
props.remove(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clear()
|
public void clear()
|
||||||
{
|
{
|
||||||
props.clear();
|
props.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public Collection<String> keys()
|
public Collection<String> keys()
|
||||||
{
|
{
|
||||||
|
|
||||||
// Set<String> keys = new HashSet<>();
|
// Set<String> keys = new HashSet<>();
|
||||||
// for (Object o : props.keySet()) {
|
// for (Object o : props.keySet()) {
|
||||||
// keys.add((String) o);
|
// keys.add((String) o);
|
||||||
// }
|
// }
|
||||||
// return keys;
|
// return keys;
|
||||||
|
|
||||||
// we know it is strings.
|
// we know it is strings.
|
||||||
return (Collection<String>) (Collection<?>) props.keySet();
|
return (Collection<String>) (Collection<?>) props.keySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,15 +23,15 @@ import java.util.Vector;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
class SortedProperties extends java.util.Properties {
|
class SortedProperties extends java.util.Properties {
|
||||||
|
|
||||||
/** Comments for individual keys */
|
/** Comments for individual keys */
|
||||||
private final Hashtable<String, String> keyComments = new Hashtable<>();
|
private final Hashtable<String, String> keyComments = new Hashtable<>();
|
||||||
|
|
||||||
|
|
||||||
private static void writeComments(BufferedWriter bw, String comm) throws IOException
|
private static void writeComments(BufferedWriter bw, String comm) throws IOException
|
||||||
{
|
{
|
||||||
final String comments = comm.replace("\n\n", "\n \n");
|
final String comments = comm.replace("\n\n", "\n \n");
|
||||||
|
|
||||||
final int len = comments.length();
|
final int len = comments.length();
|
||||||
int current = 0;
|
int current = 0;
|
||||||
int last = 0;
|
int last = 0;
|
||||||
@@ -44,7 +44,7 @@ class SortedProperties extends java.util.Properties {
|
|||||||
if (last != current) {
|
if (last != current) {
|
||||||
bw.write("# " + comments.substring(last, current));
|
bw.write("# " + comments.substring(last, current));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c > '\u00ff') {
|
if (c > '\u00ff') {
|
||||||
uu[2] = hexDigit(c, 12);
|
uu[2] = hexDigit(c, 12);
|
||||||
uu[3] = hexDigit(c, 8);
|
uu[3] = hexDigit(c, 8);
|
||||||
@@ -64,13 +64,13 @@ class SortedProperties extends java.util.Properties {
|
|||||||
if (last != current) {
|
if (last != current) {
|
||||||
bw.write("# " + comments.substring(last, current));
|
bw.write("# " + comments.substring(last, current));
|
||||||
}
|
}
|
||||||
|
|
||||||
bw.newLine();
|
bw.newLine();
|
||||||
bw.newLine();
|
bw.newLine();
|
||||||
bw.newLine();
|
bw.newLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||||
@Override
|
@Override
|
||||||
public synchronized Enumeration keys()
|
public synchronized Enumeration keys()
|
||||||
@@ -83,8 +83,8 @@ class SortedProperties extends java.util.Properties {
|
|||||||
Collections.sort(keyList); //sort!
|
Collections.sort(keyList); //sort!
|
||||||
return keyList.elements();
|
return keyList.elements();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static String saveConvert(String theString, boolean escapeSpace, boolean escapeUnicode)
|
private static String saveConvert(String theString, boolean escapeSpace, boolean escapeUnicode)
|
||||||
{
|
{
|
||||||
final int len = theString.length();
|
final int len = theString.length();
|
||||||
@@ -93,10 +93,10 @@ class SortedProperties extends java.util.Properties {
|
|||||||
bufLen = Integer.MAX_VALUE;
|
bufLen = Integer.MAX_VALUE;
|
||||||
}
|
}
|
||||||
final StringBuffer result = new StringBuffer(bufLen);
|
final StringBuffer result = new StringBuffer(bufLen);
|
||||||
|
|
||||||
for (int x = 0; x < len; x++) {
|
for (int x = 0; x < len; x++) {
|
||||||
final char ch = theString.charAt(x);
|
final char ch = theString.charAt(x);
|
||||||
|
|
||||||
// Handle common case first, selecting largest block that
|
// Handle common case first, selecting largest block that
|
||||||
// avoids the specials below
|
// avoids the specials below
|
||||||
if ((ch > 61) && (ch < 127)) {
|
if ((ch > 61) && (ch < 127)) {
|
||||||
@@ -108,7 +108,7 @@ class SortedProperties extends java.util.Properties {
|
|||||||
result.append(ch);
|
result.append(ch);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case ' ':
|
case ' ':
|
||||||
if (x == 0 || escapeSpace) {
|
if (x == 0 || escapeSpace) {
|
||||||
@@ -116,27 +116,27 @@ class SortedProperties extends java.util.Properties {
|
|||||||
}
|
}
|
||||||
result.append(' ');
|
result.append(' ');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '\t':
|
case '\t':
|
||||||
result.append('\\');
|
result.append('\\');
|
||||||
result.append('t');
|
result.append('t');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '\n':
|
case '\n':
|
||||||
result.append('\\');
|
result.append('\\');
|
||||||
result.append('n');
|
result.append('n');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '\r':
|
case '\r':
|
||||||
result.append('\\');
|
result.append('\\');
|
||||||
result.append('r');
|
result.append('r');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '\f':
|
case '\f':
|
||||||
result.append('\\');
|
result.append('\\');
|
||||||
result.append('f');
|
result.append('f');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '=': // Fall through
|
case '=': // Fall through
|
||||||
case ':': // Fall through
|
case ':': // Fall through
|
||||||
case '#': // Fall through
|
case '#': // Fall through
|
||||||
@@ -144,7 +144,7 @@ class SortedProperties extends java.util.Properties {
|
|||||||
result.append('\\');
|
result.append('\\');
|
||||||
result.append(ch);
|
result.append(ch);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (((ch < 0x0020) || (ch > 0x007e)) & escapeUnicode) {
|
if (((ch < 0x0020) || (ch > 0x007e)) & escapeUnicode) {
|
||||||
result.append('\\');
|
result.append('\\');
|
||||||
@@ -158,11 +158,11 @@ class SortedProperties extends java.util.Properties {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.toString();
|
return result.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set additional comment to a key
|
* Set additional comment to a key
|
||||||
*
|
*
|
||||||
@@ -173,75 +173,75 @@ class SortedProperties extends java.util.Properties {
|
|||||||
{
|
{
|
||||||
keyComments.put(key, comment);
|
keyComments.put(key, comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
@Override
|
@Override
|
||||||
public void store(OutputStream out, String comments) throws IOException
|
public void store(OutputStream out, String comments) throws IOException
|
||||||
{
|
{
|
||||||
final BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"));
|
final BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"));
|
||||||
|
|
||||||
final boolean escUnicode = false;
|
final boolean escUnicode = false;
|
||||||
boolean firstEntry = true;
|
boolean firstEntry = true;
|
||||||
String lastSectionBeginning = "";
|
String lastSectionBeginning = "";
|
||||||
|
|
||||||
if (comments != null) {
|
if (comments != null) {
|
||||||
writeComments(bw, comments);
|
writeComments(bw, comments);
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
for (final Enumeration e = keys(); e.hasMoreElements();) {
|
for (final Enumeration e = keys(); e.hasMoreElements();) {
|
||||||
boolean wasNewLine = false;
|
boolean wasNewLine = false;
|
||||||
|
|
||||||
String key = (String) e.nextElement();
|
String key = (String) e.nextElement();
|
||||||
String val = (String) get(key);
|
String val = (String) get(key);
|
||||||
key = saveConvert(key, true, escUnicode);
|
key = saveConvert(key, true, escUnicode);
|
||||||
val = saveConvert(val, false, escUnicode);
|
val = saveConvert(val, false, escUnicode);
|
||||||
|
|
||||||
// separate sections
|
// separate sections
|
||||||
if (!lastSectionBeginning.equals(key.split("[.]")[0])) {
|
if (!lastSectionBeginning.equals(key.split("[.]")[0])) {
|
||||||
if (!firstEntry) {
|
if (!firstEntry) {
|
||||||
bw.newLine();
|
bw.newLine();
|
||||||
bw.newLine();
|
bw.newLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
wasNewLine = true;
|
wasNewLine = true;
|
||||||
lastSectionBeginning = key.split("[.]")[0];
|
lastSectionBeginning = key.split("[.]")[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keyComments.containsKey(key)) {
|
if (keyComments.containsKey(key)) {
|
||||||
String cm = keyComments.get(key);
|
String cm = keyComments.get(key);
|
||||||
cm = cm.replace("\r", "\n");
|
cm = cm.replace("\r", "\n");
|
||||||
cm = cm.replace("\r\n", "\n");
|
cm = cm.replace("\r\n", "\n");
|
||||||
cm = cm.replace("\n\n", "\n \n");
|
cm = cm.replace("\n\n", "\n \n");
|
||||||
|
|
||||||
final String[] cmlines = cm.split("\n");
|
final String[] cmlines = cm.split("\n");
|
||||||
|
|
||||||
// newline before comments
|
// newline before comments
|
||||||
if (!wasNewLine && !firstEntry) {
|
if (!wasNewLine && !firstEntry) {
|
||||||
bw.newLine();
|
bw.newLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final String cmline : cmlines) {
|
for (final String cmline : cmlines) {
|
||||||
bw.write("# " + cmline);
|
bw.write("# " + cmline);
|
||||||
bw.newLine();
|
bw.newLine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bw.write(key + " = " + val);
|
bw.write(key + " = " + val);
|
||||||
bw.newLine();
|
bw.newLine();
|
||||||
|
|
||||||
firstEntry = false;
|
firstEntry = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bw.flush();
|
bw.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static String escapifyStr(String str)
|
private static String escapifyStr(String str)
|
||||||
{
|
{
|
||||||
final StringBuilder result = new StringBuilder();
|
final StringBuilder result = new StringBuilder();
|
||||||
|
|
||||||
final int len = str.length();
|
final int len = str.length();
|
||||||
for (int x = 0; x < len; x++) {
|
for (int x = 0; x < len; x++) {
|
||||||
final char ch = str.charAt(x);
|
final char ch = str.charAt(x);
|
||||||
@@ -249,7 +249,7 @@ class SortedProperties extends java.util.Properties {
|
|||||||
result.append(ch);
|
result.append(ch);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.append('\\');
|
result.append('\\');
|
||||||
result.append('u');
|
result.append('u');
|
||||||
result.append(hexDigit(ch, 12));
|
result.append(hexDigit(ch, 12));
|
||||||
@@ -259,26 +259,26 @@ class SortedProperties extends java.util.Properties {
|
|||||||
}
|
}
|
||||||
return result.toString();
|
return result.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static char hexDigit(char ch, int offset)
|
private static char hexDigit(char ch, int offset)
|
||||||
{
|
{
|
||||||
final int val = (ch >> offset) & 0xF;
|
final int val = (ch >> offset) & 0xF;
|
||||||
if (val <= 9) {
|
if (val <= 9) {
|
||||||
return (char) ('0' + val);
|
return (char) ('0' + val);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (char) ('A' + val - 10);
|
return (char) ('A' + val - 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void load(InputStream is) throws IOException
|
public synchronized void load(InputStream is) throws IOException
|
||||||
{
|
{
|
||||||
load(is, "utf-8");
|
load(is, "utf-8");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void load(InputStream is, String encoding) throws IOException
|
public void load(InputStream is, String encoding) throws IOException
|
||||||
{
|
{
|
||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
@@ -288,18 +288,18 @@ class SortedProperties extends java.util.Properties {
|
|||||||
if (temp < 0) {
|
if (temp < 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
final char c = (char) temp;
|
final char c = (char) temp;
|
||||||
sb.append(c);
|
sb.append(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
// discard comments
|
// discard comments
|
||||||
final String read = sb.toString().replaceAll("(#|;|//|--)[^\n]*\n", "\n");
|
final String read = sb.toString().replaceAll("(#|;|//|--)[^\n]*\n", "\n");
|
||||||
|
|
||||||
final String inputString = escapifyStr(read);
|
final String inputString = escapifyStr(read);
|
||||||
final byte[] bs = inputString.getBytes("ISO-8859-1");
|
final byte[] bs = inputString.getBytes("ISO-8859-1");
|
||||||
final ByteArrayInputStream bais = new ByteArrayInputStream(bs);
|
final ByteArrayInputStream bais = new ByteArrayInputStream(bs);
|
||||||
|
|
||||||
super.load(bais);
|
super.load(bais);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package mightypork.utils.eventbus;
|
package mightypork.utils.eventbus;
|
||||||
|
|
||||||
|
|
||||||
|
import mightypork.utils.annotations.Stub;
|
||||||
import mightypork.utils.eventbus.events.flags.DelayedEvent;
|
import mightypork.utils.eventbus.events.flags.DelayedEvent;
|
||||||
import mightypork.utils.eventbus.events.flags.DirectEvent;
|
import mightypork.utils.eventbus.events.flags.DirectEvent;
|
||||||
import mightypork.utils.eventbus.events.flags.NonConsumableEvent;
|
import mightypork.utils.eventbus.events.flags.NonConsumableEvent;
|
||||||
@@ -31,19 +32,19 @@ import mightypork.utils.eventbus.events.flags.SingleReceiverEvent;
|
|||||||
* @param <HANDLER> handler type
|
* @param <HANDLER> handler type
|
||||||
*/
|
*/
|
||||||
public abstract class BusEvent<HANDLER> {
|
public abstract class BusEvent<HANDLER> {
|
||||||
|
|
||||||
private boolean consumed;
|
private boolean consumed;
|
||||||
private boolean served;
|
private boolean served;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ask handler to handle this message.
|
* Ask handler to handle this message.
|
||||||
*
|
*
|
||||||
* @param handler handler instance
|
* @param handler handler instance
|
||||||
*/
|
*/
|
||||||
protected abstract void handleBy(HANDLER handler);
|
protected abstract void handleBy(HANDLER handler);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Consume the event, so no other clients will receive it.
|
* Consume the event, so no other clients will receive it.
|
||||||
*
|
*
|
||||||
@@ -53,17 +54,15 @@ public abstract class BusEvent<HANDLER> {
|
|||||||
public final void consume()
|
public final void consume()
|
||||||
{
|
{
|
||||||
if (consumed) throw new IllegalStateException("Already consumed.");
|
if (consumed) throw new IllegalStateException("Already consumed.");
|
||||||
|
|
||||||
if (getClass().isAnnotationPresent(NonConsumableEvent.class)) {
|
if (getClass().isAnnotationPresent(NonConsumableEvent.class)) {
|
||||||
throw new UnsupportedOperationException("Not consumable.");
|
throw new UnsupportedOperationException("Not consumable.");
|
||||||
}
|
}
|
||||||
|
|
||||||
(new Throwable()).printStackTrace();
|
|
||||||
|
|
||||||
consumed = true;
|
consumed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deliver to a handler using the handleBy method.
|
* Deliver to a handler using the handleBy method.
|
||||||
*
|
*
|
||||||
@@ -72,17 +71,17 @@ public abstract class BusEvent<HANDLER> {
|
|||||||
final void deliverTo(HANDLER handler)
|
final void deliverTo(HANDLER handler)
|
||||||
{
|
{
|
||||||
handleBy(handler);
|
handleBy(handler);
|
||||||
|
|
||||||
if (!served) {
|
if (!served) {
|
||||||
if (getClass().isAnnotationPresent(SingleReceiverEvent.class)) {
|
if (getClass().isAnnotationPresent(SingleReceiverEvent.class)) {
|
||||||
consumed = true;
|
consumed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
served = true;
|
served = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the event is consumed. When an event is consumed, no other
|
* Check if the event is consumed. When an event is consumed, no other
|
||||||
* clients will receive it.
|
* clients will receive it.
|
||||||
@@ -93,8 +92,8 @@ public abstract class BusEvent<HANDLER> {
|
|||||||
{
|
{
|
||||||
return consumed;
|
return consumed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if the event was served to at least 1 client
|
* @return true if the event was served to at least 1 client
|
||||||
*/
|
*/
|
||||||
@@ -102,8 +101,8 @@ public abstract class BusEvent<HANDLER> {
|
|||||||
{
|
{
|
||||||
return served;
|
return served;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear "served" and "consumed" flags before dispatching.
|
* Clear "served" and "consumed" flags before dispatching.
|
||||||
*/
|
*/
|
||||||
@@ -112,14 +111,16 @@ public abstract class BusEvent<HANDLER> {
|
|||||||
served = false;
|
served = false;
|
||||||
consumed = false;
|
consumed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called after all clients have received the event.
|
* Called after all clients have received the event.
|
||||||
*
|
*
|
||||||
* @param bus event bus instance
|
* @param bus event bus instance
|
||||||
*/
|
*/
|
||||||
|
@Stub
|
||||||
public void onDispatchComplete(EventBus bus)
|
public void onDispatchComplete(EventBus bus)
|
||||||
{
|
{
|
||||||
|
//
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import java.util.concurrent.Delayed;
|
|||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import mightypork.utils.Reflect;
|
import mightypork.utils.Reflect;
|
||||||
import mightypork.utils.Support;
|
import mightypork.utils.Str;
|
||||||
import mightypork.utils.eventbus.clients.DelegatingClient;
|
import mightypork.utils.eventbus.clients.DelegatingClient;
|
||||||
import mightypork.utils.eventbus.events.flags.DelayedEvent;
|
import mightypork.utils.eventbus.events.flags.DelayedEvent;
|
||||||
import mightypork.utils.eventbus.events.flags.DirectEvent;
|
import mightypork.utils.eventbus.events.flags.DirectEvent;
|
||||||
@@ -26,73 +26,73 @@ import mightypork.utils.logging.Log;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
final public class EventBus implements Destroyable {
|
final public class EventBus implements Destroyable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Queued event holder
|
* Queued event holder
|
||||||
*/
|
*/
|
||||||
private class DelayQueueEntry implements Delayed {
|
private class DelayQueueEntry implements Delayed {
|
||||||
|
|
||||||
private final long due;
|
private final long due;
|
||||||
private final BusEvent<?> evt;
|
private final BusEvent<?> evt;
|
||||||
|
|
||||||
|
|
||||||
public DelayQueueEntry(double seconds, BusEvent<?> event)
|
public DelayQueueEntry(double seconds, BusEvent<?> event)
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
this.due = System.currentTimeMillis() + (long) (seconds * 1000);
|
this.due = System.currentTimeMillis() + (long) (seconds * 1000);
|
||||||
this.evt = event;
|
this.evt = event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(Delayed o)
|
public int compareTo(Delayed o)
|
||||||
{
|
{
|
||||||
return Long.valueOf(getDelay(TimeUnit.MILLISECONDS)).compareTo(o.getDelay(TimeUnit.MILLISECONDS));
|
return Long.valueOf(getDelay(TimeUnit.MILLISECONDS)).compareTo(o.getDelay(TimeUnit.MILLISECONDS));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getDelay(TimeUnit unit)
|
public long getDelay(TimeUnit unit)
|
||||||
{
|
{
|
||||||
return unit.convert(due - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
|
return unit.convert(due - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public BusEvent<?> getEvent()
|
public BusEvent<?> getEvent()
|
||||||
{
|
{
|
||||||
return evt;
|
return evt;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thread handling queued events
|
* Thread handling queued events
|
||||||
*/
|
*/
|
||||||
private class QueuePollingThread extends Thread {
|
private class QueuePollingThread extends Thread {
|
||||||
|
|
||||||
public volatile boolean stopped = false;
|
public volatile boolean stopped = false;
|
||||||
|
|
||||||
|
|
||||||
public QueuePollingThread()
|
public QueuePollingThread()
|
||||||
{
|
{
|
||||||
super("Queue Polling Thread");
|
super("Queue Polling Thread");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
DelayQueueEntry evt;
|
DelayQueueEntry evt;
|
||||||
|
|
||||||
while (!stopped) {
|
while (!stopped) {
|
||||||
evt = null;
|
evt = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
evt = sendQueue.take();
|
evt = sendQueue.take();
|
||||||
} catch (final InterruptedException ignored) {
|
} catch (final InterruptedException ignored) {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
if (evt != null) {
|
if (evt != null) {
|
||||||
try {
|
try {
|
||||||
dispatch(evt.getEvent());
|
dispatch(evt.getEvent());
|
||||||
@@ -102,36 +102,36 @@ final public class EventBus implements Destroyable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static final String logMark = "(bus) ";
|
static final String logMark = "(bus) ";
|
||||||
|
|
||||||
|
|
||||||
private static Class<?> getEventListenerClass(BusEvent<?> event)
|
private static Class<?> getEventListenerClass(BusEvent<?> event)
|
||||||
{
|
{
|
||||||
return Reflect.getGenericParameters(event.getClass())[0];
|
return Reflect.getGenericParameters(event.getClass())[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Log detailed messages (debug) */
|
/** Log detailed messages (debug) */
|
||||||
public boolean detailedLogging = false;
|
public boolean detailedLogging = false;
|
||||||
|
|
||||||
/** Queue polling thread */
|
/** Queue polling thread */
|
||||||
private final QueuePollingThread busThread;
|
private final QueuePollingThread busThread;
|
||||||
|
|
||||||
/** Registered clients */
|
/** Registered clients */
|
||||||
private final Set<Object> clients = Collections.newSetFromMap(new ConcurrentHashMap<Object, Boolean>());
|
private final Set<Object> clients = Collections.newSetFromMap(new ConcurrentHashMap<Object, Boolean>());
|
||||||
|
|
||||||
/** Whether the bus was destroyed */
|
/** Whether the bus was destroyed */
|
||||||
private boolean dead = false;
|
private boolean dead = false;
|
||||||
|
|
||||||
/** Message channels */
|
/** Message channels */
|
||||||
private final Set<EventChannel<?, ?>> channels = Collections.newSetFromMap(new ConcurrentHashMap<EventChannel<?, ?>, Boolean>());
|
private final Set<EventChannel<?, ?>> channels = Collections.newSetFromMap(new ConcurrentHashMap<EventChannel<?, ?>, Boolean>());
|
||||||
|
|
||||||
/** Messages queued for delivery */
|
/** Messages queued for delivery */
|
||||||
private final DelayQueue<DelayQueueEntry> sendQueue = new DelayQueue<>();
|
private final DelayQueue<DelayQueueEntry> sendQueue = new DelayQueue<>();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make a new bus and start it's queue thread.
|
* Make a new bus and start it's queue thread.
|
||||||
*/
|
*/
|
||||||
@@ -141,8 +141,8 @@ final public class EventBus implements Destroyable {
|
|||||||
busThread.setDaemon(true);
|
busThread.setDaemon(true);
|
||||||
busThread.start();
|
busThread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Halt bus thread and reject any future events.
|
* Halt bus thread and reject any future events.
|
||||||
*/
|
*/
|
||||||
@@ -150,12 +150,12 @@ final public class EventBus implements Destroyable {
|
|||||||
public void destroy()
|
public void destroy()
|
||||||
{
|
{
|
||||||
assertLive();
|
assertLive();
|
||||||
|
|
||||||
busThread.stopped = true;
|
busThread.stopped = true;
|
||||||
dead = true;
|
dead = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send based on annotation
|
* Send based on annotation
|
||||||
*
|
*
|
||||||
@@ -164,22 +164,22 @@ final public class EventBus implements Destroyable {
|
|||||||
public void send(BusEvent<?> event)
|
public void send(BusEvent<?> event)
|
||||||
{
|
{
|
||||||
assertLive();
|
assertLive();
|
||||||
|
|
||||||
final DelayedEvent adelay = Reflect.getAnnotation(event, DelayedEvent.class);
|
final DelayedEvent adelay = Reflect.getAnnotation(event, DelayedEvent.class);
|
||||||
if (adelay != null) {
|
if (adelay != null) {
|
||||||
sendDelayed(event, adelay.delay());
|
sendDelayed(event, adelay.delay());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Reflect.hasAnnotation(event, DirectEvent.class)) {
|
if (Reflect.hasAnnotation(event, DirectEvent.class)) {
|
||||||
sendDirect(event);
|
sendDirect(event);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sendQueued(event);
|
sendQueued(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add event to a queue
|
* Add event to a queue
|
||||||
*
|
*
|
||||||
@@ -188,11 +188,11 @@ final public class EventBus implements Destroyable {
|
|||||||
public void sendQueued(BusEvent<?> event)
|
public void sendQueued(BusEvent<?> event)
|
||||||
{
|
{
|
||||||
assertLive();
|
assertLive();
|
||||||
|
|
||||||
sendDelayed(event, 0);
|
sendDelayed(event, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add event to a queue, scheduled for given time.
|
* Add event to a queue, scheduled for given time.
|
||||||
*
|
*
|
||||||
@@ -202,17 +202,17 @@ final public class EventBus implements Destroyable {
|
|||||||
public void sendDelayed(BusEvent<?> event, double delay)
|
public void sendDelayed(BusEvent<?> event, double delay)
|
||||||
{
|
{
|
||||||
assertLive();
|
assertLive();
|
||||||
|
|
||||||
final DelayQueueEntry dm = new DelayQueueEntry(delay, event);
|
final DelayQueueEntry dm = new DelayQueueEntry(delay, event);
|
||||||
|
|
||||||
if (shallLog(event)) {
|
if (shallLog(event)) {
|
||||||
Log.f3(logMark + "Qu [" + Support.str(event) + "]" + (delay == 0 ? "" : (", delay: " + delay + "s")));
|
Log.f3(logMark + "Qu [" + Str.val(event) + "]" + (delay == 0 ? "" : (", delay: " + delay + "s")));
|
||||||
}
|
}
|
||||||
|
|
||||||
sendQueue.add(dm);
|
sendQueue.add(dm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send immediately.<br>
|
* Send immediately.<br>
|
||||||
* Should be used for real-time events that require immediate response, such
|
* Should be used for real-time events that require immediate response, such
|
||||||
@@ -223,23 +223,23 @@ final public class EventBus implements Destroyable {
|
|||||||
public void sendDirect(BusEvent<?> event)
|
public void sendDirect(BusEvent<?> event)
|
||||||
{
|
{
|
||||||
assertLive();
|
assertLive();
|
||||||
|
|
||||||
if (shallLog(event)) Log.f3(logMark + "Di [" + Support.str(event) + "]");
|
if (shallLog(event)) Log.f3(logMark + "Di [" + Str.val(event) + "]");
|
||||||
|
|
||||||
dispatch(event);
|
dispatch(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void sendDirectToChildren(DelegatingClient delegatingClient, BusEvent<?> event)
|
public void sendDirectToChildren(DelegatingClient delegatingClient, BusEvent<?> event)
|
||||||
{
|
{
|
||||||
assertLive();
|
assertLive();
|
||||||
|
|
||||||
if (shallLog(event)) Log.f3(logMark + "Di->sub [" + Support.str(event) + "]");
|
if (shallLog(event)) Log.f3(logMark + "Di->sub [" + Str.val(event) + "]");
|
||||||
|
|
||||||
doDispatch(delegatingClient.getChildClients(), event);
|
doDispatch(delegatingClient.getChildClients(), event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connect a client to the bus. The client will be connected to all current
|
* Connect a client to the bus. The client will be connected to all current
|
||||||
* and future channels, until removed from the bus.
|
* and future channels, until removed from the bus.
|
||||||
@@ -249,15 +249,15 @@ final public class EventBus implements Destroyable {
|
|||||||
public void subscribe(Object client)
|
public void subscribe(Object client)
|
||||||
{
|
{
|
||||||
assertLive();
|
assertLive();
|
||||||
|
|
||||||
if (client == null) return;
|
if (client == null) return;
|
||||||
|
|
||||||
clients.add(client);
|
clients.add(client);
|
||||||
|
|
||||||
if (detailedLogging) Log.f3(logMark + "Client joined: " + Support.str(client));
|
if (detailedLogging) Log.f3(logMark + "Client joined: " + Str.val(client));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disconnect a client from the bus.
|
* Disconnect a client from the bus.
|
||||||
*
|
*
|
||||||
@@ -266,47 +266,47 @@ final public class EventBus implements Destroyable {
|
|||||||
public void unsubscribe(Object client)
|
public void unsubscribe(Object client)
|
||||||
{
|
{
|
||||||
assertLive();
|
assertLive();
|
||||||
|
|
||||||
clients.remove(client);
|
clients.remove(client);
|
||||||
|
|
||||||
if (detailedLogging) Log.f3(logMark + "Client left: " + Support.str(client));
|
if (detailedLogging) Log.f3(logMark + "Client left: " + Str.val(client));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private boolean addChannelForEvent(BusEvent<?> event)
|
private boolean addChannelForEvent(BusEvent<?> event)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
if (detailedLogging) {
|
if (detailedLogging) {
|
||||||
Log.f3(logMark + "Setting up channel for new event type: " + Support.str(event.getClass()));
|
Log.f3(logMark + "Setting up channel for new event type: " + Str.val(event.getClass()));
|
||||||
}
|
}
|
||||||
|
|
||||||
final Class<?> listener = getEventListenerClass(event);
|
final Class<?> listener = getEventListenerClass(event);
|
||||||
final EventChannel<?, ?> ch = EventChannel.create(event.getClass(), listener);
|
final EventChannel<?, ?> ch = EventChannel.create(event.getClass(), listener);
|
||||||
|
|
||||||
if (ch.canBroadcast(event)) {
|
if (ch.canBroadcast(event)) {
|
||||||
|
|
||||||
channels.add(ch);
|
channels.add(ch);
|
||||||
//channels.flush();
|
//channels.flush();
|
||||||
|
|
||||||
if (detailedLogging) {
|
if (detailedLogging) {
|
||||||
Log.f3(logMark + "Created new channel: " + Support.str(event.getClass()) + " -> " + Support.str(listener));
|
Log.f3(logMark + "Created new channel: " + Str.val(event.getClass()) + " -> " + Str.val(listener));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Log.w(logMark + "Could not create channel for event " + Support.str(event.getClass()));
|
Log.w(logMark + "Could not create channel for event " + Str.val(event.getClass()));
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (final Throwable t) {
|
} catch (final Throwable t) {
|
||||||
Log.w(logMark + "Error while trying to add channel for event.", t);
|
Log.w(logMark + "Error while trying to add channel for event.", t);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make sure the bus is not destroyed.
|
* Make sure the bus is not destroyed.
|
||||||
*
|
*
|
||||||
@@ -316,8 +316,8 @@ final public class EventBus implements Destroyable {
|
|||||||
{
|
{
|
||||||
if (dead) throw new IllegalStateException("EventBus is dead.");
|
if (dead) throw new IllegalStateException("EventBus is dead.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send immediately.<br>
|
* Send immediately.<br>
|
||||||
* Should be used for real-time events that require immediate response, such
|
* Should be used for real-time events that require immediate response, such
|
||||||
@@ -328,12 +328,12 @@ final public class EventBus implements Destroyable {
|
|||||||
private synchronized void dispatch(BusEvent<?> event)
|
private synchronized void dispatch(BusEvent<?> event)
|
||||||
{
|
{
|
||||||
assertLive();
|
assertLive();
|
||||||
|
|
||||||
doDispatch(clients, event);
|
doDispatch(clients, event);
|
||||||
event.onDispatchComplete(this);
|
event.onDispatchComplete(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send to a set of clients
|
* Send to a set of clients
|
||||||
*
|
*
|
||||||
@@ -343,36 +343,36 @@ final public class EventBus implements Destroyable {
|
|||||||
private synchronized void doDispatch(Collection<?> clients, BusEvent<?> event)
|
private synchronized void doDispatch(Collection<?> clients, BusEvent<?> event)
|
||||||
{
|
{
|
||||||
boolean accepted = false;
|
boolean accepted = false;
|
||||||
|
|
||||||
event.clearFlags();
|
event.clearFlags();
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++) { // two tries.
|
for (int i = 0; i < 2; i++) { // two tries.
|
||||||
|
|
||||||
for (final EventChannel<?, ?> b : channels) {
|
for (final EventChannel<?, ?> b : channels) {
|
||||||
if (b.canBroadcast(event)) {
|
if (b.canBroadcast(event)) {
|
||||||
accepted = true;
|
accepted = true;
|
||||||
b.broadcast(event, clients);
|
b.broadcast(event, clients);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.isConsumed()) break;
|
if (event.isConsumed()) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!accepted) if (addChannelForEvent(event)) continue;
|
if (!accepted) if (addChannelForEvent(event)) continue;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!accepted) Log.e(logMark + "Not accepted by any channel: " + Support.str(event));
|
if (!accepted) Log.e(logMark + "Not accepted by any channel: " + Str.val(event));
|
||||||
if (!event.wasServed() && shallLog(event)) Log.w(logMark + "Not delivered: " + Support.str(event));
|
if (!event.wasServed() && shallLog(event)) Log.w(logMark + "Not delivered: " + Str.val(event));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private boolean shallLog(BusEvent<?> event)
|
private boolean shallLog(BusEvent<?> event)
|
||||||
{
|
{
|
||||||
if (!detailedLogging) return false;
|
if (!detailedLogging) return false;
|
||||||
if (Reflect.hasAnnotation(event, NotLoggedEvent.class)) return false;
|
if (Reflect.hasAnnotation(event, NotLoggedEvent.class)) return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import java.util.Collection;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
|
||||||
import mightypork.utils.Reflect;
|
import mightypork.utils.Reflect;
|
||||||
import mightypork.utils.Support;
|
import mightypork.utils.Str;
|
||||||
import mightypork.utils.eventbus.clients.DelegatingClient;
|
import mightypork.utils.eventbus.clients.DelegatingClient;
|
||||||
import mightypork.utils.eventbus.clients.ToggleableClient;
|
import mightypork.utils.eventbus.clients.ToggleableClient;
|
||||||
import mightypork.utils.eventbus.events.flags.NonRejectableEvent;
|
import mightypork.utils.eventbus.events.flags.NonRejectableEvent;
|
||||||
@@ -20,11 +20,11 @@ import mightypork.utils.logging.Log;
|
|||||||
* @param <CLIENT> client (subscriber) type
|
* @param <CLIENT> client (subscriber) type
|
||||||
*/
|
*/
|
||||||
class EventChannel<EVENT extends BusEvent<CLIENT>, CLIENT> {
|
class EventChannel<EVENT extends BusEvent<CLIENT>, CLIENT> {
|
||||||
|
|
||||||
private final Class<CLIENT> clientClass;
|
private final Class<CLIENT> clientClass;
|
||||||
private final Class<EVENT> eventClass;
|
private final Class<EVENT> eventClass;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a channel
|
* Create a channel
|
||||||
*
|
*
|
||||||
@@ -33,16 +33,16 @@ class EventChannel<EVENT extends BusEvent<CLIENT>, CLIENT> {
|
|||||||
*/
|
*/
|
||||||
public EventChannel(Class<EVENT> eventClass, Class<CLIENT> clientClass)
|
public EventChannel(Class<EVENT> eventClass, Class<CLIENT> clientClass)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (eventClass == null || clientClass == null) {
|
if (eventClass == null || clientClass == null) {
|
||||||
throw new NullPointerException("Null Event or Client class.");
|
throw new NullPointerException("Null Event or Client class.");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.clientClass = clientClass;
|
this.clientClass = clientClass;
|
||||||
this.eventClass = eventClass;
|
this.eventClass = eventClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to broadcast a event.<br>
|
* Try to broadcast a event.<br>
|
||||||
* If event is of wrong type, <code>false</code> is returned.
|
* If event is of wrong type, <code>false</code> is returned.
|
||||||
@@ -53,11 +53,11 @@ class EventChannel<EVENT extends BusEvent<CLIENT>, CLIENT> {
|
|||||||
public void broadcast(BusEvent<?> event, Collection<?> clients)
|
public void broadcast(BusEvent<?> event, Collection<?> clients)
|
||||||
{
|
{
|
||||||
if (!canBroadcast(event)) return;
|
if (!canBroadcast(event)) return;
|
||||||
|
|
||||||
doBroadcast(eventClass.cast(event), clients, new HashSet<>());
|
doBroadcast(eventClass.cast(event), clients, new HashSet<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send the event
|
* Send the event
|
||||||
*
|
*
|
||||||
@@ -68,46 +68,46 @@ class EventChannel<EVENT extends BusEvent<CLIENT>, CLIENT> {
|
|||||||
private void doBroadcast(final EVENT event, final Collection<?> clients, final Collection<Object> processed)
|
private void doBroadcast(final EVENT event, final Collection<?> clients, final Collection<Object> processed)
|
||||||
{
|
{
|
||||||
for (final Object client : clients) {
|
for (final Object client : clients) {
|
||||||
|
|
||||||
// exclude obvious non-clients
|
// exclude obvious non-clients
|
||||||
if (!isClientValid(client)) {
|
if (!isClientValid(client)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// avoid executing more times
|
// avoid executing more times
|
||||||
if (processed.contains(client)) {
|
if (processed.contains(client)) {
|
||||||
Log.w(EventBus.logMark + "Client already served: " + Support.str(client));
|
Log.w(EventBus.logMark + "Client already served: " + Str.val(client));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
processed.add(client);
|
processed.add(client);
|
||||||
|
|
||||||
final boolean must_deliver = Reflect.hasAnnotation(event, NonRejectableEvent.class);
|
final boolean must_deliver = Reflect.hasAnnotation(event, NonRejectableEvent.class);
|
||||||
|
|
||||||
// opt-out
|
// opt-out
|
||||||
if (client instanceof ToggleableClient) {
|
if (client instanceof ToggleableClient) {
|
||||||
if (!must_deliver && !((ToggleableClient) client).isListening()) continue;
|
if (!must_deliver && !((ToggleableClient) client).isListening()) continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
sendTo(client, event);
|
sendTo(client, event);
|
||||||
|
|
||||||
if (event.isConsumed()) return;
|
if (event.isConsumed()) return;
|
||||||
|
|
||||||
// pass on to delegated clients
|
// pass on to delegated clients
|
||||||
if (client instanceof DelegatingClient) {
|
if (client instanceof DelegatingClient) {
|
||||||
if (must_deliver || ((DelegatingClient) client).doesDelegate()) {
|
if (must_deliver || ((DelegatingClient) client).doesDelegate()) {
|
||||||
|
|
||||||
final Collection<?> children = ((DelegatingClient) client).getChildClients();
|
final Collection<?> children = ((DelegatingClient) client).getChildClients();
|
||||||
|
|
||||||
if (children != null && children.size() > 0) {
|
if (children != null && children.size() > 0) {
|
||||||
doBroadcast(event, children, processed);
|
doBroadcast(event, children, processed);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send an event to a client.
|
* Send an event to a client.
|
||||||
*
|
*
|
||||||
@@ -121,8 +121,8 @@ class EventChannel<EVENT extends BusEvent<CLIENT>, CLIENT> {
|
|||||||
((BusEvent<CLIENT>) event).deliverTo((CLIENT) client);
|
((BusEvent<CLIENT>) event).deliverTo((CLIENT) client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the given event can be broadcasted by this channel
|
* Check if the given event can be broadcasted by this channel
|
||||||
*
|
*
|
||||||
@@ -133,8 +133,8 @@ class EventChannel<EVENT extends BusEvent<CLIENT>, CLIENT> {
|
|||||||
{
|
{
|
||||||
return event != null && eventClass.isInstance(event);
|
return event != null && eventClass.isInstance(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an instance for given types
|
* Create an instance for given types
|
||||||
*
|
*
|
||||||
@@ -146,8 +146,8 @@ class EventChannel<EVENT extends BusEvent<CLIENT>, CLIENT> {
|
|||||||
{
|
{
|
||||||
return new EventChannel<>(eventClass, clientClass);
|
return new EventChannel<>(eventClass, clientClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if client is of channel type
|
* Check if client is of channel type
|
||||||
*
|
*
|
||||||
@@ -158,8 +158,8 @@ class EventChannel<EVENT extends BusEvent<CLIENT>, CLIENT> {
|
|||||||
{
|
{
|
||||||
return clientClass.isInstance(client);
|
return clientClass.isInstance(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the channel is compatible with given
|
* Check if the channel is compatible with given
|
||||||
*
|
*
|
||||||
@@ -170,8 +170,8 @@ class EventChannel<EVENT extends BusEvent<CLIENT>, CLIENT> {
|
|||||||
{
|
{
|
||||||
return isClientOfChannelType(client) || (client instanceof DelegatingClient);
|
return isClientOfChannelType(client) || (client instanceof DelegatingClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode()
|
public int hashCode()
|
||||||
{
|
{
|
||||||
@@ -181,8 +181,8 @@ class EventChannel<EVENT extends BusEvent<CLIENT>, CLIENT> {
|
|||||||
result = prime * result + ((eventClass == null) ? 0 : eventClass.hashCode());
|
result = prime * result + ((eventClass == null) ? 0 : eventClass.hashCode());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj)
|
public boolean equals(Object obj)
|
||||||
{
|
{
|
||||||
@@ -198,11 +198,11 @@ class EventChannel<EVENT extends BusEvent<CLIENT>, CLIENT> {
|
|||||||
} else if (!eventClass.equals(other.eventClass)) return false;
|
} else if (!eventClass.equals(other.eventClass)) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return "{ " + Support.str(eventClass) + " => " + Support.str(clientClass) + " }";
|
return "{ " + Str.val(eventClass) + " => " + Str.val(clientClass) + " }";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,33 +15,33 @@ import mightypork.utils.eventbus.EventBus;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public abstract class BusNode implements ClientHub {
|
public abstract class BusNode implements ClientHub {
|
||||||
|
|
||||||
private final Set<Object> clients = new LinkedHashSet<>();
|
private final Set<Object> clients = new LinkedHashSet<>();
|
||||||
private boolean listening = true;
|
private boolean listening = true;
|
||||||
private boolean delegating = true;
|
private boolean delegating = true;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Object> getChildClients()
|
public Collection<Object> getChildClients()
|
||||||
{
|
{
|
||||||
return clients;
|
return clients;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean doesDelegate()
|
public boolean doesDelegate()
|
||||||
{
|
{
|
||||||
return delegating;
|
return delegating;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isListening()
|
public boolean isListening()
|
||||||
{
|
{
|
||||||
return listening;
|
return listening;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a child subscriber to the {@link EventBus}.<br>
|
* Add a child subscriber to the {@link EventBus}.<br>
|
||||||
*
|
*
|
||||||
@@ -52,8 +52,8 @@ public abstract class BusNode implements ClientHub {
|
|||||||
{
|
{
|
||||||
clients.add(client);
|
clients.add(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a child subscriber
|
* Remove a child subscriber
|
||||||
*
|
*
|
||||||
@@ -66,8 +66,8 @@ public abstract class BusNode implements ClientHub {
|
|||||||
clients.remove(client);
|
clients.remove(client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set whether events should be received.
|
* Set whether events should be received.
|
||||||
*
|
*
|
||||||
@@ -77,8 +77,8 @@ public abstract class BusNode implements ClientHub {
|
|||||||
{
|
{
|
||||||
this.listening = listening;
|
this.listening = listening;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set whether events should be passed on to child nodes
|
* Set whether events should be passed on to child nodes
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -12,27 +12,27 @@ import mightypork.utils.eventbus.EventBus;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public interface ClientHub extends DelegatingClient, ToggleableClient {
|
public interface ClientHub extends DelegatingClient, ToggleableClient {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean doesDelegate();
|
public boolean doesDelegate();
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Object> getChildClients();
|
public Collection<Object> getChildClients();
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isListening();
|
public boolean isListening();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a child subscriber to the {@link EventBus}.<br>
|
* Add a child subscriber to the {@link EventBus}.<br>
|
||||||
*
|
*
|
||||||
* @param client
|
* @param client
|
||||||
*/
|
*/
|
||||||
public void addChildClient(Object client);
|
public void addChildClient(Object client);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a child subscriber
|
* Remove a child subscriber
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import java.util.ArrayList;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class ClientList extends ArrayList<Object> {
|
public class ClientList extends ArrayList<Object> {
|
||||||
|
|
||||||
public ClientList(Object... clients)
|
public ClientList(Object... clients)
|
||||||
{
|
{
|
||||||
for (final Object c : clients) {
|
for (final Object c : clients) {
|
||||||
|
|||||||
@@ -12,16 +12,16 @@ import java.util.Collection;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public interface DelegatingClient {
|
public interface DelegatingClient {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return collection of child clients. Can not be null.
|
* @return collection of child clients. Can not be null.
|
||||||
*/
|
*/
|
||||||
public Collection<?> getChildClients();
|
public Collection<?> getChildClients();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if delegating is active
|
* @return true if delegating is active
|
||||||
*/
|
*/
|
||||||
public boolean doesDelegate();
|
public boolean doesDelegate();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,10 +12,10 @@ import mightypork.utils.interfaces.Enableable;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class DelegatingList extends ClientList implements DelegatingClient, Enableable, ToggleableClient {
|
public class DelegatingList extends ClientList implements DelegatingClient, Enableable, ToggleableClient {
|
||||||
|
|
||||||
private boolean enabled = true;
|
private boolean enabled = true;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delegating list with initial clients
|
* Delegating list with initial clients
|
||||||
*
|
*
|
||||||
@@ -25,44 +25,44 @@ public class DelegatingList extends ClientList implements DelegatingClient, Enab
|
|||||||
{
|
{
|
||||||
super(clients);
|
super(clients);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Empty delegating list.
|
* Empty delegating list.
|
||||||
*/
|
*/
|
||||||
public DelegatingList()
|
public DelegatingList()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<?> getChildClients()
|
public Collection<?> getChildClients()
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean doesDelegate()
|
public boolean doesDelegate()
|
||||||
{
|
{
|
||||||
return isEnabled();
|
return isEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isListening()
|
public boolean isListening()
|
||||||
{
|
{
|
||||||
return isEnabled();
|
return isEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setEnabled(boolean yes)
|
public void setEnabled(boolean yes)
|
||||||
{
|
{
|
||||||
enabled = yes;
|
enabled = yes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabled()
|
public boolean isEnabled()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ package mightypork.utils.eventbus.clients;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public interface ToggleableClient {
|
public interface ToggleableClient {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if the client wants to receive messages
|
* @return true if the client wants to receive messages
|
||||||
*/
|
*/
|
||||||
public boolean isListening();
|
public boolean isListening();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ package mightypork.utils.eventbus.events;
|
|||||||
import mightypork.utils.eventbus.BusEvent;
|
import mightypork.utils.eventbus.BusEvent;
|
||||||
import mightypork.utils.eventbus.events.flags.DirectEvent;
|
import mightypork.utils.eventbus.events.flags.DirectEvent;
|
||||||
import mightypork.utils.eventbus.events.flags.NonConsumableEvent;
|
import mightypork.utils.eventbus.events.flags.NonConsumableEvent;
|
||||||
|
import mightypork.utils.eventbus.events.flags.NonRejectableEvent;
|
||||||
import mightypork.utils.interfaces.Destroyable;
|
import mightypork.utils.interfaces.Destroyable;
|
||||||
|
|
||||||
|
|
||||||
@@ -14,6 +15,7 @@ import mightypork.utils.interfaces.Destroyable;
|
|||||||
*/
|
*/
|
||||||
@DirectEvent
|
@DirectEvent
|
||||||
@NonConsumableEvent
|
@NonConsumableEvent
|
||||||
|
@NonRejectableEvent
|
||||||
public class DestroyEvent extends BusEvent<Destroyable> {
|
public class DestroyEvent extends BusEvent<Destroyable> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -17,10 +17,10 @@ import mightypork.utils.interfaces.Updateable;
|
|||||||
@DirectEvent
|
@DirectEvent
|
||||||
@NonConsumableEvent
|
@NonConsumableEvent
|
||||||
public class UpdateEvent extends BusEvent<Updateable> {
|
public class UpdateEvent extends BusEvent<Updateable> {
|
||||||
|
|
||||||
private final double deltaTime;
|
private final double deltaTime;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param deltaTime time since last update (sec)
|
* @param deltaTime time since last update (sec)
|
||||||
*/
|
*/
|
||||||
@@ -28,8 +28,8 @@ public class UpdateEvent extends BusEvent<Updateable> {
|
|||||||
{
|
{
|
||||||
this.deltaTime = deltaTime;
|
this.deltaTime = deltaTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleBy(Updateable handler)
|
public void handleBy(Updateable handler)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import java.lang.annotation.Target;
|
|||||||
@Inherited
|
@Inherited
|
||||||
@Documented
|
@Documented
|
||||||
public @interface DelayedEvent {
|
public @interface DelayedEvent {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return event dispatch delay [seconds]
|
* @return event dispatch delay [seconds]
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -17,5 +17,5 @@ import java.lang.annotation.Target;
|
|||||||
@Documented
|
@Documented
|
||||||
@Target(ElementType.TYPE)
|
@Target(ElementType.TYPE)
|
||||||
public @interface NonConsumableEvent {
|
public @interface NonConsumableEvent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,5 +17,5 @@ import java.lang.annotation.Target;
|
|||||||
@Documented
|
@Documented
|
||||||
@Target(ElementType.TYPE)
|
@Target(ElementType.TYPE)
|
||||||
public @interface NonRejectableEvent {
|
public @interface NonRejectableEvent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,28 +10,28 @@ import java.io.IOException;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class CorruptDataException extends IOException {
|
public class CorruptDataException extends IOException {
|
||||||
|
|
||||||
public CorruptDataException()
|
public CorruptDataException()
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public CorruptDataException(String message, Throwable cause)
|
public CorruptDataException(String message, Throwable cause)
|
||||||
{
|
{
|
||||||
super(message, cause);
|
super(message, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public CorruptDataException(String message)
|
public CorruptDataException(String message)
|
||||||
{
|
{
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public CorruptDataException(Throwable cause)
|
public CorruptDataException(Throwable cause)
|
||||||
{
|
{
|
||||||
super(cause);
|
super(cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,27 +8,27 @@ package mightypork.utils.exceptions;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class IllegalValueException extends RuntimeException {
|
public class IllegalValueException extends RuntimeException {
|
||||||
|
|
||||||
public IllegalValueException()
|
public IllegalValueException()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public IllegalValueException(String message)
|
public IllegalValueException(String message)
|
||||||
{
|
{
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public IllegalValueException(Throwable cause)
|
public IllegalValueException(Throwable cause)
|
||||||
{
|
{
|
||||||
super(cause);
|
super(cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public IllegalValueException(String message, Throwable cause)
|
public IllegalValueException(String message, Throwable cause)
|
||||||
{
|
{
|
||||||
super(message, cause);
|
super(message, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,28 +7,28 @@ package mightypork.utils.exceptions;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class KeyAlreadyExistsException extends RuntimeException {
|
public class KeyAlreadyExistsException extends RuntimeException {
|
||||||
|
|
||||||
public KeyAlreadyExistsException()
|
public KeyAlreadyExistsException()
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public KeyAlreadyExistsException(String message, Throwable cause)
|
public KeyAlreadyExistsException(String message, Throwable cause)
|
||||||
{
|
{
|
||||||
super(message, cause);
|
super(message, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public KeyAlreadyExistsException(String message)
|
public KeyAlreadyExistsException(String message)
|
||||||
{
|
{
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public KeyAlreadyExistsException(Throwable cause)
|
public KeyAlreadyExistsException(Throwable cause)
|
||||||
{
|
{
|
||||||
super(cause);
|
super(cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,11 +11,11 @@ import java.io.FileFilter;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class FileSuffixFilter implements FileFilter {
|
public class FileSuffixFilter implements FileFilter {
|
||||||
|
|
||||||
/** Array of allowed suffixes */
|
/** Array of allowed suffixes */
|
||||||
private String[] suffixes = null;
|
private String[] suffixes = null;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Suffix filter
|
* Suffix filter
|
||||||
*
|
*
|
||||||
@@ -25,22 +25,22 @@ public class FileSuffixFilter implements FileFilter {
|
|||||||
{
|
{
|
||||||
this.suffixes = suffixes;
|
this.suffixes = suffixes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean accept(File pathname)
|
public boolean accept(File pathname)
|
||||||
{
|
{
|
||||||
if (!pathname.isFile()) return false;
|
if (!pathname.isFile()) return false;
|
||||||
|
|
||||||
final String fname = pathname.getName().toLowerCase().trim();
|
final String fname = pathname.getName().toLowerCase().trim();
|
||||||
|
|
||||||
for (final String suffix : suffixes) {
|
for (final String suffix : suffixes) {
|
||||||
if (fname.endsWith(suffix.toLowerCase().trim())) {
|
if (fname.endsWith(suffix.toLowerCase().trim())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,138 +16,138 @@ import mightypork.utils.logging.Log;
|
|||||||
|
|
||||||
|
|
||||||
public class FileTreeDiff {
|
public class FileTreeDiff {
|
||||||
|
|
||||||
private static final byte[] BUFFER = new byte[2048];
|
private static final byte[] BUFFER = new byte[2048];
|
||||||
private final Checksum ck1 = new Adler32();
|
private final Checksum ck1 = new Adler32();
|
||||||
private final Checksum ck2 = new Adler32();
|
private final Checksum ck2 = new Adler32();
|
||||||
|
|
||||||
private boolean logging = true;
|
private boolean logging = true;
|
||||||
|
|
||||||
private final List<Tuple<File>> compared = new ArrayList<>();
|
private final List<Tuple<File>> compared = new ArrayList<>();
|
||||||
private final Comparator<File> fileFirstSorter = new Comparator<File>() {
|
private final Comparator<File> fileFirstSorter = new Comparator<File>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compare(File o1, File o2)
|
public int compare(File o1, File o2)
|
||||||
{
|
{
|
||||||
if (!o1.isDirectory() && o2.isDirectory()) return -1;
|
if (!o1.isDirectory() && o2.isDirectory()) return -1;
|
||||||
if (o1.isDirectory() && !o2.isDirectory()) return 1;
|
if (o1.isDirectory() && !o2.isDirectory()) return 1;
|
||||||
|
|
||||||
return o1.getName().compareTo(o2.getName());
|
return o1.getName().compareTo(o2.getName());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
public void enableLogging(boolean state)
|
public void enableLogging(boolean state)
|
||||||
{
|
{
|
||||||
logging = state;
|
logging = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean areEqual(File dir1, File dir2)
|
public boolean areEqual(File dir1, File dir2)
|
||||||
{
|
{
|
||||||
if (logging) Log.f3("Comparing directory trees:\n 1. " + dir1 + "\n 2. " + dir2);
|
if (logging) Log.f3("Comparing directory trees:\n 1. " + dir1 + "\n 2. " + dir2);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
compared.clear();
|
compared.clear();
|
||||||
buildList(dir1, dir2);
|
buildList(dir1, dir2);
|
||||||
|
|
||||||
calcChecksum();
|
calcChecksum();
|
||||||
|
|
||||||
if (logging) Log.f3("No difference found.");
|
if (logging) Log.f3("No difference found.");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
} catch (final NotEqualException e) {
|
} catch (final NotEqualException e) {
|
||||||
if (logging) Log.f3("Difference found:\n" + e.getMessage());
|
if (logging) Log.f3("Difference found:\n" + e.getMessage());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void calcChecksum() throws NotEqualException
|
private void calcChecksum() throws NotEqualException
|
||||||
{
|
{
|
||||||
|
|
||||||
for (final Tuple<File> pair : compared) {
|
for (final Tuple<File> pair : compared) {
|
||||||
ck1.reset();
|
ck1.reset();
|
||||||
ck2.reset();
|
ck2.reset();
|
||||||
|
|
||||||
try(FileInputStream in1 = new FileInputStream(pair.a);
|
try(FileInputStream in1 = new FileInputStream(pair.a);
|
||||||
FileInputStream in2 = new FileInputStream(pair.b)) {
|
FileInputStream in2 = new FileInputStream(pair.b)) {
|
||||||
|
|
||||||
try(CheckedInputStream cin1 = new CheckedInputStream(in1, ck1);
|
try(CheckedInputStream cin1 = new CheckedInputStream(in1, ck1);
|
||||||
CheckedInputStream cin2 = new CheckedInputStream(in2, ck2)) {
|
CheckedInputStream cin2 = new CheckedInputStream(in2, ck2)) {
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
final int read1 = cin1.read(BUFFER);
|
final int read1 = cin1.read(BUFFER);
|
||||||
final int read2 = cin2.read(BUFFER);
|
final int read2 = cin2.read(BUFFER);
|
||||||
|
|
||||||
if (read1 != read2 || ck1.getValue() != ck2.getValue()) {
|
if (read1 != read2 || ck1.getValue() != ck2.getValue()) {
|
||||||
throw new NotEqualException("Bytes differ:\n" + pair.a + "\n" + pair.b);
|
throw new NotEqualException("Bytes differ:\n" + pair.a + "\n" + pair.b);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (read1 == -1) break;
|
if (read1 == -1) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (final IOException e) {
|
} catch (final IOException e) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void buildList(File f1, File f2) throws NotEqualException
|
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.isDirectory() != f2.isDirectory()) throw new NotEqualException("isDirectory differs:\n" + f1 + "\n" + f2);
|
||||||
|
|
||||||
if (f1.isFile() && f2.isFile()) {
|
if (f1.isFile() && f2.isFile()) {
|
||||||
if (f1.length() != f2.length()) throw new NotEqualException("Sizes differ:\n" + f1 + "\n" + f2);
|
if (f1.length() != f2.length()) throw new NotEqualException("Sizes differ:\n" + f1 + "\n" + f2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f1.isDirectory()) {
|
if (f1.isDirectory()) {
|
||||||
final File[] children1 = f1.listFiles();
|
final File[] children1 = f1.listFiles();
|
||||||
final File[] children2 = f2.listFiles();
|
final File[] children2 = f2.listFiles();
|
||||||
|
|
||||||
Arrays.sort(children1, fileFirstSorter);
|
Arrays.sort(children1, fileFirstSorter);
|
||||||
Arrays.sort(children2, fileFirstSorter);
|
Arrays.sort(children2, fileFirstSorter);
|
||||||
|
|
||||||
if (children1.length != children2.length) throw new NotEqualException("Child counts differ:\n" + f1 + "\n" + f2);
|
if (children1.length != children2.length) throw new NotEqualException("Child counts differ:\n" + f1 + "\n" + f2);
|
||||||
|
|
||||||
for (int i = 0; i < children1.length; i++) {
|
for (int i = 0; i < children1.length; i++) {
|
||||||
final File ch1 = children1[i];
|
final File ch1 = children1[i];
|
||||||
final File ch2 = children2[i];
|
final File ch2 = children2[i];
|
||||||
|
|
||||||
if (!ch1.getName().equals(ch2.getName())) throw new NotEqualException("Filenames differ:\n" + ch1 + "\n" + ch2);
|
if (!ch1.getName().equals(ch2.getName())) throw new NotEqualException("Filenames differ:\n" + ch1 + "\n" + ch2);
|
||||||
|
|
||||||
buildList(ch1, ch2);
|
buildList(ch1, ch2);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
compared.add(new Tuple<>(f1, f2));
|
compared.add(new Tuple<>(f1, f2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class NotEqualException extends Exception {
|
private class NotEqualException extends Exception {
|
||||||
|
|
||||||
public NotEqualException(String msg)
|
public NotEqualException(String msg)
|
||||||
{
|
{
|
||||||
super(msg);
|
super(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Tuple<T> {
|
private class Tuple<T> {
|
||||||
|
|
||||||
public T a;
|
public T a;
|
||||||
public T b;
|
public T b;
|
||||||
|
|
||||||
|
|
||||||
public Tuple(T a, T b)
|
public Tuple(T a, T b)
|
||||||
{
|
{
|
||||||
this.a = a;
|
this.a = a;
|
||||||
this.b = b;
|
this.b = b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,14 +17,14 @@ import java.io.UnsupportedEncodingException;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import mightypork.utils.Str;
|
||||||
import mightypork.utils.logging.Log;
|
import mightypork.utils.logging.Log;
|
||||||
import mightypork.utils.string.StringUtil;
|
|
||||||
import mightypork.utils.string.validation.StringFilter;
|
import mightypork.utils.string.validation.StringFilter;
|
||||||
|
|
||||||
|
|
||||||
public class FileUtil {
|
public class FileUtil {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy directory recursively.
|
* Copy directory recursively.
|
||||||
*
|
*
|
||||||
@@ -36,8 +36,8 @@ public class FileUtil {
|
|||||||
{
|
{
|
||||||
copyDirectory(source, target, null, null);
|
copyDirectory(source, target, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy directory recursively - advanced variant.
|
* Copy directory recursively - advanced variant.
|
||||||
*
|
*
|
||||||
@@ -50,28 +50,28 @@ public class FileUtil {
|
|||||||
public static void copyDirectory(File source, File target, FileFilter filter, List<File> filesCopied) throws IOException
|
public static void copyDirectory(File source, File target, FileFilter filter, List<File> filesCopied) throws IOException
|
||||||
{
|
{
|
||||||
if (!source.exists()) return;
|
if (!source.exists()) return;
|
||||||
|
|
||||||
if (source.isDirectory()) {
|
if (source.isDirectory()) {
|
||||||
if (!target.exists() && !target.mkdir()) {
|
if (!target.exists() && !target.mkdir()) {
|
||||||
throw new IOException("Could not open destination directory.");
|
throw new IOException("Could not open destination directory.");
|
||||||
}
|
}
|
||||||
|
|
||||||
final String[] children = source.list();
|
final String[] children = source.list();
|
||||||
for (final String element : children) {
|
for (final String element : children) {
|
||||||
copyDirectory(new File(source, element), new File(target, element), filter, filesCopied);
|
copyDirectory(new File(source, element), new File(target, element), filter, filesCopied);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (filter != null && !filter.accept(source)) {
|
if (filter != null && !filter.accept(source)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filesCopied != null) filesCopied.add(target);
|
if (filesCopied != null) filesCopied.add(target);
|
||||||
copyFile(source, target);
|
copyFile(source, target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List directory recursively
|
* List directory recursively
|
||||||
*
|
*
|
||||||
@@ -87,17 +87,17 @@ public class FileUtil {
|
|||||||
for (final String element : children) {
|
for (final String element : children) {
|
||||||
listDirectoryRecursive(new File(source, element), filter, files);
|
listDirectoryRecursive(new File(source, element), filter, files);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (filter != null && !filter.isValid(source.getAbsolutePath())) {
|
if (filter != null && !filter.isValid(source.getAbsolutePath())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
files.add(source);
|
files.add(source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy file using streams. Make sure target directory exists!
|
* Copy file using streams. Make sure target directory exists!
|
||||||
*
|
*
|
||||||
@@ -107,15 +107,15 @@ public class FileUtil {
|
|||||||
*/
|
*/
|
||||||
public static void copyFile(File source, File target) throws IOException
|
public static void copyFile(File source, File target) throws IOException
|
||||||
{
|
{
|
||||||
|
|
||||||
try(InputStream in = new FileInputStream(source);
|
try(InputStream in = new FileInputStream(source);
|
||||||
OutputStream out = new FileOutputStream(target)) {
|
OutputStream out = new FileOutputStream(target)) {
|
||||||
|
|
||||||
copyStream(in, out);
|
copyStream(in, out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy bytes from input to output stream, leaving out stream open
|
* Copy bytes from input to output stream, leaving out stream open
|
||||||
*
|
*
|
||||||
@@ -128,19 +128,19 @@ public class FileUtil {
|
|||||||
if (in == null) {
|
if (in == null) {
|
||||||
throw new NullPointerException("Input stream is null");
|
throw new NullPointerException("Input stream is null");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (out == null) {
|
if (out == null) {
|
||||||
throw new NullPointerException("Output stream is null");
|
throw new NullPointerException("Output stream is null");
|
||||||
}
|
}
|
||||||
|
|
||||||
final byte[] buf = new byte[2048];
|
final byte[] buf = new byte[2048];
|
||||||
int len;
|
int len;
|
||||||
while ((len = in.read(buf)) > 0) {
|
while ((len = in.read(buf)) > 0) {
|
||||||
out.write(buf, 0, len);
|
out.write(buf, 0, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Improved delete
|
* Improved delete
|
||||||
*
|
*
|
||||||
@@ -153,18 +153,18 @@ public class FileUtil {
|
|||||||
if (!path.exists()) {
|
if (!path.exists()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!recursive || !path.isDirectory()) return path.delete();
|
if (!recursive || !path.isDirectory()) return path.delete();
|
||||||
|
|
||||||
final String[] list = path.list();
|
final String[] list = path.list();
|
||||||
for (int i = 0; i < list.length; i++) {
|
for (int i = 0; i < list.length; i++) {
|
||||||
if (!delete(new File(path, list[i]), true)) return false;
|
if (!delete(new File(path, list[i]), true)) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return path.delete();
|
return path.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read entire file to a string.
|
* Read entire file to a string.
|
||||||
*
|
*
|
||||||
@@ -175,12 +175,12 @@ public class FileUtil {
|
|||||||
public static String fileToString(File file) 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);
|
return streamToString(fin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get files in a folder (create folder if needed)
|
* Get files in a folder (create folder if needed)
|
||||||
*
|
*
|
||||||
@@ -191,8 +191,8 @@ public class FileUtil {
|
|||||||
{
|
{
|
||||||
return FileUtil.listDirectory(dir, null);
|
return FileUtil.listDirectory(dir, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get files in a folder (create folder if needed)
|
* Get files in a folder (create folder if needed)
|
||||||
*
|
*
|
||||||
@@ -203,17 +203,17 @@ public class FileUtil {
|
|||||||
public static List<File> listDirectory(File dir, FileFilter filter)
|
public static List<File> listDirectory(File dir, FileFilter filter)
|
||||||
{
|
{
|
||||||
dir.mkdir();
|
dir.mkdir();
|
||||||
|
|
||||||
final List<File> list = new ArrayList<>();
|
final List<File> list = new ArrayList<>();
|
||||||
|
|
||||||
for (final File f : dir.listFiles(filter)) {
|
for (final File f : dir.listFiles(filter)) {
|
||||||
list.add(f);
|
list.add(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove extension.
|
* Remove extension.
|
||||||
*
|
*
|
||||||
@@ -224,20 +224,20 @@ public class FileUtil {
|
|||||||
{
|
{
|
||||||
return getFilenameParts(file.getName());
|
return getFilenameParts(file.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static String getExtension(File file)
|
public static String getExtension(File file)
|
||||||
{
|
{
|
||||||
return getExtension(file.getName());
|
return getExtension(file.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static String getExtension(String file)
|
public static String getExtension(String file)
|
||||||
{
|
{
|
||||||
return StringUtil.fromLastChar(file, '.');
|
return Str.fromLast(file, '.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove extension.
|
* Remove extension.
|
||||||
*
|
*
|
||||||
@@ -247,24 +247,24 @@ public class FileUtil {
|
|||||||
public static String[] getFilenameParts(String filename)
|
public static String[] getFilenameParts(String filename)
|
||||||
{
|
{
|
||||||
String ext, name;
|
String ext, name;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ext = StringUtil.fromLastDot(filename);
|
ext = Str.fromLastDot(filename);
|
||||||
} catch (final StringIndexOutOfBoundsException e) {
|
} catch (final StringIndexOutOfBoundsException e) {
|
||||||
ext = "";
|
ext = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
name = StringUtil.toLastDot(filename);
|
name = Str.toLastDot(filename);
|
||||||
} catch (final StringIndexOutOfBoundsException e) {
|
} catch (final StringIndexOutOfBoundsException e) {
|
||||||
name = "";
|
name = "";
|
||||||
Log.w("Error extracting extension from file " + filename);
|
Log.w("Error extracting extension from file " + filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new String[] { name, ext };
|
return new String[] { name, ext };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read entire input stream to a string, and close it.
|
* Read entire input stream to a string, and close it.
|
||||||
*
|
*
|
||||||
@@ -275,8 +275,8 @@ public class FileUtil {
|
|||||||
{
|
{
|
||||||
return streamToString(in, -1);
|
return streamToString(in, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read input stream to a string, and close it.
|
* Read input stream to a string, and close it.
|
||||||
*
|
*
|
||||||
@@ -290,10 +290,10 @@ public class FileUtil {
|
|||||||
Log.e(new NullPointerException("Null stream to be converted to String."));
|
Log.e(new NullPointerException("Null stream to be converted to String."));
|
||||||
return ""; // to avoid NPE's
|
return ""; // to avoid NPE's
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferedReader br = null;
|
BufferedReader br = null;
|
||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
String line;
|
String line;
|
||||||
try {
|
try {
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
@@ -302,11 +302,11 @@ public class FileUtil {
|
|||||||
sb.append(line + "\n");
|
sb.append(line + "\n");
|
||||||
cnt++;
|
cnt++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cnt == lines && lines > 0) {
|
if (cnt == lines && lines > 0) {
|
||||||
sb.append("--- end of preview ---\n");
|
sb.append("--- end of preview ---\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (final IOException e) {
|
} catch (final IOException e) {
|
||||||
Log.e(e);
|
Log.e(e);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -316,15 +316,15 @@ public class FileUtil {
|
|||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static InputStream stringToStream(String text)
|
public static InputStream stringToStream(String text)
|
||||||
{
|
{
|
||||||
if (text == null) return null;
|
if (text == null) return null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return new ByteArrayInputStream(text.getBytes("UTF-8"));
|
return new ByteArrayInputStream(text.getBytes("UTF-8"));
|
||||||
} catch (final UnsupportedEncodingException e) {
|
} catch (final UnsupportedEncodingException e) {
|
||||||
@@ -332,38 +332,38 @@ public class FileUtil {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static InputStream getResource(String path)
|
public static InputStream getResource(String path)
|
||||||
{
|
{
|
||||||
final InputStream in = FileUtil.class.getResourceAsStream(path);
|
final InputStream in = FileUtil.class.getResourceAsStream(path);
|
||||||
|
|
||||||
if (in != null) return in;
|
if (in != null) return in;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return new FileInputStream(new File(".", path));
|
return new FileInputStream(new File(".", path));
|
||||||
|
|
||||||
} catch (final FileNotFoundException e) {
|
|
||||||
|
|
||||||
|
} catch (final FileNotFoundException e) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return new FileInputStream(WorkDir.getFile(path));
|
return new FileInputStream(WorkDir.getFile(path));
|
||||||
|
|
||||||
} catch (final FileNotFoundException e2) {
|
} catch (final FileNotFoundException e2) {
|
||||||
Log.w("Could not open resource stream, file not found: " + path);
|
Log.w("Could not open resource stream, file not found: " + path);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static String getResourceAsString(String path)
|
public static String getResourceAsString(String path)
|
||||||
{
|
{
|
||||||
return streamToString(getResource(path));
|
return streamToString(getResource(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save string to file
|
* Save string to file
|
||||||
*
|
*
|
||||||
@@ -374,44 +374,44 @@ public class FileUtil {
|
|||||||
public static void stringToFile(File file, String text) throws IOException
|
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);
|
out.print(text);
|
||||||
|
|
||||||
out.flush();
|
out.flush();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void deleteEmptyDirs(File base) throws IOException
|
public static void deleteEmptyDirs(File base) throws IOException
|
||||||
{
|
{
|
||||||
for (final File f : listDirectory(base)) {
|
for (final File f : listDirectory(base)) {
|
||||||
if (!f.isDirectory()) continue;
|
if (!f.isDirectory()) continue;
|
||||||
|
|
||||||
deleteEmptyDirs(f);
|
deleteEmptyDirs(f);
|
||||||
|
|
||||||
final List<File> children = listDirectory(f);
|
final List<File> children = listDirectory(f);
|
||||||
if (children.size() == 0) {
|
if (children.size() == 0) {
|
||||||
if (!f.delete()) throw new IOException("Could not delete a directory: " + f);
|
if (!f.delete()) throw new IOException("Could not delete a directory: " + f);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static String getBasename(String name)
|
public static String getBasename(String name)
|
||||||
{
|
{
|
||||||
return StringUtil.toLastChar(StringUtil.fromLastChar(name, '/'), '.');
|
return Str.toLast(Str.fromLast(name, '/'), '.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static String getFilename(String name)
|
public static String getFilename(String name)
|
||||||
{
|
{
|
||||||
return StringUtil.fromLastChar(name, '/');
|
return Str.fromLast(name, '/');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy resource to file
|
* Copy resource to file
|
||||||
*
|
*
|
||||||
@@ -422,14 +422,14 @@ public class FileUtil {
|
|||||||
public static void resourceToFile(String resname, File file) throws IOException
|
public static void resourceToFile(String resname, File file) throws IOException
|
||||||
{
|
{
|
||||||
try(InputStream in = FileUtil.getResource(resname);
|
try(InputStream in = FileUtil.getResource(resname);
|
||||||
OutputStream out = new FileOutputStream(file)) {
|
OutputStream out = new FileOutputStream(file)) {
|
||||||
|
|
||||||
FileUtil.copyStream(in, out);
|
FileUtil.copyStream(in, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get resource as string, safely closing streams.
|
* Get resource as string, safely closing streams.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -13,19 +13,19 @@ import java.nio.channels.FileLock;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class InstanceLock {
|
public class InstanceLock {
|
||||||
|
|
||||||
@SuppressWarnings("resource")
|
@SuppressWarnings("resource")
|
||||||
public static boolean onFile(final File lockFile)
|
public static boolean onFile(final File lockFile)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
lockFile.getParentFile().mkdirs();
|
lockFile.getParentFile().mkdirs();
|
||||||
final RandomAccessFile randomAccessFile = new RandomAccessFile(lockFile, "rw");
|
final RandomAccessFile randomAccessFile = new RandomAccessFile(lockFile, "rw");
|
||||||
|
|
||||||
final FileLock fileLock = randomAccessFile.getChannel().tryLock();
|
final FileLock fileLock = randomAccessFile.getChannel().tryLock();
|
||||||
if (fileLock != null) {
|
if (fileLock != null) {
|
||||||
|
|
||||||
Runtime.getRuntime().addShutdownHook(new Thread() {
|
Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
@@ -39,10 +39,10 @@ public class InstanceLock {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
} catch (final IOException e) {
|
} catch (final IOException e) {
|
||||||
System.err.println("IO error while obtaining lock.");
|
System.err.println("IO error while obtaining lock.");
|
||||||
@@ -50,5 +50,5 @@ public class InstanceLock {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,90 +5,90 @@ import java.io.File;
|
|||||||
|
|
||||||
|
|
||||||
public class OsUtils {
|
public class OsUtils {
|
||||||
|
|
||||||
public static enum EnumOS
|
public static enum EnumOS
|
||||||
{
|
{
|
||||||
linux, macos, solaris, unknown, windows;
|
linux, macos, solaris, unknown, windows;
|
||||||
|
|
||||||
public boolean isLinux()
|
public boolean isLinux()
|
||||||
{
|
{
|
||||||
return this == linux || this == solaris;
|
return this == linux || this == solaris;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean isMac()
|
public boolean isMac()
|
||||||
{
|
{
|
||||||
return this == macos;
|
return this == macos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean isWindows()
|
public boolean isWindows()
|
||||||
{
|
{
|
||||||
return this == windows;
|
return this == windows;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static EnumOS cachedOs;
|
private static EnumOS cachedOs;
|
||||||
|
|
||||||
|
|
||||||
public static File getHomeWorkDir(String dirname)
|
public static File getHomeWorkDir(String dirname)
|
||||||
{
|
{
|
||||||
final String userhome = System.getProperty("user.home", ".");
|
final String userhome = System.getProperty("user.home", ".");
|
||||||
File file;
|
File file;
|
||||||
|
|
||||||
switch (getOs()) {
|
switch (getOs()) {
|
||||||
case linux:
|
case linux:
|
||||||
case solaris:
|
case solaris:
|
||||||
file = new File(userhome, dirname + '/');
|
file = new File(userhome, dirname + '/');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case windows:
|
case windows:
|
||||||
final String appdata = System.getenv("APPDATA");
|
final String appdata = System.getenv("APPDATA");
|
||||||
|
|
||||||
if (appdata != null) {
|
if (appdata != null) {
|
||||||
file = new File(appdata, dirname + '/');
|
file = new File(appdata, dirname + '/');
|
||||||
} else {
|
} else {
|
||||||
file = new File(userhome, dirname + '/');
|
file = new File(userhome, dirname + '/');
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case macos:
|
case macos:
|
||||||
file = new File(userhome, "Library/Application Support/" + dirname);
|
file = new File(userhome, "Library/Application Support/" + dirname);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
file = new File(userhome, dirname + "/");
|
file = new File(userhome, dirname + "/");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static EnumOS getOs()
|
public static EnumOS getOs()
|
||||||
{
|
{
|
||||||
if (cachedOs != null) return cachedOs;
|
if (cachedOs != null) return cachedOs;
|
||||||
|
|
||||||
final String s = System.getProperty("os.name").toLowerCase();
|
final String s = System.getProperty("os.name").toLowerCase();
|
||||||
|
|
||||||
if (s.contains("win")) {
|
if (s.contains("win")) {
|
||||||
cachedOs = EnumOS.windows;
|
cachedOs = EnumOS.windows;
|
||||||
|
|
||||||
} else if (s.contains("mac")) {
|
} else if (s.contains("mac")) {
|
||||||
cachedOs = EnumOS.macos;
|
cachedOs = EnumOS.macos;
|
||||||
|
|
||||||
} else if (s.contains("linux") || s.contains("unix")) {
|
} else if (s.contains("linux") || s.contains("unix")) {
|
||||||
cachedOs = EnumOS.linux;
|
cachedOs = EnumOS.linux;
|
||||||
|
|
||||||
} else if (s.contains("solaris") || s.contains("sunos")) {
|
} else if (s.contains("solaris") || s.contains("sunos")) {
|
||||||
cachedOs = EnumOS.solaris;
|
cachedOs = EnumOS.solaris;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
cachedOs = EnumOS.unknown;
|
cachedOs = EnumOS.unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
return cachedOs;
|
return cachedOs;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,11 +14,11 @@ import mightypork.utils.logging.Log;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class WorkDir {
|
public class WorkDir {
|
||||||
|
|
||||||
private static File baseDir = new File(".");
|
private static File baseDir = new File(".");
|
||||||
private static Map<String, String> namedPaths = new HashMap<>();
|
private static Map<String, String> namedPaths = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the workdir for the given root path
|
* Initialize the workdir for the given root path
|
||||||
*
|
*
|
||||||
@@ -28,8 +28,8 @@ public class WorkDir {
|
|||||||
{
|
{
|
||||||
WorkDir.baseDir = workdir;
|
WorkDir.baseDir = workdir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a path alias (dir or file), relative to the workdir.
|
* Add a path alias (dir or file), relative to the workdir.
|
||||||
*
|
*
|
||||||
@@ -40,8 +40,8 @@ public class WorkDir {
|
|||||||
{
|
{
|
||||||
namedPaths.put(alias, path);
|
namedPaths.put(alias, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get workdir folder, create if not exists.
|
* Get workdir folder, create if not exists.
|
||||||
*
|
*
|
||||||
@@ -51,18 +51,18 @@ public class WorkDir {
|
|||||||
public static File getDir(String path)
|
public static File getDir(String path)
|
||||||
{
|
{
|
||||||
if (namedPaths.containsKey(path)) path = namedPaths.get(path);
|
if (namedPaths.containsKey(path)) path = namedPaths.get(path);
|
||||||
|
|
||||||
final File f = new File(baseDir, path);
|
final File f = new File(baseDir, path);
|
||||||
if (!f.exists()) {
|
if (!f.exists()) {
|
||||||
if (!f.mkdirs()) {
|
if (!f.mkdirs()) {
|
||||||
Log.w("Could not create a directory: " + f + " (path: " + path + ")");
|
Log.w("Could not create a directory: " + f + " (path: " + path + ")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get workdir file, create parent if not exists.
|
* Get workdir file, create parent if not exists.
|
||||||
*
|
*
|
||||||
@@ -72,19 +72,19 @@ public class WorkDir {
|
|||||||
public static File getFile(String path)
|
public static File getFile(String path)
|
||||||
{
|
{
|
||||||
if (namedPaths.containsKey(path)) path = namedPaths.get(path);
|
if (namedPaths.containsKey(path)) path = namedPaths.get(path);
|
||||||
|
|
||||||
final File f = new File(baseDir, path);
|
final File f = new File(baseDir, path);
|
||||||
|
|
||||||
// create the parent dir
|
// create the parent dir
|
||||||
if (!f.getParent().equals(baseDir)) {
|
if (!f.getParent().equals(baseDir)) {
|
||||||
f.getParentFile().mkdirs();
|
f.getParentFile().mkdirs();
|
||||||
}
|
}
|
||||||
|
|
||||||
return f;
|
return f;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the workdir File
|
* @return the workdir File
|
||||||
*/
|
*/
|
||||||
@@ -92,5 +92,5 @@ public class WorkDir {
|
|||||||
{
|
{
|
||||||
return baseDir;
|
return baseDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,25 +20,25 @@ import mightypork.utils.logging.Log;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class ZipBuilder {
|
public class ZipBuilder {
|
||||||
|
|
||||||
private final ZipOutputStream out;
|
private final ZipOutputStream out;
|
||||||
private final HashSet<String> included = new HashSet<>();
|
private final HashSet<String> included = new HashSet<>();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param target target zip file
|
* @param target target zip file
|
||||||
* @throws IOException if the file is directory or cannot be created
|
* @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.");
|
if (!target.getParentFile().mkdirs()) throw new IOException("Could not create output directory.");
|
||||||
|
|
||||||
final FileOutputStream dest = new FileOutputStream(target);
|
final FileOutputStream dest = new FileOutputStream(target);
|
||||||
out = new ZipOutputStream(new BufferedOutputStream(dest));
|
out = new ZipOutputStream(new BufferedOutputStream(dest));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add stream to a path
|
* Add stream to a path
|
||||||
*
|
*
|
||||||
@@ -54,13 +54,13 @@ public class ZipBuilder {
|
|||||||
return; // ignore
|
return; // ignore
|
||||||
}
|
}
|
||||||
included.add(path);
|
included.add(path);
|
||||||
|
|
||||||
out.putNextEntry(new ZipEntry(path));
|
out.putNextEntry(new ZipEntry(path));
|
||||||
|
|
||||||
FileUtil.copyStream(in, out);
|
FileUtil.copyStream(in, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add string as a file
|
* Add string as a file
|
||||||
*
|
*
|
||||||
@@ -73,15 +73,15 @@ public class ZipBuilder {
|
|||||||
path = preparePath(path);
|
path = preparePath(path);
|
||||||
if (included.contains(path)) return; // ignore
|
if (included.contains(path)) return; // ignore
|
||||||
included.add(path);
|
included.add(path);
|
||||||
|
|
||||||
out.putNextEntry(new ZipEntry(path));
|
out.putNextEntry(new ZipEntry(path));
|
||||||
|
|
||||||
try(InputStream in = FileUtil.stringToStream(text)) {
|
try(InputStream in = FileUtil.stringToStream(text)) {
|
||||||
FileUtil.copyStream(in, out);
|
FileUtil.copyStream(in, out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add resource obtained via FileUtils.getResource()
|
* Add resource obtained via FileUtils.getResource()
|
||||||
*
|
*
|
||||||
@@ -94,15 +94,15 @@ public class ZipBuilder {
|
|||||||
path = preparePath(path);
|
path = preparePath(path);
|
||||||
if (included.contains(path)) return; // ignore
|
if (included.contains(path)) return; // ignore
|
||||||
included.add(path);
|
included.add(path);
|
||||||
|
|
||||||
out.putNextEntry(new ZipEntry(path));
|
out.putNextEntry(new ZipEntry(path));
|
||||||
|
|
||||||
try(InputStream in = FileUtil.getResource(resPath)) {
|
try(InputStream in = FileUtil.getResource(resPath)) {
|
||||||
FileUtil.copyStream(in, out);
|
FileUtil.copyStream(in, out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Normalize path
|
* Normalize path
|
||||||
*
|
*
|
||||||
@@ -112,13 +112,13 @@ public class ZipBuilder {
|
|||||||
private static String preparePath(String path)
|
private static String preparePath(String path)
|
||||||
{
|
{
|
||||||
path = path.replace("\\", "/");
|
path = path.replace("\\", "/");
|
||||||
|
|
||||||
if (path.charAt(0) == '/') path = path.substring(1);
|
if (path.charAt(0) == '/') path = path.substring(1);
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close the zip stream
|
* Close the zip stream
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -24,10 +24,10 @@ import mightypork.utils.string.validation.StringFilter;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class ZipUtils {
|
public class ZipUtils {
|
||||||
|
|
||||||
private static final int BUFFER_SIZE = 2048;
|
private static final int BUFFER_SIZE = 2048;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract zip file to target directory
|
* Extract zip file to target directory
|
||||||
*
|
*
|
||||||
@@ -43,8 +43,8 @@ public class ZipUtils {
|
|||||||
return extractZip(zip, outputDir, filter);
|
return extractZip(zip, outputDir, filter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract zip file to target directory
|
* Extract zip file to target directory
|
||||||
*
|
*
|
||||||
@@ -57,35 +57,35 @@ public class ZipUtils {
|
|||||||
public static List<String> extractZip(ZipFile zip, File outputDir, StringFilter filter) throws IOException
|
public static List<String> extractZip(ZipFile zip, File outputDir, StringFilter filter) throws IOException
|
||||||
{
|
{
|
||||||
final ArrayList<String> files = new ArrayList<>();
|
final ArrayList<String> files = new ArrayList<>();
|
||||||
|
|
||||||
if (!outputDir.mkdirs()) throw new IOException("Could not create output directory.");
|
if (!outputDir.mkdirs()) throw new IOException("Could not create output directory.");
|
||||||
|
|
||||||
final Enumeration<? extends ZipEntry> zipFileEntries = zip.entries();
|
final Enumeration<? extends ZipEntry> zipFileEntries = zip.entries();
|
||||||
|
|
||||||
// process each entry
|
// process each entry
|
||||||
while (zipFileEntries.hasMoreElements()) {
|
while (zipFileEntries.hasMoreElements()) {
|
||||||
final ZipEntry entry = zipFileEntries.nextElement();
|
final ZipEntry entry = zipFileEntries.nextElement();
|
||||||
|
|
||||||
// parse filename and path
|
// parse filename and path
|
||||||
final String entryPath = entry.getName();
|
final String entryPath = entry.getName();
|
||||||
final File destFile = new File(outputDir, entryPath);
|
final File destFile = new File(outputDir, entryPath);
|
||||||
final File destinationParent = destFile.getParentFile();
|
final File destinationParent = destFile.getParentFile();
|
||||||
|
|
||||||
if (entry.isDirectory() || (filter != null && !filter.isValid(entryPath))) continue;
|
if (entry.isDirectory() || (filter != null && !filter.isValid(entryPath))) continue;
|
||||||
|
|
||||||
// make sure directories exist
|
// make sure directories exist
|
||||||
if (!destinationParent.mkdirs()) throw new IOException("Could not create directory.");
|
if (!destinationParent.mkdirs()) throw new IOException("Could not create directory.");
|
||||||
|
|
||||||
if (!entry.isDirectory()) {
|
if (!entry.isDirectory()) {
|
||||||
extractZipEntry(zip, entry, destFile);
|
extractZipEntry(zip, entry, destFile);
|
||||||
files.add(entryPath);
|
files.add(entryPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read zip entries and add their paths to a list
|
* Read zip entries and add their paths to a list
|
||||||
*
|
*
|
||||||
@@ -99,8 +99,8 @@ public class ZipUtils {
|
|||||||
return listZip(zip);
|
return listZip(zip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read zip entries and add their paths to a list
|
* Read zip entries and add their paths to a list
|
||||||
*
|
*
|
||||||
@@ -111,22 +111,22 @@ public class ZipUtils {
|
|||||||
public static List<String> listZip(ZipFile zip) throws IOException
|
public static List<String> listZip(ZipFile zip) throws IOException
|
||||||
{
|
{
|
||||||
final ArrayList<String> files = new ArrayList<>();
|
final ArrayList<String> files = new ArrayList<>();
|
||||||
|
|
||||||
final Enumeration<? extends ZipEntry> zipFileEntries = zip.entries();
|
final Enumeration<? extends ZipEntry> zipFileEntries = zip.entries();
|
||||||
|
|
||||||
// process each entry
|
// process each entry
|
||||||
while (zipFileEntries.hasMoreElements()) {
|
while (zipFileEntries.hasMoreElements()) {
|
||||||
final ZipEntry entry = zipFileEntries.nextElement();
|
final ZipEntry entry = zipFileEntries.nextElement();
|
||||||
|
|
||||||
if (!entry.isDirectory()) {
|
if (!entry.isDirectory()) {
|
||||||
files.add(entry.getName());
|
files.add(entry.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract one zip entry to target file
|
* Extract one zip entry to target file
|
||||||
*
|
*
|
||||||
@@ -138,17 +138,17 @@ public class ZipUtils {
|
|||||||
public static void extractZipEntry(ZipFile zip, ZipEntry entry, File destFile) throws IOException
|
public static void extractZipEntry(ZipFile zip, ZipEntry entry, File destFile) throws IOException
|
||||||
{
|
{
|
||||||
if (!destFile.getParentFile().mkdirs()) throw new IOException("Could not create output directory.");
|
if (!destFile.getParentFile().mkdirs()) throw new IOException("Could not create output directory.");
|
||||||
|
|
||||||
try(InputStream in = zip.getInputStream(entry);
|
try(InputStream in = zip.getInputStream(entry);
|
||||||
BufferedInputStream is = new BufferedInputStream(in);
|
BufferedInputStream is = new BufferedInputStream(in);
|
||||||
FileOutputStream fos = new FileOutputStream(destFile);
|
FileOutputStream fos = new FileOutputStream(destFile);
|
||||||
BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER_SIZE)) {
|
BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER_SIZE)) {
|
||||||
|
|
||||||
FileUtil.copyStream(is, dest);
|
FileUtil.copyStream(is, dest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load zip entry to String
|
* Load zip entry to String
|
||||||
*
|
*
|
||||||
@@ -172,8 +172,8 @@ public class ZipUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static boolean entryExists(File selectedFile, String string)
|
public static boolean entryExists(File selectedFile, String string)
|
||||||
{
|
{
|
||||||
try(ZipFile zf = new ZipFile(selectedFile)) {
|
try(ZipFile zf = new ZipFile(selectedFile)) {
|
||||||
@@ -182,6 +182,6 @@ public class ZipUtils {
|
|||||||
Log.w("Error reading zip.", e);
|
Log.w("Error reading zip.", e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ package mightypork.utils.interfaces;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public interface Destroyable {
|
public interface Destroyable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy this object
|
* Destroy this object
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -9,15 +9,15 @@ package mightypork.utils.interfaces;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public interface Enableable {
|
public interface Enableable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Change enabled state
|
* Change enabled state
|
||||||
*
|
*
|
||||||
* @param yes enabled
|
* @param yes enabled
|
||||||
*/
|
*/
|
||||||
public void setEnabled(boolean yes);
|
public void setEnabled(boolean yes);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if enabled
|
* @return true if enabled
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ package mightypork.utils.interfaces;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public interface Hideable {
|
public interface Hideable {
|
||||||
|
|
||||||
void setVisible(boolean yes);
|
void setVisible(boolean yes);
|
||||||
|
|
||||||
|
|
||||||
boolean isVisible();
|
boolean isVisible();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,22 +7,22 @@ package mightypork.utils.interfaces;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public interface Pauseable {
|
public interface Pauseable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pause operation
|
* Pause operation
|
||||||
*/
|
*/
|
||||||
public void pause();
|
public void pause();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resume operation
|
* Resume operation
|
||||||
*/
|
*/
|
||||||
public void resume();
|
public void resume();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return paused state
|
* @return paused state
|
||||||
*/
|
*/
|
||||||
public boolean isPaused();
|
public boolean isPaused();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ package mightypork.utils.interfaces;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public interface Pollable {
|
public interface Pollable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update internal state
|
* Update internal state
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ package mightypork.utils.interfaces;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public interface Updateable {
|
public interface Updateable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update item state based on elapsed time
|
* Update item state based on elapsed time
|
||||||
*
|
*
|
||||||
|
|||||||
+109
-109
@@ -13,7 +13,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import mightypork.utils.Reflect;
|
import mightypork.utils.Reflect;
|
||||||
import mightypork.utils.Support;
|
import mightypork.utils.Str;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -22,13 +22,13 @@ import mightypork.utils.Support;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class Ion {
|
public class Ion {
|
||||||
|
|
||||||
private static final int RESERVED_LOW = 0;
|
private static final int RESERVED_LOW = 0;
|
||||||
private static final int RESERVED_HIGH = 49;
|
private static final int RESERVED_HIGH = 49;
|
||||||
|
|
||||||
private static final int RANGE_LOW = 0;
|
private static final int RANGE_LOW = 0;
|
||||||
private static final int RANGE_HIGH = 255;
|
private static final int RANGE_HIGH = 255;
|
||||||
|
|
||||||
// marks for object saving
|
// marks for object saving
|
||||||
/** Null mark */
|
/** Null mark */
|
||||||
static final int NULL = 0;
|
static final int NULL = 0;
|
||||||
@@ -84,28 +84,28 @@ public class Ion {
|
|||||||
public static final int MAP = 25;
|
public static final int MAP = 25;
|
||||||
/** Array of arbitrary objects */
|
/** Array of arbitrary objects */
|
||||||
public static final int OBJECT_ARRAY = 26;
|
public static final int OBJECT_ARRAY = 26;
|
||||||
|
|
||||||
/** Ionizables<Mark, Class> */
|
/** Ionizables<Mark, Class> */
|
||||||
private static Map<Integer, Class<?>> markToClass = new HashMap<>();
|
private static Map<Integer, Class<?>> markToClass = new HashMap<>();
|
||||||
private static Map<Class<?>, Integer> classToMark = new HashMap<>();
|
private static Map<Class<?>, Integer> classToMark = new HashMap<>();
|
||||||
|
|
||||||
private static Map<Class<?>, IonizerBinary<?>> ionizersBinary = new HashMap<>();
|
private static Map<Class<?>, IonizerBinary<?>> ionizersBinary = new HashMap<>();
|
||||||
private static Map<Class<?>, IonizerBundled<?>> ionizersBundled = new HashMap<>();
|
private static Map<Class<?>, IonizerBundled<?>> ionizersBundled = new HashMap<>();
|
||||||
|
|
||||||
private static boolean reservedMarkChecking;
|
private static boolean reservedMarkChecking;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
reservedMarkChecking = false;
|
reservedMarkChecking = false;
|
||||||
|
|
||||||
// register built-ins
|
// register built-ins
|
||||||
register(ION_BUNDLE, IonDataBundle.class);
|
register(ION_BUNDLE, IonDataBundle.class);
|
||||||
register(SEQUENCE_WRAPPER, IonSequenceWrapper.class);
|
register(SEQUENCE_WRAPPER, IonSequenceWrapper.class);
|
||||||
register(MAP_WRAPPER, IonMapWrapper.class);
|
register(MAP_WRAPPER, IonMapWrapper.class);
|
||||||
|
|
||||||
reservedMarkChecking = true;
|
reservedMarkChecking = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a type for writing/loading.
|
* Register a type for writing/loading.
|
||||||
*
|
*
|
||||||
@@ -116,16 +116,16 @@ public class Ion {
|
|||||||
{
|
{
|
||||||
if (!IonBinary.class.isAssignableFrom(objClass)) {
|
if (!IonBinary.class.isAssignableFrom(objClass)) {
|
||||||
if (!IonBundled.class.isAssignableFrom(objClass)) {
|
if (!IonBundled.class.isAssignableFrom(objClass)) {
|
||||||
throw new IllegalArgumentException("Cannot register directly: " + Support.str(objClass));
|
throw new IllegalArgumentException("Cannot register directly: " + Str.val(objClass));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assertHasImplicitConstructor(objClass);
|
assertHasImplicitConstructor(objClass);
|
||||||
|
|
||||||
registerUsingMark(mark, objClass);
|
registerUsingMark(mark, objClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to register a type using a static final ION_MARK int field.
|
* Try to register a type using a static final ION_MARK int field.
|
||||||
*
|
*
|
||||||
@@ -135,37 +135,37 @@ public class Ion {
|
|||||||
{
|
{
|
||||||
if (!IonBinary.class.isAssignableFrom(objClass)) {
|
if (!IonBinary.class.isAssignableFrom(objClass)) {
|
||||||
if (!IonBundled.class.isAssignableFrom(objClass)) {
|
if (!IonBundled.class.isAssignableFrom(objClass)) {
|
||||||
throw new IllegalArgumentException("Cannot register directly: " + Support.str(objClass));
|
throw new IllegalArgumentException("Cannot register directly: " + Str.val(objClass));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assertHasImplicitConstructor(objClass);
|
assertHasImplicitConstructor(objClass);
|
||||||
registerUsingConstant(objClass);
|
registerUsingConstant(objClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static void registerUsingMark(int mark, Class<?> objClass)
|
private static void registerUsingMark(int mark, Class<?> objClass)
|
||||||
{
|
{
|
||||||
assertMarkAvailable(mark, objClass);
|
assertMarkAvailable(mark, objClass);
|
||||||
|
|
||||||
markToClass.put(mark, objClass);
|
markToClass.put(mark, objClass);
|
||||||
classToMark.put(objClass, mark);
|
classToMark.put(objClass, mark);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void registerUsingConstant(Class<?> objClass)
|
public static void registerUsingConstant(Class<?> objClass)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
final int mark = ((Number) Reflect.getConstantFieldValue(objClass, "ION_MARK")).intValue();
|
final int mark = ((Number) Reflect.getConstantFieldValue(objClass, "ION_MARK")).intValue();
|
||||||
|
|
||||||
registerUsingMark(mark, objClass);
|
registerUsingMark(mark, objClass);
|
||||||
|
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
throw new RuntimeException("Could not register " + Support.str(objClass) + " using an ION_MARK field.", e);
|
throw new RuntimeException("Could not register " + Str.val(objClass) + " using an ION_MARK field.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register new binary ionizer.
|
* Register new binary ionizer.
|
||||||
*
|
*
|
||||||
@@ -175,13 +175,13 @@ public class Ion {
|
|||||||
public static void registerIndirect(int mark, IonizerBinary<?> ionizer)
|
public static void registerIndirect(int mark, IonizerBinary<?> ionizer)
|
||||||
{
|
{
|
||||||
final Class<?> objClass = Reflect.getGenericParameters(ionizer.getClass())[0];
|
final Class<?> objClass = Reflect.getGenericParameters(ionizer.getClass())[0];
|
||||||
|
|
||||||
registerUsingMark(mark, objClass);
|
registerUsingMark(mark, objClass);
|
||||||
|
|
||||||
ionizersBinary.put(objClass, ionizer);
|
ionizersBinary.put(objClass, ionizer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register new bundled ionizer.
|
* Register new bundled ionizer.
|
||||||
*
|
*
|
||||||
@@ -191,13 +191,13 @@ public class Ion {
|
|||||||
public static void registerIndirect(int mark, IonizerBundled<?> ionizer)
|
public static void registerIndirect(int mark, IonizerBundled<?> ionizer)
|
||||||
{
|
{
|
||||||
final Class<?> objClass = Reflect.getGenericParameters(ionizer.getClass())[0];
|
final Class<?> objClass = Reflect.getGenericParameters(ionizer.getClass())[0];
|
||||||
|
|
||||||
registerUsingMark(mark, objClass);
|
registerUsingMark(mark, objClass);
|
||||||
|
|
||||||
ionizersBundled.put(objClass, ionizer);
|
ionizersBundled.put(objClass, ionizer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static void assertHasImplicitConstructor(Class<?> objClass)
|
private static void assertHasImplicitConstructor(Class<?> objClass)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
@@ -206,28 +206,28 @@ public class Ion {
|
|||||||
throw new RuntimeException("Class " + objClass + " doesn't have an implicit constructor.");
|
throw new RuntimeException("Class " + objClass + " doesn't have an implicit constructor.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static void assertMarkAvailable(int mark, Class<?> objClass)
|
private static void assertMarkAvailable(int mark, Class<?> objClass)
|
||||||
{
|
{
|
||||||
// negative marks are allowed.
|
// negative marks are allowed.
|
||||||
if (mark > RANGE_HIGH) throw new IllegalArgumentException("Mark must be < 256.");
|
if (mark > RANGE_HIGH) throw new IllegalArgumentException("Mark must be < 256.");
|
||||||
if (mark < RANGE_LOW) throw new IllegalArgumentException("Mark must be positive.");
|
if (mark < RANGE_LOW) throw new IllegalArgumentException("Mark must be positive.");
|
||||||
|
|
||||||
if (reservedMarkChecking && isMarkReserved(mark)) {
|
if (reservedMarkChecking && isMarkReserved(mark)) {
|
||||||
throw new IllegalArgumentException("Marks " + RESERVED_LOW + ".." + RESERVED_HIGH + " are reserved.");
|
throw new IllegalArgumentException("Marks " + RESERVED_LOW + ".." + RESERVED_HIGH + " are reserved.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (markToClass.containsKey(mark)) {
|
if (markToClass.containsKey(mark)) {
|
||||||
throw new IllegalArgumentException("Mark " + mark + " is already in use.");
|
throw new IllegalArgumentException("Mark " + mark + " is already in use.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (classToMark.containsKey(objClass)) {
|
if (classToMark.containsKey(objClass)) {
|
||||||
throw new IllegalArgumentException(Support.str(objClass) + " is already registered.");
|
throw new IllegalArgumentException(Str.val(objClass) + " is already registered.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load binary from file and cast.
|
* Load binary from file and cast.
|
||||||
*/
|
*/
|
||||||
@@ -235,8 +235,8 @@ public class Ion {
|
|||||||
{
|
{
|
||||||
return fromFile(new File(path));
|
return fromFile(new File(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load binary from file and cast.
|
* Load binary from file and cast.
|
||||||
*/
|
*/
|
||||||
@@ -246,8 +246,8 @@ public class Ion {
|
|||||||
return fromStream(in);
|
return fromStream(in);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write binary to file with mark.
|
* Write binary to file with mark.
|
||||||
*/
|
*/
|
||||||
@@ -255,24 +255,24 @@ public class Ion {
|
|||||||
{
|
{
|
||||||
toFile(new File(path), obj);
|
toFile(new File(path), obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write binary to file with mark.
|
* Write binary to file with mark.
|
||||||
*/
|
*/
|
||||||
public static void toFile(File file, Object obj) throws IOException
|
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);
|
toStream(out, obj);
|
||||||
|
|
||||||
out.flush();
|
out.flush();
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
throw new IOException("Error writing to ION file.", e);
|
throw new IOException("Error writing to ION file.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load object from stream based on mark, try to cast.
|
* Load object from stream based on mark, try to cast.
|
||||||
*/
|
*/
|
||||||
@@ -282,8 +282,8 @@ public class Ion {
|
|||||||
return (T) inp.readObject();
|
return (T) inp.readObject();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write object to output with a mark.
|
* Write object to output with a mark.
|
||||||
*/
|
*/
|
||||||
@@ -293,8 +293,8 @@ public class Ion {
|
|||||||
iout.writeObject(obj);
|
iout.writeObject(obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get ion input
|
* Get ion input
|
||||||
*
|
*
|
||||||
@@ -306,8 +306,8 @@ public class Ion {
|
|||||||
{
|
{
|
||||||
return getInput(new File(path));
|
return getInput(new File(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get ion input
|
* Get ion input
|
||||||
*
|
*
|
||||||
@@ -320,8 +320,8 @@ public class Ion {
|
|||||||
{
|
{
|
||||||
return new IonInput(new FileInputStream(file));
|
return new IonInput(new FileInputStream(file));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get ion output
|
* Get ion output
|
||||||
*
|
*
|
||||||
@@ -333,8 +333,8 @@ public class Ion {
|
|||||||
{
|
{
|
||||||
return getOutput(new File(path));
|
return getOutput(new File(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get ion output
|
* Get ion output
|
||||||
*
|
*
|
||||||
@@ -347,8 +347,8 @@ public class Ion {
|
|||||||
{
|
{
|
||||||
return new IonOutput(new FileOutputStream(file));
|
return new IonOutput(new FileOutputStream(file));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create new bundle and write the object to it.
|
* Create new bundle and write the object to it.
|
||||||
*/
|
*/
|
||||||
@@ -358,8 +358,8 @@ public class Ion {
|
|||||||
content.save(ib);
|
content.save(ib);
|
||||||
return ib;
|
return ib;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to unwrap an object from bundle. The object class must have implicit
|
* Try to unwrap an object from bundle. The object class must have implicit
|
||||||
* accessible constructor.
|
* accessible constructor.
|
||||||
@@ -376,59 +376,59 @@ public class Ion {
|
|||||||
inst.load(bundle);
|
inst.load(bundle);
|
||||||
return inst;
|
return inst;
|
||||||
} catch (InstantiationException | IllegalAccessException e) {
|
} catch (InstantiationException | IllegalAccessException e) {
|
||||||
throw new IOException("Could not instantiate " + Support.str(objClass) + ".");
|
throw new IOException("Could not instantiate " + Str.val(objClass) + ".");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Class<?> getClassForMark(int mark)
|
static Class<?> getClassForMark(int mark)
|
||||||
{
|
{
|
||||||
return markToClass.get(mark);
|
return markToClass.get(mark);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static IonizerBinary<?> getIonizerBinaryForClass(Class<?> clz)
|
static IonizerBinary<?> getIonizerBinaryForClass(Class<?> clz)
|
||||||
{
|
{
|
||||||
return ionizersBinary.get(clz);
|
return ionizersBinary.get(clz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static IonizerBundled<?> getIonizerBundledForClass(Class<?> clz)
|
static IonizerBundled<?> getIonizerBundledForClass(Class<?> clz)
|
||||||
{
|
{
|
||||||
return ionizersBundled.get(clz);
|
return ionizersBundled.get(clz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static int getMark(Object object)
|
public static int getMark(Object object)
|
||||||
{
|
{
|
||||||
assertRegistered(object);
|
assertRegistered(object);
|
||||||
|
|
||||||
return classToMark.get(object.getClass());
|
return classToMark.get(object.getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if the mark is for a registered {@link IonBinary} object
|
* @return true if the mark is for a registered {@link IonBinary} object
|
||||||
*/
|
*/
|
||||||
static boolean isMarkForBinary(int mark)
|
static boolean isMarkForBinary(int mark)
|
||||||
{
|
{
|
||||||
if (!markToClass.containsKey(mark)) return false;
|
if (!markToClass.containsKey(mark)) return false;
|
||||||
|
|
||||||
return IonBinary.class.isAssignableFrom(markToClass.get(mark));
|
return IonBinary.class.isAssignableFrom(markToClass.get(mark));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if the mark is for a registered {@link IonBinary} object
|
* @return true if the mark is for a registered {@link IonBinary} object
|
||||||
*/
|
*/
|
||||||
static boolean isMarkForBundled(int mark)
|
static boolean isMarkForBundled(int mark)
|
||||||
{
|
{
|
||||||
if (!markToClass.containsKey(mark)) return false;
|
if (!markToClass.containsKey(mark)) return false;
|
||||||
|
|
||||||
return IonBundled.class.isAssignableFrom(markToClass.get(mark));
|
return IonBundled.class.isAssignableFrom(markToClass.get(mark));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if the mark is for a registered indirectly saved binary
|
* @return true if the mark is for a registered indirectly saved binary
|
||||||
* object
|
* object
|
||||||
@@ -436,11 +436,11 @@ public class Ion {
|
|||||||
static boolean isMarkForIndirectBinary(int mark)
|
static boolean isMarkForIndirectBinary(int mark)
|
||||||
{
|
{
|
||||||
if (!markToClass.containsKey(mark)) return false;
|
if (!markToClass.containsKey(mark)) return false;
|
||||||
|
|
||||||
return ionizersBinary.containsKey(markToClass.get(mark));
|
return ionizersBinary.containsKey(markToClass.get(mark));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if the mark is for a registered indirectly saved bundled
|
* @return true if the mark is for a registered indirectly saved bundled
|
||||||
* object
|
* object
|
||||||
@@ -448,11 +448,11 @@ public class Ion {
|
|||||||
static boolean isMarkForIndirectBundled(int mark)
|
static boolean isMarkForIndirectBundled(int mark)
|
||||||
{
|
{
|
||||||
if (!markToClass.containsKey(mark)) return false;
|
if (!markToClass.containsKey(mark)) return false;
|
||||||
|
|
||||||
return ionizersBundled.containsKey(markToClass.get(mark));
|
return ionizersBundled.containsKey(markToClass.get(mark));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if the mark is reserved for internal use
|
* @return true if the mark is reserved for internal use
|
||||||
*/
|
*/
|
||||||
@@ -460,8 +460,8 @@ public class Ion {
|
|||||||
{
|
{
|
||||||
return mark >= RESERVED_LOW && mark <= RESERVED_HIGH;
|
return mark >= RESERVED_LOW && mark <= RESERVED_HIGH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if the mark is for a registered {@link IonBinary} object
|
* @return true if the mark is for a registered {@link IonBinary} object
|
||||||
*/
|
*/
|
||||||
@@ -469,11 +469,11 @@ public class Ion {
|
|||||||
{
|
{
|
||||||
final Class<?> clazz = object.getClass();
|
final Class<?> clazz = object.getClass();
|
||||||
if (classToMark.containsKey(clazz)) return true;
|
if (classToMark.containsKey(clazz)) return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make sure object is registered in the table.
|
* Make sure object is registered in the table.
|
||||||
*
|
*
|
||||||
@@ -482,11 +482,11 @@ public class Ion {
|
|||||||
static void assertRegistered(Object obj)
|
static void assertRegistered(Object obj)
|
||||||
{
|
{
|
||||||
if (!isRegistered(obj)) {
|
if (!isRegistered(obj)) {
|
||||||
throw new RuntimeException("Type not registered: " + Support.str(obj.getClass()));
|
throw new RuntimeException("Type not registered: " + Str.val(obj.getClass()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For get all external registered types - just like if the class was
|
* For get all external registered types - just like if the class was
|
||||||
* freshly loaded. Can be used for unit tests.
|
* freshly loaded. Can be used for unit tests.
|
||||||
@@ -494,31 +494,31 @@ public class Ion {
|
|||||||
public static void reset()
|
public static void reset()
|
||||||
{
|
{
|
||||||
final List<Integer> toRemove = new ArrayList<>();
|
final List<Integer> toRemove = new ArrayList<>();
|
||||||
|
|
||||||
// remove direct
|
// remove direct
|
||||||
for (final Integer mark : markToClass.keySet()) {
|
for (final Integer mark : markToClass.keySet()) {
|
||||||
if (!isMarkReserved(mark)) {
|
if (!isMarkReserved(mark)) {
|
||||||
toRemove.add(mark);
|
toRemove.add(mark);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final int i : toRemove) {
|
for (final int i : toRemove) {
|
||||||
|
|
||||||
final Class<?> clz = markToClass.remove(i);
|
final Class<?> clz = markToClass.remove(i);
|
||||||
|
|
||||||
classToMark.remove(clz);
|
classToMark.remove(clz);
|
||||||
ionizersBinary.remove(clz);
|
ionizersBinary.remove(clz);
|
||||||
ionizersBundled.remove(clz);
|
ionizersBundled.remove(clz);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static boolean isObjectIndirectBundled(Object obj)
|
public static boolean isObjectIndirectBundled(Object obj)
|
||||||
{
|
{
|
||||||
return ionizersBundled.containsKey(obj.getClass());
|
return ionizersBundled.containsKey(obj.getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static boolean isObjectIndirectBinary(Object obj)
|
public static boolean isObjectIndirectBinary(Object obj)
|
||||||
{
|
{
|
||||||
return ionizersBinary.containsKey(obj.getClass());
|
return ionizersBinary.containsKey(obj.getClass());
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import java.io.IOException;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public interface IonBinary {
|
public interface IonBinary {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load data from the input stream.
|
* Load data from the input stream.
|
||||||
*
|
*
|
||||||
@@ -19,8 +19,8 @@ public interface IonBinary {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
void load(IonInput in) throws IOException;
|
void load(IonInput in) throws IOException;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store data to output stream (in such way that the load method will later
|
* Store data to output stream (in such way that the load method will later
|
||||||
* be able to read it).
|
* be able to read it).
|
||||||
|
|||||||
@@ -8,15 +8,15 @@ package mightypork.utils.ion;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public interface IonBundled {
|
public interface IonBundled {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load this object from the data bundle
|
* Load this object from the data bundle
|
||||||
*
|
*
|
||||||
* @param in bundle to load from
|
* @param in bundle to load from
|
||||||
*/
|
*/
|
||||||
void load(IonDataBundle in);
|
void load(IonDataBundle in);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save this object to the data bundle
|
* Save this object to the data bundle
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -16,10 +16,10 @@ import java.util.Map;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class IonDataBundle implements IonBinary {
|
public class IonDataBundle implements IonBinary {
|
||||||
|
|
||||||
private final Map<String, Object> backingMap = new HashMap<>();
|
private final Map<String, Object> backingMap = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear & fill a provided bundle with elements from a bundle value
|
* Clear & fill a provided bundle with elements from a bundle value
|
||||||
*
|
*
|
||||||
@@ -29,14 +29,14 @@ public class IonDataBundle implements IonBinary {
|
|||||||
public void loadBundle(String key, IonDataBundle filled)
|
public void loadBundle(String key, IonDataBundle filled)
|
||||||
{
|
{
|
||||||
if (!containsKey(key)) return;
|
if (!containsKey(key)) return;
|
||||||
|
|
||||||
final IonDataBundle ib = get(key, new IonDataBundle());
|
final IonDataBundle ib = get(key, new IonDataBundle());
|
||||||
|
|
||||||
filled.clear();
|
filled.clear();
|
||||||
filled.putAll(ib);
|
filled.putAll(ib);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a key is used in the bundle
|
* Check if a key is used in the bundle
|
||||||
*
|
*
|
||||||
@@ -47,8 +47,8 @@ public class IonDataBundle implements IonBinary {
|
|||||||
{
|
{
|
||||||
return backingMap.containsKey(key);
|
return backingMap.containsKey(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a value is contained in the bundle
|
* Check if a value is contained in the bundle
|
||||||
*
|
*
|
||||||
@@ -59,8 +59,8 @@ public class IonDataBundle implements IonBinary {
|
|||||||
{
|
{
|
||||||
return backingMap.containsValue(value);
|
return backingMap.containsValue(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a map value
|
* Get a map value
|
||||||
*
|
*
|
||||||
@@ -71,8 +71,8 @@ public class IonDataBundle implements IonBinary {
|
|||||||
{
|
{
|
||||||
return loadMap(key, new LinkedHashMap<K, V>());
|
return loadMap(key, new LinkedHashMap<K, V>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear & fill the provided map with elements from a map value
|
* Clear & fill the provided map with elements from a map value
|
||||||
*
|
*
|
||||||
@@ -87,8 +87,8 @@ public class IonDataBundle implements IonBinary {
|
|||||||
imw.fill(filled);
|
imw.fill(filled);
|
||||||
return filled;
|
return filled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a sequence value
|
* Get a sequence value
|
||||||
*
|
*
|
||||||
@@ -99,8 +99,8 @@ public class IonDataBundle implements IonBinary {
|
|||||||
{
|
{
|
||||||
return loadSequence(key, new ArrayList<E>());
|
return loadSequence(key, new ArrayList<E>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear & fill the provided Collection with elements from a sequence value
|
* Clear & fill the provided Collection with elements from a sequence value
|
||||||
*
|
*
|
||||||
@@ -114,11 +114,11 @@ public class IonDataBundle implements IonBinary {
|
|||||||
if (isw == null) throw new RuntimeException("No such key: " + key);
|
if (isw == null) throw new RuntimeException("No such key: " + key);
|
||||||
filled.clear();
|
filled.clear();
|
||||||
isw.fill(filled);
|
isw.fill(filled);
|
||||||
|
|
||||||
return filled;
|
return filled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load a bundled object from a bundle value.<br>
|
* Load a bundled object from a bundle value.<br>
|
||||||
* The object does not have to be registered.
|
* The object does not have to be registered.
|
||||||
@@ -131,13 +131,13 @@ public class IonDataBundle implements IonBinary {
|
|||||||
{
|
{
|
||||||
final IonDataBundle bu = get(key, null);
|
final IonDataBundle bu = get(key, null);
|
||||||
if (bu == null) throw new RuntimeException("No such key: " + key);
|
if (bu == null) throw new RuntimeException("No such key: " + key);
|
||||||
|
|
||||||
loaded.load(bu);
|
loaded.load(bu);
|
||||||
|
|
||||||
return loaded;
|
return loaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save a bundled object to a bundle value.<br>
|
* Save a bundled object to a bundle value.<br>
|
||||||
* The object does not have to be registered.
|
* The object does not have to be registered.
|
||||||
@@ -151,8 +151,8 @@ public class IonDataBundle implements IonBinary {
|
|||||||
saved.save(bu);
|
saved.save(bu);
|
||||||
put(key, bu);
|
put(key, bu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get value, or fallback (if none found of with bad type).
|
* Get value, or fallback (if none found of with bad type).
|
||||||
*
|
*
|
||||||
@@ -170,8 +170,8 @@ public class IonDataBundle implements IonBinary {
|
|||||||
return fallback;
|
return fallback;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get value, or null (if none found of with bad type).
|
* Get value, or null (if none found of with bad type).
|
||||||
*
|
*
|
||||||
@@ -182,124 +182,124 @@ public class IonDataBundle implements IonBinary {
|
|||||||
{
|
{
|
||||||
return get(key, (T) null);
|
return get(key, (T) null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void put(String key, Object value)
|
public void put(String key, Object value)
|
||||||
{
|
{
|
||||||
if (key == null || value == null) return;
|
if (key == null || value == null) return;
|
||||||
if (!Ion.isRegistered(value)) throw new IllegalArgumentException("Cannot add to bundle, not registered: " + value);
|
if (!Ion.isRegistered(value)) throw new IllegalArgumentException("Cannot add to bundle, not registered: " + value);
|
||||||
backingMap.put(key, value);
|
backingMap.put(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void put(String key, boolean value)
|
public void put(String key, boolean value)
|
||||||
{
|
{
|
||||||
backingMap.put(key, value);
|
backingMap.put(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void put(String key, byte value)
|
public void put(String key, byte value)
|
||||||
{
|
{
|
||||||
backingMap.put(key, value);
|
backingMap.put(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void put(String key, char value)
|
public void put(String key, char value)
|
||||||
{
|
{
|
||||||
backingMap.put(key, value);
|
backingMap.put(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void put(String key, short value)
|
public void put(String key, short value)
|
||||||
{
|
{
|
||||||
backingMap.put(key, value);
|
backingMap.put(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void put(String key, int value)
|
public void put(String key, int value)
|
||||||
{
|
{
|
||||||
backingMap.put(key, value);
|
backingMap.put(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void put(String key, long value)
|
public void put(String key, long value)
|
||||||
{
|
{
|
||||||
backingMap.put(key, value);
|
backingMap.put(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void put(String key, double value)
|
public void put(String key, double value)
|
||||||
{
|
{
|
||||||
backingMap.put(key, value);
|
backingMap.put(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void put(String key, float value)
|
public void put(String key, float value)
|
||||||
{
|
{
|
||||||
backingMap.put(key, value);
|
backingMap.put(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void put(String key, String value)
|
public void put(String key, String value)
|
||||||
{
|
{
|
||||||
backingMap.put(key, value);
|
backingMap.put(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void put(String key, boolean[] value)
|
public void put(String key, boolean[] value)
|
||||||
{
|
{
|
||||||
backingMap.put(key, value);
|
backingMap.put(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void put(String key, char[] value)
|
public void put(String key, char[] value)
|
||||||
{
|
{
|
||||||
backingMap.put(key, value);
|
backingMap.put(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void put(String key, short[] value)
|
public void put(String key, short[] value)
|
||||||
{
|
{
|
||||||
backingMap.put(key, value);
|
backingMap.put(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void put(String key, int[] value)
|
public void put(String key, int[] value)
|
||||||
{
|
{
|
||||||
backingMap.put(key, value);
|
backingMap.put(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void put(String key, long[] value)
|
public void put(String key, long[] value)
|
||||||
{
|
{
|
||||||
backingMap.put(key, value);
|
backingMap.put(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void put(String key, double[] value)
|
public void put(String key, double[] value)
|
||||||
{
|
{
|
||||||
backingMap.put(key, value);
|
backingMap.put(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void put(String key, float[] value)
|
public void put(String key, float[] value)
|
||||||
{
|
{
|
||||||
backingMap.put(key, value);
|
backingMap.put(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void put(String key, String[] value)
|
public void put(String key, String[] value)
|
||||||
{
|
{
|
||||||
backingMap.put(key, value);
|
backingMap.put(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void put(String key, Object[] value)
|
public void put(String key, Object[] value)
|
||||||
{
|
{
|
||||||
backingMap.put(key, value);
|
backingMap.put(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Put a sequence to the bundle.
|
* Put a sequence to the bundle.
|
||||||
*
|
*
|
||||||
@@ -311,8 +311,8 @@ public class IonDataBundle implements IonBinary {
|
|||||||
{
|
{
|
||||||
backingMap.put(key, new IonSequenceWrapper(c));
|
backingMap.put(key, new IonSequenceWrapper(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Put a map to the bundle.
|
* Put a map to the bundle.
|
||||||
*
|
*
|
||||||
@@ -324,22 +324,22 @@ public class IonDataBundle implements IonBinary {
|
|||||||
{
|
{
|
||||||
backingMap.put(key, new IonMapWrapper(m));
|
backingMap.put(key, new IonMapWrapper(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load(IonInput in) throws IOException
|
public void load(IonInput in) throws IOException
|
||||||
{
|
{
|
||||||
in.readMap(backingMap);
|
in.readMap(backingMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void save(IonOutput out) throws IOException
|
public void save(IonOutput out) throws IOException
|
||||||
{
|
{
|
||||||
out.writeMap(backingMap);
|
out.writeMap(backingMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get number of elements in the bundle
|
* Get number of elements in the bundle
|
||||||
*
|
*
|
||||||
@@ -349,8 +349,8 @@ public class IonDataBundle implements IonBinary {
|
|||||||
{
|
{
|
||||||
return backingMap.size();
|
return backingMap.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether the bundle is empty
|
* Check whether the bundle is empty
|
||||||
*
|
*
|
||||||
@@ -360,8 +360,8 @@ public class IonDataBundle implements IonBinary {
|
|||||||
{
|
{
|
||||||
return backingMap.isEmpty();
|
return backingMap.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove all elements
|
* Remove all elements
|
||||||
*/
|
*/
|
||||||
@@ -369,8 +369,8 @@ public class IonDataBundle implements IonBinary {
|
|||||||
{
|
{
|
||||||
backingMap.clear();
|
backingMap.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a value by key
|
* Remove a value by key
|
||||||
*
|
*
|
||||||
@@ -381,8 +381,8 @@ public class IonDataBundle implements IonBinary {
|
|||||||
{
|
{
|
||||||
return backingMap.remove(key);
|
return backingMap.remove(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Put all from another bundle
|
* Put all from another bundle
|
||||||
*
|
*
|
||||||
@@ -392,15 +392,15 @@ public class IonDataBundle implements IonBinary {
|
|||||||
{
|
{
|
||||||
backingMap.putAll(anotherBundle.backingMap);
|
backingMap.putAll(anotherBundle.backingMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return backingMap.toString();
|
return backingMap.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode()
|
public int hashCode()
|
||||||
{
|
{
|
||||||
@@ -409,8 +409,8 @@ public class IonDataBundle implements IonBinary {
|
|||||||
result = prime * result + ((backingMap == null) ? 0 : backingMap.hashCode());
|
result = prime * result + ((backingMap == null) ? 0 : backingMap.hashCode());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj)
|
public boolean equals(Object obj)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,25 +23,25 @@ import mightypork.utils.exceptions.CorruptDataException;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class IonInput implements Closeable {
|
public class IonInput implements Closeable {
|
||||||
|
|
||||||
private final DataInput in;
|
private final DataInput in;
|
||||||
private final InputStream stream;
|
private final InputStream stream;
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("resource")
|
@SuppressWarnings("resource")
|
||||||
public IonInput(File inFile) throws FileNotFoundException
|
public IonInput(File inFile) throws FileNotFoundException
|
||||||
{
|
{
|
||||||
this(new FileInputStream(inFile));
|
this(new FileInputStream(inFile));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public IonInput(InputStream in)
|
public IonInput(InputStream in)
|
||||||
{
|
{
|
||||||
this.stream = in;
|
this.stream = in;
|
||||||
this.in = new DataInputStream(in);
|
this.in = new DataInputStream(in);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read int 0-255. Suitable when the int was written using
|
* Read int 0-255. Suitable when the int was written using
|
||||||
* <code>writeIntByte()</code> method.
|
* <code>writeIntByte()</code> method.
|
||||||
@@ -53,8 +53,8 @@ public class IonInput implements Closeable {
|
|||||||
{
|
{
|
||||||
return in.readUnsignedByte();
|
return in.readUnsignedByte();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read an int 0-65535. Suitable when the int was written using
|
* Read an int 0-65535. Suitable when the int was written using
|
||||||
* <code>writeIntShort()</code> method.
|
* <code>writeIntShort()</code> method.
|
||||||
@@ -66,62 +66,62 @@ public class IonInput implements Closeable {
|
|||||||
{
|
{
|
||||||
return in.readUnsignedShort();
|
return in.readUnsignedShort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean readBoolean() throws IOException
|
public boolean readBoolean() throws IOException
|
||||||
{
|
{
|
||||||
return in.readBoolean();
|
return in.readBoolean();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public byte readByte() throws IOException
|
public byte readByte() throws IOException
|
||||||
{
|
{
|
||||||
return in.readByte();
|
return in.readByte();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public short readShort() throws IOException
|
public short readShort() throws IOException
|
||||||
{
|
{
|
||||||
return in.readShort();
|
return in.readShort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public char readChar() throws IOException
|
public char readChar() throws IOException
|
||||||
{
|
{
|
||||||
return in.readChar();
|
return in.readChar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public int readInt() throws IOException
|
public int readInt() throws IOException
|
||||||
{
|
{
|
||||||
return in.readInt();
|
return in.readInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public long readLong() throws IOException
|
public long readLong() throws IOException
|
||||||
{
|
{
|
||||||
return in.readLong();
|
return in.readLong();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public float readFloat() throws IOException
|
public float readFloat() throws IOException
|
||||||
{
|
{
|
||||||
return in.readFloat();
|
return in.readFloat();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public double readDouble() throws IOException
|
public double readDouble() throws IOException
|
||||||
{
|
{
|
||||||
return in.readDouble();
|
return in.readDouble();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String readString() throws IOException
|
public String readString() throws IOException
|
||||||
{
|
{
|
||||||
return in.readUTF();
|
return in.readUTF();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean[] readBooleans() throws IOException
|
public boolean[] readBooleans() throws IOException
|
||||||
{
|
{
|
||||||
final int length = readLength();
|
final int length = readLength();
|
||||||
@@ -131,8 +131,8 @@ public class IonInput implements Closeable {
|
|||||||
}
|
}
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public byte[] readBytes() throws IOException
|
public byte[] readBytes() throws IOException
|
||||||
{
|
{
|
||||||
final int length = readLength();
|
final int length = readLength();
|
||||||
@@ -142,8 +142,8 @@ public class IonInput implements Closeable {
|
|||||||
}
|
}
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public char[] readChars() throws IOException
|
public char[] readChars() throws IOException
|
||||||
{
|
{
|
||||||
final int length = readLength();
|
final int length = readLength();
|
||||||
@@ -153,8 +153,8 @@ public class IonInput implements Closeable {
|
|||||||
}
|
}
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public short[] readShorts() throws IOException
|
public short[] readShorts() throws IOException
|
||||||
{
|
{
|
||||||
final int length = readLength();
|
final int length = readLength();
|
||||||
@@ -164,8 +164,8 @@ public class IonInput implements Closeable {
|
|||||||
}
|
}
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public int[] readInts() throws IOException
|
public int[] readInts() throws IOException
|
||||||
{
|
{
|
||||||
final int length = readLength();
|
final int length = readLength();
|
||||||
@@ -175,8 +175,8 @@ public class IonInput implements Closeable {
|
|||||||
}
|
}
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public long[] readLongs() throws IOException
|
public long[] readLongs() throws IOException
|
||||||
{
|
{
|
||||||
final int length = readLength();
|
final int length = readLength();
|
||||||
@@ -186,8 +186,8 @@ public class IonInput implements Closeable {
|
|||||||
}
|
}
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public float[] readFloats() throws IOException
|
public float[] readFloats() throws IOException
|
||||||
{
|
{
|
||||||
final int length = readLength();
|
final int length = readLength();
|
||||||
@@ -197,8 +197,8 @@ public class IonInput implements Closeable {
|
|||||||
}
|
}
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public double[] readDoubles() throws IOException
|
public double[] readDoubles() throws IOException
|
||||||
{
|
{
|
||||||
final int length = readLength();
|
final int length = readLength();
|
||||||
@@ -208,8 +208,8 @@ public class IonInput implements Closeable {
|
|||||||
}
|
}
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String[] readStrings() throws IOException
|
public String[] readStrings() throws IOException
|
||||||
{
|
{
|
||||||
final int length = readLength();
|
final int length = readLength();
|
||||||
@@ -219,8 +219,8 @@ public class IonInput implements Closeable {
|
|||||||
}
|
}
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Object[] readObjects() throws IOException
|
public Object[] readObjects() throws IOException
|
||||||
{
|
{
|
||||||
final int length = readLength();
|
final int length = readLength();
|
||||||
@@ -230,8 +230,8 @@ public class IonInput implements Closeable {
|
|||||||
}
|
}
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read bundle without a mark
|
* Read bundle without a mark
|
||||||
*/
|
*/
|
||||||
@@ -241,8 +241,8 @@ public class IonInput implements Closeable {
|
|||||||
ib.load(this);
|
ib.load(this);
|
||||||
return ib;
|
return ib;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read bundle without a mark, load into a provided one
|
* Read bundle without a mark, load into a provided one
|
||||||
*/
|
*/
|
||||||
@@ -251,20 +251,20 @@ public class IonInput implements Closeable {
|
|||||||
filled.clear();
|
filled.clear();
|
||||||
filled.load(this);
|
filled.load(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private int readMark() throws IOException
|
private int readMark() throws IOException
|
||||||
{
|
{
|
||||||
return readIntByte();
|
return readIntByte();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private int readLength() throws IOException
|
private int readLength() throws IOException
|
||||||
{
|
{
|
||||||
return readInt();
|
return readInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* Read object based on mark; if null mark is found, returns default value.
|
* Read object based on mark; if null mark is found, returns default value.
|
||||||
@@ -288,8 +288,8 @@ public class IonInput implements Closeable {
|
|||||||
throw new CorruptDataException("Could not load object.", e);
|
throw new CorruptDataException("Could not load object.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read single object, preceded by a mark.
|
* Read single object, preceded by a mark.
|
||||||
*
|
*
|
||||||
@@ -299,115 +299,115 @@ public class IonInput implements Closeable {
|
|||||||
public Object readObject() throws IOException
|
public Object readObject() throws IOException
|
||||||
{
|
{
|
||||||
final int mark = readMark();
|
final int mark = readMark();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
if (Ion.isMarkForBinary(mark)) {
|
if (Ion.isMarkForBinary(mark)) {
|
||||||
IonBinary loaded;
|
IonBinary loaded;
|
||||||
|
|
||||||
loaded = (IonBinary) Ion.getClassForMark(mark).newInstance();
|
loaded = (IonBinary) Ion.getClassForMark(mark).newInstance();
|
||||||
|
|
||||||
loaded.load(this);
|
loaded.load(this);
|
||||||
return loaded;
|
return loaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Ion.isMarkForBundled(mark)) {
|
if (Ion.isMarkForBundled(mark)) {
|
||||||
IonBundled loaded;
|
IonBundled loaded;
|
||||||
|
|
||||||
loaded = (IonBundled) Ion.getClassForMark(mark).newInstance();
|
loaded = (IonBundled) Ion.getClassForMark(mark).newInstance();
|
||||||
|
|
||||||
final IonDataBundle ib = readBundle();
|
final IonDataBundle ib = readBundle();
|
||||||
loaded.load(ib);
|
loaded.load(ib);
|
||||||
return loaded;
|
return loaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Ion.isMarkForIndirectBundled(mark)) {
|
if (Ion.isMarkForIndirectBundled(mark)) {
|
||||||
final IonizerBundled<?> ionizer = Ion.getIonizerBundledForClass(Ion.getClassForMark(mark));
|
final IonizerBundled<?> ionizer = Ion.getIonizerBundledForClass(Ion.getClassForMark(mark));
|
||||||
return ionizer.load(readBundle());
|
return ionizer.load(readBundle());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Ion.isMarkForIndirectBinary(mark)) {
|
if (Ion.isMarkForIndirectBinary(mark)) {
|
||||||
final IonizerBinary<?> ionizer = Ion.getIonizerBinaryForClass(Ion.getClassForMark(mark));
|
final IonizerBinary<?> ionizer = Ion.getIonizerBinaryForClass(Ion.getClassForMark(mark));
|
||||||
return ionizer.load(this);
|
return ionizer.load(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
throw new RuntimeException("Could not load object for mark: " + mark, e);
|
throw new RuntimeException("Could not load object for mark: " + mark, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (mark) {
|
switch (mark) {
|
||||||
case Ion.NULL:
|
case Ion.NULL:
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
case Ion.BOOLEAN:
|
case Ion.BOOLEAN:
|
||||||
return readBoolean();
|
return readBoolean();
|
||||||
|
|
||||||
case Ion.BYTE:
|
case Ion.BYTE:
|
||||||
return readByte();
|
return readByte();
|
||||||
|
|
||||||
case Ion.CHAR:
|
case Ion.CHAR:
|
||||||
return readChar();
|
return readChar();
|
||||||
|
|
||||||
case Ion.SHORT:
|
case Ion.SHORT:
|
||||||
return readShort();
|
return readShort();
|
||||||
|
|
||||||
case Ion.INT:
|
case Ion.INT:
|
||||||
return readInt();
|
return readInt();
|
||||||
|
|
||||||
case Ion.LONG:
|
case Ion.LONG:
|
||||||
return readLong();
|
return readLong();
|
||||||
|
|
||||||
case Ion.FLOAT:
|
case Ion.FLOAT:
|
||||||
return readFloat();
|
return readFloat();
|
||||||
|
|
||||||
case Ion.DOUBLE:
|
case Ion.DOUBLE:
|
||||||
return readDouble();
|
return readDouble();
|
||||||
|
|
||||||
case Ion.STRING:
|
case Ion.STRING:
|
||||||
return readString();
|
return readString();
|
||||||
|
|
||||||
case Ion.BOOLEAN_ARRAY:
|
case Ion.BOOLEAN_ARRAY:
|
||||||
return readBooleans();
|
return readBooleans();
|
||||||
|
|
||||||
case Ion.BYTE_ARRAY:
|
case Ion.BYTE_ARRAY:
|
||||||
return readBytes();
|
return readBytes();
|
||||||
|
|
||||||
case Ion.CHAR_ARRAY:
|
case Ion.CHAR_ARRAY:
|
||||||
return readChars();
|
return readChars();
|
||||||
|
|
||||||
case Ion.SHORT_ARRAY:
|
case Ion.SHORT_ARRAY:
|
||||||
return readShorts();
|
return readShorts();
|
||||||
|
|
||||||
case Ion.INT_ARRAY:
|
case Ion.INT_ARRAY:
|
||||||
return readInts();
|
return readInts();
|
||||||
|
|
||||||
case Ion.LONG_ARRAY:
|
case Ion.LONG_ARRAY:
|
||||||
return readLongs();
|
return readLongs();
|
||||||
|
|
||||||
case Ion.FLOAT_ARRAY:
|
case Ion.FLOAT_ARRAY:
|
||||||
return readFloats();
|
return readFloats();
|
||||||
|
|
||||||
case Ion.DOUBLE_ARRAY:
|
case Ion.DOUBLE_ARRAY:
|
||||||
return readDoubles();
|
return readDoubles();
|
||||||
|
|
||||||
case Ion.STRING_ARRAY:
|
case Ion.STRING_ARRAY:
|
||||||
return readStrings();
|
return readStrings();
|
||||||
|
|
||||||
case Ion.OBJECT_ARRAY:
|
case Ion.OBJECT_ARRAY:
|
||||||
return readObjects();
|
return readObjects();
|
||||||
|
|
||||||
case Ion.MAP:
|
case Ion.MAP:
|
||||||
return readMap();
|
return readMap();
|
||||||
|
|
||||||
case Ion.SEQUENCE:
|
case Ion.SEQUENCE:
|
||||||
return readSequence();
|
return readSequence();
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new CorruptDataException("Invalid mark: " + mark);
|
throw new CorruptDataException("Invalid mark: " + mark);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads mark and returns true if the mark is ENTRY, false if the mark is
|
* Reads mark and returns true if the mark is ENTRY, false if the mark is
|
||||||
* END. Throws an exception otherwise.
|
* END. Throws an exception otherwise.
|
||||||
@@ -420,11 +420,11 @@ public class IonInput implements Closeable {
|
|||||||
final int mark = readMark();
|
final int mark = readMark();
|
||||||
if (mark == Ion.ENTRY) return true;
|
if (mark == Ion.ENTRY) return true;
|
||||||
if (mark == Ion.END) return false;
|
if (mark == Ion.END) return false;
|
||||||
|
|
||||||
throw new CorruptDataException("Unexpected mark in sequence: " + mark);
|
throw new CorruptDataException("Unexpected mark in sequence: " + mark);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read a sequence of elements into an ArrayList
|
* Read a sequence of elements into an ArrayList
|
||||||
*
|
*
|
||||||
@@ -435,8 +435,8 @@ public class IonInput implements Closeable {
|
|||||||
{
|
{
|
||||||
return readSequence(new ArrayList<T>());
|
return readSequence(new ArrayList<T>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load entries into a collection. The collection is cleaned first.
|
* Load entries into a collection. The collection is cleaned first.
|
||||||
*
|
*
|
||||||
@@ -457,8 +457,8 @@ public class IonInput implements Closeable {
|
|||||||
throw new CorruptDataException("Unexpected element type in sequence.", e);
|
throw new CorruptDataException("Unexpected element type in sequence.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read element pairs into a HashMap
|
* Read element pairs into a HashMap
|
||||||
*
|
*
|
||||||
@@ -469,8 +469,8 @@ public class IonInput implements Closeable {
|
|||||||
{
|
{
|
||||||
return readMap(new HashMap<K, V>());
|
return readMap(new HashMap<K, V>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load data into a map. The map is cleaned first.
|
* Load data into a map. The map is cleaned first.
|
||||||
*
|
*
|
||||||
@@ -486,7 +486,7 @@ public class IonInput implements Closeable {
|
|||||||
while (hasNextEntry()) {
|
while (hasNextEntry()) {
|
||||||
final K key = (K) readObject();
|
final K key = (K) readObject();
|
||||||
final V value = (V) readObject();
|
final V value = (V) readObject();
|
||||||
|
|
||||||
filled.put(key, value);
|
filled.put(key, value);
|
||||||
}
|
}
|
||||||
return filled;
|
return filled;
|
||||||
@@ -494,8 +494,8 @@ public class IonInput implements Closeable {
|
|||||||
throw new CorruptDataException("Unexpected element type in map.", e);
|
throw new CorruptDataException("Unexpected element type in map.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException
|
public void close() throws IOException
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,47 +8,47 @@ import java.util.Map;
|
|||||||
|
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
class IonMapWrapper implements IonBinary {
|
class IonMapWrapper implements IonBinary {
|
||||||
|
|
||||||
private final Map map;
|
private final Map map;
|
||||||
|
|
||||||
|
|
||||||
public IonMapWrapper()
|
public IonMapWrapper()
|
||||||
{
|
{
|
||||||
map = new LinkedHashMap<>();
|
map = new LinkedHashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public IonMapWrapper(Map saved)
|
public IonMapWrapper(Map saved)
|
||||||
{
|
{
|
||||||
map = saved;
|
map = saved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load(IonInput in) throws IOException
|
public void load(IonInput in) throws IOException
|
||||||
{
|
{
|
||||||
map.clear();
|
map.clear();
|
||||||
in.readMap(map);
|
in.readMap(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void save(IonOutput out) throws IOException
|
public void save(IonOutput out) throws IOException
|
||||||
{
|
{
|
||||||
out.writeMap(map);
|
out.writeMap(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void fill(Map o)
|
public void fill(Map o)
|
||||||
{
|
{
|
||||||
o.clear();
|
o.clear();
|
||||||
o.putAll(map);
|
o.putAll(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Map getMap()
|
public Map getMap()
|
||||||
{
|
{
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,97 +20,97 @@ import java.util.Map.Entry;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class IonOutput implements Closeable {
|
public class IonOutput implements Closeable {
|
||||||
|
|
||||||
private final DataOutput out;
|
private final DataOutput out;
|
||||||
private final OutputStream stream;
|
private final OutputStream stream;
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("resource")
|
@SuppressWarnings("resource")
|
||||||
public IonOutput(File outFile) throws FileNotFoundException
|
public IonOutput(File outFile) throws FileNotFoundException
|
||||||
{
|
{
|
||||||
this(new FileOutputStream(outFile));
|
this(new FileOutputStream(outFile));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public IonOutput(OutputStream out)
|
public IonOutput(OutputStream out)
|
||||||
{
|
{
|
||||||
this.stream = out;
|
this.stream = out;
|
||||||
this.out = new DataOutputStream(out);
|
this.out = new DataOutputStream(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void writeBoolean(boolean a) throws IOException
|
public void writeBoolean(boolean a) throws IOException
|
||||||
{
|
{
|
||||||
out.writeBoolean(a);
|
out.writeBoolean(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void writeByte(int a) throws IOException
|
public void writeByte(int a) throws IOException
|
||||||
{
|
{
|
||||||
out.writeByte(a);
|
out.writeByte(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void writeShort(int a) throws IOException
|
public void writeShort(int a) throws IOException
|
||||||
{
|
{
|
||||||
out.writeShort(a);
|
out.writeShort(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void writeChar(int a) throws IOException
|
public void writeChar(int a) throws IOException
|
||||||
{
|
{
|
||||||
out.writeChar(a);
|
out.writeChar(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void writeInt(int a) throws IOException
|
public void writeInt(int a) throws IOException
|
||||||
{
|
{
|
||||||
out.writeInt(a);
|
out.writeInt(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void writeIntShort(int a) throws IOException
|
public void writeIntShort(int a) throws IOException
|
||||||
{
|
{
|
||||||
out.writeShort(a);
|
out.writeShort(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void writeIntByte(int a) throws IOException
|
public void writeIntByte(int a) throws IOException
|
||||||
{
|
{
|
||||||
out.writeByte(a);
|
out.writeByte(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void writeLong(long a) throws IOException
|
public void writeLong(long a) throws IOException
|
||||||
{
|
{
|
||||||
out.writeLong(a);
|
out.writeLong(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void writeFloat(float a) throws IOException
|
public void writeFloat(float a) throws IOException
|
||||||
{
|
{
|
||||||
out.writeFloat(a);
|
out.writeFloat(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void writeDouble(double a) throws IOException
|
public void writeDouble(double a) throws IOException
|
||||||
{
|
{
|
||||||
out.writeDouble(a);
|
out.writeDouble(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void writeBytes(String a) throws IOException
|
public void writeBytes(String a) throws IOException
|
||||||
{
|
{
|
||||||
out.writeBytes(a);
|
out.writeBytes(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void writeString(String a) throws IOException
|
public void writeString(String a) throws IOException
|
||||||
{
|
{
|
||||||
out.writeUTF(a);
|
out.writeUTF(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void writeBooleans(boolean[] arr) throws IOException
|
public void writeBooleans(boolean[] arr) throws IOException
|
||||||
{
|
{
|
||||||
writeLength(arr.length);
|
writeLength(arr.length);
|
||||||
@@ -118,8 +118,8 @@ public class IonOutput implements Closeable {
|
|||||||
out.writeBoolean(a);
|
out.writeBoolean(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void writeBytes(byte[] arr) throws IOException
|
public void writeBytes(byte[] arr) throws IOException
|
||||||
{
|
{
|
||||||
writeLength(arr.length);
|
writeLength(arr.length);
|
||||||
@@ -127,8 +127,8 @@ public class IonOutput implements Closeable {
|
|||||||
out.writeByte(a);
|
out.writeByte(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void writeChars(char[] arr) throws IOException
|
public void writeChars(char[] arr) throws IOException
|
||||||
{
|
{
|
||||||
writeLength(arr.length);
|
writeLength(arr.length);
|
||||||
@@ -136,8 +136,8 @@ public class IonOutput implements Closeable {
|
|||||||
out.writeChar(a);
|
out.writeChar(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void writeShorts(short[] arr) throws IOException
|
public void writeShorts(short[] arr) throws IOException
|
||||||
{
|
{
|
||||||
writeLength(arr.length);
|
writeLength(arr.length);
|
||||||
@@ -145,8 +145,8 @@ public class IonOutput implements Closeable {
|
|||||||
out.writeShort(a);
|
out.writeShort(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void writeInts(int[] arr) throws IOException
|
public void writeInts(int[] arr) throws IOException
|
||||||
{
|
{
|
||||||
writeLength(arr.length);
|
writeLength(arr.length);
|
||||||
@@ -154,8 +154,8 @@ public class IonOutput implements Closeable {
|
|||||||
out.writeInt(a);
|
out.writeInt(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void writeLongs(long[] arr) throws IOException
|
public void writeLongs(long[] arr) throws IOException
|
||||||
{
|
{
|
||||||
writeLength(arr.length);
|
writeLength(arr.length);
|
||||||
@@ -163,8 +163,8 @@ public class IonOutput implements Closeable {
|
|||||||
out.writeLong(a);
|
out.writeLong(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void writeFloats(float[] arr) throws IOException
|
public void writeFloats(float[] arr) throws IOException
|
||||||
{
|
{
|
||||||
writeLength(arr.length);
|
writeLength(arr.length);
|
||||||
@@ -172,8 +172,8 @@ public class IonOutput implements Closeable {
|
|||||||
out.writeFloat(a);
|
out.writeFloat(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void writeDoubles(double[] arr) throws IOException
|
public void writeDoubles(double[] arr) throws IOException
|
||||||
{
|
{
|
||||||
writeLength(arr.length);
|
writeLength(arr.length);
|
||||||
@@ -181,8 +181,8 @@ public class IonOutput implements Closeable {
|
|||||||
out.writeDouble(a);
|
out.writeDouble(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void writeStrings(String[] arr) throws IOException
|
public void writeStrings(String[] arr) throws IOException
|
||||||
{
|
{
|
||||||
writeLength(arr.length);
|
writeLength(arr.length);
|
||||||
@@ -190,8 +190,8 @@ public class IonOutput implements Closeable {
|
|||||||
out.writeUTF(a);
|
out.writeUTF(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write a bundle without a mark
|
* Write a bundle without a mark
|
||||||
*/
|
*/
|
||||||
@@ -199,8 +199,8 @@ public class IonOutput implements Closeable {
|
|||||||
{
|
{
|
||||||
bundle.save(this);
|
bundle.save(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write array of objects. Works with all that is supported by writeObject()
|
* Write array of objects. Works with all that is supported by writeObject()
|
||||||
*
|
*
|
||||||
@@ -214,8 +214,8 @@ public class IonOutput implements Closeable {
|
|||||||
writeObject(a);
|
writeObject(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public <T> void writeSequence(Collection<T> sequence) throws IOException
|
public <T> void writeSequence(Collection<T> sequence) throws IOException
|
||||||
{
|
{
|
||||||
for (final T element : sequence) {
|
for (final T element : sequence) {
|
||||||
@@ -224,47 +224,47 @@ public class IonOutput implements Closeable {
|
|||||||
}
|
}
|
||||||
endSequence();
|
endSequence();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public <K, V> void writeMap(Map<K, V> map) throws IOException
|
public <K, V> void writeMap(Map<K, V> map) throws IOException
|
||||||
{
|
{
|
||||||
for (final Entry<K, V> e : map.entrySet()) {
|
for (final Entry<K, V> e : map.entrySet()) {
|
||||||
if (e.getValue() == null) {
|
if (e.getValue() == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
startEntry();
|
startEntry();
|
||||||
writeObject(e.getKey());
|
writeObject(e.getKey());
|
||||||
writeObject(e.getValue());
|
writeObject(e.getValue());
|
||||||
}
|
}
|
||||||
endSequence();
|
endSequence();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void endSequence() throws IOException
|
public void endSequence() throws IOException
|
||||||
{
|
{
|
||||||
writeMark(Ion.END);
|
writeMark(Ion.END);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void startEntry() throws IOException
|
public void startEntry() throws IOException
|
||||||
{
|
{
|
||||||
writeMark(Ion.ENTRY);
|
writeMark(Ion.ENTRY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void writeMark(int mark) throws IOException
|
private void writeMark(int mark) throws IOException
|
||||||
{
|
{
|
||||||
writeIntByte(mark);
|
writeIntByte(mark);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void writeLength(int length) throws IOException
|
private void writeLength(int length) throws IOException
|
||||||
{
|
{
|
||||||
writeInt(length);
|
writeInt(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write an object. Supported are built-in types and types registered to
|
* Write an object. Supported are built-in types and types registered to
|
||||||
* Ion.
|
* Ion.
|
||||||
@@ -278,177 +278,177 @@ public class IonOutput implements Closeable {
|
|||||||
writeMark(Ion.NULL);
|
writeMark(Ion.NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj instanceof IonBinary) {
|
if (obj instanceof IonBinary) {
|
||||||
final IonBinary iObj = (IonBinary) obj;
|
final IonBinary iObj = (IonBinary) obj;
|
||||||
|
|
||||||
writeMark(Ion.getMark(obj));
|
writeMark(Ion.getMark(obj));
|
||||||
iObj.save(this);
|
iObj.save(this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj instanceof IonBundled) {
|
if (obj instanceof IonBundled) {
|
||||||
final IonBundled iObj = (IonBundled) obj;
|
final IonBundled iObj = (IonBundled) obj;
|
||||||
|
|
||||||
writeMark(Ion.getMark(obj));
|
writeMark(Ion.getMark(obj));
|
||||||
|
|
||||||
final IonDataBundle bundle = new IonDataBundle();
|
final IonDataBundle bundle = new IonDataBundle();
|
||||||
iObj.save(bundle);
|
iObj.save(bundle);
|
||||||
writeBundle(bundle);
|
writeBundle(bundle);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Ion.isObjectIndirectBundled(obj)) {
|
if (Ion.isObjectIndirectBundled(obj)) {
|
||||||
final IonizerBundled<?> ionizer = Ion.getIonizerBundledForClass(obj.getClass());
|
final IonizerBundled<?> ionizer = Ion.getIonizerBundledForClass(obj.getClass());
|
||||||
|
|
||||||
writeMark(Ion.getMark(obj));
|
writeMark(Ion.getMark(obj));
|
||||||
|
|
||||||
final IonDataBundle bundle = new IonDataBundle();
|
final IonDataBundle bundle = new IonDataBundle();
|
||||||
ionizer._save(obj, bundle);
|
ionizer._save(obj, bundle);
|
||||||
writeBundle(bundle);
|
writeBundle(bundle);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Ion.isObjectIndirectBinary(obj)) {
|
if (Ion.isObjectIndirectBinary(obj)) {
|
||||||
final IonizerBinary<?> ionizer = Ion.getIonizerBinaryForClass(obj.getClass());
|
final IonizerBinary<?> ionizer = Ion.getIonizerBinaryForClass(obj.getClass());
|
||||||
|
|
||||||
writeMark(Ion.getMark(obj));
|
writeMark(Ion.getMark(obj));
|
||||||
|
|
||||||
ionizer._save(obj, this);
|
ionizer._save(obj, this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj instanceof Map) {
|
if (obj instanceof Map) {
|
||||||
writeMark(Ion.MAP);
|
writeMark(Ion.MAP);
|
||||||
writeMap((Map<?, ?>) obj);
|
writeMap((Map<?, ?>) obj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj instanceof Collection) {
|
if (obj instanceof Collection) {
|
||||||
writeMark(Ion.SEQUENCE);
|
writeMark(Ion.SEQUENCE);
|
||||||
writeSequence((Collection<?>) obj);
|
writeSequence((Collection<?>) obj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj instanceof Boolean) {
|
if (obj instanceof Boolean) {
|
||||||
writeMark(Ion.BOOLEAN);
|
writeMark(Ion.BOOLEAN);
|
||||||
writeBoolean((Boolean) obj);
|
writeBoolean((Boolean) obj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj instanceof Byte) {
|
if (obj instanceof Byte) {
|
||||||
writeMark(Ion.BYTE);
|
writeMark(Ion.BYTE);
|
||||||
writeByte((Byte) obj);
|
writeByte((Byte) obj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj instanceof Character) {
|
if (obj instanceof Character) {
|
||||||
writeMark(Ion.CHAR);
|
writeMark(Ion.CHAR);
|
||||||
writeChar((Character) obj);
|
writeChar((Character) obj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj instanceof Short) {
|
if (obj instanceof Short) {
|
||||||
writeMark(Ion.SHORT);
|
writeMark(Ion.SHORT);
|
||||||
writeShort((Short) obj);
|
writeShort((Short) obj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj instanceof Integer) {
|
if (obj instanceof Integer) {
|
||||||
writeMark(Ion.INT);
|
writeMark(Ion.INT);
|
||||||
writeInt((Integer) obj);
|
writeInt((Integer) obj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj instanceof Long) {
|
if (obj instanceof Long) {
|
||||||
writeMark(Ion.LONG);
|
writeMark(Ion.LONG);
|
||||||
writeLong((Long) obj);
|
writeLong((Long) obj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj instanceof Float) {
|
if (obj instanceof Float) {
|
||||||
writeMark(Ion.FLOAT);
|
writeMark(Ion.FLOAT);
|
||||||
writeFloat((Float) obj);
|
writeFloat((Float) obj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj instanceof Double) {
|
if (obj instanceof Double) {
|
||||||
writeMark(Ion.DOUBLE);
|
writeMark(Ion.DOUBLE);
|
||||||
writeDouble((Double) obj);
|
writeDouble((Double) obj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj instanceof String) {
|
if (obj instanceof String) {
|
||||||
writeMark(Ion.STRING);
|
writeMark(Ion.STRING);
|
||||||
writeString((String) obj);
|
writeString((String) obj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj instanceof boolean[]) {
|
if (obj instanceof boolean[]) {
|
||||||
writeMark(Ion.BOOLEAN_ARRAY);
|
writeMark(Ion.BOOLEAN_ARRAY);
|
||||||
writeBooleans((boolean[]) obj);
|
writeBooleans((boolean[]) obj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj instanceof byte[]) {
|
if (obj instanceof byte[]) {
|
||||||
writeMark(Ion.BYTE_ARRAY);
|
writeMark(Ion.BYTE_ARRAY);
|
||||||
writeBytes((byte[]) obj);
|
writeBytes((byte[]) obj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj instanceof char[]) {
|
if (obj instanceof char[]) {
|
||||||
writeMark(Ion.CHAR_ARRAY);
|
writeMark(Ion.CHAR_ARRAY);
|
||||||
writeChars((char[]) obj);
|
writeChars((char[]) obj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj instanceof short[]) {
|
if (obj instanceof short[]) {
|
||||||
writeMark(Ion.SHORT_ARRAY);
|
writeMark(Ion.SHORT_ARRAY);
|
||||||
writeShorts((short[]) obj);
|
writeShorts((short[]) obj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj instanceof int[]) {
|
if (obj instanceof int[]) {
|
||||||
writeMark(Ion.INT_ARRAY);
|
writeMark(Ion.INT_ARRAY);
|
||||||
writeInts((int[]) obj);
|
writeInts((int[]) obj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj instanceof long[]) {
|
if (obj instanceof long[]) {
|
||||||
writeMark(Ion.LONG_ARRAY);
|
writeMark(Ion.LONG_ARRAY);
|
||||||
writeLongs((long[]) obj);
|
writeLongs((long[]) obj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj instanceof float[]) {
|
if (obj instanceof float[]) {
|
||||||
writeMark(Ion.FLOAT_ARRAY);
|
writeMark(Ion.FLOAT_ARRAY);
|
||||||
writeFloats((float[]) obj);
|
writeFloats((float[]) obj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj instanceof double[]) {
|
if (obj instanceof double[]) {
|
||||||
writeMark(Ion.DOUBLE_ARRAY);
|
writeMark(Ion.DOUBLE_ARRAY);
|
||||||
writeDoubles((double[]) obj);
|
writeDoubles((double[]) obj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj instanceof String[]) {
|
if (obj instanceof String[]) {
|
||||||
writeMark(Ion.STRING_ARRAY);
|
writeMark(Ion.STRING_ARRAY);
|
||||||
writeStrings((String[]) obj);
|
writeStrings((String[]) obj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj instanceof Object[]) {
|
if (obj instanceof Object[]) {
|
||||||
writeMark(Ion.OBJECT_ARRAY);
|
writeMark(Ion.OBJECT_ARRAY);
|
||||||
writeObjects((Object[]) obj);
|
writeObjects((Object[]) obj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new IOException("Object " + obj + " could not be be written to stream.");
|
throw new IOException("Object " + obj + " could not be be written to stream.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException
|
public void close() throws IOException
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,47 +8,47 @@ import java.util.Collection;
|
|||||||
|
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
class IonSequenceWrapper implements IonBinary {
|
class IonSequenceWrapper implements IonBinary {
|
||||||
|
|
||||||
private Collection collection = new ArrayList();
|
private Collection collection = new ArrayList();
|
||||||
|
|
||||||
|
|
||||||
public IonSequenceWrapper()
|
public IonSequenceWrapper()
|
||||||
{
|
{
|
||||||
collection = new ArrayList();
|
collection = new ArrayList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public IonSequenceWrapper(Collection saved)
|
public IonSequenceWrapper(Collection saved)
|
||||||
{
|
{
|
||||||
collection = saved;
|
collection = saved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load(IonInput in) throws IOException
|
public void load(IonInput in) throws IOException
|
||||||
{
|
{
|
||||||
collection.clear();
|
collection.clear();
|
||||||
in.readSequence(collection);
|
in.readSequence(collection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void save(IonOutput out) throws IOException
|
public void save(IonOutput out) throws IOException
|
||||||
{
|
{
|
||||||
out.writeSequence(collection);
|
out.writeSequence(collection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void fill(Collection o)
|
public void fill(Collection o)
|
||||||
{
|
{
|
||||||
o.clear();
|
o.clear();
|
||||||
o.addAll(collection);
|
o.addAll(collection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Collection getSequence()
|
public Collection getSequence()
|
||||||
{
|
{
|
||||||
return collection;
|
return collection;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,14 +12,14 @@ import java.io.IOException;
|
|||||||
* @param <T>
|
* @param <T>
|
||||||
*/
|
*/
|
||||||
public abstract class IonizerBinary<T> {
|
public abstract class IonizerBinary<T> {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
final void _save(Object object, IonOutput out) throws IOException
|
final void _save(Object object, IonOutput out) throws IOException
|
||||||
{
|
{
|
||||||
save((T) object, out);
|
save((T) object, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save an object to ion output
|
* Save an object to ion output
|
||||||
*
|
*
|
||||||
@@ -28,8 +28,8 @@ public abstract class IonizerBinary<T> {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public abstract void save(T object, IonOutput out) throws IOException;
|
public abstract void save(T object, IonOutput out) throws IOException;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load an object from ion input
|
* Load an object from ion input
|
||||||
*
|
*
|
||||||
@@ -37,5 +37,5 @@ public abstract class IonizerBinary<T> {
|
|||||||
* @return the loaded object
|
* @return the loaded object
|
||||||
*/
|
*/
|
||||||
public abstract T load(IonInput in) throws IOException;
|
public abstract T load(IonInput in) throws IOException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,14 +9,14 @@ package mightypork.utils.ion;
|
|||||||
* @param <T>
|
* @param <T>
|
||||||
*/
|
*/
|
||||||
public abstract class IonizerBundled<T> {
|
public abstract class IonizerBundled<T> {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
final void _save(Object object, IonDataBundle out)
|
final void _save(Object object, IonDataBundle out)
|
||||||
{
|
{
|
||||||
save((T) object, out);
|
save((T) object, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save an object to data bundle
|
* Save an object to data bundle
|
||||||
*
|
*
|
||||||
@@ -24,8 +24,8 @@ public abstract class IonizerBundled<T> {
|
|||||||
* @param out bundle to save to
|
* @param out bundle to save to
|
||||||
*/
|
*/
|
||||||
public abstract void save(T object, IonDataBundle out);
|
public abstract void save(T object, IonDataBundle out);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load an object from a bundle
|
* Load an object from a bundle
|
||||||
*
|
*
|
||||||
@@ -33,5 +33,5 @@ public abstract class IonizerBundled<T> {
|
|||||||
* @return the loaded object
|
* @return the loaded object
|
||||||
*/
|
*/
|
||||||
public abstract T load(IonDataBundle in);
|
public abstract T load(IonDataBundle in);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,13 +7,13 @@ import java.io.StringWriter;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import mightypork.utils.Str;
|
||||||
import mightypork.utils.annotations.FactoryMethod;
|
import mightypork.utils.annotations.FactoryMethod;
|
||||||
import mightypork.utils.logging.monitors.LogMonitor;
|
import mightypork.utils.logging.monitors.LogMonitor;
|
||||||
import mightypork.utils.logging.monitors.LogMonitorStdout;
|
import mightypork.utils.logging.monitors.LogMonitorStdout;
|
||||||
import mightypork.utils.logging.writers.ArchivingLog;
|
import mightypork.utils.logging.writers.ArchivingLog;
|
||||||
import mightypork.utils.logging.writers.LogWriter;
|
import mightypork.utils.logging.writers.LogWriter;
|
||||||
import mightypork.utils.logging.writers.SimpleLog;
|
import mightypork.utils.logging.writers.SimpleLog;
|
||||||
import mightypork.utils.string.StringUtil;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -22,15 +22,15 @@ import mightypork.utils.string.StringUtil;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class Log {
|
public class Log {
|
||||||
|
|
||||||
private static LogWriter main = null;
|
private static LogWriter main = null;
|
||||||
private static boolean enabled = true;
|
private static boolean enabled = true;
|
||||||
private static final LogMonitorStdout sysoMonitor = new LogMonitorStdout();
|
private static final LogMonitorStdout sysoMonitor = new LogMonitorStdout();
|
||||||
private static final long start_ms = System.currentTimeMillis();
|
private static final long start_ms = System.currentTimeMillis();
|
||||||
|
|
||||||
private static HashMap<String, SimpleLog> logs = new HashMap<>();
|
private static HashMap<String, SimpleLog> logs = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a logger. If another with the name already exists, it'll be
|
* Create a logger. If another with the name already exists, it'll be
|
||||||
* retrieved instead of creating a new one.
|
* retrieved instead of creating a new one.
|
||||||
@@ -44,16 +44,16 @@ public class Log {
|
|||||||
public static synchronized LogWriter create(String logName, File logFile, int oldLogsCount)
|
public static synchronized LogWriter create(String logName, File logFile, int oldLogsCount)
|
||||||
{
|
{
|
||||||
if (logs.containsKey(logName)) return logs.get(logName);
|
if (logs.containsKey(logName)) return logs.get(logName);
|
||||||
|
|
||||||
final ArchivingLog log = new ArchivingLog(logName, logFile, oldLogsCount);
|
final ArchivingLog log = new ArchivingLog(logName, logFile, oldLogsCount);
|
||||||
log.init();
|
log.init();
|
||||||
|
|
||||||
logs.put(logName, log);
|
logs.put(logName, log);
|
||||||
|
|
||||||
return log;
|
return log;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a logger. If another with the name already exists, it'll be
|
* Create a logger. If another with the name already exists, it'll be
|
||||||
* retrieved instead of creating a new one.
|
* retrieved instead of creating a new one.
|
||||||
@@ -66,50 +66,50 @@ public class Log {
|
|||||||
public static synchronized LogWriter create(String logName, File logFile)
|
public static synchronized LogWriter create(String logName, File logFile)
|
||||||
{
|
{
|
||||||
if (logs.containsKey(logName)) return logs.get(logName);
|
if (logs.containsKey(logName)) return logs.get(logName);
|
||||||
|
|
||||||
final SimpleLog log = new SimpleLog(logName, logFile);
|
final SimpleLog log = new SimpleLog(logName, logFile);
|
||||||
log.init();
|
log.init();
|
||||||
|
|
||||||
logs.put(logName, log);
|
logs.put(logName, log);
|
||||||
|
|
||||||
return log;
|
return log;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void setMainLogger(LogWriter log)
|
public static void setMainLogger(LogWriter log)
|
||||||
{
|
{
|
||||||
main = log;
|
main = log;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static LogWriter getMainLogger()
|
public static LogWriter getMainLogger()
|
||||||
{
|
{
|
||||||
return main;
|
return main;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void addMonitor(LogMonitor mon)
|
public static void addMonitor(LogMonitor mon)
|
||||||
{
|
{
|
||||||
assertInited();
|
assertInited();
|
||||||
|
|
||||||
main.addMonitor(mon);
|
main.addMonitor(mon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void removeMonitor(LogMonitor mon)
|
public static void removeMonitor(LogMonitor mon)
|
||||||
{
|
{
|
||||||
assertInited();
|
assertInited();
|
||||||
|
|
||||||
main.removeMonitor(mon);
|
main.removeMonitor(mon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static void assertInited()
|
private static void assertInited()
|
||||||
{
|
{
|
||||||
if (main == null) throw new IllegalStateException("Main logger not initialized.");
|
if (main == null) throw new IllegalStateException("Main logger not initialized.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log a message
|
* Log a message
|
||||||
*
|
*
|
||||||
@@ -120,14 +120,14 @@ public class Log {
|
|||||||
{
|
{
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
sysoMonitor.onMessageLogged(level, formatMessage(level, msg, null, start_ms));
|
sysoMonitor.onMessageLogged(level, formatMessage(level, msg, null, start_ms));
|
||||||
|
|
||||||
if (main != null) {
|
if (main != null) {
|
||||||
main.log(level, msg);
|
main.log(level, msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log a message
|
* Log a message
|
||||||
*
|
*
|
||||||
@@ -139,14 +139,14 @@ public class Log {
|
|||||||
{
|
{
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
sysoMonitor.onMessageLogged(level, formatMessage(level, msg, t, start_ms));
|
sysoMonitor.onMessageLogged(level, formatMessage(level, msg, t, start_ms));
|
||||||
|
|
||||||
if (main != null) {
|
if (main != null) {
|
||||||
main.log(level, msg, t);
|
main.log(level, msg, t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log FINE message
|
* Log FINE message
|
||||||
*
|
*
|
||||||
@@ -156,8 +156,8 @@ public class Log {
|
|||||||
{
|
{
|
||||||
log(Level.FINE, msg);
|
log(Level.FINE, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log FINER message
|
* Log FINER message
|
||||||
*
|
*
|
||||||
@@ -167,8 +167,8 @@ public class Log {
|
|||||||
{
|
{
|
||||||
log(Level.FINER, msg);
|
log(Level.FINER, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log FINEST message
|
* Log FINEST message
|
||||||
*
|
*
|
||||||
@@ -178,8 +178,8 @@ public class Log {
|
|||||||
{
|
{
|
||||||
log(Level.FINEST, msg);
|
log(Level.FINEST, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log INFO message
|
* Log INFO message
|
||||||
*
|
*
|
||||||
@@ -189,8 +189,8 @@ public class Log {
|
|||||||
{
|
{
|
||||||
log(Level.INFO, msg);
|
log(Level.INFO, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log WARNING message (less severe than ERROR)
|
* Log WARNING message (less severe than ERROR)
|
||||||
*
|
*
|
||||||
@@ -200,8 +200,8 @@ public class Log {
|
|||||||
{
|
{
|
||||||
log(Level.WARNING, msg);
|
log(Level.WARNING, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log ERROR message
|
* Log ERROR message
|
||||||
*
|
*
|
||||||
@@ -211,8 +211,8 @@ public class Log {
|
|||||||
{
|
{
|
||||||
log(Level.SEVERE, msg);
|
log(Level.SEVERE, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log warning message with exception
|
* Log warning message with exception
|
||||||
*
|
*
|
||||||
@@ -223,8 +223,8 @@ public class Log {
|
|||||||
{
|
{
|
||||||
log(Level.WARNING, msg, thrown);
|
log(Level.WARNING, msg, thrown);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log exception thrown as warning
|
* Log exception thrown as warning
|
||||||
*
|
*
|
||||||
@@ -234,8 +234,8 @@ public class Log {
|
|||||||
{
|
{
|
||||||
log(Level.WARNING, null, thrown);
|
log(Level.WARNING, null, thrown);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log error message
|
* Log error message
|
||||||
*
|
*
|
||||||
@@ -246,8 +246,8 @@ public class Log {
|
|||||||
{
|
{
|
||||||
log(Level.SEVERE, msg, thrown);
|
log(Level.SEVERE, msg, thrown);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log exception thrown as error
|
* Log exception thrown as error
|
||||||
*
|
*
|
||||||
@@ -257,28 +257,28 @@ public class Log {
|
|||||||
{
|
{
|
||||||
log(Level.SEVERE, null, thrown);
|
log(Level.SEVERE, null, thrown);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void enable(boolean flag)
|
public static void enable(boolean flag)
|
||||||
{
|
{
|
||||||
enabled = flag;
|
enabled = flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void setSysoutLevel(Level level)
|
public static void setSysoutLevel(Level level)
|
||||||
{
|
{
|
||||||
sysoMonitor.setLevel(level);
|
sysoMonitor.setLevel(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void setLevel(Level level)
|
public static void setLevel(Level level)
|
||||||
{
|
{
|
||||||
assertInited();
|
assertInited();
|
||||||
|
|
||||||
main.setLevel(level);
|
main.setLevel(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get stack trace from throwable
|
* Get stack trace from throwable
|
||||||
*
|
*
|
||||||
@@ -294,31 +294,31 @@ public class Log {
|
|||||||
sw.flush();
|
sw.flush();
|
||||||
return sw.toString();
|
return sw.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static String formatMessage(Level level, String message, Throwable throwable, long start_ms)
|
public static String formatMessage(Level level, String message, Throwable throwable, long start_ms)
|
||||||
{
|
{
|
||||||
if (message == null) message = "";
|
if (message == null) message = "";
|
||||||
|
|
||||||
final String nl = System.getProperty("line.separator");
|
final String nl = System.getProperty("line.separator");
|
||||||
|
|
||||||
if (message.length() > 0) {
|
if (message.length() > 0) {
|
||||||
if (message.equals("\n")) {
|
if (message.equals("\n")) {
|
||||||
return nl;
|
return nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.charAt(0) == '\n') {
|
if (message.charAt(0) == '\n') {
|
||||||
message = nl + message.substring(1);
|
message = nl + message.substring(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final long time_ms = (System.currentTimeMillis() - start_ms);
|
final long time_ms = (System.currentTimeMillis() - start_ms);
|
||||||
final double time_s = time_ms / 1000D;
|
final double time_s = time_ms / 1000D;
|
||||||
final String time = String.format("%6.2f ", time_s);
|
final String time = String.format("%6.2f ", time_s);
|
||||||
final String time_blank = StringUtil.repeat(" ", time.length());
|
final String time_blank = Str.repeat(" ", time.length());
|
||||||
|
|
||||||
String prefix = "[ ? ]";
|
String prefix = "[ ? ]";
|
||||||
|
|
||||||
if (level == Level.FINE) {
|
if (level == Level.FINE) {
|
||||||
prefix = "[ # ] ";
|
prefix = "[ # ] ";
|
||||||
} else if (level == Level.FINER) {
|
} else if (level == Level.FINER) {
|
||||||
@@ -332,13 +332,13 @@ public class Log {
|
|||||||
} else if (level == Level.WARNING) {
|
} else if (level == Level.WARNING) {
|
||||||
prefix = "[!W!] ";
|
prefix = "[!W!] ";
|
||||||
}
|
}
|
||||||
|
|
||||||
message = time + prefix + message.replaceAll("\n", nl + time_blank + prefix) + nl;
|
message = time + prefix + message.replaceAll("\n", nl + time_blank + prefix) + nl;
|
||||||
|
|
||||||
if (throwable != null) {
|
if (throwable != null) {
|
||||||
message += getStackTrace(throwable);
|
message += getStackTrace(throwable);
|
||||||
}
|
}
|
||||||
|
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,32 +5,32 @@ import java.util.logging.Level;
|
|||||||
|
|
||||||
|
|
||||||
public abstract class LogMonitor {
|
public abstract class LogMonitor {
|
||||||
|
|
||||||
private boolean enabled = true;
|
private boolean enabled = true;
|
||||||
private Level accepted = Level.ALL;
|
private Level accepted = Level.ALL;
|
||||||
|
|
||||||
|
|
||||||
public void onMessageLogged(Level level, String message)
|
public void onMessageLogged(Level level, String message)
|
||||||
{
|
{
|
||||||
if (!enabled) return;
|
if (!enabled) return;
|
||||||
if (accepted.intValue() > level.intValue()) return;
|
if (accepted.intValue() > level.intValue()) return;
|
||||||
|
|
||||||
logMessage(level, message);
|
logMessage(level, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected abstract void logMessage(Level level, String message);
|
protected abstract void logMessage(Level level, String message);
|
||||||
|
|
||||||
|
|
||||||
public void setLevel(Level level)
|
public void setLevel(Level level)
|
||||||
{
|
{
|
||||||
this.accepted = level;
|
this.accepted = level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void enable(boolean flag)
|
public void enable(boolean flag)
|
||||||
{
|
{
|
||||||
this.enabled = flag;
|
this.enabled = flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import java.util.logging.Level;
|
|||||||
|
|
||||||
|
|
||||||
public class LogMonitorStdout extends LogMonitor {
|
public class LogMonitorStdout extends LogMonitor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void logMessage(Level level, String message)
|
protected void logMessage(Level level, String message)
|
||||||
{
|
{
|
||||||
@@ -15,5 +15,5 @@ public class LogMonitorStdout extends LogMonitor {
|
|||||||
System.out.print(message);
|
System.out.print(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ import java.util.Comparator;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import mightypork.utils.Str;
|
||||||
import mightypork.utils.files.FileUtil;
|
import mightypork.utils.files.FileUtil;
|
||||||
import mightypork.utils.string.StringUtil;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -125,6 +125,6 @@ public class ArchivingLog extends SimpleLog {
|
|||||||
*/
|
*/
|
||||||
private String getSuffix()
|
private String getSuffix()
|
||||||
{
|
{
|
||||||
return StringUtil.fromLastChar(getFile().toString(), '.');
|
return Str.fromLast(getFile().toString(), '.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,45 +12,45 @@ import mightypork.utils.logging.monitors.LogMonitor;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public interface LogWriter {
|
public interface LogWriter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare logs for logging
|
* Prepare logs for logging
|
||||||
*/
|
*/
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add log monitor
|
* Add log monitor
|
||||||
*
|
*
|
||||||
* @param mon monitor
|
* @param mon monitor
|
||||||
*/
|
*/
|
||||||
void addMonitor(LogMonitor mon);
|
void addMonitor(LogMonitor mon);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a monitor
|
* Remove a monitor
|
||||||
*
|
*
|
||||||
* @param removed monitor to remove
|
* @param removed monitor to remove
|
||||||
*/
|
*/
|
||||||
void removeMonitor(LogMonitor removed);
|
void removeMonitor(LogMonitor removed);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set logging level
|
* Set logging level
|
||||||
*
|
*
|
||||||
* @param level
|
* @param level
|
||||||
*/
|
*/
|
||||||
void setLevel(Level level);
|
void setLevel(Level level);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable logging.
|
* Enable logging.
|
||||||
*
|
*
|
||||||
* @param flag do enable logging
|
* @param flag do enable logging
|
||||||
*/
|
*/
|
||||||
void enable(boolean flag);
|
void enable(boolean flag);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log a message
|
* Log a message
|
||||||
*
|
*
|
||||||
@@ -58,8 +58,8 @@ public interface LogWriter {
|
|||||||
* @param msg message text
|
* @param msg message text
|
||||||
*/
|
*/
|
||||||
void log(Level level, String msg);
|
void log(Level level, String msg);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log a message
|
* Log a message
|
||||||
*
|
*
|
||||||
@@ -68,5 +68,5 @@ public interface LogWriter {
|
|||||||
* @param t thrown exception
|
* @param t thrown exception
|
||||||
*/
|
*/
|
||||||
void log(Level level, String msg, Throwable t);
|
void log(Level level, String msg, Throwable t);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,69 +21,69 @@ import mightypork.utils.logging.monitors.LogMonitor;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class SimpleLog implements LogWriter {
|
public class SimpleLog implements LogWriter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log file formatter.
|
* Log file formatter.
|
||||||
*/
|
*/
|
||||||
class LogFormatter extends Formatter {
|
class LogFormatter extends Formatter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String format(LogRecord record)
|
public String format(LogRecord record)
|
||||||
{
|
{
|
||||||
return Log.formatMessage(record.getLevel(), record.getMessage(), record.getThrown(), started_ms);
|
return Log.formatMessage(record.getLevel(), record.getMessage(), record.getThrown(), started_ms);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Log file */
|
/** Log file */
|
||||||
private final File file;
|
private final File file;
|
||||||
|
|
||||||
/** Log name */
|
/** Log name */
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
/** Logger instance. */
|
/** Logger instance. */
|
||||||
private Logger logger;
|
private Logger logger;
|
||||||
|
|
||||||
private boolean enabled = true;
|
private boolean enabled = true;
|
||||||
private final HashSet<LogMonitor> monitors = new HashSet<>();
|
private final HashSet<LogMonitor> monitors = new HashSet<>();
|
||||||
private final long started_ms;
|
private final long started_ms;
|
||||||
|
|
||||||
|
|
||||||
public SimpleLog(String name, File file)
|
public SimpleLog(String name, File file)
|
||||||
{
|
{
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.file = file;
|
this.file = file;
|
||||||
this.started_ms = System.currentTimeMillis();
|
this.started_ms = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init()
|
public void init()
|
||||||
{
|
{
|
||||||
logger = Logger.getLogger(getName());
|
logger = Logger.getLogger(getName());
|
||||||
|
|
||||||
FileHandler handler = null;
|
FileHandler handler = null;
|
||||||
try {
|
try {
|
||||||
handler = new FileHandler(getFile().getPath());
|
handler = new FileHandler(getFile().getPath());
|
||||||
} catch (final Throwable t) {
|
} catch (final Throwable t) {
|
||||||
throw new RuntimeException("Failed to init log.", t);
|
throw new RuntimeException("Failed to init log.", t);
|
||||||
}
|
}
|
||||||
|
|
||||||
handler.setFormatter(new LogFormatter());
|
handler.setFormatter(new LogFormatter());
|
||||||
logger.addHandler(handler);
|
logger.addHandler(handler);
|
||||||
logger.setUseParentHandlers(false);
|
logger.setUseParentHandlers(false);
|
||||||
logger.setLevel(Level.ALL);
|
logger.setLevel(Level.ALL);
|
||||||
|
|
||||||
printHeader();
|
printHeader();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected void printHeader()
|
protected void printHeader()
|
||||||
{
|
{
|
||||||
final String stamp = (new SimpleDateFormat("yyyy/MM/dd HH:mm:ss")).format(new Date());
|
final String stamp = (new SimpleDateFormat("yyyy/MM/dd HH:mm:ss")).format(new Date());
|
||||||
log(Level.INFO, "Logger \"" + getName() + "\" initialized.\n" + stamp);
|
log(Level.INFO, "Logger \"" + getName() + "\" initialized.\n" + stamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add log monitor
|
* Add log monitor
|
||||||
*
|
*
|
||||||
@@ -94,8 +94,8 @@ public class SimpleLog implements LogWriter {
|
|||||||
{
|
{
|
||||||
monitors.add(mon);
|
monitors.add(mon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a monitor
|
* Remove a monitor
|
||||||
*
|
*
|
||||||
@@ -106,61 +106,61 @@ public class SimpleLog implements LogWriter {
|
|||||||
{
|
{
|
||||||
monitors.remove(removed);
|
monitors.remove(removed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setLevel(Level level)
|
public void setLevel(Level level)
|
||||||
{
|
{
|
||||||
logger.setLevel(level);
|
logger.setLevel(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enable(boolean flag)
|
public void enable(boolean flag)
|
||||||
{
|
{
|
||||||
enabled = flag;
|
enabled = flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public File getFile()
|
public File getFile()
|
||||||
{
|
{
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String getName()
|
public String getName()
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void log(Level level, String msg)
|
public void log(Level level, String msg)
|
||||||
{
|
{
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
logger.log(level, msg);
|
logger.log(level, msg);
|
||||||
|
|
||||||
final String fmt = Log.formatMessage(level, msg, null, started_ms);
|
final String fmt = Log.formatMessage(level, msg, null, started_ms);
|
||||||
|
|
||||||
for (final LogMonitor mon : monitors) {
|
for (final LogMonitor mon : monitors) {
|
||||||
mon.onMessageLogged(level, fmt);
|
mon.onMessageLogged(level, fmt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void log(Level level, String msg, Throwable t)
|
public void log(Level level, String msg, Throwable t)
|
||||||
{
|
{
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
logger.log(level, msg, t);
|
logger.log(level, msg, t);
|
||||||
|
|
||||||
final String fmt = Log.formatMessage(level, msg, t, started_ms);
|
final String fmt = Log.formatMessage(level, msg, t, started_ms);
|
||||||
|
|
||||||
for (final LogMonitor mon : monitors) {
|
for (final LogMonitor mon : monitors) {
|
||||||
mon.onMessageLogged(level, fmt);
|
mon.onMessageLogged(level, fmt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,16 +17,16 @@ import mightypork.utils.math.constraints.vect.Vect;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public final class Calc {
|
public final class Calc {
|
||||||
|
|
||||||
private Calc()
|
private Calc()
|
||||||
{
|
{
|
||||||
// not instantiable
|
// not instantiable
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Square root of two */
|
/** Square root of two */
|
||||||
public static final double SQ2 = 1.41421356237;
|
public static final double SQ2 = 1.41421356237;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get distance from 2D line to 2D point [X,Y]
|
* Get distance from 2D line to 2D point [X,Y]
|
||||||
*
|
*
|
||||||
@@ -40,53 +40,53 @@ public final class Calc {
|
|||||||
// line point L[lx,ly]
|
// line point L[lx,ly]
|
||||||
final double lx = linePoint.x();
|
final double lx = linePoint.x();
|
||||||
final double ly = linePoint.y();
|
final double ly = linePoint.y();
|
||||||
|
|
||||||
// line equation ax+by+c=0
|
// line equation ax+by+c=0
|
||||||
final double a = -lineDirVec.y();
|
final double a = -lineDirVec.y();
|
||||||
final double b = lineDirVec.x();
|
final double b = lineDirVec.x();
|
||||||
final double c = -a * lx - b * ly;
|
final double c = -a * lx - b * ly;
|
||||||
|
|
||||||
// checked point P[x,y]
|
// checked point P[x,y]
|
||||||
final double x = point.x();
|
final double x = point.x();
|
||||||
final double y = point.y();
|
final double y = point.y();
|
||||||
|
|
||||||
// distance
|
// distance
|
||||||
return Math.abs(a * x + b * y + c) / Math.sqrt(a * a + b * b);
|
return Math.abs(a * x + b * y + c) / Math.sqrt(a * a + b * b);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Random rand = new Random();
|
public static final Random rand = new Random();
|
||||||
|
|
||||||
|
|
||||||
public static double sphereSurface(double radius)
|
public static double sphereSurface(double radius)
|
||||||
{
|
{
|
||||||
return 4D * Math.PI * square(radius);
|
return 4D * Math.PI * square(radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static double sphereVolume(double radius)
|
public static double sphereVolume(double radius)
|
||||||
{
|
{
|
||||||
return (4D / 3D) * Math.PI * cube(radius);
|
return (4D / 3D) * Math.PI * cube(radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static double sphereRadius(double volume)
|
public static double sphereRadius(double volume)
|
||||||
{
|
{
|
||||||
return Math.cbrt((3D * volume) / (4 * Math.PI));
|
return Math.cbrt((3D * volume) / (4 * Math.PI));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static double circleSurface(double radius)
|
public static double circleSurface(double radius)
|
||||||
{
|
{
|
||||||
return Math.PI * square(radius);
|
return Math.PI * square(radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static double circleRadius(double surface)
|
public static double circleRadius(double surface)
|
||||||
{
|
{
|
||||||
return Math.sqrt(surface / Math.PI);
|
return Math.sqrt(surface / Math.PI);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Safe equals that works with nulls
|
* Safe equals that works with nulls
|
||||||
*
|
*
|
||||||
@@ -98,8 +98,8 @@ public final class Calc {
|
|||||||
{
|
{
|
||||||
return a == null ? b == null : a.equals(b);
|
return a == null ? b == null : a.equals(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clamp integer
|
* Clamp integer
|
||||||
*
|
*
|
||||||
@@ -112,8 +112,8 @@ public final class Calc {
|
|||||||
{
|
{
|
||||||
return number < min ? min : number > max ? max : number;
|
return number < min ? min : number > max ? max : number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clamp double
|
* Clamp double
|
||||||
*
|
*
|
||||||
@@ -126,14 +126,14 @@ public final class Calc {
|
|||||||
{
|
{
|
||||||
return number < min ? min : number > max ? max : number;
|
return number < min ? min : number > max ? max : number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static boolean isInRange(double number, double left, double right)
|
public static boolean isInRange(double number, double left, double right)
|
||||||
{
|
{
|
||||||
return number >= left && number <= right;
|
return number >= left && number <= right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get number from A to B at delta time (A -> B)
|
* Get number from A to B at delta time (A -> B)
|
||||||
*
|
*
|
||||||
@@ -147,8 +147,8 @@ public final class Calc {
|
|||||||
{
|
{
|
||||||
return from + (to - from) * easing.get(elapsed);
|
return from + (to - from) * easing.get(elapsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get angle [degrees] from A to B at delta time (tween A to B)
|
* Get angle [degrees] from A to B at delta time (tween A to B)
|
||||||
*
|
*
|
||||||
@@ -162,8 +162,8 @@ public final class Calc {
|
|||||||
{
|
{
|
||||||
return Deg.norm(from - Deg.delta(to, from) * easing.get(elapsed));
|
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)
|
* Get angle [radians] from A to B at delta time (tween A to B)
|
||||||
*
|
*
|
||||||
@@ -177,8 +177,8 @@ public final class Calc {
|
|||||||
{
|
{
|
||||||
return Rad.norm(from - Rad.delta(to, from) * easing.get(elapsed));
|
return Rad.norm(from - Rad.delta(to, from) * easing.get(elapsed));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static double max(double... numbers)
|
public static double max(double... numbers)
|
||||||
{
|
{
|
||||||
double highest = numbers[0];
|
double highest = numbers[0];
|
||||||
@@ -187,8 +187,8 @@ public final class Calc {
|
|||||||
}
|
}
|
||||||
return highest;
|
return highest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static int max(int... numbers)
|
public static int max(int... numbers)
|
||||||
{
|
{
|
||||||
int highest = numbers[0];
|
int highest = numbers[0];
|
||||||
@@ -197,8 +197,8 @@ public final class Calc {
|
|||||||
}
|
}
|
||||||
return highest;
|
return highest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static double min(double... numbers)
|
public static double min(double... numbers)
|
||||||
{
|
{
|
||||||
double lowest = numbers[0];
|
double lowest = numbers[0];
|
||||||
@@ -207,8 +207,8 @@ public final class Calc {
|
|||||||
}
|
}
|
||||||
return lowest;
|
return lowest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static int min(int... numbers)
|
public static int min(int... numbers)
|
||||||
{
|
{
|
||||||
int lowest = numbers[0];
|
int lowest = numbers[0];
|
||||||
@@ -217,8 +217,8 @@ public final class Calc {
|
|||||||
}
|
}
|
||||||
return lowest;
|
return lowest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Split comma separated list of integers.
|
* Split comma separated list of integers.
|
||||||
*
|
*
|
||||||
@@ -231,21 +231,21 @@ public final class Calc {
|
|||||||
if (list == null) {
|
if (list == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final String[] parts = list.split(Character.toString(delimiter));
|
final String[] parts = list.split(Character.toString(delimiter));
|
||||||
|
|
||||||
final ArrayList<Integer> intList = new ArrayList<>();
|
final ArrayList<Integer> intList = new ArrayList<>();
|
||||||
|
|
||||||
for (final String part : parts) {
|
for (final String part : parts) {
|
||||||
try {
|
try {
|
||||||
intList.add(Integer.parseInt(part.trim()));
|
intList.add(Integer.parseInt(part.trim()));
|
||||||
} catch (final NumberFormatException e) {}
|
} catch (final NumberFormatException e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
return intList;
|
return intList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pick random element from a given list.
|
* Pick random element from a given list.
|
||||||
*
|
*
|
||||||
@@ -256,8 +256,8 @@ public final class Calc {
|
|||||||
{
|
{
|
||||||
return pick(rand, list);
|
return pick(rand, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pick random element from a given list.
|
* Pick random element from a given list.
|
||||||
*
|
*
|
||||||
@@ -270,8 +270,8 @@ public final class Calc {
|
|||||||
if (list.size() == 0) return null;
|
if (list.size() == 0) return null;
|
||||||
return list.get(rand.nextInt(list.size()));
|
return list.get(rand.nextInt(list.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Take a square
|
* Take a square
|
||||||
*
|
*
|
||||||
@@ -282,8 +282,8 @@ public final class Calc {
|
|||||||
{
|
{
|
||||||
return a * a;
|
return a * a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Take a cube
|
* Take a cube
|
||||||
*
|
*
|
||||||
@@ -294,8 +294,8 @@ public final class Calc {
|
|||||||
{
|
{
|
||||||
return a * a * a;
|
return a * a * a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param d number
|
* @param d number
|
||||||
* @return fractional part
|
* @return fractional part
|
||||||
@@ -304,8 +304,8 @@ public final class Calc {
|
|||||||
{
|
{
|
||||||
return d - Math.floor(d);
|
return d - Math.floor(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make sure value is within array length.
|
* Make sure value is within array length.
|
||||||
*
|
*
|
||||||
@@ -319,8 +319,8 @@ public final class Calc {
|
|||||||
throw new IndexOutOfBoundsException();
|
throw new IndexOutOfBoundsException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get distance of two coordinates in 2D plane
|
* Get distance of two coordinates in 2D plane
|
||||||
*
|
*
|
||||||
@@ -334,21 +334,21 @@ public final class Calc {
|
|||||||
{
|
{
|
||||||
return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
|
return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static int randInt(Random rand, int low, int high)
|
public static int randInt(Random rand, int low, int high)
|
||||||
{
|
{
|
||||||
final int range = Math.abs(high - low) + 1;
|
final int range = Math.abs(high - low) + 1;
|
||||||
return low + rand.nextInt(range);
|
return low + rand.nextInt(range);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static int randInt(int low, int high)
|
public static int randInt(int low, int high)
|
||||||
{
|
{
|
||||||
return randInt(rand, low, high);
|
return randInt(rand, low, high);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get ordinal version of numbers (1 = 1st, 5 = 5th etc.)
|
* Get ordinal version of numbers (1 = 1st, 5 = 5th etc.)
|
||||||
*
|
*
|
||||||
@@ -364,8 +364,8 @@ public final class Calc {
|
|||||||
}
|
}
|
||||||
return number + "th";
|
return number + "th";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format number with thousands separated.
|
* Format number with thousands separated.
|
||||||
*
|
*
|
||||||
@@ -378,18 +378,18 @@ public final class Calc {
|
|||||||
final String num = String.valueOf(number);
|
final String num = String.valueOf(number);
|
||||||
final String dot = String.valueOf(thousandSep);
|
final String dot = String.valueOf(thousandSep);
|
||||||
String out = "";
|
String out = "";
|
||||||
|
|
||||||
int cnt = 1;
|
int cnt = 1;
|
||||||
for (int i = num.length() - 1; i >= 0; i--) {
|
for (int i = num.length() - 1; i >= 0; i--) {
|
||||||
out = num.charAt(i) + out;
|
out = num.charAt(i) + out;
|
||||||
if (cnt % 3 == 0 && i > 0) out = dot + out;
|
if (cnt % 3 == 0 && i > 0) out = dot + out;
|
||||||
cnt++;
|
cnt++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static int countBits(byte b)
|
public static int countBits(byte b)
|
||||||
{
|
{
|
||||||
int c = 0;
|
int c = 0;
|
||||||
|
|||||||
@@ -10,16 +10,16 @@ import mightypork.utils.math.constraints.vect.Vect;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class Polar {
|
public class Polar {
|
||||||
|
|
||||||
/** angle in radians */
|
/** angle in radians */
|
||||||
private double angle = 0;
|
private double angle = 0;
|
||||||
|
|
||||||
/** distance in units */
|
/** distance in units */
|
||||||
private double radius = 0;
|
private double radius = 0;
|
||||||
|
|
||||||
private Vect coord = null;
|
private Vect coord = null;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a polar
|
* Create a polar
|
||||||
*
|
*
|
||||||
@@ -30,8 +30,8 @@ public class Polar {
|
|||||||
{
|
{
|
||||||
this(angle, false, distance);
|
this(angle, false, distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a polar
|
* Create a polar
|
||||||
*
|
*
|
||||||
@@ -44,8 +44,8 @@ public class Polar {
|
|||||||
this.radius = distance;
|
this.radius = distance;
|
||||||
this.angle = deg ? Math.toRadians(angle) : angle;
|
this.angle = deg ? Math.toRadians(angle) : angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return angle in RAD
|
* @return angle in RAD
|
||||||
*/
|
*/
|
||||||
@@ -53,8 +53,8 @@ public class Polar {
|
|||||||
{
|
{
|
||||||
return angle;
|
return angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return angle in DEG
|
* @return angle in DEG
|
||||||
*/
|
*/
|
||||||
@@ -62,8 +62,8 @@ public class Polar {
|
|||||||
{
|
{
|
||||||
return Math.toDegrees(angle);
|
return Math.toDegrees(angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param angle angle in RAD
|
* @param angle angle in RAD
|
||||||
*/
|
*/
|
||||||
@@ -71,8 +71,8 @@ public class Polar {
|
|||||||
{
|
{
|
||||||
this.angle = angle;
|
this.angle = angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param angle angle in DEG
|
* @param angle angle in DEG
|
||||||
*/
|
*/
|
||||||
@@ -80,8 +80,8 @@ public class Polar {
|
|||||||
{
|
{
|
||||||
this.angle = Math.toRadians(angle);
|
this.angle = Math.toRadians(angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return radius
|
* @return radius
|
||||||
*/
|
*/
|
||||||
@@ -89,8 +89,8 @@ public class Polar {
|
|||||||
{
|
{
|
||||||
return radius;
|
return radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param r radius
|
* @param r radius
|
||||||
*/
|
*/
|
||||||
@@ -98,8 +98,8 @@ public class Polar {
|
|||||||
{
|
{
|
||||||
this.radius = r;
|
this.radius = r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make polar from coord
|
* Make polar from coord
|
||||||
*
|
*
|
||||||
@@ -109,10 +109,10 @@ public class Polar {
|
|||||||
public static Polar fromCoord(Vect coord)
|
public static Polar fromCoord(Vect coord)
|
||||||
{
|
{
|
||||||
return Polar.fromCoord(coord.x(), coord.y());
|
return Polar.fromCoord(coord.x(), coord.y());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make polar from coords
|
* Make polar from coords
|
||||||
*
|
*
|
||||||
@@ -124,11 +124,11 @@ public class Polar {
|
|||||||
{
|
{
|
||||||
final double a = Math.atan2(y, x);
|
final double a = Math.atan2(y, x);
|
||||||
final double r = Math.sqrt(x * x + y * y);
|
final double r = Math.sqrt(x * x + y * y);
|
||||||
|
|
||||||
return new Polar(a, r);
|
return new Polar(a, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get coord from polar
|
* Get coord from polar
|
||||||
*
|
*
|
||||||
@@ -138,32 +138,32 @@ public class Polar {
|
|||||||
{
|
{
|
||||||
// lazy init
|
// lazy init
|
||||||
if (coord == null) coord = new Vect() {
|
if (coord == null) coord = new Vect() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double x()
|
public double x()
|
||||||
{
|
{
|
||||||
return radius * Math.cos(angle);
|
return radius * Math.cos(angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double y()
|
public double y()
|
||||||
{
|
{
|
||||||
return radius * Math.sin(angle);
|
return radius * Math.sin(angle);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return coord;
|
return coord;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return "Polar(" + angle + "rad, " + radius + ")";
|
return "Polar(" + angle + "rad, " + radius + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode()
|
public int hashCode()
|
||||||
{
|
{
|
||||||
@@ -176,8 +176,8 @@ public class Polar {
|
|||||||
result = prime * result + (int) (temp ^ (temp >>> 32));
|
result = prime * result + (int) (temp ^ (temp >>> 32));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj)
|
public boolean equals(Object obj)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,24 +10,24 @@ import java.util.Random;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class Range {
|
public class Range {
|
||||||
|
|
||||||
public static Range make(double low, double high)
|
public static Range make(double low, double high)
|
||||||
{
|
{
|
||||||
return new Range(low, high);
|
return new Range(low, high);
|
||||||
}
|
}
|
||||||
|
|
||||||
private double min = 0;
|
private double min = 0;
|
||||||
private double max = 1;
|
private double max = 1;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implicit range constructor 0-1
|
* Implicit range constructor 0-1
|
||||||
*/
|
*/
|
||||||
public Range()
|
public Range()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create new range
|
* Create new range
|
||||||
*
|
*
|
||||||
@@ -40,8 +40,8 @@ public class Range {
|
|||||||
this.max = max;
|
this.max = max;
|
||||||
norm();
|
norm();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create new range
|
* Create new range
|
||||||
*
|
*
|
||||||
@@ -52,39 +52,39 @@ public class Range {
|
|||||||
this.min = minmax;
|
this.min = minmax;
|
||||||
this.max = minmax;
|
this.max = minmax;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static Range fromString(String string)
|
public static Range fromString(String string)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
String s = string.trim();
|
String s = string.trim();
|
||||||
|
|
||||||
// drop whitespace
|
// drop whitespace
|
||||||
s = s.replaceAll("\\s", "");
|
s = s.replaceAll("\\s", "");
|
||||||
|
|
||||||
// drop brackets
|
// drop brackets
|
||||||
s = s.replaceAll("[\\(\\[\\{\\)\\]\\}]", "");
|
s = s.replaceAll("[\\(\\[\\{\\)\\]\\}]", "");
|
||||||
|
|
||||||
// norm separators
|
// norm separators
|
||||||
s = s.replaceAll("[:;]", "|").replace("..", "|");
|
s = s.replaceAll("[:;]", "|").replace("..", "|");
|
||||||
|
|
||||||
// norm floating point
|
// norm floating point
|
||||||
s = s.replaceAll("[,]", ".");
|
s = s.replaceAll("[,]", ".");
|
||||||
|
|
||||||
// dash to pipe, if not a minus sign
|
// dash to pipe, if not a minus sign
|
||||||
s = s.replaceAll("([0-9])\\s?[\\-]", "$1|");
|
s = s.replaceAll("([0-9])\\s?[\\-]", "$1|");
|
||||||
|
|
||||||
final String[] parts = s.split("[|]");
|
final String[] parts = s.split("[|]");
|
||||||
|
|
||||||
if (parts.length >= 1) {
|
if (parts.length >= 1) {
|
||||||
|
|
||||||
final double low = Double.parseDouble(parts[0].trim());
|
final double low = Double.parseDouble(parts[0].trim());
|
||||||
|
|
||||||
if (parts.length == 2) {
|
if (parts.length == 2) {
|
||||||
final double high = Double.parseDouble(parts[1].trim());
|
final double high = Double.parseDouble(parts[1].trim());
|
||||||
return Range.make(low, high);
|
return Range.make(low, high);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Range.make(low, low);
|
return Range.make(low, low);
|
||||||
}
|
}
|
||||||
} catch (final RuntimeException e) {
|
} catch (final RuntimeException e) {
|
||||||
@@ -92,15 +92,15 @@ public class Range {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return String.format("(%f : %f)", getMin(), getMax());
|
return String.format("(%f : %f)", getMin(), getMax());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make sure min is <= max
|
* Make sure min is <= max
|
||||||
*/
|
*/
|
||||||
@@ -112,8 +112,8 @@ public class Range {
|
|||||||
max = t;
|
max = t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get random integer from range
|
* Get random integer from range
|
||||||
*
|
*
|
||||||
@@ -123,8 +123,8 @@ public class Range {
|
|||||||
{
|
{
|
||||||
return randInt(Calc.rand);
|
return randInt(Calc.rand);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get random double from this range
|
* Get random double from this range
|
||||||
*
|
*
|
||||||
@@ -134,8 +134,8 @@ public class Range {
|
|||||||
{
|
{
|
||||||
return randDouble(Calc.rand);
|
return randDouble(Calc.rand);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get random integer from range
|
* Get random integer from range
|
||||||
*
|
*
|
||||||
@@ -146,8 +146,8 @@ public class Range {
|
|||||||
{
|
{
|
||||||
return Calc.randInt(rand, (int) Math.round(min), (int) Math.round(min));
|
return Calc.randInt(rand, (int) Math.round(min), (int) Math.round(min));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get random double from this range
|
* Get random double from this range
|
||||||
*
|
*
|
||||||
@@ -158,8 +158,8 @@ public class Range {
|
|||||||
{
|
{
|
||||||
return min + rand.nextDouble() * (max - min);
|
return min + rand.nextDouble() * (max - min);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get min
|
* Get min
|
||||||
*
|
*
|
||||||
@@ -169,8 +169,8 @@ public class Range {
|
|||||||
{
|
{
|
||||||
return min;
|
return min;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get max
|
* Get max
|
||||||
*
|
*
|
||||||
@@ -180,8 +180,8 @@ public class Range {
|
|||||||
{
|
{
|
||||||
return max;
|
return max;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set min
|
* Set min
|
||||||
*
|
*
|
||||||
@@ -192,8 +192,8 @@ public class Range {
|
|||||||
this.min = min;
|
this.min = min;
|
||||||
norm();
|
norm();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set max
|
* Set max
|
||||||
*
|
*
|
||||||
@@ -204,8 +204,8 @@ public class Range {
|
|||||||
this.max = max;
|
this.max = max;
|
||||||
norm();
|
norm();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get identical copy
|
* Get identical copy
|
||||||
*
|
*
|
||||||
@@ -215,8 +215,8 @@ public class Range {
|
|||||||
{
|
{
|
||||||
return new Range(min, max);
|
return new Range(min, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set to value of other range
|
* Set to value of other range
|
||||||
*
|
*
|
||||||
@@ -229,8 +229,8 @@ public class Range {
|
|||||||
max = other.max;
|
max = other.max;
|
||||||
norm();
|
norm();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set to min-max values
|
* Set to min-max values
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -13,59 +13,59 @@ import mightypork.utils.math.constraints.vect.VectConst;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class Coord {
|
public class Coord {
|
||||||
|
|
||||||
public int x;
|
public int x;
|
||||||
public int y;
|
public int y;
|
||||||
|
|
||||||
|
|
||||||
@FactoryMethod
|
@FactoryMethod
|
||||||
public static Coord make(int x, int y)
|
public static Coord make(int x, int y)
|
||||||
{
|
{
|
||||||
return new Coord(x, y);
|
return new Coord(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@FactoryMethod
|
@FactoryMethod
|
||||||
public static Coord make(Coord other)
|
public static Coord make(Coord other)
|
||||||
{
|
{
|
||||||
return new Coord(other);
|
return new Coord(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@FactoryMethod
|
@FactoryMethod
|
||||||
public static Coord zero()
|
public static Coord zero()
|
||||||
{
|
{
|
||||||
return make(0, 0);
|
return make(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Coord()
|
public Coord()
|
||||||
{
|
{
|
||||||
// for ion
|
// for ion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Coord(int x, int y)
|
public Coord(int x, int y)
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.y = y;
|
this.y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Coord(Coord other)
|
public Coord(Coord other)
|
||||||
{
|
{
|
||||||
this.x = other.x;
|
this.x = other.x;
|
||||||
this.y = other.y;
|
this.y = other.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Coord add(int addX, int addY)
|
public Coord add(int addX, int addY)
|
||||||
{
|
{
|
||||||
return new Coord(x + addX, y + addY);
|
return new Coord(x + addX, y + addY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add other coord in a copy
|
* Add other coord in a copy
|
||||||
*
|
*
|
||||||
@@ -76,33 +76,33 @@ public class Coord {
|
|||||||
{
|
{
|
||||||
return add(added.x, added.y);
|
return add(added.x, added.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Coord add(Move added)
|
public Coord add(Move added)
|
||||||
{
|
{
|
||||||
return add(added.x(), added.y());
|
return add(added.x(), added.y());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Coord copy()
|
public Coord copy()
|
||||||
{
|
{
|
||||||
return make(this);
|
return make(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setTo(int x, int y)
|
public void setTo(int x, int y)
|
||||||
{
|
{
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.y = y;
|
this.y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setTo(Coord pos)
|
public void setTo(Coord pos)
|
||||||
{
|
{
|
||||||
setTo(pos.x, pos.y);
|
setTo(pos.x, pos.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if coord is in a range (inclusive)
|
* Check if coord is in a range (inclusive)
|
||||||
*
|
*
|
||||||
@@ -116,27 +116,27 @@ public class Coord {
|
|||||||
{
|
{
|
||||||
return !(x < x0 || x > x1 || y < y0 || y > y1);
|
return !(x < x0 || x > x1 || y < y0 || y > y1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public double dist(Coord coord)
|
public double dist(Coord coord)
|
||||||
{
|
{
|
||||||
return Calc.dist(x, y, coord.x, coord.y);
|
return Calc.dist(x, y, coord.x, coord.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public VectConst toVect()
|
public VectConst toVect()
|
||||||
{
|
{
|
||||||
return Vect.make(x, y);
|
return Vect.make(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return "Coord(" + x + "," + y + ")";
|
return "Coord(" + x + "," + y + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode()
|
public int hashCode()
|
||||||
{
|
{
|
||||||
@@ -146,8 +146,8 @@ public class Coord {
|
|||||||
result = prime * result + y;
|
result = prime * result + y;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj)
|
public boolean equals(Object obj)
|
||||||
{
|
{
|
||||||
@@ -159,8 +159,8 @@ public class Coord {
|
|||||||
if (y != other.y) return false;
|
if (y != other.y) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static Coord fromVect(Vect vect)
|
public static Coord fromVect(Vect vect)
|
||||||
{
|
{
|
||||||
return make((int) Math.floor(vect.x()), (int) Math.floor(vect.y()));
|
return make((int) Math.floor(vect.x()), (int) Math.floor(vect.y()));
|
||||||
|
|||||||
@@ -8,57 +8,57 @@ package mightypork.utils.math.algo;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class Move {
|
public class Move {
|
||||||
|
|
||||||
public static final Move NORTH = new Move(0, -1);
|
public static final Move NORTH = new Move(0, -1);
|
||||||
public static final Move SOUTH = 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 EAST = new Move(1, 0);
|
||||||
public static final Move WEST = new Move(-1, 0);
|
public static final Move WEST = new Move(-1, 0);
|
||||||
public static final Move NONE = new Move(0, 0);
|
public static final Move NONE = new Move(0, 0);
|
||||||
|
|
||||||
|
|
||||||
public static Move make(int x, int y)
|
public static Move make(int x, int y)
|
||||||
{
|
{
|
||||||
x = x < 0 ? -1 : x > 0 ? 1 : 0;
|
x = x < 0 ? -1 : x > 0 ? 1 : 0;
|
||||||
y = y < 0 ? -1 : y > 0 ? 1 : 0;
|
y = y < 0 ? -1 : y > 0 ? 1 : 0;
|
||||||
|
|
||||||
if (y == -1 && x == 0) return NORTH;
|
if (y == -1 && x == 0) return NORTH;
|
||||||
if (y == 1 && x == 0) return SOUTH;
|
if (y == 1 && x == 0) return SOUTH;
|
||||||
if (x == -1 && y == 0) return WEST;
|
if (x == -1 && y == 0) return WEST;
|
||||||
if (x == 1 && y == 0) return EAST;
|
if (x == 1 && y == 0) return EAST;
|
||||||
if (x == 0 && y == 0) return NONE;
|
if (x == 0 && y == 0) return NONE;
|
||||||
|
|
||||||
return new Move(x, y);
|
return new Move(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final byte x;
|
private final byte x;
|
||||||
private final byte y;
|
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.x = (byte) (x < 0 ? -1 : x > 0 ? 1 : 0);
|
||||||
this.y = (byte) (y < 0 ? -1 : y > 0 ? 1 : 0);
|
this.y = (byte) (y < 0 ? -1 : y > 0 ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public int x()
|
public int x()
|
||||||
{
|
{
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public int y()
|
public int y()
|
||||||
{
|
{
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Coord toCoord()
|
public Coord toCoord()
|
||||||
{
|
{
|
||||||
return Coord.make(x, y);
|
return Coord.make(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import mightypork.utils.math.Calc;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class Moves {
|
public class Moves {
|
||||||
|
|
||||||
public static final byte BIT_NW = (byte) 0b10000000;
|
public static final byte BIT_NW = (byte) 0b10000000;
|
||||||
public static final byte BIT_N = (byte) 0b01000000;
|
public static final byte BIT_N = (byte) 0b01000000;
|
||||||
public static final byte BIT_NE = (byte) 0b00100000;
|
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_S = (byte) 0b00000100;
|
||||||
public static final byte BIT_SW = (byte) 0b00000010;
|
public static final byte BIT_SW = (byte) 0b00000010;
|
||||||
public static final byte BIT_W = (byte) 0b00000001;
|
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_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_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_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_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_SW_CORNER = BIT_W | BIT_SW | BIT_S;
|
||||||
public static final byte BITS_SE_CORNER = BIT_E | BIT_SE | 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 NW = Move.make(-1, -1);
|
||||||
public static final Move N = Move.make(0, -1);
|
public static final Move N = Move.make(0, -1);
|
||||||
public static final Move NE = Move.make(1, -1);
|
public static final Move NE = Move.make(1, -1);
|
||||||
@@ -41,7 +41,7 @@ public class Moves {
|
|||||||
public static final Move S = Move.make(0, 1);
|
public static final Move S = Move.make(0, 1);
|
||||||
public static final Move SW = Move.make(-1, 1);
|
public static final Move SW = Move.make(-1, 1);
|
||||||
public static final Move W = Move.make(-1, 0);
|
public static final Move W = Move.make(-1, 0);
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
/** All sides, in the order of bits. */
|
/** All sides, in the order of bits. */
|
||||||
public final static List<Move> ALL_SIDES = Collections.unmodifiableList(Arrays.asList(
|
public final static List<Move> ALL_SIDES = Collections.unmodifiableList(Arrays.asList(
|
||||||
@@ -54,16 +54,16 @@ public class Moves {
|
|||||||
SW,
|
SW,
|
||||||
W
|
W
|
||||||
));
|
));
|
||||||
|
|
||||||
public final static List<Move> CARDINAL_SIDES = Collections.unmodifiableList(Arrays.asList(
|
public final static List<Move> CARDINAL_SIDES = Collections.unmodifiableList(Arrays.asList(
|
||||||
N,
|
N,
|
||||||
E,
|
E,
|
||||||
S,
|
S,
|
||||||
W
|
W
|
||||||
));
|
));
|
||||||
|
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get element from all sides
|
* Get element from all sides
|
||||||
*
|
*
|
||||||
@@ -74,20 +74,20 @@ public class Moves {
|
|||||||
{
|
{
|
||||||
return ALL_SIDES.get(i);
|
return ALL_SIDES.get(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static byte getBit(int i)
|
public static byte getBit(int i)
|
||||||
{
|
{
|
||||||
return (byte) (1 << (7 - i));
|
return (byte) (1 << (7 - i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static Move randomCardinal()
|
public static Move randomCardinal()
|
||||||
{
|
{
|
||||||
return Calc.pick(CARDINAL_SIDES);
|
return Calc.pick(CARDINAL_SIDES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static Move randomCardinal(Random rand)
|
public static Move randomCardinal(Random rand)
|
||||||
{
|
{
|
||||||
return Calc.pick(rand, CARDINAL_SIDES);
|
return Calc.pick(rand, CARDINAL_SIDES);
|
||||||
|
|||||||
@@ -11,30 +11,30 @@ import mightypork.utils.math.algo.Move;
|
|||||||
|
|
||||||
|
|
||||||
public abstract class FloodFill {
|
public abstract class FloodFill {
|
||||||
|
|
||||||
public abstract boolean canEnter(Coord pos);
|
public abstract boolean canEnter(Coord pos);
|
||||||
|
|
||||||
|
|
||||||
public abstract boolean canSpreadFrom(Coord pos);
|
public abstract boolean canSpreadFrom(Coord pos);
|
||||||
|
|
||||||
|
|
||||||
public abstract List<Move> getSpreadSides();
|
public abstract List<Move> getSpreadSides();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the max distance filled form start point. Use -1 for unlimited range.
|
* Get the max distance filled form start point. Use -1 for unlimited range.
|
||||||
*
|
*
|
||||||
* @return max distance
|
* @return max distance
|
||||||
*/
|
*/
|
||||||
public abstract double getMaxDistance();
|
public abstract double getMaxDistance();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if start should be spread no matter what
|
* @return true if start should be spread no matter what
|
||||||
*/
|
*/
|
||||||
public abstract boolean forceSpreadStart();
|
public abstract boolean forceSpreadStart();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fill an area
|
* Fill an area
|
||||||
*
|
*
|
||||||
@@ -45,32 +45,32 @@ public abstract class FloodFill {
|
|||||||
public final boolean fill(Coord start, Collection<Coord> foundNodes)
|
public final boolean fill(Coord start, Collection<Coord> foundNodes)
|
||||||
{
|
{
|
||||||
final Queue<Coord> activeNodes = new LinkedList<>();
|
final Queue<Coord> activeNodes = new LinkedList<>();
|
||||||
|
|
||||||
final double maxDist = getMaxDistance();
|
final double maxDist = getMaxDistance();
|
||||||
|
|
||||||
activeNodes.add(start);
|
activeNodes.add(start);
|
||||||
|
|
||||||
boolean forceSpreadNext = forceSpreadStart();
|
boolean forceSpreadNext = forceSpreadStart();
|
||||||
|
|
||||||
boolean limitReached = false;
|
boolean limitReached = false;
|
||||||
|
|
||||||
while (!activeNodes.isEmpty()) {
|
while (!activeNodes.isEmpty()) {
|
||||||
final Coord current = activeNodes.poll();
|
final Coord current = activeNodes.poll();
|
||||||
foundNodes.add(current);
|
foundNodes.add(current);
|
||||||
|
|
||||||
if (!canSpreadFrom(current) && !forceSpreadNext) continue;
|
if (!canSpreadFrom(current) && !forceSpreadNext) continue;
|
||||||
|
|
||||||
forceSpreadNext = false;
|
forceSpreadNext = false;
|
||||||
|
|
||||||
for (final Move spr : getSpreadSides()) {
|
for (final Move spr : getSpreadSides()) {
|
||||||
final Coord next = current.add(spr);
|
final Coord next = current.add(spr);
|
||||||
if (activeNodes.contains(next) || foundNodes.contains(next)) continue;
|
if (activeNodes.contains(next) || foundNodes.contains(next)) continue;
|
||||||
|
|
||||||
if (next.dist(start) > maxDist) {
|
if (next.dist(start) > maxDist) {
|
||||||
limitReached = true;
|
limitReached = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canEnter(next)) {
|
if (canEnter(next)) {
|
||||||
activeNodes.add(next);
|
activeNodes.add(next);
|
||||||
} else {
|
} else {
|
||||||
@@ -78,7 +78,7 @@ public abstract class FloodFill {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return !limitReached;
|
return !limitReached;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import mightypork.utils.math.algo.Coord;
|
|||||||
|
|
||||||
|
|
||||||
public abstract class Heuristic {
|
public abstract class Heuristic {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get tile cost (estimate of how many tiles remain to the target)
|
* Get tile cost (estimate of how many tiles remain to the target)
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -19,30 +19,30 @@ import mightypork.utils.math.algo.pathfinding.heuristics.ManhattanHeuristic;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public abstract class PathFinder {
|
public abstract class PathFinder {
|
||||||
|
|
||||||
private static final FComparator F_COMPARATOR = new FComparator();
|
private static final FComparator F_COMPARATOR = new FComparator();
|
||||||
|
|
||||||
public static final Heuristic CORNER_HEURISTIC = new ManhattanHeuristic();
|
public static final Heuristic CORNER_HEURISTIC = new ManhattanHeuristic();
|
||||||
public static final Heuristic DIAGONAL_HEURISTIC = new DiagonalHeuristic();
|
public static final Heuristic DIAGONAL_HEURISTIC = new DiagonalHeuristic();
|
||||||
|
|
||||||
private boolean ignoreStart;
|
private boolean ignoreStart;
|
||||||
private boolean ignoreEnd;
|
private boolean ignoreEnd;
|
||||||
|
|
||||||
|
|
||||||
public List<Move> findPathRelative(Coord start, Coord end)
|
public List<Move> findPathRelative(Coord start, Coord end)
|
||||||
{
|
{
|
||||||
return findPathRelative(start, end, ignoreStart, ignoreEnd);
|
return findPathRelative(start, end, ignoreStart, ignoreEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public List<Move> findPathRelative(Coord start, Coord end, boolean ignoreStart, boolean ignoreEnd)
|
public List<Move> findPathRelative(Coord start, Coord end, boolean ignoreStart, boolean ignoreEnd)
|
||||||
{
|
{
|
||||||
final List<Coord> path = findPath(start, end, ignoreStart, ignoreEnd);
|
final List<Coord> path = findPath(start, end, ignoreStart, ignoreEnd);
|
||||||
|
|
||||||
if (path == null) return null;
|
if (path == null) return null;
|
||||||
|
|
||||||
final List<Move> out = new ArrayList<>();
|
final List<Move> out = new ArrayList<>();
|
||||||
|
|
||||||
final Coord current = start.copy();
|
final Coord current = start.copy();
|
||||||
for (final Coord c : path) {
|
for (final Coord c : path) {
|
||||||
if (c.equals(current)) continue;
|
if (c.equals(current)) continue;
|
||||||
@@ -50,24 +50,24 @@ public abstract class PathFinder {
|
|||||||
current.x = c.x;
|
current.x = c.x;
|
||||||
current.y = c.y;
|
current.y = c.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public List<Coord> findPath(Coord start, Coord end)
|
public List<Coord> findPath(Coord start, Coord end)
|
||||||
{
|
{
|
||||||
return findPath(start, end, ignoreStart, ignoreEnd);
|
return findPath(start, end, ignoreStart, ignoreEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public List<Coord> findPath(Coord start, Coord end, boolean ignoreStart, boolean ignoreEnd)
|
public List<Coord> findPath(Coord start, Coord end, boolean ignoreStart, boolean ignoreEnd)
|
||||||
{
|
{
|
||||||
final LinkedList<Node> open = new LinkedList<>();
|
final LinkedList<Node> open = new LinkedList<>();
|
||||||
final LinkedList<Node> closed = new LinkedList<>();
|
final LinkedList<Node> closed = new LinkedList<>();
|
||||||
|
|
||||||
final Heuristic heuristic = getHeuristic();
|
final Heuristic heuristic = getHeuristic();
|
||||||
|
|
||||||
// add first node
|
// add first node
|
||||||
{
|
{
|
||||||
final Node n = new Node(start);
|
final Node n = new Node(start);
|
||||||
@@ -75,37 +75,37 @@ public abstract class PathFinder {
|
|||||||
n.g_cost = 0;
|
n.g_cost = 0;
|
||||||
open.add(n);
|
open.add(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
Node current = null;
|
Node current = null;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
current = open.poll();
|
current = open.poll();
|
||||||
|
|
||||||
if (current == null) {
|
if (current == null) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
closed.add(current);
|
closed.add(current);
|
||||||
|
|
||||||
if (current.pos.equals(end)) {
|
if (current.pos.equals(end)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final Move go : getWalkSides()) {
|
for (final Move go : getWalkSides()) {
|
||||||
|
|
||||||
final Coord c = current.pos.add(go);
|
final Coord c = current.pos.add(go);
|
||||||
if (!isAccessible(c) && !(c.equals(end) && ignoreEnd) && !(c.equals(start) && ignoreStart)) continue;
|
if (!isAccessible(c) && !(c.equals(end) && ignoreEnd) && !(c.equals(start) && ignoreStart)) continue;
|
||||||
final Node a = new Node(c);
|
final Node a = new Node(c);
|
||||||
a.g_cost = current.g_cost + getCost(c, a.pos);
|
a.g_cost = current.g_cost + getCost(c, a.pos);
|
||||||
a.h_cost = (int) (heuristic.getCost(a.pos, end) * getMinCost());
|
a.h_cost = (int) (heuristic.getCost(a.pos, end) * getMinCost());
|
||||||
a.parent = current;
|
a.parent = current;
|
||||||
|
|
||||||
if (!closed.contains(a)) {
|
if (!closed.contains(a)) {
|
||||||
|
|
||||||
if (open.contains(a)) {
|
if (open.contains(a)) {
|
||||||
|
|
||||||
boolean needSort = false;
|
boolean needSort = false;
|
||||||
|
|
||||||
// find where it is
|
// find where it is
|
||||||
for (final Node n : open) {
|
for (final Node n : open) {
|
||||||
if (n.pos.equals(a.pos)) { // found it
|
if (n.pos.equals(a.pos)) { // found it
|
||||||
@@ -117,52 +117,52 @@ public abstract class PathFinder {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needSort) Collections.sort(open, F_COMPARATOR);
|
if (needSort) Collections.sort(open, F_COMPARATOR);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
open.add(a);
|
open.add(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current == null) {
|
if (current == null) {
|
||||||
return null; // no path found
|
return null; // no path found
|
||||||
}
|
}
|
||||||
|
|
||||||
final LinkedList<Coord> path = new LinkedList<>();
|
final LinkedList<Coord> path = new LinkedList<>();
|
||||||
|
|
||||||
// extract path elements
|
// extract path elements
|
||||||
while (current != null) {
|
while (current != null) {
|
||||||
path.addFirst(current.pos);
|
path.addFirst(current.pos);
|
||||||
current = current.parent;
|
current = current.parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Node {
|
private static class Node {
|
||||||
|
|
||||||
Coord pos;
|
Coord pos;
|
||||||
int g_cost; // to get there
|
int g_cost; // to get there
|
||||||
int h_cost; // to target
|
int h_cost; // to target
|
||||||
Node parent;
|
Node parent;
|
||||||
|
|
||||||
|
|
||||||
public Node(Coord pos)
|
public Node(Coord pos)
|
||||||
{
|
{
|
||||||
this.pos = pos;
|
this.pos = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int fCost()
|
int fCost()
|
||||||
{
|
{
|
||||||
return g_cost + h_cost;
|
return g_cost + h_cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode()
|
public int hashCode()
|
||||||
{
|
{
|
||||||
@@ -171,8 +171,8 @@ public abstract class PathFinder {
|
|||||||
result = prime * result + ((pos == null) ? 0 : pos.hashCode());
|
result = prime * result + ((pos == null) ? 0 : pos.hashCode());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj)
|
public boolean equals(Object obj)
|
||||||
{
|
{
|
||||||
@@ -185,53 +185,53 @@ public abstract class PathFinder {
|
|||||||
} else if (!pos.equals(other.pos)) return false;
|
} else if (!pos.equals(other.pos)) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return "N " + pos + ", G =" + g_cost + ", H = " + h_cost;
|
return "N " + pos + ", G =" + g_cost + ", H = " + h_cost;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class FComparator implements Comparator<Node> {
|
private static class FComparator implements Comparator<Node> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compare(Node n1, Node n2)
|
public int compare(Node n1, Node n2)
|
||||||
{
|
{
|
||||||
return n1.fCost() - n2.fCost();
|
return n1.fCost() - n2.fCost();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setIgnoreEnd(boolean ignoreEnd)
|
public void setIgnoreEnd(boolean ignoreEnd)
|
||||||
{
|
{
|
||||||
this.ignoreEnd = ignoreEnd;
|
this.ignoreEnd = ignoreEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setIgnoreStart(boolean ignoreStart)
|
public void setIgnoreStart(boolean ignoreStart)
|
||||||
{
|
{
|
||||||
this.ignoreStart = ignoreStart;
|
this.ignoreStart = ignoreStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return used heuristic
|
* @return used heuristic
|
||||||
*/
|
*/
|
||||||
protected abstract Heuristic getHeuristic();
|
protected abstract Heuristic getHeuristic();
|
||||||
|
|
||||||
|
|
||||||
protected abstract List<Move> getWalkSides();
|
protected abstract List<Move> getWalkSides();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param pos tile pos
|
* @param pos tile pos
|
||||||
* @return true if the tile is walkable
|
* @return true if the tile is walkable
|
||||||
*/
|
*/
|
||||||
public abstract boolean isAccessible(Coord pos);
|
public abstract boolean isAccessible(Coord pos);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cost of walking onto a tile. It's useful to use ie. 10 for basic step.
|
* Cost of walking onto a tile. It's useful to use ie. 10 for basic step.
|
||||||
*
|
*
|
||||||
@@ -240,8 +240,8 @@ public abstract class PathFinder {
|
|||||||
* @return cost
|
* @return cost
|
||||||
*/
|
*/
|
||||||
protected abstract int getCost(Coord from, Coord to);
|
protected abstract int getCost(Coord from, Coord to);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return lowest cost. Used to multiply heuristics.
|
* @return lowest cost. Used to multiply heuristics.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -14,48 +14,48 @@ import mightypork.utils.math.algo.Move;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class PathFinderProxy extends PathFinder {
|
public class PathFinderProxy extends PathFinder {
|
||||||
|
|
||||||
private final PathFinder source;
|
private final PathFinder source;
|
||||||
|
|
||||||
|
|
||||||
public PathFinderProxy(PathFinder other)
|
public PathFinderProxy(PathFinder other)
|
||||||
{
|
{
|
||||||
this.source = other;
|
this.source = other;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAccessible(Coord pos)
|
public boolean isAccessible(Coord pos)
|
||||||
{
|
{
|
||||||
return source.isAccessible(pos);
|
return source.isAccessible(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getCost(Coord from, Coord to)
|
public int getCost(Coord from, Coord to)
|
||||||
{
|
{
|
||||||
return source.getCost(from, to);
|
return source.getCost(from, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMinCost()
|
public int getMinCost()
|
||||||
{
|
{
|
||||||
return source.getMinCost();
|
return source.getMinCost();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Heuristic getHeuristic()
|
protected Heuristic getHeuristic()
|
||||||
{
|
{
|
||||||
return source.getHeuristic();
|
return source.getHeuristic();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<Move> getWalkSides()
|
protected List<Move> getWalkSides()
|
||||||
{
|
{
|
||||||
return source.getWalkSides();
|
return source.getWalkSides();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import mightypork.utils.math.algo.pathfinding.Heuristic;
|
|||||||
|
|
||||||
|
|
||||||
public class DiagonalHeuristic extends Heuristic {
|
public class DiagonalHeuristic extends Heuristic {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getCost(Coord pos, Coord target)
|
public double getCost(Coord pos, Coord target)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import mightypork.utils.math.algo.pathfinding.Heuristic;
|
|||||||
|
|
||||||
|
|
||||||
public class ManhattanHeuristic extends Heuristic {
|
public class ManhattanHeuristic extends Heuristic {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getCost(Coord pos, Coord target)
|
public double getCost(Coord pos, Coord target)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ package mightypork.utils.math.angles;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
class Angles {
|
class Angles {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delta of two angles (positive or negative - positive is CCW)
|
* Delta of two angles (positive or negative - positive is CCW)
|
||||||
*
|
*
|
||||||
@@ -22,11 +22,11 @@ class Angles {
|
|||||||
alpha = norm(alpha + fullAngle / 2D, fullAngle);
|
alpha = norm(alpha + fullAngle / 2D, fullAngle);
|
||||||
beta = norm(beta + fullAngle / 2D, fullAngle);
|
beta = norm(beta + fullAngle / 2D, fullAngle);
|
||||||
}
|
}
|
||||||
|
|
||||||
return beta - alpha;
|
return beta - alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Difference of two angles (same as delta, but always positive)
|
* Difference of two angles (same as delta, but always positive)
|
||||||
*
|
*
|
||||||
@@ -39,8 +39,8 @@ class Angles {
|
|||||||
{
|
{
|
||||||
return Math.abs(delta(alpha, beta, fullAngle));
|
return Math.abs(delta(alpha, beta, fullAngle));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Normalize angle to 0-full range
|
* Normalize angle to 0-full range
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ package mightypork.utils.math.angles;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class Deg {
|
public class Deg {
|
||||||
|
|
||||||
/** 180° in degrees */
|
/** 180° in degrees */
|
||||||
public static final double a180 = 180;
|
public static final double a180 = 180;
|
||||||
/** 270° in degrees */
|
/** 270° in degrees */
|
||||||
@@ -18,8 +18,8 @@ public class Deg {
|
|||||||
public static final double a45 = 45;
|
public static final double a45 = 45;
|
||||||
/** 90° in degrees */
|
/** 90° in degrees */
|
||||||
public static final double a90 = 90;
|
public static final double a90 = 90;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subtract two angles alpha - beta
|
* Subtract two angles alpha - beta
|
||||||
*
|
*
|
||||||
@@ -31,8 +31,8 @@ public class Deg {
|
|||||||
{
|
{
|
||||||
return Angles.delta(alpha, beta, a360);
|
return Angles.delta(alpha, beta, a360);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Difference of two angles (absolute value of delta)
|
* Difference of two angles (absolute value of delta)
|
||||||
*
|
*
|
||||||
@@ -44,8 +44,8 @@ public class Deg {
|
|||||||
{
|
{
|
||||||
return Angles.diff(alpha, beta, a360);
|
return Angles.diff(alpha, beta, a360);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cosinus in degrees
|
* Cosinus in degrees
|
||||||
*
|
*
|
||||||
@@ -56,8 +56,8 @@ public class Deg {
|
|||||||
{
|
{
|
||||||
return Math.cos(toRad(deg));
|
return Math.cos(toRad(deg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sinus in degrees
|
* Sinus in degrees
|
||||||
*
|
*
|
||||||
@@ -68,8 +68,8 @@ public class Deg {
|
|||||||
{
|
{
|
||||||
return Math.sin(toRad(deg));
|
return Math.sin(toRad(deg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tangents in degrees
|
* Tangents in degrees
|
||||||
*
|
*
|
||||||
@@ -80,8 +80,8 @@ public class Deg {
|
|||||||
{
|
{
|
||||||
return Math.tan(toRad(deg));
|
return Math.tan(toRad(deg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Angle normalized to 0-360 range
|
* Angle normalized to 0-360 range
|
||||||
*
|
*
|
||||||
@@ -92,8 +92,8 @@ public class Deg {
|
|||||||
{
|
{
|
||||||
return Angles.norm(angle, a360);
|
return Angles.norm(angle, a360);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert to radians
|
* Convert to radians
|
||||||
*
|
*
|
||||||
@@ -104,8 +104,8 @@ public class Deg {
|
|||||||
{
|
{
|
||||||
return Math.toRadians(deg);
|
return Math.toRadians(deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Round angle to 0,45,90,135...
|
* Round angle to 0,45,90,135...
|
||||||
*
|
*
|
||||||
@@ -123,8 +123,8 @@ public class Deg {
|
|||||||
if (a == 360) a = 0;
|
if (a == 360) a = 0;
|
||||||
return (int) Math.round(a);
|
return (int) Math.round(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Round angle to 0,15,30,45,60,75,90...
|
* Round angle to 0,15,30,45,60,75,90...
|
||||||
*
|
*
|
||||||
@@ -135,8 +135,8 @@ public class Deg {
|
|||||||
{
|
{
|
||||||
return roundToIncrement(deg, 15);
|
return roundToIncrement(deg, 15);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Round angle to 0,45,90,135...
|
* Round angle to 0,45,90,135...
|
||||||
*
|
*
|
||||||
@@ -147,8 +147,8 @@ public class Deg {
|
|||||||
{
|
{
|
||||||
return roundToIncrement(deg, 45);
|
return roundToIncrement(deg, 45);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Round angle to 0,90,180,270
|
* Round angle to 0,90,180,270
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ package mightypork.utils.math.angles;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class Rad {
|
public class Rad {
|
||||||
|
|
||||||
/** 180° in radians */
|
/** 180° in radians */
|
||||||
public static final double a180 = Math.PI;
|
public static final double a180 = Math.PI;
|
||||||
/** 270° in radians */
|
/** 270° in radians */
|
||||||
@@ -18,8 +18,8 @@ public class Rad {
|
|||||||
public static final double a45 = Math.PI / 4D;
|
public static final double a45 = Math.PI / 4D;
|
||||||
/** 90° in radians */
|
/** 90° in radians */
|
||||||
public static final double a90 = Math.PI / 2D;
|
public static final double a90 = Math.PI / 2D;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subtract two angles alpha - beta
|
* Subtract two angles alpha - beta
|
||||||
*
|
*
|
||||||
@@ -31,8 +31,8 @@ public class Rad {
|
|||||||
{
|
{
|
||||||
return Angles.delta(alpha, beta, a360);
|
return Angles.delta(alpha, beta, a360);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Difference of two angles (absolute value of delta)
|
* Difference of two angles (absolute value of delta)
|
||||||
*
|
*
|
||||||
@@ -44,8 +44,8 @@ public class Rad {
|
|||||||
{
|
{
|
||||||
return Angles.delta(alpha, beta, a360);
|
return Angles.delta(alpha, beta, a360);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cos
|
* Cos
|
||||||
*
|
*
|
||||||
@@ -56,8 +56,8 @@ public class Rad {
|
|||||||
{
|
{
|
||||||
return Math.cos(rad);
|
return Math.cos(rad);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sin
|
* Sin
|
||||||
*
|
*
|
||||||
@@ -68,8 +68,8 @@ public class Rad {
|
|||||||
{
|
{
|
||||||
return Math.sin(rad);
|
return Math.sin(rad);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tan
|
* Tan
|
||||||
*
|
*
|
||||||
@@ -80,8 +80,8 @@ public class Rad {
|
|||||||
{
|
{
|
||||||
return Math.tan(rad);
|
return Math.tan(rad);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Angle normalized to 0-2*PI range
|
* Angle normalized to 0-2*PI range
|
||||||
*
|
*
|
||||||
@@ -92,8 +92,8 @@ public class Rad {
|
|||||||
{
|
{
|
||||||
return Angles.norm(angle, a360);
|
return Angles.norm(angle, a360);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert to degrees
|
* Convert to degrees
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -10,128 +10,128 @@ import mightypork.utils.math.constraints.num.NumBound;
|
|||||||
|
|
||||||
|
|
||||||
public abstract class Animator implements NumBound, Updateable, Pauseable {
|
public abstract class Animator implements NumBound, Updateable, Pauseable {
|
||||||
|
|
||||||
private final NumAnimated numAnim;
|
private final NumAnimated numAnim;
|
||||||
private final Num animatorValue;
|
private final Num animatorValue;
|
||||||
private final double highValue;
|
private final double highValue;
|
||||||
private final double lowValue;
|
private final double lowValue;
|
||||||
|
|
||||||
|
|
||||||
public Animator(double period)
|
public Animator(double period)
|
||||||
{
|
{
|
||||||
this(0, 1, period, Easing.LINEAR);
|
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);
|
this(start, end, period, Easing.LINEAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Animator(double period, Easing easing)
|
public Animator(double period, Easing easing)
|
||||||
{
|
{
|
||||||
this(0, 1, period, 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 = new NumAnimated(0, easing);
|
||||||
numAnim.setDefaultDuration(period);
|
numAnim.setDefaultDuration(period);
|
||||||
|
|
||||||
this.lowValue = start;
|
this.lowValue = start;
|
||||||
this.highValue = end;
|
this.highValue = end;
|
||||||
|
|
||||||
this.animatorValue = numAnim.mul(end - start).add(start);
|
this.animatorValue = numAnim.mul(end - start).add(start);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void pause()
|
public void pause()
|
||||||
{
|
{
|
||||||
numAnim.pause();
|
numAnim.pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void start()
|
public void start()
|
||||||
{
|
{
|
||||||
resume();
|
resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resume()
|
public void resume()
|
||||||
{
|
{
|
||||||
numAnim.resume();
|
numAnim.resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPaused()
|
public boolean isPaused()
|
||||||
{
|
{
|
||||||
return numAnim.isPaused();
|
return numAnim.isPaused();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void reset()
|
public void reset()
|
||||||
{
|
{
|
||||||
numAnim.reset();
|
numAnim.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void restart()
|
public void restart()
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
resume();
|
resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setDuration(double secs)
|
public void setDuration(double secs)
|
||||||
{
|
{
|
||||||
numAnim.setDefaultDuration(secs);
|
numAnim.setDefaultDuration(secs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public double getDuration()
|
public double getDuration()
|
||||||
{
|
{
|
||||||
return numAnim.getDefaultDuration();
|
return numAnim.getDefaultDuration();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Num getNum()
|
public Num getNum()
|
||||||
{
|
{
|
||||||
return animatorValue;
|
return animatorValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public double getValue()
|
public double getValue()
|
||||||
{
|
{
|
||||||
return animatorValue.value();
|
return animatorValue.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(double delta)
|
public void update(double delta)
|
||||||
{
|
{
|
||||||
numAnim.update(delta);
|
numAnim.update(delta);
|
||||||
if (numAnim.isFinished()) nextCycle(numAnim);
|
if (numAnim.isFinished()) nextCycle(numAnim);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Stub
|
@Stub
|
||||||
protected abstract void nextCycle(NumAnimated anim);
|
protected abstract void nextCycle(NumAnimated anim);
|
||||||
|
|
||||||
|
|
||||||
public void setProgress(double value)
|
public void setProgress(double value)
|
||||||
{
|
{
|
||||||
final double target = numAnim.getEnd();
|
final double target = numAnim.getEnd();
|
||||||
numAnim.setTo(Calc.clamp(value, lowValue, highValue));
|
numAnim.setTo(Calc.clamp(value, lowValue, highValue));
|
||||||
numAnim.animate((target < value ? highValue : lowValue), target, numAnim.getDefaultDuration());
|
numAnim.animate((target < value ? highValue : lowValue), target, numAnim.getDefaultDuration());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public double getProgress()
|
public double getProgress()
|
||||||
{
|
{
|
||||||
return numAnim.value();
|
return numAnim.value();
|
||||||
|
|||||||
@@ -7,34 +7,34 @@ package mightypork.utils.math.animation;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class AnimatorBounce extends Animator {
|
public class AnimatorBounce extends Animator {
|
||||||
|
|
||||||
private boolean wasUp = false;
|
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);
|
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);
|
super(start, end, period);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public AnimatorBounce(double period, Easing easing)
|
public AnimatorBounce(double period, Easing easing)
|
||||||
{
|
{
|
||||||
super(period, easing);
|
super(period, easing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public AnimatorBounce(double period)
|
public AnimatorBounce(double period)
|
||||||
{
|
{
|
||||||
super(period);
|
super(period);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void nextCycle(NumAnimated anim)
|
protected void nextCycle(NumAnimated anim)
|
||||||
{
|
{
|
||||||
@@ -43,8 +43,8 @@ public class AnimatorBounce extends Animator {
|
|||||||
} else {
|
} else {
|
||||||
anim.fadeIn();
|
anim.fadeIn();
|
||||||
}
|
}
|
||||||
|
|
||||||
wasUp = !wasUp;
|
wasUp = !wasUp;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,36 +8,36 @@ package mightypork.utils.math.animation;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class AnimatorRewind extends Animator {
|
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);
|
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);
|
super(start, end, period);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public AnimatorRewind(double period, Easing easing)
|
public AnimatorRewind(double period, Easing easing)
|
||||||
{
|
{
|
||||||
super(period, easing);
|
super(period, easing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public AnimatorRewind(double period)
|
public AnimatorRewind(double period)
|
||||||
{
|
{
|
||||||
super(period);
|
super(period);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void nextCycle(NumAnimated anim)
|
protected void nextCycle(NumAnimated anim)
|
||||||
{
|
{
|
||||||
anim.reset();
|
anim.reset();
|
||||||
anim.fadeIn();
|
anim.fadeIn();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ package mightypork.utils.math.animation;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public abstract class Easing {
|
public abstract class Easing {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get value at time t.
|
* Get value at time t.
|
||||||
*
|
*
|
||||||
@@ -15,8 +15,8 @@ public abstract class Easing {
|
|||||||
* @return value at given t (0..1, can exceed if needed)
|
* @return value at given t (0..1, can exceed if needed)
|
||||||
*/
|
*/
|
||||||
public abstract double get(double t);
|
public abstract double get(double t);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reverse an easing (factory method)
|
* Reverse an easing (factory method)
|
||||||
*
|
*
|
||||||
@@ -27,8 +27,8 @@ public abstract class Easing {
|
|||||||
{
|
{
|
||||||
return new Reverse(original);
|
return new Reverse(original);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Combine two easings (factory method)
|
* Combine two easings (factory method)
|
||||||
*
|
*
|
||||||
@@ -40,8 +40,8 @@ public abstract class Easing {
|
|||||||
{
|
{
|
||||||
return new Composite(in, out);
|
return new Composite(in, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create "bilinear" easing - compose of straight and reverse. (factory
|
* Create "bilinear" easing - compose of straight and reverse. (factory
|
||||||
* method)
|
* method)
|
||||||
@@ -53,17 +53,17 @@ public abstract class Easing {
|
|||||||
{
|
{
|
||||||
return combine(in, reverse(in));
|
return combine(in, reverse(in));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reverse EasingFunction
|
* Reverse EasingFunction
|
||||||
*
|
*
|
||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
private static class Reverse extends Easing {
|
private static class Reverse extends Easing {
|
||||||
|
|
||||||
private final Easing ea;
|
private final Easing ea;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param in Easing to reverse
|
* @param in Easing to reverse
|
||||||
*/
|
*/
|
||||||
@@ -71,26 +71,26 @@ public abstract class Easing {
|
|||||||
{
|
{
|
||||||
this.ea = in;
|
this.ea = in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double get(double t)
|
public double get(double t)
|
||||||
{
|
{
|
||||||
return 1 - ea.get(1 - t);
|
return 1 - ea.get(1 - t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Composite EasingFunction (0-0.5 EasingFunction A, 0.5-1 EasingFunction B)
|
* Composite EasingFunction (0-0.5 EasingFunction A, 0.5-1 EasingFunction B)
|
||||||
*
|
*
|
||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
private static class Composite extends Easing {
|
private static class Composite extends Easing {
|
||||||
|
|
||||||
private final Easing in;
|
private final Easing in;
|
||||||
private final Easing out;
|
private final Easing out;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a composite EasingFunction
|
* Create a composite EasingFunction
|
||||||
*
|
*
|
||||||
@@ -102,8 +102,8 @@ public abstract class Easing {
|
|||||||
this.in = in;
|
this.in = in;
|
||||||
this.out = out;
|
this.out = out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double get(double t)
|
public double get(double t)
|
||||||
{
|
{
|
||||||
@@ -111,172 +111,172 @@ public abstract class Easing {
|
|||||||
return 0.5 + out.get(2 * t - 1) * 0.5;
|
return 0.5 + out.get(2 * t - 1) * 0.5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** No easing; At t=0.5 goes high. */
|
/** No easing; At t=0.5 goes high. */
|
||||||
public static final Easing NONE = new Easing() {
|
public static final Easing NONE = new Easing() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double get(double t)
|
public double get(double t)
|
||||||
{
|
{
|
||||||
return (t < 0.5 ? 0 : 1);
|
return (t < 0.5 ? 0 : 1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Linear (y=t) easing */
|
/** Linear (y=t) easing */
|
||||||
public static final Easing LINEAR = new Easing() {
|
public static final Easing LINEAR = new Easing() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double get(double t)
|
public double get(double t)
|
||||||
{
|
{
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Quadratic (y=t^2) easing in */
|
/** Quadratic (y=t^2) easing in */
|
||||||
public static final Easing QUADRATIC_IN = new Easing() {
|
public static final Easing QUADRATIC_IN = new Easing() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double get(double t)
|
public double get(double t)
|
||||||
{
|
{
|
||||||
return t * t;
|
return t * t;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Quadratic (y=t^2) easing out */
|
/** Quadratic (y=t^2) easing out */
|
||||||
public static final Easing QUADRATIC_OUT = reverse(QUADRATIC_IN);
|
public static final Easing QUADRATIC_OUT = reverse(QUADRATIC_IN);
|
||||||
|
|
||||||
/** Quadratic (y=t^2) easing both */
|
/** Quadratic (y=t^2) easing both */
|
||||||
public static final Easing QUADRATIC_BOTH = inOut(QUADRATIC_IN);
|
public static final Easing QUADRATIC_BOTH = inOut(QUADRATIC_IN);
|
||||||
|
|
||||||
/** Cubic (y=t^3) easing in */
|
/** Cubic (y=t^3) easing in */
|
||||||
public static final Easing CUBIC_IN = new Easing() {
|
public static final Easing CUBIC_IN = new Easing() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double get(double t)
|
public double get(double t)
|
||||||
{
|
{
|
||||||
return t * t * t;
|
return t * t * t;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Cubic (y=t^3) easing out */
|
/** Cubic (y=t^3) easing out */
|
||||||
public static final Easing CUBIC_OUT = reverse(CUBIC_IN);
|
public static final Easing CUBIC_OUT = reverse(CUBIC_IN);
|
||||||
|
|
||||||
/** Cubic (y=t^3) easing both */
|
/** Cubic (y=t^3) easing both */
|
||||||
public static final Easing CUBIC_BOTH = inOut(CUBIC_IN);
|
public static final Easing CUBIC_BOTH = inOut(CUBIC_IN);
|
||||||
|
|
||||||
/** Quartic (y=t^4) easing in */
|
/** Quartic (y=t^4) easing in */
|
||||||
public static final Easing QUARTIC_IN = new Easing() {
|
public static final Easing QUARTIC_IN = new Easing() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double get(double t)
|
public double get(double t)
|
||||||
{
|
{
|
||||||
return t * t * t * t;
|
return t * t * t * t;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Quartic (y=t^4) easing out */
|
/** Quartic (y=t^4) easing out */
|
||||||
public static final Easing QUARTIC_OUT = reverse(QUADRATIC_IN);
|
public static final Easing QUARTIC_OUT = reverse(QUADRATIC_IN);
|
||||||
|
|
||||||
/** Quartic (y=t^4) easing both */
|
/** Quartic (y=t^4) easing both */
|
||||||
public static final Easing QUARTIC_BOTH = inOut(QUADRATIC_IN);
|
public static final Easing QUARTIC_BOTH = inOut(QUADRATIC_IN);
|
||||||
|
|
||||||
/** Quintic (y=t^5) easing in */
|
/** Quintic (y=t^5) easing in */
|
||||||
public static final Easing QUINTIC_IN = new Easing() {
|
public static final Easing QUINTIC_IN = new Easing() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double get(double t)
|
public double get(double t)
|
||||||
{
|
{
|
||||||
return t * t * t * t * t;
|
return t * t * t * t * t;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Quintic (y=t^5) easing out */
|
/** Quintic (y=t^5) easing out */
|
||||||
public static final Easing QUINTIC_OUT = reverse(QUINTIC_IN);
|
public static final Easing QUINTIC_OUT = reverse(QUINTIC_IN);
|
||||||
|
|
||||||
/** Quintic (y=t^5) easing both */
|
/** Quintic (y=t^5) easing both */
|
||||||
public static final Easing QUINTIC_BOTH = inOut(QUINTIC_IN);
|
public static final Easing QUINTIC_BOTH = inOut(QUINTIC_IN);
|
||||||
|
|
||||||
/** Sine easing in */
|
/** Sine easing in */
|
||||||
public static final Easing SINE_IN = new Easing() {
|
public static final Easing SINE_IN = new Easing() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double get(double t)
|
public double get(double t)
|
||||||
{
|
{
|
||||||
return 1 - Math.cos(t * (Math.PI / 2));
|
return 1 - Math.cos(t * (Math.PI / 2));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Sine easing out */
|
/** Sine easing out */
|
||||||
public static final Easing SINE_OUT = reverse(SINE_IN);
|
public static final Easing SINE_OUT = reverse(SINE_IN);
|
||||||
|
|
||||||
/** Sine easing both */
|
/** Sine easing both */
|
||||||
public static final Easing SINE_BOTH = inOut(SINE_IN);
|
public static final Easing SINE_BOTH = inOut(SINE_IN);
|
||||||
|
|
||||||
/** Exponential easing in */
|
/** Exponential easing in */
|
||||||
public static final Easing EXPO_IN = new Easing() {
|
public static final Easing EXPO_IN = new Easing() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double get(double t)
|
public double get(double t)
|
||||||
{
|
{
|
||||||
return Math.pow(2, 10 * (t - 1));
|
return Math.pow(2, 10 * (t - 1));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Exponential easing out */
|
/** Exponential easing out */
|
||||||
public static final Easing EXPO_OUT = reverse(EXPO_IN);
|
public static final Easing EXPO_OUT = reverse(EXPO_IN);
|
||||||
|
|
||||||
/** Exponential easing both */
|
/** Exponential easing both */
|
||||||
public static final Easing EXPO_BOTH = inOut(EXPO_IN);
|
public static final Easing EXPO_BOTH = inOut(EXPO_IN);
|
||||||
|
|
||||||
/** Circular easing in */
|
/** Circular easing in */
|
||||||
public static final Easing CIRC_IN = new Easing() {
|
public static final Easing CIRC_IN = new Easing() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double get(double t)
|
public double get(double t)
|
||||||
{
|
{
|
||||||
return 1 - Math.sqrt(1 - t * t);
|
return 1 - Math.sqrt(1 - t * t);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Circular easing out */
|
/** Circular easing out */
|
||||||
public static final Easing CIRC_OUT = reverse(CIRC_IN);
|
public static final Easing CIRC_OUT = reverse(CIRC_IN);
|
||||||
|
|
||||||
/** Circular easing both */
|
/** Circular easing both */
|
||||||
public static final Easing CIRC_BOTH = inOut(CIRC_IN);
|
public static final Easing CIRC_BOTH = inOut(CIRC_IN);
|
||||||
|
|
||||||
/** Bounce easing in */
|
/** Bounce easing in */
|
||||||
public static final Easing BOUNCE_OUT = new Easing() {
|
public static final Easing BOUNCE_OUT = new Easing() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double get(double t)
|
public double get(double t)
|
||||||
{
|
{
|
||||||
if (t < (1 / 2.75f)) {
|
if (t < (1 / 2.75f)) {
|
||||||
return (7.5625f * t * t);
|
return (7.5625f * t * t);
|
||||||
|
|
||||||
} else if (t < (2 / 2.75f)) {
|
} else if (t < (2 / 2.75f)) {
|
||||||
t -= (1.5f / 2.75f);
|
t -= (1.5f / 2.75f);
|
||||||
return (7.5625f * t * t + 0.75f);
|
return (7.5625f * t * t + 0.75f);
|
||||||
|
|
||||||
} else if (t < (2.5 / 2.75)) {
|
} else if (t < (2.5 / 2.75)) {
|
||||||
t -= (2.25f / 2.75f);
|
t -= (2.25f / 2.75f);
|
||||||
return (7.5625f * t * t + 0.9375f);
|
return (7.5625f * t * t + 0.9375f);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
t -= (2.625f / 2.75f);
|
t -= (2.625f / 2.75f);
|
||||||
return (7.5625f * t * t + 0.984375f);
|
return (7.5625f * t * t + 0.984375f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Bounce easing out */
|
/** Bounce easing out */
|
||||||
public static final Easing BOUNCE_IN = reverse(BOUNCE_OUT);
|
public static final Easing BOUNCE_IN = reverse(BOUNCE_OUT);
|
||||||
|
|
||||||
/** Bounce easing both */
|
/** Bounce easing both */
|
||||||
public static final Easing BOUNCE_BOTH = inOut(BOUNCE_IN);
|
public static final Easing BOUNCE_BOTH = inOut(BOUNCE_IN);
|
||||||
|
|
||||||
/** Back easing in */
|
/** Back easing in */
|
||||||
public static final Easing BACK_IN = new Easing() {
|
public static final Easing BACK_IN = new Easing() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double get(double t)
|
public double get(double t)
|
||||||
{
|
{
|
||||||
@@ -284,31 +284,31 @@ public abstract class Easing {
|
|||||||
return t * t * ((s + 1) * t - s);
|
return t * t * ((s + 1) * t - s);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Back easing out */
|
/** Back easing out */
|
||||||
public static final Easing BACK_OUT = reverse(BACK_IN);
|
public static final Easing BACK_OUT = reverse(BACK_IN);
|
||||||
|
|
||||||
/** Back easing both */
|
/** Back easing both */
|
||||||
public static final Easing BACK_BOTH = inOut(BACK_IN);
|
public static final Easing BACK_BOTH = inOut(BACK_IN);
|
||||||
|
|
||||||
/** Elastic easing in */
|
/** Elastic easing in */
|
||||||
public static final Easing ELASTIC_IN = new Easing() {
|
public static final Easing ELASTIC_IN = new Easing() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double get(double t)
|
public double get(double t)
|
||||||
{
|
{
|
||||||
if (t == 0) return 0;
|
if (t == 0) return 0;
|
||||||
if (t == 1) return 1;
|
if (t == 1) return 1;
|
||||||
|
|
||||||
final double p = .3f;
|
final double p = .3f;
|
||||||
final double s = p / 4;
|
final double s = p / 4;
|
||||||
return -(Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p));
|
return -(Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Elastic easing out */
|
/** Elastic easing out */
|
||||||
public static final Easing ELASTIC_OUT = reverse(ELASTIC_IN);
|
public static final Easing ELASTIC_OUT = reverse(ELASTIC_IN);
|
||||||
|
|
||||||
/** Elastic easing both */
|
/** Elastic easing both */
|
||||||
public static final Easing ELASTIC_BOTH = inOut(ELASTIC_IN);
|
public static final Easing ELASTIC_BOTH = inOut(ELASTIC_IN);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,31 +15,31 @@ import mightypork.utils.math.constraints.num.var.NumMutable;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class NumAnimated extends NumMutable implements Updateable, Pauseable {
|
public class NumAnimated extends NumMutable implements Updateable, Pauseable {
|
||||||
|
|
||||||
/** target double */
|
/** target double */
|
||||||
protected double to = 0;
|
protected double to = 0;
|
||||||
|
|
||||||
/** last tick double */
|
/** last tick double */
|
||||||
protected double from = 0;
|
protected double from = 0;
|
||||||
|
|
||||||
/** how long the transition should last */
|
/** how long the transition should last */
|
||||||
protected double duration = 0;
|
protected double duration = 0;
|
||||||
|
|
||||||
/** current anim time */
|
/** current anim time */
|
||||||
protected double elapsedTime = 0;
|
protected double elapsedTime = 0;
|
||||||
|
|
||||||
/** True if this animator is paused */
|
/** True if this animator is paused */
|
||||||
protected boolean paused = false;
|
protected boolean paused = false;
|
||||||
|
|
||||||
/** Easing fn */
|
/** Easing fn */
|
||||||
protected Easing easingCurrent = Easing.LINEAR;
|
protected Easing easingCurrent = Easing.LINEAR;
|
||||||
protected Easing easingOut = Easing.LINEAR;
|
protected Easing easingOut = Easing.LINEAR;
|
||||||
protected Easing easingIn = Easing.LINEAR;
|
protected Easing easingIn = Easing.LINEAR;
|
||||||
|
|
||||||
/** Default duration (seconds) */
|
/** Default duration (seconds) */
|
||||||
private double defaultDuration = 1;
|
private double defaultDuration = 1;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* With linear easing
|
* With linear easing
|
||||||
*
|
*
|
||||||
@@ -49,8 +49,8 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
|
|||||||
{
|
{
|
||||||
setTo(value);
|
setTo(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create animator with easing
|
* Create animator with easing
|
||||||
*
|
*
|
||||||
@@ -62,8 +62,8 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
|
|||||||
this(value);
|
this(value);
|
||||||
setEasing(easing);
|
setEasing(easing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create animator with easing
|
* Create animator with easing
|
||||||
*
|
*
|
||||||
@@ -76,8 +76,8 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
|
|||||||
this(value);
|
this(value);
|
||||||
setEasing(easingIn, easingOut);
|
setEasing(easingIn, easingOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create animator with easing
|
* Create animator with easing
|
||||||
*
|
*
|
||||||
@@ -91,8 +91,8 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
|
|||||||
setEasing(easing);
|
setEasing(easing);
|
||||||
setDefaultDuration(defaultDuration);
|
setDefaultDuration(defaultDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create animator with easing
|
* Create animator with easing
|
||||||
*
|
*
|
||||||
@@ -107,8 +107,8 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
|
|||||||
setEasing(easingIn, easingOut);
|
setEasing(easingIn, easingOut);
|
||||||
setDefaultDuration(defaultDuration);
|
setDefaultDuration(defaultDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create as copy of another
|
* Create as copy of another
|
||||||
*
|
*
|
||||||
@@ -118,8 +118,8 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
|
|||||||
{
|
{
|
||||||
setTo(other);
|
setTo(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param easing easing function
|
* @param easing easing function
|
||||||
*/
|
*/
|
||||||
@@ -127,8 +127,8 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
|
|||||||
{
|
{
|
||||||
this.easingCurrent = this.easingIn = this.easingOut = easing;
|
this.easingCurrent = this.easingIn = this.easingOut = easing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param easingIn easing for fade in
|
* @param easingIn easing for fade in
|
||||||
* @param easingOut easing for fade out
|
* @param easingOut easing for fade out
|
||||||
@@ -139,8 +139,8 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
|
|||||||
this.easingOut = easingOut;
|
this.easingOut = easingOut;
|
||||||
this.easingCurrent = easingIn;
|
this.easingCurrent = easingIn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get start value
|
* Get start value
|
||||||
*
|
*
|
||||||
@@ -150,8 +150,8 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
|
|||||||
{
|
{
|
||||||
return from;
|
return from;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get end value
|
* Get end value
|
||||||
*
|
*
|
||||||
@@ -161,8 +161,8 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
|
|||||||
{
|
{
|
||||||
return to;
|
return to;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return current animation duration (seconds)
|
* @return current animation duration (seconds)
|
||||||
*/
|
*/
|
||||||
@@ -170,8 +170,8 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
|
|||||||
{
|
{
|
||||||
return duration;
|
return duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return elapsed time in current animation (seconds)
|
* @return elapsed time in current animation (seconds)
|
||||||
*/
|
*/
|
||||||
@@ -179,8 +179,8 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
|
|||||||
{
|
{
|
||||||
return elapsedTime;
|
return elapsedTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return default animation duration (seconds)
|
* @return default animation duration (seconds)
|
||||||
*/
|
*/
|
||||||
@@ -188,8 +188,8 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
|
|||||||
{
|
{
|
||||||
return defaultDuration;
|
return defaultDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param defaultDuration default animation duration (seconds)
|
* @param defaultDuration default animation duration (seconds)
|
||||||
*/
|
*/
|
||||||
@@ -197,8 +197,8 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
|
|||||||
{
|
{
|
||||||
this.defaultDuration = defaultDuration;
|
this.defaultDuration = defaultDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get value at delta time
|
* Get value at delta time
|
||||||
*
|
*
|
||||||
@@ -210,8 +210,8 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
|
|||||||
if (duration == 0) return to;
|
if (duration == 0) return to;
|
||||||
return Calc.interpolate(from, to, (elapsedTime / duration), easingCurrent);
|
return Calc.interpolate(from, to, (elapsedTime / duration), easingCurrent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get how much of the animation is already finished
|
* Get how much of the animation is already finished
|
||||||
*
|
*
|
||||||
@@ -222,13 +222,13 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
|
|||||||
if (duration == 0) return 1;
|
if (duration == 0) return 1;
|
||||||
return elapsedTime / duration;
|
return elapsedTime / duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(double delta)
|
public void update(double delta)
|
||||||
{
|
{
|
||||||
if (paused || isFinished()) return;
|
if (paused || isFinished()) return;
|
||||||
|
|
||||||
elapsedTime = Calc.clamp(elapsedTime + delta, 0, duration);
|
elapsedTime = Calc.clamp(elapsedTime + delta, 0, duration);
|
||||||
if (isFinished()) {
|
if (isFinished()) {
|
||||||
duration = 0;
|
duration = 0;
|
||||||
@@ -236,8 +236,8 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
|
|||||||
from = to;
|
from = to;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get if animation is finished
|
* Get if animation is finished
|
||||||
*
|
*
|
||||||
@@ -247,8 +247,8 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
|
|||||||
{
|
{
|
||||||
return duration == 0 || elapsedTime >= duration;
|
return duration == 0 || elapsedTime >= duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set to a value (without animation)
|
* Set to a value (without animation)
|
||||||
*
|
*
|
||||||
@@ -261,8 +261,8 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
|
|||||||
elapsedTime = 0;
|
elapsedTime = 0;
|
||||||
duration = 0;
|
duration = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy other
|
* Copy other
|
||||||
*
|
*
|
||||||
@@ -280,8 +280,8 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
|
|||||||
this.easingOut = other.easingOut;
|
this.easingOut = other.easingOut;
|
||||||
this.defaultDuration = other.defaultDuration;
|
this.defaultDuration = other.defaultDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Animate between two states, start from current value (if it's in between)
|
* Animate between two states, start from current value (if it's in between)
|
||||||
*
|
*
|
||||||
@@ -292,19 +292,19 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
|
|||||||
public void animate(double from, double to, double time)
|
public void animate(double from, double to, double time)
|
||||||
{
|
{
|
||||||
final double current = value();
|
final double current = value();
|
||||||
|
|
||||||
this.from = from;
|
this.from = from;
|
||||||
this.to = to;
|
this.to = to;
|
||||||
|
|
||||||
final double progress = getProgressFromValue(current);
|
final double progress = getProgressFromValue(current);
|
||||||
|
|
||||||
this.from = (progress > 0 ? current : from);
|
this.from = (progress > 0 ? current : from);
|
||||||
|
|
||||||
this.duration = time * (1 - progress);
|
this.duration = time * (1 - progress);
|
||||||
this.elapsedTime = 0;
|
this.elapsedTime = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get progress already elapsed based on current value.<br>
|
* Get progress already elapsed based on current value.<br>
|
||||||
* Used to resume animation from current point in fading etc.
|
* Used to resume animation from current point in fading etc.
|
||||||
@@ -315,19 +315,19 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
|
|||||||
protected double getProgressFromValue(double value)
|
protected double getProgressFromValue(double value)
|
||||||
{
|
{
|
||||||
double p = 0;
|
double p = 0;
|
||||||
|
|
||||||
if (from == to) return 0;
|
if (from == to) return 0;
|
||||||
|
|
||||||
if (value >= from && value <= to) { // up
|
if (value >= from && value <= to) { // up
|
||||||
p = ((value - from) / (to - from));
|
p = ((value - from) / (to - from));
|
||||||
} else if (value >= to && value <= from) { // down
|
} else if (value >= to && value <= from) { // down
|
||||||
p = ((from - value) / (from - to));
|
p = ((from - value) / (from - to));
|
||||||
}
|
}
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Animate to a value from current value
|
* Animate to a value from current value
|
||||||
*
|
*
|
||||||
@@ -341,8 +341,8 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
|
|||||||
this.duration = duration;
|
this.duration = duration;
|
||||||
this.elapsedTime = 0;
|
this.elapsedTime = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Animate 0 to 1
|
* Animate 0 to 1
|
||||||
*
|
*
|
||||||
@@ -353,8 +353,8 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
|
|||||||
easingCurrent = easingIn;
|
easingCurrent = easingIn;
|
||||||
animate(0, 1, time);
|
animate(0, 1, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Animate 1 to 0
|
* Animate 1 to 0
|
||||||
*
|
*
|
||||||
@@ -365,8 +365,8 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
|
|||||||
easingCurrent = easingOut;
|
easingCurrent = easingOut;
|
||||||
animate(1, 0, time);
|
animate(1, 0, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Animate 0 to 1 with default duration
|
* Animate 0 to 1 with default duration
|
||||||
*/
|
*/
|
||||||
@@ -375,8 +375,8 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
|
|||||||
easingCurrent = easingIn;
|
easingCurrent = easingIn;
|
||||||
animate(0, 1, defaultDuration);
|
animate(0, 1, defaultDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Animate 1 to 0 with default duration
|
* Animate 1 to 0 with default duration
|
||||||
*/
|
*/
|
||||||
@@ -385,8 +385,8 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
|
|||||||
easingCurrent = easingOut;
|
easingCurrent = easingOut;
|
||||||
animate(1, 0, defaultDuration);
|
animate(1, 0, defaultDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make a copy
|
* Make a copy
|
||||||
*
|
*
|
||||||
@@ -397,15 +397,15 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
|
|||||||
{
|
{
|
||||||
return new NumAnimated(this);
|
return new NumAnimated(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return "Animation(" + from + " -> " + to + ", t=" + duration + "s, elapsed=" + elapsedTime + "s)";
|
return "Animation(" + from + " -> " + to + ", t=" + duration + "s, elapsed=" + elapsedTime + "s)";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set to zero and stop animation
|
* Set to zero and stop animation
|
||||||
*/
|
*/
|
||||||
@@ -416,8 +416,8 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
|
|||||||
duration = 0;
|
duration = 0;
|
||||||
paused = false;
|
paused = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop animation, keep current value
|
* Stop animation, keep current value
|
||||||
*/
|
*/
|
||||||
@@ -427,29 +427,29 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable {
|
|||||||
elapsedTime = 0;
|
elapsedTime = 0;
|
||||||
duration = 0;
|
duration = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void pause()
|
public void pause()
|
||||||
{
|
{
|
||||||
paused = true;
|
paused = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resume()
|
public void resume()
|
||||||
{
|
{
|
||||||
paused = false;
|
paused = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPaused()
|
public boolean isPaused()
|
||||||
{
|
{
|
||||||
return paused;
|
return paused;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean isInProgress()
|
public boolean isInProgress()
|
||||||
{
|
{
|
||||||
return !isFinished() && !isPaused();
|
return !isFinished() && !isPaused();
|
||||||
|
|||||||
@@ -11,33 +11,33 @@ import mightypork.utils.math.angles.Deg;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class NumAnimatedDeg extends NumAnimated {
|
public class NumAnimatedDeg extends NumAnimated {
|
||||||
|
|
||||||
public NumAnimatedDeg(NumAnimated other)
|
public NumAnimatedDeg(NumAnimated other)
|
||||||
{
|
{
|
||||||
super(other);
|
super(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public NumAnimatedDeg(double value)
|
public NumAnimatedDeg(double value)
|
||||||
{
|
{
|
||||||
super(value);
|
super(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public NumAnimatedDeg(double value, Easing easing)
|
public NumAnimatedDeg(double value, Easing easing)
|
||||||
{
|
{
|
||||||
super(value, easing);
|
super(value, easing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double value()
|
public double value()
|
||||||
{
|
{
|
||||||
if (duration == 0) return Deg.norm(to);
|
if (duration == 0) return Deg.norm(to);
|
||||||
return Calc.interpolateDeg(from, to, (elapsedTime / duration), easingCurrent);
|
return Calc.interpolateDeg(from, to, (elapsedTime / duration), easingCurrent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected double getProgressFromValue(double value)
|
protected double getProgressFromValue(double value)
|
||||||
{
|
{
|
||||||
@@ -46,7 +46,7 @@ public class NumAnimatedDeg extends NumAnimated {
|
|||||||
final double partial = Deg.diff(from, value);
|
final double partial = Deg.diff(from, value);
|
||||||
return partial / whole;
|
return partial / whole;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,33 +11,33 @@ import mightypork.utils.math.angles.Rad;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class NumAnimatedRad extends NumAnimated {
|
public class NumAnimatedRad extends NumAnimated {
|
||||||
|
|
||||||
public NumAnimatedRad(NumAnimated other)
|
public NumAnimatedRad(NumAnimated other)
|
||||||
{
|
{
|
||||||
super(other);
|
super(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public NumAnimatedRad(double value)
|
public NumAnimatedRad(double value)
|
||||||
{
|
{
|
||||||
super(value);
|
super(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public NumAnimatedRad(double value, Easing easing)
|
public NumAnimatedRad(double value, Easing easing)
|
||||||
{
|
{
|
||||||
super(value, easing);
|
super(value, easing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double value()
|
public double value()
|
||||||
{
|
{
|
||||||
if (duration == 0) return Rad.norm(to);
|
if (duration == 0) return Rad.norm(to);
|
||||||
return Calc.interpolateRad(from, to, (elapsedTime / duration), easingCurrent);
|
return Calc.interpolateRad(from, to, (elapsedTime / duration), easingCurrent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected double getProgressFromValue(double value)
|
protected double getProgressFromValue(double value)
|
||||||
{
|
{
|
||||||
@@ -46,7 +46,7 @@ public class NumAnimatedRad extends NumAnimated {
|
|||||||
final double partial = Rad.diff(from, value);
|
final double partial = Rad.diff(from, value);
|
||||||
return partial / whole;
|
return partial / whole;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,11 +14,11 @@ import mightypork.utils.math.constraints.vect.var.VectMutable;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class VectAnimated extends VectMutable implements Pauseable, Updateable {
|
public class VectAnimated extends VectMutable implements Pauseable, Updateable {
|
||||||
|
|
||||||
private final NumAnimated x, y, z;
|
private final NumAnimated x, y, z;
|
||||||
private double defaultDuration = 0.5;
|
private double defaultDuration = 0.5;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an animated vector; This way different easing / settings can be
|
* Create an animated vector; This way different easing / settings can be
|
||||||
* specified for each coordinate.
|
* specified for each coordinate.
|
||||||
@@ -33,8 +33,8 @@ public class VectAnimated extends VectMutable implements Pauseable, Updateable {
|
|||||||
this.y = y;
|
this.y = y;
|
||||||
this.z = z;
|
this.z = z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an animated vector
|
* Create an animated vector
|
||||||
*
|
*
|
||||||
@@ -47,29 +47,29 @@ public class VectAnimated extends VectMutable implements Pauseable, Updateable {
|
|||||||
y = new NumAnimated(start.y(), easing);
|
y = new NumAnimated(start.y(), easing);
|
||||||
z = new NumAnimated(start.z(), easing);
|
z = new NumAnimated(start.z(), easing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double x()
|
public double x()
|
||||||
{
|
{
|
||||||
return x.value();
|
return x.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double y()
|
public double y()
|
||||||
{
|
{
|
||||||
return y.value();
|
return y.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double z()
|
public double z()
|
||||||
{
|
{
|
||||||
return z.value();
|
return z.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setTo(double x, double y, double z)
|
public void setTo(double x, double y, double z)
|
||||||
{
|
{
|
||||||
@@ -77,35 +77,35 @@ public class VectAnimated extends VectMutable implements Pauseable, Updateable {
|
|||||||
setY(y);
|
setY(y);
|
||||||
setZ(z);
|
setZ(z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setX(double x)
|
public void setX(double x)
|
||||||
{
|
{
|
||||||
this.x.setTo(x);
|
this.x.setTo(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setY(double y)
|
public void setY(double y)
|
||||||
{
|
{
|
||||||
this.y.setTo(y);
|
this.y.setTo(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setZ(double z)
|
public void setZ(double z)
|
||||||
{
|
{
|
||||||
this.z.setTo(z);
|
this.z.setTo(z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void add(Vect offset, double duration)
|
public void add(Vect offset, double duration)
|
||||||
{
|
{
|
||||||
animate(this.add(offset), duration);
|
animate(this.add(offset), duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public VectAnimated animate(double x, double y, double z, double duration)
|
public VectAnimated animate(double x, double y, double z, double duration)
|
||||||
{
|
{
|
||||||
this.x.animate(x, duration);
|
this.x.animate(x, duration);
|
||||||
@@ -113,15 +113,15 @@ public class VectAnimated extends VectMutable implements Pauseable, Updateable {
|
|||||||
this.z.animate(z, duration);
|
this.z.animate(z, duration);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public VectAnimated animate(Vect target, double duration)
|
public VectAnimated animate(Vect target, double duration)
|
||||||
{
|
{
|
||||||
animate(target.x(), target.y(), target.z(), duration);
|
animate(target.x(), target.y(), target.z(), duration);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public VectAnimated animate(double x, double y, double z)
|
public VectAnimated animate(double x, double y, double z)
|
||||||
{
|
{
|
||||||
this.x.animate(x, defaultDuration);
|
this.x.animate(x, defaultDuration);
|
||||||
@@ -129,15 +129,15 @@ public class VectAnimated extends VectMutable implements Pauseable, Updateable {
|
|||||||
this.z.animate(z, defaultDuration);
|
this.z.animate(z, defaultDuration);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public VectAnimated animate(Vect target)
|
public VectAnimated animate(Vect target)
|
||||||
{
|
{
|
||||||
animate(target.x(), target.y(), target.z());
|
animate(target.x(), target.y(), target.z());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the default duration (seconds)
|
* @return the default duration (seconds)
|
||||||
*/
|
*/
|
||||||
@@ -145,8 +145,8 @@ public class VectAnimated extends VectMutable implements Pauseable, Updateable {
|
|||||||
{
|
{
|
||||||
return defaultDuration;
|
return defaultDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set default animation duration (when changed without using animate())
|
* Set default animation duration (when changed without using animate())
|
||||||
*
|
*
|
||||||
@@ -156,8 +156,8 @@ public class VectAnimated extends VectMutable implements Pauseable, Updateable {
|
|||||||
{
|
{
|
||||||
this.defaultDuration = defaultDuration;
|
this.defaultDuration = defaultDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(double delta)
|
public void update(double delta)
|
||||||
{
|
{
|
||||||
@@ -165,8 +165,8 @@ public class VectAnimated extends VectMutable implements Pauseable, Updateable {
|
|||||||
y.update(delta);
|
y.update(delta);
|
||||||
z.update(delta);
|
z.update(delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void pause()
|
public void pause()
|
||||||
{
|
{
|
||||||
@@ -174,8 +174,8 @@ public class VectAnimated extends VectMutable implements Pauseable, Updateable {
|
|||||||
y.pause();
|
y.pause();
|
||||||
z.pause();
|
z.pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resume()
|
public void resume()
|
||||||
{
|
{
|
||||||
@@ -183,15 +183,15 @@ public class VectAnimated extends VectMutable implements Pauseable, Updateable {
|
|||||||
y.resume();
|
y.resume();
|
||||||
z.resume();
|
z.resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPaused()
|
public boolean isPaused()
|
||||||
{
|
{
|
||||||
return x.isPaused(); // BÚNO
|
return x.isPaused(); // BÚNO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if the animation is finished
|
* @return true if the animation is finished
|
||||||
*/
|
*/
|
||||||
@@ -199,8 +199,8 @@ public class VectAnimated extends VectMutable implements Pauseable, Updateable {
|
|||||||
{
|
{
|
||||||
return x.isFinished(); // BÚNO
|
return x.isFinished(); // BÚNO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return current animation duration
|
* @return current animation duration
|
||||||
*/
|
*/
|
||||||
@@ -208,8 +208,8 @@ public class VectAnimated extends VectMutable implements Pauseable, Updateable {
|
|||||||
{
|
{
|
||||||
return x.getDuration(); // BÚNO
|
return x.getDuration(); // BÚNO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return elapsed time since the start of the animation
|
* @return elapsed time since the start of the animation
|
||||||
*/
|
*/
|
||||||
@@ -217,8 +217,8 @@ public class VectAnimated extends VectMutable implements Pauseable, Updateable {
|
|||||||
{
|
{
|
||||||
return x.getElapsed(); // BÚNO
|
return x.getElapsed(); // BÚNO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return animation progress (elapsed / duration)
|
* @return animation progress (elapsed / duration)
|
||||||
*/
|
*/
|
||||||
@@ -226,8 +226,8 @@ public class VectAnimated extends VectMutable implements Pauseable, Updateable {
|
|||||||
{
|
{
|
||||||
return x.getProgress(); // BÚNO
|
return x.getProgress(); // BÚNO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set easing for all three coordinates
|
* Set easing for all three coordinates
|
||||||
*
|
*
|
||||||
@@ -239,8 +239,8 @@ public class VectAnimated extends VectMutable implements Pauseable, Updateable {
|
|||||||
y.setEasing(easing);
|
y.setEasing(easing);
|
||||||
z.setEasing(easing);
|
z.setEasing(easing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an animated vector; This way different easing / settings can be
|
* Create an animated vector; This way different easing / settings can be
|
||||||
* specified for each coordinate.
|
* specified for each coordinate.
|
||||||
@@ -255,8 +255,8 @@ public class VectAnimated extends VectMutable implements Pauseable, Updateable {
|
|||||||
{
|
{
|
||||||
return new VectAnimated(x, y, z);
|
return new VectAnimated(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an animated vector
|
* Create an animated vector
|
||||||
*
|
*
|
||||||
@@ -269,8 +269,8 @@ public class VectAnimated extends VectMutable implements Pauseable, Updateable {
|
|||||||
{
|
{
|
||||||
return new VectAnimated(start, easing);
|
return new VectAnimated(start, easing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an animated vector, initialized at 0,0,0
|
* Create an animated vector, initialized at 0,0,0
|
||||||
*
|
*
|
||||||
@@ -282,5 +282,5 @@ public class VectAnimated extends VectMutable implements Pauseable, Updateable {
|
|||||||
{
|
{
|
||||||
return new VectAnimated(Vect.ZERO, easing);
|
return new VectAnimated(Vect.ZERO, easing);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,11 +16,11 @@ import mightypork.utils.math.constraints.num.Num;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public abstract class Color {
|
public abstract class Color {
|
||||||
|
|
||||||
private static final Stack<Num> alphaStack = new Stack<>();
|
private static final Stack<Num> alphaStack = new Stack<>();
|
||||||
private static volatile boolean alphaStackEnabled = true;
|
private static volatile boolean alphaStackEnabled = true;
|
||||||
|
|
||||||
|
|
||||||
@FactoryMethod
|
@FactoryMethod
|
||||||
public static final Color fromHex(int rgb_hex)
|
public static final Color fromHex(int rgb_hex)
|
||||||
{
|
{
|
||||||
@@ -29,146 +29,146 @@ public abstract class Color {
|
|||||||
final int ri = (rgb_hex >> 16) & 0xff;
|
final int ri = (rgb_hex >> 16) & 0xff;
|
||||||
return rgb(ri / 255D, gi / 255D, bi / 255D);
|
return rgb(ri / 255D, gi / 255D, bi / 255D);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@FactoryMethod
|
@FactoryMethod
|
||||||
public static final Color rgb(double r, double g, double b)
|
public static final Color rgb(double r, double g, double b)
|
||||||
{
|
{
|
||||||
return rgba(Num.make(r), Num.make(g), Num.make(b), Num.ONE);
|
return rgba(Num.make(r), Num.make(g), Num.make(b), Num.ONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@FactoryMethod
|
@FactoryMethod
|
||||||
public static final Color rgba(double r, double g, double b, double a)
|
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));
|
return rgba(Num.make(r), Num.make(g), Num.make(b), Num.make(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@FactoryMethod
|
@FactoryMethod
|
||||||
public static final Color rgb(Num r, Num g, Num b)
|
public static final Color rgb(Num r, Num g, Num b)
|
||||||
{
|
{
|
||||||
return rgba(r, g, b, Num.ONE);
|
return rgba(r, g, b, Num.ONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@FactoryMethod
|
@FactoryMethod
|
||||||
public static final Color rgba(Num r, Num g, Num b, Num a)
|
public static final Color rgba(Num r, Num g, Num b, Num a)
|
||||||
{
|
{
|
||||||
return new ColorRgb(r, g, b, a);
|
return new ColorRgb(r, g, b, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@FactoryMethod
|
@FactoryMethod
|
||||||
public static final Color hsb(double h, double s, double b)
|
public static final Color hsb(double h, double s, double b)
|
||||||
{
|
{
|
||||||
return hsba(Num.make(h), Num.make(s), Num.make(b), Num.ONE);
|
return hsba(Num.make(h), Num.make(s), Num.make(b), Num.ONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@FactoryMethod
|
@FactoryMethod
|
||||||
public static final Color hsba(double h, double s, double b, double a)
|
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));
|
return hsba(Num.make(h), Num.make(s), Num.make(b), Num.make(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@FactoryMethod
|
@FactoryMethod
|
||||||
public static final Color hsb(Num h, Num s, Num b)
|
public static final Color hsb(Num h, Num s, Num b)
|
||||||
{
|
{
|
||||||
return hsba(h, s, b, Num.ONE);
|
return hsba(h, s, b, Num.ONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@FactoryMethod
|
@FactoryMethod
|
||||||
public static final Color hsba(Num h, Num s, Num b, Num a)
|
public static final Color hsba(Num h, Num s, Num b, Num a)
|
||||||
{
|
{
|
||||||
return new ColorHsb(h, s, b, a);
|
return new ColorHsb(h, s, b, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@FactoryMethod
|
@FactoryMethod
|
||||||
public static final Color light(double a)
|
public static final Color light(double a)
|
||||||
{
|
{
|
||||||
return light(Num.make(a));
|
return light(Num.make(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@FactoryMethod
|
@FactoryMethod
|
||||||
public static final Color light(Num a)
|
public static final Color light(Num a)
|
||||||
{
|
{
|
||||||
return rgba(Num.ONE, Num.ONE, Num.ONE, a);
|
return rgba(Num.ONE, Num.ONE, Num.ONE, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@FactoryMethod
|
@FactoryMethod
|
||||||
public static final Color dark(double a)
|
public static final Color dark(double a)
|
||||||
{
|
{
|
||||||
return dark(Num.make(a));
|
return dark(Num.make(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@FactoryMethod
|
@FactoryMethod
|
||||||
public static final Color dark(Num a)
|
public static final Color dark(Num a)
|
||||||
{
|
{
|
||||||
return rgba(Num.ZERO, Num.ZERO, Num.ZERO, a);
|
return rgba(Num.ZERO, Num.ZERO, Num.ZERO, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected static final double clamp(Num n)
|
protected static final double clamp(Num n)
|
||||||
{
|
{
|
||||||
return Calc.clamp(n.value(), 0, 1);
|
return Calc.clamp(n.value(), 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected static final double clamp(double n)
|
protected static final double clamp(double n)
|
||||||
{
|
{
|
||||||
return Calc.clamp(n, 0, 1);
|
return Calc.clamp(n, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return red 0-1
|
* @return red 0-1
|
||||||
*/
|
*/
|
||||||
public abstract double r();
|
public abstract double r();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return green 0-1
|
* @return green 0-1
|
||||||
*/
|
*/
|
||||||
public abstract double g();
|
public abstract double g();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return blue 0-1
|
* @return blue 0-1
|
||||||
*/
|
*/
|
||||||
public abstract double b();
|
public abstract double b();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return alpha 0-1
|
* @return alpha 0-1
|
||||||
*/
|
*/
|
||||||
public final double a()
|
public final double a()
|
||||||
{
|
{
|
||||||
double alpha = rawAlpha();
|
double alpha = rawAlpha();
|
||||||
|
|
||||||
if (alphaStackEnabled) {
|
if (alphaStackEnabled) {
|
||||||
|
|
||||||
for (final Num n : alphaStack) {
|
for (final Num n : alphaStack) {
|
||||||
alpha *= clamp(n.value());
|
alpha *= clamp(n.value());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return clamp(alpha);
|
return clamp(alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return alpha 0-1, before multiplying with the global alpha value.
|
* @return alpha 0-1, before multiplying with the global alpha value.
|
||||||
*/
|
*/
|
||||||
protected abstract double rawAlpha();
|
protected abstract double rawAlpha();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* Push alpha multiplier on the stack (can be animated or whatever you
|
* Push alpha multiplier on the stack (can be animated or whatever you
|
||||||
@@ -188,11 +188,11 @@ public abstract class Color {
|
|||||||
if (!alphaStackEnabled) {
|
if (!alphaStackEnabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
alphaStack.push(alpha);
|
alphaStack.push(alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a pushed alpha multiplier from the stack. If there's no remaining
|
* Remove a pushed alpha multiplier from the stack. If there's no remaining
|
||||||
* multiplier on the stack, an exception is raised.
|
* multiplier on the stack, an exception is raised.
|
||||||
@@ -204,15 +204,15 @@ public abstract class Color {
|
|||||||
if (!alphaStackEnabled) {
|
if (!alphaStackEnabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (alphaStack.isEmpty()) {
|
if (alphaStack.isEmpty()) {
|
||||||
throw new EmptyStackException();
|
throw new EmptyStackException();
|
||||||
}
|
}
|
||||||
|
|
||||||
alphaStack.pop();
|
alphaStack.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable alpha stack. When disabled, pushAlpha() and popAlpha() have no
|
* Enable alpha stack. When disabled, pushAlpha() and popAlpha() have no
|
||||||
* effect.
|
* effect.
|
||||||
@@ -223,8 +223,8 @@ public abstract class Color {
|
|||||||
{
|
{
|
||||||
alphaStackEnabled = yes;
|
alphaStackEnabled = yes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if alpha stack is enabled.
|
* @return true if alpha stack is enabled.
|
||||||
*/
|
*/
|
||||||
@@ -232,20 +232,20 @@ public abstract class Color {
|
|||||||
{
|
{
|
||||||
return alphaStackEnabled;
|
return alphaStackEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Color withAlpha(double multiplier)
|
public Color withAlpha(double multiplier)
|
||||||
{
|
{
|
||||||
return new ColorAlphaAdjuster(this, Num.make(multiplier));
|
return new ColorAlphaAdjuster(this, Num.make(multiplier));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Color withAlpha(Num multiplier)
|
public Color withAlpha(Num multiplier)
|
||||||
{
|
{
|
||||||
return new ColorAlphaAdjuster(this, multiplier);
|
return new ColorAlphaAdjuster(this, multiplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode()
|
public int hashCode()
|
||||||
{
|
{
|
||||||
@@ -262,8 +262,8 @@ public abstract class Color {
|
|||||||
result = prime * result + (int) (temp ^ (temp >>> 32));
|
result = prime * result + (int) (temp ^ (temp >>> 32));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj)
|
public boolean equals(Object obj)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,43 +5,43 @@ import mightypork.utils.math.constraints.num.Num;
|
|||||||
|
|
||||||
|
|
||||||
public class ColorAlphaAdjuster extends Color {
|
public class ColorAlphaAdjuster extends Color {
|
||||||
|
|
||||||
private final Color source;
|
private final Color source;
|
||||||
private final Num alphaAdjust;
|
private final Num alphaAdjust;
|
||||||
|
|
||||||
|
|
||||||
public ColorAlphaAdjuster(Color source, Num alphaMul)
|
public ColorAlphaAdjuster(Color source, Num alphaMul)
|
||||||
{
|
{
|
||||||
this.source = source;
|
this.source = source;
|
||||||
this.alphaAdjust = alphaMul;
|
this.alphaAdjust = alphaMul;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double r()
|
public double r()
|
||||||
{
|
{
|
||||||
return source.r();
|
return source.r();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double g()
|
public double g()
|
||||||
{
|
{
|
||||||
return source.g();
|
return source.g();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double b()
|
public double b()
|
||||||
{
|
{
|
||||||
return source.b();
|
return source.b();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected double rawAlpha()
|
protected double rawAlpha()
|
||||||
{
|
{
|
||||||
return source.rawAlpha() * alphaAdjust.value();
|
return source.rawAlpha() * alphaAdjust.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ import mightypork.utils.math.constraints.num.Num;
|
|||||||
|
|
||||||
|
|
||||||
public class ColorHsb extends Color {
|
public class ColorHsb extends Color {
|
||||||
|
|
||||||
private final Num h;
|
private final Num h;
|
||||||
private final Num s;
|
private final Num s;
|
||||||
private final Num b;
|
private final Num b;
|
||||||
private final Num a;
|
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.h = h;
|
||||||
@@ -19,44 +19,44 @@ public class ColorHsb extends Color {
|
|||||||
this.b = b;
|
this.b = b;
|
||||||
this.a = a;
|
this.a = a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private double[] asRgb()
|
private double[] asRgb()
|
||||||
{
|
{
|
||||||
final int hex = java.awt.Color.HSBtoRGB((float) clamp(h), (float) clamp(s), (float) clamp(b));
|
final int hex = java.awt.Color.HSBtoRGB((float) clamp(h), (float) clamp(s), (float) clamp(b));
|
||||||
|
|
||||||
final int bi = hex & 0xff;
|
final int bi = hex & 0xff;
|
||||||
final int gi = (hex >> 8) & 0xff;
|
final int gi = (hex >> 8) & 0xff;
|
||||||
final int ri = (hex >> 16) & 0xff;
|
final int ri = (hex >> 16) & 0xff;
|
||||||
return new double[] { ri / 255D, gi / 255D, bi / 255D, clamp(a) };
|
return new double[] { ri / 255D, gi / 255D, bi / 255D, clamp(a) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double r()
|
public double r()
|
||||||
{
|
{
|
||||||
return asRgb()[0];
|
return asRgb()[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double g()
|
public double g()
|
||||||
{
|
{
|
||||||
return asRgb()[1];
|
return asRgb()[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double b()
|
public double b()
|
||||||
{
|
{
|
||||||
return asRgb()[2];
|
return asRgb()[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected double rawAlpha()
|
protected double rawAlpha()
|
||||||
{
|
{
|
||||||
return asRgb()[3];
|
return asRgb()[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ import mightypork.utils.math.constraints.num.Num;
|
|||||||
|
|
||||||
|
|
||||||
public class ColorRgb extends Color {
|
public class ColorRgb extends Color {
|
||||||
|
|
||||||
private final Num r;
|
private final Num r;
|
||||||
private final Num g;
|
private final Num g;
|
||||||
private final Num b;
|
private final Num b;
|
||||||
private final Num a;
|
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.r = r;
|
||||||
@@ -19,33 +19,33 @@ public class ColorRgb extends Color {
|
|||||||
this.b = b;
|
this.b = b;
|
||||||
this.a = a;
|
this.a = a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double r()
|
public double r()
|
||||||
{
|
{
|
||||||
return clamp(r);
|
return clamp(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double g()
|
public double g()
|
||||||
{
|
{
|
||||||
return clamp(g);
|
return clamp(g);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double b()
|
public double b()
|
||||||
{
|
{
|
||||||
return clamp(b);
|
return clamp(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected double rawAlpha()
|
protected double rawAlpha()
|
||||||
{
|
{
|
||||||
return clamp(a);
|
return clamp(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ package mightypork.utils.math.color;
|
|||||||
* @author MightyPork
|
* @author MightyPork
|
||||||
*/
|
*/
|
||||||
public class Grad {
|
public class Grad {
|
||||||
|
|
||||||
public final Color leftTop, rightTop, rightBottom, leftBottom;
|
public final Color leftTop, rightTop, rightBottom, leftBottom;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a gradient
|
* Create a gradient
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ package mightypork.utils.math.color;
|
|||||||
* @author MightyPork
|
* @author MightyPork
|
||||||
*/
|
*/
|
||||||
public class GradH extends Grad {
|
public class GradH extends Grad {
|
||||||
|
|
||||||
public GradH(Color left, Color right)
|
public GradH(Color left, Color right)
|
||||||
{
|
{
|
||||||
super(left, right, right, left);
|
super(left, right, right, left);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ package mightypork.utils.math.color;
|
|||||||
* @author MightyPork
|
* @author MightyPork
|
||||||
*/
|
*/
|
||||||
public class GradV extends Grad {
|
public class GradV extends Grad {
|
||||||
|
|
||||||
public GradV(Color top, Color bottom)
|
public GradV(Color top, Color bottom)
|
||||||
{
|
{
|
||||||
super(top, top, bottom, bottom);
|
super(top, top, bottom, bottom);
|
||||||
|
|||||||
@@ -10,12 +10,12 @@ import mightypork.utils.math.color.Color;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public interface CGA {
|
public interface CGA {
|
||||||
|
|
||||||
Color BLACK = Color.fromHex(0x000000);
|
Color BLACK = Color.fromHex(0x000000);
|
||||||
Color GRAY_DARK = Color.fromHex(0x686868);
|
Color GRAY_DARK = Color.fromHex(0x686868);
|
||||||
Color GRAY_LIGHT = Color.fromHex(0xB8B8B8);
|
Color GRAY_LIGHT = Color.fromHex(0xB8B8B8);
|
||||||
Color WHITE = Color.fromHex(0xFFFFFF);
|
Color WHITE = Color.fromHex(0xFFFFFF);
|
||||||
|
|
||||||
Color RED_DARK = Color.fromHex(0xC41F0C);
|
Color RED_DARK = Color.fromHex(0xC41F0C);
|
||||||
Color RED_LIGHT = Color.fromHex(0xFF706A);
|
Color RED_LIGHT = Color.fromHex(0xFF706A);
|
||||||
Color MAGENTA_DARK = Color.fromHex(0xC12BB6);
|
Color MAGENTA_DARK = Color.fromHex(0xC12BB6);
|
||||||
@@ -26,7 +26,7 @@ public interface CGA {
|
|||||||
Color CYAN_LIGHT = Color.fromHex(0x23FCFE);
|
Color CYAN_LIGHT = Color.fromHex(0x23FCFE);
|
||||||
Color GREEN_DARK = Color.fromHex(0x00B41D);
|
Color GREEN_DARK = Color.fromHex(0x00B41D);
|
||||||
Color GREEN_LIGHT = Color.fromHex(0x39FA6F);
|
Color GREEN_LIGHT = Color.fromHex(0x39FA6F);
|
||||||
|
|
||||||
Color YELLOW = Color.fromHex(0xFFFD72);
|
Color YELLOW = Color.fromHex(0xFFFD72);
|
||||||
Color BROWN = Color.fromHex(0xC16A14);
|
Color BROWN = Color.fromHex(0xC16A14);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import mightypork.utils.math.color.Color;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public interface CMDR {
|
public interface CMDR {
|
||||||
|
|
||||||
Color BLACK = Color.fromHex(0x040013);
|
Color BLACK = Color.fromHex(0x040013);
|
||||||
Color WHITE = Color.fromHex(0xFFFFFF);
|
Color WHITE = Color.fromHex(0xFFFFFF);
|
||||||
Color RED = Color.fromHex(0x883932);
|
Color RED = Color.fromHex(0x883932);
|
||||||
|
|||||||
@@ -10,23 +10,23 @@ import mightypork.utils.math.color.Color;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public interface PAL16 {
|
public interface PAL16 {
|
||||||
|
|
||||||
Color VOID = Color.fromHex(0x000000);
|
Color VOID = Color.fromHex(0x000000);
|
||||||
Color ASH = Color.fromHex(0x9D9D9D);
|
Color ASH = Color.fromHex(0x9D9D9D);
|
||||||
Color BLIND = Color.fromHex(0xFFFFFF);
|
Color BLIND = Color.fromHex(0xFFFFFF);
|
||||||
|
|
||||||
Color BLOODRED = Color.fromHex(0xBE2633);
|
Color BLOODRED = Color.fromHex(0xBE2633);
|
||||||
Color PIGMEAT = Color.fromHex(0xE06F8B);
|
Color PIGMEAT = Color.fromHex(0xE06F8B);
|
||||||
|
|
||||||
Color OLDPOOP = Color.fromHex(0x493C2B);
|
Color OLDPOOP = Color.fromHex(0x493C2B);
|
||||||
Color NEWPOOP = Color.fromHex(0xA46422);
|
Color NEWPOOP = Color.fromHex(0xA46422);
|
||||||
Color BLAZE = Color.fromHex(0xEB8931);
|
Color BLAZE = Color.fromHex(0xEB8931);
|
||||||
Color ZORNSKIN = Color.fromHex(0xF7E26B);
|
Color ZORNSKIN = Color.fromHex(0xF7E26B);
|
||||||
|
|
||||||
Color SHADEGREEN = Color.fromHex(0x2F484E);
|
Color SHADEGREEN = Color.fromHex(0x2F484E);
|
||||||
Color LEAFGREEN = Color.fromHex(0x44891A);
|
Color LEAFGREEN = Color.fromHex(0x44891A);
|
||||||
Color SLIMEGREEN = Color.fromHex(0xA3CE27);
|
Color SLIMEGREEN = Color.fromHex(0xA3CE27);
|
||||||
|
|
||||||
Color NIGHTBLUE = Color.fromHex(0x1B2632);
|
Color NIGHTBLUE = Color.fromHex(0x1B2632);
|
||||||
Color SEABLUE = Color.fromHex(0x005784);
|
Color SEABLUE = Color.fromHex(0x005784);
|
||||||
Color SKYBLUE = Color.fromHex(0x31A2F2);
|
Color SKYBLUE = Color.fromHex(0x31A2F2);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import mightypork.utils.math.color.Color;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public class RGB {
|
public class RGB {
|
||||||
|
|
||||||
public static final Color BLACK_10 = Color.rgba(0, 0, 0, 0.1);
|
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_20 = Color.rgba(0, 0, 0, 0.2);
|
||||||
public static final Color BLACK_30 = Color.rgba(0, 0, 0, 0.3);
|
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_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_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 BLACK_90 = Color.rgba(0, 0, 0, 0.9);
|
||||||
|
|
||||||
public static final Color WHITE = Color.fromHex(0xFFFFFF);
|
public static final Color WHITE = Color.fromHex(0xFFFFFF);
|
||||||
public static final Color BLACK = Color.fromHex(0x000000);
|
public static final Color BLACK = Color.fromHex(0x000000);
|
||||||
public static final Color GRAY_DARK = Color.fromHex(0x808080);
|
public static final Color GRAY_DARK = Color.fromHex(0x808080);
|
||||||
public static final Color GRAY = Color.fromHex(0xA0A0A0);
|
public static final Color GRAY = Color.fromHex(0xA0A0A0);
|
||||||
public static final Color GRAY_LIGHT = Color.fromHex(0xC0C0C0);
|
public static final Color GRAY_LIGHT = Color.fromHex(0xC0C0C0);
|
||||||
|
|
||||||
public static final Color RED = Color.fromHex(0xFF0000);
|
public static final Color RED = Color.fromHex(0xFF0000);
|
||||||
public static final Color GREEN = Color.fromHex(0x00FF00);
|
public static final Color GREEN = Color.fromHex(0x00FF00);
|
||||||
public static final Color BLUE = Color.fromHex(0x0000FF);
|
public static final Color BLUE = Color.fromHex(0x0000FF);
|
||||||
|
|
||||||
public static final Color YELLOW = Color.fromHex(0xFFFF00);
|
public static final Color YELLOW = Color.fromHex(0xFFFF00);
|
||||||
public static final Color CYAN = Color.fromHex(0x00FFFF);
|
public static final Color CYAN = Color.fromHex(0x00FFFF);
|
||||||
public static final Color MAGENTA = Color.fromHex(0xFF00FF);
|
public static final Color MAGENTA = Color.fromHex(0xFF00FF);
|
||||||
|
|
||||||
public static final Color PINK = Color.fromHex(0xFF3FFC);
|
public static final Color PINK = Color.fromHex(0xFF3FFC);
|
||||||
public static final Color ORANGE = Color.fromHex(0xFC4800);
|
public static final Color ORANGE = Color.fromHex(0xFC4800);
|
||||||
public static final Color BROWN = Color.fromHex(0x83501B);
|
public static final Color BROWN = Color.fromHex(0x83501B);
|
||||||
|
|
||||||
public static final Color NONE = Color.rgba(0, 0, 0, 0);
|
public static final Color NONE = Color.rgba(0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,11 +10,11 @@ import mightypork.utils.math.color.Color;
|
|||||||
* @author Ondřej Hruška (MightyPork)
|
* @author Ondřej Hruška (MightyPork)
|
||||||
*/
|
*/
|
||||||
public interface ZX {
|
public interface ZX {
|
||||||
|
|
||||||
Color BLACK = Color.fromHex(0x000000);
|
Color BLACK = Color.fromHex(0x000000);
|
||||||
Color GRAY = Color.fromHex(0xCBCBCB);
|
Color GRAY = Color.fromHex(0xCBCBCB);
|
||||||
Color WHITE = Color.fromHex(0xFFFFFF);
|
Color WHITE = Color.fromHex(0xFFFFFF);
|
||||||
|
|
||||||
Color RED_DARK = Color.fromHex(0xD8240F);
|
Color RED_DARK = Color.fromHex(0xD8240F);
|
||||||
Color RED_LIGHT = Color.fromHex(0xFF3016);
|
Color RED_LIGHT = Color.fromHex(0xFF3016);
|
||||||
Color MAGENTA_DARK = Color.fromHex(0xD530C9);
|
Color MAGENTA_DARK = Color.fromHex(0xD530C9);
|
||||||
@@ -25,7 +25,7 @@ public interface ZX {
|
|||||||
Color CYAN_LIGHT = Color.fromHex(0xFFFD33);
|
Color CYAN_LIGHT = Color.fromHex(0xFFFD33);
|
||||||
Color GREEN_DARK = Color.fromHex(0x00C721);
|
Color GREEN_DARK = Color.fromHex(0x00C721);
|
||||||
Color GREEN_LIGHT = Color.fromHex(0x00F92C);
|
Color GREEN_LIGHT = Color.fromHex(0x00F92C);
|
||||||
|
|
||||||
Color YELLOW_DARK = Color.fromHex(0xCECA26);
|
Color YELLOW_DARK = Color.fromHex(0xCECA26);
|
||||||
Color YELLOW_LIGHT = Color.fromHex(0xFFFD33);
|
Color YELLOW_LIGHT = Color.fromHex(0xFFFD33);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,33 +11,33 @@ import mightypork.utils.interfaces.Pollable;
|
|||||||
* @param <C> constraint type
|
* @param <C> constraint type
|
||||||
*/
|
*/
|
||||||
public interface CachedConstraint<C> extends Pollable {
|
public interface CachedConstraint<C> extends Pollable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called after the cache has changed value (and digest).
|
* Called after the cache has changed value (and digest).
|
||||||
*/
|
*/
|
||||||
void onConstraintChanged();
|
void onConstraintChanged();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the cached value
|
* @return the cached value
|
||||||
*/
|
*/
|
||||||
C getCacheSource();
|
C getCacheSource();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable caching & digest caching
|
* Enable caching & digest caching
|
||||||
*
|
*
|
||||||
* @param yes enable caching
|
* @param yes enable caching
|
||||||
*/
|
*/
|
||||||
void enableCaching(boolean yes);
|
void enableCaching(boolean yes);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if caching is on
|
* @return true if caching is on
|
||||||
*/
|
*/
|
||||||
boolean isCachingEnabled();
|
boolean isCachingEnabled();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update cached value and cached digest (if digest caching is enabled).<br>
|
* Update cached value and cached digest (if digest caching is enabled).<br>
|
||||||
* source constraint is polled beforehand.
|
* source constraint is polled beforehand.
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user