equivalent-exchange-3/common/com/pahimar/ee3/emc/EmcValue.java

285 lines
8 KiB
Java
Raw Normal View History

2013-08-23 16:59:50 +02:00
package com.pahimar.ee3.emc;
import java.lang.reflect.Type;
2013-08-23 16:59:50 +02:00
import java.util.ArrayList;
import java.util.Collections;
2013-08-23 16:59:50 +02:00
import java.util.List;
2013-11-20 02:19:33 +01:00
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
2013-11-20 02:19:33 +01:00
import com.google.gson.JsonSyntaxException;
2013-08-23 16:59:50 +02:00
/**
* Equivalent-Exchange-3
*
* EMCEntry
*
* @author pahimar
* @license Lesser GNU Public License v3 (http://www.gnu.org/licenses/lgpl.html)
*
*/
public class EmcValue implements Comparable<EmcValue> {
2013-08-23 16:59:50 +02:00
// Gson serializer for serializing to/deserializing from json
private static final Gson gsonSerializer = (new GsonBuilder()).registerTypeAdapter(EmcValue.class, new EmcValue().new EmcValueJsonSerializer()).create();
2013-11-21 02:17:32 +01:00
public final float[] components;
2013-08-23 16:59:50 +02:00
public EmcValue() {
2013-10-21 00:30:15 +02:00
this(new float[EmcType.TYPES.length]);
2013-08-23 16:59:50 +02:00
}
public EmcValue(int value) {
this((float) value);
}
2013-08-23 16:59:50 +02:00
public EmcValue(float value) {
2013-10-21 00:30:15 +02:00
this(value, EmcType.DEFAULT);
2013-08-23 16:59:50 +02:00
}
public EmcValue(float value, EmcComponent component) {
2013-09-07 04:47:12 +02:00
2013-10-21 00:30:15 +02:00
this(value, component.type);
2013-08-23 16:59:50 +02:00
}
2013-11-21 02:17:32 +01:00
public EmcValue(int value, EmcType emcType) {
2013-11-21 02:17:32 +01:00
this((float) value, emcType);
}
2013-11-21 02:17:32 +01:00
2013-10-21 00:30:15 +02:00
public EmcValue(float value, EmcType emcType) {
2013-09-07 04:47:12 +02:00
this.components = new float[EmcType.TYPES.length];
2013-10-21 00:30:15 +02:00
this.components[emcType.ordinal()] = value;
}
public EmcValue(float[] components) {
this.components = components;
2013-08-23 16:59:50 +02:00
}
2013-09-07 04:47:12 +02:00
public EmcValue(int value, List<EmcComponent> componentList) {
2013-08-23 16:59:50 +02:00
this((float) value, componentList);
}
public EmcValue(float value, List<EmcComponent> componentList) {
this.components = new float[EmcType.TYPES.length];
List<EmcComponent> collatedComponents = collateComponents(componentList);
int totalComponents = 0;
for (EmcComponent component : collatedComponents) {
if (component.weight > 0) {
totalComponents += component.weight;
2013-10-06 04:46:29 +02:00
}
}
if (totalComponents > 0) {
for (EmcComponent component : collatedComponents) {
if (component.weight > 0) {
this.components[component.type.ordinal()] = value * (component.weight * 1F / totalComponents);
}
}
}
else {
this.components[EmcType.DEFAULT.ordinal()] = value;
}
2013-08-23 16:59:50 +02:00
}
public float getValue() {
float sumSubValues = 0;
for (float subValue : this.components) {
if (subValue > 0) {
sumSubValues += subValue;
}
}
return sumSubValues;
}
2013-08-23 16:59:50 +02:00
@Override
public boolean equals(Object object) {
if (!(object instanceof EmcValue)) {
return false;
}
return (compareTo((EmcValue) object) == 0);
2013-08-23 16:59:50 +02:00
}
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
2013-11-21 02:17:32 +01:00
// TODO Intelligible output
2013-10-21 00:30:15 +02:00
stringBuilder.append("[");
2013-11-21 02:17:32 +01:00
2013-10-21 00:30:15 +02:00
for (EmcType emcType : EmcType.TYPES) {
if (components[emcType.ordinal()] > 0) {
stringBuilder.append(String.format(" %s:%s ", emcType, components[emcType.ordinal()]));
}
}
2013-11-21 02:17:32 +01:00
2013-10-21 00:30:15 +02:00
stringBuilder.append("]");
2013-08-23 16:59:50 +02:00
return stringBuilder.toString();
}
@Override
public int hashCode() {
int hashCode = 1;
hashCode = 37 * hashCode + Float.floatToIntBits(getValue());
for (float subValue : components) {
hashCode = 37 * hashCode + Float.floatToIntBits(subValue);
}
2013-08-23 16:59:50 +02:00
return hashCode;
}
2013-09-07 04:47:12 +02:00
@Override
public int compareTo(EmcValue emcValue) {
2013-09-10 19:29:30 +02:00
if (emcValue instanceof EmcValue) {
2013-10-21 00:30:15 +02:00
return compareComponents(this.components, emcValue.components);
2013-09-07 04:47:12 +02:00
}
else {
return -1;
2013-09-07 04:47:12 +02:00
}
}
2013-11-21 02:17:32 +01:00
2013-11-20 02:19:33 +01:00
/**
* Deserializes an EmcValue object from the given serialized json String
*
2013-11-21 02:17:32 +01:00
* @param jsonEmcValue
* Json encoded String representing a EmcValue object
* @return The EmcValue that was encoded as json, or null if a valid
* EmcValue could not be decoded from given String
2013-11-20 02:19:33 +01:00
*/
public static EmcValue createFromJson(String jsonEmcValue) {
2013-11-21 02:17:32 +01:00
2013-11-20 02:19:33 +01:00
try {
return (EmcValue) gsonSerializer.fromJson(jsonEmcValue, EmcValue.class);
2013-11-20 02:19:33 +01:00
}
catch (JsonSyntaxException exception) {
// TODO Log something regarding the failed parse
}
2013-11-21 02:17:32 +01:00
2013-11-20 02:19:33 +01:00
return null;
}
2013-11-21 02:17:32 +01:00
2013-11-20 02:19:33 +01:00
/**
* Returns this EmcValue as a json serialized String
*
* @return Json serialized String of this EmcValue
*/
public String toJson() {
2013-11-21 02:17:32 +01:00
return gsonSerializer.toJson(this);
2013-11-20 02:19:33 +01:00
}
2013-09-07 04:47:12 +02:00
private static List<EmcComponent> collateComponents(List<EmcComponent> uncollatedComponents) {
Integer[] componentCount = new Integer[EmcType.TYPES.length];
2013-09-07 04:47:12 +02:00
for (EmcComponent emcComponent : uncollatedComponents) {
if (componentCount[emcComponent.type.ordinal()] == null) {
componentCount[emcComponent.type.ordinal()] = new Integer(0);
2013-09-07 04:47:12 +02:00
}
if (emcComponent.weight >= 0) {
componentCount[emcComponent.type.ordinal()] = new Integer(componentCount[emcComponent.type.ordinal()].intValue() + emcComponent.weight);
}
2013-09-07 04:47:12 +02:00
}
List<EmcComponent> collatedComponents = new ArrayList<EmcComponent>();
2013-10-06 04:46:29 +02:00
for (int i = 0; i < EmcType.TYPES.length; i++) {
2013-09-07 04:47:12 +02:00
if (componentCount[i] != null) {
2013-10-06 04:46:29 +02:00
collatedComponents.add(new EmcComponent(EmcType.TYPES[i], componentCount[i].intValue()));
2013-09-07 04:47:12 +02:00
}
}
2013-10-06 04:46:29 +02:00
Collections.sort(collatedComponents);
2013-09-07 04:47:12 +02:00
return collatedComponents;
}
private static int compareComponents(float[] first, float[] second) {
if (first.length == EmcType.TYPES.length && second.length == EmcType.TYPES.length) {
2013-10-21 00:30:15 +02:00
for (EmcType emcType : EmcType.TYPES) {
if (Float.compare(first[emcType.ordinal()], second[emcType.ordinal()]) != 0) {
return Float.compare(first[emcType.ordinal()], second[emcType.ordinal()]);
}
}
return 0;
}
else {
throw new ArrayIndexOutOfBoundsException();
}
}
2013-11-21 02:17:32 +01:00
private class EmcValueJsonSerializer
implements JsonDeserializer<EmcValue>, JsonSerializer<EmcValue> {
@Override
public JsonElement serialize(EmcValue emcValue, Type type, JsonSerializationContext context) {
JsonObject jsonEmcValue = new JsonObject();
2013-11-21 02:17:32 +01:00
for (EmcType emcType : EmcType.TYPES) {
jsonEmcValue.addProperty(emcType.toString(), emcValue.components[emcType.ordinal()]);
}
2013-11-21 02:17:32 +01:00
return jsonEmcValue;
}
@Override
public EmcValue deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext context) throws JsonParseException {
float[] emcValueComponents = new float[EmcType.TYPES.length];
2013-11-21 02:17:32 +01:00
JsonObject jsonEmcValue = (JsonObject) jsonElement;
for (EmcType emcType : EmcType.TYPES) {
if ((jsonEmcValue.get(emcType.toString()) != null) && (jsonEmcValue.get(emcType.toString()).isJsonPrimitive())) {
try {
emcValueComponents[emcType.ordinal()] = jsonEmcValue.get(emcType.toString()).getAsFloat();
}
catch (UnsupportedOperationException exception) {
// TODO Better logging/handling of the exception
exception.printStackTrace(System.err);
}
}
}
2013-11-21 02:17:32 +01:00
EmcValue emcValue = new EmcValue(emcValueComponents);
2013-11-21 02:17:32 +01:00
if (emcValue.getValue() > 0f) {
return emcValue;
}
2013-11-21 02:17:32 +01:00
return null;
}
}
2013-08-23 16:59:50 +02:00
}