package iamrescue.communication.messages.codec.property; import iamrescue.communication.messages.codec.BitStreamDecoder; import iamrescue.communication.messages.codec.BitStreamEncoder; import iamrescue.communication.messages.codec.CodecUtils; import org.apache.commons.lang.Validate; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import rescuecore2.worldmodel.Entity; import rescuecore2.worldmodel.Property; import rescuecore2.worldmodel.properties.DoubleProperty; import rescuecore2.worldmodel.properties.IntProperty; public abstract class ByteScaleConverter extends APropertyCodec { private Log log = LogFactory.getLog(ByteScaleConverter.class); private boolean improveResolutionForSmallerValues; public Class<? extends Number> getEncodedValueType() { return Byte.class; } public ByteScaleConverter(boolean improveResolutionForSmallerValues) { this.improveResolutionForSmallerValues = improveResolutionForSmallerValues; } @Override public Property decode(Entity object, BitStreamDecoder decoder) { int encodedValue = decoder.readInt(); int minValue = getMinValue(object); int range = getMaxValue(object) - getMinValue(object); double percentage = CodecUtils .convertByteToPercentage((byte) encodedValue); if (improveResolutionForSmallerValues) percentage *= percentage; int value = (int) ((percentage) * range + minValue); Validate.isTrue(value >= getMinValue(object), "Decoded Value " + value + " is < min value " + getMinValue(object) + " of property " + getPropertyKey()); Validate.isTrue(value <= getMaxValue(object), "Decoded Value " + value + " is > max value " + getMaxValue(object) + " of property " + getPropertyKey()); return PropertyFactory.create(getPropertyKey(), value); } @Override public void encode(Entity object, Property propertyValue, BitStreamEncoder encoder) { int minValue = getMinValue(object); int range = getMaxValue(object) - getMinValue(object); if (!(propertyValue instanceof DoubleProperty || propertyValue instanceof IntProperty)) { throw new IllegalArgumentException("Can only encode numbers"); } double value = ((Number) propertyValue.getValue()).doubleValue(); if (value < getMinValue(object)) { log.warn("Losing precision: Value " + value + " is < min value " + getMinValue(object) + " of property " + getPropertyKey()); value = getMinValue(object); } if (value > getMaxValue(object)) { log.warn("Losing precision: Value " + value + " is > max value " + getMaxValue(object) + " of property " + getPropertyKey()); value = getMaxValue(object); } double percentage = (value - minValue) / range; if (improveResolutionForSmallerValues) percentage = Math.sqrt(percentage); byte convertPercentageToByte = CodecUtils .convertPercentageToByte(percentage); encoder.appendByte(convertPercentageToByte); } public abstract int getMaxValue(Entity object); public abstract int getMinValue(Entity object); }